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 VideoDecodeAccelerator |
6 // that utilizes the hardware video decoder present on the Exynos SoC. | 6 // that utilizes hardware video decoders, which expose Video4Linux 2 API |
| 7 // (http://linuxtv.org/downloads/v4l-dvb-apis/). |
7 | 8 |
8 #ifndef CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_DECODE_ACCELERATOR_H_ | 9 #ifndef CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_DECODE_ACCELERATOR_H_ |
9 #define CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_DECODE_ACCELERATOR_H_ | 10 #define CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_DECODE_ACCELERATOR_H_ |
10 | 11 |
11 #include <queue> | 12 #include <queue> |
12 #include <vector> | 13 #include <vector> |
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 { |
31 class H264Parser; | 32 class H264Parser; |
32 | 33 |
33 // This class handles Exynos video acceleration directly through the V4L2 | 34 // This class handles video accelerators directly through a V4L2 device exported |
34 // device exported by the Multi Format Codec hardware block. | 35 // by the hardware blocks. |
35 // | 36 // |
36 // The threading model of this class is driven by the fact that it needs to | 37 // 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 | 38 // interface two fundamentally different event queues -- the one Chromium |
38 // provides through MessageLoop, and the one driven by the V4L2 devices which | 39 // 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: | 40 // is waited on with epoll(). There are three threads involved in this class: |
40 // | 41 // |
41 // * The child thread, which is the main GPU process thread which calls the | 42 // * The child thread, which is the main GPU process thread which calls the |
42 // media::VideoDecodeAccelerator entry points. Calls from this thread | 43 // media::VideoDecodeAccelerator entry points. Calls from this thread |
43 // generally do not block (with the exception of Initialize() and Destroy()). | 44 // generally do not block (with the exception of Initialize() and Destroy()). |
44 // They post tasks to the decoder_thread_, which actually services the task | 45 // They post tasks to the decoder_thread_, which actually services the task |
45 // and calls back when complete through the | 46 // and calls back when complete through the |
46 // media::VideoDecodeAccelerator::Client interface. | 47 // media::VideoDecodeAccelerator::Client interface. |
47 // * The decoder_thread_, owned by this class. It services API tasks, through | 48 // * The decoder_thread_, owned by this class. It services API tasks, through |
48 // the *Task() routines, as well as V4L2 device events, through | 49 // the *Task() routines, as well as V4L2 device events, through |
49 // ServiceDeviceTask(). Almost all state modification is done on this thread. | 50 // 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 | 51 // * 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 | 52 // the V4L2 in DevicePollTask() and schedule a ServiceDeviceTask() on the |
52 // decoder_thread_ when something interesting happens. | 53 // decoder_thread_ when something interesting happens. |
53 // TODO(sheu): replace this thread with an TYPE_IO decoder_thread_. | 54 // TODO(sheu): replace this thread with an TYPE_IO decoder_thread_. |
54 // | 55 // |
55 // Note that this class has no locks! Everything's serviced on the | 56 // Note that this class has no locks! Everything's serviced on the |
56 // decoder_thread_, so there are no synchronization issues. | 57 // decoder_thread_, so there are no synchronization issues. |
57 // ... well, there are, but it's a matter of getting messages posted in the | 58 // ... well, there are, but it's a matter of getting messages posted in the |
58 // right order, not fiddling with locks. | 59 // right order, not fiddling with locks. |
59 class CONTENT_EXPORT ExynosVideoDecodeAccelerator | 60 class CONTENT_EXPORT V4L2VideoDecodeAccelerator |
60 : public VideoDecodeAcceleratorImpl { | 61 : public VideoDecodeAcceleratorImpl { |
61 public: | 62 public: |
62 ExynosVideoDecodeAccelerator( | 63 V4L2VideoDecodeAccelerator( |
63 EGLDisplay egl_display, | 64 EGLDisplay egl_display, |
64 Client* client, | 65 Client* client, |
65 const base::WeakPtr<Client>& io_client_, | 66 const base::WeakPtr<Client>& io_client_, |
66 const base::Callback<bool(void)>& make_context_current, | 67 const base::Callback<bool(void)>& make_context_current, |
67 const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy); | 68 const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy); |
68 virtual ~ExynosVideoDecodeAccelerator(); | 69 virtual ~V4L2VideoDecodeAccelerator(); |
69 | 70 |
70 // media::VideoDecodeAccelerator implementation. | 71 // media::VideoDecodeAccelerator implementation. |
71 // Note: Initialize() and Destroy() are synchronous. | 72 // Note: Initialize() and Destroy() are synchronous. |
72 virtual bool Initialize(media::VideoCodecProfile profile) OVERRIDE; | 73 virtual bool Initialize(media::VideoCodecProfile profile) OVERRIDE; |
73 virtual void Decode(const media::BitstreamBuffer& bitstream_buffer) OVERRIDE; | 74 virtual void Decode(const media::BitstreamBuffer& bitstream_buffer) OVERRIDE; |
74 virtual void AssignPictureBuffers( | 75 virtual void AssignPictureBuffers( |
75 const std::vector<media::PictureBuffer>& buffers) OVERRIDE; | 76 const std::vector<media::PictureBuffer>& buffers) OVERRIDE; |
76 virtual void ReusePictureBuffer(int32 picture_buffer_id) OVERRIDE; | 77 virtual void ReusePictureBuffer(int32 picture_buffer_id) OVERRIDE; |
77 virtual void Flush() OVERRIDE; | 78 virtual void Flush() OVERRIDE; |
78 virtual void Reset() OVERRIDE; | 79 virtual void Reset() OVERRIDE; |
79 virtual void Destroy() OVERRIDE; | 80 virtual void Destroy() OVERRIDE; |
80 | 81 |
81 // VideoDecodeAcceleratorImpl implementation. | 82 // VideoDecodeAcceleratorImpl implementation. |
82 virtual bool CanDecodeOnIOThread() OVERRIDE; | 83 virtual bool CanDecodeOnIOThread() OVERRIDE; |
83 | 84 |
84 private: | 85 private: |
85 // These are rather subjectively tuned. | 86 // These are rather subjectively tuned. |
86 enum { | 87 enum { |
87 kMfcInputBufferCount = 8, | 88 kInputBufferCount = 8, |
88 // TODO(posciak): determine MFC input buffer size based on level limits. | 89 // TODO(posciak): determine input buffer size based on level limits. |
89 // See http://crbug.com/255116. | 90 // See http://crbug.com/255116. |
90 kMfcInputBufferMaxSize = 1024 * 1024, | 91 kInputBufferMaxSize = 1024 * 1024, |
91 // Number of output buffers to use for each VDA stage above what's required | 92 // 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 | 93 // by the decoder (e.g. DPB size, in H264). We need |
93 // media::limits::kMaxVideoFrames to fill up the GpuVideoDecode pipeline, | 94 // media::limits::kMaxVideoFrames to fill up the GpuVideoDecode pipeline, |
94 // and +1 for a frame in transit. | 95 // and +1 for a frame in transit. |
95 kDpbOutputBufferExtraCount = media::limits::kMaxVideoFrames + 1, | 96 kDpbOutputBufferExtraCount = media::limits::kMaxVideoFrames + 1, |
96 }; | 97 }; |
97 | 98 |
98 // Internal state of the decoder. | 99 // Internal state of the decoder. |
99 enum State { | 100 enum State { |
100 kUninitialized, // Initialize() not yet called. | 101 kUninitialized, // Initialize() not yet called. |
101 kInitialized, // Initialize() returned true; ready to start decoding. | 102 kInitialized, // Initialize() returned true; ready to start decoding. |
102 kDecoding, // DecodeBufferInitial() successful; decoding frames. | 103 kDecoding, // DecodeBufferInitial() successful; decoding frames. |
103 kResetting, // Presently resetting. | 104 kResetting, // Presently resetting. |
104 kAfterReset, // After Reset(), ready to start decoding again. | 105 kAfterReset, // After Reset(), ready to start decoding again. |
105 kChangingResolution, // Performing resolution change, all remaining | 106 kChangingResolution, // Performing resolution change, all remaining |
106 // pre-change frames decoded and processed. | 107 // pre-change frames decoded and processed. |
107 kError, // Error in kDecoding state. | 108 kError, // Error in kDecoding state. |
108 }; | 109 }; |
109 | 110 |
110 enum BufferId { | 111 enum BufferId { |
111 kFlushBufferId = -2 // Buffer id for flush buffer, queued by FlushTask(). | 112 kFlushBufferId = -2 // Buffer id for flush buffer, queued by FlushTask(). |
112 }; | 113 }; |
113 | 114 |
114 // File descriptors we need to poll. | 115 // File descriptors we need to poll. |
115 enum PollFds { | 116 enum PollFds { |
116 kPollMfc = (1 << 0), | 117 kPollDecoder = (1 << 0), |
117 }; | 118 }; |
118 | 119 |
119 // Auto-destruction reference for BitstreamBuffer, for message-passing from | 120 // Auto-destruction reference for BitstreamBuffer, for message-passing from |
120 // Decode() to DecodeTask(). | 121 // Decode() to DecodeTask(). |
121 struct BitstreamBufferRef; | 122 struct BitstreamBufferRef; |
122 | 123 |
123 // Auto-destruction reference for an array of PictureBuffer, for | 124 // Auto-destruction reference for an array of PictureBuffer, for |
124 // message-passing from AssignPictureBuffers() to AssignPictureBuffersTask(). | 125 // message-passing from AssignPictureBuffers() to AssignPictureBuffersTask(). |
125 struct PictureBufferArrayRef; | 126 struct PictureBufferArrayRef; |
126 | 127 |
127 // Auto-destruction reference for EGLSync (for message-passing). | 128 // Auto-destruction reference for EGLSync (for message-passing). |
128 struct EGLSyncKHRRef; | 129 struct EGLSyncKHRRef; |
129 | 130 |
130 // Record for decoded pictures that can be sent to PictureReady. | 131 // Record for decoded pictures that can be sent to PictureReady. |
131 struct PictureRecord; | 132 struct PictureRecord; |
132 | 133 |
133 // Record for MFC input buffers. | 134 // Record for input buffers. |
134 struct MfcInputRecord { | 135 struct InputRecord { |
135 MfcInputRecord(); | 136 InputRecord(); |
136 ~MfcInputRecord(); | 137 ~InputRecord(); |
137 bool at_device; // held by device. | 138 bool at_device; // held by device. |
138 void* address; // mmap() address. | 139 void* address; // mmap() address. |
139 size_t length; // mmap() length. | 140 size_t length; // mmap() length. |
140 off_t bytes_used; // bytes filled in the mmap() segment. | 141 off_t bytes_used; // bytes filled in the mmap() segment. |
141 int32 input_id; // triggering input_id as given to Decode(). | 142 int32 input_id; // triggering input_id as given to Decode(). |
142 }; | 143 }; |
143 | 144 |
144 // Record for MFC output buffers. | 145 // Record for output buffers. |
145 struct MfcOutputRecord { | 146 struct OutputRecord { |
146 MfcOutputRecord(); | 147 OutputRecord(); |
147 ~MfcOutputRecord(); | 148 ~OutputRecord(); |
148 bool at_device; // held by device. | 149 bool at_device; // held by device. |
149 bool at_client; // held by client. | 150 bool at_client; // held by client. |
150 int fds[2]; // file descriptors for each plane. | 151 int fds[2]; // file descriptors for each plane. |
151 EGLImageKHR egl_image; // EGLImageKHR for the output buffer. | 152 EGLImageKHR egl_image; // EGLImageKHR for the output buffer. |
152 EGLSyncKHR egl_sync; // sync the compositor's use of the EGLImage. | 153 EGLSyncKHR egl_sync; // sync the compositor's use of the EGLImage. |
153 int32 picture_id; // picture buffer id as returned to PictureReady(). | 154 int32 picture_id; // picture buffer id as returned to PictureReady(). |
154 bool cleared; // Whether the texture is cleared and safe to render | 155 bool cleared; // Whether the texture is cleared and safe to render |
155 // from. See TextureManager for details. | 156 // from. See TextureManager for details. |
156 }; | 157 }; |
157 | 158 |
(...skipping 25 matching lines...) Expand all Loading... |
183 bool AppendToInputFrame(const void* data, size_t size); | 184 bool AppendToInputFrame(const void* data, size_t size); |
184 // Flush data for one decoded frame. | 185 // Flush data for one decoded frame. |
185 bool FlushInputFrame(); | 186 bool FlushInputFrame(); |
186 | 187 |
187 // Process an AssignPictureBuffers() API call. After this, the | 188 // Process an AssignPictureBuffers() API call. After this, the |
188 // device_poll_thread_ can be started safely, since we have all our | 189 // device_poll_thread_ can be started safely, since we have all our |
189 // buffers. | 190 // buffers. |
190 void AssignPictureBuffersTask(scoped_ptr<PictureBufferArrayRef> pic_buffers); | 191 void AssignPictureBuffersTask(scoped_ptr<PictureBufferArrayRef> pic_buffers); |
191 | 192 |
192 // Service I/O on the V4L2 devices. This task should only be scheduled from | 193 // Service I/O on the V4L2 devices. This task should only be scheduled from |
193 // DevicePollTask(). If |mfc_event_pending| is true, one or more events | 194 // DevicePollTask(). If |event_pending| is true, one or more events |
194 // on MFC file descriptor are pending. | 195 // on file descriptor are pending. |
195 void ServiceDeviceTask(bool mfc_event_pending); | 196 void ServiceDeviceTask(bool event_pending); |
196 // Handle the various device queues. | 197 // Handle the various device queues. |
197 void EnqueueMfc(); | 198 void Enqueue(); |
198 void DequeueMfc(); | 199 void Dequeue(); |
199 // Handle incoming MFC events. | 200 // Handle incoming events. |
200 void DequeueMfcEvents(); | 201 void DequeueEvents(); |
201 // Enqueue a buffer on the corresponding queue. | 202 // Enqueue a buffer on the corresponding queue. |
202 bool EnqueueMfcInputRecord(); | 203 bool EnqueueInputRecord(); |
203 bool EnqueueMfcOutputRecord(); | 204 bool EnqueueOutputRecord(); |
204 | 205 |
205 // Process a ReusePictureBuffer() API call. The API call create an EGLSync | 206 // Process a ReusePictureBuffer() API call. The API call create an EGLSync |
206 // object on the main (GPU process) thread; we will record this object so we | 207 // object on the main (GPU process) thread; we will record this object so we |
207 // can wait on it before reusing the buffer. | 208 // can wait on it before reusing the buffer. |
208 void ReusePictureBufferTask(int32 picture_buffer_id, | 209 void ReusePictureBufferTask(int32 picture_buffer_id, |
209 scoped_ptr<EGLSyncKHRRef> egl_sync_ref); | 210 scoped_ptr<EGLSyncKHRRef> egl_sync_ref); |
210 | 211 |
211 // Flush() task. Child thread should not submit any more buffers until it | 212 // Flush() task. Child thread should not submit any more buffers until it |
212 // receives the NotifyFlushDone callback. This task will schedule an empty | 213 // receives the NotifyFlushDone callback. This task will schedule an empty |
213 // BitstreamBufferRef (with input_id == kFlushBufferId) to perform the flush. | 214 // BitstreamBufferRef (with input_id == kFlushBufferId) to perform the flush. |
214 void FlushTask(); | 215 void FlushTask(); |
215 // Notify the client of a flush completion, if required. This should be | 216 // Notify the client of a flush completion, if required. This should be |
216 // called any time a relevant queue could potentially be emptied: see | 217 // called any time a relevant queue could potentially be emptied: see |
217 // function definition. | 218 // function definition. |
218 void NotifyFlushDoneIfNeeded(); | 219 void NotifyFlushDoneIfNeeded(); |
219 | 220 |
220 // Reset() task. This task will schedule a ResetDoneTask() that will send | 221 // Reset() task. This task will schedule a ResetDoneTask() that will send |
221 // the NotifyResetDone callback, then set the decoder state to kResetting so | 222 // the NotifyResetDone callback, then set the decoder state to kResetting so |
222 // that all intervening tasks will drain. | 223 // that all intervening tasks will drain. |
223 void ResetTask(); | 224 void ResetTask(); |
224 // ResetDoneTask() will set the decoder state back to kAfterReset, so | 225 // ResetDoneTask() will set the decoder state back to kAfterReset, so |
225 // subsequent decoding can continue. | 226 // subsequent decoding can continue. |
226 void ResetDoneTask(); | 227 void ResetDoneTask(); |
227 | 228 |
228 // Device destruction task. | 229 // Device destruction task. |
229 void DestroyTask(); | 230 void DestroyTask(); |
230 | 231 |
231 // Attempt to start/stop device_poll_thread_. | 232 // Attempt to start/stop device_poll_thread_. |
232 bool StartDevicePoll(); | 233 bool StartDevicePoll(); |
233 // If |keep_mfc_input_state| is true, don't reset MFC input state; used during | 234 // If |keep_input_state| is true, don't reset input state; used during |
234 // resolution change. | 235 // resolution change. |
235 bool StopDevicePoll(bool keep_mfc_input_state); | 236 bool StopDevicePoll(bool keep_input_state); |
236 // Set/clear the device poll interrupt (using device_poll_interrupt_fd_). | 237 // Set/clear the device poll interrupt (using device_poll_interrupt_fd_). |
237 bool SetDevicePollInterrupt(); | 238 bool SetDevicePollInterrupt(); |
238 bool ClearDevicePollInterrupt(); | 239 bool ClearDevicePollInterrupt(); |
239 | 240 |
240 void StartResolutionChangeIfNeeded(); | 241 void StartResolutionChangeIfNeeded(); |
241 void FinishResolutionChange(); | 242 void FinishResolutionChange(); |
242 void ResumeAfterResolutionChange(); | 243 void ResumeAfterResolutionChange(); |
243 | 244 |
244 // Try to get output format from MFC, detected after parsing the beginning | 245 // Try to get output format, detected after parsing the beginning |
245 // of the stream. Sets |again| to true if more parsing is needed. | 246 // of the stream. Sets |again| to true if more parsing is needed. |
246 bool GetFormatInfo(struct v4l2_format* format, bool* again); | 247 bool GetFormatInfo(struct v4l2_format* format, bool* again); |
247 // Create MFC output buffers for the given |format|. | 248 // Create output buffers for the given |format|. |
248 bool CreateBuffersForFormat(const struct v4l2_format& format); | 249 bool CreateBuffersForFormat(const struct v4l2_format& format); |
249 | 250 |
250 // | 251 // |
251 // Device tasks, to be run on device_poll_thread_. | 252 // Device tasks, to be run on device_poll_thread_. |
252 // | 253 // |
253 | 254 |
254 // The device task. | 255 // The device task. |
255 void DevicePollTask(unsigned int poll_fds); | 256 void DevicePollTask(unsigned int poll_fds); |
256 | 257 |
257 // | 258 // |
258 // Safe from any thread. | 259 // Safe from any thread. |
259 // | 260 // |
260 | 261 |
261 // Error notification (using PostTask() to child thread, if necessary). | 262 // Error notification (using PostTask() to child thread, if necessary). |
262 void NotifyError(Error error); | 263 void NotifyError(Error error); |
263 | 264 |
264 // Set the decoder_thread_ state (using PostTask to decoder thread, if | 265 // Set the decoder_thread_ state (using PostTask to decoder thread, if |
265 // necessary). | 266 // necessary). |
266 void SetDecoderState(State state); | 267 void SetDecoderState(State state); |
267 | 268 |
268 // | 269 // |
269 // Other utility functions. Called on decoder_thread_, unless | 270 // Other utility functions. Called on decoder_thread_, unless |
270 // decoder_thread_ is not yet started, in which case the child thread can call | 271 // decoder_thread_ is not yet started, in which case the child thread can call |
271 // these (e.g. in Initialize() or Destroy()). | 272 // these (e.g. in Initialize() or Destroy()). |
272 // | 273 // |
273 | 274 |
274 // Create the buffers we need. | 275 // Create the buffers we need. |
275 bool CreateMfcInputBuffers(); | 276 bool CreateInputBuffers(); |
276 bool CreateMfcOutputBuffers(); | 277 bool CreateOutputBuffers(); |
277 | 278 |
278 // | 279 // |
279 // Methods run on child thread. | 280 // Methods run on child thread. |
280 // | 281 // |
281 | 282 |
282 // Destroy buffers. | 283 // Destroy buffers. |
283 void DestroyMfcInputBuffers(); | 284 void DestroyInputBuffers(); |
284 void DestroyMfcOutputBuffers(); | 285 void DestroyOutputBuffers(); |
285 void ResolutionChangeDestroyBuffers(); | 286 void ResolutionChangeDestroyBuffers(); |
286 | 287 |
287 // Send decoded pictures to PictureReady. | 288 // Send decoded pictures to PictureReady. |
288 void SendPictureReady(); | 289 void SendPictureReady(); |
289 | 290 |
290 // Callback that indicates a picture has been cleared. | 291 // Callback that indicates a picture has been cleared. |
291 void PictureCleared(); | 292 void PictureCleared(); |
292 | 293 |
293 // Our original calling message loop for the child thread. | 294 // Our original calling message loop for the child thread. |
294 scoped_refptr<base::MessageLoopProxy> child_message_loop_proxy_; | 295 scoped_refptr<base::MessageLoopProxy> child_message_loop_proxy_; |
295 | 296 |
296 // Message loop of the IO thread. | 297 // Message loop of the IO thread. |
297 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; | 298 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; |
298 | 299 |
299 // WeakPtr<> pointing to |this| for use in posting tasks from the decoder or | 300 // 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 | 301 // 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 | 302 // 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 | 303 // 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), | 304 // thread to the decoder or device thread should use base::Unretained(this), |
304 // and tasks posted the other way should use |weak_this_|. | 305 // and tasks posted the other way should use |weak_this_|. |
305 base::WeakPtr<ExynosVideoDecodeAccelerator> weak_this_; | 306 base::WeakPtr<V4L2VideoDecodeAccelerator> weak_this_; |
306 | 307 |
307 // To expose client callbacks from VideoDecodeAccelerator. | 308 // To expose client callbacks from VideoDecodeAccelerator. |
308 // NOTE: all calls to these objects *MUST* be executed on | 309 // NOTE: all calls to these objects *MUST* be executed on |
309 // child_message_loop_proxy_. | 310 // child_message_loop_proxy_. |
310 base::WeakPtrFactory<Client> client_ptr_factory_; | 311 base::WeakPtrFactory<Client> client_ptr_factory_; |
311 base::WeakPtr<Client> client_; | 312 base::WeakPtr<Client> client_; |
312 // Callbacks to |io_client_| must be executed on |io_message_loop_proxy_|. | 313 // Callbacks to |io_client_| must be executed on |io_message_loop_proxy_|. |
313 base::WeakPtr<Client> io_client_; | 314 base::WeakPtr<Client> io_client_; |
314 | 315 |
315 // | 316 // |
316 // Decoder state, owned and operated by decoder_thread_. | 317 // Decoder state, owned and operated by decoder_thread_. |
317 // Before decoder_thread_ has started, the decoder state is managed by | 318 // Before decoder_thread_ has started, the decoder state is managed by |
318 // the child (main) thread. After decoder_thread_ has started, the decoder | 319 // the child (main) thread. After decoder_thread_ has started, the decoder |
319 // thread should be the only one managing these. | 320 // thread should be the only one managing these. |
320 // | 321 // |
321 | 322 |
322 // This thread services tasks posted from the VDA API entry points by the | 323 // This thread services tasks posted from the VDA API entry points by the |
323 // child thread and device service callbacks posted from the device thread. | 324 // child thread and device service callbacks posted from the device thread. |
324 base::Thread decoder_thread_; | 325 base::Thread decoder_thread_; |
325 // Decoder state machine state. | 326 // Decoder state machine state. |
326 State decoder_state_; | 327 State decoder_state_; |
327 // BitstreamBuffer we're presently reading. | 328 // BitstreamBuffer we're presently reading. |
328 scoped_ptr<BitstreamBufferRef> decoder_current_bitstream_buffer_; | 329 scoped_ptr<BitstreamBufferRef> decoder_current_bitstream_buffer_; |
329 // FlushTask() and ResetTask() should not affect buffers that have been | 330 // FlushTask() and ResetTask() should not affect buffers that have been |
330 // queued afterwards. For flushing or resetting the pipeline then, we will | 331 // queued afterwards. For flushing or resetting the pipeline then, we will |
331 // delay these buffers until after the flush or reset completes. | 332 // delay these buffers until after the flush or reset completes. |
332 int decoder_delay_bitstream_buffer_id_; | 333 int decoder_delay_bitstream_buffer_id_; |
333 // MFC input buffer we're presently filling. | 334 // Input buffer we're presently filling. |
334 int decoder_current_input_buffer_; | 335 int decoder_current_input_buffer_; |
335 // We track the number of buffer decode tasks we have scheduled, since each | 336 // We track the number of buffer decode tasks we have scheduled, since each |
336 // task execution should complete one buffer. If we fall behind (due to | 337 // task execution should complete one buffer. If we fall behind (due to |
337 // resource backpressure, etc.), we'll have to schedule more to catch up. | 338 // resource backpressure, etc.), we'll have to schedule more to catch up. |
338 int decoder_decode_buffer_tasks_scheduled_; | 339 int decoder_decode_buffer_tasks_scheduled_; |
339 // Picture buffers held by the client. | 340 // Picture buffers held by the client. |
340 int decoder_frames_at_client_; | 341 int decoder_frames_at_client_; |
341 // Are we flushing? | 342 // Are we flushing? |
342 bool decoder_flushing_; | 343 bool decoder_flushing_; |
343 // Got a notification from driver that it reached resolution change point | 344 // Got a notification from driver that it reached resolution change point |
344 // in the stream. | 345 // in the stream. |
345 bool resolution_change_pending_; | 346 bool resolution_change_pending_; |
346 // Got a reset request while we were performing resolution change. | 347 // Got a reset request while we were performing resolution change. |
347 bool resolution_change_reset_pending_; | 348 bool resolution_change_reset_pending_; |
348 // Input queue for decoder_thread_: BitstreamBuffers in. | 349 // Input queue for decoder_thread_: BitstreamBuffers in. |
349 std::queue<linked_ptr<BitstreamBufferRef> > decoder_input_queue_; | 350 std::queue<linked_ptr<BitstreamBufferRef> > decoder_input_queue_; |
350 // For H264 decode, hardware requires that we send it frame-sized chunks. | 351 // For H264 decode, hardware requires that we send it frame-sized chunks. |
351 // We'll need to parse the stream. | 352 // We'll need to parse the stream. |
352 scoped_ptr<content::H264Parser> decoder_h264_parser_; | 353 scoped_ptr<content::H264Parser> decoder_h264_parser_; |
353 // Set if the decoder has a pending incomplete frame in an input buffer. | 354 // Set if the decoder has a pending incomplete frame in an input buffer. |
354 bool decoder_partial_frame_pending_; | 355 bool decoder_partial_frame_pending_; |
355 | 356 |
356 // | 357 // |
357 // Hardware state and associated queues. Since decoder_thread_ services | 358 // Hardware state and associated queues. Since decoder_thread_ services |
358 // the hardware, decoder_thread_ owns these too. | 359 // the hardware, decoder_thread_ owns these too. |
359 // | 360 // |
360 | 361 |
361 // Completed decode buffers, waiting for MFC. | 362 // Completed decode buffers. |
362 std::queue<int> mfc_input_ready_queue_; | 363 std::queue<int> input_ready_queue_; |
363 | 364 |
364 // MFC decode device. | 365 // Decode device. |
365 int mfc_fd_; | 366 int fd_; |
366 | 367 |
367 // MFC input buffer state. | 368 // Input buffer state. |
368 bool mfc_input_streamon_; | 369 bool input_streamon_; |
369 // MFC input buffers enqueued to device. | 370 // Input buffers enqueued to device. |
370 int mfc_input_buffer_queued_count_; | 371 int input_buffer_queued_count_; |
371 // Input buffers ready to use, as a LIFO since we don't care about ordering. | 372 // Input buffers ready to use, as a LIFO since we don't care about ordering. |
372 std::vector<int> mfc_free_input_buffers_; | 373 std::vector<int> free_input_buffers_; |
373 // Mapping of int index to MFC input buffer record. | 374 // Mapping of int index to input buffer record. |
374 std::vector<MfcInputRecord> mfc_input_buffer_map_; | 375 std::vector<InputRecord> input_buffer_map_; |
375 | 376 |
376 // MFC output buffer state. | 377 // Output buffer state. |
377 bool mfc_output_streamon_; | 378 bool output_streamon_; |
378 // MFC output buffers enqueued to device. | 379 // Output buffers enqueued to device. |
379 int mfc_output_buffer_queued_count_; | 380 int output_buffer_queued_count_; |
380 // Output buffers ready to use, as a FIFO since we want oldest-first to hide | 381 // Output buffers ready to use, as a FIFO since we want oldest-first to hide |
381 // synchronization latency with GL. | 382 // synchronization latency with GL. |
382 std::queue<int> mfc_free_output_buffers_; | 383 std::queue<int> free_output_buffers_; |
383 // Mapping of int index to MFC output buffer record. | 384 // Mapping of int index to output buffer record. |
384 std::vector<MfcOutputRecord> mfc_output_buffer_map_; | 385 std::vector<OutputRecord> output_buffer_map_; |
385 // MFC output pixel format. | 386 // Output pixel format. |
386 uint32 mfc_output_buffer_pixelformat_; | 387 uint32 output_buffer_pixelformat_; |
387 // Required size of DPB for decoding. | 388 // Required size of DPB for decoding. |
388 int mfc_output_dpb_size_; | 389 int output_dpb_size_; |
389 | 390 |
390 // Pictures that are ready but not sent to PictureReady yet. | 391 // Pictures that are ready but not sent to PictureReady yet. |
391 std::queue<PictureRecord> pending_picture_ready_; | 392 std::queue<PictureRecord> pending_picture_ready_; |
392 | 393 |
393 // The number of pictures that are sent to PictureReady and will be cleared. | 394 // The number of pictures that are sent to PictureReady and will be cleared. |
394 int picture_clearing_count_; | 395 int picture_clearing_count_; |
395 | 396 |
396 // Output picture size. | 397 // Output picture size. |
397 gfx::Size frame_buffer_size_; | 398 gfx::Size frame_buffer_size_; |
398 | 399 |
(...skipping 13 matching lines...) Expand all Loading... |
412 | 413 |
413 // Make our context current before running any EGL entry points. | 414 // Make our context current before running any EGL entry points. |
414 base::Callback<bool(void)> make_context_current_; | 415 base::Callback<bool(void)> make_context_current_; |
415 | 416 |
416 // EGL state | 417 // EGL state |
417 EGLDisplay egl_display_; | 418 EGLDisplay egl_display_; |
418 | 419 |
419 // The codec we'll be decoding for. | 420 // The codec we'll be decoding for. |
420 media::VideoCodecProfile video_profile_; | 421 media::VideoCodecProfile video_profile_; |
421 | 422 |
422 DISALLOW_COPY_AND_ASSIGN(ExynosVideoDecodeAccelerator); | 423 DISALLOW_COPY_AND_ASSIGN(V4L2VideoDecodeAccelerator); |
423 }; | 424 }; |
424 | 425 |
425 } // namespace content | 426 } // namespace content |
426 | 427 |
427 #endif // CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_DECODE_ACCELERATOR_H_ | 428 #endif // CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_DECODE_ACCELERATOR_H_ |
OLD | NEW |