xref: /aosp_15_r20/external/v4l2_codec2/v4l2/include/v4l2_codec2/v4l2/V4L2Decoder.h (revision 0ec5a0ec62797f775085659156625e7f1bdb369f)
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