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 5 #ifndef ANDROID_V4L2_CODEC2_COMPONENTS_VIDEO_FRAME_POOL_H 6 #define ANDROID_V4L2_CODEC2_COMPONENTS_VIDEO_FRAME_POOL_H 7 8 #include <atomic> 9 #include <memory> 10 #include <optional> 11 #include <queue> 12 13 #include <C2Buffer.h> 14 #include <base/callback.h> 15 #include <base/memory/weak_ptr.h> 16 #include <base/sequenced_task_runner.h> 17 #include <base/threading/thread.h> 18 19 #include <size.h> 20 #include <v4l2_codec2/common/VideoTypes.h> 21 #include <v4l2_codec2/components/VideoFrame.h> 22 23 namespace android { 24 25 // Fetch C2GraphicBlock from C2BlockPool and wrap to VideoFrame. 26 // Provide asynchronous call which avoid the caller busy-polling while 27 // C2BlockPool::fetchGraphicBlock() times out. 28 class VideoFramePool { 29 public: 30 using FrameWithBlockId = std::pair<std::unique_ptr<VideoFrame>, uint32_t>; 31 using GetVideoFrameCB = ::base::OnceCallback<void(std::optional<FrameWithBlockId>)>; 32 33 static std::unique_ptr<VideoFramePool> Create( 34 std::shared_ptr<C2BlockPool> blockPool, const size_t numBuffers, 35 const media::Size& size, HalPixelFormat pixelFormat, bool isSecure, 36 scoped_refptr<::base::SequencedTaskRunner> taskRunner); 37 ~VideoFramePool(); 38 39 // Get a VideoFrame instance, which will be passed via |cb|. 40 // If any error occurs, then nullptr will be passed via |cb|. 41 // Return false if the previous callback has not been called, and |cb| will 42 // be dropped directly. 43 bool getVideoFrame(GetVideoFrameCB cb); 44 45 private: 46 // |blockPool| is the C2BlockPool that we fetch graphic blocks from. 47 // |size| is the resolution size of the required graphic blocks. 48 // |pixelFormat| is the pixel format of the required graphic blocks. 49 // |isSecure| indicates the video stream is encrypted or not. 50 // All public methods and the callbacks should be run on |taskRunner|. 51 VideoFramePool(std::shared_ptr<C2BlockPool> blockPool, const media::Size& size, 52 HalPixelFormat pixelFormat, bool isSecure, 53 scoped_refptr<::base::SequencedTaskRunner> taskRunner); 54 bool initialize(); 55 void destroyTask(); 56 57 static void getVideoFrameTaskThunk(scoped_refptr<::base::SequencedTaskRunner> taskRunner, 58 std::optional<::base::WeakPtr<VideoFramePool>> weakPool); 59 void getVideoFrameTask(); 60 void onVideoFrameReady(std::optional<FrameWithBlockId> frameWithBlockId); 61 62 // Extracts buffer ID from graphic block. 63 // |block| is the graphic block allocated by |blockPool|. 64 static std::optional<uint32_t> getBufferIdFromGraphicBlock(const C2BlockPool& blockPool, 65 const C2Block2D& block); 66 67 // Ask |blockPool| to allocate the specified number of buffers. 68 // |bufferCount| is the number of requested buffers. 69 static c2_status_t requestNewBufferSet(C2BlockPool& blockPool, int32_t bufferCount); 70 71 // Ask |blockPool| to notify when a block is available via |cb|. 72 // Return true if |blockPool| supports notifying buffer available. 73 static bool setNotifyBlockAvailableCb(C2BlockPool& blockPool, ::base::OnceClosure cb); 74 75 std::shared_ptr<C2BlockPool> mBlockPool; 76 const media::Size mSize; 77 const HalPixelFormat mPixelFormat; 78 const C2MemoryUsage mMemoryUsage; 79 80 GetVideoFrameCB mOutputCb; 81 82 scoped_refptr<::base::SequencedTaskRunner> mClientTaskRunner; 83 ::base::Thread mFetchThread{"VideoFramePoolFetchThread"}; 84 scoped_refptr<::base::SequencedTaskRunner> mFetchTaskRunner; 85 86 ::base::WeakPtr<VideoFramePool> mClientWeakThis; 87 ::base::WeakPtr<VideoFramePool> mFetchWeakThis; 88 ::base::WeakPtrFactory<VideoFramePool> mClientWeakThisFactory{this}; 89 ::base::WeakPtrFactory<VideoFramePool> mFetchWeakThisFactory{this}; 90 }; 91 92 } // namespace android 93 94 #endif // ANDROID_V4L2_CODEC2_COMPONENTS_VIDEO_FRAME_POOL_H 95