1 /* 2 * Copyright (c) 2009-2011 Intel Corporation. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 //#define LOG_NDEBUG 0 18 #define LOG_TAG "OMXVideoDecoder" 19 #include <wrs_omxil_core/log.h> 20 #include "OMXVideoDecoderBase.h" 21 #include <va/va_android.h> 22 23 static const char* VA_RAW_MIME_TYPE = "video/x-raw-va"; 24 static const uint32_t VA_COLOR_FORMAT = 0x7FA00E00; 25 26 OMXVideoDecoderBase::OMXVideoDecoderBase() 27 : mRotationDegrees(0), 28 mVideoDecoder(NULL), 29 mNativeBufferCount(OUTPORT_NATIVE_BUFFER_COUNT), 30 #ifdef TARGET_HAS_VPP 31 mVppBufferNum(0), 32 #endif 33 mWorkingMode(RAWDATA_MODE), 34 mErrorReportEnabled (false) { 35 mOMXBufferHeaderTypePtrNum = 0; 36 memset(&mGraphicBufferParam, 0, sizeof(mGraphicBufferParam)); 37 } 38 39 OMXVideoDecoderBase::~OMXVideoDecoderBase() { 40 releaseVideoDecoder(mVideoDecoder); 41 42 if (this->ports) { 43 if (this->ports[INPORT_INDEX]) { 44 delete this->ports[INPORT_INDEX]; 45 this->ports[INPORT_INDEX] = NULL; 46 } 47 48 if (this->ports[OUTPORT_INDEX]) { 49 delete this->ports[OUTPORT_INDEX]; 50 this->ports[OUTPORT_INDEX] = NULL; 51 } 52 } 53 } 54 55 OMX_ERRORTYPE OMXVideoDecoderBase::InitInputPort(void) { 56 this->ports[INPORT_INDEX] = new PortVideo; 57 if (this->ports[INPORT_INDEX] == NULL) { 58 return OMX_ErrorInsufficientResources; 59 } 60 61 PortVideo *port = static_cast<PortVideo *>(this->ports[INPORT_INDEX]); 62 63 // OMX_PARAM_PORTDEFINITIONTYPE 64 OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionInput; 65 memset(¶mPortDefinitionInput, 0, sizeof(paramPortDefinitionInput)); 66 SetTypeHeader(¶mPortDefinitionInput, sizeof(paramPortDefinitionInput)); 67 paramPortDefinitionInput.nPortIndex = INPORT_INDEX; 68 paramPortDefinitionInput.eDir = OMX_DirInput; 69 paramPortDefinitionInput.nBufferCountActual = INPORT_ACTUAL_BUFFER_COUNT; 70 paramPortDefinitionInput.nBufferCountMin = INPORT_MIN_BUFFER_COUNT; 71 paramPortDefinitionInput.nBufferSize = INPORT_BUFFER_SIZE; 72 paramPortDefinitionInput.bEnabled = OMX_TRUE; 73 paramPortDefinitionInput.bPopulated = OMX_FALSE; 74 paramPortDefinitionInput.eDomain = OMX_PortDomainVideo; 75 paramPortDefinitionInput.format.video.cMIMEType = NULL; // to be overridden 76 paramPortDefinitionInput.format.video.pNativeRender = NULL; 77 paramPortDefinitionInput.format.video.nFrameWidth = 176; 78 paramPortDefinitionInput.format.video.nFrameHeight = 144; 79 paramPortDefinitionInput.format.video.nStride = 0; 80 paramPortDefinitionInput.format.video.nSliceHeight = 0; 81 paramPortDefinitionInput.format.video.nBitrate = 64000; 82 paramPortDefinitionInput.format.video.xFramerate = 15 << 16; 83 // TODO: check if we need to set bFlagErrorConcealment to OMX_TRUE 84 paramPortDefinitionInput.format.video.bFlagErrorConcealment = OMX_FALSE; 85 paramPortDefinitionInput.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; // to be overridden 86 paramPortDefinitionInput.format.video.eColorFormat = OMX_COLOR_FormatUnused; 87 paramPortDefinitionInput.format.video.pNativeWindow = NULL; 88 paramPortDefinitionInput.bBuffersContiguous = OMX_FALSE; 89 paramPortDefinitionInput.nBufferAlignment = 0; 90 91 // Derived class must implement this interface and override any field if needed. 92 // eCompressionFormat and and cMIMEType must be overridden 93 InitInputPortFormatSpecific(¶mPortDefinitionInput); 94 95 port->SetPortDefinition(¶mPortDefinitionInput, true); 96 97 // OMX_VIDEO_PARAM_PORTFORMATTYPE 98 OMX_VIDEO_PARAM_PORTFORMATTYPE paramPortFormat; 99 memset(¶mPortFormat, 0, sizeof(paramPortFormat)); 100 SetTypeHeader(¶mPortFormat, sizeof(paramPortFormat)); 101 paramPortFormat.nPortIndex = INPORT_INDEX; 102 paramPortFormat.nIndex = 0; 103 paramPortFormat.eCompressionFormat = paramPortDefinitionInput.format.video.eCompressionFormat; 104 paramPortFormat.eColorFormat = paramPortDefinitionInput.format.video.eColorFormat; 105 paramPortFormat.xFramerate = paramPortDefinitionInput.format.video.xFramerate; 106 107 port->SetPortVideoParam(¶mPortFormat, true); 108 109 return OMX_ErrorNone; 110 } 111 112 113 OMX_ERRORTYPE OMXVideoDecoderBase::InitOutputPort(void) { 114 this->ports[OUTPORT_INDEX] = new PortVideo; 115 if (this->ports[OUTPORT_INDEX] == NULL) { 116 return OMX_ErrorInsufficientResources; 117 } 118 119 PortVideo *port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]); 120 121 // OMX_PARAM_PORTDEFINITIONTYPE 122 OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionOutput; 123 124 memset(¶mPortDefinitionOutput, 0, sizeof(paramPortDefinitionOutput)); 125 SetTypeHeader(¶mPortDefinitionOutput, sizeof(paramPortDefinitionOutput)); 126 127 paramPortDefinitionOutput.nPortIndex = OUTPORT_INDEX; 128 paramPortDefinitionOutput.eDir = OMX_DirOutput; 129 paramPortDefinitionOutput.nBufferCountActual = OUTPORT_ACTUAL_BUFFER_COUNT; 130 paramPortDefinitionOutput.nBufferCountMin = OUTPORT_MIN_BUFFER_COUNT; 131 paramPortDefinitionOutput.nBufferSize = sizeof(VideoRenderBuffer); 132 133 paramPortDefinitionOutput.bEnabled = OMX_TRUE; 134 paramPortDefinitionOutput.bPopulated = OMX_FALSE; 135 paramPortDefinitionOutput.eDomain = OMX_PortDomainVideo; 136 paramPortDefinitionOutput.format.video.cMIMEType = (OMX_STRING)VA_RAW_MIME_TYPE; 137 paramPortDefinitionOutput.format.video.pNativeRender = NULL; 138 paramPortDefinitionOutput.format.video.nFrameWidth = 176; 139 paramPortDefinitionOutput.format.video.nFrameHeight = 144; 140 paramPortDefinitionOutput.format.video.nStride = 176; 141 paramPortDefinitionOutput.format.video.nSliceHeight = 144; 142 paramPortDefinitionOutput.format.video.nBitrate = 64000; 143 paramPortDefinitionOutput.format.video.xFramerate = 15 << 16; 144 paramPortDefinitionOutput.format.video.bFlagErrorConcealment = OMX_FALSE; 145 paramPortDefinitionOutput.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; 146 paramPortDefinitionOutput.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; 147 paramPortDefinitionOutput.format.video.pNativeWindow = NULL; 148 paramPortDefinitionOutput.bBuffersContiguous = OMX_FALSE; 149 paramPortDefinitionOutput.nBufferAlignment = 0; 150 151 // no format specific to initialize output port 152 InitOutputPortFormatSpecific(¶mPortDefinitionOutput); 153 154 port->SetPortDefinition(¶mPortDefinitionOutput, true); 155 156 // OMX_VIDEO_PARAM_PORTFORMATTYPE 157 OMX_VIDEO_PARAM_PORTFORMATTYPE paramPortFormat; 158 SetTypeHeader(¶mPortFormat, sizeof(paramPortFormat)); 159 paramPortFormat.nPortIndex = OUTPORT_INDEX; 160 paramPortFormat.nIndex = 0; 161 paramPortFormat.eCompressionFormat = paramPortDefinitionOutput.format.video.eCompressionFormat; 162 paramPortFormat.eColorFormat = paramPortDefinitionOutput.format.video.eColorFormat; 163 paramPortFormat.xFramerate = paramPortDefinitionOutput.format.video.xFramerate; 164 165 port->SetPortVideoParam(¶mPortFormat, true); 166 167 return OMX_ErrorNone; 168 } 169 170 OMX_ERRORTYPE OMXVideoDecoderBase::InitOutputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *) { 171 // no format specific to initialize output port 172 return OMX_ErrorNone; 173 } 174 175 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorInit(void) { 176 OMX_ERRORTYPE ret; 177 ret = OMXComponentCodecBase::ProcessorInit(); 178 CHECK_RETURN_VALUE("OMXComponentCodecBase::ProcessorInit"); 179 180 if (mVideoDecoder == NULL) { 181 LOGE("ProcessorInit: Video decoder is not created."); 182 return OMX_ErrorDynamicResourcesUnavailable; 183 } 184 185 VideoConfigBuffer configBuffer; 186 ret = PrepareConfigBuffer(&configBuffer); 187 CHECK_RETURN_VALUE("PrepareConfigBuffer"); 188 189 //pthread_mutex_lock(&mSerializationLock); 190 Decode_Status status = mVideoDecoder->start(&configBuffer); 191 //pthread_mutex_unlock(&mSerializationLock); 192 193 if (status != DECODE_SUCCESS) { 194 return TranslateDecodeStatus(status); 195 } 196 197 return OMX_ErrorNone; 198 } 199 200 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorReset(void) { 201 OMX_ERRORTYPE ret; 202 VideoConfigBuffer configBuffer; 203 // reset the configbuffer and set it to mix 204 ret = PrepareConfigBuffer(&configBuffer); 205 CHECK_RETURN_VALUE("PrepareConfigBuffer"); 206 mVideoDecoder->reset(&configBuffer); 207 return OMX_ErrorNone; 208 } 209 210 211 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorDeinit(void) { 212 if (mWorkingMode != GRAPHICBUFFER_MODE) { 213 if (mVideoDecoder == NULL) { 214 LOGE("ProcessorDeinit: Video decoder is not created."); 215 return OMX_ErrorDynamicResourcesUnavailable; 216 } 217 mVideoDecoder->stop(); 218 } 219 mOMXBufferHeaderTypePtrNum = 0; 220 memset(&mGraphicBufferParam, 0, sizeof(mGraphicBufferParam)); 221 mRotationDegrees = 0; 222 #ifdef TARGET_HAS_VPP 223 mVppBufferNum = 0; 224 #endif 225 return OMXComponentCodecBase::ProcessorDeinit(); 226 } 227 228 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorStart(void) { 229 return OMXComponentCodecBase::ProcessorStart(); 230 } 231 232 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorStop(void) { 233 // There is no need to return all retained buffers as we don't accumulate buffer 234 //this->ports[INPORT_INDEX]->ReturnAllRetainedBuffers(); 235 236 // TODO: this is new code 237 ProcessorFlush(OMX_ALL); 238 if (mWorkingMode == GRAPHICBUFFER_MODE) { 239 // for GRAPHICBUFFER_MODE mode, va_destroySurface need to lock the graphicbuffer, 240 // Make sure va_destroySurface is called(ExecutingToIdle) before graphicbuffer is freed(IdleToLoaded). 241 if (mVideoDecoder == NULL) { 242 LOGE("ProcessorStop: Video decoder is not created."); 243 return OMX_ErrorDynamicResourcesUnavailable; 244 } 245 mVideoDecoder->stop(); 246 } 247 return OMXComponentCodecBase::ProcessorStop(); 248 } 249 250 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorPause(void) { 251 return OMXComponentCodecBase::ProcessorPause(); 252 } 253 254 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorResume(void) { 255 return OMXComponentCodecBase::ProcessorResume(); 256 } 257 258 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorFlush(OMX_U32 portIndex) { 259 LOGI("Flushing port# %u.", portIndex); 260 if (mVideoDecoder == NULL) { 261 LOGE("ProcessorFlush: Video decoder is not created."); 262 return OMX_ErrorDynamicResourcesUnavailable; 263 } 264 265 // Portbase has returned all retained buffers. 266 if (portIndex == INPORT_INDEX || portIndex == OMX_ALL) { 267 //pthread_mutex_lock(&mSerializationLock); 268 LOGW("Flushing video pipeline."); 269 mVideoDecoder->flush(); 270 //pthread_mutex_unlock(&mSerializationLock); 271 } 272 // TODO: do we need to flush output port? 273 return OMX_ErrorNone; 274 } 275 276 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorPreFreeBuffer(OMX_U32 nPortIndex, OMX_BUFFERHEADERTYPE * pBuffer) { 277 if (mWorkingMode == GRAPHICBUFFER_MODE) 278 return OMX_ErrorNone; 279 280 if (nPortIndex == OUTPORT_INDEX && pBuffer->pPlatformPrivate) { 281 VideoRenderBuffer *p = (VideoRenderBuffer *)pBuffer->pPlatformPrivate; 282 p->renderDone = true; 283 pBuffer->pPlatformPrivate = NULL; 284 } 285 return OMX_ErrorNone; 286 } 287 288 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorPreFillBuffer(OMX_BUFFERHEADERTYPE* buffer) { 289 if (mWorkingMode == GRAPHICBUFFER_MODE && buffer->nOutputPortIndex == OUTPORT_INDEX){ 290 Decode_Status status; 291 if(mVideoDecoder == NULL){ 292 LOGW("ProcessorPreFillBuffer: Video decoder is not created"); 293 return OMX_ErrorDynamicResourcesUnavailable; 294 } 295 status = mVideoDecoder->signalRenderDone(buffer->pBuffer); 296 297 if (status != DECODE_SUCCESS) { 298 LOGW("ProcessorPreFillBuffer:: signalRenderDone return error"); 299 return TranslateDecodeStatus(status); 300 } 301 } else if (buffer->pPlatformPrivate && buffer->nOutputPortIndex == OUTPORT_INDEX){ 302 VideoRenderBuffer *p = (VideoRenderBuffer *)buffer->pPlatformPrivate; 303 p->renderDone = true; 304 buffer->pPlatformPrivate = NULL; 305 } 306 return OMX_ErrorNone; 307 } 308 309 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorProcess( 310 OMX_BUFFERHEADERTYPE ***pBuffers, 311 buffer_retain_t *retains, 312 OMX_U32) { 313 314 OMX_ERRORTYPE ret; 315 Decode_Status status; 316 OMX_BOOL isResolutionChange = OMX_FALSE; 317 // fill render buffer without draining decoder output queue 318 ret = FillRenderBuffer(pBuffers[OUTPORT_INDEX], &retains[OUTPORT_INDEX], 0, &isResolutionChange); 319 if (ret == OMX_ErrorNone) { 320 retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 321 if (isResolutionChange) { 322 HandleFormatChange(); 323 } 324 // TODO: continue decoding 325 return ret; 326 } else if (ret != OMX_ErrorNotReady) { 327 return ret; 328 } 329 330 VideoDecodeBuffer decodeBuffer; 331 // PrepareDecodeBuffer will set retain to either BUFFER_RETAIN_GETAGAIN or BUFFER_RETAIN_NOT_RETAIN 332 ret = PrepareDecodeBuffer(*pBuffers[INPORT_INDEX], &retains[INPORT_INDEX], &decodeBuffer); 333 if (ret == OMX_ErrorNotReady) { 334 retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 335 return OMX_ErrorNone; 336 } else if (ret != OMX_ErrorNone) { 337 return ret; 338 } 339 340 if (decodeBuffer.size != 0) { 341 //pthread_mutex_lock(&mSerializationLock); 342 status = mVideoDecoder->decode(&decodeBuffer); 343 //pthread_mutex_unlock(&mSerializationLock); 344 345 if (status == DECODE_FORMAT_CHANGE) { 346 ret = HandleFormatChange(); 347 CHECK_RETURN_VALUE("HandleFormatChange"); 348 ((*pBuffers[OUTPORT_INDEX]))->nFilledLen = 0; 349 retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 350 retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 351 // real dynamic resolution change will be handled later 352 // Here is just a temporary workaround 353 // don't use the output buffer if format is changed. 354 return OMX_ErrorNone; 355 } else if (status == DECODE_NO_CONFIG) { 356 LOGW("Decoder returns DECODE_NO_CONFIG."); 357 retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 358 return OMX_ErrorNone; 359 } else if (status == DECODE_NO_REFERENCE) { 360 LOGW("Decoder returns DECODE_NO_REFERENCE."); 361 //retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 362 //return OMX_ErrorNone; 363 } else if (status == DECODE_MULTIPLE_FRAME){ 364 if (decodeBuffer.ext != NULL && decodeBuffer.ext->extType == PACKED_FRAME_TYPE && decodeBuffer.ext->extData != NULL) { 365 PackedFrameData* nextFrame = (PackedFrameData*)decodeBuffer.ext->extData; 366 (*pBuffers[INPORT_INDEX])->nOffset += nextFrame->offSet; 367 (*pBuffers[INPORT_INDEX])->nTimeStamp = nextFrame->timestamp; 368 (*pBuffers[INPORT_INDEX])->nFilledLen -= nextFrame->offSet; 369 retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 370 LOGW("Find multiple frames in a buffer, next frame offset = %d, timestamp = %lld", (*pBuffers[INPORT_INDEX])->nOffset, (*pBuffers[INPORT_INDEX])->nTimeStamp); 371 } 372 } 373 else if (status != DECODE_SUCCESS && status != DECODE_FRAME_DROPPED) { 374 if (checkFatalDecoderError(status)) { 375 return TranslateDecodeStatus(status); 376 } else { 377 // For decoder errors that could be omitted, not throw error and continue to decode. 378 TranslateDecodeStatus(status); 379 380 ((*pBuffers[OUTPORT_INDEX]))->nFilledLen = 0; 381 382 // Do not return, and try to drain the output queue 383 // retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 384 // return OMX_ErrorNone; 385 } 386 } 387 } 388 // drain the decoder output queue when in EOS state and fill the render buffer 389 ret = FillRenderBuffer(pBuffers[OUTPORT_INDEX], &retains[OUTPORT_INDEX], 390 ((*pBuffers[INPORT_INDEX]))->nFlags,&isResolutionChange); 391 392 if (isResolutionChange) { 393 HandleFormatChange(); 394 } 395 396 bool inputEoS = ((*pBuffers[INPORT_INDEX])->nFlags & OMX_BUFFERFLAG_EOS); 397 bool outputEoS = ((*pBuffers[OUTPORT_INDEX])->nFlags & OMX_BUFFERFLAG_EOS); 398 // if output port is not eos, retain the input buffer until all the output buffers are drained. 399 if (inputEoS && !outputEoS) { 400 retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 401 // the input buffer is retained for draining purpose. Set nFilledLen to 0 so buffer will not be decoded again. 402 (*pBuffers[INPORT_INDEX])->nFilledLen = 0; 403 } 404 405 if (ret == OMX_ErrorNotReady) { 406 retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 407 ret = OMX_ErrorNone; 408 } 409 410 return ret; 411 } 412 413 bool OMXVideoDecoderBase::IsAllBufferAvailable(void) { 414 bool b = ComponentBase::IsAllBufferAvailable(); 415 if (b == false) { 416 return false; 417 } 418 419 PortVideo *port = NULL; 420 port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]); 421 const OMX_PARAM_PORTDEFINITIONTYPE* port_def = port->GetPortDefinition(); 422 // if output port is disabled, retain the input buffer 423 if (!port_def->bEnabled) { 424 return false; 425 } 426 427 if (mVideoDecoder) { 428 return mVideoDecoder->checkBufferAvail(); 429 } 430 return false; 431 } 432 433 OMX_ERRORTYPE OMXVideoDecoderBase::PrepareConfigBuffer(VideoConfigBuffer *p) { 434 // default config buffer preparation 435 memset(p, 0, sizeof(VideoConfigBuffer)); 436 437 const OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput = this->ports[INPORT_INDEX]->GetPortDefinition(); 438 if (paramPortDefinitionInput == NULL) { 439 return OMX_ErrorBadParameter; 440 } 441 442 if (mWorkingMode == GRAPHICBUFFER_MODE) { 443 p->surfaceNumber = mOMXBufferHeaderTypePtrNum; 444 for (uint32_t i = 0; i < mOMXBufferHeaderTypePtrNum; i++){ 445 OMX_BUFFERHEADERTYPE *buffer_hdr = mOMXBufferHeaderTypePtrArray[i]; 446 p->graphicBufferHandler[i] = buffer_hdr->pBuffer; 447 LOGV("PrepareConfigBuffer bufferid = %p, handle = %p", buffer_hdr, buffer_hdr->pBuffer); 448 } 449 p->flag |= USE_NATIVE_GRAPHIC_BUFFER; 450 p->graphicBufferStride = mGraphicBufferParam.graphicBufferStride; 451 p->graphicBufferColorFormat = mGraphicBufferParam.graphicBufferColorFormat; 452 p->graphicBufferWidth = mGraphicBufferParam.graphicBufferWidth; 453 p->graphicBufferHeight = mGraphicBufferParam.graphicBufferHeight; 454 if (p->graphicBufferColorFormat == OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled 455 #ifdef USE_GEN_HW 456 || p->graphicBufferColorFormat == HAL_PIXEL_FORMAT_NV12_X_TILED_INTEL 457 #endif 458 ) 459 p->flag |= USE_TILING_MEMORY; 460 461 if (mEnableAdaptivePlayback) 462 p->flag |= WANT_ADAPTIVE_PLAYBACK; 463 464 PortVideo *port = NULL; 465 port = static_cast<PortVideo *>(this->ports[INPORT_INDEX]); 466 OMX_PARAM_PORTDEFINITIONTYPE port_def; 467 memcpy(&port_def, port->GetPortDefinition(), sizeof(port_def)); 468 469 if (port_def.format.video.pNativeWindow != NULL) { 470 p->nativeWindow = port_def.format.video.pNativeWindow; 471 LOGD("NativeWindow = %p", p->nativeWindow); 472 } 473 474 } 475 476 p->rotationDegrees = mRotationDegrees; 477 #ifdef TARGET_HAS_VPP 478 p->vppBufferNum = mVppBufferNum; 479 #endif 480 p->width = paramPortDefinitionInput->format.video.nFrameWidth; 481 p->height = paramPortDefinitionInput->format.video.nFrameHeight; 482 483 return OMX_ErrorNone; 484 } 485 486 OMX_ERRORTYPE OMXVideoDecoderBase::PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE *buffer, buffer_retain_t *retain, VideoDecodeBuffer *p) { 487 // default decode buffer preparation 488 memset(p, 0, sizeof(VideoDecodeBuffer)); 489 if (buffer->nFilledLen == 0) { 490 LOGW("Len of filled data to decode is 0."); 491 return OMX_ErrorNone; //OMX_ErrorBadParameter; 492 } 493 494 if (buffer->pBuffer == NULL) { 495 LOGE("Buffer to decode is empty."); 496 return OMX_ErrorBadParameter; 497 } 498 499 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { 500 LOGI("Buffer has OMX_BUFFERFLAG_CODECCONFIG flag."); 501 } 502 503 if (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) { 504 // TODO: Handle OMX_BUFFERFLAG_DECODEONLY : drop the decoded frame without rendering it. 505 LOGW("Buffer has OMX_BUFFERFLAG_DECODEONLY flag."); 506 } 507 508 p->data = buffer->pBuffer + buffer->nOffset; 509 p->size = buffer->nFilledLen; 510 p->timeStamp = buffer->nTimeStamp; 511 if (buffer->nFlags & (OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS)) { 512 // TODO: OMX_BUFFERFLAG_ENDOFFRAME can be used to indicate end of a NAL unit. 513 // setting this flag may cause corruption if buffer does not contain end-of-frame data. 514 p->flag = HAS_COMPLETE_FRAME; 515 } 516 517 if (buffer->nFlags & OMX_BUFFERFLAG_SYNCFRAME) { 518 p->flag |= IS_SYNC_FRAME; 519 } 520 521 if (buffer->pInputPortPrivate) { 522 uint32_t degree = 0; 523 memcpy ((void *) °ree, buffer->pInputPortPrivate, sizeof(uint32_t)); 524 p->rotationDegrees = degree; 525 LOGV("rotationDegrees = %d", p->rotationDegrees); 526 } else { 527 p->rotationDegrees = mRotationDegrees; 528 } 529 530 *retain= BUFFER_RETAIN_NOT_RETAIN; 531 return OMX_ErrorNone; 532 } 533 534 OMX_ERRORTYPE OMXVideoDecoderBase::FillRenderBuffer(OMX_BUFFERHEADERTYPE **pBuffer, buffer_retain_t *retain, 535 OMX_U32 inportBufferFlags, OMX_BOOL *isResolutionChange) { 536 OMX_BUFFERHEADERTYPE *buffer = *pBuffer; 537 OMX_BUFFERHEADERTYPE *buffer_orign = buffer; 538 VideoErrorBuffer *ErrBufPtr = NULL; 539 540 if (mWorkingMode != GRAPHICBUFFER_MODE && buffer->pPlatformPrivate) { 541 VideoRenderBuffer *p = (VideoRenderBuffer *)buffer->pPlatformPrivate; 542 p->renderDone = true; 543 buffer->pPlatformPrivate = NULL; 544 } 545 546 if (mWorkingMode == GRAPHICBUFFER_MODE && mErrorReportEnabled) { 547 if (buffer->pOutputPortPrivate == NULL) 548 LOGE("The App doesn't provide the output buffer for error reporting"); 549 else 550 ErrBufPtr = (VideoErrorBuffer *)buffer->pOutputPortPrivate; 551 } 552 553 bool draining = (inportBufferFlags & OMX_BUFFERFLAG_EOS); 554 //pthread_mutex_lock(&mSerializationLock); 555 const VideoRenderBuffer *renderBuffer = mVideoDecoder->getOutput(draining, ErrBufPtr); 556 //pthread_mutex_unlock(&mSerializationLock); 557 if (renderBuffer == NULL) { 558 buffer->nFilledLen = 0; 559 if (draining) { 560 LOGI("output EOS received"); 561 buffer->nFlags = OMX_BUFFERFLAG_EOS; 562 return OMX_ErrorNone; 563 } 564 return OMX_ErrorNotReady; 565 } 566 567 if (mWorkingMode == GRAPHICBUFFER_MODE) { 568 buffer = *pBuffer = mOMXBufferHeaderTypePtrArray[renderBuffer->graphicBufferIndex]; 569 } 570 571 buffer->nFlags = OMX_BUFFERFLAG_ENDOFFRAME; 572 #ifdef DEINTERLACE_EXT 573 if (renderBuffer->scanFormat & (VA_TOP_FIELD | VA_BOTTOM_FIELD)) 574 buffer->nFlags |= OMX_BUFFERFLAG_TFF; 575 #endif 576 buffer->nTimeStamp = renderBuffer->timeStamp; 577 578 if (renderBuffer->flag & IS_EOS) { 579 buffer->nFlags |= OMX_BUFFERFLAG_EOS; 580 } 581 *isResolutionChange = (renderBuffer->flag & IS_RESOLUTION_CHANGE)? OMX_TRUE: OMX_FALSE; 582 583 if (mWorkingMode == GRAPHICBUFFER_MODE) { 584 if (buffer_orign != buffer) { 585 VideoErrorBuffer *ErrBufOutPtr = NULL; 586 ErrBufOutPtr = (VideoErrorBuffer *)buffer->pOutputPortPrivate; 587 if (ErrBufPtr && ErrBufOutPtr) { 588 memcpy(ErrBufOutPtr, ErrBufPtr, sizeof(VideoErrorBuffer)); 589 memset(ErrBufPtr, 0, sizeof(VideoErrorBuffer)); 590 } 591 *retain = BUFFER_RETAIN_OVERRIDDEN; 592 } 593 buffer->nFilledLen = sizeof(OMX_U8*); 594 } else { 595 uint32_t size = 0; 596 Decode_Status status = mVideoDecoder->getRawDataFromSurface(const_cast<VideoRenderBuffer *>(renderBuffer), buffer->pBuffer + buffer->nOffset, &size, false); 597 if (status != DECODE_SUCCESS) { 598 return TranslateDecodeStatus(status); 599 } 600 buffer->nFilledLen = size; 601 buffer->pPlatformPrivate = (void *)renderBuffer; 602 } 603 604 return OMX_ErrorNone; 605 } 606 607 OMX_ERRORTYPE OMXVideoDecoderBase::HandleFormatChange(void) { 608 LOGW("Video format is changed."); 609 //pthread_mutex_lock(&mSerializationLock); 610 const VideoFormatInfo *formatInfo = mVideoDecoder->getFormatInfo(); 611 //pthread_mutex_unlock(&mSerializationLock); 612 613 // Sync port definition as it may change. 614 OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionInput, paramPortDefinitionOutput; 615 616 memcpy(¶mPortDefinitionInput, 617 this->ports[INPORT_INDEX]->GetPortDefinition(), 618 sizeof(paramPortDefinitionInput)); 619 620 memcpy(¶mPortDefinitionOutput, 621 this->ports[OUTPORT_INDEX]->GetPortDefinition(), 622 sizeof(paramPortDefinitionOutput)); 623 624 uint32_t width = formatInfo->width; 625 uint32_t height = formatInfo->height; 626 uint32_t stride = formatInfo->width; 627 uint32_t sliceHeight = formatInfo->height; 628 629 uint32_t widthCropped = formatInfo->width - formatInfo->cropLeft - formatInfo->cropRight; 630 uint32_t heightCropped = formatInfo->height - formatInfo->cropTop - formatInfo->cropBottom; 631 uint32_t strideCropped = widthCropped; 632 uint32_t sliceHeightCropped = heightCropped; 633 int force_realloc = 0; 634 635 #ifdef TARGET_HAS_VPP 636 LOGI("============== mVppBufferNum = %d\n", mVppBufferNum); 637 if (paramPortDefinitionOutput.nBufferCountActual - mVppBufferNum < formatInfo->actualBufferNeeded) { 638 #else 639 if (paramPortDefinitionOutput.nBufferCountActual < formatInfo->actualBufferNeeded) { 640 #endif 641 if (mWorkingMode == GRAPHICBUFFER_MODE) { 642 LOGV("output port buffer number is not enough: %d to %d", 643 paramPortDefinitionOutput.nBufferCountActual, 644 formatInfo->actualBufferNeeded); 645 paramPortDefinitionOutput.nBufferCountActual = mNativeBufferCount = formatInfo->actualBufferNeeded; 646 paramPortDefinitionOutput.nBufferCountMin = mNativeBufferCount; 647 force_realloc = 1; 648 } 649 } 650 651 LOGV("Original size = %u x %u, new size = %d x %d, cropped size = %d x %d", 652 paramPortDefinitionInput.format.video.nFrameWidth, 653 paramPortDefinitionInput.format.video.nFrameHeight, 654 width, height, widthCropped, heightCropped); 655 656 if (!force_realloc && 657 widthCropped == paramPortDefinitionOutput.format.video.nFrameWidth && 658 heightCropped == paramPortDefinitionOutput.format.video.nFrameHeight) { 659 if (mWorkingMode == RAWDATA_MODE) { 660 LOGW("Change of portsetting is not reported as size is not changed."); 661 return OMX_ErrorNone; 662 } 663 } 664 665 paramPortDefinitionInput.format.video.nFrameWidth = width; 666 paramPortDefinitionInput.format.video.nFrameHeight = height; 667 paramPortDefinitionInput.format.video.nStride = stride; 668 paramPortDefinitionInput.format.video.nSliceHeight = sliceHeight; 669 670 if (mWorkingMode == RAWDATA_MODE) { 671 paramPortDefinitionOutput.format.video.nFrameWidth = widthCropped; 672 paramPortDefinitionOutput.format.video.nFrameHeight = heightCropped; 673 paramPortDefinitionOutput.format.video.nStride = strideCropped; 674 paramPortDefinitionOutput.format.video.nSliceHeight = sliceHeightCropped; 675 } else if (mWorkingMode == GRAPHICBUFFER_MODE) { 676 // when the width and height ES parse are not larger than allocated graphic buffer in outport, 677 // there is no need to reallocate graphic buffer,just report the crop info to omx client 678 if (!force_realloc && width <= formatInfo->surfaceWidth && height <= formatInfo->surfaceHeight) { 679 this->ports[INPORT_INDEX]->SetPortDefinition(¶mPortDefinitionInput, true); 680 this->ports[OUTPORT_INDEX]->ReportOutputCrop(); 681 return OMX_ErrorNone; 682 } 683 684 if (width > formatInfo->surfaceWidth || height > formatInfo->surfaceHeight) { 685 // update the real decoded resolution to outport instead of display resolution for graphic buffer reallocation 686 // when the width and height parsed from ES are larger than allocated graphic buffer in outport, 687 paramPortDefinitionOutput.format.video.nFrameWidth = width; 688 paramPortDefinitionOutput.format.video.nFrameHeight = (height + 0x1f) & ~0x1f; 689 paramPortDefinitionOutput.format.video.eColorFormat = GetOutputColorFormat( 690 paramPortDefinitionOutput.format.video.nFrameWidth); 691 paramPortDefinitionOutput.format.video.nStride = stride; 692 paramPortDefinitionOutput.format.video.nSliceHeight = sliceHeight; 693 } 694 } 695 696 paramPortDefinitionOutput.bEnabled = (OMX_BOOL)false; 697 mOMXBufferHeaderTypePtrNum = 0; 698 memset(&mGraphicBufferParam, 0, sizeof(mGraphicBufferParam)); 699 700 this->ports[INPORT_INDEX]->SetPortDefinition(¶mPortDefinitionInput, true); 701 this->ports[OUTPORT_INDEX]->SetPortDefinition(¶mPortDefinitionOutput, true); 702 703 if (mWorkingMode == GRAPHICBUFFER_MODE) { 704 // Make sure va_destroySurface is called before graphicbuffer is freed in case of port setting changed 705 mVideoDecoder->freeSurfaceBuffers(); 706 } 707 this->ports[OUTPORT_INDEX]->ReportPortSettingsChanged(); 708 return OMX_ErrorNone; 709 } 710 711 OMX_ERRORTYPE OMXVideoDecoderBase::TranslateDecodeStatus(Decode_Status status) { 712 switch (status) { 713 case DECODE_NEED_RESTART: 714 LOGE("Decoder returned DECODE_NEED_RESTART"); 715 return (OMX_ERRORTYPE)OMX_ErrorIntelVideoNotPermitted; 716 case DECODE_NO_CONFIG: 717 LOGE("Decoder returned DECODE_NO_CONFIG"); 718 return (OMX_ERRORTYPE)OMX_ErrorIntelMissingConfig; 719 case DECODE_NO_SURFACE: 720 LOGE("Decoder returned DECODE_NO_SURFACE"); 721 return OMX_ErrorDynamicResourcesUnavailable; 722 case DECODE_NO_REFERENCE: 723 LOGE("Decoder returned DECODE_NO_REFERENCE"); 724 return OMX_ErrorDynamicResourcesUnavailable; // TO DO 725 case DECODE_NO_PARSER: 726 LOGE("Decoder returned DECODE_NO_PARSER"); 727 return OMX_ErrorDynamicResourcesUnavailable; 728 case DECODE_INVALID_DATA: 729 LOGE("Decoder returned DECODE_INVALID_DATA"); 730 return OMX_ErrorBadParameter; 731 case DECODE_DRIVER_FAIL: 732 LOGE("Decoder returned DECODE_DRIVER_FAIL"); 733 return OMX_ErrorHardware; 734 case DECODE_PARSER_FAIL: 735 LOGE("Decoder returned DECODE_PARSER_FAIL"); 736 return (OMX_ERRORTYPE)OMX_ErrorIntelProcessStream; // OMX_ErrorStreamCorrupt 737 case DECODE_MEMORY_FAIL: 738 LOGE("Decoder returned DECODE_MEMORY_FAIL"); 739 return OMX_ErrorInsufficientResources; 740 case DECODE_FAIL: 741 LOGE("Decoder returned DECODE_FAIL"); 742 return OMX_ErrorUndefined; 743 case DECODE_SUCCESS: 744 return OMX_ErrorNone; 745 case DECODE_FORMAT_CHANGE: 746 LOGW("Decoder returned DECODE_FORMAT_CHANGE"); 747 return OMX_ErrorNone; 748 case DECODE_FRAME_DROPPED: 749 LOGI("Decoder returned DECODE_FRAME_DROPPED"); 750 return OMX_ErrorNone; 751 default: 752 LOGW("Decoder returned unknown error"); 753 return OMX_ErrorUndefined; 754 } 755 } 756 757 OMX_ERRORTYPE OMXVideoDecoderBase::BuildHandlerList(void) { 758 OMXComponentCodecBase::BuildHandlerList(); 759 AddHandler(OMX_IndexParamVideoPortFormat, GetParamVideoPortFormat, SetParamVideoPortFormat); 760 AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtGetNativeBufferUsage), GetNativeBufferUsage, SetNativeBufferUsage); 761 AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtUseNativeBuffer), GetNativeBuffer, SetNativeBuffer); 762 AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtEnableNativeBuffer), GetNativeBufferMode, SetNativeBufferMode); 763 AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtRotationDegrees), GetDecoderRotation, SetDecoderRotation); 764 #ifdef TARGET_HAS_VPP 765 AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtVppBufferNum), GetDecoderVppBufferNum, SetDecoderVppBufferNum); 766 #endif 767 AddHandler(OMX_IndexConfigCommonOutputCrop, GetDecoderOutputCrop, SetDecoderOutputCrop); 768 AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtEnableErrorReport), GetErrorReportMode, SetErrorReportMode); 769 770 return OMX_ErrorNone; 771 } 772 773 OMX_ERRORTYPE OMXVideoDecoderBase::GetParamVideoPortFormat(OMX_PTR pStructure) { 774 OMX_ERRORTYPE ret; 775 OMX_VIDEO_PARAM_PORTFORMATTYPE *p = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pStructure; 776 777 CHECK_TYPE_HEADER(p); 778 CHECK_PORT_INDEX_RANGE(p); 779 CHECK_ENUMERATION_RANGE(p->nIndex, 1); 780 781 PortVideo *port = NULL; 782 port = static_cast<PortVideo *>(this->ports[p->nPortIndex]); 783 memcpy(p, port->GetPortVideoParam(), sizeof(*p)); 784 return OMX_ErrorNone; 785 } 786 787 OMX_ERRORTYPE OMXVideoDecoderBase::SetParamVideoPortFormat(OMX_PTR pStructure) { 788 OMX_ERRORTYPE ret; 789 OMX_VIDEO_PARAM_PORTFORMATTYPE *p = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pStructure; 790 791 CHECK_TYPE_HEADER(p); 792 CHECK_PORT_INDEX_RANGE(p); 793 CHECK_SET_PARAM_STATE(); 794 795 // TODO: do we need to check if port is enabled? 796 PortVideo *port = NULL; 797 port = static_cast<PortVideo *>(this->ports[p->nPortIndex]); 798 port->SetPortVideoParam(p, false); 799 return OMX_ErrorNone; 800 } 801 802 OMX_ERRORTYPE OMXVideoDecoderBase::GetNativeBufferUsageSpecific(OMX_PTR pStructure) { 803 OMX_ERRORTYPE ret; 804 GetAndroidNativeBufferUsageParams *param = (GetAndroidNativeBufferUsageParams*)pStructure; 805 CHECK_TYPE_HEADER(param); 806 param->nUsage |= GRALLOC_USAGE_HW_TEXTURE; 807 return OMX_ErrorNone; 808 } 809 OMX_ERRORTYPE OMXVideoDecoderBase::SetNativeBufferUsageSpecific(OMX_PTR) { 810 CHECK_SET_PARAM_STATE(); 811 return OMX_ErrorBadParameter; 812 } 813 814 OMX_ERRORTYPE OMXVideoDecoderBase::GetNativeBufferUsage(OMX_PTR pStructure) { 815 return this->GetNativeBufferUsageSpecific(pStructure); 816 } 817 OMX_ERRORTYPE OMXVideoDecoderBase::SetNativeBufferUsage(OMX_PTR pStructure) { 818 return this->SetNativeBufferUsageSpecific(pStructure); 819 } 820 821 OMX_ERRORTYPE OMXVideoDecoderBase::GetNativeBuffer(OMX_PTR) { 822 return OMX_ErrorBadParameter; 823 } 824 825 OMX_ERRORTYPE OMXVideoDecoderBase::SetNativeBuffer(OMX_PTR pStructure) { 826 OMX_ERRORTYPE ret; 827 UseAndroidNativeBufferParams *param = (UseAndroidNativeBufferParams*)pStructure; 828 CHECK_TYPE_HEADER(param); 829 if (param->nPortIndex != OUTPORT_INDEX) 830 return OMX_ErrorBadParameter; 831 OMX_BUFFERHEADERTYPE **buf_hdr = NULL; 832 833 mOMXBufferHeaderTypePtrNum++; 834 if (mOMXBufferHeaderTypePtrNum > MAX_GRAPHIC_BUFFER_NUM) 835 return OMX_ErrorOverflow; 836 837 buf_hdr = &mOMXBufferHeaderTypePtrArray[mOMXBufferHeaderTypePtrNum-1]; 838 839 ret = this->ports[OUTPORT_INDEX]->UseBuffer(buf_hdr, OUTPORT_INDEX, param->pAppPrivate, sizeof(OMX_U8*), 840 const_cast<OMX_U8*>(reinterpret_cast<const OMX_U8*>(param->nativeBuffer->handle))); 841 if (ret != OMX_ErrorNone) 842 return ret; 843 844 if (mOMXBufferHeaderTypePtrNum == 1) { 845 mGraphicBufferParam.graphicBufferColorFormat = param->nativeBuffer->format; 846 mGraphicBufferParam.graphicBufferStride = param->nativeBuffer->stride; 847 mGraphicBufferParam.graphicBufferWidth = param->nativeBuffer->width; 848 mGraphicBufferParam.graphicBufferHeight = param->nativeBuffer->height; 849 } 850 851 *(param->bufferHeader) = *buf_hdr; 852 853 return OMX_ErrorNone; 854 } 855 856 OMX_ERRORTYPE OMXVideoDecoderBase::GetNativeBufferMode(OMX_PTR pStructure) { 857 return this->GetNativeBufferModeSpecific(pStructure); 858 } 859 860 OMX_ERRORTYPE OMXVideoDecoderBase::SetNativeBufferMode(OMX_PTR pStructure) { 861 return this->SetNativeBufferModeSpecific(pStructure); 862 } 863 864 OMX_ERRORTYPE OMXVideoDecoderBase::GetNativeBufferModeSpecific(OMX_PTR) { 865 LOGE("GetNativeBufferMode is not implemented"); 866 return OMX_ErrorNotImplemented; 867 } 868 869 OMX_ERRORTYPE OMXVideoDecoderBase::SetNativeBufferModeSpecific(OMX_PTR pStructure) { 870 OMX_ERRORTYPE ret; 871 EnableAndroidNativeBuffersParams *param = (EnableAndroidNativeBuffersParams*)pStructure; 872 873 CHECK_TYPE_HEADER(param); 874 CHECK_PORT_INDEX_RANGE(param); 875 CHECK_SET_PARAM_STATE(); 876 if (!param->enable) { 877 mWorkingMode = RAWDATA_MODE; 878 return OMX_ErrorNone; 879 } 880 mWorkingMode = GRAPHICBUFFER_MODE; 881 PortVideo *port = NULL; 882 port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]); 883 884 OMX_PARAM_PORTDEFINITIONTYPE port_def; 885 memcpy(&port_def,port->GetPortDefinition(),sizeof(port_def)); 886 port_def.nBufferCountMin = mNativeBufferCount; 887 if (mEnableAdaptivePlayback) { 888 SetMaxOutputBufferCount(&port_def); 889 } else { 890 port_def.nBufferCountActual = mNativeBufferCount; 891 } 892 port_def.format.video.cMIMEType = (OMX_STRING)VA_VED_RAW_MIME_TYPE; 893 port_def.format.video.eColorFormat = OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar; 894 port_def.format.video.nFrameHeight = (port_def.format.video.nFrameHeight + 0x1f) & ~0x1f; 895 port_def.format.video.eColorFormat = GetOutputColorFormat( 896 port_def.format.video.nFrameWidth); 897 port->SetPortDefinition(&port_def,true); 898 899 return OMX_ErrorNone; 900 } 901 902 OMX_ERRORTYPE OMXVideoDecoderBase::GetDecoderRotation(OMX_PTR) { 903 return OMX_ErrorBadParameter; 904 } 905 OMX_ERRORTYPE OMXVideoDecoderBase::SetDecoderRotation(OMX_PTR pStructure) { 906 CHECK_SET_PARAM_STATE(); 907 int32_t rotationDegrees = 0; 908 909 if (pStructure) { 910 rotationDegrees = *(static_cast<int32_t*>(pStructure)); 911 mRotationDegrees = rotationDegrees; 912 LOGI("Rotation Degree = %d", rotationDegrees); 913 return OMX_ErrorNone; 914 } else { 915 return OMX_ErrorBadParameter; 916 } 917 } 918 919 #ifdef TARGET_HAS_VPP 920 OMX_ERRORTYPE OMXVideoDecoderBase::GetDecoderVppBufferNum(OMX_PTR pStructure) { 921 return OMX_ErrorBadParameter; 922 } 923 OMX_ERRORTYPE OMXVideoDecoderBase::SetDecoderVppBufferNum(OMX_PTR pStructure) { 924 CHECK_SET_PARAM_STATE(); 925 int32_t num = 0; 926 927 num = *(static_cast<int32_t*>(pStructure)); 928 mVppBufferNum = num; 929 930 return OMX_ErrorNone; 931 } 932 #endif 933 934 OMX_ERRORTYPE OMXVideoDecoderBase::GetDecoderOutputCropSpecific(OMX_PTR pStructure) { 935 OMX_ERRORTYPE ret; 936 OMX_CONFIG_RECTTYPE *rectParams = (OMX_CONFIG_RECTTYPE *)pStructure; 937 938 CHECK_TYPE_HEADER(rectParams); 939 940 if (rectParams->nPortIndex != OUTPORT_INDEX) { 941 return OMX_ErrorUndefined; 942 } 943 const VideoFormatInfo *formatInfo = mVideoDecoder->getFormatInfo(); 944 if (formatInfo->valid == true) { 945 rectParams->nLeft = formatInfo->cropLeft; 946 rectParams->nTop = formatInfo->cropTop; 947 rectParams->nWidth = formatInfo->width - formatInfo->cropLeft - formatInfo->cropRight; 948 rectParams->nHeight = formatInfo->height - formatInfo->cropTop - formatInfo->cropBottom; 949 return OMX_ErrorNone; 950 } else { 951 return OMX_ErrorFormatNotDetected; 952 } 953 } 954 955 OMX_ERRORTYPE OMXVideoDecoderBase::SetDecoderOutputCropSpecific(OMX_PTR) { 956 return OMX_ErrorUnsupportedSetting; 957 } 958 959 OMX_ERRORTYPE OMXVideoDecoderBase::SetDecoderOutputCrop(OMX_PTR pStructure) { 960 return this->SetDecoderOutputCropSpecific(pStructure); 961 } 962 963 OMX_ERRORTYPE OMXVideoDecoderBase::GetDecoderOutputCrop(OMX_PTR pStructure) { 964 return this->GetDecoderOutputCropSpecific(pStructure); 965 } 966 967 OMX_ERRORTYPE OMXVideoDecoderBase::GetErrorReportMode(OMX_PTR) { 968 LOGE("GetErrorReportMode is not implemented"); 969 return OMX_ErrorNotImplemented; 970 } 971 972 OMX_ERRORTYPE OMXVideoDecoderBase::SetErrorReportMode(OMX_PTR pStructure) { 973 OMX_ERRORTYPE ret; 974 975 OMX_VIDEO_CONFIG_INTEL_ERROR_REPORT *p = (OMX_VIDEO_CONFIG_INTEL_ERROR_REPORT *)pStructure; 976 CHECK_TYPE_HEADER(p); 977 CHECK_PORT_INDEX(p, OUTPORT_INDEX); 978 979 mErrorReportEnabled = p->bEnable; 980 LOGD("Error reporting is %s", mErrorReportEnabled ? "enabled" : "disabled"); 981 982 mVideoDecoder->enableErrorReport(mErrorReportEnabled); 983 return OMX_ErrorNone; 984 } 985 986 OMX_COLOR_FORMATTYPE OMXVideoDecoderBase::GetOutputColorFormat(int width) { 987 #ifndef VED_TILING 988 return OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar; 989 #else 990 if (width > 1280 && width <= 2048) { 991 LOGI("HD Video and use tiled format"); 992 return OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled; 993 } else { 994 return OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar; 995 } 996 #endif 997 } 998 999 OMX_ERRORTYPE OMXVideoDecoderBase::SetMaxOutputBufferCount(OMX_PARAM_PORTDEFINITIONTYPE *) { 1000 return OMX_ErrorNone; 1001 } 1002