vda_video_frame_pool.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // Copyright 2020 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_CHROMEOS_VDA_VIDEO_FRAME_POOL_H_
  5. #define MEDIA_GPU_CHROMEOS_VDA_VIDEO_FRAME_POOL_H_
  6. #include "base/containers/queue.h"
  7. #include "base/memory/scoped_refptr.h"
  8. #include "base/memory/weak_ptr.h"
  9. #include "base/task/sequenced_task_runner.h"
  10. #include "media/base/video_frame.h"
  11. #include "media/gpu/chromeos/chromeos_status.h"
  12. #include "media/gpu/chromeos/dmabuf_video_frame_pool.h"
  13. #include "media/gpu/chromeos/fourcc.h"
  14. #include "third_party/abseil-cpp/absl/types/optional.h"
  15. namespace base {
  16. class WaitableEvent;
  17. }
  18. namespace media {
  19. class GpuBufferLayout;
  20. // This class is used by VdVideoDecodeAccelerator, which adapts
  21. // VideoDecodeAccelerator to VideoDecoder interface.
  22. // The mission is to allocate and manage DMA-buf VideoFrame by delegating the
  23. // requests of buffer allocation to a VideoDecodeAccelerator instance, and
  24. // provide VideoFrame to the VideoDecoder instance.
  25. // The communication with VdVideoDecodeAccelerator, which inherits
  26. // VdaDelegate, is executed on |vda_task_runner_|, and the communication with
  27. // VideoDecoder instance is on |parent_task_runner_|.
  28. class VdaVideoFramePool : public DmabufVideoFramePool {
  29. public:
  30. class VdaDelegate {
  31. public:
  32. // Callback for returning the layout of requested buffer.
  33. using NotifyLayoutChangedCb =
  34. base::OnceCallback<void(CroStatus::Or<GpuBufferLayout>)>;
  35. // Callback for importing available frames to this pool.
  36. using ImportFrameCb =
  37. base::RepeatingCallback<void(scoped_refptr<VideoFrame>)>;
  38. // Request new frames from VDA's client. VdaDelegate has to return the
  39. // layout of frames by calling |notify_layout_changed_cb|.
  40. // After that, VdaDelegate should pass frames by calling
  41. // |import_frame_cb|.
  42. // Note: RequestFrames(), |notify_layout_changed_cb|, and |import_frame_cb|
  43. // should be called on VdaVideoFramePool's |vda_task_runner_|.
  44. virtual void RequestFrames(const Fourcc& fourcc,
  45. const gfx::Size& coded_size,
  46. const gfx::Rect& visible_rect,
  47. size_t max_num_frames,
  48. NotifyLayoutChangedCb notify_layout_changed_cb,
  49. ImportFrameCb import_frame_cb) = 0;
  50. };
  51. VdaVideoFramePool(base::WeakPtr<VdaDelegate> vda,
  52. scoped_refptr<base::SequencedTaskRunner> vda_task_runner);
  53. ~VdaVideoFramePool() override;
  54. // DmabufVideoFramePool implementation.
  55. CroStatus::Or<GpuBufferLayout> Initialize(const Fourcc& fourcc,
  56. const gfx::Size& coded_size,
  57. const gfx::Rect& visible_rect,
  58. const gfx::Size& natural_size,
  59. size_t max_num_frames,
  60. bool use_protected,
  61. bool use_linear_buffers) override;
  62. scoped_refptr<VideoFrame> GetFrame() override;
  63. bool IsExhausted() override;
  64. void NotifyWhenFrameAvailable(base::OnceClosure cb) override;
  65. void ReleaseAllFrames() override;
  66. private:
  67. // Update the layout of the buffers. |vda_| calls this as
  68. // NotifyLayoutChangedCb.
  69. static void OnRequestFramesDone(base::WaitableEvent* done,
  70. CroStatus::Or<GpuBufferLayout>* layout,
  71. CroStatus::Or<GpuBufferLayout> layout_value);
  72. // Thunk to post ImportFrame() to |task_runner|.
  73. // Because this thunk may be called in any thread, We don't want to
  74. // dereference WeakPtr. Therefore we wrap the WeakPtr by absl::optional to
  75. // avoid the task runner defererencing the WeakPtr.
  76. static void ImportFrameThunk(
  77. scoped_refptr<base::SequencedTaskRunner> task_runner,
  78. absl::optional<base::WeakPtr<VdaVideoFramePool>> weak_this,
  79. scoped_refptr<VideoFrame> frame);
  80. // Import an available frame.
  81. void ImportFrame(scoped_refptr<VideoFrame> frame);
  82. // Call |frame_available_cb_| when the pool is not exhausted.
  83. void CallFrameAvailableCbIfNeeded();
  84. // WeakPtr of VdaDelegate instance, bound at |vda_task_runner_|.
  85. base::WeakPtr<VdaDelegate> vda_;
  86. // Task runner that interacts with VdaDelegate. All VdaDelegate's methods
  87. // and their callbacks should be called on this task runner.
  88. // Note: DmabufVideoFrame's public methods like Initialize() and GetFrame()
  89. // should be called on |parent_task_runner_|.
  90. scoped_refptr<base::SequencedTaskRunner> vda_task_runner_;
  91. // The callback which is called when the pool is not exhausted.
  92. base::OnceClosure frame_available_cb_;
  93. // The layout of the frames in |frame_pool_|.
  94. absl::optional<GpuBufferLayout> layout_;
  95. // Data passed from Initialize().
  96. size_t max_num_frames_ = 0;
  97. absl::optional<Fourcc> fourcc_;
  98. gfx::Size coded_size_;
  99. gfx::Rect visible_rect_;
  100. gfx::Size natural_size_;
  101. base::queue<scoped_refptr<VideoFrame>> frame_pool_;
  102. // Sequence checker for |parent_task_runner_|.
  103. SEQUENCE_CHECKER(parent_sequence_checker_);
  104. // The weak pointer of this, bound at |parent_task_runner_|.
  105. base::WeakPtr<VdaVideoFramePool> weak_this_;
  106. base::WeakPtrFactory<VdaVideoFramePool> weak_this_factory_{this};
  107. };
  108. } // namespace media
  109. #endif // MEDIA_GPU_CHROMEOS_VDA_VIDEO_FRAME_POOL_H_