1 // Copyright 2015 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.
5 #ifndef CONTENT_COMMON_GPU_MEDIA_V4L2_SLICE_VIDEO_DECODE_ACCELERATOR_H_
6 #define CONTENT_COMMON_GPU_MEDIA_V4L2_SLICE_VIDEO_DECODE_ACCELERATOR_H_
8 #include <linux/videodev2.h>
12 #include "base/memory/linked_ptr.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/synchronization/waitable_event.h"
17 #include "base/threading/thread.h"
18 #include "content/common/content_export.h"
19 #include "content/common/gpu/media/h264_decoder.h"
20 #include "content/common/gpu/media/v4l2_device.h"
21 #include "content/common/gpu/media/vp8_decoder.h"
22 #include "media/video/video_decode_accelerator.h"
26 // An implementation of VideoDecodeAccelerator that utilizes the V4L2 slice
27 // level codec API for decoding. The slice level API provides only a low-level
28 // decoding functionality and requires userspace to provide support for parsing
29 // the input stream and managing decoder state across frames.
30 class CONTENT_EXPORT V4L2SliceVideoDecodeAccelerator
31 : public media::VideoDecodeAccelerator
{
33 class V4L2DecodeSurface
;
35 V4L2SliceVideoDecodeAccelerator(
36 const scoped_refptr
<V4L2Device
>& device
,
37 EGLDisplay egl_display
,
38 EGLContext egl_context
,
39 const base::WeakPtr
<Client
>& io_client_
,
40 const base::Callback
<bool(void)>& make_context_current
,
41 const scoped_refptr
<base::MessageLoopProxy
>& io_message_loop_proxy
);
42 ~V4L2SliceVideoDecodeAccelerator() override
;
44 // media::VideoDecodeAccelerator implementation.
45 bool Initialize(media::VideoCodecProfile profile
,
46 VideoDecodeAccelerator::Client
* client
) override
;
47 void Decode(const media::BitstreamBuffer
& bitstream_buffer
) override
;
48 void AssignPictureBuffers(
49 const std::vector
<media::PictureBuffer
>& buffers
) override
;
50 void ReusePictureBuffer(int32 picture_buffer_id
) override
;
51 void Flush() override
;
52 void Reset() override
;
53 void Destroy() override
;
54 bool CanDecodeOnIOThread() override
;
57 class V4L2H264Accelerator
;
58 class V4L2VP8Accelerator
;
60 // Record for input buffers.
70 // Record for output buffers.
76 EGLImageKHR egl_image
;
81 // See http://crbug.com/255116.
82 // Input bitstream buffer size for up to 1080p streams.
83 const size_t kInputBufferMaxSizeFor1080p
= 1024 * 1024;
84 // Input bitstream buffer size for up to 4k streams.
85 const size_t kInputBufferMaxSizeFor4k
= 4 * kInputBufferMaxSizeFor1080p
;
86 const size_t kNumInputBuffers
= 16;
89 // Below methods are used by accelerator implementations.
91 // Append slice data in |data| of size |size| to pending hardware
92 // input buffer with |index|. This buffer will be submitted for decode
93 // on the next DecodeSurface(). Return true on success.
94 bool SubmitSlice(int index
, const uint8_t* data
, size_t size
);
96 // Submit controls in |ext_ctrls| to hardware. Return true on success.
97 bool SubmitExtControls(struct v4l2_ext_controls
* ext_ctrls
);
99 // Decode of |dec_surface| is ready to be submitted and all codec-specific
100 // settings are set in hardware.
101 void DecodeSurface(const scoped_refptr
<V4L2DecodeSurface
>& dec_surface
);
103 // |dec_surface| is ready to be outputted once decode is finished.
104 // This can be called before decode is actually done in hardware, and this
105 // method is responsible for maintaining the ordering, i.e. the surfaces will
106 // be outputted in the same order as SurfaceReady calls. To do so, the
107 // surfaces are put on decoder_display_queue_ and sent to output in that
108 // order once all preceding surfaces are sent.
109 void SurfaceReady(const scoped_refptr
<V4L2DecodeSurface
>& dec_surface
);
112 // Internal methods of this class.
114 // Recycle a V4L2 input buffer with |index| after dequeuing from device.
115 void ReuseInputBuffer(int index
);
117 // Recycle V4L2 output buffer with |index|. Used as surface release callback.
118 void ReuseOutputBuffer(int index
);
120 // Queue a |dec_surface| to device for decoding.
121 void Enqueue(const scoped_refptr
<V4L2DecodeSurface
>& dec_surface
);
123 // Dequeue any V4L2 buffers available and process.
126 // V4L2 QBUF helpers.
127 bool EnqueueInputRecord(int index
, uint32_t config_store
);
128 bool EnqueueOutputRecord(int index
);
130 // Set input and output formats in hardware.
133 // Create input and output buffers.
134 bool CreateInputBuffers();
135 bool CreateOutputBuffers();
137 // Destroy input buffers.
138 void DestroyInputBuffers();
140 // Destroy output buffers and release associated resources (textures,
141 // EGLImages). If |dismiss| is true, also dismissing the associated
143 bool DestroyOutputs(bool dismiss
);
145 // Used by DestroyOutputs.
146 bool DestroyOutputBuffers();
148 // Dismiss all |picture_buffer_ids| via Client::DismissPictureBuffer()
149 // and signal |done| after finishing.
150 void DismissPictures(std::vector
<int32
> picture_buffer_ids
,
151 base::WaitableEvent
* done
);
153 // Task to finish initialization on decoder_thread_.
154 void InitializeTask();
156 // Surface set change (resolution change) flow.
157 // If we have no surfaces allocated, just allocate them and return.
158 // Otherwise mark us as pending for surface set change.
159 void InitiateSurfaceSetChange();
160 // If a surface set change is pending and we are ready, stop the device,
161 // destroy outputs, releasing resources and dismissing pictures as required,
162 // followed by allocating a new set for the new resolution/DPB size
163 // as provided by decoder. Finally, try to resume decoding.
164 void FinishSurfaceSetChangeIfNeeded();
166 void NotifyError(Error error
);
169 // Sets the state to kError and notifies client if needed.
170 void SetErrorState(Error error
);
172 // Flush flow when requested by client.
173 // When Flush() is called, it posts a FlushTask, which checks the input queue.
174 // If nothing is pending for decode on decoder_input_queue_, we call
175 // InitiateFlush() directly. Otherwise, we push a dummy BitstreamBufferRef
176 // onto the decoder_input_queue_ to schedule a flush. When we reach it later
177 // on, we call InitiateFlush() to perform it at the correct time.
179 // Tell the decoder to flush all frames, reset it and mark us as scheduled
180 // for flush, so that we can finish it once all pending decodes are finished.
181 void InitiateFlush();
182 // If all pending frames are decoded and we are waiting to flush, perform it.
183 // This will send all pending pictures to client and notify the client that
184 // flush is complete and puts us in a state ready to resume.
185 void FinishFlushIfNeeded();
187 // Reset flow when requested by client.
188 // Drop all inputs and reset the decoder and mark us as pending for reset.
190 // If all pending frames are decoded and we are waiting to reset, perform it.
191 // This drops all pending outputs (client is not interested anymore),
192 // notifies the client we are done and puts us in a state ready to resume.
193 void FinishResetIfNeeded();
195 // Process pending events if any.
196 void ProcessPendingEventsIfNeeded();
198 // Performed on decoder_thread_ as a consequence of poll() on decoder_thread_
199 // returning an event.
200 void ServiceDeviceTask();
202 // Schedule poll if we have any buffers queued and the poll thread
203 // is not stopped (on surface set change).
204 void SchedulePollIfNeeded();
206 // Attempt to start/stop device_poll_thread_.
207 bool StartDevicePoll();
208 bool StopDevicePoll(bool keep_input_state
);
210 // Ran on device_poll_thread_ to wait for device events.
211 void DevicePollTask(bool poll_device
);
214 // We are in this state until Initialize() returns successfully.
215 // We can't post errors to the client in this state yet.
217 // Initialize() returned successfully.
219 // This state allows making progress decoding more input stream.
221 // Transitional state when we are not decoding any more stream, but are
222 // performing flush, reset, resolution change or are destroying ourselves.
224 // Error state, set when sending NotifyError to client.
228 // Buffer id for flush buffer, queued by FlushTask().
229 const int kFlushBufferId
= -2;
231 // Handler for Decode() on decoder_thread_.
232 void DecodeTask(const media::BitstreamBuffer
& bitstream_buffer
);
234 // Schedule a new DecodeBufferTask if we are decoding.
235 void ScheduleDecodeBufferTaskIfNeeded();
237 // Main decoder loop. Keep decoding the current buffer in decoder_, asking
238 // for more stream via TrySetNewBistreamBuffer() if decoder_ requests so,
239 // and handle other returns from it appropriately.
240 void DecodeBufferTask();
242 // Check decoder_input_queue_ for any available buffers to decode and
243 // set the decoder_current_bitstream_buffer_ to the next buffer if one is
244 // available, taking it off the queue. Also set the current stream pointer
245 // in decoder_, and return true.
246 // Return false if no buffers are pending on decoder_input_queue_.
247 bool TrySetNewBistreamBuffer();
249 // Auto-destruction reference for EGLSync (for message-passing).
250 struct EGLSyncKHRRef
;
251 void ReusePictureBufferTask(int32 picture_buffer_id
,
252 scoped_ptr
<EGLSyncKHRRef
> egl_sync_ref
);
254 // Called to actually send |dec_surface| to the client, after it is decoded
255 // preserving the order in which it was scheduled via SurfaceReady().
256 void OutputSurface(const scoped_refptr
<V4L2DecodeSurface
>& dec_surface
);
258 // Goes over the |decoder_display_queue_| and sends all buffers from the
259 // front of the queue that are already decoded to the client, in order.
260 void TryOutputSurfaces();
262 // Creates a new decode surface or returns nullptr if one is not available.
263 scoped_refptr
<V4L2DecodeSurface
> CreateSurface();
265 // Send decoded pictures to PictureReady.
266 void SendPictureReady();
268 // Callback that indicates a picture has been cleared.
269 void PictureCleared();
271 size_t input_planes_count_
;
272 size_t output_planes_count_
;
274 // GPU Child thread message loop.
275 const scoped_refptr
<base::MessageLoopProxy
> child_message_loop_proxy_
;
277 // IO thread message loop.
278 scoped_refptr
<base::MessageLoopProxy
> io_message_loop_proxy_
;
280 // WeakPtr<> pointing to |this| for use in posting tasks from the decoder or
281 // device worker threads back to the child thread.
282 base::WeakPtr
<V4L2SliceVideoDecodeAccelerator
> weak_this_
;
284 // To expose client callbacks from VideoDecodeAccelerator.
285 // NOTE: all calls to these objects *MUST* be executed on
286 // child_message_loop_proxy_.
287 scoped_ptr
<base::WeakPtrFactory
<VideoDecodeAccelerator::Client
>>
289 base::WeakPtr
<VideoDecodeAccelerator::Client
> client_
;
290 // Callbacks to |io_client_| must be executed on |io_message_loop_proxy_|.
291 base::WeakPtr
<Client
> io_client_
;
293 // V4L2 device in use.
294 scoped_refptr
<V4L2Device
> device_
;
296 // Thread to communicate with the device on.
297 base::Thread decoder_thread_
;
298 scoped_refptr
<base::MessageLoopProxy
> decoder_thread_proxy_
;
300 // Thread used to poll the device for events.
301 base::Thread device_poll_thread_
;
303 // Input queue state.
304 bool input_streamon_
;
305 // Number of input buffers enqueued to the device.
306 int input_buffer_queued_count_
;
307 // Input buffers ready to use; LIFO since we don't care about ordering.
308 std::list
<int> free_input_buffers_
;
309 // Mapping of int index to an input buffer record.
310 std::vector
<InputRecord
> input_buffer_map_
;
312 // Output queue state.
313 bool output_streamon_
;
314 // Number of output buffers enqueued to the device.
315 int output_buffer_queued_count_
;
316 // Output buffers ready to use.
317 std::list
<int> free_output_buffers_
;
318 // Mapping of int index to an output buffer record.
319 std::vector
<OutputRecord
> output_buffer_map_
;
321 media::VideoCodecProfile video_profile_
;
322 uint32_t output_format_fourcc_
;
323 gfx::Size visible_size_
;
324 gfx::Size coded_size_
;
326 struct BitstreamBufferRef
;
327 // Input queue of stream buffers coming from the client.
328 std::queue
<linked_ptr
<BitstreamBufferRef
>> decoder_input_queue_
;
329 // BitstreamBuffer currently being processed.
330 scoped_ptr
<BitstreamBufferRef
> decoder_current_bitstream_buffer_
;
332 // Queue storing decode surfaces ready to be output as soon as they are
333 // decoded. The surfaces must be output in order they are queued.
334 std::queue
<scoped_refptr
<V4L2DecodeSurface
>> decoder_display_queue_
;
339 // If any of these are true, we are waiting for the device to finish decoding
340 // all previously-queued frames, so we can finish the flush/reset/surface
341 // change flows. These can stack.
342 bool decoder_flushing_
;
343 bool decoder_resetting_
;
344 bool surface_set_change_pending_
;
346 // Hardware accelerators.
347 // TODO(posciak): Try to have a superclass here if possible.
348 scoped_ptr
<V4L2H264Accelerator
> h264_accelerator_
;
349 scoped_ptr
<V4L2VP8Accelerator
> vp8_accelerator_
;
351 // Codec-specific software decoder in use.
352 scoped_ptr
<AcceleratedVideoDecoder
> decoder_
;
354 // Surfaces queued to device to keep references to them while decoded.
355 using V4L2DecodeSurfaceByOutputId
=
356 std::map
<int, scoped_refptr
<V4L2DecodeSurface
>>;
357 V4L2DecodeSurfaceByOutputId surfaces_at_device_
;
359 // Surfaces sent to client to keep references to them while displayed.
360 using V4L2DecodeSurfaceByPictureBufferId
=
361 std::map
<int32
, scoped_refptr
<V4L2DecodeSurface
>>;
362 V4L2DecodeSurfaceByPictureBufferId surfaces_at_display_
;
364 // Record for decoded pictures that can be sent to PictureReady.
365 struct PictureRecord
;
366 // Pictures that are ready but not sent to PictureReady yet.
367 std::queue
<PictureRecord
> pending_picture_ready_
;
369 // The number of pictures that are sent to PictureReady and will be cleared.
370 int picture_clearing_count_
;
372 // Used by the decoder thread to wait for AssignPictureBuffers to arrive
373 // to avoid races with potential Reset requests.
374 base::WaitableEvent pictures_assigned_
;
376 // Make the GL context current callback.
377 base::Callback
<bool(void)> make_context_current_
;
380 EGLDisplay egl_display_
;
381 EGLContext egl_context_
;
383 // The WeakPtrFactory for |weak_this_|.
384 base::WeakPtrFactory
<V4L2SliceVideoDecodeAccelerator
> weak_this_factory_
;
386 DISALLOW_COPY_AND_ASSIGN(V4L2SliceVideoDecodeAccelerator
);
389 class V4L2H264Picture
;
390 class V4L2VP8Picture
;
392 } // namespace content
394 #endif // CONTENT_COMMON_GPU_MEDIA_V4L2_SLICE_VIDEO_DECODE_ACCELERATOR_H_