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

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

Issue 104713014: VDA: Restructure EVDA (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years 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 (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
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
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
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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698