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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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(). |
208 void ServiceDeviceTask(); | 210 void ServiceDeviceTask(bool event_pending); |
209 // Handle the various device queues. | 211 // Handle the various device queues. |
210 void EnqueueMfc(); | 212 void EnqueueMfc(); |
211 void DequeueMfc(); | 213 void DequeueMfc(); |
212 void EnqueueGsc(); | 214 void EnqueueGsc(); |
213 void DequeueGsc(); | 215 void DequeueGsc(); |
| 216 void DequeueEvents(); |
214 // Enqueue a buffer on the corresponding queue. | 217 // Enqueue a buffer on the corresponding queue. |
215 bool EnqueueMfcInputRecord(); | 218 bool EnqueueMfcInputRecord(); |
216 bool EnqueueMfcOutputRecord(); | 219 bool EnqueueMfcOutputRecord(); |
217 bool EnqueueGscInputRecord(); | 220 bool EnqueueGscInputRecord(); |
218 bool EnqueueGscOutputRecord(); | 221 bool EnqueueGscOutputRecord(); |
219 | 222 |
220 // Process a ReusePictureBuffer() API call. The API call create an EGLSync | 223 // 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 | 224 // object on the main (GPU process) thread; we will record this object so we |
222 // can wait on it before reusing the buffer. | 225 // can wait on it before reusing the buffer. |
223 void ReusePictureBufferTask(int32 picture_buffer_id, | 226 void ReusePictureBufferTask(int32 picture_buffer_id, |
(...skipping 14 matching lines...) Expand all Loading... |
238 void ResetTask(); | 241 void ResetTask(); |
239 // ResetDoneTask() will set the decoder state back to kAfterReset, so | 242 // ResetDoneTask() will set the decoder state back to kAfterReset, so |
240 // subsequent decoding can continue. | 243 // subsequent decoding can continue. |
241 void ResetDoneTask(); | 244 void ResetDoneTask(); |
242 | 245 |
243 // Device destruction task. | 246 // Device destruction task. |
244 void DestroyTask(); | 247 void DestroyTask(); |
245 | 248 |
246 // Attempt to start/stop device_poll_thread_. | 249 // Attempt to start/stop device_poll_thread_. |
247 bool StartDevicePoll(); | 250 bool StartDevicePoll(); |
248 bool StopDevicePoll(); | 251 // |keep_mfc_input| if true, don't reset MFC input state, used during |
| 252 // resolution change. |
| 253 bool StopDevicePoll(bool keep_mfc_input); |
249 // Set/clear the device poll interrupt (using device_poll_interrupt_fd_). | 254 // Set/clear the device poll interrupt (using device_poll_interrupt_fd_). |
250 bool SetDevicePollInterrupt(); | 255 bool SetDevicePollInterrupt(); |
251 bool ClearDevicePollInterrupt(); | 256 bool ClearDevicePollInterrupt(); |
252 | 257 |
| 258 void StartResolutionChangeIfNeeded(); |
| 259 void ResChangeDestroyBuffersOnChildThread(); |
| 260 void FinishResolutionChangeTask(); |
| 261 void ResumeAfterResolutionChangeTask(); |
| 262 |
253 // | 263 // |
254 // Device tasks, to be run on device_poll_thread_. | 264 // Device tasks, to be run on device_poll_thread_. |
255 // | 265 // |
256 | 266 |
257 // The device task. | 267 // The device task. |
258 void DevicePollTask(unsigned int poll_fds); | 268 void DevicePollTask(unsigned int poll_fds); |
259 | 269 |
260 // | 270 // |
261 // Safe from any thread. | 271 // Safe from any thread. |
262 // | 272 // |
263 | 273 |
264 // Error notification (using PostTask() to child thread, if necessary). | 274 // Error notification (using PostTask() to child thread, if necessary). |
265 void NotifyError(Error error); | 275 void NotifyError(Error error); |
266 | 276 |
267 // Set the decoder_thread_ state (using PostTask to decoder thread, if | 277 // Set the decoder_thread_ state (using PostTask to decoder thread, if |
268 // necessary). | 278 // necessary). |
269 void SetDecoderState(State state); | 279 void SetDecoderState(State state); |
270 | 280 |
271 // | 281 // |
272 // Other utility functions. Called on decoder_thread_, unless | 282 // Other utility functions. Called on decoder_thread_, unless |
273 // decoder_thread_ is not yet started, in which case the child thread can call | 283 // decoder_thread_ is not yet started, in which case the child thread can call |
274 // these (e.g. in Initialize() or Destroy()). | 284 // these (e.g. in Initialize() or Destroy()). |
275 // | 285 // |
276 | 286 |
277 // Create the buffers we need. | 287 // Create the buffers we need. |
| 288 bool GetFormatInfo(struct v4l2_format* format, bool* again); |
| 289 bool CreateBuffersForFormat(const struct v4l2_format& format); |
278 bool CreateMfcInputBuffers(); | 290 bool CreateMfcInputBuffers(); |
279 bool CreateMfcOutputBuffers(); | 291 bool CreateMfcOutputBuffers(); |
280 bool CreateGscInputBuffers(); | 292 bool CreateGscInputBuffers(); |
281 bool CreateGscOutputBuffers(); | 293 bool CreateGscOutputBuffers(); |
282 | 294 |
283 // Destroy these buffers. | 295 // Destroy these buffers. |
284 void DestroyMfcInputBuffers(); | 296 void DestroyMfcInputBuffers(); |
285 void DestroyMfcOutputBuffers(); | 297 void DestroyMfcOutputBuffers(); |
286 void DestroyGscInputBuffers(); | 298 void DestroyGscInputBuffers(); |
287 void DestroyGscOutputBuffers(); | 299 void DestroyGscOutputBuffers(); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 // MFC input buffer we're presently filling. | 336 // MFC input buffer we're presently filling. |
325 int decoder_current_input_buffer_; | 337 int decoder_current_input_buffer_; |
326 // We track the number of buffer decode tasks we have scheduled, since each | 338 // 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 | 339 // 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. | 340 // resource backpressure, etc.), we'll have to schedule more to catch up. |
329 int decoder_decode_buffer_tasks_scheduled_; | 341 int decoder_decode_buffer_tasks_scheduled_; |
330 // Picture buffers held by the client. | 342 // Picture buffers held by the client. |
331 int decoder_frames_at_client_; | 343 int decoder_frames_at_client_; |
332 // Are we flushing? | 344 // Are we flushing? |
333 bool decoder_flushing_; | 345 bool decoder_flushing_; |
| 346 // Got a notification from driver that it reached resolution change point |
| 347 // in the stream. |
| 348 bool resolution_change_pending_; |
| 349 // Got a reset request while we were performing resolution change. |
| 350 bool reset_pending_; |
334 // Input queue for decoder_thread_: BitstreamBuffers in. | 351 // Input queue for decoder_thread_: BitstreamBuffers in. |
335 std::list<linked_ptr<BitstreamBufferRef> > decoder_input_queue_; | 352 std::list<linked_ptr<BitstreamBufferRef> > decoder_input_queue_; |
336 // For H264 decode, hardware requires that we send it frame-sized chunks. | 353 // For H264 decode, hardware requires that we send it frame-sized chunks. |
337 // We'll need to parse the stream. | 354 // We'll need to parse the stream. |
338 scoped_ptr<content::H264Parser> decoder_h264_parser_; | 355 scoped_ptr<content::H264Parser> decoder_h264_parser_; |
339 // Set if the decoder has a pending incomplete frame in an input buffer. | 356 // Set if the decoder has a pending incomplete frame in an input buffer. |
340 bool decoder_partial_frame_pending_; | 357 bool decoder_partial_frame_pending_; |
341 | 358 |
342 // | 359 // |
343 // Hardware state and associated queues. Since decoder_thread_ services | 360 // Hardware state and associated queues. Since decoder_thread_ services |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 | 440 |
424 // The codec we'll be decoding for. | 441 // The codec we'll be decoding for. |
425 media::VideoCodecProfile video_profile_; | 442 media::VideoCodecProfile video_profile_; |
426 | 443 |
427 DISALLOW_COPY_AND_ASSIGN(ExynosVideoDecodeAccelerator); | 444 DISALLOW_COPY_AND_ASSIGN(ExynosVideoDecodeAccelerator); |
428 }; | 445 }; |
429 | 446 |
430 } // namespace content | 447 } // namespace content |
431 | 448 |
432 #endif // CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_DECODE_ACCELERATOR_H_ | 449 #endif // CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_DECODE_ACCELERATOR_H_ |
OLD | NEW |