| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/omx_video_decode_accelerator.h" | 5 #include "content/common/gpu/omx_video_decode_accelerator.h" |
| 6 | 6 |
| 7 #include "base/stl_util-inl.h" | 7 #include "base/stl_util-inl.h" |
| 8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
| 9 #include "content/common/gpu/gles2_texture_to_egl_image_translator.h" | 9 #include "content/common/gpu/gles2_texture_to_egl_image_translator.h" |
| 10 #include "content/common/gpu/gpu_channel.h" | 10 #include "content/common/gpu/gpu_channel.h" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 height_(-1), | 48 height_(-1), |
| 49 input_buffer_count_(0), | 49 input_buffer_count_(0), |
| 50 input_buffer_size_(0), | 50 input_buffer_size_(0), |
| 51 input_port_(0), | 51 input_port_(0), |
| 52 input_buffers_at_component_(0), | 52 input_buffers_at_component_(0), |
| 53 output_buffer_count_(0), | 53 output_buffer_count_(0), |
| 54 output_buffer_size_(0), | 54 output_buffer_size_(0), |
| 55 output_port_(0), | 55 output_port_(0), |
| 56 output_buffers_at_component_(0), | 56 output_buffers_at_component_(0), |
| 57 uses_egl_image_(false), | 57 uses_egl_image_(false), |
| 58 client_(client) { | 58 client_(client), |
| 59 on_port_disable_event_func_(NULL), |
| 60 on_port_enable_event_func_(NULL), |
| 61 on_state_event_func_(NULL), |
| 62 on_flush_event_func_(NULL), |
| 63 on_buffer_flag_event_func_(NULL) { |
| 59 if (!AreOMXFunctionPointersInitialized()) { | 64 if (!AreOMXFunctionPointersInitialized()) { |
| 60 LOG(ERROR) << "Failed to load openmax library"; | 65 LOG(ERROR) << "Failed to load openmax library"; |
| 61 return; | 66 return; |
| 62 } | 67 } |
| 63 OMX_ERRORTYPE result = omx_init(); | 68 OMX_ERRORTYPE result = omx_init(); |
| 64 if (result != OMX_ErrorNone) | 69 if (result != OMX_ErrorNone) |
| 65 LOG(ERROR) << "Failed to init OpenMAX core"; | 70 LOG(ERROR) << "Failed to init OpenMAX core"; |
| 66 } | 71 } |
| 67 | 72 |
| 68 OmxVideoDecodeAccelerator::~OmxVideoDecodeAccelerator() { | 73 OmxVideoDecodeAccelerator::~OmxVideoDecodeAccelerator() { |
| 69 DCHECK(free_input_buffers_.empty()); | 74 DCHECK(free_input_buffers_.empty()); |
| 70 DCHECK_EQ(0, input_buffers_at_component_); | 75 DCHECK_EQ(0, input_buffers_at_component_); |
| 71 DCHECK_EQ(0, output_buffers_at_component_); | 76 DCHECK_EQ(0, output_buffers_at_component_); |
| 72 DCHECK(output_pictures_.empty()); | 77 DCHECK(output_pictures_.empty()); |
| 73 } | 78 } |
| 74 | 79 |
| 80 void OmxVideoDecodeAccelerator::SetEglState( |
| 81 EGLDisplay egl_display, EGLContext egl_context) { |
| 82 egl_display_ = egl_display; |
| 83 egl_context_ = egl_context; |
| 84 } |
| 85 |
| 75 void OmxVideoDecodeAccelerator::GetConfigs( | 86 void OmxVideoDecodeAccelerator::GetConfigs( |
| 76 const std::vector<uint32>& requested_configs, | 87 const std::vector<uint32>& requested_configs, |
| 77 std::vector<uint32>* matched_configs) { | 88 std::vector<uint32>* matched_configs) { |
| 78 // TODO(vhiremath@nvidia.com) use this properly | 89 // TODO(vhiremath@nvidia.com) use this properly |
| 79 NOTIMPLEMENTED(); | 90 NOTIMPLEMENTED(); |
| 80 } | 91 } |
| 81 | 92 |
| 82 // This is to initialize the OMX data structures to default values. | 93 // This is to initialize the OMX data structures to default values. |
| 83 template <typename T> | 94 template <typename T> |
| 84 static void InitParam(const OmxVideoDecodeAccelerator& dec, T* param) { | 95 static void InitParam(const OmxVideoDecodeAccelerator& dec, T* param) { |
| 85 memset(param, 0, sizeof(T)); | 96 memset(param, 0, sizeof(T)); |
| 86 param->nVersion.nVersion = 0x00000101; | 97 param->nVersion.nVersion = 0x00000101; |
| 87 param->nSize = sizeof(T); | 98 param->nSize = sizeof(T); |
| 88 } | 99 } |
| 89 | 100 |
| 90 bool OmxVideoDecodeAccelerator::Initialize(const std::vector<uint32>& config) { | 101 bool OmxVideoDecodeAccelerator::Initialize(const std::vector<uint32>& config) { |
| 91 // TODO(vhiremath@nvidia.com) get these actual values from config | 102 // TODO(vhiremath@nvidia.com) get these actual values from config |
| 92 // Assume qvga for now | 103 // Assume qvga for now |
| 93 width_ = 320; | 104 width_ = 320; |
| 94 height_ = 240; | 105 height_ = 240; |
| 95 | 106 |
| 96 client_state_ = OMX_StateLoaded; | 107 client_state_ = OMX_StateLoaded; |
| 97 if (!CreateComponent()) { | 108 if (!CreateComponent()) { |
| 98 StopOnError(); | 109 StopOnError(); |
| 99 return false; | 110 return false; |
| 100 } | 111 } |
| 112 |
| 101 // Transition component to Idle state | 113 // Transition component to Idle state |
| 114 DCHECK(!on_state_event_func_); |
| 102 on_state_event_func_ = | 115 on_state_event_func_ = |
| 103 &OmxVideoDecodeAccelerator::OnStateChangeLoadedToIdle; | 116 &OmxVideoDecodeAccelerator::OnStateChangeLoadedToIdle; |
| 104 if (!TransitionToState(OMX_StateIdle)) | 117 if (!TransitionToState(OMX_StateIdle)) { |
| 118 LOG(ERROR) << "TransitionToState(OMX_StateIdle) error"; |
| 119 StopOnError(); |
| 105 return false; | 120 return false; |
| 121 } |
| 106 | 122 |
| 107 if (!AllocateInputBuffers()) { | 123 if (!AllocateInputBuffers()) { |
| 108 LOG(ERROR) << "OMX_AllocateBuffer() Input buffer error"; | 124 LOG(ERROR) << "OMX_AllocateBuffer() Input buffer error"; |
| 109 StopOnError(); | 125 StopOnError(); |
| 110 return false; | 126 return false; |
| 111 } | 127 } |
| 112 | 128 |
| 113 // After AllocateInputBuffers ideally this should be AllocateOutputBuffers. | 129 // After AllocateInputBuffers ideally this should be AllocateOutputBuffers. |
| 114 // Since in this case app provides the output buffers, | 130 // Since in this case app provides the output buffers, |
| 115 // we query this through ProvidePictureBuffers. | 131 // we query this through ProvidePictureBuffers. |
| 116 // This is call to ppapi to provide the output buffers initially. | 132 // This is call to ppapi to provide the output buffers initially. |
| 117 // ProvidePictureBuffers will provide | 133 // ProvidePictureBuffers will provide |
| 118 // - SharedMemHandle in case of decoding to system memory. | 134 // - SharedMemHandle in case of decoding to system memory. |
| 119 // - Textures in case of decoding to egl-images. | 135 // - Textures in case of decoding to egl-images. |
| 120 | 136 |
| 121 // Output buffers will be eventually handed to us via | 137 // Output buffers will be eventually handed to us via |
| 122 // Assign{GLES,Sysmem}Buffers(). | 138 // Assign{GLES,Sysmem}Buffers(). |
| 123 output_buffer_count_ = kNumPictureBuffers; | 139 output_buffer_count_ = kNumPictureBuffers; |
| 124 client_->ProvidePictureBuffers( | 140 message_loop_->PostTask( |
| 125 output_buffer_count_, gfx::Size(width_, height_), | 141 FROM_HERE, |
| 126 PICTUREBUFFER_MEMORYTYPE_GL_TEXTURE); | 142 base::Bind(&Client::ProvidePictureBuffers, base::Unretained(client_), |
| 143 output_buffer_count_, gfx::Size(width_, height_), |
| 144 PICTUREBUFFER_MEMORYTYPE_GL_TEXTURE)); |
| 127 // TODO(fischman): we always ask for GLES buffers above. So why maintain the | 145 // TODO(fischman): we always ask for GLES buffers above. So why maintain the |
| 128 // !uses_egl_image_ path in this class at all? Theoretically it could be | 146 // !uses_egl_image_ path in this class at all? Theoretically it could be |
| 129 // useful for testing, but today there's no such testing. Consider ripping it | 147 // useful for testing, but today there's no such testing. Consider ripping it |
| 130 // out of this class and replacing AssignSysmemBuffers() with | 148 // out of this class and replacing AssignSysmemBuffers() with |
| 131 // NOTIMPLEMENTED(). | 149 // NOTIMPLEMENTED(). |
| 150 |
| 132 return true; | 151 return true; |
| 133 } | 152 } |
| 134 | 153 |
| 135 bool OmxVideoDecodeAccelerator::CreateComponent() { | 154 bool OmxVideoDecodeAccelerator::CreateComponent() { |
| 136 OMX_CALLBACKTYPE omx_accelerator_callbacks = { | 155 OMX_CALLBACKTYPE omx_accelerator_callbacks = { |
| 137 &OmxVideoDecodeAccelerator::EventHandler, | 156 &OmxVideoDecodeAccelerator::EventHandler, |
| 138 &OmxVideoDecodeAccelerator::EmptyBufferCallback, | 157 &OmxVideoDecodeAccelerator::EmptyBufferCallback, |
| 139 &OmxVideoDecodeAccelerator::FillBufferCallback | 158 &OmxVideoDecodeAccelerator::FillBufferCallback |
| 140 }; | 159 }; |
| 141 OMX_ERRORTYPE result = OMX_ErrorNone; | 160 OMX_ERRORTYPE result = OMX_ErrorNone; |
| 142 | 161 |
| 143 // 1. Set the role and get all components of this role. | 162 // 1. Set the role and get all components of this role. |
| 144 // TODO(vhiremath@nvidia.com) Get this role_name from the configs | 163 // TODO(vhiremath@nvidia.com) Get this role_name from the configs |
| 145 // For now hard coding to avc. | 164 // For now hard coding to avc. |
| 146 const char* role_name = "video_decoder.avc"; | 165 const char* role_name = "video_decoder.avc"; |
| 147 OMX_U32 num_roles = 0; | 166 OMX_U32 num_roles = 0; |
| 148 // Get all the components with this role. | 167 // Get all the components with this role. |
| 149 result = (*omx_get_components_of_role)( | 168 result = (*omx_get_components_of_role)( |
| 150 const_cast<OMX_STRING>(role_name), &num_roles, 0); | 169 const_cast<OMX_STRING>(role_name), &num_roles, 0); |
| 151 if (result != OMX_ErrorNone || num_roles == 0) { | 170 if (result != OMX_ErrorNone || num_roles == 0) { |
| 152 LOG(ERROR) << "Unsupported Role: " << role_name; | 171 LOG(ERROR) << "Unsupported Role: " << role_name << ", " << result; |
| 153 StopOnError(); | 172 StopOnError(); |
| 154 return false; | 173 return false; |
| 155 } | 174 } |
| 156 | 175 |
| 157 // We haven't seen HW that needs more yet, | 176 // We haven't seen HW that needs more yet, |
| 158 // but there is no reason not to raise. | 177 // but there is no reason not to raise. |
| 159 const OMX_U32 kMaxRolePerComponent = 3; | 178 const OMX_U32 kMaxRolePerComponent = 3; |
| 160 CHECK_LT(num_roles, kMaxRolePerComponent); | 179 CHECK_LT(num_roles, kMaxRolePerComponent); |
| 161 | 180 |
| 162 scoped_array<scoped_array<OMX_U8> > component_names( | 181 scoped_array<scoped_array<OMX_U8> > component_names( |
| (...skipping 27 matching lines...) Expand all Loading... |
| 190 return false; | 209 return false; |
| 191 } | 210 } |
| 192 | 211 |
| 193 // 4. Get the port information. This will obtain information about the | 212 // 4. Get the port information. This will obtain information about the |
| 194 // number of ports and index of the first port. | 213 // number of ports and index of the first port. |
| 195 OMX_PORT_PARAM_TYPE port_param; | 214 OMX_PORT_PARAM_TYPE port_param; |
| 196 InitParam(*this, &port_param); | 215 InitParam(*this, &port_param); |
| 197 result = OMX_GetParameter(component_handle_, OMX_IndexParamVideoInit, | 216 result = OMX_GetParameter(component_handle_, OMX_IndexParamVideoInit, |
| 198 &port_param); | 217 &port_param); |
| 199 if ((result != OMX_ErrorNone) || (port_param.nPorts != 2)) { | 218 if ((result != OMX_ErrorNone) || (port_param.nPorts != 2)) { |
| 200 LOG(ERROR) << "Failed to get Port Param"; | 219 LOG(ERROR) << "Failed to get Port Param: " |
| 220 << result << ", " << port_param.nPorts; |
| 201 StopOnError(); | 221 StopOnError(); |
| 202 return false; | 222 return false; |
| 203 } | 223 } |
| 204 input_port_ = port_param.nStartPortNumber; | 224 input_port_ = port_param.nStartPortNumber; |
| 205 output_port_ = input_port_ + 1; | 225 output_port_ = input_port_ + 1; |
| 206 // 5. Set role for the component because components can have multiple roles. | 226 // 5. Set role for the component because components can have multiple roles. |
| 207 OMX_PARAM_COMPONENTROLETYPE role_type; | 227 OMX_PARAM_COMPONENTROLETYPE role_type; |
| 208 InitParam(*this, &role_type); | 228 InitParam(*this, &role_type); |
| 209 base::strlcpy(reinterpret_cast<char*>(role_type.cRole), | 229 base::strlcpy(reinterpret_cast<char*>(role_type.cRole), |
| 210 role_name, | 230 role_name, |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 // not make any assumptions about its completion. | 306 // not make any assumptions about its completion. |
| 287 omx_buff_ids_.insert(std::make_pair( | 307 omx_buff_ids_.insert(std::make_pair( |
| 288 omx_buffer, std::make_pair(shm.release(), bitstream_buffer.id()))); | 308 omx_buffer, std::make_pair(shm.release(), bitstream_buffer.id()))); |
| 289 return true; | 309 return true; |
| 290 } | 310 } |
| 291 | 311 |
| 292 // NOTE: this is only partially-implemented as never unsets uses_egl_image_ once | 312 // NOTE: this is only partially-implemented as never unsets uses_egl_image_ once |
| 293 // set. | 313 // set. |
| 294 void OmxVideoDecodeAccelerator::AssignGLESBuffers( | 314 void OmxVideoDecodeAccelerator::AssignGLESBuffers( |
| 295 const std::vector<media::GLESBuffer>& buffers) { | 315 const std::vector<media::GLESBuffer>& buffers) { |
| 316 CHECK_EQ(message_loop_, MessageLoop::current()); |
| 296 uses_egl_image_ = true; | 317 uses_egl_image_ = true; |
| 297 std::vector<media::BaseBuffer*> base_buffers(buffers.size()); | 318 std::vector<media::BaseBuffer*> base_buffers(buffers.size()); |
| 298 for (size_t i = 0; i < buffers.size(); ++i) | 319 for (size_t i = 0; i < buffers.size(); ++i) |
| 299 base_buffers[i] = new media::GLESBuffer(buffers[i]); | 320 base_buffers[i] = new media::GLESBuffer(buffers[i]); |
| 300 AssignBuffersHelper(base_buffers); | 321 AssignBuffersHelper(base_buffers); |
| 301 } | 322 } |
| 302 | 323 |
| 303 void OmxVideoDecodeAccelerator::AssignSysmemBuffers( | 324 void OmxVideoDecodeAccelerator::AssignSysmemBuffers( |
| 304 const std::vector<media::SysmemBuffer>& buffers) { | 325 const std::vector<media::SysmemBuffer>& buffers) { |
| 326 CHECK_EQ(message_loop_, MessageLoop::current()); |
| 305 DCHECK(!uses_egl_image_); | 327 DCHECK(!uses_egl_image_); |
| 306 std::vector<media::BaseBuffer*> base_buffers(buffers.size()); | 328 std::vector<media::BaseBuffer*> base_buffers(buffers.size()); |
| 307 for (size_t i = 0; i < buffers.size(); ++i) | 329 for (size_t i = 0; i < buffers.size(); ++i) |
| 308 base_buffers[i] = new media::SysmemBuffer(buffers[i]); | 330 base_buffers[i] = new media::SysmemBuffer(buffers[i]); |
| 309 AssignBuffersHelper(base_buffers); | 331 AssignBuffersHelper(base_buffers); |
| 310 } | 332 } |
| 311 | 333 |
| 312 void OmxVideoDecodeAccelerator::AssignBuffersHelper( | 334 void OmxVideoDecodeAccelerator::AssignBuffersHelper( |
| 313 const std::vector<media::BaseBuffer*>& buffers) { | 335 const std::vector<media::BaseBuffer*>& buffers) { |
| 314 assigned_picture_buffers_.insert( | 336 assigned_picture_buffers_.insert( |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 return; | 371 return; |
| 350 } | 372 } |
| 351 } else { | 373 } else { |
| 352 output_buffer_count_ = port_format.nBufferCountActual; | 374 output_buffer_count_ = port_format.nBufferCountActual; |
| 353 } | 375 } |
| 354 output_buffer_size_ = port_format.nBufferSize; | 376 output_buffer_size_ = port_format.nBufferSize; |
| 355 | 377 |
| 356 if (!AllocateOutputBuffers()) { | 378 if (!AllocateOutputBuffers()) { |
| 357 LOG(ERROR) << "OMX_AllocateBuffer() Output buffer error"; | 379 LOG(ERROR) << "OMX_AllocateBuffer() Output buffer error"; |
| 358 StopOnError(); | 380 StopOnError(); |
| 381 return; |
| 359 } | 382 } |
| 360 } | 383 } |
| 361 | 384 |
| 362 void OmxVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) { | 385 void OmxVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) { |
| 363 // TODO(vhiremath@nvidia.com) Avoid leaking of the picture buffer. | 386 // TODO(vhiremath@nvidia.com) Avoid leaking of the picture buffer. |
| 364 if (!CanFillBuffer()) | 387 if (!CanFillBuffer()) |
| 365 return; | 388 return; |
| 366 | 389 |
| 367 for (int i = 0; i < output_buffer_count_; ++i) { | 390 for (int i = 0; i < output_buffer_count_; ++i) { |
| 368 if (picture_buffer_id != assigned_picture_buffers_[i]->id()) | 391 if (picture_buffer_id != assigned_picture_buffers_[i]->id()) |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 OMX_GetState(component_handle_, &il_state); | 427 OMX_GetState(component_handle_, &il_state); |
| 405 DCHECK_EQ(il_state, OMX_StateExecuting); | 428 DCHECK_EQ(il_state, OMX_StateExecuting); |
| 406 if (il_state != OMX_StateExecuting) { | 429 if (il_state != OMX_StateExecuting) { |
| 407 client_->NotifyFlushDone(); | 430 client_->NotifyFlushDone(); |
| 408 return false; | 431 return false; |
| 409 } | 432 } |
| 410 on_buffer_flag_event_func_ = &OmxVideoDecodeAccelerator::FlushBegin; | 433 on_buffer_flag_event_func_ = &OmxVideoDecodeAccelerator::FlushBegin; |
| 411 | 434 |
| 412 OMX_BUFFERHEADERTYPE* omx_buffer = free_input_buffers_.front(); | 435 OMX_BUFFERHEADERTYPE* omx_buffer = free_input_buffers_.front(); |
| 413 free_input_buffers_.pop(); | 436 free_input_buffers_.pop(); |
| 437 |
| 414 omx_buffer->nFilledLen = 0; | 438 omx_buffer->nFilledLen = 0; |
| 415 omx_buffer->nAllocLen = omx_buffer->nFilledLen; | 439 omx_buffer->nAllocLen = omx_buffer->nFilledLen; |
| 416 omx_buffer->nFlags |= OMX_BUFFERFLAG_EOS; | 440 omx_buffer->nFlags |= OMX_BUFFERFLAG_EOS; |
| 417 omx_buffer->nTimeStamp = 0; | 441 omx_buffer->nTimeStamp = 0; |
| 418 // Give this buffer to OMX. | 442 // Give this buffer to OMX. |
| 419 OMX_ERRORTYPE result = OMX_ErrorNone; | 443 OMX_ERRORTYPE result = OMX_ErrorNone; |
| 420 result = OMX_EmptyThisBuffer(component_handle_, omx_buffer); | 444 result = OMX_EmptyThisBuffer(component_handle_, omx_buffer); |
| 421 if (result != OMX_ErrorNone) { | 445 if (result != OMX_ErrorNone) { |
| 422 LOG(ERROR) << "OMX_EmptyThisBuffer() failed with result " << result; | 446 LOG(ERROR) << "OMX_EmptyThisBuffer() failed with result " << result; |
| 423 StopOnError(); | 447 StopOnError(); |
| 424 return false; | 448 return false; |
| 425 } | 449 } |
| 426 input_buffers_at_component_++; | 450 input_buffers_at_component_++; |
| 427 return true; | 451 return true; |
| 428 } | 452 } |
| 429 | 453 |
| 430 void OmxVideoDecodeAccelerator::FlushBegin() { | 454 void OmxVideoDecodeAccelerator::FlushBegin() { |
| 431 VLOG(1) << "Starting actual flush for EOS"; | 455 VLOG(1) << "Starting actual flush for EOS"; |
| 456 DCHECK(!on_state_event_func_); |
| 432 on_state_event_func_ = &OmxVideoDecodeAccelerator::PauseFromExecuting; | 457 on_state_event_func_ = &OmxVideoDecodeAccelerator::PauseFromExecuting; |
| 433 TransitionToState(OMX_StatePause); | 458 TransitionToState(OMX_StatePause); |
| 434 } | 459 } |
| 435 | 460 |
| 436 void OmxVideoDecodeAccelerator::PauseFromExecuting(OMX_STATETYPE ignored) { | 461 void OmxVideoDecodeAccelerator::PauseFromExecuting(OMX_STATETYPE ignored) { |
| 437 on_state_event_func_ = NULL; | 462 on_state_event_func_ = NULL; |
| 438 FlushIOPorts(); | 463 FlushIOPorts(); |
| 439 } | 464 } |
| 440 | 465 |
| 441 void OmxVideoDecodeAccelerator::FlushIOPorts() { | 466 void OmxVideoDecodeAccelerator::FlushIOPorts() { |
| 442 // TODO(vhiremath@nvidia.com) review again for trick modes. | 467 // TODO(vhiremath@nvidia.com) review again for trick modes. |
| 443 VLOG(1) << "FlushIOPorts"; | 468 VLOG(1) << "FlushIOPorts"; |
| 444 | 469 |
| 445 // Flush input port first. | 470 // Flush input port first. |
| 446 on_flush_event_func_ = &OmxVideoDecodeAccelerator::PortFlushDone; | 471 DCHECK(!on_flush_event_func_); |
| 472 on_flush_event_func_ = &OmxVideoDecodeAccelerator::InputPortFlushDone; |
| 447 OMX_ERRORTYPE result; | 473 OMX_ERRORTYPE result; |
| 448 result = OMX_SendCommand(component_handle_, | 474 result = OMX_SendCommand(component_handle_, |
| 449 OMX_CommandFlush, | 475 OMX_CommandFlush, |
| 450 input_port_, 0); | 476 input_port_, 0); |
| 451 if (result != OMX_ErrorNone) { | 477 if (result != OMX_ErrorNone) { |
| 452 LOG(ERROR) << "OMX_SendCommand(OMX_CommandFlush) failed"; | 478 LOG(ERROR) << "OMX_SendCommand(OMX_CommandFlush) failed"; |
| 453 StopOnError(); | 479 StopOnError(); |
| 454 return; | 480 return; |
| 455 } | 481 } |
| 456 } | 482 } |
| 457 | 483 |
| 458 void OmxVideoDecodeAccelerator::PortFlushDone(int port) { | 484 void OmxVideoDecodeAccelerator::InputPortFlushDone(int port) { |
| 459 DCHECK_NE(port, static_cast<int>(OMX_ALL)); | 485 DCHECK_EQ(port, input_port_); |
| 460 | 486 VLOG(1) << "Input Port had been flushed"; |
| 461 if (port == input_port_) { | 487 DCHECK_EQ(input_buffers_at_component_, 0); |
| 462 VLOG(1) << "Input Port had been flushed"; | 488 // Flush output port next. |
| 463 DCHECK_EQ(input_buffers_at_component_, 0); | 489 DCHECK(!on_flush_event_func_); |
| 464 // Flush output port next. | 490 on_flush_event_func_ = &OmxVideoDecodeAccelerator::OutputPortFlushDone; |
| 465 OMX_ERRORTYPE result; | 491 if (OMX_ErrorNone != |
| 466 result = OMX_SendCommand(component_handle_, | 492 OMX_SendCommand(component_handle_, |
| 467 OMX_CommandFlush, | 493 OMX_CommandFlush, |
| 468 output_port_, 0); | 494 output_port_, 0)) { |
| 469 if (result != OMX_ErrorNone) { | 495 LOG(ERROR) << "OMX_SendCommand(OMX_CommandFlush) failed"; |
| 470 LOG(ERROR) << "OMX_SendCommand(OMX_CommandFlush) failed"; | 496 StopOnError(); |
| 471 StopOnError(); | |
| 472 return; | |
| 473 } | |
| 474 return; | 497 return; |
| 475 } | 498 } |
| 499 } |
| 476 | 500 |
| 477 if (port == output_port_) { | 501 void OmxVideoDecodeAccelerator::OutputPortFlushDone(int port) { |
| 478 VLOG(1) << "Output Port had been flushed"; | 502 DCHECK_EQ(port, output_port_); |
| 479 DCHECK_EQ(output_buffers_at_component_, 0); | |
| 480 } | |
| 481 | 503 |
| 504 VLOG(1) << "Output Port had been flushed"; |
| 505 DCHECK_EQ(output_buffers_at_component_, 0); |
| 482 client_state_ = OMX_StatePause; | 506 client_state_ = OMX_StatePause; |
| 483 // So Finally call OnPortCommandFlush which should | 507 // So Finally call OnPortCommandFlush which should |
| 484 // internally call DismissPictureBuffer(); | 508 // internally call DismissPictureBuffer(); |
| 485 OnPortCommandFlush(OMX_StateExecuting); | 509 OnPortCommandFlush(OMX_StateExecuting); |
| 486 } | 510 } |
| 487 | 511 |
| 488 bool OmxVideoDecodeAccelerator::Abort() { | 512 bool OmxVideoDecodeAccelerator::Abort() { |
| 513 CHECK_EQ(message_loop_, MessageLoop::current()); |
| 489 // TODO(vhiremath@nvidia.com) | 514 // TODO(vhiremath@nvidia.com) |
| 490 // Need more thinking on this to handle w.r.t OMX. | 515 // Need more thinking on this to handle w.r.t OMX. |
| 491 // There is no explicit UnInitialize call for this. | 516 // There is no explicit UnInitialize call for this. |
| 492 // Also review again for trick modes. | 517 // Also review again for trick modes. |
| 493 client_->NotifyAbortDone(); | 518 client_->NotifyAbortDone(); |
| 494 return true; | 519 return true; |
| 495 } | 520 } |
| 496 | 521 |
| 497 // Event callback during initialization to handle DoneStateSet to idle | 522 // Event callback during initialization to handle DoneStateSet to idle |
| 498 void OmxVideoDecodeAccelerator::OnStateChangeLoadedToIdle(OMX_STATETYPE state) { | 523 void OmxVideoDecodeAccelerator::OnStateChangeLoadedToIdle(OMX_STATETYPE state) { |
| 524 CHECK_EQ(message_loop_, MessageLoop::current()); |
| 525 DCHECK(!on_state_event_func_); |
| 499 DCHECK_EQ(client_state_, OMX_StateLoaded); | 526 DCHECK_EQ(client_state_, OMX_StateLoaded); |
| 500 DCHECK_EQ(OMX_StateIdle, state); | 527 DCHECK_EQ(OMX_StateIdle, state); |
| 528 |
| 501 VLOG(1) << "OMX video decode engine is in Idle"; | 529 VLOG(1) << "OMX video decode engine is in Idle"; |
| 502 | 530 |
| 503 on_state_event_func_ = | 531 on_state_event_func_ = |
| 504 &OmxVideoDecodeAccelerator::OnStateChangeIdleToExecuting; | 532 &OmxVideoDecodeAccelerator::OnStateChangeIdleToExecuting; |
| 505 if (!TransitionToState(OMX_StateExecuting)) | 533 if (!TransitionToState(OMX_StateExecuting)) |
| 506 return; | 534 return; |
| 507 } | 535 } |
| 508 | 536 |
| 509 // Event callback during initialization to handle DoneStateSet to executing | 537 // Event callback during initialization to handle DoneStateSet to executing |
| 510 void OmxVideoDecodeAccelerator::OnStateChangeIdleToExecuting( | 538 void OmxVideoDecodeAccelerator::OnStateChangeIdleToExecuting( |
| 511 OMX_STATETYPE state) { | 539 OMX_STATETYPE state) { |
| 540 CHECK_EQ(message_loop_, MessageLoop::current()); |
| 512 DCHECK_EQ(OMX_StateExecuting, state); | 541 DCHECK_EQ(OMX_StateExecuting, state); |
| 542 DCHECK(!on_state_event_func_); |
| 513 VLOG(1) << "OMX video decode engine is in Executing"; | 543 VLOG(1) << "OMX video decode engine is in Executing"; |
| 514 | 544 |
| 515 client_state_ = OMX_StateExecuting; | 545 client_state_ = OMX_StateExecuting; |
| 516 on_state_event_func_ = NULL; | |
| 517 // This will kickoff the actual decoding | 546 // This will kickoff the actual decoding |
| 518 InitialFillBuffer(); | 547 InitialFillBuffer(); |
| 548 |
| 549 client_->NotifyInitializeDone(); |
| 519 } | 550 } |
| 520 | 551 |
| 521 // Send state transition command to component. | 552 // Send state transition command to component. |
| 522 bool OmxVideoDecodeAccelerator::TransitionToState(OMX_STATETYPE new_state) { | 553 bool OmxVideoDecodeAccelerator::TransitionToState(OMX_STATETYPE new_state) { |
| 523 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_, | 554 DCHECK(on_state_event_func_); |
| 524 OMX_CommandStateSet, | 555 OMX_ERRORTYPE result = OMX_SendCommand( |
| 525 new_state, 0); | 556 component_handle_, OMX_CommandStateSet, new_state, 0); |
| 526 if (result != OMX_ErrorNone) { | 557 if (result != OMX_ErrorNone) { |
| 527 LOG(ERROR) << "SendCommand(OMX_CommandStateSet) failed"; | 558 LOG(ERROR) << "SendCommand(OMX_CommandStateSet) failed"; |
| 528 StopOnError(); | 559 StopOnError(); |
| 529 return false; | 560 return false; |
| 530 } | 561 } |
| 531 return true; | 562 return true; |
| 532 } | 563 } |
| 533 | 564 |
| 534 void OmxVideoDecodeAccelerator::OnPortCommandFlush(OMX_STATETYPE state) { | 565 void OmxVideoDecodeAccelerator::OnPortCommandFlush(OMX_STATETYPE state) { |
| 535 DCHECK_EQ(state, OMX_StateExecuting); | 566 DCHECK_EQ(state, OMX_StateExecuting); |
| 567 CHECK_EQ(message_loop_, MessageLoop::current()); |
| 536 | 568 |
| 537 VLOG(1) << "Deinit from Executing"; | 569 VLOG(1) << "Deinit from Executing"; |
| 570 DCHECK(!on_state_event_func_); |
| 538 on_state_event_func_ = | 571 on_state_event_func_ = |
| 539 &OmxVideoDecodeAccelerator::OnStateChangeExecutingToIdle; | 572 &OmxVideoDecodeAccelerator::OnStateChangeExecutingToIdle; |
| 540 TransitionToState(OMX_StateIdle); | 573 TransitionToState(OMX_StateIdle); |
| 541 for (int i = 0; i < output_buffer_count_; ++i) { | 574 for (int i = 0; i < output_buffer_count_; ++i) { |
| 542 OutputPicture output_picture = output_pictures_[i]; | 575 OutputPicture output_picture = output_pictures_[i]; |
| 543 client_->DismissPictureBuffer(output_picture.first); | 576 client_->DismissPictureBuffer(output_picture.first); |
| 544 } | 577 } |
| 545 STLDeleteElements(&assigned_picture_buffers_); | 578 STLDeleteElements(&assigned_picture_buffers_); |
| 546 } | 579 } |
| 547 | 580 |
| 548 void OmxVideoDecodeAccelerator::OnStateChangeExecutingToIdle( | 581 void OmxVideoDecodeAccelerator::OnStateChangeExecutingToIdle( |
| 549 OMX_STATETYPE state) { | 582 OMX_STATETYPE state) { |
| 550 DCHECK_EQ(state, OMX_StateIdle); | 583 DCHECK_EQ(state, OMX_StateIdle); |
| 584 DCHECK(!on_state_event_func_); |
| 551 | 585 |
| 552 VLOG(1) << "Deinit from Idle"; | 586 VLOG(1) << "Deinit from Idle"; |
| 553 on_state_event_func_ = | 587 on_state_event_func_ = |
| 554 &OmxVideoDecodeAccelerator::OnStateChangeIdleToLoaded; | 588 &OmxVideoDecodeAccelerator::OnStateChangeIdleToLoaded; |
| 555 TransitionToState(OMX_StateLoaded); | 589 TransitionToState(OMX_StateLoaded); |
| 556 | 590 |
| 557 if (!input_buffers_at_component_) | 591 if (!input_buffers_at_component_) |
| 558 FreeInputBuffers(); | 592 FreeInputBuffers(); |
| 559 | 593 |
| 560 if (!output_buffers_at_component_) | 594 if (!output_buffers_at_component_) |
| 561 FreeOutputBuffers(); | 595 FreeOutputBuffers(); |
| 562 } | 596 } |
| 563 | 597 |
| 564 void OmxVideoDecodeAccelerator::OnStateChangeIdleToLoaded(OMX_STATETYPE state) { | 598 void OmxVideoDecodeAccelerator::OnStateChangeIdleToLoaded(OMX_STATETYPE state) { |
| 565 DCHECK_EQ(state, OMX_StateLoaded); | 599 DCHECK_EQ(state, OMX_StateLoaded); |
| 600 CHECK_EQ(message_loop_, MessageLoop::current()); |
| 601 DCHECK(!on_state_event_func_); |
| 566 | 602 |
| 567 VLOG(1) << "Idle to Loaded"; | 603 VLOG(1) << "Idle to Loaded"; |
| 568 | 604 |
| 569 if (component_handle_) { | 605 if (component_handle_) { |
| 570 OMX_ERRORTYPE result = (*omx_free_handle)(component_handle_); | 606 OMX_ERRORTYPE result = (*omx_free_handle)(component_handle_); |
| 571 if (result != OMX_ErrorNone) | 607 if (result != OMX_ErrorNone) |
| 572 LOG(ERROR) << "OMX_FreeHandle() error. Error code: " << result; | 608 LOG(ERROR) << "OMX_FreeHandle() error. Error code: " << result; |
| 573 component_handle_ = NULL; | 609 component_handle_ = NULL; |
| 574 } | 610 } |
| 575 client_state_ = OMX_StateLoaded; | 611 client_state_ = OMX_StateLoaded; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 592 case OMX_StateLoaded: | 628 case OMX_StateLoaded: |
| 593 OnStateChangeIdleToLoaded(OMX_StateLoaded); | 629 OnStateChangeIdleToLoaded(OMX_StateLoaded); |
| 594 return; | 630 return; |
| 595 default: | 631 default: |
| 596 // LOG unexpected state or just ignore? | 632 // LOG unexpected state or just ignore? |
| 597 return; | 633 return; |
| 598 } | 634 } |
| 599 } | 635 } |
| 600 | 636 |
| 601 bool OmxVideoDecodeAccelerator::AllocateInputBuffers() { | 637 bool OmxVideoDecodeAccelerator::AllocateInputBuffers() { |
| 602 scoped_array<uint8> data(new uint8[input_buffer_size_]); | |
| 603 | |
| 604 for (int i = 0; i < input_buffer_count_; ++i) { | 638 for (int i = 0; i < input_buffer_count_; ++i) { |
| 605 OMX_BUFFERHEADERTYPE* buffer; | 639 OMX_BUFFERHEADERTYPE* buffer; |
| 606 OMX_ERRORTYPE result = | 640 OMX_ERRORTYPE result = |
| 607 OMX_UseBuffer(component_handle_, &buffer, input_port_, | 641 OMX_AllocateBuffer(component_handle_, &buffer, input_port_, |
| 608 this, input_buffer_size_, data.get()); | 642 this, input_buffer_size_); |
| 609 if (result != OMX_ErrorNone) | 643 if (result != OMX_ErrorNone) |
| 610 return false; | 644 return false; |
| 611 buffer->nInputPortIndex = input_port_; | 645 buffer->nInputPortIndex = input_port_; |
| 612 buffer->nOffset = 0; | 646 buffer->nOffset = 0; |
| 613 buffer->nFlags = 0; | 647 buffer->nFlags = 0; |
| 614 free_input_buffers_.push(buffer); | 648 free_input_buffers_.push(buffer); |
| 615 } | 649 } |
| 616 return true; | 650 return true; |
| 617 } | 651 } |
| 618 | 652 |
| 619 bool OmxVideoDecodeAccelerator::AllocateOutputBuffers() { | 653 bool OmxVideoDecodeAccelerator::AllocateOutputBuffers() { |
| 620 static Gles2TextureToEglImageTranslator* texture2eglImage_translator( | 654 CHECK_EQ(message_loop_, MessageLoop::current()); |
| 621 new Gles2TextureToEglImageTranslator(NULL, 0)); | 655 static Gles2TextureToEglImageTranslator texture2eglImage_translator; |
| 622 | 656 |
| 623 gfx::Size decoded_pixel_size(width_, height_); | 657 gfx::Size decoded_pixel_size(width_, height_); |
| 624 gfx::Size visible_pixel_size(width_, height_); | 658 gfx::Size visible_pixel_size(width_, height_); |
| 625 // TODO(fischman): remove garbage bitstream buffer id's below (42 and 24) when | 659 // TODO(fischman): remove garbage bitstream buffer id's below (42 and 24) when |
| 626 // the bitstream_buffer_id field is removed from Picture. | 660 // the bitstream_buffer_id field is removed from Picture. |
| 627 if (uses_egl_image_) { | 661 if (uses_egl_image_) { |
| 628 for (uint32 i = 0; i < assigned_picture_buffers_.size(); i++) { | 662 for (uint32 i = 0; i < assigned_picture_buffers_.size(); i++) { |
| 629 media::GLESBuffer* gles_buffer = | 663 media::GLESBuffer* gles_buffer = |
| 630 reinterpret_cast<media::GLESBuffer*>(assigned_picture_buffers_[i]); | 664 reinterpret_cast<media::GLESBuffer*>(assigned_picture_buffers_[i]); |
| 631 OMX_BUFFERHEADERTYPE* omx_buffer; | 665 OMX_BUFFERHEADERTYPE* omx_buffer; |
| 632 void* egl = texture2eglImage_translator->TranslateToEglImage( | 666 void* egl = texture2eglImage_translator.TranslateToEglImage( |
| 633 gles_buffer->texture_id()); | 667 egl_display_, egl_context_, gles_buffer->texture_id()); |
| 634 OMX_ERRORTYPE result = OMX_UseEGLImage( | 668 OMX_ERRORTYPE result = OMX_UseEGLImage( |
| 635 component_handle_, &omx_buffer, output_port_, gles_buffer, egl); | 669 component_handle_, &omx_buffer, output_port_, gles_buffer, egl); |
| 636 if (result != OMX_ErrorNone) { | 670 if (result != OMX_ErrorNone) { |
| 637 LOG(ERROR) << "OMX_UseEGLImage failed"; | 671 LOG(ERROR) << "OMX_UseEGLImage failed with: " << result; |
| 638 return false; | 672 return false; |
| 639 } | 673 } |
| 640 omx_buffer->pAppPrivate = | 674 omx_buffer->pAppPrivate = |
| 641 new media::Picture(gles_buffer->id(), | 675 new media::Picture(gles_buffer->id(), |
| 642 42 /* garbage bitstreambuffer id */, | 676 42 /* garbage bitstreambuffer id */, |
| 643 decoded_pixel_size, visible_pixel_size); | 677 decoded_pixel_size, visible_pixel_size); |
| 644 output_pictures_.push_back( | 678 output_pictures_.push_back( |
| 645 std::make_pair(assigned_picture_buffers_[i]->id(), omx_buffer)); | 679 std::make_pair(assigned_picture_buffers_[i]->id(), omx_buffer)); |
| 646 } | 680 } |
| 647 } else { | 681 } else { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 667 | 701 |
| 668 void OmxVideoDecodeAccelerator::FreeInputBuffers() { | 702 void OmxVideoDecodeAccelerator::FreeInputBuffers() { |
| 669 // Calls to OMX to free buffers. | 703 // Calls to OMX to free buffers. |
| 670 OMX_ERRORTYPE result; | 704 OMX_ERRORTYPE result; |
| 671 OMX_BUFFERHEADERTYPE* omx_buffer; | 705 OMX_BUFFERHEADERTYPE* omx_buffer; |
| 672 while (!free_input_buffers_.empty()) { | 706 while (!free_input_buffers_.empty()) { |
| 673 omx_buffer = free_input_buffers_.front(); | 707 omx_buffer = free_input_buffers_.front(); |
| 674 free_input_buffers_.pop(); | 708 free_input_buffers_.pop(); |
| 675 result = OMX_FreeBuffer(component_handle_, input_port_, omx_buffer); | 709 result = OMX_FreeBuffer(component_handle_, input_port_, omx_buffer); |
| 676 if (result != OMX_ErrorNone) { | 710 if (result != OMX_ErrorNone) { |
| 677 LOG(ERROR) << "SendCommand(OMX_CommandPortDisable) failed"; | 711 LOG(ERROR) << "OMX_CommandPortDisable failed with: " << result; |
| 678 StopOnError(); | 712 StopOnError(); |
| 679 return; | 713 return; |
| 680 } | 714 } |
| 681 } | 715 } |
| 682 } | 716 } |
| 683 | 717 |
| 684 void OmxVideoDecodeAccelerator::FreeOutputBuffers() { | 718 void OmxVideoDecodeAccelerator::FreeOutputBuffers() { |
| 685 // Calls to OMX to free buffers. | 719 // Calls to OMX to free buffers. |
| 686 OMX_ERRORTYPE result; | 720 OMX_ERRORTYPE result; |
| 687 for (size_t i = 0; i < output_pictures_.size(); ++i) { | 721 for (size_t i = 0; i < output_pictures_.size(); ++i) { |
| 688 OMX_BUFFERHEADERTYPE* omx_buffer = output_pictures_[i].second; | 722 OMX_BUFFERHEADERTYPE* omx_buffer = output_pictures_[i].second; |
| 689 CHECK(omx_buffer); | 723 CHECK(omx_buffer); |
| 690 delete reinterpret_cast<media::Picture*>(omx_buffer->pAppPrivate); | 724 delete reinterpret_cast<media::Picture*>(omx_buffer->pAppPrivate); |
| 691 result = OMX_FreeBuffer(component_handle_, output_port_, omx_buffer); | 725 result = OMX_FreeBuffer(component_handle_, output_port_, omx_buffer); |
| 692 if (result != OMX_ErrorNone) { | 726 if (result != OMX_ErrorNone) { |
| 693 LOG(ERROR) << "SendCommand(OMX_CommandPortDisable) failed"; | 727 LOG(ERROR) << "OMX_FreeBuffer failed with: " << result; |
| 694 StopOnError(); | 728 StopOnError(); |
| 695 return; | 729 return; |
| 696 } | 730 } |
| 697 } | 731 } |
| 698 output_pictures_.clear(); | 732 output_pictures_.clear(); |
| 699 } | 733 } |
| 700 | 734 |
| 701 void OmxVideoDecodeAccelerator::OnPortSettingsChangedRun( | 735 void OmxVideoDecodeAccelerator::OnPortSettingsChangedRun( |
| 702 int port, OMX_INDEXTYPE index) { | 736 int port, OMX_INDEXTYPE index) { |
| 703 // TODO(vhiremath@nvidia.com) visit again later | 737 // TODO(vhiremath@nvidia.com) visit again later |
| 704 // Port settings changes can be called during run time | 738 // Port settings changes can be called during run time |
| 705 // changes in the resolution of video playback. | 739 // changes in the resolution of video playback. |
| 706 // In this case, the component detects PortSettingsChanged | 740 // In this case, the component detects PortSettingsChanged |
| 707 // and sends the particular event to the IL-client. | 741 // and sends the particular event to the IL-client. |
| 708 // This needs to be handled in this method. | 742 // This needs to be handled in this method. |
| 709 return; | 743 return; |
| 710 } | 744 } |
| 711 | 745 |
| 712 void OmxVideoDecodeAccelerator::FillBufferDoneTask( | 746 void OmxVideoDecodeAccelerator::FillBufferDoneTask( |
| 713 OMX_BUFFERHEADERTYPE* buffer) { | 747 OMX_BUFFERHEADERTYPE* buffer) { |
| 748 CHECK_EQ(message_loop_, MessageLoop::current()); |
| 714 DCHECK_GT(output_buffers_at_component_, 0); | 749 DCHECK_GT(output_buffers_at_component_, 0); |
| 715 output_buffers_at_component_--; | 750 output_buffers_at_component_--; |
| 716 client_->PictureReady(*reinterpret_cast<media::Picture*>( | 751 client_->PictureReady(*reinterpret_cast<media::Picture*>( |
| 717 buffer->pAppPrivate)); | 752 buffer->pAppPrivate)); |
| 718 } | 753 } |
| 719 | 754 |
| 720 void OmxVideoDecodeAccelerator::EmptyBufferDoneTask( | 755 void OmxVideoDecodeAccelerator::EmptyBufferDoneTask( |
| 721 OMX_BUFFERHEADERTYPE* buffer) { | 756 OMX_BUFFERHEADERTYPE* buffer) { |
| 722 DCHECK_GT(input_buffers_at_component_, 0); | 757 DCHECK_GT(input_buffers_at_component_, 0); |
| 758 CHECK_EQ(message_loop_, MessageLoop::current()); |
| 723 free_input_buffers_.push(buffer); | 759 free_input_buffers_.push(buffer); |
| 724 input_buffers_at_component_--; | 760 input_buffers_at_component_--; |
| 725 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) | 761 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) |
| 726 return; | 762 return; |
| 763 |
| 727 // Retrieve the corresponding BitstreamBuffer's id and notify the client of | 764 // Retrieve the corresponding BitstreamBuffer's id and notify the client of |
| 728 // its completion. | 765 // its completion. |
| 729 OMXBufferIdMap::iterator it = omx_buff_ids_.find(buffer); | 766 OMXBufferIdMap::iterator it = omx_buff_ids_.find(buffer); |
| 730 if (it == omx_buff_ids_.end()) { | 767 if (it == omx_buff_ids_.end()) { |
| 731 LOG(ERROR) << "Unexpectedly failed to find a buffer id."; | 768 LOG(ERROR) << "Unexpectedly failed to find a buffer id."; |
| 732 StopOnError(); | 769 StopOnError(); |
| 733 return; | 770 return; |
| 734 } | 771 } |
| 735 delete it->second.first; | 772 delete it->second.first; |
| 736 client_->NotifyEndOfBitstreamBuffer(it->second.second); | 773 client_->NotifyEndOfBitstreamBuffer(it->second.second); |
| 737 omx_buff_ids_.erase(it); | 774 omx_buff_ids_.erase(it); |
| 738 } | 775 } |
| 739 | 776 |
| 740 void OmxVideoDecodeAccelerator::EventHandlerCompleteTask(OMX_EVENTTYPE event, | 777 void OmxVideoDecodeAccelerator::EventHandlerCompleteTask(OMX_EVENTTYPE event, |
| 741 OMX_U32 data1, | 778 OMX_U32 data1, |
| 742 OMX_U32 data2) { | 779 OMX_U32 data2) { |
| 780 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 743 switch (event) { | 781 switch (event) { |
| 744 case OMX_EventCmdComplete: { | 782 case OMX_EventCmdComplete: { |
| 745 // If the last command was successful, we have completed | 783 // If the last command was successful, we have completed |
| 746 // a state transition. So notify that we have done it | 784 // a state transition. So notify that we have done it |
| 747 // accordingly. | 785 // accordingly. |
| 748 OMX_COMMANDTYPE cmd = static_cast<OMX_COMMANDTYPE>(data1); | 786 OMX_COMMANDTYPE cmd = static_cast<OMX_COMMANDTYPE>(data1); |
| 749 switch (cmd) { | 787 switch (cmd) { |
| 750 case OMX_CommandPortDisable: { | 788 case OMX_CommandPortDisable: |
| 751 if (on_port_disable_event_func_) | 789 if (on_port_disable_event_func_) { |
| 752 (this->*on_port_disable_event_func_)(static_cast<int>(data2)); | 790 void (OmxVideoDecodeAccelerator::*func)(int) = NULL; |
| 791 std::swap(func, on_port_disable_event_func_); |
| 792 (this->*func)(static_cast<int>(data2)); |
| 753 } | 793 } |
| 754 break; | 794 break; |
| 755 case OMX_CommandPortEnable: { | 795 case OMX_CommandPortEnable: |
| 756 if (on_port_enable_event_func_) | 796 if (on_port_enable_event_func_) { |
| 757 (this->*on_port_enable_event_func_)(static_cast<int>(data2)); | 797 void (OmxVideoDecodeAccelerator::*func)(int) = NULL; |
| 798 std::swap(func, on_port_enable_event_func_); |
| 799 (this->*func)(static_cast<int>(data2)); |
| 758 } | 800 } |
| 759 break; | 801 break; |
| 760 case OMX_CommandStateSet: | 802 case OMX_CommandStateSet: |
| 761 (this->*on_state_event_func_)(static_cast<OMX_STATETYPE>(data2)); | 803 { |
| 804 void (OmxVideoDecodeAccelerator::*func)(OMX_STATETYPE state) = NULL; |
| 805 std::swap(func, on_state_event_func_); |
| 806 (this->*func)(static_cast<OMX_STATETYPE>(data2)); |
| 807 } |
| 762 break; | 808 break; |
| 763 case OMX_CommandFlush: | 809 case OMX_CommandFlush: |
| 764 (this->*on_flush_event_func_)(data2); | 810 { |
| 811 void (OmxVideoDecodeAccelerator::*func)(int) = NULL; |
| 812 std::swap(func, on_flush_event_func_); |
| 813 (this->*func)(data2); |
| 814 } |
| 765 break; | 815 break; |
| 766 default: | 816 default: |
| 767 LOG(ERROR) << "Unknown command completed\n" << data1; | 817 LOG(ERROR) << "Unknown command completed\n" << data1; |
| 768 break; | 818 break; |
| 769 } | 819 } |
| 770 break; | 820 break; |
| 771 } | 821 } |
| 772 case OMX_EventError: | 822 case OMX_EventError: |
| 773 if (static_cast<OMX_ERRORTYPE>(data1) == OMX_ErrorInvalidState) | 823 if (static_cast<OMX_ERRORTYPE>(data1) == OMX_ErrorInvalidState) |
| 774 StopOnError(); | 824 StopOnError(); |
| 775 break; | 825 break; |
| 776 case OMX_EventPortSettingsChanged: | 826 case OMX_EventPortSettingsChanged: |
| 777 // TODO(vhiremath@nvidia.com) remove this hack | 827 // TODO(vhiremath@nvidia.com) remove this hack |
| 778 // when all vendors observe same spec. | 828 // when all vendors observe same spec. |
| 779 if (data1 < OMX_IndexComponentStartUnused) { | 829 if (data1 < OMX_IndexComponentStartUnused) { |
| 780 OnPortSettingsChangedRun(static_cast<int>(data1), | 830 OnPortSettingsChangedRun(static_cast<int>(data1), |
| 781 static_cast<OMX_INDEXTYPE>(data2)); | 831 static_cast<OMX_INDEXTYPE>(data2)); |
| 782 } else { | 832 } else { |
| 783 OnPortSettingsChangedRun(static_cast<int>(data2), | 833 OnPortSettingsChangedRun(static_cast<int>(data2), |
| 784 static_cast<OMX_INDEXTYPE>(data1)); | 834 static_cast<OMX_INDEXTYPE>(data1)); |
| 785 } | 835 } |
| 786 break; | 836 break; |
| 787 case OMX_EventBufferFlag: | 837 case OMX_EventBufferFlag: |
| 788 if (data1 == static_cast<OMX_U32>(output_port_)) { | 838 if (data1 == static_cast<OMX_U32>(output_port_)) { |
| 789 (this->*on_buffer_flag_event_func_)(); | 839 void (OmxVideoDecodeAccelerator::*func)() = NULL; |
| 840 std::swap(func, on_buffer_flag_event_func_); |
| 841 (this->*func)(); |
| 790 } | 842 } |
| 791 break; | 843 break; |
| 792 default: | 844 default: |
| 793 LOG(ERROR) << "Warning - Unknown event received\n"; | 845 LOG(ERROR) << "Warning - Unknown event received\n"; |
| 794 break; | 846 break; |
| 795 } | 847 } |
| 796 } | 848 } |
| 797 | 849 |
| 798 // static | 850 // static |
| 799 OMX_ERRORTYPE OmxVideoDecodeAccelerator::EventHandler(OMX_HANDLETYPE component, | 851 OMX_ERRORTYPE OmxVideoDecodeAccelerator::EventHandler(OMX_HANDLETYPE component, |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 869 StopOnError(); | 921 StopOnError(); |
| 870 return false; | 922 return false; |
| 871 } | 923 } |
| 872 return (il_state == OMX_StateExecuting); | 924 return (il_state == OMX_StateExecuting); |
| 873 } | 925 } |
| 874 | 926 |
| 875 // Send command to disable/enable port. | 927 // Send command to disable/enable port. |
| 876 void OmxVideoDecodeAccelerator::ChangePort( | 928 void OmxVideoDecodeAccelerator::ChangePort( |
| 877 OMX_COMMANDTYPE cmd, int port_index) { | 929 OMX_COMMANDTYPE cmd, int port_index) { |
| 878 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_, | 930 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_, |
| 879 cmd, port_index, 0); | 931 cmd, port_index, 0); |
| 880 if (result != OMX_ErrorNone) { | 932 if (result != OMX_ErrorNone) { |
| 881 LOG(ERROR) << "SendCommand(OMX_CommandPortDisable) failed"; | 933 LOG(ERROR) << "SendCommand(OMX_CommandPortDisable) failed"; |
| 882 StopOnError(); | 934 StopOnError(); |
| 883 return; | 935 return; |
| 884 } | 936 } |
| 885 } | 937 } |
| 886 | 938 |
| 887 DISABLE_RUNNABLE_METHOD_REFCOUNT(OmxVideoDecodeAccelerator); | 939 DISABLE_RUNNABLE_METHOD_REFCOUNT(OmxVideoDecodeAccelerator); |
| OLD | NEW |