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 #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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |