• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 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_ENCODER_H
6 #define ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_ENCODER_H
7 
8 #include <stdint.h>
9 #include <memory>
10 #include <optional>
11 #include <queue>
12 #include <vector>
13 
14 #include <base/memory/weak_ptr.h>
15 #include <base/sequenced_task_runner.h>
16 #include <ui/Size.h>
17 
18 #include <v4l2_codec2/common/Common.h>
19 #include <v4l2_codec2/components/VideoEncoder.h>
20 
21 namespace android {
22 
23 struct BitstreamBuffer;
24 struct VideoFramePlane;
25 class V4L2Device;
26 class V4L2Queue;
27 
28 class V4L2Encoder : public VideoEncoder {
29 public:
30     // Number of buffers on V4L2 device queues.
31     static constexpr size_t kInputBufferCount = 2;
32     static constexpr size_t kOutputBufferCount = 2;
33 
34     static std::unique_ptr<VideoEncoder> create(
35             C2Config::profile_t profile, std::optional<uint8_t> level, const ui::Size& visibleSize,
36             uint32_t stride, uint32_t keyFramePeriod, C2Config::bitrate_mode_t bitrateMode,
37             uint32_t bitrate, std::optional<uint32_t> peakBitrate,
38             FetchOutputBufferCB fetchOutputBufferCb, InputBufferDoneCB inputBufferDoneCb,
39             OutputBufferDoneCB outputBufferDoneCb, DrainDoneCB drainDoneCb, ErrorCB errorCb,
40             scoped_refptr<::base::SequencedTaskRunner> taskRunner);
41     ~V4L2Encoder() override;
42 
43     bool encode(std::unique_ptr<InputFrame> frame) override;
44     void drain() override;
45     void flush() override;
46 
47     bool setBitrate(uint32_t bitrate) override;
48     bool setPeakBitrate(uint32_t peakBitrate) override;
49     bool setFramerate(uint32_t framerate) override;
50     void requestKeyframe() override;
51 
52     VideoPixelFormat inputFormat() const override;
visibleSize()53     const ui::Size& visibleSize() const override { return mVisibleSize; }
codedSize()54     const ui::Size& codedSize() const override { return mInputCodedSize; }
55 
56 private:
57     // Possible encoder states.
58     enum class State {
59         UNINITIALIZED,            // Not initialized yet or initialization failed.
60         WAITING_FOR_INPUT_FRAME,  // Waiting for frames to be queued.
61         WAITING_FOR_V4L2_BUFFER,  // Waiting for V4L2 input queue buffers.
62         ENCODING,                 // Queuing input buffers.
63         DRAINING,                 // Draining encoder.
64         ERROR,                    // Encoder encountered an error.
65     };
66 
67     // Contains a single encode request.
68     struct EncodeRequest {
EncodeRequestEncodeRequest69         EncodeRequest(std::unique_ptr<InputFrame> video_frame)
70               : video_frame(std::move(video_frame)) {}
71         ~EncodeRequest() = default;
72         EncodeRequest(EncodeRequest&&) = default;
73         EncodeRequest& operator=(EncodeRequest&&) = default;
74 
75         std::unique_ptr<InputFrame> video_frame;
76         bool end_of_stream = false;
77     };
78 
79     V4L2Encoder(scoped_refptr<::base::SequencedTaskRunner> taskRunner,
80                 FetchOutputBufferCB fetchOutputBufferCb, InputBufferDoneCB mInputBufferDoneCb,
81                 OutputBufferDoneCB mOutputBufferDoneCb, DrainDoneCB drainDoneCb, ErrorCB errorCb);
82 
83     // Initialize the V4L2 encoder for specified parameters.
84     bool initialize(C2Config::profile_t outputProfile, std::optional<uint8_t> level,
85                     const ui::Size& visibleSize, uint32_t stride, uint32_t keyFramePeriod,
86                     C2Config::bitrate_mode_t bitrateMode, uint32_t bitrate,
87                     std::optional<uint32_t> peakBitrate);
88 
89     // Handle the next encode request on the queue.
90     void handleEncodeRequest();
91     // Handle a request to flush the encoder.
92     void handleFlushRequest();
93     // Handle a request to drain the encoder.
94     void handleDrainRequest();
95     // Called when draining the encoder has completed.
96     void onDrainDone(bool done);
97 
98     // Configure input format on the V4L2 device.
99     bool configureInputFormat(VideoPixelFormat inputFormat, uint32_t stride);
100     // Configure output format on the V4L2 device.
101     bool configureOutputFormat(C2Config::profile_t outputProfile);
102     // Configure required and optional controls on the V4L2 device.
103     bool configureDevice(C2Config::profile_t outputProfile,
104                          std::optional<const uint8_t> outputH264Level);
105     // Configure required and optional H.264 controls on the V4L2 device.
106     bool configureH264(C2Config::profile_t outputProfile,
107                        std::optional<const uint8_t> outputH264Level);
108     // Configure the specified bitrate mode on the V4L2 device.
109     bool configureBitrateMode(C2Config::bitrate_mode_t bitrateMode);
110 
111     // Attempt to start the V4L2 device poller.
112     bool startDevicePoll();
113     // Attempt to stop the V4L2 device poller.
114     bool stopDevicePoll();
115     // Called by the V4L2 device poller whenever an error occurred.
116     void onPollError();
117     // Service I/O on the V4L2 device, called by the V4L2 device poller.
118     void serviceDeviceTask(bool event);
119 
120     // Enqueue an input buffer to be encoded on the device input queue. Returns whether the
121     // operation was successful.
122     bool enqueueInputBuffer(std::unique_ptr<InputFrame> frame);
123     // Enqueue an output buffer to store the encoded bitstream on the device output queue. Returns
124     // whether the operation was successful.
125     bool enqueueOutputBuffer();
126     // Dequeue an input buffer the V4L2 device has finished encoding on the device input queue.
127     // Returns whether a buffer could be dequeued.
128     bool dequeueInputBuffer();
129     // Dequeue an output buffer containing the encoded bitstream from the device output queue.
130     // Returns whether the operation was successful.
131     bool dequeueOutputBuffer();
132 
133     // Create input buffers on the V4L2 device input queue.
134     bool createInputBuffers();
135     // Create output buffers on the V4L2 device output queue.
136     bool createOutputBuffers();
137     // Destroy the input buffers on the V4L2 device input queue.
138     void destroyInputBuffers();
139     // Destroy the output buffers on the V4L2 device output queue.
140     void destroyOutputBuffers();
141 
142     // Notify the client an error occurred and switch to the error state.
143     void onError();
144 
145     // Change the state of the encoder.
146     void setState(State state);
147     // Get the specified encoder |state| as string.
148     static const char* stateToString(State state);
149 
150     // The list of currently queued encode requests.
151     std::queue<EncodeRequest> mEncodeRequests;
152 
153     // The video stream's visible size.
154     ui::Size mVisibleSize;
155     // The video stream's coded size.
156     ui::Size mInputCodedSize;
157     // The input layout configured on the V4L2 device.
158     std::optional<VideoFrameLayout> mInputLayout;
159     // Required output buffer byte size.
160     uint32_t mOutputBufferSize = 0;
161 
162     // How often we want to request the V4L2 device to create a key frame.
163     uint32_t mKeyFramePeriod = 0;
164     // Key frame counter, a key frame will be requested each time it reaches zero.
165     uint32_t mKeyFrameCounter = 0;
166 
167     // Whether we need to manually cache and prepend SPS and PPS to IDR frames.
168     bool mInjectParamsBeforeIDR = false;
169     // The latest cached SPS and PPS (without H.264 start code).
170     std::vector<uint8_t> mCachedSPS;
171     std::vector<uint8_t> mCachedPPS;
172 
173     // The V4L2 device and associated queues used to interact with the device.
174     scoped_refptr<V4L2Device> mDevice;
175     scoped_refptr<V4L2Queue> mInputQueue;
176     scoped_refptr<V4L2Queue> mOutputQueue;
177 
178     // List of frames associated with each buffer in the V4L2 device input queue.
179     std::vector<std::unique_ptr<InputFrame>> mInputBuffers;
180     // List of bitstream buffers associated with each buffer in the V4L2 device output queue.
181     std::vector<std::unique_ptr<BitstreamBuffer>> mOutputBuffers;
182 
183     // Callbacks to be triggered on various events.
184     FetchOutputBufferCB mFetchOutputBufferCb;
185     InputBufferDoneCB mInputBufferDoneCb;
186     OutputBufferDoneCB mOutputBufferDoneCb;
187     DrainDoneCB mDrainDoneCb;
188     ErrorCB mErrorCb;
189 
190     // The current state of the encoder.
191     State mState = State::UNINITIALIZED;
192 
193     scoped_refptr<::base::SequencedTaskRunner> mTaskRunner;
194 
195     ::base::WeakPtr<V4L2Encoder> mWeakThis;
196     ::base::WeakPtrFactory<V4L2Encoder> mWeakThisFactory{this};
197 };
198 
199 }  // namespace android
200 
201 #endif  // ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_ENCODER_H
202