xref: /aosp_15_r20/external/v4l2_codec2/components/include/v4l2_codec2/components/EncodeComponent.h (revision 0ec5a0ec62797f775085659156625e7f1bdb369f)
1 // Copyright 2023 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_ENCODE_COMPONENT_H
6 #define ANDROID_V4L2_CODEC2_COMPONENTS_ENCODE_COMPONENT_H
7 
8 #include <atomic>
9 #include <limits>
10 #include <memory>
11 #include <optional>
12 #include <unordered_map>
13 #include <vector>
14 
15 #include <C2Component.h>
16 #include <C2ComponentFactory.h>
17 #include <C2Config.h>
18 #include <C2Enum.h>
19 #include <C2Param.h>
20 #include <C2ParamDef.h>
21 #include <SimpleC2Interface.h>
22 #include <base/memory/scoped_refptr.h>
23 #include <base/single_thread_task_runner.h>
24 #include <base/synchronization/waitable_event.h>
25 #include <base/threading/thread.h>
26 #include <util/C2InterfaceHelper.h>
27 #include <v4l2_codec2/common/Common.h>
28 #include <v4l2_codec2/common/VideoPixelFormat.h>
29 
30 namespace android {
31 
32 struct BitstreamBuffer;
33 class FormatConverter;
34 class VideoEncoder;
35 class EncodeInterface;
36 
37 std::optional<std::vector<VideoFramePlane>> getVideoFrameLayout(const C2ConstGraphicBlock& block,
38                                                                 VideoPixelFormat* format);
39 
40 std::optional<uint32_t> getVideoFrameStride(VideoPixelFormat format, ui::Size size);
41 
42 class EncodeComponent : public C2Component, public std::enable_shared_from_this<EncodeComponent> {
43 public:
44     virtual ~EncodeComponent() override;
45 
46     // Implementation of the C2Component interface.
47     c2_status_t start() override;
48     c2_status_t stop() override;
49     c2_status_t reset() override;
50     c2_status_t release() override;
51     c2_status_t queue_nb(std::list<std::unique_ptr<C2Work>>* const items) override;
52     c2_status_t drain_nb(drain_mode_t mode) override;
53     c2_status_t flush_sm(flush_mode_t mode,
54                          std::list<std::unique_ptr<C2Work>>* const flushedWork) override;
55     c2_status_t announce_nb(const std::vector<C2WorkOutline>& items) override;
56     c2_status_t setListener_vb(const std::shared_ptr<Listener>& listener,
57                                c2_blocking_t mayBlock) override;
58     std::shared_ptr<C2ComponentInterface> intf() override;
59 
60 protected:
61     // Possible component states.
62     enum class ComponentState {
63         UNLOADED,  // Initial state of component.
64         LOADED,    // The component is stopped, ready to start running.
65         RUNNING,   // The component is currently running.
66         ERROR,     // An error occurred.
67     };
68 
69     EncodeComponent(C2String name, c2_node_id_t id, std::shared_ptr<EncodeInterface> interface);
70 
71     EncodeComponent(const EncodeComponent&) = delete;
72     EncodeComponent& operator=(const EncodeComponent&) = delete;
73 
74     // Initialize the V4L2 device for encoding with the requested configuration.
75     virtual bool initializeEncoder() = 0;
76 
77     // Initialize the encoder on the encoder thread.
78     void startTask(bool* success, ::base::WaitableEvent* done);
79     // Destroy the encoder on the encoder thread.
80     void stopTask(::base::WaitableEvent* done);
81     // Queue a new encode work item on the encoder thread.
82     void queueTask(std::unique_ptr<C2Work> work);
83     // Drain all currently scheduled work on the encoder thread. The encoder will process all
84     // scheduled work and mark the last item as EOS, before processing any new work.
85     void drainTask(drain_mode_t drainMode);
86     // Called on the encoder thread when a drain is completed.
87     void onDrainDone(bool success);
88     // Flush all currently scheduled work on the encoder thread. The encoder will abort all
89     // scheduled work items, work that can be immediately aborted will be placed in |flushedWork|.
90     void flushTask(::base::WaitableEvent* done,
91                    std::list<std::unique_ptr<C2Work>>* const flushedWork);
92     // Set the component listener on the encoder thread.
93     void setListenerTask(const std::shared_ptr<Listener>& listener, ::base::WaitableEvent* done);
94 
95     // Update the |mBitrate| and |mFramerate| currently configured on the V4L2 device, to match the
96     // values requested by the codec 2.0 framework.
97     bool updateEncodingParameters();
98 
99     // Schedule the next encode operation on the V4L2 device.
100     void scheduleNextEncodeTask();
101     // Encode the specified |block| with corresponding |index| and |timestamp|.
102     bool encode(C2ConstGraphicBlock block, uint64_t index, int64_t timestamp);
103     // Flush the encoder.
104     void flush();
105 
106     // Fetch a new output buffer from the output block pool with specified |size|.
107     void fetchOutputBlock(uint32_t size, std::unique_ptr<BitstreamBuffer>* buffer);
108 
109     // Called on the encoder thread when the encoder is done using an input buffer.
110     void onInputBufferDone(uint64_t index);
111     // Called on the encoder thread when an output buffer is ready.
112     void onOutputBufferDone(size_t dataSize, int64_t timestamp, bool keyFrame,
113                             std::unique_ptr<BitstreamBuffer> buffer);
114 
115     // Helper function to find a work item in the output work queue by index.
116     C2Work* getWorkByIndex(uint64_t index);
117     // Helper function to find a work item in the output work queue by timestamp.
118     C2Work* getWorkByTimestamp(int64_t timestamp);
119     // Helper function to determine if the specified |work| item is finished.
120     bool isWorkDone(const C2Work& work) const;
121     // Notify the listener the specified |work| item is finished.
122     void reportWork(std::unique_ptr<C2Work> work);
123 
124     // Configure the c2 block pool that will be used to create output buffers.
125     bool getBlockPool();
126 
127     // Notify the client an error occurred and switch to the error state.
128     void reportError(c2_status_t error);
129 
130     // Change the state of the component.
131     void setComponentState(ComponentState state);
132     // Get the specified component |state| as string.
133     static const char* componentStateToString(ComponentState state);
134 
135     // The underlying V4L2 encoder.
136     std::unique_ptr<VideoEncoder> mEncoder;
137 
138     // The component's registered name.
139     const C2String mName;
140     // The component's id, provided by the C2 framework upon initialization.
141     const c2_node_id_t mId = 0;
142     // The component's interface implementation.
143     const std::shared_ptr<EncodeInterface> mInterface;
144 
145     // Mutex used by the component to synchronize start/stop/reset/release calls, as the codec 2.0
146     // API can be accessed from any thread.
147     std::mutex mComponentLock;
148 
149     // The component's listener to be notified when events occur, only accessed on encoder thread.
150     std::shared_ptr<Listener> mListener;
151 
152     // The queue of encode work items waiting for free buffers in the input convertor.
153     std::queue<std::unique_ptr<C2Work>> mInputConverterQueue;
154     // An input format convertor will be used if the device doesn't support the video's format.
155     std::unique_ptr<FormatConverter> mInputFormatConverter;
156 
157     // Pixel format of frames sent to V4L2 encoder, determined when the first input frame is queued.
158     VideoPixelFormat mInputPixelFormat = VideoPixelFormat::UNKNOWN;
159     // Layout of frames sent to V4L2 encoder, determined when the first input frame is queued.
160     std::vector<VideoFramePlane> mInputLayout;
161 
162     // The bitrate currently configured on the v4l2 device.
163     uint32_t mBitrate = 0;
164     // The bitrate mode currently configured on the v4l2 device.
165     C2Config::bitrate_mode_t mBitrateMode = C2Config::BITRATE_CONST;
166     // The framerate currently configured on the v4l2 device.
167     uint32_t mFramerate = 0;
168     // Maximum valid framerate for current output level and input frame size.
169     uint32_t mMaxFramerate = std::numeric_limits<uint32_t>::max();
170     // The timestamp of the last frame encoded, used to dynamically adjust the framerate.
171     std::optional<int64_t> mLastFrameTime;
172 
173     // Whether we need to extract and submit CSD (codec-specific data, e.g. H.264 SPS).
174     bool mExtractCSD = false;
175 
176     // The queue of encode work items currently being processed.
177     std::deque<std::unique_ptr<C2Work>> mWorkQueue;
178 
179     // The output block pool.
180     std::shared_ptr<C2BlockPool> mOutputBlockPool;
181 
182     // The component state, accessible from any thread as C2Component interface is not thread-safe.
183     std::atomic<ComponentState> mComponentState;
184 
185     // The encoder thread on which all interaction with the V4L2 device is performed.
186     ::base::Thread mEncoderThread{"EncodeComponentThread"};
187     // The task runner on the encoder thread.
188     scoped_refptr<::base::SequencedTaskRunner> mEncoderTaskRunner;
189 
190     // The WeakPtrFactory used to get weak pointers of this.
191     ::base::WeakPtr<EncodeComponent> mWeakThis;
192     ::base::WeakPtrFactory<EncodeComponent> mWeakThisFactory{this};
193 };
194 
195 }  // namespace android
196 
197 #endif  // ANDROID_V4L2_CODEC2_COMPONENTS_ENCODE_COMPONENT_H
198