ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / content / common / gpu / media / v4l2_slice_video_decode_accelerator.h
blob2fdefe9297b5d3fe24e0175887344d8df26e3f8e
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>
9 #include <queue>
10 #include <vector>
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"
24 namespace content {
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 {
32 public:
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;
56 private:
57 class V4L2H264Accelerator;
58 class V4L2VP8Accelerator;
60 // Record for input buffers.
61 struct InputRecord {
62 InputRecord();
63 int32 input_id;
64 void* address;
65 size_t length;
66 size_t bytes_used;
67 bool at_device;
70 // Record for output buffers.
71 struct OutputRecord {
72 OutputRecord();
73 bool at_device;
74 bool at_client;
75 int32 picture_id;
76 EGLImageKHR egl_image;
77 EGLSyncKHR egl_sync;
78 bool cleared;
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.
124 void Dequeue();
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.
131 bool SetupFormats();
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
142 // PictureBuffers.
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);
167 void DestroyTask();
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.
178 void FlushTask();
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.
189 void ResetTask();
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);
213 enum State {
214 // We are in this state until Initialize() returns successfully.
215 // We can't post errors to the client in this state yet.
216 kUninitialized,
217 // Initialize() returned successfully.
218 kInitialized,
219 // This state allows making progress decoding more input stream.
220 kDecoding,
221 // Transitional state when we are not decoding any more stream, but are
222 // performing flush, reset, resolution change or are destroying ourselves.
223 kIdle,
224 // Error state, set when sending NotifyError to client.
225 kError,
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>>
288 client_ptr_factory_;
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_;
336 // Decoder state.
337 State state_;
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_;
379 // EGL state
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_