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 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
95 kDpbOutputBufferExtraCount = 3, | 95 kDpbOutputBufferExtraCount = 3, |
96 }; | 96 }; |
97 | 97 |
98 // Internal state of the decoder. | 98 // Internal state of the decoder. |
99 enum State { | 99 enum State { |
100 kUninitialized, // Initialize() not yet called. | 100 kUninitialized, // Initialize() not yet called. |
101 kInitialized, // Initialize() returned true; ready to start decoding. | 101 kInitialized, // Initialize() returned true; ready to start decoding. |
102 kDecoding, // DecodeBufferInitial() successful; decoding frames. | 102 kDecoding, // DecodeBufferInitial() successful; decoding frames. |
103 kResetting, // Presently resetting. | 103 kResetting, // Presently resetting. |
104 kAfterReset, // After Reset(), ready to start decoding again. | 104 kAfterReset, // After Reset(), ready to start decoding again. |
105 kChangingResolution, // Performing resolution change, all remaining | |
106 // pre-change frames decoded and processed. | |
105 kError, // Error in kDecoding state. | 107 kError, // Error in kDecoding state. |
106 }; | 108 }; |
107 | 109 |
108 enum BufferId { | 110 enum BufferId { |
109 kFlushBufferId = -2 // Buffer id for flush buffer, queued by FlushTask(). | 111 kFlushBufferId = -2 // Buffer id for flush buffer, queued by FlushTask(). |
110 }; | 112 }; |
111 | 113 |
112 // File descriptors we need to poll. | 114 // File descriptors we need to poll. |
113 enum PollFds { | 115 enum PollFds { |
114 kPollMfc = (1 << 0), | 116 kPollMfc = (1 << 0), |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
197 bool AppendToInputFrame(const void* data, size_t size); | 199 bool AppendToInputFrame(const void* data, size_t size); |
198 // Flush data for one decoded frame. | 200 // Flush data for one decoded frame. |
199 bool FlushInputFrame(); | 201 bool FlushInputFrame(); |
200 | 202 |
201 // Process an AssignPictureBuffers() API call. After this, the | 203 // Process an AssignPictureBuffers() API call. After this, the |
202 // device_poll_thread_ can be started safely, since we have all our | 204 // device_poll_thread_ can be started safely, since we have all our |
203 // buffers. | 205 // buffers. |
204 void AssignPictureBuffersTask(scoped_ptr<PictureBufferArrayRef> pic_buffers); | 206 void AssignPictureBuffersTask(scoped_ptr<PictureBufferArrayRef> pic_buffers); |
205 | 207 |
206 // Service I/O on the V4L2 devices. This task should only be scheduled from | 208 // Service I/O on the V4L2 devices. This task should only be scheduled from |
207 // DevicePollTask(). | 209 // DevicePollTask(). If |mfc_event_pending| is true, one or more events |
208 void ServiceDeviceTask(); | 210 // on MFC file descriptor are pending. |
211 void ServiceDeviceTask(bool mfc_event_pending); | |
209 // Handle the various device queues. | 212 // Handle the various device queues. |
210 void EnqueueMfc(); | 213 void EnqueueMfc(); |
211 void DequeueMfc(); | 214 void DequeueMfc(); |
212 void EnqueueGsc(); | 215 void EnqueueGsc(); |
213 void DequeueGsc(); | 216 void DequeueGsc(); |
217 // Handle incoming MFC events. | |
218 void DequeueMfcEvents(); | |
214 // Enqueue a buffer on the corresponding queue. | 219 // Enqueue a buffer on the corresponding queue. |
215 bool EnqueueMfcInputRecord(); | 220 bool EnqueueMfcInputRecord(); |
216 bool EnqueueMfcOutputRecord(); | 221 bool EnqueueMfcOutputRecord(); |
217 bool EnqueueGscInputRecord(); | 222 bool EnqueueGscInputRecord(); |
218 bool EnqueueGscOutputRecord(); | 223 bool EnqueueGscOutputRecord(); |
219 | 224 |
220 // Process a ReusePictureBuffer() API call. The API call create an EGLSync | 225 // Process a ReusePictureBuffer() API call. The API call create an EGLSync |
221 // object on the main (GPU process) thread; we will record this object so we | 226 // object on the main (GPU process) thread; we will record this object so we |
222 // can wait on it before reusing the buffer. | 227 // can wait on it before reusing the buffer. |
223 void ReusePictureBufferTask(int32 picture_buffer_id, | 228 void ReusePictureBufferTask(int32 picture_buffer_id, |
(...skipping 14 matching lines...) Expand all Loading... | |
238 void ResetTask(); | 243 void ResetTask(); |
239 // ResetDoneTask() will set the decoder state back to kAfterReset, so | 244 // ResetDoneTask() will set the decoder state back to kAfterReset, so |
240 // subsequent decoding can continue. | 245 // subsequent decoding can continue. |
241 void ResetDoneTask(); | 246 void ResetDoneTask(); |
242 | 247 |
243 // Device destruction task. | 248 // Device destruction task. |
244 void DestroyTask(); | 249 void DestroyTask(); |
245 | 250 |
246 // Attempt to start/stop device_poll_thread_. | 251 // Attempt to start/stop device_poll_thread_. |
247 bool StartDevicePoll(); | 252 bool StartDevicePoll(); |
248 bool StopDevicePoll(); | 253 // If |keep_mfc_input_state| is true, don't reset MFC input state; used during |
254 // resolution change. | |
255 bool StopDevicePoll(bool keep_mfc_input_state); | |
249 // Set/clear the device poll interrupt (using device_poll_interrupt_fd_). | 256 // Set/clear the device poll interrupt (using device_poll_interrupt_fd_). |
250 bool SetDevicePollInterrupt(); | 257 bool SetDevicePollInterrupt(); |
251 bool ClearDevicePollInterrupt(); | 258 bool ClearDevicePollInterrupt(); |
252 | 259 |
260 void StartResolutionChangeIfNeeded(); | |
261 void FinishResolutionChange(); | |
sheu
2013/08/12 03:06:17
I noted before that I'd like to see these moved to
Pawel Osciak
2013/08/12 03:19:10
These three are run on decoder thread. Only Resolu
sheu
2013/08/12 04:49:20
Sorry for the confusion -- I was replying to the o
| |
262 void ResumeAfterResolutionChange(); | |
263 | |
264 // Try to get output format from MFC, detected after parsing the beginning | |
265 // of the stream. Sets |again| to true if more parsing is needed. | |
266 bool GetFormatInfo(struct v4l2_format* format, bool* again); | |
267 // Create MFC output and GSC input and output buffers for the given |format|. | |
268 bool CreateBuffersForFormat(const struct v4l2_format& format); | |
269 | |
253 // | 270 // |
254 // Device tasks, to be run on device_poll_thread_. | 271 // Device tasks, to be run on device_poll_thread_. |
255 // | 272 // |
256 | 273 |
257 // The device task. | 274 // The device task. |
258 void DevicePollTask(unsigned int poll_fds); | 275 void DevicePollTask(unsigned int poll_fds); |
259 | 276 |
260 // | 277 // |
261 // Safe from any thread. | 278 // Safe from any thread. |
262 // | 279 // |
(...skipping 10 matching lines...) Expand all Loading... | |
273 // decoder_thread_ is not yet started, in which case the child thread can call | 290 // decoder_thread_ is not yet started, in which case the child thread can call |
274 // these (e.g. in Initialize() or Destroy()). | 291 // these (e.g. in Initialize() or Destroy()). |
275 // | 292 // |
276 | 293 |
277 // Create the buffers we need. | 294 // Create the buffers we need. |
278 bool CreateMfcInputBuffers(); | 295 bool CreateMfcInputBuffers(); |
279 bool CreateMfcOutputBuffers(); | 296 bool CreateMfcOutputBuffers(); |
280 bool CreateGscInputBuffers(); | 297 bool CreateGscInputBuffers(); |
281 bool CreateGscOutputBuffers(); | 298 bool CreateGscOutputBuffers(); |
282 | 299 |
283 // Destroy these buffers. | 300 // |
301 // Methods run on child thread. | |
302 // | |
303 | |
304 // Destroy buffers. | |
284 void DestroyMfcInputBuffers(); | 305 void DestroyMfcInputBuffers(); |
285 void DestroyMfcOutputBuffers(); | 306 void DestroyMfcOutputBuffers(); |
286 void DestroyGscInputBuffers(); | 307 void DestroyGscInputBuffers(); |
287 void DestroyGscOutputBuffers(); | 308 void DestroyGscOutputBuffers(); |
309 void ResolutionChangeDestroyBuffers(); | |
288 | 310 |
289 // Our original calling message loop for the child thread. | 311 // Our original calling message loop for the child thread. |
290 scoped_refptr<base::MessageLoopProxy> child_message_loop_proxy_; | 312 scoped_refptr<base::MessageLoopProxy> child_message_loop_proxy_; |
291 | 313 |
292 // WeakPtr<> pointing to |this| for use in posting tasks from the decoder or | 314 // WeakPtr<> pointing to |this| for use in posting tasks from the decoder or |
293 // device worker threads back to the child thread. Because the worker threads | 315 // device worker threads back to the child thread. Because the worker threads |
294 // are members of this class, any task running on those threads is guaranteed | 316 // are members of this class, any task running on those threads is guaranteed |
295 // that this object is still alive. As a result, tasks posted from the child | 317 // that this object is still alive. As a result, tasks posted from the child |
296 // thread to the decoder or device thread should use base::Unretained(this), | 318 // thread to the decoder or device thread should use base::Unretained(this), |
297 // and tasks posted the other way should use |weak_this_|. | 319 // and tasks posted the other way should use |weak_this_|. |
(...skipping 26 matching lines...) Expand all Loading... | |
324 // MFC input buffer we're presently filling. | 346 // MFC input buffer we're presently filling. |
325 int decoder_current_input_buffer_; | 347 int decoder_current_input_buffer_; |
326 // We track the number of buffer decode tasks we have scheduled, since each | 348 // We track the number of buffer decode tasks we have scheduled, since each |
327 // task execution should complete one buffer. If we fall behind (due to | 349 // task execution should complete one buffer. If we fall behind (due to |
328 // resource backpressure, etc.), we'll have to schedule more to catch up. | 350 // resource backpressure, etc.), we'll have to schedule more to catch up. |
329 int decoder_decode_buffer_tasks_scheduled_; | 351 int decoder_decode_buffer_tasks_scheduled_; |
330 // Picture buffers held by the client. | 352 // Picture buffers held by the client. |
331 int decoder_frames_at_client_; | 353 int decoder_frames_at_client_; |
332 // Are we flushing? | 354 // Are we flushing? |
333 bool decoder_flushing_; | 355 bool decoder_flushing_; |
356 // Got a notification from driver that it reached resolution change point | |
357 // in the stream. | |
358 bool resolution_change_pending_; | |
359 // Got a reset request while we were performing resolution change. | |
360 bool resolution_change_reset_pending_; | |
334 // Input queue for decoder_thread_: BitstreamBuffers in. | 361 // Input queue for decoder_thread_: BitstreamBuffers in. |
335 std::list<linked_ptr<BitstreamBufferRef> > decoder_input_queue_; | 362 std::list<linked_ptr<BitstreamBufferRef> > decoder_input_queue_; |
336 // For H264 decode, hardware requires that we send it frame-sized chunks. | 363 // For H264 decode, hardware requires that we send it frame-sized chunks. |
337 // We'll need to parse the stream. | 364 // We'll need to parse the stream. |
338 scoped_ptr<content::H264Parser> decoder_h264_parser_; | 365 scoped_ptr<content::H264Parser> decoder_h264_parser_; |
339 // Set if the decoder has a pending incomplete frame in an input buffer. | 366 // Set if the decoder has a pending incomplete frame in an input buffer. |
340 bool decoder_partial_frame_pending_; | 367 bool decoder_partial_frame_pending_; |
341 | 368 |
342 // | 369 // |
343 // Hardware state and associated queues. Since decoder_thread_ services | 370 // Hardware state and associated queues. Since decoder_thread_ services |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
423 | 450 |
424 // The codec we'll be decoding for. | 451 // The codec we'll be decoding for. |
425 media::VideoCodecProfile video_profile_; | 452 media::VideoCodecProfile video_profile_; |
426 | 453 |
427 DISALLOW_COPY_AND_ASSIGN(ExynosVideoDecodeAccelerator); | 454 DISALLOW_COPY_AND_ASSIGN(ExynosVideoDecodeAccelerator); |
428 }; | 455 }; |
429 | 456 |
430 } // namespace content | 457 } // namespace content |
431 | 458 |
432 #endif // CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_DECODE_ACCELERATOR_H_ | 459 #endif // CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_DECODE_ACCELERATOR_H_ |
OLD | NEW |