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 #include <ui/Size.h> 19 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, const ui::Size& size, 35 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 // |maxBufferCount| maximum number of buffer that should should provide to client 48 // |size| is the resolution size of the required graphic blocks. 49 // |pixelFormat| is the pixel format of the required graphic blocks. 50 // |isSecure| indicates the video stream is encrypted or not. 51 // All public methods and the callbacks should be run on |taskRunner|. 52 VideoFramePool(std::shared_ptr<C2BlockPool> blockPool, const size_t maxBufferCount, 53 const ui::Size& size, HalPixelFormat pixelFormat, C2MemoryUsage memoryUsage, 54 scoped_refptr<::base::SequencedTaskRunner> taskRunner); 55 bool initialize(); 56 void destroyTask(); 57 58 static void getVideoFrameTaskThunk(scoped_refptr<::base::SequencedTaskRunner> taskRunner, 59 std::optional<::base::WeakPtr<VideoFramePool>> weakPool); 60 void getVideoFrameTask(); 61 void onVideoFrameReady(std::optional<FrameWithBlockId> frameWithBlockId); 62 63 // Returns true if a buffer shall not be handed to client. 64 bool shouldDropBuffer(uint32_t bufferId); 65 66 static std::optional<uint32_t> getBufferIdFromGraphicBlock(C2BlockPool& blockPool, 67 const C2Block2D& block); 68 69 std::shared_ptr<C2BlockPool> mBlockPool; 70 71 // Holds the number of maximum amount of buffers that VideoFramePool 72 // should provide to client. 73 size_t mMaxBufferCount; 74 // Contains known buffer ids that are valid for the pool. 75 std::set<uint32_t> mBuffers; 76 77 const ui::Size mSize; 78 const HalPixelFormat mPixelFormat; 79 const C2MemoryUsage mMemoryUsage; 80 81 GetVideoFrameCB mOutputCb; 82 83 scoped_refptr<::base::SequencedTaskRunner> mClientTaskRunner; 84 ::base::Thread mFetchThread{"VideoFramePoolFetchThread"}; 85 scoped_refptr<::base::SequencedTaskRunner> mFetchTaskRunner; 86 87 ::base::WeakPtr<VideoFramePool> mClientWeakThis; 88 ::base::WeakPtr<VideoFramePool> mFetchWeakThis; 89 ::base::WeakPtrFactory<VideoFramePool> mClientWeakThisFactory{this}; 90 ::base::WeakPtrFactory<VideoFramePool> mFetchWeakThisFactory{this}; 91 }; 92 93 } // namespace android 94 95 #endif // ANDROID_V4L2_CODEC2_COMPONENTS_VIDEO_FRAME_POOL_H 96