OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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_ |
OLD | NEW |