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

Side by Side Diff: content/common/gpu/media/omx_video_decode_accelerator.cc

Issue 11076009: OVDA: Perform an egl sync before reusing a texture. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 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 | Annotate | Revision Log
« no previous file with comments | « content/common/gpu/media/omx_video_decode_accelerator.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include "content/common/gpu/media/omx_video_decode_accelerator.h" 5 #include "content/common/gpu/media/omx_video_decode_accelerator.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/debug/trace_event.h" 8 #include "base/debug/trace_event.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
(...skipping 18 matching lines...) Expand all
29 typedef OMX_ERRORTYPE (*OMXGetComponentsOfRole)(OMX_STRING, OMX_U32*, OMX_U8**); 29 typedef OMX_ERRORTYPE (*OMXGetComponentsOfRole)(OMX_STRING, OMX_U32*, OMX_U8**);
30 typedef OMX_ERRORTYPE (*OMXFreeHandle)(OMX_HANDLETYPE); 30 typedef OMX_ERRORTYPE (*OMXFreeHandle)(OMX_HANDLETYPE);
31 typedef OMX_ERRORTYPE (*OMXDeinit)(); 31 typedef OMX_ERRORTYPE (*OMXDeinit)();
32 32
33 OMXInit omx_init = NULL; 33 OMXInit omx_init = NULL;
34 OMXGetHandle omx_gethandle = NULL; 34 OMXGetHandle omx_gethandle = NULL;
35 OMXGetComponentsOfRole omx_get_components_of_role = NULL; 35 OMXGetComponentsOfRole omx_get_components_of_role = NULL;
36 OMXFreeHandle omx_free_handle = NULL; 36 OMXFreeHandle omx_free_handle = NULL;
37 OMXDeinit omx_deinit = NULL; 37 OMXDeinit omx_deinit = NULL;
38 38
39 static PFNEGLCREATESYNCKHRPROC egl_create_sync_khr = NULL;
40 static PFNEGLGETSYNCATTRIBKHRPROC egl_get_sync_attrib_khr = NULL;
41 static PFNEGLDESTROYSYNCKHRPROC egl_destroy_sync_khr = NULL;
42
39 // Maps h264-related Profile enum values to OMX_VIDEO_AVCPROFILETYPE values. 43 // Maps h264-related Profile enum values to OMX_VIDEO_AVCPROFILETYPE values.
40 static OMX_U32 MapH264ProfileToOMXAVCProfile(uint32 profile) { 44 static OMX_U32 MapH264ProfileToOMXAVCProfile(uint32 profile) {
41 switch (profile) { 45 switch (profile) {
42 case media::H264PROFILE_BASELINE: 46 case media::H264PROFILE_BASELINE:
43 return OMX_VIDEO_AVCProfileBaseline; 47 return OMX_VIDEO_AVCProfileBaseline;
44 case media::H264PROFILE_MAIN: 48 case media::H264PROFILE_MAIN:
45 return OMX_VIDEO_AVCProfileMain; 49 return OMX_VIDEO_AVCProfileMain;
46 case media::H264PROFILE_EXTENDED: 50 case media::H264PROFILE_EXTENDED:
47 return OMX_VIDEO_AVCProfileExtended; 51 return OMX_VIDEO_AVCProfileExtended;
48 case media::H264PROFILE_HIGH: 52 case media::H264PROFILE_HIGH:
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 return; // get all the buffers first. 383 return; // get all the buffers first.
380 DCHECK_EQ(pictures_.size(), kNumPictureBuffers); 384 DCHECK_EQ(pictures_.size(), kNumPictureBuffers);
381 385
382 // These do their own RETURN_ON_FAILURE dances. 386 // These do their own RETURN_ON_FAILURE dances.
383 if (!AllocateOutputBuffers()) 387 if (!AllocateOutputBuffers())
384 return; 388 return;
385 if (!SendCommandToPort(OMX_CommandPortEnable, output_port_)) 389 if (!SendCommandToPort(OMX_CommandPortEnable, output_port_))
386 return; 390 return;
387 } 391 }
388 392
393 class OmxVideoDecodeAccelerator::PictureSyncObject {
piman 2012/10/12 19:37:10 nit: we usually don't define inner classes in the
Pawel Osciak 2012/10/12 20:33:08 Ok, if that's the convention. (The idea was to hav
394 public:
395 // Create a sync object and insert into the GPU command stream.
396 PictureSyncObject(EGLDisplay egl_display);
397 ~PictureSyncObject();
398
399 // Check the status of the sync object. Return true if synced.
Ami GONE FROM CHROMIUM 2012/10/12 19:34:46 Style-guide-sanctioned comment style would be: //
Pawel Osciak 2012/10/12 20:33:08 Done.
400 bool IsSynced();
401
402 private:
403 EGLSyncKHR egl_sync_obj_;
404 EGLDisplay egl_display_;
405 };
406
407 OmxVideoDecodeAccelerator::PictureSyncObject::PictureSyncObject(
408 EGLDisplay egl_display)
409 : egl_display_(egl_display) {
410 DCHECK(egl_display_ != EGL_NO_DISPLAY);
411
412 egl_sync_obj_ = egl_create_sync_khr(egl_display_, EGL_SYNC_FENCE_KHR, NULL);
413 DCHECK(egl_sync_obj_ != EGL_NO_SYNC_KHR)
414 << "Failed creating a sync object, will not sync.";
Ami GONE FROM CHROMIUM 2012/10/12 19:34:46 msg is still bogus (not only will the process not
Pawel Osciak 2012/10/12 20:33:08 Heh. Somehow my brain won't acknowledge that this
415 }
416
417 OmxVideoDecodeAccelerator::PictureSyncObject::~PictureSyncObject() {
418 if (egl_sync_obj_ != EGL_NO_SYNC_KHR)
Ami GONE FROM CHROMIUM 2012/10/12 19:34:46 Not possible for this to be false anymore, so can
Pawel Osciak 2012/10/12 20:33:08 Done.
419 egl_destroy_sync_khr(egl_display_, egl_sync_obj_);
420 }
421
422 bool OmxVideoDecodeAccelerator::PictureSyncObject::IsSynced() {
423 EGLint value;
piman 2012/10/12 19:37:10 nit: = 0
Ami GONE FROM CHROMIUM 2012/10/12 19:43:56 OOC: Why?
Pawel Osciak 2012/10/12 20:33:08 Are you worried the call would exit early before o
Pawel Osciak 2012/10/12 20:34:54 Oh, but that's only only in debug builds. I really
424 EGLBoolean ret = egl_get_sync_attrib_khr(
425 egl_display_, egl_sync_obj_, EGL_SYNC_STATUS_KHR, &value);
426 DCHECK(ret) << "Failed getting sync object state.";
427
428 if (value == EGL_UNSIGNALED_KHR)
Ami GONE FROM CHROMIUM 2012/10/12 19:34:46 l.428-431 is equiv to return value == EGL_SIGNALED
Pawel Osciak 2012/10/12 20:33:08 Done.
429 return false;
430
431 return true;
432 }
433
389 void OmxVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) { 434 void OmxVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) {
435 DCHECK_EQ(message_loop_, MessageLoop::current());
390 TRACE_EVENT1("Video Decoder", "OVDA::ReusePictureBuffer", 436 TRACE_EVENT1("Video Decoder", "OVDA::ReusePictureBuffer",
391 "Picture id", picture_buffer_id); 437 "Picture id", picture_buffer_id);
438 scoped_ptr<PictureSyncObject> egl_sync_obj(
439 new PictureSyncObject(egl_display_));
440
441 // Start checking sync status periodically.
442 CheckPictureStatus(picture_buffer_id, egl_sync_obj.Pass());
443 }
444
445 void OmxVideoDecodeAccelerator::CheckPictureStatus(
446 int32 picture_buffer_id,
447 scoped_ptr<PictureSyncObject> egl_sync_obj) {
448 DCHECK_EQ(message_loop_, MessageLoop::current());
449
450 // It's possible for this task to never run if the message loop is
451 // stopped. In that case we may never call QueuePictureBuffer().
452 // This is fine though, because all pictures, irrespective of their state,
453 // are in pictures_ map and that's what will be used to do the clean up.
454 // 5ms feels like a good compromise, allowing some decoding ahead
455 // (up to 3 frames/vsync) to compensate for more difficult frames.
456 if (!egl_sync_obj->IsSynced()) {
457 MessageLoop::current()->PostDelayedTask(FROM_HERE, base::Bind(
458 &OmxVideoDecodeAccelerator::CheckPictureStatus, weak_this_,
459 picture_buffer_id, base::Passed(&egl_sync_obj)),
460 base::TimeDelta::FromMilliseconds(5));
piman 2012/10/12 19:37:10 nit: can you make this a constant in global scope
Pawel Osciak 2012/10/12 20:33:08 Done.
461 return;
462 }
463
464 // Synced successfully. Queue the buffer for reuse.
465 QueuePictureBuffer(picture_buffer_id);
466 }
467
468 void OmxVideoDecodeAccelerator::QueuePictureBuffer(int32 picture_buffer_id) {
392 DCHECK_EQ(message_loop_, MessageLoop::current()); 469 DCHECK_EQ(message_loop_, MessageLoop::current());
393 470
394 // During port-flushing, do not call OMX FillThisBuffer. 471 // During port-flushing, do not call OMX FillThisBuffer.
395 if (current_state_change_ == RESETTING) { 472 if (current_state_change_ == RESETTING) {
396 queued_picture_buffer_ids_.push_back(picture_buffer_id); 473 queued_picture_buffer_ids_.push_back(picture_buffer_id);
397 return; 474 return;
398 } 475 }
399 476
400 RETURN_ON_FAILURE(CanFillBuffer(), "Can't fill buffer", ILLEGAL_STATE,); 477 // We might have started destroying while waiting for the picture. It's safe
478 // to drop it here, because we will free all the pictures regardless of their
479 // state using the pictures_ map.
480 if (!CanFillBuffer())
481 return;
401 482
402 OutputPictureById::iterator it = pictures_.find(picture_buffer_id); 483 OutputPictureById::iterator it = pictures_.find(picture_buffer_id);
403 RETURN_ON_FAILURE(it != pictures_.end(), 484 RETURN_ON_FAILURE(it != pictures_.end(),
404 "Missing picture buffer id: " << picture_buffer_id, 485 "Missing picture buffer id: " << picture_buffer_id,
405 INVALID_ARGUMENT,); 486 INVALID_ARGUMENT,);
406 OutputPicture& output_picture = it->second; 487 OutputPicture& output_picture = it->second;
407 488
408 ++output_buffers_at_component_; 489 ++output_buffers_at_component_;
409 OMX_ERRORTYPE result = 490 OMX_ERRORTYPE result =
410 OMX_FillThisBuffer(component_handle_, output_picture.omx_buffer_header); 491 OMX_FillThisBuffer(component_handle_, output_picture.omx_buffer_header);
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after
1084 omx_init = reinterpret_cast<OMXInit>(dlsym(omx_handle, "OMX_Init")); 1165 omx_init = reinterpret_cast<OMXInit>(dlsym(omx_handle, "OMX_Init"));
1085 omx_gethandle = 1166 omx_gethandle =
1086 reinterpret_cast<OMXGetHandle>(dlsym(omx_handle, "OMX_GetHandle")); 1167 reinterpret_cast<OMXGetHandle>(dlsym(omx_handle, "OMX_GetHandle"));
1087 omx_get_components_of_role = 1168 omx_get_components_of_role =
1088 reinterpret_cast<OMXGetComponentsOfRole>( 1169 reinterpret_cast<OMXGetComponentsOfRole>(
1089 dlsym(omx_handle, "OMX_GetComponentsOfRole")); 1170 dlsym(omx_handle, "OMX_GetComponentsOfRole"));
1090 omx_free_handle = 1171 omx_free_handle =
1091 reinterpret_cast<OMXFreeHandle>(dlsym(omx_handle, "OMX_FreeHandle")); 1172 reinterpret_cast<OMXFreeHandle>(dlsym(omx_handle, "OMX_FreeHandle"));
1092 omx_deinit = 1173 omx_deinit =
1093 reinterpret_cast<OMXDeinit>(dlsym(omx_handle, "OMX_Deinit")); 1174 reinterpret_cast<OMXDeinit>(dlsym(omx_handle, "OMX_Deinit"));
1175
1176 egl_create_sync_khr = reinterpret_cast<PFNEGLCREATESYNCKHRPROC>(
1177 eglGetProcAddress("eglCreateSyncKHR"));
1178 egl_get_sync_attrib_khr = reinterpret_cast<PFNEGLGETSYNCATTRIBKHRPROC>(
1179 eglGetProcAddress("eglGetSyncAttribKHR"));
1180 egl_destroy_sync_khr = reinterpret_cast<PFNEGLDESTROYSYNCKHRPROC>(
1181 eglGetProcAddress("eglDestroySyncKHR"));
1182
1094 return (omx_init && omx_gethandle && omx_get_components_of_role && 1183 return (omx_init && omx_gethandle && omx_get_components_of_role &&
1095 omx_free_handle && omx_deinit); 1184 omx_free_handle && omx_deinit && egl_create_sync_khr &&
1185 egl_get_sync_attrib_khr && egl_destroy_sync_khr);
1096 } 1186 }
1097 1187
1098 // static 1188 // static
1099 OMX_ERRORTYPE OmxVideoDecodeAccelerator::EventHandler(OMX_HANDLETYPE component, 1189 OMX_ERRORTYPE OmxVideoDecodeAccelerator::EventHandler(OMX_HANDLETYPE component,
1100 OMX_PTR priv_data, 1190 OMX_PTR priv_data,
1101 OMX_EVENTTYPE event, 1191 OMX_EVENTTYPE event,
1102 OMX_U32 data1, 1192 OMX_U32 data1,
1103 OMX_U32 data2, 1193 OMX_U32 data2,
1104 OMX_PTR event_data) { 1194 OMX_PTR event_data) {
1105 // Called on the OMX thread. 1195 // Called on the OMX thread.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1160 1250
1161 bool OmxVideoDecodeAccelerator::SendCommandToPort( 1251 bool OmxVideoDecodeAccelerator::SendCommandToPort(
1162 OMX_COMMANDTYPE cmd, int port_index) { 1252 OMX_COMMANDTYPE cmd, int port_index) {
1163 DCHECK_EQ(message_loop_, MessageLoop::current()); 1253 DCHECK_EQ(message_loop_, MessageLoop::current());
1164 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_, 1254 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_,
1165 cmd, port_index, 0); 1255 cmd, port_index, 0);
1166 RETURN_ON_OMX_FAILURE(result, "SendCommand() failed" << cmd, 1256 RETURN_ON_OMX_FAILURE(result, "SendCommand() failed" << cmd,
1167 PLATFORM_FAILURE, false); 1257 PLATFORM_FAILURE, false);
1168 return true; 1258 return true;
1169 } 1259 }
OLDNEW
« no previous file with comments | « content/common/gpu/media/omx_video_decode_accelerator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698