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