123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- // Copyright 2020 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef MEDIA_GPU_CHROMEOS_VDA_VIDEO_FRAME_POOL_H_
- #define MEDIA_GPU_CHROMEOS_VDA_VIDEO_FRAME_POOL_H_
- #include "base/containers/queue.h"
- #include "base/memory/scoped_refptr.h"
- #include "base/memory/weak_ptr.h"
- #include "base/task/sequenced_task_runner.h"
- #include "media/base/video_frame.h"
- #include "media/gpu/chromeos/chromeos_status.h"
- #include "media/gpu/chromeos/dmabuf_video_frame_pool.h"
- #include "media/gpu/chromeos/fourcc.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- namespace base {
- class WaitableEvent;
- }
- namespace media {
- class GpuBufferLayout;
- // This class is used by VdVideoDecodeAccelerator, which adapts
- // VideoDecodeAccelerator to VideoDecoder interface.
- // The mission is to allocate and manage DMA-buf VideoFrame by delegating the
- // requests of buffer allocation to a VideoDecodeAccelerator instance, and
- // provide VideoFrame to the VideoDecoder instance.
- // The communication with VdVideoDecodeAccelerator, which inherits
- // VdaDelegate, is executed on |vda_task_runner_|, and the communication with
- // VideoDecoder instance is on |parent_task_runner_|.
- class VdaVideoFramePool : public DmabufVideoFramePool {
- public:
- class VdaDelegate {
- public:
- // Callback for returning the layout of requested buffer.
- using NotifyLayoutChangedCb =
- base::OnceCallback<void(CroStatus::Or<GpuBufferLayout>)>;
- // Callback for importing available frames to this pool.
- using ImportFrameCb =
- base::RepeatingCallback<void(scoped_refptr<VideoFrame>)>;
- // Request new frames from VDA's client. VdaDelegate has to return the
- // layout of frames by calling |notify_layout_changed_cb|.
- // After that, VdaDelegate should pass frames by calling
- // |import_frame_cb|.
- // Note: RequestFrames(), |notify_layout_changed_cb|, and |import_frame_cb|
- // should be called on VdaVideoFramePool's |vda_task_runner_|.
- virtual void RequestFrames(const Fourcc& fourcc,
- const gfx::Size& coded_size,
- const gfx::Rect& visible_rect,
- size_t max_num_frames,
- NotifyLayoutChangedCb notify_layout_changed_cb,
- ImportFrameCb import_frame_cb) = 0;
- };
- VdaVideoFramePool(base::WeakPtr<VdaDelegate> vda,
- scoped_refptr<base::SequencedTaskRunner> vda_task_runner);
- ~VdaVideoFramePool() override;
- // DmabufVideoFramePool implementation.
- CroStatus::Or<GpuBufferLayout> Initialize(const Fourcc& fourcc,
- const gfx::Size& coded_size,
- const gfx::Rect& visible_rect,
- const gfx::Size& natural_size,
- size_t max_num_frames,
- bool use_protected,
- bool use_linear_buffers) override;
- scoped_refptr<VideoFrame> GetFrame() override;
- bool IsExhausted() override;
- void NotifyWhenFrameAvailable(base::OnceClosure cb) override;
- void ReleaseAllFrames() override;
- private:
- // Update the layout of the buffers. |vda_| calls this as
- // NotifyLayoutChangedCb.
- static void OnRequestFramesDone(base::WaitableEvent* done,
- CroStatus::Or<GpuBufferLayout>* layout,
- CroStatus::Or<GpuBufferLayout> layout_value);
- // Thunk to post ImportFrame() to |task_runner|.
- // Because this thunk may be called in any thread, We don't want to
- // dereference WeakPtr. Therefore we wrap the WeakPtr by absl::optional to
- // avoid the task runner defererencing the WeakPtr.
- static void ImportFrameThunk(
- scoped_refptr<base::SequencedTaskRunner> task_runner,
- absl::optional<base::WeakPtr<VdaVideoFramePool>> weak_this,
- scoped_refptr<VideoFrame> frame);
- // Import an available frame.
- void ImportFrame(scoped_refptr<VideoFrame> frame);
- // Call |frame_available_cb_| when the pool is not exhausted.
- void CallFrameAvailableCbIfNeeded();
- // WeakPtr of VdaDelegate instance, bound at |vda_task_runner_|.
- base::WeakPtr<VdaDelegate> vda_;
- // Task runner that interacts with VdaDelegate. All VdaDelegate's methods
- // and their callbacks should be called on this task runner.
- // Note: DmabufVideoFrame's public methods like Initialize() and GetFrame()
- // should be called on |parent_task_runner_|.
- scoped_refptr<base::SequencedTaskRunner> vda_task_runner_;
- // The callback which is called when the pool is not exhausted.
- base::OnceClosure frame_available_cb_;
- // The layout of the frames in |frame_pool_|.
- absl::optional<GpuBufferLayout> layout_;
- // Data passed from Initialize().
- size_t max_num_frames_ = 0;
- absl::optional<Fourcc> fourcc_;
- gfx::Size coded_size_;
- gfx::Rect visible_rect_;
- gfx::Size natural_size_;
- base::queue<scoped_refptr<VideoFrame>> frame_pool_;
- // Sequence checker for |parent_task_runner_|.
- SEQUENCE_CHECKER(parent_sequence_checker_);
- // The weak pointer of this, bound at |parent_task_runner_|.
- base::WeakPtr<VdaVideoFramePool> weak_this_;
- base::WeakPtrFactory<VdaVideoFramePool> weak_this_factory_{this};
- };
- } // namespace media
- #endif // MEDIA_GPU_CHROMEOS_VDA_VIDEO_FRAME_POOL_H_
|