| 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/media/omx_video_decode_accelerator.h" | 5 #include "content/common/gpu/media/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/gpu_channel.h" | 9 #include "content/common/gpu/gpu_channel.h" |
| 10 #include "content/common/gpu/media/gles2_texture_to_egl_image_translator.h" | 10 #include "content/common/gpu/media/gles2_texture_to_egl_image_translator.h" |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 memset(param, 0, sizeof(T)); | 139 memset(param, 0, sizeof(T)); |
| 140 param->nVersion.nVersion = 0x00000101; | 140 param->nVersion.nVersion = 0x00000101; |
| 141 param->nSize = sizeof(T); | 141 param->nSize = sizeof(T); |
| 142 } | 142 } |
| 143 | 143 |
| 144 bool OmxVideoDecodeAccelerator::Initialize(const std::vector<uint32>& config) { | 144 bool OmxVideoDecodeAccelerator::Initialize(const std::vector<uint32>& config) { |
| 145 // Extract the required info from the configs. | 145 // Extract the required info from the configs. |
| 146 // For now consider only what we care about. | 146 // For now consider only what we care about. |
| 147 std::vector<uint32> matched_configs; | 147 std::vector<uint32> matched_configs; |
| 148 GetConfigs(config, &matched_configs); | 148 GetConfigs(config, &matched_configs); |
| 149 if (config != matched_configs) | 149 if (config != matched_configs) { |
| 150 StopOnError(VIDEODECODERERROR_INVALIDINPUT); |
| 150 return false; | 151 return false; |
| 152 } |
| 151 client_state_ = OMX_StateLoaded; | 153 client_state_ = OMX_StateLoaded; |
| 152 if (!CreateComponent()) { | 154 if (!CreateComponent()) { |
| 153 StopOnError(); | 155 StopOnError(VIDEODECODERERROR_UNINITIALIZED); |
| 154 return false; | 156 return false; |
| 155 } | 157 } |
| 156 | 158 |
| 157 // Transition component to Idle state | 159 // Transition component to Idle state |
| 158 DCHECK(!on_state_event_func_); | 160 DCHECK(!on_state_event_func_); |
| 159 on_state_event_func_ = | 161 on_state_event_func_ = |
| 160 &OmxVideoDecodeAccelerator::OnStateChangeLoadedToIdle; | 162 &OmxVideoDecodeAccelerator::OnStateChangeLoadedToIdle; |
| 161 if (!TransitionToState(OMX_StateIdle)) { | 163 if (!TransitionToState(OMX_StateIdle)) { |
| 162 LOG(ERROR) << "TransitionToState(OMX_StateIdle) error"; | 164 LOG(ERROR) << "TransitionToState(OMX_StateIdle) error"; |
| 163 StopOnError(); | 165 StopOnError(VIDEODECODERERROR_UNINITIALIZED); |
| 164 return false; | 166 return false; |
| 165 } | 167 } |
| 166 | 168 |
| 167 if (!AllocateInputBuffers()) { | 169 if (!AllocateInputBuffers()) { |
| 168 LOG(ERROR) << "OMX_AllocateBuffer() Input buffer error"; | 170 LOG(ERROR) << "OMX_AllocateBuffer() Input buffer error"; |
| 169 StopOnError(); | 171 StopOnError(VIDEODECODERERROR_MEMFAILURE); |
| 170 return false; | 172 return false; |
| 171 } | 173 } |
| 172 | 174 |
| 173 return true; | 175 return true; |
| 174 } | 176 } |
| 175 | 177 |
| 176 bool OmxVideoDecodeAccelerator::CreateComponent() { | 178 bool OmxVideoDecodeAccelerator::CreateComponent() { |
| 177 OMX_CALLBACKTYPE omx_accelerator_callbacks = { | 179 OMX_CALLBACKTYPE omx_accelerator_callbacks = { |
| 178 &OmxVideoDecodeAccelerator::EventHandler, | 180 &OmxVideoDecodeAccelerator::EventHandler, |
| 179 &OmxVideoDecodeAccelerator::EmptyBufferCallback, | 181 &OmxVideoDecodeAccelerator::EmptyBufferCallback, |
| 180 &OmxVideoDecodeAccelerator::FillBufferCallback | 182 &OmxVideoDecodeAccelerator::FillBufferCallback |
| 181 }; | 183 }; |
| 182 OMX_ERRORTYPE result = OMX_ErrorNone; | 184 OMX_ERRORTYPE result = OMX_ErrorNone; |
| 183 | 185 |
| 184 // Set the role and get all components of this role. | 186 // Set the role and get all components of this role. |
| 185 // TODO(vhiremath@nvidia.com) Get this role_name from the configs | 187 // TODO(vhiremath@nvidia.com) Get this role_name from the configs |
| 186 // For now hard coding to avc. | 188 // For now hard coding to avc. |
| 187 const char* role_name = "video_decoder.avc"; | 189 const char* role_name = "video_decoder.avc"; |
| 188 OMX_U32 num_roles = 0; | 190 OMX_U32 num_roles = 0; |
| 189 // Get all the components with this role. | 191 // Get all the components with this role. |
| 190 result = (*omx_get_components_of_role)( | 192 result = (*omx_get_components_of_role)( |
| 191 const_cast<OMX_STRING>(role_name), &num_roles, 0); | 193 const_cast<OMX_STRING>(role_name), &num_roles, 0); |
| 192 if (result != OMX_ErrorNone || num_roles == 0) { | 194 if (result != OMX_ErrorNone || num_roles == 0) { |
| 193 LOG(ERROR) << "Unsupported Role: " << role_name << ", " << result; | 195 LOG(ERROR) << "Unsupported Role: " << role_name << ", " << result; |
| 194 StopOnError(); | 196 StopOnError(VIDEODECODERERROR_UNSUPPORTED); |
| 195 return false; | 197 return false; |
| 196 } | 198 } |
| 197 | 199 |
| 198 // We haven't seen HW that needs more yet, but there is no reason not to | 200 // We haven't seen HW that needs more yet, but there is no reason not to |
| 199 // raise. | 201 // raise. |
| 200 const OMX_U32 kMaxRolePerComponent = 3; | 202 const OMX_U32 kMaxRolePerComponent = 3; |
| 201 CHECK_LT(num_roles, kMaxRolePerComponent); | 203 CHECK_LT(num_roles, kMaxRolePerComponent); |
| 202 | 204 |
| 203 scoped_array<scoped_array<OMX_U8> > component_names( | 205 scoped_array<scoped_array<OMX_U8> > component_names( |
| 204 new scoped_array<OMX_U8>[num_roles]); | 206 new scoped_array<OMX_U8>[num_roles]); |
| 205 for (size_t i = 0; i < num_roles; ++i) | 207 for (size_t i = 0; i < num_roles; ++i) |
| 206 component_names[i].reset(new OMX_U8[OMX_MAX_STRINGNAME_SIZE]); | 208 component_names[i].reset(new OMX_U8[OMX_MAX_STRINGNAME_SIZE]); |
| 207 result = (*omx_get_components_of_role)( | 209 result = (*omx_get_components_of_role)( |
| 208 const_cast<OMX_STRING>(role_name), | 210 const_cast<OMX_STRING>(role_name), |
| 209 &num_roles, reinterpret_cast<OMX_U8**>(component_names.get())); | 211 &num_roles, reinterpret_cast<OMX_U8**>(component_names.get())); |
| 210 | 212 |
| 211 // Use first component only. Copy the name of the first component so that we | 213 // Use first component only. Copy the name of the first component so that we |
| 212 // could free the memory. | 214 // could free the memory. |
| 213 std::string component_name; | 215 std::string component_name; |
| 214 if (result == OMX_ErrorNone) | 216 if (result == OMX_ErrorNone) |
| 215 component_name = reinterpret_cast<char*>(component_names[0].get()); | 217 component_name = reinterpret_cast<char*>(component_names[0].get()); |
| 216 | 218 |
| 217 if (result != OMX_ErrorNone || num_roles == 0) { | 219 if (result != OMX_ErrorNone || num_roles == 0) { |
| 218 LOG(ERROR) << "Unsupported Role: " << component_name.c_str(); | 220 LOG(ERROR) << "Unsupported Role: " << component_name.c_str(); |
| 219 StopOnError(); | 221 StopOnError(VIDEODECODERERROR_UNSUPPORTED); |
| 220 return false; | 222 return false; |
| 221 } | 223 } |
| 222 | 224 |
| 223 // Get the handle to the component. After OMX_GetHandle(), the component is | 225 // Get the handle to the component. After OMX_GetHandle(), the component is |
| 224 // in loaded state. | 226 // in loaded state. |
| 225 OMX_STRING component = const_cast<OMX_STRING>(component_name.c_str()); | 227 OMX_STRING component = const_cast<OMX_STRING>(component_name.c_str()); |
| 226 result = omx_gethandle(&component_handle_, component, this, | 228 result = omx_gethandle(&component_handle_, component, this, |
| 227 &omx_accelerator_callbacks); | 229 &omx_accelerator_callbacks); |
| 228 if (result != OMX_ErrorNone) { | 230 if (result != OMX_ErrorNone) { |
| 229 LOG(ERROR) << "Failed to Load the component: " << component; | 231 LOG(ERROR) << "Failed to Load the component: " << component; |
| 230 StopOnError(); | 232 StopOnError(VIDEODECODERERROR_INSUFFICIENT_RESOURCES); |
| 231 return false; | 233 return false; |
| 232 } | 234 } |
| 233 | 235 |
| 234 // Get the port information. This will obtain information about the number of | 236 // Get the port information. This will obtain information about the number of |
| 235 // ports and index of the first port. | 237 // ports and index of the first port. |
| 236 OMX_PORT_PARAM_TYPE port_param; | 238 OMX_PORT_PARAM_TYPE port_param; |
| 237 InitParam(*this, &port_param); | 239 InitParam(*this, &port_param); |
| 238 result = OMX_GetParameter(component_handle_, OMX_IndexParamVideoInit, | 240 result = OMX_GetParameter(component_handle_, OMX_IndexParamVideoInit, |
| 239 &port_param); | 241 &port_param); |
| 240 if ((result != OMX_ErrorNone) || (port_param.nPorts != 2)) { | 242 if ((result != OMX_ErrorNone) || (port_param.nPorts != 2)) { |
| 241 LOG(ERROR) << "Failed to get Port Param: " | 243 LOG(ERROR) << "Failed to get Port Param: " |
| 242 << result << ", " << port_param.nPorts; | 244 << result << ", " << port_param.nPorts; |
| 243 StopOnError(); | 245 StopOnError(VIDEODECODERERROR_INSUFFICIENT_RESOURCES); |
| 244 return false; | 246 return false; |
| 245 } | 247 } |
| 246 input_port_ = port_param.nStartPortNumber; | 248 input_port_ = port_param.nStartPortNumber; |
| 247 output_port_ = input_port_ + 1; | 249 output_port_ = input_port_ + 1; |
| 248 | 250 |
| 249 // Set role for the component because components can have multiple roles. | 251 // Set role for the component because components can have multiple roles. |
| 250 OMX_PARAM_COMPONENTROLETYPE role_type; | 252 OMX_PARAM_COMPONENTROLETYPE role_type; |
| 251 InitParam(*this, &role_type); | 253 InitParam(*this, &role_type); |
| 252 base::strlcpy(reinterpret_cast<char*>(role_type.cRole), | 254 base::strlcpy(reinterpret_cast<char*>(role_type.cRole), |
| 253 role_name, | 255 role_name, |
| 254 OMX_MAX_STRINGNAME_SIZE); | 256 OMX_MAX_STRINGNAME_SIZE); |
| 255 | 257 |
| 256 result = OMX_SetParameter(component_handle_, | 258 result = OMX_SetParameter(component_handle_, |
| 257 OMX_IndexParamStandardComponentRole, | 259 OMX_IndexParamStandardComponentRole, |
| 258 &role_type); | 260 &role_type); |
| 259 if (result != OMX_ErrorNone) { | 261 if (result != OMX_ErrorNone) { |
| 260 LOG(ERROR) << "Failed to Set Role"; | 262 LOG(ERROR) << "Failed to Set Role"; |
| 261 StopOnError(); | 263 StopOnError(VIDEODECODERERROR_INVALIDINPUT); |
| 262 return false; | 264 return false; |
| 263 } | 265 } |
| 264 | 266 |
| 265 // Populate input-buffer-related members based on input port data. | 267 // Populate input-buffer-related members based on input port data. |
| 266 OMX_PARAM_PORTDEFINITIONTYPE port_format; | 268 OMX_PARAM_PORTDEFINITIONTYPE port_format; |
| 267 InitParam(*this, &port_format); | 269 InitParam(*this, &port_format); |
| 268 port_format.nPortIndex = input_port_; | 270 port_format.nPortIndex = input_port_; |
| 269 result = OMX_GetParameter(component_handle_, | 271 result = OMX_GetParameter(component_handle_, |
| 270 OMX_IndexParamPortDefinition, | 272 OMX_IndexParamPortDefinition, |
| 271 &port_format); | 273 &port_format); |
| 272 if (result != OMX_ErrorNone) { | 274 if (result != OMX_ErrorNone) { |
| 273 LOG(ERROR) << "GetParameter(OMX_IndexParamPortDefinition) failed"; | 275 LOG(ERROR) << "GetParameter(OMX_IndexParamPortDefinition) failed"; |
| 274 StopOnError(); | 276 StopOnError(VIDEODECODERERROR_INVALIDINPUT); |
| 275 return false; | 277 return false; |
| 276 } | 278 } |
| 277 if (OMX_DirInput != port_format.eDir) { | 279 if (OMX_DirInput != port_format.eDir) { |
| 278 LOG(ERROR) << "Expected input port"; | 280 LOG(ERROR) << "Expected input port"; |
| 279 StopOnError(); | 281 StopOnError(VIDEODECODERERROR_INVALIDINPUT); |
| 280 return false; | 282 return false; |
| 281 } | 283 } |
| 282 input_buffer_count_ = port_format.nBufferCountActual; | 284 input_buffer_count_ = port_format.nBufferCountActual; |
| 283 input_buffer_size_ = port_format.nBufferSize; | 285 input_buffer_size_ = port_format.nBufferSize; |
| 284 | 286 |
| 285 // Verify output port conforms to our expectations. | 287 // Verify output port conforms to our expectations. |
| 286 InitParam(*this, &port_format); | 288 InitParam(*this, &port_format); |
| 287 port_format.nPortIndex = output_port_; | 289 port_format.nPortIndex = output_port_; |
| 288 result = OMX_GetParameter(component_handle_, | 290 result = OMX_GetParameter(component_handle_, |
| 289 OMX_IndexParamPortDefinition, | 291 OMX_IndexParamPortDefinition, |
| 290 &port_format); | 292 &port_format); |
| 291 if (result != OMX_ErrorNone) { | 293 if (result != OMX_ErrorNone) { |
| 292 LOG(ERROR) << "GetParameter(OMX_IndexParamPortDefinition) failed"; | 294 LOG(ERROR) << "GetParameter(OMX_IndexParamPortDefinition) failed"; |
| 293 StopOnError(); | 295 StopOnError(VIDEODECODERERROR_INVALIDINPUT); |
| 294 return false; | 296 return false; |
| 295 } | 297 } |
| 296 if (OMX_DirOutput != port_format.eDir) { | 298 if (OMX_DirOutput != port_format.eDir) { |
| 297 LOG(ERROR) << "Expect Output Port"; | 299 LOG(ERROR) << "Expect Output Port"; |
| 298 StopOnError(); | 300 StopOnError(VIDEODECODERERROR_INVALIDINPUT); |
| 299 return false; | 301 return false; |
| 300 } | 302 } |
| 301 | 303 |
| 302 // Set output port parameters. | 304 // Set output port parameters. |
| 303 port_format.nBufferCountActual = kNumPictureBuffers; | 305 port_format.nBufferCountActual = kNumPictureBuffers; |
| 304 port_format.nBufferCountMin = kNumPictureBuffers; | 306 port_format.nBufferCountMin = kNumPictureBuffers; |
| 305 // Force an OMX_EventPortSettingsChanged event to be sent once we know the | 307 // Force an OMX_EventPortSettingsChanged event to be sent once we know the |
| 306 // stream's real dimensions (which can only happen once some Decode() work has | 308 // stream's real dimensions (which can only happen once some Decode() work has |
| 307 // been done). | 309 // been done). |
| 308 port_format.format.video.nFrameWidth = -1; | 310 port_format.format.video.nFrameWidth = -1; |
| 309 port_format.format.video.nFrameHeight = -1; | 311 port_format.format.video.nFrameHeight = -1; |
| 310 result = OMX_SetParameter(component_handle_, | 312 result = OMX_SetParameter(component_handle_, |
| 311 OMX_IndexParamPortDefinition, | 313 OMX_IndexParamPortDefinition, |
| 312 &port_format); | 314 &port_format); |
| 313 if (result != OMX_ErrorNone) { | 315 if (result != OMX_ErrorNone) { |
| 314 LOG(ERROR) << "SetParameter(OMX_IndexParamPortDefinition) failed"; | 316 LOG(ERROR) << "SetParameter(OMX_IndexParamPortDefinition) failed"; |
| 315 StopOnError(); | 317 StopOnError(VIDEODECODERERROR_INVALIDINPUT); |
| 316 return false; | 318 return false; |
| 317 } | 319 } |
| 318 | 320 |
| 319 // Fill the component with fake output buffers. This seems to be required for | 321 // Fill the component with fake output buffers. This seems to be required for |
| 320 // the component to move from Loaded to Idle. How bogus. | 322 // the component to move from Loaded to Idle. How bogus. |
| 321 for (int i = 0; i < kNumPictureBuffers; ++i) { | 323 for (int i = 0; i < kNumPictureBuffers; ++i) { |
| 322 OMX_BUFFERHEADERTYPE* buffer; | 324 OMX_BUFFERHEADERTYPE* buffer; |
| 323 result = OMX_UseBuffer(component_handle_, &buffer, output_port_, | 325 result = OMX_UseBuffer(component_handle_, &buffer, output_port_, |
| 324 NULL, 0, reinterpret_cast<OMX_U8*>(0x1)); | 326 NULL, 0, reinterpret_cast<OMX_U8*>(0x1)); |
| 325 if (result != OMX_ErrorNone) { | 327 if (result != OMX_ErrorNone) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 365 // Abuse the header's nTimeStamp field to propagate the bitstream buffer ID to | 367 // Abuse the header's nTimeStamp field to propagate the bitstream buffer ID to |
| 366 // the output buffer's nTimeStamp field, so we can report it back to the | 368 // the output buffer's nTimeStamp field, so we can report it back to the |
| 367 // client in PictureReady(). | 369 // client in PictureReady(). |
| 368 omx_buffer->nTimeStamp = bitstream_buffer.id(); | 370 omx_buffer->nTimeStamp = bitstream_buffer.id(); |
| 369 | 371 |
| 370 // Give this buffer to OMX. | 372 // Give this buffer to OMX. |
| 371 OMX_ERRORTYPE result = OMX_ErrorNone; | 373 OMX_ERRORTYPE result = OMX_ErrorNone; |
| 372 result = OMX_EmptyThisBuffer(component_handle_, omx_buffer); | 374 result = OMX_EmptyThisBuffer(component_handle_, omx_buffer); |
| 373 if (result != OMX_ErrorNone) { | 375 if (result != OMX_ErrorNone) { |
| 374 LOG(ERROR) << "OMX_EmptyThisBuffer() failed with result " << result; | 376 LOG(ERROR) << "OMX_EmptyThisBuffer() failed with result " << result; |
| 375 StopOnError(); | 377 StopOnError(VIDEODECODERERROR_INVALIDINPUT); |
| 376 return; | 378 return; |
| 377 } | 379 } |
| 378 input_buffers_at_component_++; | 380 input_buffers_at_component_++; |
| 379 } | 381 } |
| 380 | 382 |
| 381 void OmxVideoDecodeAccelerator::AssignGLESBuffers( | 383 void OmxVideoDecodeAccelerator::AssignGLESBuffers( |
| 382 const std::vector<media::GLESBuffer>& buffers) { | 384 const std::vector<media::GLESBuffer>& buffers) { |
| 383 if (!CanFillBuffer()) { | 385 if (!CanFillBuffer()) { |
| 384 StopOnError(); | 386 StopOnError(VIDEODECODERERROR_UNINITIALIZED); |
| 385 return; | 387 return; |
| 386 } | 388 } |
| 387 CHECK_EQ(output_buffers_at_component_, 0); | 389 CHECK_EQ(output_buffers_at_component_, 0); |
| 388 CHECK_EQ(fake_output_buffers_.size(), 0U); | 390 CHECK_EQ(fake_output_buffers_.size(), 0U); |
| 389 CHECK_EQ(pictures_.size(), 0U); | 391 CHECK_EQ(pictures_.size(), 0U); |
| 390 | 392 |
| 391 CHECK_EQ(message_loop_, MessageLoop::current()); | 393 CHECK_EQ(message_loop_, MessageLoop::current()); |
| 392 for (size_t i = 0; i < buffers.size(); ++i) { | 394 for (size_t i = 0; i < buffers.size(); ++i) { |
| 393 CHECK(pictures_.insert(std::make_pair( | 395 CHECK(pictures_.insert(std::make_pair( |
| 394 buffers[i].id(), OutputPicture(buffers[i], NULL))).second); | 396 buffers[i].id(), OutputPicture(buffers[i], NULL))).second); |
| 395 } | 397 } |
| 396 | 398 |
| 397 if (pictures_.size() < kNumPictureBuffers) | 399 if (pictures_.size() < kNumPictureBuffers) |
| 398 return; // get all the buffers first. | 400 return; // get all the buffers first. |
| 399 DCHECK_EQ(pictures_.size(), kNumPictureBuffers); | 401 DCHECK_EQ(pictures_.size(), kNumPictureBuffers); |
| 400 | 402 |
| 401 if (!AllocateOutputBuffers()) { | 403 if (!AllocateOutputBuffers()) { |
| 402 LOG(ERROR) << "OMX_AllocateBuffer() Output buffer error"; | 404 LOG(ERROR) << "OMX_AllocateBuffer() Output buffer error"; |
| 403 StopOnError(); | 405 StopOnError(VIDEODECODERERROR_MEMFAILURE); |
| 404 return; | 406 return; |
| 405 } | 407 } |
| 406 | 408 |
| 407 DCHECK(!on_port_enable_event_func_); | 409 DCHECK(!on_port_enable_event_func_); |
| 408 on_port_enable_event_func_ = | 410 on_port_enable_event_func_ = |
| 409 &OmxVideoDecodeAccelerator::PortEnabledAfterSettingsChange; | 411 &OmxVideoDecodeAccelerator::PortEnabledAfterSettingsChange; |
| 410 ChangePort(OMX_CommandPortEnable, output_port_); | 412 ChangePort(OMX_CommandPortEnable, output_port_); |
| 411 } | 413 } |
| 412 | 414 |
| 413 void OmxVideoDecodeAccelerator::AssignSysmemBuffers( | 415 void OmxVideoDecodeAccelerator::AssignSysmemBuffers( |
| (...skipping 13 matching lines...) Expand all Loading... |
| 427 LOG(DFATAL) << "Missing picture buffer id: " << picture_buffer_id; | 429 LOG(DFATAL) << "Missing picture buffer id: " << picture_buffer_id; |
| 428 return; | 430 return; |
| 429 } | 431 } |
| 430 OutputPicture& output_picture = it->second; | 432 OutputPicture& output_picture = it->second; |
| 431 | 433 |
| 432 ++output_buffers_at_component_; | 434 ++output_buffers_at_component_; |
| 433 OMX_ERRORTYPE result = | 435 OMX_ERRORTYPE result = |
| 434 OMX_FillThisBuffer(component_handle_, output_picture.omx_buffer_header); | 436 OMX_FillThisBuffer(component_handle_, output_picture.omx_buffer_header); |
| 435 if (result != OMX_ErrorNone) { | 437 if (result != OMX_ErrorNone) { |
| 436 LOG(ERROR) << "OMX_FillThisBuffer() failed with result " << result; | 438 LOG(ERROR) << "OMX_FillThisBuffer() failed with result " << result; |
| 437 StopOnError(); | 439 StopOnError(VIDEODECODERERROR_INVALIDINPUT); |
| 438 return; | 440 return; |
| 439 } | 441 } |
| 440 } | 442 } |
| 441 | 443 |
| 442 void OmxVideoDecodeAccelerator::Flush() { | 444 void OmxVideoDecodeAccelerator::Flush() { |
| 443 OMX_STATETYPE il_state; | 445 OMX_STATETYPE il_state; |
| 444 OMX_GetState(component_handle_, &il_state); | 446 OMX_GetState(component_handle_, &il_state); |
| 445 DCHECK_EQ(il_state, OMX_StateExecuting); | 447 DCHECK_EQ(il_state, OMX_StateExecuting); |
| 446 // Decode the pending data first. Then flush I/O ports. | 448 // Decode the pending data first. Then flush I/O ports. |
| 447 if (il_state != OMX_StateExecuting) { | 449 if (il_state != OMX_StateExecuting) { |
| 448 client_->NotifyFlushDone(); | 450 client_->NotifyFlushDone(); |
| 449 return; | 451 return; |
| 450 } | 452 } |
| 451 on_buffer_flag_event_func_ = &OmxVideoDecodeAccelerator::FlushBegin; | 453 on_buffer_flag_event_func_ = &OmxVideoDecodeAccelerator::FlushBegin; |
| 452 | 454 |
| 453 OMX_BUFFERHEADERTYPE* omx_buffer = free_input_buffers_.front(); | 455 OMX_BUFFERHEADERTYPE* omx_buffer = free_input_buffers_.front(); |
| 454 free_input_buffers_.pop(); | 456 free_input_buffers_.pop(); |
| 455 | 457 |
| 456 omx_buffer->nFilledLen = 0; | 458 omx_buffer->nFilledLen = 0; |
| 457 omx_buffer->nAllocLen = omx_buffer->nFilledLen; | 459 omx_buffer->nAllocLen = omx_buffer->nFilledLen; |
| 458 omx_buffer->nFlags |= OMX_BUFFERFLAG_EOS; | 460 omx_buffer->nFlags |= OMX_BUFFERFLAG_EOS; |
| 459 omx_buffer->nTimeStamp = 0; | 461 omx_buffer->nTimeStamp = 0; |
| 460 // Give this buffer to OMX. | 462 // Give this buffer to OMX. |
| 461 OMX_ERRORTYPE result = OMX_ErrorNone; | 463 OMX_ERRORTYPE result = OMX_ErrorNone; |
| 462 result = OMX_EmptyThisBuffer(component_handle_, omx_buffer); | 464 result = OMX_EmptyThisBuffer(component_handle_, omx_buffer); |
| 463 if (result != OMX_ErrorNone) { | 465 if (result != OMX_ErrorNone) { |
| 464 LOG(ERROR) << "OMX_EmptyThisBuffer() failed with result " << result; | 466 LOG(ERROR) << "OMX_EmptyThisBuffer() failed with result " << result; |
| 465 StopOnError(); | 467 StopOnError(VIDEODECODERERROR_INVALIDINPUT); |
| 466 return; | 468 return; |
| 467 } | 469 } |
| 468 input_buffers_at_component_++; | 470 input_buffers_at_component_++; |
| 469 } | 471 } |
| 470 | 472 |
| 471 void OmxVideoDecodeAccelerator::FlushBegin() { | 473 void OmxVideoDecodeAccelerator::FlushBegin() { |
| 472 VLOG(1) << "Starting actual flush for EOS"; | 474 VLOG(1) << "Starting actual flush for EOS"; |
| 473 DCHECK(!on_state_event_func_); | 475 DCHECK(!on_state_event_func_); |
| 474 on_state_event_func_ = &OmxVideoDecodeAccelerator::PauseFromExecuting; | 476 on_state_event_func_ = &OmxVideoDecodeAccelerator::PauseFromExecuting; |
| 475 TransitionToState(OMX_StatePause); | 477 TransitionToState(OMX_StatePause); |
| 476 } | 478 } |
| 477 | 479 |
| 478 void OmxVideoDecodeAccelerator::PauseFromExecuting(OMX_STATETYPE ignored) { | 480 void OmxVideoDecodeAccelerator::PauseFromExecuting(OMX_STATETYPE ignored) { |
| 479 on_state_event_func_ = NULL; | 481 on_state_event_func_ = NULL; |
| 480 FlushIOPorts(); | 482 FlushIOPorts(); |
| 481 } | 483 } |
| 482 | 484 |
| 483 void OmxVideoDecodeAccelerator::FlushIOPorts() { | 485 void OmxVideoDecodeAccelerator::FlushIOPorts() { |
| 484 // TODO(vhiremath@nvidia.com) review again for trick modes. | 486 // TODO(vhiremath@nvidia.com) review again for trick modes. |
| 485 VLOG(1) << "FlushIOPorts"; | 487 VLOG(1) << "FlushIOPorts"; |
| 486 | 488 |
| 487 // Flush input port first. | 489 // Flush input port first. |
| 488 DCHECK(!on_flush_event_func_); | 490 DCHECK(!on_flush_event_func_); |
| 489 on_flush_event_func_ = &OmxVideoDecodeAccelerator::InputPortFlushDone; | 491 on_flush_event_func_ = &OmxVideoDecodeAccelerator::InputPortFlushDone; |
| 490 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_, | 492 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_, |
| 491 OMX_CommandFlush, | 493 OMX_CommandFlush, |
| 492 input_port_, 0); | 494 input_port_, 0); |
| 493 if (result != OMX_ErrorNone) { | 495 if (result != OMX_ErrorNone) { |
| 494 LOG(ERROR) << "OMX_SendCommand(OMX_CommandFlush) failed"; | 496 LOG(ERROR) << "OMX_SendCommand(OMX_CommandFlush) failed"; |
| 495 StopOnError(); | 497 StopOnError(VIDEODECODERERROR_INVALIDINPUT); |
| 496 return; | 498 return; |
| 497 } | 499 } |
| 498 } | 500 } |
| 499 | 501 |
| 500 void OmxVideoDecodeAccelerator::InputPortFlushDone(int port) { | 502 void OmxVideoDecodeAccelerator::InputPortFlushDone(int port) { |
| 501 DCHECK_EQ(port, input_port_); | 503 DCHECK_EQ(port, input_port_); |
| 502 VLOG(1) << "Input Port has been flushed"; | 504 VLOG(1) << "Input Port has been flushed"; |
| 503 DCHECK_EQ(input_buffers_at_component_, 0); | 505 DCHECK_EQ(input_buffers_at_component_, 0); |
| 504 // Flush output port next. | 506 // Flush output port next. |
| 505 DCHECK(!on_flush_event_func_); | 507 DCHECK(!on_flush_event_func_); |
| 506 on_flush_event_func_ = &OmxVideoDecodeAccelerator::OutputPortFlushDone; | 508 on_flush_event_func_ = &OmxVideoDecodeAccelerator::OutputPortFlushDone; |
| 507 if (OMX_ErrorNone != | 509 if (OMX_ErrorNone != |
| 508 OMX_SendCommand(component_handle_, | 510 OMX_SendCommand(component_handle_, |
| 509 OMX_CommandFlush, | 511 OMX_CommandFlush, |
| 510 output_port_, 0)) { | 512 output_port_, 0)) { |
| 511 LOG(ERROR) << "OMX_SendCommand(OMX_CommandFlush) failed"; | 513 LOG(ERROR) << "OMX_SendCommand(OMX_CommandFlush) failed"; |
| 512 StopOnError(); | 514 StopOnError(VIDEODECODERERROR_INVALIDINPUT); |
| 513 return; | 515 return; |
| 514 } | 516 } |
| 515 } | 517 } |
| 516 | 518 |
| 517 void OmxVideoDecodeAccelerator::OutputPortFlushDone(int port) { | 519 void OmxVideoDecodeAccelerator::OutputPortFlushDone(int port) { |
| 518 DCHECK_EQ(port, output_port_); | 520 DCHECK_EQ(port, output_port_); |
| 519 | 521 |
| 520 VLOG(1) << "Output Port has been flushed"; | 522 VLOG(1) << "Output Port has been flushed"; |
| 521 DCHECK_EQ(output_buffers_at_component_, 0); | 523 DCHECK_EQ(output_buffers_at_component_, 0); |
| 522 client_state_ = OMX_StatePause; | 524 client_state_ = OMX_StatePause; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 // Request filling of our fake buffers to trigger decode processing. In | 559 // Request filling of our fake buffers to trigger decode processing. In |
| 558 // reality as soon as any data is decoded these will get dismissed due to | 560 // reality as soon as any data is decoded these will get dismissed due to |
| 559 // dimension mismatch. | 561 // dimension mismatch. |
| 560 for (std::set<OMX_BUFFERHEADERTYPE*>::iterator it = | 562 for (std::set<OMX_BUFFERHEADERTYPE*>::iterator it = |
| 561 fake_output_buffers_.begin(); | 563 fake_output_buffers_.begin(); |
| 562 it != fake_output_buffers_.end(); ++it) { | 564 it != fake_output_buffers_.end(); ++it) { |
| 563 OMX_BUFFERHEADERTYPE* buffer = *it; | 565 OMX_BUFFERHEADERTYPE* buffer = *it; |
| 564 OMX_ERRORTYPE result = OMX_FillThisBuffer(component_handle_, buffer); | 566 OMX_ERRORTYPE result = OMX_FillThisBuffer(component_handle_, buffer); |
| 565 if (result != OMX_ErrorNone) { | 567 if (result != OMX_ErrorNone) { |
| 566 LOG(ERROR) << "OMX_FillThisBuffer() failed with: " << result; | 568 LOG(ERROR) << "OMX_FillThisBuffer() failed with: " << result; |
| 567 StopOnError(); | 569 StopOnError(VIDEODECODERERROR_INVALIDINPUT); |
| 568 return; | 570 return; |
| 569 } | 571 } |
| 570 ++output_buffers_at_component_; | 572 ++output_buffers_at_component_; |
| 571 } | 573 } |
| 572 | 574 |
| 573 message_loop_->PostTask( | 575 message_loop_->PostTask( |
| 574 FROM_HERE, | 576 FROM_HERE, |
| 575 base::Bind(&Client::NotifyInitializeDone, base::Unretained(client_))); | 577 base::Bind(&Client::NotifyInitializeDone, base::Unretained(client_))); |
| 576 } | 578 } |
| 577 | 579 |
| 578 // Send state transition command to component. | 580 // Send state transition command to component. |
| 579 bool OmxVideoDecodeAccelerator::TransitionToState(OMX_STATETYPE new_state) { | 581 bool OmxVideoDecodeAccelerator::TransitionToState(OMX_STATETYPE new_state) { |
| 580 DCHECK(on_state_event_func_); | 582 DCHECK(on_state_event_func_); |
| 581 OMX_ERRORTYPE result = OMX_SendCommand( | 583 OMX_ERRORTYPE result = OMX_SendCommand( |
| 582 component_handle_, OMX_CommandStateSet, new_state, 0); | 584 component_handle_, OMX_CommandStateSet, new_state, 0); |
| 583 if (result != OMX_ErrorNone) { | 585 if (result != OMX_ErrorNone) { |
| 584 LOG(ERROR) << "SendCommand(OMX_CommandStateSet) failed"; | 586 LOG(ERROR) << "SendCommand(OMX_CommandStateSet) failed"; |
| 585 StopOnError(); | 587 StopOnError(VIDEODECODERERROR_INVALIDINPUT); |
| 586 return false; | 588 return false; |
| 587 } | 589 } |
| 590 client_state_ = new_state; |
| 588 return true; | 591 return true; |
| 589 } | 592 } |
| 590 | 593 |
| 591 void OmxVideoDecodeAccelerator::ShutDownOMXFromExecuting() { | 594 void OmxVideoDecodeAccelerator::ShutDownOMXFromExecuting() { |
| 592 VLOG(1) << "Deinit from Executing"; | 595 VLOG(1) << "Deinit from Executing"; |
| 593 DCHECK(!on_state_event_func_); | 596 DCHECK(!on_state_event_func_); |
| 594 on_state_event_func_ = | 597 on_state_event_func_ = |
| 595 &OmxVideoDecodeAccelerator::OnStateChangeExecutingToIdle; | 598 &OmxVideoDecodeAccelerator::OnStateChangeExecutingToIdle; |
| 596 TransitionToState(OMX_StateIdle); | 599 TransitionToState(OMX_StateIdle); |
| 597 } | 600 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 624 if (result != OMX_ErrorNone) | 627 if (result != OMX_ErrorNone) |
| 625 LOG(ERROR) << "OMX_FreeHandle() error. Error code: " << result; | 628 LOG(ERROR) << "OMX_FreeHandle() error. Error code: " << result; |
| 626 component_handle_ = NULL; | 629 component_handle_ = NULL; |
| 627 } | 630 } |
| 628 client_state_ = OMX_StateLoaded; | 631 client_state_ = OMX_StateLoaded; |
| 629 (*omx_deinit)(); | 632 (*omx_deinit)(); |
| 630 VLOG(1) << "OMX Deinit Clean exit done"; | 633 VLOG(1) << "OMX Deinit Clean exit done"; |
| 631 client_->NotifyAbortDone(); | 634 client_->NotifyAbortDone(); |
| 632 } | 635 } |
| 633 | 636 |
| 634 void OmxVideoDecodeAccelerator::StopOnError() { | 637 void OmxVideoDecodeAccelerator::StopOnError( |
| 638 media::VideoDecodeAccelerator::Error error) { |
| 639 if (client_) |
| 640 client_->NotifyError(error); |
| 641 if (client_state_ == OMX_StateInvalid) |
| 642 return; |
| 643 |
| 644 client_state_ = OMX_StateInvalid; |
| 645 if (!component_handle_) |
| 646 return; |
| 647 |
| 635 OMX_STATETYPE il_state; | 648 OMX_STATETYPE il_state; |
| 636 OMX_GetState(component_handle_, &il_state); | 649 OMX_GetState(component_handle_, &il_state); |
| 637 client_state_ = OMX_StateInvalid; | |
| 638 switch (il_state) { | 650 switch (il_state) { |
| 639 case OMX_StateExecuting: | 651 case OMX_StateExecuting: |
| 640 ShutDownOMXFromExecuting(); | 652 ShutDownOMXFromExecuting(); |
| 641 return; | 653 return; |
| 642 case OMX_StateIdle: | 654 case OMX_StateIdle: |
| 643 OnStateChangeExecutingToIdle(OMX_StateIdle); | 655 OnStateChangeExecutingToIdle(OMX_StateIdle); |
| 644 return; | 656 return; |
| 645 case OMX_StateLoaded: | 657 case OMX_StateLoaded: |
| 646 OnStateChangeIdleToLoaded(OMX_StateLoaded); | 658 OnStateChangeIdleToLoaded(OMX_StateLoaded); |
| 647 return; | 659 return; |
| 648 default: | 660 default: |
| 649 // LOG unexpected state or just ignore? | 661 LOG(ERROR) << "Invalid state: " |
| 662 << il_state << " received in StopOnError()"; |
| 650 return; | 663 return; |
| 651 } | 664 } |
| 652 } | 665 } |
| 653 | 666 |
| 654 bool OmxVideoDecodeAccelerator::AllocateInputBuffers() { | 667 bool OmxVideoDecodeAccelerator::AllocateInputBuffers() { |
| 655 for (int i = 0; i < input_buffer_count_; ++i) { | 668 for (int i = 0; i < input_buffer_count_; ++i) { |
| 656 OMX_BUFFERHEADERTYPE* buffer; | 669 OMX_BUFFERHEADERTYPE* buffer; |
| 657 // While registering the buffer header we use fake buffer information | 670 // While registering the buffer header we use fake buffer information |
| 658 // (length 0, at memory address 0x1) to fake out the "safety" check in | 671 // (length 0, at memory address 0x1) to fake out the "safety" check in |
| 659 // OMX_UseBuffer. When it comes time to actually use this header in Decode | 672 // OMX_UseBuffer. When it comes time to actually use this header in Decode |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 706 void OmxVideoDecodeAccelerator::FreeInputBuffers() { | 719 void OmxVideoDecodeAccelerator::FreeInputBuffers() { |
| 707 // Calls to OMX to free buffers. | 720 // Calls to OMX to free buffers. |
| 708 OMX_ERRORTYPE result; | 721 OMX_ERRORTYPE result; |
| 709 OMX_BUFFERHEADERTYPE* omx_buffer; | 722 OMX_BUFFERHEADERTYPE* omx_buffer; |
| 710 while (!free_input_buffers_.empty()) { | 723 while (!free_input_buffers_.empty()) { |
| 711 omx_buffer = free_input_buffers_.front(); | 724 omx_buffer = free_input_buffers_.front(); |
| 712 free_input_buffers_.pop(); | 725 free_input_buffers_.pop(); |
| 713 result = OMX_FreeBuffer(component_handle_, input_port_, omx_buffer); | 726 result = OMX_FreeBuffer(component_handle_, input_port_, omx_buffer); |
| 714 if (result != OMX_ErrorNone) { | 727 if (result != OMX_ErrorNone) { |
| 715 LOG(ERROR) << "OMX_FreeBuffer failed with: " << result; | 728 LOG(ERROR) << "OMX_FreeBuffer failed with: " << result; |
| 716 StopOnError(); | 729 StopOnError(VIDEODECODERERROR_INVALIDINPUT); |
| 717 return; | 730 return; |
| 718 } | 731 } |
| 719 } | 732 } |
| 720 VLOG(1) << "Input buffers freed."; | 733 VLOG(1) << "Input buffers freed."; |
| 721 } | 734 } |
| 722 | 735 |
| 723 void OmxVideoDecodeAccelerator::FreeOutputBuffers() { | 736 void OmxVideoDecodeAccelerator::FreeOutputBuffers() { |
| 724 // Calls to OMX to free buffers. | 737 // Calls to OMX to free buffers. |
| 725 OMX_ERRORTYPE result; | 738 OMX_ERRORTYPE result; |
| 726 for (OutputPictureById::iterator it = pictures_.begin(); | 739 for (OutputPictureById::iterator it = pictures_.begin(); |
| 727 it != pictures_.end(); ++it) { | 740 it != pictures_.end(); ++it) { |
| 728 OMX_BUFFERHEADERTYPE* omx_buffer = it->second.omx_buffer_header; | 741 OMX_BUFFERHEADERTYPE* omx_buffer = it->second.omx_buffer_header; |
| 729 CHECK(omx_buffer); | 742 CHECK(omx_buffer); |
| 730 delete reinterpret_cast<media::Picture*>(omx_buffer->pAppPrivate); | 743 delete reinterpret_cast<media::Picture*>(omx_buffer->pAppPrivate); |
| 731 result = OMX_FreeBuffer(component_handle_, output_port_, omx_buffer); | 744 result = OMX_FreeBuffer(component_handle_, output_port_, omx_buffer); |
| 732 if (result != OMX_ErrorNone) { | 745 if (result != OMX_ErrorNone) { |
| 733 LOG(ERROR) << "OMX_FreeBuffer failed with: " << result; | 746 LOG(ERROR) << "OMX_FreeBuffer failed with: " << result; |
| 734 StopOnError(); | 747 StopOnError(VIDEODECODERERROR_INVALIDINPUT); |
| 735 return; | 748 return; |
| 736 } | 749 } |
| 737 client_->DismissPictureBuffer(it->first); | 750 client_->DismissPictureBuffer(it->first); |
| 738 } | 751 } |
| 739 pictures_.clear(); | 752 pictures_.clear(); |
| 740 } | 753 } |
| 741 | 754 |
| 742 void OmxVideoDecodeAccelerator::OnIndexParamPortDefinitionChanged(int port) { | 755 void OmxVideoDecodeAccelerator::OnIndexParamPortDefinitionChanged(int port) { |
| 743 DCHECK_EQ(port, output_port_); | 756 DCHECK_EQ(port, output_port_); |
| 744 DCHECK(!on_port_disable_event_func_); | 757 DCHECK(!on_port_disable_event_func_); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 774 static_cast<int32>(kNumPictureBuffers), | 787 static_cast<int32>(kNumPictureBuffers), |
| 775 gfx::Size(vformat.nFrameWidth, vformat.nFrameHeight), | 788 gfx::Size(vformat.nFrameWidth, vformat.nFrameHeight), |
| 776 PICTUREBUFFER_MEMORYTYPE_GL_TEXTURE)); | 789 PICTUREBUFFER_MEMORYTYPE_GL_TEXTURE)); |
| 777 } | 790 } |
| 778 | 791 |
| 779 void OmxVideoDecodeAccelerator::PortEnabledAfterSettingsChange(int port) { | 792 void OmxVideoDecodeAccelerator::PortEnabledAfterSettingsChange(int port) { |
| 780 DCHECK_EQ(port, output_port_); | 793 DCHECK_EQ(port, output_port_); |
| 781 | 794 |
| 782 if (!CanFillBuffer()) { | 795 if (!CanFillBuffer()) { |
| 783 LOG(ERROR) << "Can't FillBuffer on port-enabled"; | 796 LOG(ERROR) << "Can't FillBuffer on port-enabled"; |
| 784 StopOnError(); | 797 StopOnError(VIDEODECODERERROR_INSUFFICIENT_RESOURCES); |
| 785 return; | 798 return; |
| 786 } | 799 } |
| 787 | 800 |
| 788 // Ask the decoder to fill the output buffers. | 801 // Ask the decoder to fill the output buffers. |
| 789 for (OutputPictureById::iterator it = pictures_.begin(); | 802 for (OutputPictureById::iterator it = pictures_.begin(); |
| 790 it != pictures_.end(); ++it) { | 803 it != pictures_.end(); ++it) { |
| 791 OMX_BUFFERHEADERTYPE* omx_buffer = it->second.omx_buffer_header; | 804 OMX_BUFFERHEADERTYPE* omx_buffer = it->second.omx_buffer_header; |
| 792 DCHECK(omx_buffer); | 805 DCHECK(omx_buffer); |
| 793 // Clear EOS flag. | 806 // Clear EOS flag. |
| 794 omx_buffer->nFlags &= ~OMX_BUFFERFLAG_EOS; | 807 omx_buffer->nFlags &= ~OMX_BUFFERFLAG_EOS; |
| 795 omx_buffer->nOutputPortIndex = output_port_; | 808 omx_buffer->nOutputPortIndex = output_port_; |
| 796 ++output_buffers_at_component_; | 809 ++output_buffers_at_component_; |
| 797 OMX_ERRORTYPE result = OMX_FillThisBuffer(component_handle_, omx_buffer); | 810 OMX_ERRORTYPE result = OMX_FillThisBuffer(component_handle_, omx_buffer); |
| 798 if (result != OMX_ErrorNone) { | 811 if (result != OMX_ErrorNone) { |
| 799 LOG(ERROR) << "OMX_FillThisBuffer() failed with result " << result; | 812 LOG(ERROR) << "OMX_FillThisBuffer() failed with result " << result; |
| 800 StopOnError(); | 813 StopOnError(VIDEODECODERERROR_INSUFFICIENT_BUFFERS); |
| 801 return; | 814 return; |
| 802 } | 815 } |
| 803 } | 816 } |
| 804 } | 817 } |
| 805 | 818 |
| 806 void OmxVideoDecodeAccelerator::FillBufferDoneTask( | 819 void OmxVideoDecodeAccelerator::FillBufferDoneTask( |
| 807 OMX_BUFFERHEADERTYPE* buffer) { | 820 OMX_BUFFERHEADERTYPE* buffer) { |
| 808 CHECK_EQ(message_loop_, MessageLoop::current()); | 821 CHECK_EQ(message_loop_, MessageLoop::current()); |
| 809 DCHECK_GT(output_buffers_at_component_, 0); | 822 DCHECK_GT(output_buffers_at_component_, 0); |
| 810 --output_buffers_at_component_; | 823 --output_buffers_at_component_; |
| 811 | 824 |
| 812 if (fake_output_buffers_.size() && fake_output_buffers_.count(buffer)) { | 825 if (fake_output_buffers_.size() && fake_output_buffers_.count(buffer)) { |
| 813 CHECK_EQ(fake_output_buffers_.erase(buffer), 1U); | 826 CHECK_EQ(fake_output_buffers_.erase(buffer), 1U); |
| 814 OMX_ERRORTYPE result = | 827 OMX_ERRORTYPE result = |
| 815 OMX_FreeBuffer(component_handle_, output_port_, buffer); | 828 OMX_FreeBuffer(component_handle_, output_port_, buffer); |
| 816 if (result != OMX_ErrorNone) { | 829 if (result != OMX_ErrorNone) { |
| 817 LOG(ERROR) << "OMX_FreeBuffer failed with: " << result; | 830 LOG(ERROR) << "OMX_FreeBuffer failed with: " << result; |
| 818 StopOnError(); | 831 StopOnError(VIDEODECODERERROR_INVALIDINPUT); |
| 819 return; | 832 return; |
| 820 } | 833 } |
| 821 return; | 834 return; |
| 822 } | 835 } |
| 823 CHECK(!fake_output_buffers_.size()); | 836 CHECK(!fake_output_buffers_.size()); |
| 824 | 837 |
| 825 // During the transition from Paused to Idle (e.g. during Flush()) all | 838 // During the transition from Paused to Idle (e.g. during Flush()) all |
| 826 // pictures are sent back through here. Avoid giving them to the client. | 839 // pictures are sent back through here. Avoid giving them to the client. |
| 827 // TODO(fischman): this is a hokey way to detect this condition. The state | 840 // TODO(fischman): this is a hokey way to detect this condition. The state |
| 828 // transitions in this class need to be rethought, and this implemented more | 841 // transitions in this class need to be rethought, and this implemented more |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 901 (this->*func)(data2); | 914 (this->*func)(data2); |
| 902 } | 915 } |
| 903 break; | 916 break; |
| 904 default: | 917 default: |
| 905 LOG(ERROR) << "Unknown command completed\n" << data1; | 918 LOG(ERROR) << "Unknown command completed\n" << data1; |
| 906 break; | 919 break; |
| 907 } | 920 } |
| 908 break; | 921 break; |
| 909 } | 922 } |
| 910 case OMX_EventError: | 923 case OMX_EventError: |
| 911 if (static_cast<OMX_ERRORTYPE>(data1) == OMX_ErrorInvalidState) | 924 StopOnError(VIDEODECODERERROR_HARDWARE); |
| 912 StopOnError(); | |
| 913 break; | 925 break; |
| 914 case OMX_EventPortSettingsChanged: | 926 case OMX_EventPortSettingsChanged: |
| 915 if (data2 == OMX_IndexParamPortDefinition) { | 927 if (data2 == OMX_IndexParamPortDefinition) { |
| 916 OnIndexParamPortDefinitionChanged(static_cast<int>(data1)); | 928 OnIndexParamPortDefinitionChanged(static_cast<int>(data1)); |
| 917 } else if (data1 == static_cast<OMX_U32>(output_port_) && | 929 } else if (data1 == static_cast<OMX_U32>(output_port_) && |
| 918 data2 == OMX_IndexConfigCommonOutputCrop) { | 930 data2 == OMX_IndexConfigCommonOutputCrop) { |
| 919 // TODO(vjain): Handle video crop rect. | 931 // TODO(vjain): Handle video crop rect. |
| 920 } else { | 932 } else { |
| 921 LOG(ERROR) << "Unexpected EventPortSettingsChanged [data1:" | 933 LOG(ERROR) << "Unexpected EventPortSettingsChanged [data1:" |
| 922 << data1 << " data2:" << data2 << "]"; | 934 << data1 << " data2:" << data2 << "]"; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 999 bool OmxVideoDecodeAccelerator::CanFillBuffer() { | 1011 bool OmxVideoDecodeAccelerator::CanFillBuffer() { |
| 1000 // Make sure component is in the executing state and end-of-stream | 1012 // Make sure component is in the executing state and end-of-stream |
| 1001 // has not been reached. | 1013 // has not been reached. |
| 1002 OMX_ERRORTYPE result; | 1014 OMX_ERRORTYPE result; |
| 1003 OMX_STATETYPE il_state; | 1015 OMX_STATETYPE il_state; |
| 1004 if (client_state_ == OMX_StateLoaded) | 1016 if (client_state_ == OMX_StateLoaded) |
| 1005 return false; | 1017 return false; |
| 1006 result = OMX_GetState(component_handle_, &il_state); | 1018 result = OMX_GetState(component_handle_, &il_state); |
| 1007 if (result != OMX_ErrorNone) { | 1019 if (result != OMX_ErrorNone) { |
| 1008 LOG(ERROR) << "OMX_GetState failed"; | 1020 LOG(ERROR) << "OMX_GetState failed"; |
| 1009 StopOnError(); | 1021 StopOnError(VIDEODECODERERROR_INVALIDINPUT); |
| 1010 return false; | 1022 return false; |
| 1011 } | 1023 } |
| 1012 return (il_state == OMX_StateExecuting); | 1024 return (il_state == OMX_StateExecuting); |
| 1013 } | 1025 } |
| 1014 | 1026 |
| 1015 // Send command to disable/enable port. | 1027 // Send command to disable/enable port. |
| 1016 void OmxVideoDecodeAccelerator::ChangePort( | 1028 void OmxVideoDecodeAccelerator::ChangePort( |
| 1017 OMX_COMMANDTYPE cmd, int port_index) { | 1029 OMX_COMMANDTYPE cmd, int port_index) { |
| 1018 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_, | 1030 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_, |
| 1019 cmd, port_index, 0); | 1031 cmd, port_index, 0); |
| 1020 if (result != OMX_ErrorNone) { | 1032 if (result != OMX_ErrorNone) { |
| 1021 LOG(ERROR) << "SendCommand() failed" << cmd << ":" << result; | 1033 LOG(ERROR) << "SendCommand() failed" << cmd << ":" << result; |
| 1022 StopOnError(); | 1034 StopOnError(VIDEODECODERERROR_INVALIDINPUT); |
| 1023 return; | 1035 return; |
| 1024 } | 1036 } |
| 1025 } | 1037 } |
| 1026 | 1038 |
| 1027 DISABLE_RUNNABLE_METHOD_REFCOUNT(OmxVideoDecodeAccelerator); | 1039 DISABLE_RUNNABLE_METHOD_REFCOUNT(OmxVideoDecodeAccelerator); |
| OLD | NEW |