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_V4L2_DECODER_H 6 #define ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_DECODER_H 7 8 #include <stdint.h> 9 10 #include <memory> 11 #include <optional> 12 13 #include <base/callback.h> 14 #include <base/memory/weak_ptr.h> 15 16 #include <ui/Rect.h> 17 #include <ui/Size.h> 18 #include <v4l2_codec2/common/V4L2Device.h> 19 #include <v4l2_codec2/common/VideoTypes.h> 20 #include <v4l2_codec2/components/VideoDecoder.h> 21 #include <v4l2_codec2/components/VideoFrame.h> 22 #include <v4l2_codec2/components/VideoFramePool.h> 23 24 namespace android { 25 26 class V4L2Decoder : public VideoDecoder { 27 public: 28 static std::unique_ptr<VideoDecoder> Create( 29 const VideoCodec& codec, const size_t inputBufferSize, const size_t minNumOutputBuffers, 30 GetPoolCB getPoolCB, OutputCB outputCb, ErrorCB errorCb, 31 scoped_refptr<::base::SequencedTaskRunner> taskRunner); 32 ~V4L2Decoder() override; 33 34 void decode(std::unique_ptr<ConstBitstreamBuffer> buffer, DecodeCB decodeCb) override; 35 void drain(DecodeCB drainCb) override; 36 void flush() override; 37 38 private: 39 enum class State { 40 Idle, // Not received any decode buffer after initialized, flushed, or drained. 41 Decoding, 42 Draining, 43 Error, 44 }; 45 static const char* StateToString(State state); 46 47 struct DecodeRequest { DecodeRequestDecodeRequest48 DecodeRequest(std::unique_ptr<ConstBitstreamBuffer> buffer, DecodeCB decodeCb) 49 : buffer(std::move(buffer)), decodeCb(std::move(decodeCb)) {} 50 DecodeRequest(DecodeRequest&&) = default; 51 ~DecodeRequest() = default; 52 53 std::unique_ptr<ConstBitstreamBuffer> buffer; // nullptr means Drain 54 DecodeCB decodeCb; 55 }; 56 57 V4L2Decoder(scoped_refptr<::base::SequencedTaskRunner> taskRunner); 58 bool start(const VideoCodec& codec, const size_t inputBufferSize, 59 const size_t minNumOutputBuffers, GetPoolCB getPoolCb, OutputCB outputCb, 60 ErrorCB errorCb); 61 bool setupInputFormat(const uint32_t inputPixelFormat, const size_t inputBufferSize); 62 void pumpDecodeRequest(); 63 64 void serviceDeviceTask(bool event); 65 bool dequeueResolutionChangeEvent(); 66 bool changeResolution(); 67 bool setupOutputFormat(const ui::Size& size); 68 69 void tryFetchVideoFrame(); 70 void onVideoFrameReady(std::optional<VideoFramePool::FrameWithBlockId> frameWithBlockId); 71 72 std::optional<size_t> getNumOutputBuffers(); 73 std::optional<struct v4l2_format> getFormatInfo(); 74 Rect getVisibleRect(const ui::Size& codedSize); 75 bool sendV4L2DecoderCmd(bool start); 76 77 void setState(State newState); 78 void onError(); 79 80 std::unique_ptr<VideoFramePool> mVideoFramePool; 81 82 scoped_refptr<V4L2Device> mDevice; 83 scoped_refptr<V4L2Queue> mInputQueue; 84 scoped_refptr<V4L2Queue> mOutputQueue; 85 86 std::queue<DecodeRequest> mDecodeRequests; 87 std::map<int32_t, DecodeCB> mPendingDecodeCbs; 88 89 size_t mMinNumOutputBuffers = 0; 90 GetPoolCB mGetPoolCb; 91 OutputCB mOutputCb; 92 DecodeCB mDrainCb; 93 ErrorCB mErrorCb; 94 95 ui::Size mCodedSize; 96 Rect mVisibleRect; 97 98 std::map<size_t, std::unique_ptr<VideoFrame>> mFrameAtDevice; 99 100 // Block IDs can be arbitrarily large, but we only have a limited number of 101 // buffers. This maintains an association between a block ID and a specific 102 // V4L2 buffer index. 103 std::map<size_t, size_t> mBlockIdToV4L2Id; 104 105 State mState = State::Idle; 106 107 scoped_refptr<::base::SequencedTaskRunner> mTaskRunner; 108 109 ::base::WeakPtr<V4L2Decoder> mWeakThis; 110 ::base::WeakPtrFactory<V4L2Decoder> mWeakThisFactory{this}; 111 }; 112 113 } // namespace android 114 115 #endif // ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_DECODER_H 116