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_V4L2_V4L2_DECODER_H 6 #define ANDROID_V4L2_CODEC2_V4L2_V4L2_DECODER_H 7 8 #include <stdint.h> 9 10 #include <cstdint> 11 #include <memory> 12 #include <optional> 13 #include <utility> 14 15 #include <base/callback.h> 16 #include <base/memory/weak_ptr.h> 17 18 #include <ui/GraphicBuffer.h> 19 #include <ui/Rect.h> 20 #include <ui/Size.h> 21 #include <v4l2_codec2/common/Fourcc.h> 22 #include <v4l2_codec2/common/VideoTypes.h> 23 #include <v4l2_codec2/components/VideoDecoder.h> 24 #include <v4l2_codec2/components/VideoFrame.h> 25 #include <v4l2_codec2/components/VideoFramePool.h> 26 #include <v4l2_codec2/plugin_store/DmabufHelpers.h> 27 #include <v4l2_codec2/v4l2/V4L2Device.h> 28 29 namespace android { 30 31 // Currently we only support flexible pixel 420 format YCBCR_420_888 in Android. 32 // Here is the list of flexible 420 format. 33 constexpr std::initializer_list<uint32_t> kSupportedOutputFourccs = { 34 Fourcc::YU12, Fourcc::YV12, Fourcc::YM12, Fourcc::YM21, 35 Fourcc::NV12, Fourcc::NV21, Fourcc::NM12, Fourcc::NM21, 36 }; 37 38 class V4L2Decoder : public VideoDecoder { 39 public: 40 static std::unique_ptr<VideoDecoder> Create( 41 uint32_t debugStreamId, const VideoCodec& codec, const size_t inputBufferSize, 42 const size_t minNumOutputBuffers, GetPoolCB getPoolCB, OutputCB outputCb, 43 ErrorCB errorCb, scoped_refptr<::base::SequencedTaskRunner> taskRunner, bool isSecure); 44 ~V4L2Decoder() override; 45 46 void decode(std::unique_ptr<ConstBitstreamBuffer> buffer, DecodeCB decodeCb) override; 47 void drain(DecodeCB drainCb) override; 48 void flush() override; 49 50 private: 51 static constexpr size_t kNumInputBuffers = 16; 52 53 enum class State { 54 Idle, // Not received any decode buffer after initialized, flushed, or drained. 55 Decoding, 56 Draining, 57 Error, 58 }; 59 static const char* StateToString(State state); 60 61 struct DecodeRequest { DecodeRequestDecodeRequest62 DecodeRequest(std::unique_ptr<ConstBitstreamBuffer> buffer, DecodeCB decodeCb) 63 : buffer(std::move(buffer)), decodeCb(std::move(decodeCb)) {} 64 DecodeRequest(DecodeRequest&&) = default; 65 ~DecodeRequest() = default; 66 67 std::unique_ptr<ConstBitstreamBuffer> buffer; // nullptr means Drain 68 DecodeCB decodeCb; 69 }; 70 71 V4L2Decoder(uint32_t debugStreamId, scoped_refptr<::base::SequencedTaskRunner> taskRunner); 72 bool start(const VideoCodec& codec, const size_t inputBufferSize, 73 const size_t minNumOutputBuffers, GetPoolCB getPoolCb, OutputCB outputCb, 74 ErrorCB errorCb, bool isSecure); 75 bool setupInputFormat(const uint32_t inputPixelFormat, const size_t inputBufferSize); 76 77 // Sets minimal resolution and allocates minimal amount of output buffers for 78 // drain done signaling. 79 bool setupInitialOutput(); 80 // Find the first output format and sets output to its minimal resolution. 81 bool setupMinimalOutputFormat(); 82 // Allocates the at least |minOutputBuffersCount| of output buffers using set format 83 bool startOutputQueue(size_t minOutputBuffersCount, enum v4l2_memory memory); 84 85 void pumpDecodeRequest(); 86 87 void serviceDeviceTask(bool event); 88 bool dequeueResolutionChangeEvent(); 89 bool changeResolution(); 90 bool setupOutputFormat(const ui::Size& size); 91 92 void tryFetchVideoFrame(); 93 void onVideoFrameReady(std::optional<VideoFramePool::FrameWithBlockId> frameWithBlockId); 94 95 std::optional<size_t> getNumOutputBuffers(); 96 std::optional<struct v4l2_format> getFormatInfo(); 97 Rect getVisibleRect(const ui::Size& codedSize); 98 bool sendV4L2DecoderCmd(bool start); 99 100 void setState(State newState); 101 void onError(); 102 103 uint32_t mDebugStreamId; 104 105 std::unique_ptr<VideoFramePool> mVideoFramePool; 106 107 scoped_refptr<V4L2Device> mDevice; 108 scoped_refptr<V4L2Queue> mInputQueue; 109 scoped_refptr<V4L2Queue> mOutputQueue; 110 111 // Contains the initial EOS buffer, until DRC event is dequeued. 112 sp<GraphicBuffer> mInitialEosBuffer; 113 114 std::queue<DecodeRequest> mDecodeRequests; 115 std::map<int32_t, DecodeCB> mPendingDecodeCbs; 116 // Marks that we need to wait for DRC before drain can complete. 117 bool mPendingDRC = false; 118 // Holds information about secure playback, which won't allow decoder to 119 // access frames in order to provide extra meta information (like checking 120 // for pending DRC). 121 bool mIsSecure; 122 VideoCodec mCodec; 123 124 // Tracks the last DMA buffer ID which was used for a given V4L2 input 125 // buffer ID. Used to try to avoid re-importing buffers. 126 unique_id_t mLastDmaBufferId[kNumInputBuffers]; 127 128 // The next input buffer ID to allocate. Note that since we don't un-allocate 129 // ids, all entries less than this in mLastDmaBufferId are valid. 130 size_t mNextInputBufferId = 0; 131 132 size_t mMinNumOutputBuffers = 0; 133 GetPoolCB mGetPoolCb; 134 OutputCB mOutputCb; 135 DecodeCB mDrainCb; 136 ErrorCB mErrorCb; 137 138 ui::Size mCodedSize; 139 Rect mVisibleRect; 140 141 // Currently enqueued frame at the deocder device, mapped using V4L2 buffer ID. 142 std::map<size_t, std::unique_ptr<VideoFrame>> mFrameAtDevice; 143 144 // A queue of previously enqueued frames, that were returned during flush 145 // (STREAMOFF). Those frames will be reused as soon as `tryFetchVideoFrame` 146 // is called. This is a workaround for b/297228544 and helps with general 147 // responsiveness of the video playback due to b/270003218. 148 std::queue<std::pair<size_t, std::unique_ptr<VideoFrame>>> mReuseFrameQueue; 149 150 // Block IDs can be arbitrarily large, but we only have a limited number of 151 // buffers. This maintains an association between a block ID and a specific 152 // V4L2 buffer index. 153 std::map<size_t, size_t> mBlockIdToV4L2Id; 154 155 State mState = State::Idle; 156 157 scoped_refptr<::base::SequencedTaskRunner> mTaskRunner; 158 159 ::base::WeakPtr<V4L2Decoder> mWeakThis; 160 ::base::WeakPtrFactory<V4L2Decoder> mWeakThisFactory{this}; 161 }; 162 163 } // namespace android 164 165 #endif // ANDROID_V4L2_CODEC2_V4L2_V4L2_DECODER_H 166