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

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"
14 #include "media/base/bitstream_buffer.h" 13 #include "media/base/bitstream_buffer.h"
15 #include "media/video/picture.h" 14 #include "media/video/picture.h"
16 15
16 #if (defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL))
Ami GONE FROM CHROMIUM 2012/02/18 00:00:25 No other configuration builds this .cc file so IMO
17 #include "ui/gfx/gl/gl_surface_egl.h"
18 #endif
19
17 // Helper typedef for input buffers. This is used as the pAppPrivate field of 20 // 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 21 // OMX_BUFFERHEADERTYPEs of input buffers, to point to the data associated with
19 // them. 22 // them.
20 typedef std::pair<scoped_ptr<base::SharedMemory>, int32> SharedMemoryAndId; 23 typedef std::pair<scoped_ptr<base::SharedMemory>, int32> SharedMemoryAndId;
21 24
22 enum { kNumPictureBuffers = 4 }; 25 enum { kNumPictureBuffers = 4 };
23 26
24 // Open the libnvomx here for now. 27 // Open the libnvomx here for now.
25 void* omx_handle = dlopen("libnvomx.so", RTLD_NOW); 28 void* omx_handle = dlopen("libnvomx.so", RTLD_NOW);
26 29
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 : message_loop_(MessageLoop::current()), 105 : message_loop_(MessageLoop::current()),
103 component_handle_(NULL), 106 component_handle_(NULL),
104 client_state_(OMX_StateMax), 107 client_state_(OMX_StateMax),
105 current_state_change_(NO_TRANSITION), 108 current_state_change_(NO_TRANSITION),
106 input_buffer_count_(0), 109 input_buffer_count_(0),
107 input_buffer_size_(0), 110 input_buffer_size_(0),
108 input_port_(0), 111 input_port_(0),
109 input_buffers_at_component_(0), 112 input_buffers_at_component_(0),
110 output_port_(0), 113 output_port_(0),
111 output_buffers_at_component_(0), 114 output_buffers_at_component_(0),
115 width_(-1),
116 height_(-1),
112 client_(client), 117 client_(client),
113 profile_(OMX_VIDEO_AVCProfileMax), 118 profile_(OMX_VIDEO_AVCProfileMax),
114 component_name_is_nvidia_h264ext_(false) { 119 component_name_is_nvidia_h264ext_(false),
120 component_name_is_sec_h264ext_(false) {
115 RETURN_ON_FAILURE(AreOMXFunctionPointersInitialized(), 121 RETURN_ON_FAILURE(AreOMXFunctionPointersInitialized(),
116 "Failed to load openmax library", PLATFORM_FAILURE,); 122 "Failed to load openmax library", PLATFORM_FAILURE,);
117 RETURN_ON_OMX_FAILURE(omx_init(), "Failed to init OpenMAX core", 123 RETURN_ON_OMX_FAILURE(omx_init(), "Failed to init OpenMAX core",
118 PLATFORM_FAILURE,); 124 PLATFORM_FAILURE,);
119 } 125 }
120 126
121 OmxVideoDecodeAccelerator::~OmxVideoDecodeAccelerator() { 127 OmxVideoDecodeAccelerator::~OmxVideoDecodeAccelerator() {
122 DCHECK_EQ(message_loop_, MessageLoop::current()); 128 DCHECK_EQ(message_loop_, MessageLoop::current());
123 DCHECK(free_input_buffers_.empty()); 129 DCHECK(free_input_buffers_.empty());
124 DCHECK_EQ(0, input_buffers_at_component_); 130 DCHECK_EQ(0, input_buffers_at_component_);
(...skipping 67 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");
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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 347
338 void OmxVideoDecodeAccelerator::AssignPictureBuffers( 348 void OmxVideoDecodeAccelerator::AssignPictureBuffers(
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 Display* x_display = NULL;
358 if (component_name_is_sec_h264ext_)
359 x_display = gfx::GLSurfaceEGL::GetNativeDisplay();
360
361 texture2eglImage_translator_ =
Ami GONE FROM CHROMIUM 2012/02/18 00:00:25 This is leaking a translator per call to AssignPic
362 new Gles2TextureToEglImageTranslator(x_display);
348 for (size_t i = 0; i < buffers.size(); ++i) { 363 for (size_t i = 0; i < buffers.size(); ++i) {
349 EGLImageKHR egl_image = texture2eglImage_translator.TranslateToEglImage( 364 EGLImageKHR egl_image = texture2eglImage_translator_->TranslateToEglImage(
350 egl_display_, egl_context_, buffers[i].texture_id()); 365 egl_display_, egl_context_,
366 buffers[i].texture_id(), width_, height_);
351 CHECK(pictures_.insert(std::make_pair( 367 CHECK(pictures_.insert(std::make_pair(
352 buffers[i].id(), OutputPicture(buffers[i], NULL, egl_image))).second); 368 buffers[i].id(), OutputPicture(buffers[i], NULL, egl_image))).second);
353 } 369 }
354 370
355 if (pictures_.size() < kNumPictureBuffers) 371 if (pictures_.size() < kNumPictureBuffers)
356 return; // get all the buffers first. 372 return; // get all the buffers first.
357 DCHECK_EQ(pictures_.size(), kNumPictureBuffers); 373 DCHECK_EQ(pictures_.size(), kNumPictureBuffers);
358 374
359 // These do their own RETURN_ON_FAILURE dances. 375 // These do their own RETURN_ON_FAILURE dances.
360 if (!AllocateOutputBuffers()) 376 if (!AllocateOutputBuffers())
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
689 free_input_buffers_.pop(); 705 free_input_buffers_.pop();
690 result = OMX_FreeBuffer(component_handle_, input_port_, omx_buffer); 706 result = OMX_FreeBuffer(component_handle_, input_port_, omx_buffer);
691 RETURN_ON_OMX_FAILURE(result, "OMX_FreeBuffer", PLATFORM_FAILURE,); 707 RETURN_ON_OMX_FAILURE(result, "OMX_FreeBuffer", PLATFORM_FAILURE,);
692 } 708 }
693 } 709 }
694 710
695 void OmxVideoDecodeAccelerator::FreeOutputBuffers() { 711 void OmxVideoDecodeAccelerator::FreeOutputBuffers() {
696 DCHECK_EQ(message_loop_, MessageLoop::current()); 712 DCHECK_EQ(message_loop_, MessageLoop::current());
697 // Calls to OMX to free buffers. 713 // Calls to OMX to free buffers.
698 OMX_ERRORTYPE result; 714 OMX_ERRORTYPE result;
699 static Gles2TextureToEglImageTranslator texture2eglImage_translator;
700 for (OutputPictureById::iterator it = pictures_.begin(); 715 for (OutputPictureById::iterator it = pictures_.begin();
701 it != pictures_.end(); ++it) { 716 it != pictures_.end(); ++it) {
702 OMX_BUFFERHEADERTYPE* omx_buffer = it->second.omx_buffer_header; 717 OMX_BUFFERHEADERTYPE* omx_buffer = it->second.omx_buffer_header;
703 DCHECK(omx_buffer); 718 DCHECK(omx_buffer);
704 delete reinterpret_cast<media::Picture*>(omx_buffer->pAppPrivate); 719 delete reinterpret_cast<media::Picture*>(omx_buffer->pAppPrivate);
705 result = OMX_FreeBuffer(component_handle_, output_port_, omx_buffer); 720 result = OMX_FreeBuffer(component_handle_, output_port_, omx_buffer);
706 RETURN_ON_OMX_FAILURE(result, "OMX_FreeBuffer", PLATFORM_FAILURE,); 721 RETURN_ON_OMX_FAILURE(result, "OMX_FreeBuffer", PLATFORM_FAILURE,);
707 texture2eglImage_translator.DestroyEglImage(egl_display_, 722 texture2eglImage_translator_->DestroyEglImage(egl_display_,
708 it->second.egl_image); 723 it->second.egl_image);
709 if (client_) 724 if (client_)
710 client_->DismissPictureBuffer(it->first); 725 client_->DismissPictureBuffer(it->first);
711 } 726 }
712 pictures_.clear(); 727 pictures_.clear();
713 } 728 }
714 729
715 void OmxVideoDecodeAccelerator::OnOutputPortDisabled() { 730 void OmxVideoDecodeAccelerator::OnOutputPortDisabled() {
716 DCHECK_EQ(message_loop_, MessageLoop::current()); 731 DCHECK_EQ(message_loop_, MessageLoop::current());
717 OMX_PARAM_PORTDEFINITIONTYPE port_format; 732 OMX_PARAM_PORTDEFINITIONTYPE port_format;
718 InitParam(*this, &port_format); 733 InitParam(*this, &port_format);
719 port_format.nPortIndex = output_port_; 734 port_format.nPortIndex = output_port_;
720 OMX_ERRORTYPE result = OMX_GetParameter( 735 OMX_ERRORTYPE result = OMX_GetParameter(
721 component_handle_, OMX_IndexParamPortDefinition, &port_format); 736 component_handle_, OMX_IndexParamPortDefinition, &port_format);
722 RETURN_ON_OMX_FAILURE(result, "OMX_GetParameter", PLATFORM_FAILURE,); 737 RETURN_ON_OMX_FAILURE(result, "OMX_GetParameter", PLATFORM_FAILURE,);
723 DCHECK_EQ(port_format.nBufferCountMin, kNumPictureBuffers); 738 DCHECK_EQ(port_format.nBufferCountMin, kNumPictureBuffers);
724 739
725 // TODO(fischman): to support mid-stream resize, need to free/dismiss any 740 // 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 741 // |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). 742 // this (there's already freeing logic there, which should not be duplicated).
728 743
729 // Request picture buffers to be handed to the component. 744 // Request picture buffers to be handed to the component.
730 // ProvidePictureBuffers() will trigger AssignPictureBuffers, which ultimately 745 // ProvidePictureBuffers() will trigger AssignPictureBuffers, which ultimately
731 // assigns the textures to the component and re-enables the port. 746 // assigns the textures to the component and re-enables the port.
732 const OMX_VIDEO_PORTDEFINITIONTYPE& vformat = port_format.format.video; 747 const OMX_VIDEO_PORTDEFINITIONTYPE& vformat = port_format.format.video;
748 width_ = vformat.nFrameWidth;
749 height_ = vformat.nFrameHeight;
750
733 if (client_) { 751 if (client_) {
734 client_->ProvidePictureBuffers( 752 client_->ProvidePictureBuffers(
735 kNumPictureBuffers, 753 kNumPictureBuffers,
736 gfx::Size(vformat.nFrameWidth, vformat.nFrameHeight)); 754 gfx::Size(vformat.nFrameWidth, vformat.nFrameHeight));
737 } 755 }
738 } 756 }
739 757
740 void OmxVideoDecodeAccelerator::OnOutputPortEnabled() { 758 void OmxVideoDecodeAccelerator::OnOutputPortEnabled() {
741 DCHECK_EQ(message_loop_, MessageLoop::current()); 759 DCHECK_EQ(message_loop_, MessageLoop::current());
742 760
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 1051
1034 bool OmxVideoDecodeAccelerator::SendCommandToPort( 1052 bool OmxVideoDecodeAccelerator::SendCommandToPort(
1035 OMX_COMMANDTYPE cmd, int port_index) { 1053 OMX_COMMANDTYPE cmd, int port_index) {
1036 DCHECK_EQ(message_loop_, MessageLoop::current()); 1054 DCHECK_EQ(message_loop_, MessageLoop::current());
1037 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_, 1055 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_,
1038 cmd, port_index, 0); 1056 cmd, port_index, 0);
1039 RETURN_ON_OMX_FAILURE(result, "SendCommand() failed" << cmd, 1057 RETURN_ON_OMX_FAILURE(result, "SendCommand() failed" << cmd,
1040 PLATFORM_FAILURE, false); 1058 PLATFORM_FAILURE, false);
1041 return true; 1059 return true;
1042 } 1060 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698