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 <rect.h> 17 #include <size.h> 18 #include <v4l2_codec2/common/VideoTypes.h> 19 #include <v4l2_codec2/components/VideoDecoder.h> 20 #include <v4l2_codec2/components/VideoFrame.h> 21 #include <v4l2_codec2/components/VideoFramePool.h> 22 #include <v4l2_device.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, GetPoolCB getPoolCB, 30 OutputCB outputCb, ErrorCB errorCb, 31 scoped_refptr<::base::SequencedTaskRunner> taskRunner); 32 ~V4L2Decoder() override; 33 34 void decode(std::unique_ptr<BitstreamBuffer> 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<BitstreamBuffer> buffer, DecodeCB decodeCb) 49 : buffer(std::move(buffer)), decodeCb(std::move(decodeCb)) {} 50 DecodeRequest(DecodeRequest&&) = default; 51 ~DecodeRequest() = default; 52 DecodeRequest& operator=(DecodeRequest&&); 53 54 std::unique_ptr<BitstreamBuffer> buffer; // nullptr means Drain 55 DecodeCB decodeCb; 56 }; 57 58 V4L2Decoder(scoped_refptr<::base::SequencedTaskRunner> taskRunner); 59 bool start(const VideoCodec& codec, const size_t inputBufferSize, GetPoolCB getPoolCb, 60 OutputCB outputCb, 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 68 void tryFetchVideoFrame(); 69 void onVideoFrameReady(std::optional<VideoFramePool::FrameWithBlockId> frameWithBlockId); 70 71 std::optional<size_t> getNumOutputBuffers(); 72 std::optional<struct v4l2_format> getFormatInfo(); 73 media::Rect getVisibleRect(const media::Size& codedSize); 74 bool sendV4L2DecoderCmd(bool start); 75 76 void setState(State newState); 77 void onError(); 78 79 std::unique_ptr<VideoFramePool> mVideoFramePool; 80 81 scoped_refptr<media::V4L2Device> mDevice; 82 scoped_refptr<media::V4L2Queue> mInputQueue; 83 scoped_refptr<media::V4L2Queue> mOutputQueue; 84 85 std::queue<DecodeRequest> mDecodeRequests; 86 std::map<int32_t, DecodeCB> mPendingDecodeCbs; 87 88 GetPoolCB mGetPoolCb; 89 OutputCB mOutputCb; 90 DecodeCB mDrainCb; 91 ErrorCB mErrorCb; 92 93 media::Size mCodedSize; 94 media::Rect mVisibleRect; 95 96 std::map<size_t, std::unique_ptr<VideoFrame>> mFrameAtDevice; 97 98 // Block IDs can be arbitrarily large, but we only have a limited number of 99 // buffers. This maintains an association between a block ID and a specific 100 // V4L2 buffer index. 101 std::map<size_t, size_t> mBlockIdToV4L2Id; 102 103 State mState = State::Idle; 104 105 scoped_refptr<::base::SequencedTaskRunner> mTaskRunner; 106 107 ::base::WeakPtr<V4L2Decoder> mWeakThis; 108 ::base::WeakPtrFactory<V4L2Decoder> mWeakThisFactory{this}; 109 }; 110 111 } // namespace android 112 113 #endif // ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_DECODER_H 114