vaapi_video_decoder.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef MEDIA_GPU_VAAPI_VAAPI_VIDEO_DECODER_H_
  5. #define MEDIA_GPU_VAAPI_VAAPI_VIDEO_DECODER_H_
  6. #include <stdint.h>
  7. #include <va/va.h>
  8. #include <map>
  9. #include <memory>
  10. #include <utility>
  11. #include "base/containers/lru_cache.h"
  12. #include "base/containers/queue.h"
  13. #include "base/containers/small_map.h"
  14. #include "base/memory/raw_ptr.h"
  15. #include "base/memory/scoped_refptr.h"
  16. #include "base/memory/weak_ptr.h"
  17. #include "base/sequence_checker.h"
  18. #include "base/time/time.h"
  19. #include "build/chromeos_buildflags.h"
  20. #include "media/base/callback_registry.h"
  21. #include "media/base/cdm_context.h"
  22. #include "media/base/status.h"
  23. #include "media/base/supported_video_decoder_config.h"
  24. #include "media/base/video_aspect_ratio.h"
  25. #include "media/base/video_codecs.h"
  26. #include "media/base/video_frame_layout.h"
  27. #include "media/gpu/chromeos/video_decoder_pipeline.h"
  28. #include "media/gpu/decode_surface_handler.h"
  29. #include "media/gpu/vaapi/vaapi_status.h"
  30. #include "third_party/abseil-cpp/absl/types/optional.h"
  31. #include "ui/gfx/geometry/rect.h"
  32. #include "ui/gfx/geometry/size.h"
  33. #include "ui/gfx/gpu_memory_buffer.h"
  34. #include "ui/gfx/hdr_metadata.h"
  35. namespace media {
  36. class AcceleratedVideoDecoder;
  37. class VaapiVideoDecoderDelegate;
  38. class DmabufVideoFramePool;
  39. class VaapiWrapper;
  40. class VideoFrame;
  41. class VASurface;
  42. class VaapiVideoDecoder : public VideoDecoderMixin,
  43. public DecodeSurfaceHandler<VASurface> {
  44. public:
  45. static std::unique_ptr<VideoDecoderMixin> Create(
  46. std::unique_ptr<MediaLog> media_log,
  47. scoped_refptr<base::SequencedTaskRunner> decoder_task_runner,
  48. base::WeakPtr<VideoDecoderMixin::Client> client);
  49. VaapiVideoDecoder(const VaapiVideoDecoder&) = delete;
  50. VaapiVideoDecoder& operator=(const VaapiVideoDecoder&) = delete;
  51. static absl::optional<SupportedVideoDecoderConfigs> GetSupportedConfigs();
  52. // VideoDecoderMixin implementation, VideoDecoder part.
  53. void Initialize(const VideoDecoderConfig& config,
  54. bool low_delay,
  55. CdmContext* cdm_context,
  56. InitCB init_cb,
  57. const OutputCB& output_cb,
  58. const WaitingCB& waiting_cb) override;
  59. void Decode(scoped_refptr<DecoderBuffer> buffer, DecodeCB decode_cb) override;
  60. void Reset(base::OnceClosure reset_cb) override;
  61. bool NeedsBitstreamConversion() const override;
  62. bool CanReadWithoutStalling() const override;
  63. int GetMaxDecodeRequests() const override;
  64. VideoDecoderType GetDecoderType() const override;
  65. bool IsPlatformDecoder() const override;
  66. // VideoDecoderMixin implementation, specific part.
  67. void ApplyResolutionChange() override;
  68. bool NeedsTranscryption() override;
  69. // DecodeSurfaceHandler<VASurface> implementation.
  70. scoped_refptr<VASurface> CreateSurface() override;
  71. void SurfaceReady(scoped_refptr<VASurface> va_surface,
  72. int32_t buffer_id,
  73. const gfx::Rect& visible_rect,
  74. const VideoColorSpace& color_space) override;
  75. private:
  76. // Decode task holding single decode request.
  77. struct DecodeTask {
  78. DecodeTask(scoped_refptr<DecoderBuffer> buffer,
  79. int32_t buffer_id,
  80. DecodeCB decode_done_cb);
  81. DecodeTask(const DecodeTask&) = delete;
  82. DecodeTask& operator=(const DecodeTask&) = delete;
  83. DecodeTask(DecodeTask&&);
  84. DecodeTask& operator=(DecodeTask&&) = default;
  85. ~DecodeTask();
  86. scoped_refptr<DecoderBuffer> buffer_;
  87. int32_t buffer_id_ = -1;
  88. DecodeCB decode_done_cb_;
  89. };
  90. enum class State {
  91. kUninitialized, // not initialized yet or initialization failed.
  92. kWaitingForInput, // waiting for input buffers.
  93. kWaitingForOutput, // waiting for output buffers.
  94. kWaitingForProtected, // waiting on something related to protected content,
  95. // either setup, full sample parsing or key loading.
  96. kDecoding, // decoding buffers.
  97. kChangingResolution, // need to change resolution, waiting for pipeline to
  98. // be flushed.
  99. kExpectingReset, // resolution change is aborted, waiting for decoder
  100. // to be reset.
  101. kResetting, // resetting decoder.
  102. kError, // decoder encountered an error.
  103. };
  104. VaapiVideoDecoder(
  105. std::unique_ptr<MediaLog> media_log,
  106. scoped_refptr<base::SequencedTaskRunner> decoder_task_runner,
  107. base::WeakPtr<VideoDecoderMixin::Client> client);
  108. ~VaapiVideoDecoder() override;
  109. // Schedule the next decode task in the queue to be executed.
  110. void ScheduleNextDecodeTask();
  111. // Try to decode a single input buffer.
  112. void HandleDecodeTask();
  113. // Clear the decode task queue. This is done when resetting or destroying the
  114. // decoder, or encountering an error.
  115. void ClearDecodeTaskQueue(DecoderStatus status);
  116. // Releases the local reference to the VideoFrame associated with the
  117. // specified |surface_id| on the decoder thread. This is called when
  118. // |decoder_| has outputted the VideoFrame and stopped using it as a
  119. // reference frame. Note that this doesn't mean the frame can be reused
  120. // immediately, as it might still be used by the client.
  121. void ReleaseVideoFrame(VASurfaceID surface_id);
  122. // Callback for the frame pool to notify us when a frame becomes available.
  123. void NotifyFrameAvailable();
  124. // Callback from accelerator to indicate the protected state has been updated
  125. // so we can proceed or fail.
  126. void ProtectedSessionUpdate(bool success);
  127. // Flushes |decoder_|, blocking until all pending decode tasks have been
  128. // executed and all frames have been output.
  129. void Flush();
  130. // Called when resetting the decoder is finished, to execute |reset_cb|.
  131. void ResetDone(base::OnceClosure reset_cb);
  132. // Create codec-specific AcceleratedVideoDecoder and reset related variables.
  133. VaapiStatus CreateAcceleratedVideoDecoder();
  134. // Change the current |state_| to the specified |state|.
  135. void SetState(State state);
  136. // Tell SetState() to change the |state_| to kError and send |message| to
  137. // MediaLog and to LOG(ERROR).
  138. void SetErrorState(std::string message);
  139. // Callback for the CDM to notify |this|.
  140. void OnCdmContextEvent(CdmContext::Event event);
  141. // This is a callback from ApplyResolutionChange() when we need to query the
  142. // browser process for the screen sizes.
  143. void ApplyResolutionChangeWithScreenSizes(
  144. const std::vector<gfx::Size>& screen_resolution);
  145. // Private static helper to allow using weak ptr instead of an unretained ptr.
  146. static CroStatus::Or<scoped_refptr<VideoFrame>> AllocateCustomFrameProxy(
  147. base::WeakPtr<VaapiVideoDecoder> decoder,
  148. VideoPixelFormat format,
  149. const gfx::Size& coded_size,
  150. const gfx::Rect& visible_rect,
  151. const gfx::Size& natural_size,
  152. bool use_protected,
  153. bool use_linear_buffers,
  154. base::TimeDelta timestamp);
  155. // Allocates a new VideoFrame using a new VASurface directly. Since this is
  156. // only used on linux, it also sets the required YCbCr information for the
  157. // frame it creates.
  158. CroStatus::Or<scoped_refptr<VideoFrame>> AllocateCustomFrame(
  159. VideoPixelFormat format,
  160. const gfx::Size& coded_size,
  161. const gfx::Rect& visible_rect,
  162. const gfx::Size& natural_size,
  163. bool use_protected,
  164. bool use_linear_buffers,
  165. base::TimeDelta timestamp);
  166. // Having too many decoder instances at once may cause us to run out of FDs
  167. // and subsequently crash (b/181264362). To avoid that, we limit the maximum
  168. // number of decoder instances that can exist at once. |num_instances_| tracks
  169. // that number.
  170. //
  171. // TODO(andrescj): we can relax this once we extract video decoding into its
  172. // own process.
  173. static constexpr int kMaxNumOfInstances = 16;
  174. static base::AtomicRefCount num_instances_;
  175. // The video decoder's state.
  176. State state_ = State::kUninitialized;
  177. // Callback used to notify the client when a frame is available for output.
  178. OutputCB output_cb_;
  179. // Callback used to notify the client when we have lost decode context and
  180. // request a reset (Used in protected decoding).
  181. WaitingCB waiting_cb_;
  182. // Bitstream information, written during Initialize().
  183. VideoCodecProfile profile_ = VIDEO_CODEC_PROFILE_UNKNOWN;
  184. VideoColorSpace color_space_;
  185. absl::optional<gfx::HDRMetadata> hdr_metadata_;
  186. // Aspect ratio from the config.
  187. VideoAspectRatio aspect_ratio_;
  188. // The time at which each buffer decode operation started. Not each decode
  189. // operation leads to a frame being output and frames might be reordered, so
  190. // we don't know when it's safe to drop a timestamp. This means we need to use
  191. // a cache here, with a size large enough to account for frame reordering.
  192. base::LRUCache<int32_t, base::TimeDelta> buffer_id_to_timestamp_;
  193. // Queue containing all requested decode tasks.
  194. base::queue<DecodeTask> decode_task_queue_;
  195. // The decode task we're currently trying to execute.
  196. absl::optional<DecodeTask> current_decode_task_;
  197. // The next input buffer id.
  198. int32_t next_buffer_id_ = 0;
  199. // The list of frames currently used as output buffers or reference frames.
  200. std::map<VASurfaceID, scoped_refptr<VideoFrame>> output_frames_;
  201. // VASurfaces are created via importing resources from a DmabufVideoFramePool
  202. // into libva in CreateSurface(). The following map keeps those VASurfaces for
  203. // reuse according to the expectations of libva vaDestroySurfaces(): "Surfaces
  204. // can only be destroyed after all contexts using these surfaces have been
  205. // destroyed."
  206. // TODO(crbug.com/1040291): remove this keep-alive when using SharedImages.
  207. base::small_map<std::map<gfx::GpuMemoryBufferId, scoped_refptr<VASurface>>>
  208. allocated_va_surfaces_;
  209. // We need to use a CdmContextRef so that we destruct
  210. // |cdm_event_cb_registration_| before the CDM is destructed. The CDM has
  211. // mechanisms to ensure destruction on the proper thread.
  212. //
  213. // For clarity, the MojoVideoDecoderService does hold a reference to both the
  214. // decoder and the CDM to ensure the CDM doesn't get destructed before the
  215. // decoder; however, in the VideoDecoderPipeline, which owns the
  216. // VaapiVideoDecoder, it uses an asynchronous destructor to destroy the
  217. // pipeline (and thus the VaapiVideoDecoder) on the decoder thread.
  218. std::unique_ptr<CdmContextRef> cdm_context_ref_;
  219. EncryptionScheme encryption_scheme_;
  220. #if BUILDFLAG(IS_CHROMEOS_ASH)
  221. // To keep the CdmContext event callback registered.
  222. std::unique_ptr<CallbackRegistration> cdm_event_cb_registration_;
  223. #endif
  224. // Platform and codec specific video decoder.
  225. std::unique_ptr<AcceleratedVideoDecoder> decoder_;
  226. scoped_refptr<VaapiWrapper> vaapi_wrapper_;
  227. // TODO(crbug.com/1022246): Instead of having the raw pointer here, getting
  228. // the pointer from AcceleratedVideoDecoder.
  229. raw_ptr<VaapiVideoDecoderDelegate> decoder_delegate_ = nullptr;
  230. // This is used on AMD protected content implementations to indicate that the
  231. // DecoderBuffers we receive have been transcrypted and need special handling.
  232. bool transcryption_ = false;
  233. SEQUENCE_CHECKER(sequence_checker_);
  234. base::WeakPtr<VaapiVideoDecoder> weak_this_;
  235. base::WeakPtrFactory<VaapiVideoDecoder> weak_this_factory_;
  236. };
  237. } // namespace media
  238. #endif // MEDIA_GPU_VAAPI_VAAPI_VIDEO_DECODER_H_