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

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

Issue 23526070: Remove GSC usage from ExynosVideoDecodeAccelerator. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@git-svn
Patch Set: 7e4634ee Functional. Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 // This file contains an implementation of VideoDecoderAccelerator 5 // This file contains an implementation of VideoDecoderAccelerator
6 // that utilizes the hardware video decoder present on the Exynos SoC. 6 // that utilizes the hardware video decoder present on the Exynos SoC.
7 7
8 #ifndef CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_DECODE_ACCELERATOR_H_ 8 #ifndef CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_DECODE_ACCELERATOR_H_
9 #define CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_DECODE_ACCELERATOR_H_ 9 #define CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_DECODE_ACCELERATOR_H_
10 10
(...skipping 12 matching lines...) Expand all
23 #include "ui/gl/gl_bindings.h" 23 #include "ui/gl/gl_bindings.h"
24 24
25 namespace base { 25 namespace base {
26 class MessageLoopProxy; 26 class MessageLoopProxy;
27 } 27 }
28 28
29 namespace content { 29 namespace content {
30 class H264Parser; 30 class H264Parser;
31 31
32 // This class handles Exynos video acceleration directly through the V4L2 32 // This class handles Exynos video acceleration directly through the V4L2
33 // devices exported by the Multi Format Codec and GScaler hardware blocks. 33 // device exported by the Multi Format Codec hardware block.
34 // 34 //
35 // The threading model of this class is driven by the fact that it needs to 35 // The threading model of this class is driven by the fact that it needs to
36 // interface two fundamentally different event queues -- the one Chromium 36 // interface two fundamentally different event queues -- the one Chromium
37 // provides through MessageLoop, and the one driven by the V4L2 devices which 37 // provides through MessageLoop, and the one driven by the V4L2 devices which
38 // is waited on with epoll(). There are three threads involved in this class: 38 // is waited on with epoll(). There are three threads involved in this class:
39 // 39 //
40 // * The child thread, which is the main GPU process thread which calls the 40 // * The child thread, which is the main GPU process thread which calls the
41 // media::VideoDecodeAccelerator entry points. Calls from this thread 41 // media::VideoDecodeAccelerator entry points. Calls from this thread
42 // generally do not block (with the exception of Initialize() and Destroy()). 42 // generally do not block (with the exception of Initialize() and Destroy()).
43 // They post tasks to the decoder_thread_, which actually services the task 43 // They post tasks to the decoder_thread_, which actually services the task
(...skipping 30 matching lines...) Expand all
74 virtual void AssignPictureBuffers( 74 virtual void AssignPictureBuffers(
75 const std::vector<media::PictureBuffer>& buffers) OVERRIDE; 75 const std::vector<media::PictureBuffer>& buffers) OVERRIDE;
76 virtual void ReusePictureBuffer(int32 picture_buffer_id) OVERRIDE; 76 virtual void ReusePictureBuffer(int32 picture_buffer_id) OVERRIDE;
77 virtual void Flush() OVERRIDE; 77 virtual void Flush() OVERRIDE;
78 virtual void Reset() OVERRIDE; 78 virtual void Reset() OVERRIDE;
79 virtual void Destroy() OVERRIDE; 79 virtual void Destroy() OVERRIDE;
80 80
81 // VideoDecodeAcceleratorImpl implementation. 81 // VideoDecodeAcceleratorImpl implementation.
82 virtual bool CanDecodeOnIOThread() OVERRIDE; 82 virtual bool CanDecodeOnIOThread() OVERRIDE;
83 83
84 // Do any necessary initialization before the sandbox is enabled.
85 static void PreSandboxInitialization();
86
87 // Lazily initialize static data after sandbox is enabled. Return false on
88 // init failure.
89 static bool PostSandboxInitialization();
90
91 private: 84 private:
92 // These are rather subjectively tuned. 85 // These are rather subjectively tuned.
93 enum { 86 enum {
94 kMfcInputBufferCount = 8, 87 kMfcInputBufferCount = 8,
95 // TODO(posciak): determine MFC input buffer size based on level limits. 88 // TODO(posciak): determine MFC input buffer size based on level limits.
96 // See http://crbug.com/255116. 89 // See http://crbug.com/255116.
97 kMfcInputBufferMaxSize = 1024 * 1024, 90 kMfcInputBufferMaxSize = 1024 * 1024,
98 kGscInputBufferCount = 4,
99 // Number of output buffers to use for each VDA stage above what's required 91 // Number of output buffers to use for each VDA stage above what's required
100 // by the decoder (e.g. DPB size, in H264). We need 92 // by the decoder (e.g. DPB size, in H264). We need
101 // media::limits::kMaxVideoFrames to fill up the GpuVideoDecode pipeline, 93 // media::limits::kMaxVideoFrames to fill up the GpuVideoDecode pipeline,
102 // and +1 for a frame in transit. 94 // and +1 for a frame in transit.
103 kDpbOutputBufferExtraCount = media::limits::kMaxVideoFrames + 1, 95 kDpbOutputBufferExtraCount = media::limits::kMaxVideoFrames + 1,
104 }; 96 };
105 97
106 // Internal state of the decoder. 98 // Internal state of the decoder.
107 enum State { 99 enum State {
108 kUninitialized, // Initialize() not yet called. 100 kUninitialized, // Initialize() not yet called.
109 kInitialized, // Initialize() returned true; ready to start decoding. 101 kInitialized, // Initialize() returned true; ready to start decoding.
110 kDecoding, // DecodeBufferInitial() successful; decoding frames. 102 kDecoding, // DecodeBufferInitial() successful; decoding frames.
111 kResetting, // Presently resetting. 103 kResetting, // Presently resetting.
112 kAfterReset, // After Reset(), ready to start decoding again. 104 kAfterReset, // After Reset(), ready to start decoding again.
113 kChangingResolution, // Performing resolution change, all remaining 105 kChangingResolution, // Performing resolution change, all remaining
114 // pre-change frames decoded and processed. 106 // pre-change frames decoded and processed.
115 kError, // Error in kDecoding state. 107 kError, // Error in kDecoding state.
116 }; 108 };
117 109
118 enum BufferId { 110 enum BufferId {
119 kFlushBufferId = -2 // Buffer id for flush buffer, queued by FlushTask(). 111 kFlushBufferId = -2 // Buffer id for flush buffer, queued by FlushTask().
120 }; 112 };
121 113
122 // File descriptors we need to poll. 114 // File descriptors we need to poll.
123 enum PollFds { 115 enum PollFds {
124 kPollMfc = (1 << 0), 116 kPollMfc = (1 << 0),
125 kPollGsc = (1 << 1),
126 }; 117 };
127 118
128 // Auto-destruction reference for BitstreamBuffer, for message-passing from 119 // Auto-destruction reference for BitstreamBuffer, for message-passing from
129 // Decode() to DecodeTask(). 120 // Decode() to DecodeTask().
130 struct BitstreamBufferRef; 121 struct BitstreamBufferRef;
131 122
132 // Auto-destruction reference for an array of PictureBuffer, for 123 // Auto-destruction reference for an array of PictureBuffer, for
133 // message-passing from AssignPictureBuffers() to AssignPictureBuffersTask(). 124 // message-passing from AssignPictureBuffers() to AssignPictureBuffersTask().
134 struct PictureBufferArrayRef; 125 struct PictureBufferArrayRef;
135 126
136 // Auto-destruction reference for EGLSync (for message-passing). 127 // Auto-destruction reference for EGLSync (for message-passing).
137 struct EGLSyncKHRRef; 128 struct EGLSyncKHRRef;
138 129
139 // Record for MFC input buffers. 130 // Record for MFC input buffers.
140 struct MfcInputRecord { 131 struct MfcInputRecord {
141 MfcInputRecord(); 132 MfcInputRecord();
142 ~MfcInputRecord(); 133 ~MfcInputRecord();
143 bool at_device; // held by device. 134 bool at_device; // held by device.
144 void* address; // mmap() address. 135 void* address; // mmap() address.
145 size_t length; // mmap() length. 136 size_t length; // mmap() length.
146 off_t bytes_used; // bytes filled in the mmap() segment. 137 off_t bytes_used; // bytes filled in the mmap() segment.
147 int32 input_id; // triggering input_id as given to Decode(). 138 int32 input_id; // triggering input_id as given to Decode().
148 }; 139 };
149 140
150 // Record for MFC output buffers. 141 // Record for MFC output buffers.
151 struct MfcOutputRecord { 142 struct MfcOutputRecord {
152 MfcOutputRecord(); 143 MfcOutputRecord();
153 ~MfcOutputRecord(); 144 ~MfcOutputRecord();
154 bool at_device; // held by device. 145 bool at_device; // held by device.
155 size_t bytes_used[2]; // bytes used in each dmabuf. 146 bool at_client; // held by client.
156 void* address[2]; // mmap() address for each plane. 147 int fds[2]; // file descriptors for each plane.
157 size_t length[2]; // mmap() length for each plane. 148 EGLImageKHR egl_image; // EGLImageKHR for the output buffer.
158 int32 input_id; // triggering input_id as given to Decode(). 149 EGLSyncKHR egl_sync; // sync the compositor's use of the EGLImage.
159 }; 150 int32 picture_id; // picture buffer id as returned to PictureReady().
160
161 // Record for GSC input buffers.
162 struct GscInputRecord {
163 GscInputRecord();
164 ~GscInputRecord();
165 bool at_device; // held by device.
166 int mfc_output; // MFC output buffer index to recycle when this input
167 // is complete.
168 };
169
170 // Record for GSC output buffers.
171 struct GscOutputRecord {
172 GscOutputRecord();
173 ~GscOutputRecord();
174 bool at_device; // held by device.
175 bool at_client; // held by client.
176 int fd; // file descriptor from backing EGLImage.
177 EGLImageKHR egl_image; // backing EGLImage.
178 EGLSyncKHR egl_sync; // sync the compositor's use of the EGLImage.
179 int32 picture_id; // picture buffer id as returned to PictureReady().
180 }; 151 };
181 152
182 // 153 //
183 // Decoding tasks, to be run on decode_thread_. 154 // Decoding tasks, to be run on decode_thread_.
184 // 155 //
185 156
186 // Enqueue a BitstreamBuffer to decode. This will enqueue a buffer to the 157 // Enqueue a BitstreamBuffer to decode. This will enqueue a buffer to the
187 // decoder_input_queue_, then queue a DecodeBufferTask() to actually decode 158 // decoder_input_queue_, then queue a DecodeBufferTask() to actually decode
188 // the buffer. 159 // the buffer.
189 void DecodeTask(const media::BitstreamBuffer& bitstream_buffer); 160 void DecodeTask(const media::BitstreamBuffer& bitstream_buffer);
(...skipping 23 matching lines...) Expand all
213 // buffers. 184 // buffers.
214 void AssignPictureBuffersTask(scoped_ptr<PictureBufferArrayRef> pic_buffers); 185 void AssignPictureBuffersTask(scoped_ptr<PictureBufferArrayRef> pic_buffers);
215 186
216 // Service I/O on the V4L2 devices. This task should only be scheduled from 187 // Service I/O on the V4L2 devices. This task should only be scheduled from
217 // DevicePollTask(). If |mfc_event_pending| is true, one or more events 188 // DevicePollTask(). If |mfc_event_pending| is true, one or more events
218 // on MFC file descriptor are pending. 189 // on MFC file descriptor are pending.
219 void ServiceDeviceTask(bool mfc_event_pending); 190 void ServiceDeviceTask(bool mfc_event_pending);
220 // Handle the various device queues. 191 // Handle the various device queues.
221 void EnqueueMfc(); 192 void EnqueueMfc();
222 void DequeueMfc(); 193 void DequeueMfc();
223 void EnqueueGsc();
224 void DequeueGsc();
225 // Handle incoming MFC events. 194 // Handle incoming MFC events.
226 void DequeueMfcEvents(); 195 void DequeueMfcEvents();
227 // Enqueue a buffer on the corresponding queue. 196 // Enqueue a buffer on the corresponding queue.
228 bool EnqueueMfcInputRecord(); 197 bool EnqueueMfcInputRecord();
229 bool EnqueueMfcOutputRecord(); 198 bool EnqueueMfcOutputRecord();
230 bool EnqueueGscInputRecord();
231 bool EnqueueGscOutputRecord();
232 199
233 // Process a ReusePictureBuffer() API call. The API call create an EGLSync 200 // Process a ReusePictureBuffer() API call. The API call create an EGLSync
234 // object on the main (GPU process) thread; we will record this object so we 201 // object on the main (GPU process) thread; we will record this object so we
235 // can wait on it before reusing the buffer. 202 // can wait on it before reusing the buffer.
236 void ReusePictureBufferTask(int32 picture_buffer_id, 203 void ReusePictureBufferTask(int32 picture_buffer_id,
237 scoped_ptr<EGLSyncKHRRef> egl_sync_ref); 204 scoped_ptr<EGLSyncKHRRef> egl_sync_ref);
238 205
239 // Flush() task. Child thread should not submit any more buffers until it 206 // Flush() task. Child thread should not submit any more buffers until it
240 // receives the NotifyFlushDone callback. This task will schedule an empty 207 // receives the NotifyFlushDone callback. This task will schedule an empty
241 // BitstreamBufferRef (with input_id == kFlushBufferId) to perform the flush. 208 // BitstreamBufferRef (with input_id == kFlushBufferId) to perform the flush.
(...skipping 23 matching lines...) Expand all
265 bool SetDevicePollInterrupt(); 232 bool SetDevicePollInterrupt();
266 bool ClearDevicePollInterrupt(); 233 bool ClearDevicePollInterrupt();
267 234
268 void StartResolutionChangeIfNeeded(); 235 void StartResolutionChangeIfNeeded();
269 void FinishResolutionChange(); 236 void FinishResolutionChange();
270 void ResumeAfterResolutionChange(); 237 void ResumeAfterResolutionChange();
271 238
272 // Try to get output format from MFC, detected after parsing the beginning 239 // Try to get output format from MFC, detected after parsing the beginning
273 // of the stream. Sets |again| to true if more parsing is needed. 240 // of the stream. Sets |again| to true if more parsing is needed.
274 bool GetFormatInfo(struct v4l2_format* format, bool* again); 241 bool GetFormatInfo(struct v4l2_format* format, bool* again);
275 // Create MFC output and GSC input and output buffers for the given |format|. 242 // Create MFC output and GSC input and output buffers for the given |format|.
Pawel Osciak 2013/09/30 05:16:25 Remove GSC reference.
sheu 2013/10/04 23:25:56 Done.
276 bool CreateBuffersForFormat(const struct v4l2_format& format); 243 bool CreateBuffersForFormat(const struct v4l2_format& format);
277 244
278 // 245 //
279 // Device tasks, to be run on device_poll_thread_. 246 // Device tasks, to be run on device_poll_thread_.
280 // 247 //
281 248
282 // The device task. 249 // The device task.
283 void DevicePollTask(unsigned int poll_fds); 250 void DevicePollTask(unsigned int poll_fds);
284 251
285 // 252 //
286 // Safe from any thread. 253 // Safe from any thread.
287 // 254 //
288 255
289 // Error notification (using PostTask() to child thread, if necessary). 256 // Error notification (using PostTask() to child thread, if necessary).
290 void NotifyError(Error error); 257 void NotifyError(Error error);
291 258
292 // Set the decoder_thread_ state (using PostTask to decoder thread, if 259 // Set the decoder_thread_ state (using PostTask to decoder thread, if
293 // necessary). 260 // necessary).
294 void SetDecoderState(State state); 261 void SetDecoderState(State state);
295 262
296 // 263 //
297 // Other utility functions. Called on decoder_thread_, unless 264 // Other utility functions. Called on decoder_thread_, unless
298 // decoder_thread_ is not yet started, in which case the child thread can call 265 // decoder_thread_ is not yet started, in which case the child thread can call
299 // these (e.g. in Initialize() or Destroy()). 266 // these (e.g. in Initialize() or Destroy()).
300 // 267 //
301 268
302 // Create the buffers we need. 269 // Create the buffers we need.
303 bool CreateMfcInputBuffers(); 270 bool CreateMfcInputBuffers();
304 bool CreateMfcOutputBuffers(); 271 bool CreateMfcOutputBuffers();
305 bool CreateGscInputBuffers();
306 bool CreateGscOutputBuffers();
307 272
308 // 273 //
309 // Methods run on child thread. 274 // Methods run on child thread.
310 // 275 //
311 276
312 // Destroy buffers. 277 // Destroy buffers.
313 void DestroyMfcInputBuffers(); 278 void DestroyMfcInputBuffers();
314 void DestroyMfcOutputBuffers(); 279 void DestroyMfcOutputBuffers();
315 void DestroyGscInputBuffers();
316 void DestroyGscOutputBuffers();
317 void ResolutionChangeDestroyBuffers(); 280 void ResolutionChangeDestroyBuffers();
318 281
319 // Our original calling message loop for the child thread. 282 // Our original calling message loop for the child thread.
320 scoped_refptr<base::MessageLoopProxy> child_message_loop_proxy_; 283 scoped_refptr<base::MessageLoopProxy> child_message_loop_proxy_;
321 284
322 // Message loop of the IO thread. 285 // Message loop of the IO thread.
323 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; 286 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;
324 287
325 // WeakPtr<> pointing to |this| for use in posting tasks from the decoder or 288 // WeakPtr<> pointing to |this| for use in posting tasks from the decoder or
326 // device worker threads back to the child thread. Because the worker threads 289 // device worker threads back to the child thread. Because the worker threads
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 int mfc_input_buffer_queued_count_; 359 int mfc_input_buffer_queued_count_;
397 // Input buffers ready to use, as a LIFO since we don't care about ordering. 360 // Input buffers ready to use, as a LIFO since we don't care about ordering.
398 std::vector<int> mfc_free_input_buffers_; 361 std::vector<int> mfc_free_input_buffers_;
399 // Mapping of int index to MFC input buffer record. 362 // Mapping of int index to MFC input buffer record.
400 std::vector<MfcInputRecord> mfc_input_buffer_map_; 363 std::vector<MfcInputRecord> mfc_input_buffer_map_;
401 364
402 // MFC output buffer state. 365 // MFC output buffer state.
403 bool mfc_output_streamon_; 366 bool mfc_output_streamon_;
404 // MFC output buffers enqueued to device. 367 // MFC output buffers enqueued to device.
405 int mfc_output_buffer_queued_count_; 368 int mfc_output_buffer_queued_count_;
406 // Output buffers ready to use, as a LIFO since we don't care about ordering. 369 // Output buffers ready to use, as a FIFO since we want oldest-first.
Pawel Osciak 2013/09/30 05:16:25 Document why oldest-first please.
sheu 2013/10/04 23:25:56 Done.
407 std::vector<int> mfc_free_output_buffers_; 370 std::list<int> mfc_free_output_buffers_;
Pawel Osciak 2013/09/30 05:16:25 std::queue?
sheu 2013/10/04 23:25:56 Can't clear() them.
Pawel Osciak 2013/10/05 00:06:33 https://code.google.com/p/chromium/codesearch#chro
sheu 2013/11/07 02:37:27 Seems kind of... inefficient?
Pawel Osciak 2013/11/07 03:48:46 Seems kind of an... overoptimization? ;) Especiall
408 // Mapping of int index to MFC output buffer record. 371 // Mapping of int index to MFC output buffer record.
409 std::vector<MfcOutputRecord> mfc_output_buffer_map_; 372 std::vector<MfcOutputRecord> mfc_output_buffer_map_;
410 // Required size of MFC output buffers. Two sizes for two planes. 373 // Required size of MFC output buffers. Two sizes for two planes.
411 size_t mfc_output_buffer_size_[2]; 374 size_t mfc_output_buffer_size_[2];
412 uint32 mfc_output_buffer_pixelformat_; 375 uint32 mfc_output_buffer_pixelformat_;
413 // Required size of DPB for decoding. 376 // Required size of DPB for decoding.
414 int mfc_output_dpb_size_; 377 int mfc_output_dpb_size_;
415 378
416 // Completed MFC outputs, waiting for GSC.
417 std::list<int> mfc_output_gsc_input_queue_;
418
419 // GSC decode device.
420 int gsc_fd_;
421
422 // GSC input buffer state.
423 bool gsc_input_streamon_;
424 // GSC input buffers enqueued to device.
425 int gsc_input_buffer_queued_count_;
426 // Input buffers ready to use, as a LIFO since we don't care about ordering.
427 std::vector<int> gsc_free_input_buffers_;
428 // Mapping of int index to GSC input buffer record.
429 std::vector<GscInputRecord> gsc_input_buffer_map_;
430
431 // GSC output buffer state.
432 bool gsc_output_streamon_;
433 // GSC output buffers enqueued to device.
434 int gsc_output_buffer_queued_count_;
435 // Output buffers ready to use. We need a FIFO here.
436 std::list<int> gsc_free_output_buffers_;
437 // Mapping of int index to GSC output buffer record.
438 std::vector<GscOutputRecord> gsc_output_buffer_map_;
439
440 // Output picture size. 379 // Output picture size.
441 gfx::Size frame_buffer_size_; 380 gfx::Size frame_buffer_size_;
442 381
443 // 382 //
444 // The device polling thread handles notifications of V4L2 device changes. 383 // The device polling thread handles notifications of V4L2 device changes.
445 // 384 //
446 385
447 // The thread. 386 // The thread.
448 base::Thread device_poll_thread_; 387 base::Thread device_poll_thread_;
449 // eventfd fd to signal device poll thread when its poll() should be 388 // eventfd fd to signal device poll thread when its poll() should be
(...skipping 13 matching lines...) Expand all
463 402
464 // The codec we'll be decoding for. 403 // The codec we'll be decoding for.
465 media::VideoCodecProfile video_profile_; 404 media::VideoCodecProfile video_profile_;
466 405
467 DISALLOW_COPY_AND_ASSIGN(ExynosVideoDecodeAccelerator); 406 DISALLOW_COPY_AND_ASSIGN(ExynosVideoDecodeAccelerator);
468 }; 407 };
469 408
470 } // namespace content 409 } // namespace content
471 410
472 #endif // CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_DECODE_ACCELERATOR_H_ 411 #endif // CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_DECODE_ACCELERATOR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698