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. |
| 7 | 7 |
| 8 #ifndef CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_DECODE_ACCELERATOR_H_ | 8 #ifndef CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_DECODE_ACCELERATOR_H_ |
| 9 #define CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_DECODE_ACCELERATOR_H_ | 9 #define CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_DECODE_ACCELERATOR_H_ |
| 10 | 10 |
| 11 #include <queue> | 11 #include <queue> |
| 12 #include <vector> | 12 #include <vector> |
| 13 #include <poll.h> | |
|
Pawel Osciak
2013/12/24 03:45:24
Please keep lexicographical order.
In general, pl
| |
| 13 | 14 |
| 14 #include "base/callback_forward.h" | 15 #include "base/callback_forward.h" |
| 15 #include "base/memory/linked_ptr.h" | 16 #include "base/memory/linked_ptr.h" |
| 16 #include "base/memory/scoped_ptr.h" | 17 #include "base/memory/scoped_ptr.h" |
| 17 #include "base/threading/thread.h" | 18 #include "base/threading/thread.h" |
| 18 #include "content/common/content_export.h" | 19 #include "content/common/content_export.h" |
| 19 #include "content/common/gpu/media/video_decode_accelerator_impl.h" | 20 #include "content/common/gpu/media/video_decode_accelerator_impl.h" |
| 20 #include "media/base/limits.h" | 21 #include "media/base/limits.h" |
| 21 #include "media/base/video_decoder_config.h" | 22 #include "media/base/video_decoder_config.h" |
| 22 #include "media/video/picture.h" | 23 #include "media/video/picture.h" |
| 23 #include "ui/gfx/size.h" | 24 #include "ui/gfx/size.h" |
| 24 #include "ui/gl/gl_bindings.h" | 25 #include "ui/gl/gl_bindings.h" |
| 25 | 26 |
| 26 namespace base { | 27 namespace base { |
| 27 class MessageLoopProxy; | 28 class MessageLoopProxy; |
| 28 } | 29 } |
| 29 | 30 |
| 30 namespace content { | 31 namespace content { |
| 32 | |
| 33 class V4L2Device { | |
|
Pawel Osciak
2013/12/24 03:45:24
Please either make the interface a nested class in
| |
| 34 public : | |
|
Pawel Osciak
2013/12/24 03:45:24
Coding style for class definitions: http://google-
| |
| 35 virtual int dev_open(const char *fd,int flags) = 0; | |
|
Pawel Osciak
2013/12/24 03:45:24
Please add documentation for all members.
Pawel Osciak
2013/12/24 03:45:24
Style, method names: http://google-styleguide.goog
| |
| 36 virtual int dev_close (int fd) = 0; | |
|
Pawel Osciak
2013/12/24 03:45:24
Does the client of this class need to be aware of
| |
| 37 virtual int dev_ioctl (int fd, int flags, void *arg) = 0; | |
| 38 virtual int dev_poll (struct pollfd *fds, nfds_t nfds, int n) = 0; | |
|
Pawel Osciak
2013/12/24 03:45:24
Similarly, we should be able to spare the client a
| |
| 39 virtual bool SetDevicePollInterrupt(int fd) = 0; | |
| 40 virtual bool ClearDevicePollInterrupt(int fd) = 0; | |
| 41 virtual void *dev_mmap (void *addr, | |
| 42 unsigned int len, int prot, int flags, int fd, unsigned int offset) = 0; | |
|
Pawel Osciak
2013/12/24 03:45:24
Parameter stale wrapping is wrong, please see:
htt
| |
| 43 virtual void dev_munmap (void *addr, unsigned int len); | |
| 44 }; | |
|
Pawel Osciak
2013/12/24 03:45:24
Please also, as I mentioned before, have a factory
| |
| 45 | |
| 31 class H264Parser; | 46 class H264Parser; |
| 32 | 47 |
| 33 // This class handles Exynos video acceleration directly through the V4L2 | 48 // This class handles Exynos video acceleration directly through the V4L2 |
| 34 // device exported by the Multi Format Codec hardware block. | 49 // device exported by the Multi Format Codec hardware block. |
| 35 // | 50 // |
| 36 // The threading model of this class is driven by the fact that it needs to | 51 // 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 | 52 // interface two fundamentally different event queues -- the one Chromium |
| 38 // provides through MessageLoop, and the one driven by the V4L2 devices which | 53 // 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: | 54 // is waited on with epoll(). There are three threads involved in this class: |
| 40 // | 55 // |
| 41 // * The child thread, which is the main GPU process thread which calls the | 56 // * The child thread, which is the main GPU process thread which calls the |
| 42 // media::VideoDecodeAccelerator entry points. Calls from this thread | 57 // media::VideoDecodeAccelerator entry points. Calls from this thread |
| 43 // generally do not block (with the exception of Initialize() and Destroy()). | 58 // generally do not block (with the exception of Initialize() and Destroy()). |
| 44 // They post tasks to the decoder_thread_, which actually services the task | 59 // They post tasks to the decoder_thread_, which actually services the task |
| 45 // and calls back when complete through the | 60 // and calls back when complete through the |
| 46 // media::VideoDecodeAccelerator::Client interface. | 61 // media::VideoDecodeAccelerator::Client interface. |
| 47 // * The decoder_thread_, owned by this class. It services API tasks, through | 62 // * The decoder_thread_, owned by this class. It services API tasks, through |
| 48 // the *Task() routines, as well as V4L2 device events, through | 63 // the *Task() routines, as well as V4L2 device events, through |
| 49 // ServiceDeviceTask(). Almost all state modification is done on this thread. | 64 // 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 | 65 // * 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 | 66 // the V4L2 in DevicePollTask() and schedule a ServiceDeviceTask() on the |
| 52 // decoder_thread_ when something interesting happens. | 67 // decoder_thread_ when something interesting happens. |
| 53 // TODO(sheu): replace this thread with an TYPE_IO decoder_thread_. | 68 // TODO(sheu): replace this thread with an TYPE_IO decoder_thread_. |
| 54 // | 69 // |
| 55 // Note that this class has no locks! Everything's serviced on the | 70 // Note that this class has no locks! Everything's serviced on the |
| 56 // decoder_thread_, so there are no synchronization issues. | 71 // decoder_thread_, so there are no synchronization issues. |
| 57 // ... well, there are, but it's a matter of getting messages posted in the | 72 // ... well, there are, but it's a matter of getting messages posted in the |
| 58 // right order, not fiddling with locks. | 73 // right order, not fiddling with locks. |
| 59 class CONTENT_EXPORT ExynosVideoDecodeAccelerator | 74 class CONTENT_EXPORT V4L2VideoDecodeAccelerator |
| 60 : public VideoDecodeAcceleratorImpl { | 75 : public VideoDecodeAcceleratorImpl { |
| 61 public: | 76 public: |
| 62 ExynosVideoDecodeAccelerator( | 77 V4L2VideoDecodeAccelerator( |
| 63 EGLDisplay egl_display, | 78 EGLDisplay egl_display, |
| 64 EGLContext egl_context, | |
|
Pawel Osciak
2013/12/24 03:45:24
You are not rebased on top of ToT if you still hav
| |
| 65 Client* client, | 79 Client* client, |
| 66 const base::WeakPtr<Client>& io_client_, | 80 const base::WeakPtr<Client>& io_client_, |
| 67 const base::Callback<bool(void)>& make_context_current, | 81 const base::Callback<bool(void)>& make_context_current, |
| 68 const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy); | 82 const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy); |
| 69 virtual ~ExynosVideoDecodeAccelerator(); | 83 virtual ~V4L2VideoDecodeAccelerator(); |
| 70 | 84 |
| 71 // media::VideoDecodeAccelerator implementation. | 85 // media::VideoDecodeAccelerator implementation. |
| 72 // Note: Initialize() and Destroy() are synchronous. | 86 // Note: Initialize() and Destroy() are synchronous. |
| 73 virtual bool Initialize(media::VideoCodecProfile profile) OVERRIDE; | 87 virtual bool Initialize(media::VideoCodecProfile profile) OVERRIDE; |
| 74 virtual void Decode(const media::BitstreamBuffer& bitstream_buffer) OVERRIDE; | 88 virtual void Decode(const media::BitstreamBuffer& bitstream_buffer) OVERRIDE; |
| 75 virtual void AssignPictureBuffers( | 89 virtual void AssignPictureBuffers( |
| 76 const std::vector<media::PictureBuffer>& buffers) OVERRIDE; | 90 const std::vector<media::PictureBuffer>& buffers) OVERRIDE; |
| 77 virtual void ReusePictureBuffer(int32 picture_buffer_id) OVERRIDE; | 91 virtual void ReusePictureBuffer(int32 picture_buffer_id) OVERRIDE; |
| 78 virtual void Flush() OVERRIDE; | 92 virtual void Flush() OVERRIDE; |
| 79 virtual void Reset() OVERRIDE; | 93 virtual void Reset() OVERRIDE; |
| 80 virtual void Destroy() OVERRIDE; | 94 virtual void Destroy() OVERRIDE; |
| 81 | 95 |
| 82 // VideoDecodeAcceleratorImpl implementation. | 96 // VideoDecodeAcceleratorImpl implementation. |
| 83 virtual bool CanDecodeOnIOThread() OVERRIDE; | 97 virtual bool CanDecodeOnIOThread() OVERRIDE; |
| 84 | 98 |
| 99 class ExynosV4L2Device : public V4L2Device { | |
|
Pawel Osciak
2013/12/24 03:45:24
Please abstract to a separate file.
| |
| 100 public : | |
|
Pawel Osciak
2013/12/24 03:45:24
Style (indent, spacing).
| |
| 101 ExynosV4L2Device() {} | |
| 102 int dev_open(const char *fd, int flags); | |
|
Pawel Osciak
2013/12/24 03:45:24
Please use the OVERRIDE macro.
| |
| 103 int dev_close (int fd); | |
| 104 int dev_ioctl (int fd, int flags, void *arg); | |
| 105 int dev_poll (struct pollfd *fds, nfds_t nfds, int n); | |
| 106 // Set/clear the device poll interrupt (using device_poll_interrupt_fd_). | |
| 107 bool SetDevicePollInterrupt(int fd); | |
| 108 bool ClearDevicePollInterrupt(int fd); | |
| 109 void *dev_mmap (void *addr, | |
| 110 unsigned int len, int prot, int flags, int fd, unsigned int offset); | |
| 111 void dev_munmap (void *addr, unsigned int len); | |
| 112 }; | |
| 113 ExynosV4L2Device *device; | |
|
Pawel Osciak
2013/12/24 03:45:24
This should be a a scoped_ptr.
| |
| 114 | |
| 85 private: | 115 private: |
| 86 // These are rather subjectively tuned. | 116 // These are rather subjectively tuned. |
| 87 enum { | 117 enum { |
| 88 kMfcInputBufferCount = 8, | 118 kMfcInputBufferCount = 8, |
| 89 // TODO(posciak): determine MFC input buffer size based on level limits. | 119 // TODO(posciak): determine MFC input buffer size based on level limits. |
| 90 // See http://crbug.com/255116. | 120 // See http://crbug.com/255116. |
| 91 kMfcInputBufferMaxSize = 1024 * 1024, | 121 kMfcInputBufferMaxSize = 1024 * 1024, |
| 92 // Number of output buffers to use for each VDA stage above what's required | 122 // Number of output buffers to use for each VDA stage above what's required |
| 93 // by the decoder (e.g. DPB size, in H264). We need | 123 // by the decoder (e.g. DPB size, in H264). We need |
| 94 // media::limits::kMaxVideoFrames to fill up the GpuVideoDecode pipeline, | 124 // media::limits::kMaxVideoFrames to fill up the GpuVideoDecode pipeline, |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 227 void ResetDoneTask(); | 257 void ResetDoneTask(); |
| 228 | 258 |
| 229 // Device destruction task. | 259 // Device destruction task. |
| 230 void DestroyTask(); | 260 void DestroyTask(); |
| 231 | 261 |
| 232 // Attempt to start/stop device_poll_thread_. | 262 // Attempt to start/stop device_poll_thread_. |
| 233 bool StartDevicePoll(); | 263 bool StartDevicePoll(); |
| 234 // If |keep_mfc_input_state| is true, don't reset MFC input state; used during | 264 // If |keep_mfc_input_state| is true, don't reset MFC input state; used during |
| 235 // resolution change. | 265 // resolution change. |
| 236 bool StopDevicePoll(bool keep_mfc_input_state); | 266 bool StopDevicePoll(bool keep_mfc_input_state); |
| 237 // Set/clear the device poll interrupt (using device_poll_interrupt_fd_). | |
| 238 bool SetDevicePollInterrupt(); | |
| 239 bool ClearDevicePollInterrupt(); | |
| 240 | 267 |
| 241 void StartResolutionChangeIfNeeded(); | 268 void StartResolutionChangeIfNeeded(); |
| 242 void FinishResolutionChange(); | 269 void FinishResolutionChange(); |
| 243 void ResumeAfterResolutionChange(); | 270 void ResumeAfterResolutionChange(); |
| 244 | 271 |
| 245 // Try to get output format from MFC, detected after parsing the beginning | 272 // Try to get output format from MFC, detected after parsing the beginning |
| 246 // of the stream. Sets |again| to true if more parsing is needed. | 273 // of the stream. Sets |again| to true if more parsing is needed. |
| 247 bool GetFormatInfo(struct v4l2_format* format, bool* again); | 274 bool GetFormatInfo(struct v4l2_format* format, bool* again); |
| 248 // Create MFC output buffers for the given |format|. | 275 // Create MFC output buffers for the given |format|. |
| 249 bool CreateBuffersForFormat(const struct v4l2_format& format); | 276 bool CreateBuffersForFormat(const struct v4l2_format& format); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 296 | 323 |
| 297 // Message loop of the IO thread. | 324 // Message loop of the IO thread. |
| 298 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; | 325 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; |
| 299 | 326 |
| 300 // WeakPtr<> pointing to |this| for use in posting tasks from the decoder or | 327 // WeakPtr<> pointing to |this| for use in posting tasks from the decoder or |
| 301 // device worker threads back to the child thread. Because the worker threads | 328 // device worker threads back to the child thread. Because the worker threads |
| 302 // are members of this class, any task running on those threads is guaranteed | 329 // are members of this class, any task running on those threads is guaranteed |
| 303 // that this object is still alive. As a result, tasks posted from the child | 330 // that this object is still alive. As a result, tasks posted from the child |
| 304 // thread to the decoder or device thread should use base::Unretained(this), | 331 // thread to the decoder or device thread should use base::Unretained(this), |
| 305 // and tasks posted the other way should use |weak_this_|. | 332 // and tasks posted the other way should use |weak_this_|. |
| 306 base::WeakPtr<ExynosVideoDecodeAccelerator> weak_this_; | 333 base::WeakPtr<V4L2VideoDecodeAccelerator> weak_this_; |
| 307 | 334 |
| 308 // To expose client callbacks from VideoDecodeAccelerator. | 335 // To expose client callbacks from VideoDecodeAccelerator. |
| 309 // NOTE: all calls to these objects *MUST* be executed on | 336 // NOTE: all calls to these objects *MUST* be executed on |
| 310 // child_message_loop_proxy_. | 337 // child_message_loop_proxy_. |
| 311 base::WeakPtrFactory<Client> client_ptr_factory_; | 338 base::WeakPtrFactory<Client> client_ptr_factory_; |
| 312 base::WeakPtr<Client> client_; | 339 base::WeakPtr<Client> client_; |
| 313 // Callbacks to |io_client_| must be executed on |io_message_loop_proxy_|. | 340 // Callbacks to |io_client_| must be executed on |io_message_loop_proxy_|. |
| 314 base::WeakPtr<Client> io_client_; | 341 base::WeakPtr<Client> io_client_; |
| 315 | 342 |
| 316 // | 343 // |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 356 | 383 |
| 357 // | 384 // |
| 358 // Hardware state and associated queues. Since decoder_thread_ services | 385 // Hardware state and associated queues. Since decoder_thread_ services |
| 359 // the hardware, decoder_thread_ owns these too. | 386 // the hardware, decoder_thread_ owns these too. |
| 360 // | 387 // |
| 361 | 388 |
| 362 // Completed decode buffers, waiting for MFC. | 389 // Completed decode buffers, waiting for MFC. |
| 363 std::queue<int> mfc_input_ready_queue_; | 390 std::queue<int> mfc_input_ready_queue_; |
| 364 | 391 |
| 365 // MFC decode device. | 392 // MFC decode device. |
| 366 int mfc_fd_; | 393 int videodec_fd_; |
|
Pawel Osciak
2013/12/24 03:45:24
Don't need this anymore, we are using the device c
| |
| 367 | 394 |
| 368 // MFC input buffer state. | 395 // MFC input buffer state. |
| 369 bool mfc_input_streamon_; | 396 bool mfc_input_streamon_; |
| 370 // MFC input buffers enqueued to device. | 397 // MFC input buffers enqueued to device. |
| 371 int mfc_input_buffer_queued_count_; | 398 int mfc_input_buffer_queued_count_; |
| 372 // Input buffers ready to use, as a LIFO since we don't care about ordering. | 399 // Input buffers ready to use, as a LIFO since we don't care about ordering. |
| 373 std::vector<int> mfc_free_input_buffers_; | 400 std::vector<int> mfc_free_input_buffers_; |
| 374 // Mapping of int index to MFC input buffer record. | 401 // Mapping of int index to MFC input buffer record. |
| 375 std::vector<MfcInputRecord> mfc_input_buffer_map_; | 402 std::vector<MfcInputRecord> mfc_input_buffer_map_; |
| 376 | 403 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 409 | 436 |
| 410 // | 437 // |
| 411 // Other state, held by the child (main) thread. | 438 // Other state, held by the child (main) thread. |
| 412 // | 439 // |
| 413 | 440 |
| 414 // Make our context current before running any EGL entry points. | 441 // Make our context current before running any EGL entry points. |
| 415 base::Callback<bool(void)> make_context_current_; | 442 base::Callback<bool(void)> make_context_current_; |
| 416 | 443 |
| 417 // EGL state | 444 // EGL state |
| 418 EGLDisplay egl_display_; | 445 EGLDisplay egl_display_; |
| 419 EGLContext egl_context_; | |
| 420 | 446 |
| 421 // The codec we'll be decoding for. | 447 // The codec we'll be decoding for. |
| 422 media::VideoCodecProfile video_profile_; | 448 media::VideoCodecProfile video_profile_; |
| 423 | 449 |
| 424 DISALLOW_COPY_AND_ASSIGN(ExynosVideoDecodeAccelerator); | 450 DISALLOW_COPY_AND_ASSIGN(V4L2VideoDecodeAccelerator); |
| 425 }; | 451 }; |
| 426 | 452 |
| 427 } // namespace content | 453 } // namespace content |
| 428 | 454 |
| 429 #endif // CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_DECODE_ACCELERATOR_H_ | 455 #endif // CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_DECODE_ACCELERATOR_H_ |
| OLD | NEW |