Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // This file contains an implementation of VideoDecoderAccelerator | 5 // This file contains an implementation of VideoDecoderAccelerator |
| 6 // that utilizes the hardware video decoder present on the Exynos SoC. | 6 // that utilizes the hardware video decoder present on the Exynos SoC. |
|
Pawel Osciak
2014/01/07 04:16:27
There are two remaining mentions of "Exynos" in th
| |
| 7 | 7 |
| 8 #ifndef CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_DECODE_ACCELERATOR_H_ | 8 #ifndef CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_DECODE_ACCELERATOR_H_ |
| 9 #define CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_DECODE_ACCELERATOR_H_ | 9 #define CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_DECODE_ACCELERATOR_H_ |
| 10 | 10 |
| 11 #include <queue> | 11 #include <queue> |
| 12 #include <vector> | 12 #include <vector> |
| 13 | 13 |
| 14 #include "base/callback_forward.h" | 14 #include "base/callback_forward.h" |
| 15 #include "base/memory/linked_ptr.h" | 15 #include "base/memory/linked_ptr.h" |
| 16 #include "base/memory/scoped_ptr.h" | 16 #include "base/memory/scoped_ptr.h" |
| 17 #include "base/threading/thread.h" | 17 #include "base/threading/thread.h" |
| 18 #include "content/common/content_export.h" | 18 #include "content/common/content_export.h" |
| 19 #include "content/common/gpu/media/video_decode_accelerator_impl.h" | 19 #include "content/common/gpu/media/video_decode_accelerator_impl.h" |
| 20 #include "media/base/limits.h" | 20 #include "media/base/limits.h" |
| 21 #include "media/base/video_decoder_config.h" | 21 #include "media/base/video_decoder_config.h" |
| 22 #include "media/video/picture.h" | 22 #include "media/video/picture.h" |
| 23 #include "ui/gfx/size.h" | 23 #include "ui/gfx/size.h" |
| 24 #include "ui/gl/gl_bindings.h" | 24 #include "ui/gl/gl_bindings.h" |
| 25 | 25 |
| 26 namespace base { | 26 namespace base { |
| 27 class MessageLoopProxy; | 27 class MessageLoopProxy; |
| 28 } | 28 } |
| 29 | 29 |
| 30 namespace content { | 30 namespace content { |
| 31 class H264Parser; | 31 class H264Parser; |
| 32 | 32 |
| 33 // This class handles Exynos video acceleration directly through the V4L2 | 33 // This class handles Exynos video acceleration directly through the V4L2 |
| 34 // device exported by the Multi Format Codec hardware block. | 34 // device exported by the Multi Format Codec hardware block. |
|
Pawel Osciak
2014/01/07 04:16:27
"This class handles video accelerators directly th
| |
| 35 // | 35 // |
| 36 // The threading model of this class is driven by the fact that it needs to | 36 // The threading model of this class is driven by the fact that it needs to |
| 37 // interface two fundamentally different event queues -- the one Chromium | 37 // interface two fundamentally different event queues -- the one Chromium |
| 38 // provides through MessageLoop, and the one driven by the V4L2 devices which | 38 // provides through MessageLoop, and the one driven by the V4L2 devices which |
| 39 // is waited on with epoll(). There are three threads involved in this class: | 39 // is waited on with epoll(). There are three threads involved in this class: |
| 40 // | 40 // |
| 41 // * The child thread, which is the main GPU process thread which calls the | 41 // * The child thread, which is the main GPU process thread which calls the |
| 42 // media::VideoDecodeAccelerator entry points. Calls from this thread | 42 // media::VideoDecodeAccelerator entry points. Calls from this thread |
| 43 // generally do not block (with the exception of Initialize() and Destroy()). | 43 // generally do not block (with the exception of Initialize() and Destroy()). |
| 44 // They post tasks to the decoder_thread_, which actually services the task | 44 // They post tasks to the decoder_thread_, which actually services the task |
| 45 // and calls back when complete through the | 45 // and calls back when complete through the |
| 46 // media::VideoDecodeAccelerator::Client interface. | 46 // media::VideoDecodeAccelerator::Client interface. |
| 47 // * The decoder_thread_, owned by this class. It services API tasks, through | 47 // * The decoder_thread_, owned by this class. It services API tasks, through |
| 48 // the *Task() routines, as well as V4L2 device events, through | 48 // the *Task() routines, as well as V4L2 device events, through |
| 49 // ServiceDeviceTask(). Almost all state modification is done on this thread. | 49 // ServiceDeviceTask(). Almost all state modification is done on this thread. |
| 50 // * The device_poll_thread_, owned by this class. All it does is epoll() on | 50 // * The device_poll_thread_, owned by this class. All it does is epoll() on |
| 51 // the V4L2 in DevicePollTask() and schedule a ServiceDeviceTask() on the | 51 // the V4L2 in DevicePollTask() and schedule a ServiceDeviceTask() on the |
| 52 // decoder_thread_ when something interesting happens. | 52 // decoder_thread_ when something interesting happens. |
| 53 // TODO(sheu): replace this thread with an TYPE_IO decoder_thread_. | 53 // TODO(sheu): replace this thread with an TYPE_IO decoder_thread_. |
| 54 // | 54 // |
| 55 // Note that this class has no locks! Everything's serviced on the | 55 // Note that this class has no locks! Everything's serviced on the |
| 56 // decoder_thread_, so there are no synchronization issues. | 56 // decoder_thread_, so there are no synchronization issues. |
| 57 // ... well, there are, but it's a matter of getting messages posted in the | 57 // ... well, there are, but it's a matter of getting messages posted in the |
| 58 // right order, not fiddling with locks. | 58 // right order, not fiddling with locks. |
| 59 class CONTENT_EXPORT ExynosVideoDecodeAccelerator | 59 class CONTENT_EXPORT V4l2VideoDecodeAccelerator |
|
Pawel Osciak
2014/01/07 04:16:27
Nit: I think we might prefer V4L2 (with capital "L
shivdasp
2014/01/07 04:31:14
Done.
| |
| 60 : public VideoDecodeAcceleratorImpl { | 60 : public VideoDecodeAcceleratorImpl { |
| 61 public: | 61 public: |
| 62 ExynosVideoDecodeAccelerator( | 62 V4l2VideoDecodeAccelerator( |
| 63 EGLDisplay egl_display, | 63 EGLDisplay egl_display, |
| 64 Client* client, | 64 Client* client, |
| 65 const base::WeakPtr<Client>& io_client_, | 65 const base::WeakPtr<Client>& io_client_, |
| 66 const base::Callback<bool(void)>& make_context_current, | 66 const base::Callback<bool(void)>& make_context_current, |
| 67 const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy); | 67 const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy); |
| 68 virtual ~ExynosVideoDecodeAccelerator(); | 68 virtual ~V4l2VideoDecodeAccelerator(); |
| 69 | 69 |
| 70 // media::VideoDecodeAccelerator implementation. | 70 // media::VideoDecodeAccelerator implementation. |
| 71 // Note: Initialize() and Destroy() are synchronous. | 71 // Note: Initialize() and Destroy() are synchronous. |
| 72 virtual bool Initialize(media::VideoCodecProfile profile) OVERRIDE; | 72 virtual bool Initialize(media::VideoCodecProfile profile) OVERRIDE; |
| 73 virtual void Decode(const media::BitstreamBuffer& bitstream_buffer) OVERRIDE; | 73 virtual void Decode(const media::BitstreamBuffer& bitstream_buffer) OVERRIDE; |
| 74 virtual void AssignPictureBuffers( | 74 virtual void AssignPictureBuffers( |
| 75 const std::vector<media::PictureBuffer>& buffers) OVERRIDE; | 75 const std::vector<media::PictureBuffer>& buffers) OVERRIDE; |
| 76 virtual void ReusePictureBuffer(int32 picture_buffer_id) OVERRIDE; | 76 virtual void ReusePictureBuffer(int32 picture_buffer_id) OVERRIDE; |
| 77 virtual void Flush() OVERRIDE; | 77 virtual void Flush() OVERRIDE; |
| 78 virtual void Reset() OVERRIDE; | 78 virtual void Reset() OVERRIDE; |
| 79 virtual void Destroy() OVERRIDE; | 79 virtual void Destroy() OVERRIDE; |
| 80 | 80 |
| 81 // VideoDecodeAcceleratorImpl implementation. | 81 // VideoDecodeAcceleratorImpl implementation. |
| 82 virtual bool CanDecodeOnIOThread() OVERRIDE; | 82 virtual bool CanDecodeOnIOThread() OVERRIDE; |
| 83 | 83 |
| 84 private: | 84 private: |
| 85 // These are rather subjectively tuned. | 85 // These are rather subjectively tuned. |
| 86 enum { | 86 enum { |
| 87 kMfcInputBufferCount = 8, | 87 kMfcInputBufferCount = 8, |
|
Pawel Osciak
2014/01/07 04:16:27
I'm leaning towards renaming MFC -> Decoder everyw
shivdasp
2014/01/07 04:31:14
Should we replace "MFC" with "Decoder" for members
Pawel Osciak
2014/01/07 04:35:48
Good point. I agree.
| |
| 88 // TODO(posciak): determine MFC input buffer size based on level limits. | 88 // TODO(posciak): determine MFC input buffer size based on level limits. |
| 89 // See http://crbug.com/255116. | 89 // See http://crbug.com/255116. |
| 90 kMfcInputBufferMaxSize = 1024 * 1024, | 90 kMfcInputBufferMaxSize = 1024 * 1024, |
| 91 // Number of output buffers to use for each VDA stage above what's required | 91 // Number of output buffers to use for each VDA stage above what's required |
| 92 // by the decoder (e.g. DPB size, in H264). We need | 92 // by the decoder (e.g. DPB size, in H264). We need |
| 93 // media::limits::kMaxVideoFrames to fill up the GpuVideoDecode pipeline, | 93 // media::limits::kMaxVideoFrames to fill up the GpuVideoDecode pipeline, |
| 94 // and +1 for a frame in transit. | 94 // and +1 for a frame in transit. |
| 95 kDpbOutputBufferExtraCount = media::limits::kMaxVideoFrames + 1, | 95 kDpbOutputBufferExtraCount = media::limits::kMaxVideoFrames + 1, |
| 96 }; | 96 }; |
| 97 | 97 |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 295 | 295 |
| 296 // Message loop of the IO thread. | 296 // Message loop of the IO thread. |
| 297 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; | 297 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; |
| 298 | 298 |
| 299 // WeakPtr<> pointing to |this| for use in posting tasks from the decoder or | 299 // WeakPtr<> pointing to |this| for use in posting tasks from the decoder or |
| 300 // device worker threads back to the child thread. Because the worker threads | 300 // device worker threads back to the child thread. Because the worker threads |
| 301 // are members of this class, any task running on those threads is guaranteed | 301 // are members of this class, any task running on those threads is guaranteed |
| 302 // that this object is still alive. As a result, tasks posted from the child | 302 // that this object is still alive. As a result, tasks posted from the child |
| 303 // thread to the decoder or device thread should use base::Unretained(this), | 303 // thread to the decoder or device thread should use base::Unretained(this), |
| 304 // and tasks posted the other way should use |weak_this_|. | 304 // and tasks posted the other way should use |weak_this_|. |
| 305 base::WeakPtr<ExynosVideoDecodeAccelerator> weak_this_; | 305 base::WeakPtr<V4l2VideoDecodeAccelerator> weak_this_; |
| 306 | 306 |
| 307 // To expose client callbacks from VideoDecodeAccelerator. | 307 // To expose client callbacks from VideoDecodeAccelerator. |
| 308 // NOTE: all calls to these objects *MUST* be executed on | 308 // NOTE: all calls to these objects *MUST* be executed on |
| 309 // child_message_loop_proxy_. | 309 // child_message_loop_proxy_. |
| 310 base::WeakPtrFactory<Client> client_ptr_factory_; | 310 base::WeakPtrFactory<Client> client_ptr_factory_; |
| 311 base::WeakPtr<Client> client_; | 311 base::WeakPtr<Client> client_; |
| 312 // Callbacks to |io_client_| must be executed on |io_message_loop_proxy_|. | 312 // Callbacks to |io_client_| must be executed on |io_message_loop_proxy_|. |
| 313 base::WeakPtr<Client> io_client_; | 313 base::WeakPtr<Client> io_client_; |
| 314 | 314 |
| 315 // | 315 // |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 412 | 412 |
| 413 // Make our context current before running any EGL entry points. | 413 // Make our context current before running any EGL entry points. |
| 414 base::Callback<bool(void)> make_context_current_; | 414 base::Callback<bool(void)> make_context_current_; |
| 415 | 415 |
| 416 // EGL state | 416 // EGL state |
| 417 EGLDisplay egl_display_; | 417 EGLDisplay egl_display_; |
| 418 | 418 |
| 419 // The codec we'll be decoding for. | 419 // The codec we'll be decoding for. |
| 420 media::VideoCodecProfile video_profile_; | 420 media::VideoCodecProfile video_profile_; |
| 421 | 421 |
| 422 DISALLOW_COPY_AND_ASSIGN(ExynosVideoDecodeAccelerator); | 422 DISALLOW_COPY_AND_ASSIGN(V4l2VideoDecodeAccelerator); |
| 423 }; | 423 }; |
| 424 | 424 |
| 425 } // namespace content | 425 } // namespace content |
| 426 | 426 |
| 427 #endif // CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_DECODE_ACCELERATOR_H_ | 427 #endif // CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_DECODE_ACCELERATOR_H_ |
| OLD | NEW |