Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(22)

Side by Side Diff: content/common/gpu/media/v4l2_video_encode_accelerator.h

Issue 1882373004: Migrate content/common/gpu/media code to media/gpu (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Squash and rebase Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 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 CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_ENCODE_ACCELERATOR_H_
6 #define CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_ENCODE_ACCELERATOR_H_
7
8 #include <linux/videodev2.h>
9 #include <stddef.h>
10 #include <stdint.h>
11
12 #include <list>
13 #include <memory>
14 #include <vector>
15
16 #include "base/files/scoped_file.h"
17 #include "base/macros.h"
18 #include "base/memory/linked_ptr.h"
19 #include "base/memory/weak_ptr.h"
20 #include "base/threading/thread.h"
21 #include "base/time/time.h"
22 #include "content/common/content_export.h"
23 #include "content/common/gpu/media/v4l2_device.h"
24 #include "content/common/gpu/media/v4l2_image_processor.h"
25 #include "media/video/video_encode_accelerator.h"
26 #include "ui/gfx/geometry/size.h"
27
28 namespace media {
29
30 class BitstreamBuffer;
31
32 } // namespace media
33
34 namespace content {
35
36 // This class handles video encode acceleration by interfacing with a V4L2
37 // device exposed by the codec hardware driver. The threading model of this
38 // class is the same as in the V4L2VideoDecodeAccelerator (from which class this
39 // was designed).
40 // This class may try to instantiate and use a V4L2ImageProcessor for input
41 // format conversion, if the input format requested via Initialize() is not
42 // accepted by the hardware codec.
43 class CONTENT_EXPORT V4L2VideoEncodeAccelerator
44 : public media::VideoEncodeAccelerator {
45 public:
46 explicit V4L2VideoEncodeAccelerator(const scoped_refptr<V4L2Device>& device);
47 ~V4L2VideoEncodeAccelerator() override;
48
49 // media::VideoEncodeAccelerator implementation.
50 media::VideoEncodeAccelerator::SupportedProfiles GetSupportedProfiles()
51 override;
52 bool Initialize(media::VideoPixelFormat format,
53 const gfx::Size& input_visible_size,
54 media::VideoCodecProfile output_profile,
55 uint32_t initial_bitrate,
56 Client* client) override;
57 void Encode(const scoped_refptr<media::VideoFrame>& frame,
58 bool force_keyframe) override;
59 void UseOutputBitstreamBuffer(const media::BitstreamBuffer& buffer)
60 override;
61 void RequestEncodingParametersChange(uint32_t bitrate,
62 uint32_t framerate) override;
63 void Destroy() override;
64
65 private:
66 // Auto-destroy reference for BitstreamBuffer, for tracking buffers passed to
67 // this instance.
68 struct BitstreamBufferRef;
69
70 // Record for codec input buffers.
71 struct InputRecord {
72 InputRecord();
73 ~InputRecord();
74 bool at_device;
75 scoped_refptr<media::VideoFrame> frame;
76 };
77
78 // Record for output buffers.
79 struct OutputRecord {
80 OutputRecord();
81 ~OutputRecord();
82 bool at_device;
83 linked_ptr<BitstreamBufferRef> buffer_ref;
84 void* address;
85 size_t length;
86 };
87
88 struct ImageProcessorInputRecord {
89 ImageProcessorInputRecord();
90 ~ImageProcessorInputRecord();
91 scoped_refptr<media::VideoFrame> frame;
92 bool force_keyframe;
93 };
94
95 enum {
96 kInitialFramerate = 30,
97 // These are rather subjectively tuned.
98 kInputBufferCount = 2,
99 kOutputBufferCount = 2,
100 kImageProcBufferCount = 2,
101 kOutputBufferSize = (2 * 1024 * 1024),
102 };
103
104 // Internal state of the encoder.
105 enum State {
106 kUninitialized, // Initialize() not yet called.
107 kInitialized, // Initialize() returned true; ready to start encoding.
108 kEncoding, // Encoding frames.
109 kError, // Error in encoder state.
110 };
111
112 //
113 // Callbacks for the image processor, if one is used.
114 //
115
116 // Callback run by the image processor when a frame is ready for us to encode.
117 void FrameProcessed(bool force_keyframe,
118 base::TimeDelta timestamp,
119 int output_buffer_index);
120
121 // Error callback for handling image processor errors.
122 void ImageProcessorError();
123
124 //
125 // Encoding tasks, to be run on encode_thread_.
126 //
127
128 void EncodeTask(const scoped_refptr<media::VideoFrame>& frame,
129 bool force_keyframe);
130
131 // Add a BitstreamBuffer to the queue of buffers ready to be used for encoder
132 // output.
133 void UseOutputBitstreamBufferTask(
134 std::unique_ptr<BitstreamBufferRef> buffer_ref);
135
136 // Device destruction task.
137 void DestroyTask();
138
139 // Service I/O on the V4L2 devices. This task should only be scheduled from
140 // DevicePollTask().
141 void ServiceDeviceTask();
142
143 // Handle the device queues.
144 void Enqueue();
145 void Dequeue();
146 // Enqueue a buffer on the corresponding queue. Returns false on fatal error.
147 bool EnqueueInputRecord();
148 bool EnqueueOutputRecord();
149
150 // Attempt to start/stop device_poll_thread_.
151 bool StartDevicePoll();
152 bool StopDevicePoll();
153
154 //
155 // Device tasks, to be run on device_poll_thread_.
156 //
157
158 // The device task.
159 void DevicePollTask(bool poll_device);
160
161 //
162 // Safe from any thread.
163 //
164
165 // Error notification (using PostTask() to child thread, if necessary).
166 void NotifyError(Error error);
167
168 // Set the encoder_state_ to kError and notify the client (if necessary).
169 void SetErrorState(Error error);
170
171 //
172 // Other utility functions. Called on encoder_thread_, unless
173 // encoder_thread_ is not yet started, in which case the child thread can call
174 // these (e.g. in Initialize() or Destroy()).
175 //
176
177 // Change encoding parameters.
178 void RequestEncodingParametersChangeTask(uint32_t bitrate,
179 uint32_t framerate);
180
181 // Set up formats and initialize the device for them.
182 bool SetFormats(media::VideoPixelFormat input_format,
183 media::VideoCodecProfile output_profile);
184
185 // Try to set up the device to the input format we were Initialized() with,
186 // or if the device doesn't support it, use one it can support, so that we
187 // can later instantiate a V4L2ImageProcessor to convert to it.
188 bool NegotiateInputFormat(media::VideoPixelFormat input_format);
189
190 // Set up the device to the output format requested in Initialize().
191 bool SetOutputFormat(media::VideoCodecProfile output_profile);
192
193 // Initialize device controls with default values.
194 bool InitControls();
195
196 // Create the buffers we need.
197 bool CreateInputBuffers();
198 bool CreateOutputBuffers();
199
200 // Destroy these buffers.
201 void DestroyInputBuffers();
202 void DestroyOutputBuffers();
203
204 // Set controls in |ctrls| and return true if successful.
205 bool SetExtCtrls(std::vector<struct v4l2_ext_control> ctrls);
206
207 // Recycle output buffer of image processor with |output_buffer_index|.
208 void ReuseImageProcessorOutputBuffer(int output_buffer_index);
209
210 // Our original calling task runner for the child thread.
211 const scoped_refptr<base::SingleThreadTaskRunner> child_task_runner_;
212
213 gfx::Size visible_size_;
214 // Input allocated size required by the device.
215 gfx::Size input_allocated_size_;
216 size_t output_buffer_byte_size_;
217
218 // Formats for input frames and the output stream.
219 media::VideoPixelFormat device_input_format_;
220 size_t input_planes_count_;
221 uint32_t output_format_fourcc_;
222
223 //
224 // Encoder state, owned and operated by encoder_thread_.
225 // Before encoder_thread_ has started, the encoder state is managed by
226 // the child (main) thread. After encoder_thread_ has started, the encoder
227 // thread should be the only one managing these.
228 //
229
230 // Encoder state.
231 State encoder_state_;
232
233 // We need to provide the stream header with every keyframe, to allow
234 // midstream decoding restarts. Store it here.
235 std::unique_ptr<uint8_t[]> stream_header_;
236 size_t stream_header_size_;
237
238 // Video frames ready to be encoded.
239 std::queue<scoped_refptr<media::VideoFrame>> encoder_input_queue_;
240
241 // Encoder device.
242 scoped_refptr<V4L2Device> device_;
243
244 // Input queue state.
245 bool input_streamon_;
246 // Input buffers enqueued to device.
247 int input_buffer_queued_count_;
248 // Input buffers ready to use; LIFO since we don't care about ordering.
249 std::vector<int> free_input_buffers_;
250 // Mapping of int index to input buffer record.
251 std::vector<InputRecord> input_buffer_map_;
252 v4l2_memory input_memory_type_;
253
254 // Output queue state.
255 bool output_streamon_;
256 // Output buffers enqueued to device.
257 int output_buffer_queued_count_;
258 // Output buffers ready to use; LIFO since we don't care about ordering.
259 std::vector<int> free_output_buffers_;
260 // Mapping of int index to output buffer record.
261 std::vector<OutputRecord> output_buffer_map_;
262
263 // Bitstream buffers ready to be used to return encoded output, as a LIFO
264 // since we don't care about ordering.
265 std::vector<linked_ptr<BitstreamBufferRef> > encoder_output_queue_;
266
267 // Image processor, if one is in use.
268 std::unique_ptr<V4L2ImageProcessor> image_processor_;
269 // Indexes of free image processor output buffers. Only accessed on child
270 // thread.
271 std::vector<int> free_image_processor_output_buffers_;
272 // Video frames ready to be processed. Only accessed on child thread.
273 std::queue<ImageProcessorInputRecord> image_processor_input_queue_;
274 // Mapping of int index to fds of image processor output buffer.
275 std::vector<std::vector<base::ScopedFD>> image_processor_output_buffer_map_;
276
277 // This thread services tasks posted from the VEA API entry points by the
278 // child thread and device service callbacks posted from the device thread.
279 base::Thread encoder_thread_;
280
281 // The device polling thread handles notifications of V4L2 device changes.
282 // TODO(sheu): replace this thread with an TYPE_IO encoder_thread_.
283 base::Thread device_poll_thread_;
284
285 // To expose client callbacks from VideoEncodeAccelerator.
286 // NOTE: all calls to these objects *MUST* be executed on
287 // child_task_runner_.
288 base::WeakPtr<Client> client_;
289 std::unique_ptr<base::WeakPtrFactory<Client>> client_ptr_factory_;
290
291 // WeakPtr<> pointing to |this| for use in posting tasks from the
292 // image_processor_ back to the child thread.
293 // Tasks posted onto encoder and poll threads can use base::Unretained(this),
294 // as both threads will not outlive this object.
295 base::WeakPtr<V4L2VideoEncodeAccelerator> weak_this_;
296 base::WeakPtrFactory<V4L2VideoEncodeAccelerator> weak_this_ptr_factory_;
297
298 DISALLOW_COPY_AND_ASSIGN(V4L2VideoEncodeAccelerator);
299 };
300
301 } // namespace content
302
303 #endif // CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_ENCODE_ACCELERATOR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698