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 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 kPoll = (1 << 0), |
|
Pawel Osciak
2014/01/07 07:18:12
This doesn't make too much sense now. Maybe kPollD
| |
| 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. |
|
Pawel Osciak
2014/01/07 07:18:12
Comments should start with capital letters (be sen
| |
| 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 |