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

Side by Side Diff: content/common/gpu/media/v4l2_video_decode_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 // This file contains an implementation of VideoDecodeAccelerator
6 // that utilizes hardware video decoders, which expose Video4Linux 2 API
7 // (http://linuxtv.org/downloads/v4l-dvb-apis/).
8
9 #ifndef CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_DECODE_ACCELERATOR_H_
10 #define CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_DECODE_ACCELERATOR_H_
11
12 #include <stddef.h>
13 #include <stdint.h>
14
15 #include <memory>
16 #include <queue>
17 #include <vector>
18
19 #include "base/callback_forward.h"
20 #include "base/macros.h"
21 #include "base/memory/linked_ptr.h"
22 #include "base/memory/ref_counted.h"
23 #include "base/synchronization/waitable_event.h"
24 #include "base/threading/thread.h"
25 #include "content/common/content_export.h"
26 #include "content/common/gpu/media/gpu_video_decode_accelerator_helpers.h"
27 #include "content/common/gpu/media/v4l2_device.h"
28 #include "content/common/gpu/media/v4l2_image_processor.h"
29 #include "media/base/limits.h"
30 #include "media/base/video_decoder_config.h"
31 #include "media/video/picture.h"
32 #include "media/video/video_decode_accelerator.h"
33 #include "ui/gfx/geometry/size.h"
34 #include "ui/gl/gl_bindings.h"
35
36 namespace media {
37 class H264Parser;
38 } // namespace media
39
40 namespace content {
41 // This class handles video accelerators directly through a V4L2 device exported
42 // by the hardware blocks.
43 //
44 // The threading model of this class is driven by the fact that it needs to
45 // interface two fundamentally different event queues -- the one Chromium
46 // provides through MessageLoop, and the one driven by the V4L2 devices which
47 // is waited on with epoll(). There are three threads involved in this class:
48 //
49 // * The child thread, which is the main GPU process thread which calls the
50 // media::VideoDecodeAccelerator entry points. Calls from this thread
51 // generally do not block (with the exception of Initialize() and Destroy()).
52 // They post tasks to the decoder_thread_, which actually services the task
53 // and calls back when complete through the
54 // media::VideoDecodeAccelerator::Client interface.
55 // * The decoder_thread_, owned by this class. It services API tasks, through
56 // the *Task() routines, as well as V4L2 device events, through
57 // ServiceDeviceTask(). Almost all state modification is done on this thread
58 // (this doesn't include buffer (re)allocation sequence, see below).
59 // * The device_poll_thread_, owned by this class. All it does is epoll() on
60 // the V4L2 in DevicePollTask() and schedule a ServiceDeviceTask() on the
61 // decoder_thread_ when something interesting happens.
62 // TODO(sheu): replace this thread with an TYPE_IO decoder_thread_.
63 //
64 // Note that this class has (almost) no locks, apart from the pictures_assigned_
65 // WaitableEvent. Everything (apart from buffer (re)allocation) is serviced on
66 // the decoder_thread_, so there are no synchronization issues.
67 // ... well, there are, but it's a matter of getting messages posted in the
68 // right order, not fiddling with locks.
69 // Buffer creation is a two-step process that is serviced partially on the
70 // Child thread, because we need to wait for the client to provide textures
71 // for the buffers we allocate. We cannot keep the decoder thread running while
72 // the client allocates Pictures for us, because we need to REQBUFS first to get
73 // the required number of output buffers from the device and that cannot be done
74 // unless we free the previous set of buffers, leaving the decoding in a
75 // inoperable state for the duration of the wait for Pictures. So to prevent
76 // subtle races (esp. if we get Reset() in the meantime), we block the decoder
77 // thread while we wait for AssignPictureBuffers from the client.
78 //
79 // V4L2VideoDecodeAccelerator may use image processor to convert the output.
80 // There are three cases:
81 // Flush: V4L2VDA should wait until image processor returns all processed
82 // frames.
83 // Reset: V4L2VDA doesn't need to wait for image processor. When image processor
84 // returns an old frame, drop it.
85 // Resolution change: V4L2VDA destroy image processor when destroying output
86 // buffrers. We cannot drop any frame during resolution change. So V4L2VDA
87 // should destroy output buffers after image processor returns all the frames.
88 class CONTENT_EXPORT V4L2VideoDecodeAccelerator
89 : public media::VideoDecodeAccelerator {
90 public:
91 V4L2VideoDecodeAccelerator(
92 EGLDisplay egl_display,
93 const GetGLContextCallback& get_gl_context_cb,
94 const MakeGLContextCurrentCallback& make_context_current_cb,
95 const scoped_refptr<V4L2Device>& device);
96 ~V4L2VideoDecodeAccelerator() override;
97
98 // media::VideoDecodeAccelerator implementation.
99 // Note: Initialize() and Destroy() are synchronous.
100 bool Initialize(const Config& config, Client* client) override;
101 void Decode(const media::BitstreamBuffer& bitstream_buffer) override;
102 void AssignPictureBuffers(
103 const std::vector<media::PictureBuffer>& buffers) override;
104 void ReusePictureBuffer(int32_t picture_buffer_id) override;
105 void Flush() override;
106 void Reset() override;
107 void Destroy() override;
108 bool TryToSetupDecodeOnSeparateThread(
109 const base::WeakPtr<Client>& decode_client,
110 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner)
111 override;
112 media::VideoPixelFormat GetOutputFormat() const override;
113
114 static media::VideoDecodeAccelerator::SupportedProfiles
115 GetSupportedProfiles();
116
117 private:
118 // These are rather subjectively tuned.
119 enum {
120 kInputBufferCount = 8,
121 // TODO(posciak): determine input buffer size based on level limits.
122 // See http://crbug.com/255116.
123 // Input bitstream buffer size for up to 1080p streams.
124 kInputBufferMaxSizeFor1080p = 1024 * 1024,
125 // Input bitstream buffer size for up to 4k streams.
126 kInputBufferMaxSizeFor4k = 4 * kInputBufferMaxSizeFor1080p,
127 // Number of output buffers to use for each VDA stage above what's required
128 // by the decoder (e.g. DPB size, in H264). We need
129 // media::limits::kMaxVideoFrames to fill up the GpuVideoDecode pipeline,
130 // and +1 for a frame in transit.
131 kDpbOutputBufferExtraCount = media::limits::kMaxVideoFrames + 1,
132 };
133
134 // Internal state of the decoder.
135 enum State {
136 kUninitialized, // Initialize() not yet called.
137 kInitialized, // Initialize() returned true; ready to start decoding.
138 kDecoding, // DecodeBufferInitial() successful; decoding frames.
139 kResetting, // Presently resetting.
140 kAfterReset, // After Reset(), ready to start decoding again.
141 kChangingResolution, // Performing resolution change, all remaining
142 // pre-change frames decoded and processed.
143 kError, // Error in kDecoding state.
144 };
145
146 enum OutputRecordState {
147 kFree, // Ready to be queued to the device.
148 kAtDevice, // Held by device.
149 kAtProcessor, // Held by image processor.
150 kAtClient, // Held by client of V4L2VideoDecodeAccelerator.
151 };
152
153 enum BufferId {
154 kFlushBufferId = -2 // Buffer id for flush buffer, queued by FlushTask().
155 };
156
157 // Auto-destruction reference for BitstreamBuffer, for message-passing from
158 // Decode() to DecodeTask().
159 struct BitstreamBufferRef;
160
161 // Auto-destruction reference for EGLSync (for message-passing).
162 struct EGLSyncKHRRef;
163
164 // Record for decoded pictures that can be sent to PictureReady.
165 struct PictureRecord;
166
167 // Record for input buffers.
168 struct InputRecord {
169 InputRecord();
170 ~InputRecord();
171 bool at_device; // held by device.
172 void* address; // mmap() address.
173 size_t length; // mmap() length.
174 off_t bytes_used; // bytes filled in the mmap() segment.
175 int32_t input_id; // triggering input_id as given to Decode().
176 };
177
178 // Record for output buffers.
179 struct OutputRecord {
180 OutputRecord();
181 OutputRecord(OutputRecord&&) = default;
182 ~OutputRecord();
183 OutputRecordState state;
184 EGLImageKHR egl_image; // EGLImageKHR for the output buffer.
185 EGLSyncKHR egl_sync; // sync the compositor's use of the EGLImage.
186 int32_t picture_id; // picture buffer id as returned to PictureReady().
187 bool cleared; // Whether the texture is cleared and safe to render
188 // from. See TextureManager for details.
189 // Exported fds for image processor to import.
190 std::vector<base::ScopedFD> fds;
191 };
192
193 //
194 // Decoding tasks, to be run on decode_thread_.
195 //
196
197 // Enqueue a BitstreamBuffer to decode. This will enqueue a buffer to the
198 // decoder_input_queue_, then queue a DecodeBufferTask() to actually decode
199 // the buffer.
200 void DecodeTask(const media::BitstreamBuffer& bitstream_buffer);
201
202 // Decode from the buffers queued in decoder_input_queue_. Calls
203 // DecodeBufferInitial() or DecodeBufferContinue() as appropriate.
204 void DecodeBufferTask();
205 // Advance to the next fragment that begins a frame.
206 bool AdvanceFrameFragment(const uint8_t* data, size_t size, size_t* endpos);
207 // Schedule another DecodeBufferTask() if we're behind.
208 void ScheduleDecodeBufferTaskIfNeeded();
209
210 // Return true if we should continue to schedule DecodeBufferTask()s after
211 // completion. Store the amount of input actually consumed in |endpos|.
212 bool DecodeBufferInitial(const void* data, size_t size, size_t* endpos);
213 bool DecodeBufferContinue(const void* data, size_t size);
214
215 // Accumulate data for the next frame to decode. May return false in
216 // non-error conditions; for example when pipeline is full and should be
217 // retried later.
218 bool AppendToInputFrame(const void* data, size_t size);
219 // Flush data for one decoded frame.
220 bool FlushInputFrame();
221
222 // Service I/O on the V4L2 devices. This task should only be scheduled from
223 // DevicePollTask(). If |event_pending| is true, one or more events
224 // on file descriptor are pending.
225 void ServiceDeviceTask(bool event_pending);
226 // Handle the various device queues.
227 void Enqueue();
228 void Dequeue();
229
230 // Return true if there is a resolution change event pending.
231 bool DequeueResolutionChangeEvent();
232
233 // Enqueue a buffer on the corresponding queue.
234 bool EnqueueInputRecord();
235 bool EnqueueOutputRecord();
236
237 // Process a ReusePictureBuffer() API call. The API call create an EGLSync
238 // object on the main (GPU process) thread; we will record this object so we
239 // can wait on it before reusing the buffer.
240 void ReusePictureBufferTask(int32_t picture_buffer_id,
241 std::unique_ptr<EGLSyncKHRRef> egl_sync_ref);
242
243 // Flush() task. Child thread should not submit any more buffers until it
244 // receives the NotifyFlushDone callback. This task will schedule an empty
245 // BitstreamBufferRef (with input_id == kFlushBufferId) to perform the flush.
246 void FlushTask();
247 // Notify the client of a flush completion, if required. This should be
248 // called any time a relevant queue could potentially be emptied: see
249 // function definition.
250 void NotifyFlushDoneIfNeeded();
251
252 // Reset() task. This task will schedule a ResetDoneTask() that will send
253 // the NotifyResetDone callback, then set the decoder state to kResetting so
254 // that all intervening tasks will drain.
255 void ResetTask();
256 // ResetDoneTask() will set the decoder state back to kAfterReset, so
257 // subsequent decoding can continue.
258 void ResetDoneTask();
259
260 // Device destruction task.
261 void DestroyTask();
262
263 // Start |device_poll_thread_|.
264 bool StartDevicePoll();
265
266 // Stop |device_poll_thread_|.
267 bool StopDevicePoll();
268
269 bool StopInputStream();
270 bool StopOutputStream();
271
272 void StartResolutionChange();
273 void FinishResolutionChange();
274
275 // Try to get output format and visible size, detected after parsing the
276 // beginning of the stream. Sets |again| to true if more parsing is needed.
277 // |visible_size| could be nullptr and ignored.
278 bool GetFormatInfo(struct v4l2_format* format,
279 gfx::Size* visible_size,
280 bool* again);
281 // Create output buffers for the given |format| and |visible_size|.
282 bool CreateBuffersForFormat(const struct v4l2_format& format,
283 const gfx::Size& visible_size);
284
285 // Try to get |visible_size|. Return visible size, or, if querying it is not
286 // supported or produces invalid size, return |coded_size| instead.
287 gfx::Size GetVisibleSize(const gfx::Size& coded_size);
288
289 //
290 // Device tasks, to be run on device_poll_thread_.
291 //
292
293 // The device task.
294 void DevicePollTask(bool poll_device);
295
296 //
297 // Safe from any thread.
298 //
299
300 // Error notification (using PostTask() to child thread, if necessary).
301 void NotifyError(Error error);
302
303 // Set the decoder_state_ to kError and notify the client (if necessary).
304 void SetErrorState(Error error);
305
306 //
307 // Other utility functions. Called on decoder_thread_, unless
308 // decoder_thread_ is not yet started, in which case the child thread can call
309 // these (e.g. in Initialize() or Destroy()).
310 //
311
312 // Create the buffers we need.
313 bool CreateInputBuffers();
314 bool CreateOutputBuffers();
315
316 // Set input and output formats before starting decode.
317 bool SetupFormats();
318 // Return a usable input format of image processor. Return 0 if not found.
319 uint32_t FindImageProcessorInputFormat();
320 // Return a usable output format of image processor. Return 0 if not found.
321 uint32_t FindImageProcessorOutputFormat();
322
323 //
324 // Methods run on child thread.
325 //
326
327 // Destroy buffers.
328 void DestroyInputBuffers();
329 // In contrast to DestroyInputBuffers, which is called only from destructor,
330 // we call DestroyOutputBuffers also during playback, on resolution change.
331 // Even if anything fails along the way, we still want to go on and clean
332 // up as much as possible, so return false if this happens, so that the
333 // caller can error out on resolution change.
334 bool DestroyOutputBuffers();
335 void ResolutionChangeDestroyBuffers();
336
337 // Send decoded pictures to PictureReady.
338 void SendPictureReady();
339
340 // Callback that indicates a picture has been cleared.
341 void PictureCleared();
342
343 // Image processor returns a processed frame. Its id is |bitstream_buffer_id|
344 // and stored in |output_buffer_index| buffer of image processor.
345 void FrameProcessed(int32_t bitstream_buffer_id, int output_buffer_index);
346
347 // Image processor notifies an error.
348 void ImageProcessorError();
349
350 // Our original calling task runner for the child thread.
351 scoped_refptr<base::SingleThreadTaskRunner> child_task_runner_;
352
353 // Task runner Decode() and PictureReady() run on.
354 scoped_refptr<base::SingleThreadTaskRunner> decode_task_runner_;
355
356 // WeakPtr<> pointing to |this| for use in posting tasks from the decoder or
357 // device worker threads back to the child thread. Because the worker threads
358 // are members of this class, any task running on those threads is guaranteed
359 // that this object is still alive. As a result, tasks posted from the child
360 // thread to the decoder or device thread should use base::Unretained(this),
361 // and tasks posted the other way should use |weak_this_|.
362 base::WeakPtr<V4L2VideoDecodeAccelerator> weak_this_;
363
364 // To expose client callbacks from VideoDecodeAccelerator.
365 // NOTE: all calls to these objects *MUST* be executed on
366 // child_task_runner_.
367 std::unique_ptr<base::WeakPtrFactory<Client>> client_ptr_factory_;
368 base::WeakPtr<Client> client_;
369 // Callbacks to |decode_client_| must be executed on |decode_task_runner_|.
370 base::WeakPtr<Client> decode_client_;
371
372 //
373 // Decoder state, owned and operated by decoder_thread_.
374 // Before decoder_thread_ has started, the decoder state is managed by
375 // the child (main) thread. After decoder_thread_ has started, the decoder
376 // thread should be the only one managing these.
377 //
378
379 // This thread services tasks posted from the VDA API entry points by the
380 // child thread and device service callbacks posted from the device thread.
381 base::Thread decoder_thread_;
382 // Decoder state machine state.
383 State decoder_state_;
384 // BitstreamBuffer we're presently reading.
385 std::unique_ptr<BitstreamBufferRef> decoder_current_bitstream_buffer_;
386 // The V4L2Device this class is operating upon.
387 scoped_refptr<V4L2Device> device_;
388 // FlushTask() and ResetTask() should not affect buffers that have been
389 // queued afterwards. For flushing or resetting the pipeline then, we will
390 // delay these buffers until after the flush or reset completes.
391 int decoder_delay_bitstream_buffer_id_;
392 // Input buffer we're presently filling.
393 int decoder_current_input_buffer_;
394 // We track the number of buffer decode tasks we have scheduled, since each
395 // task execution should complete one buffer. If we fall behind (due to
396 // resource backpressure, etc.), we'll have to schedule more to catch up.
397 int decoder_decode_buffer_tasks_scheduled_;
398 // Picture buffers held by the client.
399 int decoder_frames_at_client_;
400 // Are we flushing?
401 bool decoder_flushing_;
402 // Got a reset request while we were performing resolution change.
403 bool resolution_change_reset_pending_;
404 // Input queue for decoder_thread_: BitstreamBuffers in.
405 std::queue<linked_ptr<BitstreamBufferRef> > decoder_input_queue_;
406 // For H264 decode, hardware requires that we send it frame-sized chunks.
407 // We'll need to parse the stream.
408 std::unique_ptr<media::H264Parser> decoder_h264_parser_;
409 // Set if the decoder has a pending incomplete frame in an input buffer.
410 bool decoder_partial_frame_pending_;
411
412 //
413 // Hardware state and associated queues. Since decoder_thread_ services
414 // the hardware, decoder_thread_ owns these too.
415 // output_buffer_map_, free_output_buffers_ and output_planes_count_ are an
416 // exception during the buffer (re)allocation sequence, when the
417 // decoder_thread_ is blocked briefly while the Child thread manipulates
418 // them.
419 //
420
421 // Completed decode buffers.
422 std::queue<int> input_ready_queue_;
423
424 // Input buffer state.
425 bool input_streamon_;
426 // Input buffers enqueued to device.
427 int input_buffer_queued_count_;
428 // Input buffers ready to use, as a LIFO since we don't care about ordering.
429 std::vector<int> free_input_buffers_;
430 // Mapping of int index to input buffer record.
431 std::vector<InputRecord> input_buffer_map_;
432
433 // Output buffer state.
434 bool output_streamon_;
435 // Output buffers enqueued to device.
436 int output_buffer_queued_count_;
437 // Output buffers ready to use, as a FIFO since we want oldest-first to hide
438 // synchronization latency with GL.
439 std::queue<int> free_output_buffers_;
440 // Mapping of int index to output buffer record.
441 std::vector<OutputRecord> output_buffer_map_;
442 // Required size of DPB for decoding.
443 int output_dpb_size_;
444
445 // Number of planes (i.e. separate memory buffers) for output.
446 size_t output_planes_count_;
447
448 // Pictures that are ready but not sent to PictureReady yet.
449 std::queue<PictureRecord> pending_picture_ready_;
450
451 // The number of pictures that are sent to PictureReady and will be cleared.
452 int picture_clearing_count_;
453
454 // Used by the decoder thread to wait for AssignPictureBuffers to arrive
455 // to avoid races with potential Reset requests.
456 base::WaitableEvent pictures_assigned_;
457
458 // Output picture coded size.
459 gfx::Size coded_size_;
460
461 // Output picture visible size.
462 gfx::Size visible_size_;
463
464 //
465 // The device polling thread handles notifications of V4L2 device changes.
466 //
467
468 // The thread.
469 base::Thread device_poll_thread_;
470
471 //
472 // Other state, held by the child (main) thread.
473 //
474
475 // EGL state
476 EGLDisplay egl_display_;
477
478 // Callback to get current GLContext.
479 GetGLContextCallback get_gl_context_cb_;
480 // Callback to set the correct gl context.
481 MakeGLContextCurrentCallback make_context_current_cb_;
482
483 // The codec we'll be decoding for.
484 media::VideoCodecProfile video_profile_;
485 // Chosen output format.
486 uint32_t output_format_fourcc_;
487
488 // Image processor device, if one is in use.
489 scoped_refptr<V4L2Device> image_processor_device_;
490 // Image processor. Created and destroyed on child thread.
491 std::unique_ptr<V4L2ImageProcessor> image_processor_;
492
493 // The V4L2Device EGLImage is created from.
494 scoped_refptr<V4L2Device> egl_image_device_;
495 // The format of EGLImage.
496 uint32_t egl_image_format_fourcc_;
497 // The logical dimensions of EGLImage buffer in pixels.
498 gfx::Size egl_image_size_;
499 // Number of planes for EGLImage.
500 size_t egl_image_planes_count_;
501
502 // IDs of bitstream buffers sent to image processor to process. After a
503 // buffer is processed, it will sent to render if the id is in this
504 // queue. If the id is not in this queue, the buffer will be dropped.
505 std::queue<int> image_processor_bitstream_buffer_ids_;
506
507 // Input format V4L2 fourccs this class supports.
508 static const uint32_t supported_input_fourccs_[];
509
510 // The WeakPtrFactory for |weak_this_|.
511 base::WeakPtrFactory<V4L2VideoDecodeAccelerator> weak_this_factory_;
512
513 DISALLOW_COPY_AND_ASSIGN(V4L2VideoDecodeAccelerator);
514 };
515
516 } // namespace content
517
518 #endif // CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_DECODE_ACCELERATOR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698