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

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

Issue 9346012: Video decode in hardware on ARM platform. (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Created 8 years, 10 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
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"
11 #include "base/string_util.h" 11 #include "base/string_util.h"
12 #include "content/common/gpu/gpu_channel.h" 12 #include "content/common/gpu/gpu_channel.h"
13 #include "content/common/gpu/media/gles2_texture_to_egl_image_translator.h" 13 #include "content/common/gpu/media/gles2_texture_to_egl_image_translator.h"
14 #include "media/base/bitstream_buffer.h" 14 #include "media/base/bitstream_buffer.h"
15 #include "media/video/picture.h" 15 #include "media/video/picture.h"
16 16
17 // Helper typedef for input buffers. This is used as the pAppPrivate field of 17 // Helper typedef for input buffers. This is used as the pAppPrivate field of
18 // OMX_BUFFERHEADERTYPEs of input buffers, to point to the data associated with 18 // OMX_BUFFERHEADERTYPEs of input buffers, to point to the data associated with
19 // them. 19 // them.
20 typedef std::pair<scoped_ptr<base::SharedMemory>, int32> SharedMemoryAndId; 20 typedef std::pair<scoped_ptr<base::SharedMemory>, int32> SharedMemoryAndId;
21 21
22 enum { kNumPictureBuffers = 4 }; 22 enum { kNumPictureBuffers = 4 };
23 23
24 int width_ = 0;
25 int height_ = 0;
Ami GONE FROM CHROMIUM 2012/02/07 17:05:40 No. These are mutable static globals, and are a b
24 // Open the libnvomx here for now. 26 // Open the libnvomx here for now.
25 void* omx_handle = dlopen("libnvomx.so", RTLD_NOW); 27 void* omx_handle = dlopen("libnvomx.so", RTLD_NOW);
26 28
27 typedef OMX_ERRORTYPE (*OMXInit)(); 29 typedef OMX_ERRORTYPE (*OMXInit)();
28 typedef OMX_ERRORTYPE (*OMXGetHandle)( 30 typedef OMX_ERRORTYPE (*OMXGetHandle)(
29 OMX_HANDLETYPE*, OMX_STRING, OMX_PTR, OMX_CALLBACKTYPE*); 31 OMX_HANDLETYPE*, OMX_STRING, OMX_PTR, OMX_CALLBACKTYPE*);
30 typedef OMX_ERRORTYPE (*OMXGetComponentsOfRole)(OMX_STRING, OMX_U32*, OMX_U8**); 32 typedef OMX_ERRORTYPE (*OMXGetComponentsOfRole)(OMX_STRING, OMX_U32*, OMX_U8**);
31 typedef OMX_ERRORTYPE (*OMXFreeHandle)(OMX_HANDLETYPE); 33 typedef OMX_ERRORTYPE (*OMXFreeHandle)(OMX_HANDLETYPE);
32 typedef OMX_ERRORTYPE (*OMXDeinit)(); 34 typedef OMX_ERRORTYPE (*OMXDeinit)();
33 35
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 client_state_(OMX_StateMax), 106 client_state_(OMX_StateMax),
105 current_state_change_(NO_TRANSITION), 107 current_state_change_(NO_TRANSITION),
106 input_buffer_count_(0), 108 input_buffer_count_(0),
107 input_buffer_size_(0), 109 input_buffer_size_(0),
108 input_port_(0), 110 input_port_(0),
109 input_buffers_at_component_(0), 111 input_buffers_at_component_(0),
110 output_port_(0), 112 output_port_(0),
111 output_buffers_at_component_(0), 113 output_buffers_at_component_(0),
112 client_(client), 114 client_(client),
113 profile_(OMX_VIDEO_AVCProfileMax), 115 profile_(OMX_VIDEO_AVCProfileMax),
114 component_name_is_nvidia_h264ext_(false) { 116 component_name_is_nvidia_h264ext_(false),
117 component_name_is_sec_h264ext_(false) {
115 RETURN_ON_FAILURE(AreOMXFunctionPointersInitialized(), 118 RETURN_ON_FAILURE(AreOMXFunctionPointersInitialized(),
116 "Failed to load openmax library", PLATFORM_FAILURE,); 119 "Failed to load openmax library", PLATFORM_FAILURE,);
117 RETURN_ON_OMX_FAILURE(omx_init(), "Failed to init OpenMAX core", 120 RETURN_ON_OMX_FAILURE(omx_init(), "Failed to init OpenMAX core",
118 PLATFORM_FAILURE,); 121 PLATFORM_FAILURE,);
119 } 122 }
120 123
121 OmxVideoDecodeAccelerator::~OmxVideoDecodeAccelerator() { 124 OmxVideoDecodeAccelerator::~OmxVideoDecodeAccelerator() {
122 DCHECK_EQ(message_loop_, MessageLoop::current()); 125 DCHECK_EQ(message_loop_, MessageLoop::current());
123 DCHECK(free_input_buffers_.empty()); 126 DCHECK(free_input_buffers_.empty());
124 DCHECK_EQ(0, input_buffers_at_component_); 127 DCHECK_EQ(0, input_buffers_at_component_);
125 DCHECK_EQ(0, output_buffers_at_component_); 128 DCHECK_EQ(0, output_buffers_at_component_);
126 DCHECK(pictures_.empty()); 129 DCHECK(pictures_.empty());
127 } 130 }
128 131
129 void OmxVideoDecodeAccelerator::SetEglState( 132 void OmxVideoDecodeAccelerator::SetEglState(
130 EGLDisplay egl_display, EGLContext egl_context) { 133 Display* x_display, EGLDisplay egl_display,
134 EGLContext egl_context, EGLSurface egl_surface) {
131 DCHECK_EQ(message_loop_, MessageLoop::current()); 135 DCHECK_EQ(message_loop_, MessageLoop::current());
136 x_display_ = x_display;
132 egl_display_ = egl_display; 137 egl_display_ = egl_display;
133 egl_context_ = egl_context; 138 egl_context_ = egl_context;
139 egl_surface_ = egl_surface;
134 } 140 }
135 141
136 // This is to initialize the OMX data structures to default values. 142 // This is to initialize the OMX data structures to default values.
137 template <typename T> 143 template <typename T>
138 static void InitParam(const OmxVideoDecodeAccelerator& dec, T* param) { 144 static void InitParam(const OmxVideoDecodeAccelerator& dec, T* param) {
139 memset(param, 0, sizeof(T)); 145 memset(param, 0, sizeof(T));
140 param->nVersion.nVersion = 0x00000101; 146 param->nVersion.nVersion = 0x00000101;
141 param->nSize = sizeof(T); 147 param->nSize = sizeof(T);
142 } 148 }
143 149
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 this, &omx_accelerator_callbacks); 198 this, &omx_accelerator_callbacks);
193 RETURN_ON_OMX_FAILURE(result, 199 RETURN_ON_OMX_FAILURE(result,
194 "Failed to OMX_GetHandle on: " << component.get(), 200 "Failed to OMX_GetHandle on: " << component.get(),
195 PLATFORM_FAILURE, false); 201 PLATFORM_FAILURE, false);
196 client_state_ = OMX_StateLoaded; 202 client_state_ = OMX_StateLoaded;
197 203
198 component_name_is_nvidia_h264ext_ = !strcmp( 204 component_name_is_nvidia_h264ext_ = !strcmp(
199 reinterpret_cast<char *>(component.get()), 205 reinterpret_cast<char *>(component.get()),
200 "OMX.Nvidia.h264ext.decode"); 206 "OMX.Nvidia.h264ext.decode");
201 207
208 component_name_is_sec_h264ext_ = !strcmp(
209 reinterpret_cast<char *>(component.get()),
210 "OMX.SEC.AVC.Decoder");
Ami GONE FROM CHROMIUM 2012/02/07 17:05:40 What is "SEC"? can you add a comment identifying
211
202 // Get the port information. This will obtain information about the number of 212 // Get the port information. This will obtain information about the number of
203 // ports and index of the first port. 213 // ports and index of the first port.
204 OMX_PORT_PARAM_TYPE port_param; 214 OMX_PORT_PARAM_TYPE port_param;
205 InitParam(*this, &port_param); 215 InitParam(*this, &port_param);
206 result = OMX_GetParameter(component_handle_, OMX_IndexParamVideoInit, 216 result = OMX_GetParameter(component_handle_, OMX_IndexParamVideoInit,
207 &port_param); 217 &port_param);
208 RETURN_ON_FAILURE(result == OMX_ErrorNone && port_param.nPorts == 2, 218 RETURN_ON_FAILURE(result == OMX_ErrorNone && port_param.nPorts == 2,
209 "Failed to get Port Param: " << result << ", " 219 "Failed to get Port Param: " << result << ", "
210 << port_param.nPorts, 220 << port_param.nPorts,
211 PLATFORM_FAILURE, false); 221 PLATFORM_FAILURE, false);
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 const std::vector<media::PictureBuffer>& buffers) { 349 const std::vector<media::PictureBuffer>& buffers) {
340 DCHECK_EQ(message_loop_, MessageLoop::current()); 350 DCHECK_EQ(message_loop_, MessageLoop::current());
341 RETURN_ON_FAILURE(CanFillBuffer(), "Can't fill buffer", ILLEGAL_STATE,); 351 RETURN_ON_FAILURE(CanFillBuffer(), "Can't fill buffer", ILLEGAL_STATE,);
342 352
343 DCHECK_EQ(output_buffers_at_component_, 0); 353 DCHECK_EQ(output_buffers_at_component_, 0);
344 DCHECK_EQ(fake_output_buffers_.size(), 0U); 354 DCHECK_EQ(fake_output_buffers_.size(), 0U);
345 DCHECK_EQ(pictures_.size(), 0U); 355 DCHECK_EQ(pictures_.size(), 0U);
346 356
347 static Gles2TextureToEglImageTranslator texture2eglImage_translator; 357 static Gles2TextureToEglImageTranslator texture2eglImage_translator;
348 for (size_t i = 0; i < buffers.size(); ++i) { 358 for (size_t i = 0; i < buffers.size(); ++i) {
349 EGLImageKHR egl_image = texture2eglImage_translator.TranslateToEglImage( 359 EGLImageKHR egl_image;
350 egl_display_, egl_context_, buffers[i].texture_id()); 360 if(component_name_is_sec_h264ext_) {
361 egl_image = texture2eglImage_translator.CreateEglImage(
362 x_display_, egl_display_, egl_context_, egl_surface_,
363 buffers[i].texture_id(), width_, height_);
364 }
365 else {
366 egl_image = texture2eglImage_translator.TranslateToEglImage(
367 egl_display_, egl_context_, buffers[i].texture_id());
368 }
351 CHECK(pictures_.insert(std::make_pair( 369 CHECK(pictures_.insert(std::make_pair(
352 buffers[i].id(), OutputPicture(buffers[i], NULL, egl_image))).second); 370 buffers[i].id(), OutputPicture(buffers[i], NULL, egl_image))).second);
353 } 371 }
354 372
355 if (pictures_.size() < kNumPictureBuffers) 373 if (pictures_.size() < kNumPictureBuffers)
356 return; // get all the buffers first. 374 return; // get all the buffers first.
357 DCHECK_EQ(pictures_.size(), kNumPictureBuffers); 375 DCHECK_EQ(pictures_.size(), kNumPictureBuffers);
358 376
359 // These do their own RETURN_ON_FAILURE dances. 377 // These do their own RETURN_ON_FAILURE dances.
360 if (!AllocateOutputBuffers()) 378 if (!AllocateOutputBuffers())
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 // Calls to OMX to free buffers. 715 // Calls to OMX to free buffers.
698 OMX_ERRORTYPE result; 716 OMX_ERRORTYPE result;
699 static Gles2TextureToEglImageTranslator texture2eglImage_translator; 717 static Gles2TextureToEglImageTranslator texture2eglImage_translator;
700 for (OutputPictureById::iterator it = pictures_.begin(); 718 for (OutputPictureById::iterator it = pictures_.begin();
701 it != pictures_.end(); ++it) { 719 it != pictures_.end(); ++it) {
702 OMX_BUFFERHEADERTYPE* omx_buffer = it->second.omx_buffer_header; 720 OMX_BUFFERHEADERTYPE* omx_buffer = it->second.omx_buffer_header;
703 DCHECK(omx_buffer); 721 DCHECK(omx_buffer);
704 delete reinterpret_cast<media::Picture*>(omx_buffer->pAppPrivate); 722 delete reinterpret_cast<media::Picture*>(omx_buffer->pAppPrivate);
705 result = OMX_FreeBuffer(component_handle_, output_port_, omx_buffer); 723 result = OMX_FreeBuffer(component_handle_, output_port_, omx_buffer);
706 RETURN_ON_OMX_FAILURE(result, "OMX_FreeBuffer", PLATFORM_FAILURE,); 724 RETURN_ON_OMX_FAILURE(result, "OMX_FreeBuffer", PLATFORM_FAILURE,);
707 texture2eglImage_translator.DestroyEglImage(egl_display_, 725 texture2eglImage_translator.DestroyEglImage(x_display_, egl_display_,
708 it->second.egl_image); 726 it->second.egl_image);
709 if (client_) 727 if (client_)
710 client_->DismissPictureBuffer(it->first); 728 client_->DismissPictureBuffer(it->first);
711 } 729 }
712 pictures_.clear(); 730 pictures_.clear();
713 } 731 }
714 732
715 void OmxVideoDecodeAccelerator::OnOutputPortDisabled() { 733 void OmxVideoDecodeAccelerator::OnOutputPortDisabled() {
716 DCHECK_EQ(message_loop_, MessageLoop::current()); 734 DCHECK_EQ(message_loop_, MessageLoop::current());
717 OMX_PARAM_PORTDEFINITIONTYPE port_format; 735 OMX_PARAM_PORTDEFINITIONTYPE port_format;
718 InitParam(*this, &port_format); 736 InitParam(*this, &port_format);
719 port_format.nPortIndex = output_port_; 737 port_format.nPortIndex = output_port_;
720 OMX_ERRORTYPE result = OMX_GetParameter( 738 OMX_ERRORTYPE result = OMX_GetParameter(
721 component_handle_, OMX_IndexParamPortDefinition, &port_format); 739 component_handle_, OMX_IndexParamPortDefinition, &port_format);
722 RETURN_ON_OMX_FAILURE(result, "OMX_GetParameter", PLATFORM_FAILURE,); 740 RETURN_ON_OMX_FAILURE(result, "OMX_GetParameter", PLATFORM_FAILURE,);
723 DCHECK_EQ(port_format.nBufferCountMin, kNumPictureBuffers); 741 DCHECK_EQ(port_format.nBufferCountMin, kNumPictureBuffers);
724 742
725 // TODO(fischman): to support mid-stream resize, need to free/dismiss any 743 // TODO(fischman): to support mid-stream resize, need to free/dismiss any
726 // |pictures_| we already have. Make sure that the shutdown-path agrees with 744 // |pictures_| we already have. Make sure that the shutdown-path agrees with
727 // this (there's already freeing logic there, which should not be duplicated). 745 // this (there's already freeing logic there, which should not be duplicated).
728 746
729 // Request picture buffers to be handed to the component. 747 // Request picture buffers to be handed to the component.
730 // ProvidePictureBuffers() will trigger AssignPictureBuffers, which ultimately 748 // ProvidePictureBuffers() will trigger AssignPictureBuffers, which ultimately
731 // assigns the textures to the component and re-enables the port. 749 // assigns the textures to the component and re-enables the port.
732 const OMX_VIDEO_PORTDEFINITIONTYPE& vformat = port_format.format.video; 750 const OMX_VIDEO_PORTDEFINITIONTYPE& vformat = port_format.format.video;
751 width_ = vformat.nFrameWidth;
752 height_ = vformat.nFrameHeight;
753
733 if (client_) { 754 if (client_) {
734 client_->ProvidePictureBuffers( 755 client_->ProvidePictureBuffers(
735 kNumPictureBuffers, 756 kNumPictureBuffers,
736 gfx::Size(vformat.nFrameWidth, vformat.nFrameHeight)); 757 gfx::Size(vformat.nFrameWidth, vformat.nFrameHeight));
737 } 758 }
738 } 759 }
739 760
740 void OmxVideoDecodeAccelerator::OnOutputPortEnabled() { 761 void OmxVideoDecodeAccelerator::OnOutputPortEnabled() {
741 DCHECK_EQ(message_loop_, MessageLoop::current()); 762 DCHECK_EQ(message_loop_, MessageLoop::current());
742 763
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 1054
1034 bool OmxVideoDecodeAccelerator::SendCommandToPort( 1055 bool OmxVideoDecodeAccelerator::SendCommandToPort(
1035 OMX_COMMANDTYPE cmd, int port_index) { 1056 OMX_COMMANDTYPE cmd, int port_index) {
1036 DCHECK_EQ(message_loop_, MessageLoop::current()); 1057 DCHECK_EQ(message_loop_, MessageLoop::current());
1037 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_, 1058 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_,
1038 cmd, port_index, 0); 1059 cmd, port_index, 0);
1039 RETURN_ON_OMX_FAILURE(result, "SendCommand() failed" << cmd, 1060 RETURN_ON_OMX_FAILURE(result, "SendCommand() failed" << cmd,
1040 PLATFORM_FAILURE, false); 1061 PLATFORM_FAILURE, false);
1041 return true; 1062 return true;
1042 } 1063 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698