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

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

Issue 1822983002: Support external buffer import in VDA interface and add a V4L2SVDA impl. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef CONTENT_COMMON_GPU_MEDIA_V4L2_SLICE_VIDEO_DECODE_ACCELERATOR_H_ 5 #ifndef CONTENT_COMMON_GPU_MEDIA_V4L2_SLICE_VIDEO_DECODE_ACCELERATOR_H_
6 #define CONTENT_COMMON_GPU_MEDIA_V4L2_SLICE_VIDEO_DECODE_ACCELERATOR_H_ 6 #define CONTENT_COMMON_GPU_MEDIA_V4L2_SLICE_VIDEO_DECODE_ACCELERATOR_H_
7 7
8 #include <linux/videodev2.h> 8 #include <linux/videodev2.h>
9 #include <stddef.h> 9 #include <stddef.h>
10 #include <stdint.h> 10 #include <stdint.h>
11 11
12 #include <memory> 12 #include <memory>
13 #include <queue> 13 #include <queue>
14 #include <utility>
14 #include <vector> 15 #include <vector>
15 16
16 #include "base/macros.h" 17 #include "base/macros.h"
17 #include "base/memory/linked_ptr.h" 18 #include "base/memory/linked_ptr.h"
18 #include "base/memory/ref_counted.h" 19 #include "base/memory/ref_counted.h"
19 #include "base/memory/weak_ptr.h" 20 #include "base/memory/weak_ptr.h"
20 #include "base/synchronization/waitable_event.h" 21 #include "base/synchronization/waitable_event.h"
21 #include "base/threading/thread.h" 22 #include "base/threading/thread.h"
22 #include "content/common/content_export.h" 23 #include "content/common/content_export.h"
23 #include "content/common/gpu/media/gpu_video_decode_accelerator_helpers.h" 24 #include "content/common/gpu/media/gpu_video_decode_accelerator_helpers.h"
(...skipping 18 matching lines...) Expand all
42 EGLDisplay egl_display, 43 EGLDisplay egl_display,
43 const GetGLContextCallback& get_gl_context_cb, 44 const GetGLContextCallback& get_gl_context_cb,
44 const MakeGLContextCurrentCallback& make_context_current_cb); 45 const MakeGLContextCurrentCallback& make_context_current_cb);
45 ~V4L2SliceVideoDecodeAccelerator() override; 46 ~V4L2SliceVideoDecodeAccelerator() override;
46 47
47 // media::VideoDecodeAccelerator implementation. 48 // media::VideoDecodeAccelerator implementation.
48 bool Initialize(const Config& config, Client* client) override; 49 bool Initialize(const Config& config, Client* client) override;
49 void Decode(const media::BitstreamBuffer& bitstream_buffer) override; 50 void Decode(const media::BitstreamBuffer& bitstream_buffer) override;
50 void AssignPictureBuffers( 51 void AssignPictureBuffers(
51 const std::vector<media::PictureBuffer>& buffers) override; 52 const std::vector<media::PictureBuffer>& buffers) override;
53 void ImportBufferForPicture(int32_t picture_buffer_id,
54 const std::vector<gfx::GpuMemoryBufferHandle>&
55 gpu_memory_buffer_handles) override;
52 void ReusePictureBuffer(int32_t picture_buffer_id) override; 56 void ReusePictureBuffer(int32_t picture_buffer_id) override;
53 void Flush() override; 57 void Flush() override;
54 void Reset() override; 58 void Reset() override;
55 void Destroy() override; 59 void Destroy() override;
56 bool TryToSetupDecodeOnSeparateThread( 60 bool TryToSetupDecodeOnSeparateThread(
57 const base::WeakPtr<Client>& decode_client, 61 const base::WeakPtr<Client>& decode_client,
58 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) 62 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner)
59 override; 63 override;
64 media::VideoPixelFormat GetOutputFormat() const override;
60 65
61 static media::VideoDecodeAccelerator::SupportedProfiles 66 static media::VideoDecodeAccelerator::SupportedProfiles
62 GetSupportedProfiles(); 67 GetSupportedProfiles();
63 68
64 private: 69 private:
65 class V4L2H264Accelerator; 70 class V4L2H264Accelerator;
66 class V4L2VP8Accelerator; 71 class V4L2VP8Accelerator;
67 72
68 // Record for input buffers. 73 // Record for input buffers.
69 struct InputRecord { 74 struct InputRecord {
70 InputRecord(); 75 InputRecord();
71 int32_t input_id; 76 int32_t input_id;
72 void* address; 77 void* address;
73 size_t length; 78 size_t length;
74 size_t bytes_used; 79 size_t bytes_used;
75 bool at_device; 80 bool at_device;
76 }; 81 };
77 82
78 // Record for output buffers. 83 // Record for output buffers.
79 struct OutputRecord { 84 struct OutputRecord {
80 OutputRecord(); 85 OutputRecord();
81 bool at_device; 86 bool at_device;
82 bool at_client; 87 bool at_client;
83 int32_t picture_id; 88 int32_t picture_id;
89 GLuint texture_id;
84 EGLImageKHR egl_image; 90 EGLImageKHR egl_image;
85 EGLSyncKHR egl_sync; 91 EGLSyncKHR egl_sync;
92 std::vector<base::ScopedFD> dmabuf_fds;
86 bool cleared; 93 bool cleared;
87 }; 94 };
88 95
89 // See http://crbug.com/255116. 96 // See http://crbug.com/255116.
90 // Input bitstream buffer size for up to 1080p streams. 97 // Input bitstream buffer size for up to 1080p streams.
91 const size_t kInputBufferMaxSizeFor1080p = 1024 * 1024; 98 const size_t kInputBufferMaxSizeFor1080p = 1024 * 1024;
92 // Input bitstream buffer size for up to 4k streams. 99 // Input bitstream buffer size for up to 4k streams.
93 const size_t kInputBufferMaxSizeFor4k = 4 * kInputBufferMaxSizeFor1080p; 100 const size_t kInputBufferMaxSizeFor4k = 4 * kInputBufferMaxSizeFor1080p;
94 const size_t kNumInputBuffers = 16; 101 const size_t kNumInputBuffers = 16;
95 102
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 // Destroy output buffers and release associated resources (textures, 158 // Destroy output buffers and release associated resources (textures,
152 // EGLImages). If |dismiss| is true, also dismissing the associated 159 // EGLImages). If |dismiss| is true, also dismissing the associated
153 // PictureBuffers. 160 // PictureBuffers.
154 bool DestroyOutputs(bool dismiss); 161 bool DestroyOutputs(bool dismiss);
155 162
156 // Used by DestroyOutputs. 163 // Used by DestroyOutputs.
157 bool DestroyOutputBuffers(); 164 bool DestroyOutputBuffers();
158 165
159 // Dismiss all |picture_buffer_ids| via Client::DismissPictureBuffer() 166 // Dismiss all |picture_buffer_ids| via Client::DismissPictureBuffer()
160 // and signal |done| after finishing. 167 // and signal |done| after finishing.
161 void DismissPictures(std::vector<int32_t> picture_buffer_ids, 168 void DismissPictures(const std::vector<int32_t>& picture_buffer_ids,
162 base::WaitableEvent* done); 169 base::WaitableEvent* done);
163 170
164 // Task to finish initialization on decoder_thread_. 171 // Task to finish initialization on decoder_thread_.
165 void InitializeTask(); 172 void InitializeTask();
166 173
167 // Surface set change (resolution change) flow.
168 // If we have no surfaces allocated, just allocate them and return.
169 // Otherwise mark us as pending for surface set change.
170 void InitiateSurfaceSetChange();
171 // If a surface set change is pending and we are ready, stop the device,
172 // destroy outputs, releasing resources and dismissing pictures as required,
173 // followed by allocating a new set for the new resolution/DPB size
174 // as provided by decoder. Finally, try to resume decoding.
175 void FinishSurfaceSetChangeIfNeeded();
176
177 void NotifyError(Error error); 174 void NotifyError(Error error);
178 void DestroyTask(); 175 void DestroyTask();
179 176
180 // Sets the state to kError and notifies client if needed. 177 // Sets the state to kError and notifies client if needed.
181 void SetErrorState(Error error); 178 void SetErrorState(Error error);
182 179
180 // Event handling. Events include flush, reset and resolution change and are
181 // processed while in kIdle state.
182
183 // Surface set change (resolution change) flow.
184 // If we have no surfaces allocated, start it immediately, otherwise mark
185 // ourselves as pending for surface set change.
186 void InitiateSurfaceSetChange();
187 // If a surface set change is pending and we are ready, stop the device,
188 // destroy outputs, releasing resources and dismissing pictures as required,
189 // followed by starting the flow to allocate a new set for the current
190 // resolution/DPB size, as provided by decoder.
191 bool FinishSurfaceSetChange();
192
183 // Flush flow when requested by client. 193 // Flush flow when requested by client.
184 // When Flush() is called, it posts a FlushTask, which checks the input queue. 194 // When Flush() is called, it posts a FlushTask, which checks the input queue.
185 // If nothing is pending for decode on decoder_input_queue_, we call 195 // If nothing is pending for decode on decoder_input_queue_, we call
186 // InitiateFlush() directly. Otherwise, we push a dummy BitstreamBufferRef 196 // InitiateFlush() directly. Otherwise, we push a dummy BitstreamBufferRef
187 // onto the decoder_input_queue_ to schedule a flush. When we reach it later 197 // onto the decoder_input_queue_ to schedule a flush. When we reach it later
188 // on, we call InitiateFlush() to perform it at the correct time. 198 // on, we call InitiateFlush() to perform it at the correct time.
189 void FlushTask(); 199 void FlushTask();
190 // Tell the decoder to flush all frames, reset it and mark us as scheduled 200 // Tell the decoder to flush all frames, reset it and mark us as scheduled
191 // for flush, so that we can finish it once all pending decodes are finished. 201 // for flush, so that we can finish it once all pending decodes are finished.
192 void InitiateFlush(); 202 void InitiateFlush();
193 // If all pending frames are decoded and we are waiting to flush, perform it. 203 // To be called if decoder_flushing_ is true. If not all pending frames are
194 // This will send all pending pictures to client and notify the client that 204 // decoded, return false, requesting the caller to try again later.
195 // flush is complete and puts us in a state ready to resume. 205 // Otherwise perform flush by sending all pending pictures to the client,
196 void FinishFlushIfNeeded(); 206 // notify it that flush is finished and return true, informing the caller
207 // that further progress can be made.
208 bool FinishFlush();
197 209
198 // Reset flow when requested by client. 210 // Reset flow when requested by client.
199 // Drop all inputs and reset the decoder and mark us as pending for reset. 211 // Drop all inputs, reset the decoder and mark us as pending for reset.
200 void ResetTask(); 212 void ResetTask();
201 // If all pending frames are decoded and we are waiting to reset, perform it. 213 // To be called if decoder_resetting_ is true. If not all pending frames are
202 // This drops all pending outputs (client is not interested anymore), 214 // decoded, return false, requesting the caller to try again later.
203 // notifies the client we are done and puts us in a state ready to resume. 215 // Otherwise perform reset by dropping all pending outputs (client is not
204 void FinishResetIfNeeded(); 216 // interested anymore), notifying it that reset is finished, and return true,
217 // informing the caller that further progress can be made.
218 bool FinishReset();
205 219
206 // Process pending events if any. 220 // Called when a new event is pended. Transitions us into kIdle state (if not
221 // already in it), if possible. Also starts processing events.
222 void NewEventPending();
223
224 // Called after all events are processed successfully (i.e. all Finish*()
225 // methods return true) to return to decoding state.
226 bool FinishEventProcessing();
227
228 // Process pending events, if any.
207 void ProcessPendingEventsIfNeeded(); 229 void ProcessPendingEventsIfNeeded();
208 230
231
232 // Allocate V4L2 buffers and assign them to |buffers| provided by the client
233 // via AssignPictureBuffers() on decoder thread.
234 void AssignPictureBuffersTask(
235 const std::vector<media::PictureBuffer>& buffers);
236
237 // Use buffer backed by dmabuf file descriptors in |passed_dmabuf_fds| for the
238 // OutputRecord associated with |picture_buffer_id|, taking ownership of the
239 // file descriptors.
240 void ImportBufferForPictureTask(
241 int32_t picture_buffer_id,
242 // TODO(posciak): (crbug.com/561749) we should normally be able to pass
243 // the vector by itself via std::move, but it's not possible to do this
244 // if this method is used as a callback.
245 std::unique_ptr<std::vector<base::ScopedFD>> passed_dmabuf_fds);
246
247 // Create an EGLImage for the buffer associated with V4L2 |buffer_index| and
248 // for |picture_buffer_id|, backed by dmabuf file descriptors in
249 // |passed_dmabuf_fds|, taking ownership of them.
250 // The buffer should be bound to |texture_id| and is of |size| and format
251 // described by |fourcc|.
252 void CreateEGLImageFor(
253 size_t buffer_index,
254 int32_t picture_buffer_id,
255 // TODO(posciak): (crbug.com/561749) we should normally be able to pass
256 // the vector by itself via std::move, but it's not possible to do this
257 // if this method is used as a callback.
258 std::unique_ptr<std::vector<base::ScopedFD>> passed_dmabuf_fds,
259 GLuint texture_id,
260 const gfx::Size& size,
261 uint32_t fourcc);
262
263 // Take the EGLImage |egl_image|, created for |picture_buffer_id|, and use it
264 // for OutputRecord at |buffer_index|. The buffer is backed by
265 // |passed_dmabuf_fds|, and the OutputRecord takes ownership of them.
266 void AssignEGLImage(
267 size_t buffer_index,
268 int32_t picture_buffer_id,
269 EGLImageKHR egl_image,
270 // TODO(posciak): (crbug.com/561749) we should normally be able to pass
271 // the vector by itself via std::move, but it's not possible to do this
272 // if this method is used as a callback.
273 std::unique_ptr<std::vector<base::ScopedFD>> passed_dmabuf_fds);
274
209 // Performed on decoder_thread_ as a consequence of poll() on decoder_thread_ 275 // Performed on decoder_thread_ as a consequence of poll() on decoder_thread_
210 // returning an event. 276 // returning an event.
211 void ServiceDeviceTask(); 277 void ServiceDeviceTask();
212 278
213 // Schedule poll if we have any buffers queued and the poll thread 279 // Schedule poll if we have any buffers queued and the poll thread
214 // is not stopped (on surface set change). 280 // is not stopped (on surface set change).
215 void SchedulePollIfNeeded(); 281 void SchedulePollIfNeeded();
216 282
217 // Attempt to start/stop device_poll_thread_. 283 // Attempt to start/stop device_poll_thread_.
218 bool StartDevicePoll(); 284 bool StartDevicePoll();
219 bool StopDevicePoll(bool keep_input_state); 285 bool StopDevicePoll(bool keep_input_state);
220 286
221 // Ran on device_poll_thread_ to wait for device events. 287 // Ran on device_poll_thread_ to wait for device events.
222 void DevicePollTask(bool poll_device); 288 void DevicePollTask(bool poll_device);
223 289
224 enum State { 290 enum State {
225 // We are in this state until Initialize() returns successfully. 291 // We are in this state until Initialize() returns successfully.
226 // We can't post errors to the client in this state yet. 292 // We can't post errors to the client in this state yet.
227 kUninitialized, 293 kUninitialized,
228 // Initialize() returned successfully. 294 // Initialize() returned successfully.
229 kInitialized, 295 kInitialized,
230 // This state allows making progress decoding more input stream. 296 // This state allows making progress decoding more input stream.
231 kDecoding, 297 kDecoding,
232 // Transitional state when we are not decoding any more stream, but are 298 // Transitional state when we are not decoding any more stream, but are
233 // performing flush, reset, resolution change or are destroying ourselves. 299 // performing flush, reset, resolution change or are destroying ourselves.
234 kIdle, 300 kIdle,
301 // Requested new PictureBuffers via ProvidePictureBuffers(), awaiting
302 // AssignPictureBuffers().
303 kAwaitingPictureBuffers,
235 // Error state, set when sending NotifyError to client. 304 // Error state, set when sending NotifyError to client.
236 kError, 305 kError,
237 }; 306 };
238 307
239 // Buffer id for flush buffer, queued by FlushTask(). 308 // Buffer id for flush buffer, queued by FlushTask().
240 const int kFlushBufferId = -2; 309 const int kFlushBufferId = -2;
241 310
242 // Handler for Decode() on decoder_thread_. 311 // Handler for Decode() on decoder_thread_.
243 void DecodeTask(const media::BitstreamBuffer& bitstream_buffer); 312 void DecodeTask(const media::BitstreamBuffer& bitstream_buffer);
244 313
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 // BitstreamBuffer currently being processed. 409 // BitstreamBuffer currently being processed.
341 std::unique_ptr<BitstreamBufferRef> decoder_current_bitstream_buffer_; 410 std::unique_ptr<BitstreamBufferRef> decoder_current_bitstream_buffer_;
342 411
343 // Queue storing decode surfaces ready to be output as soon as they are 412 // Queue storing decode surfaces ready to be output as soon as they are
344 // decoded. The surfaces must be output in order they are queued. 413 // decoded. The surfaces must be output in order they are queued.
345 std::queue<scoped_refptr<V4L2DecodeSurface>> decoder_display_queue_; 414 std::queue<scoped_refptr<V4L2DecodeSurface>> decoder_display_queue_;
346 415
347 // Decoder state. 416 // Decoder state.
348 State state_; 417 State state_;
349 418
419 Config::OutputMode output_mode_;
420
350 // If any of these are true, we are waiting for the device to finish decoding 421 // If any of these are true, we are waiting for the device to finish decoding
351 // all previously-queued frames, so we can finish the flush/reset/surface 422 // all previously-queued frames, so we can finish the flush/reset/surface
352 // change flows. These can stack. 423 // change flows. These can stack.
353 bool decoder_flushing_; 424 bool decoder_flushing_;
354 bool decoder_resetting_; 425 bool decoder_resetting_;
355 bool surface_set_change_pending_; 426 bool surface_set_change_pending_;
356 427
357 // Hardware accelerators. 428 // Hardware accelerators.
358 // TODO(posciak): Try to have a superclass here if possible. 429 // TODO(posciak): Try to have a superclass here if possible.
359 std::unique_ptr<V4L2H264Accelerator> h264_accelerator_; 430 std::unique_ptr<V4L2H264Accelerator> h264_accelerator_;
(...skipping 13 matching lines...) Expand all
373 V4L2DecodeSurfaceByPictureBufferId surfaces_at_display_; 444 V4L2DecodeSurfaceByPictureBufferId surfaces_at_display_;
374 445
375 // Record for decoded pictures that can be sent to PictureReady. 446 // Record for decoded pictures that can be sent to PictureReady.
376 struct PictureRecord; 447 struct PictureRecord;
377 // Pictures that are ready but not sent to PictureReady yet. 448 // Pictures that are ready but not sent to PictureReady yet.
378 std::queue<PictureRecord> pending_picture_ready_; 449 std::queue<PictureRecord> pending_picture_ready_;
379 450
380 // The number of pictures that are sent to PictureReady and will be cleared. 451 // The number of pictures that are sent to PictureReady and will be cleared.
381 int picture_clearing_count_; 452 int picture_clearing_count_;
382 453
383 // Used by the decoder thread to wait for AssignPictureBuffers to arrive
384 // to avoid races with potential Reset requests.
385 base::WaitableEvent pictures_assigned_;
386
387 // EGL state 454 // EGL state
388 EGLDisplay egl_display_; 455 EGLDisplay egl_display_;
389 456
390 // Callback to get current GLContext. 457 // Callback to get current GLContext.
391 GetGLContextCallback get_gl_context_cb_; 458 GetGLContextCallback get_gl_context_cb_;
392 // Callback to set the correct gl context. 459 // Callback to set the correct gl context.
393 MakeGLContextCurrentCallback make_context_current_cb_; 460 MakeGLContextCurrentCallback make_context_current_cb_;
394 461
395 // The WeakPtrFactory for |weak_this_|. 462 // The WeakPtrFactory for |weak_this_|.
396 base::WeakPtrFactory<V4L2SliceVideoDecodeAccelerator> weak_this_factory_; 463 base::WeakPtrFactory<V4L2SliceVideoDecodeAccelerator> weak_this_factory_;
397 464
398 DISALLOW_COPY_AND_ASSIGN(V4L2SliceVideoDecodeAccelerator); 465 DISALLOW_COPY_AND_ASSIGN(V4L2SliceVideoDecodeAccelerator);
399 }; 466 };
400 467
401 class V4L2H264Picture; 468 class V4L2H264Picture;
402 class V4L2VP8Picture; 469 class V4L2VP8Picture;
403 470
404 } // namespace content 471 } // namespace content
405 472
406 #endif // CONTENT_COMMON_GPU_MEDIA_V4L2_SLICE_VIDEO_DECODE_ACCELERATOR_H_ 473 #endif // CONTENT_COMMON_GPU_MEDIA_V4L2_SLICE_VIDEO_DECODE_ACCELERATOR_H_
OLDNEW
« no previous file with comments | « content/common/gpu/media/v4l2_device.h ('k') | content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698