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 21 #include <hardware/gralloc.h> 22 #include <va/va_android.h> 23 24 #include "OMXVideoDecoderBase.h" 25 #include "ProtectedDataBuffer.h" 26 27 28 static const char* VA_RAW_MIME_TYPE = "video/x-raw-va"; 29 static const uint32_t VA_COLOR_FORMAT = 0x7FA00E00; 30 31 OMXVideoDecoderBase::OMXVideoDecoderBase() 32 : mRotationDegrees(0), 33 #ifdef TARGET_HAS_ISV 34 mVppBufferNum(0), 35 #endif 36 mCodecPriority(1), 37 mOperatingRate(0), 38 mVideoDecoder(NULL), 39 mNativeBufferCount(OUTPORT_NATIVE_BUFFER_COUNT), 40 mWorkingMode(RAWDATA_MODE), 41 mErrorReportEnabled (false), 42 mAPMode(LEGACY_MODE), 43 mFlushMode(false), 44 mFormatChanged(false) { 45 mOMXBufferHeaderTypePtrNum = 0; 46 mMetaDataBuffersNum = 0; 47 memset(&mGraphicBufferParam, 0, sizeof(mGraphicBufferParam)); 48 } 49 50 OMXVideoDecoderBase::~OMXVideoDecoderBase() { 51 releaseVideoDecoder(mVideoDecoder); 52 53 if (this->ports) { 54 if (this->ports[INPORT_INDEX]) { 55 delete this->ports[INPORT_INDEX]; 56 this->ports[INPORT_INDEX] = NULL; 57 } 58 59 if (this->ports[OUTPORT_INDEX]) { 60 delete this->ports[OUTPORT_INDEX]; 61 this->ports[OUTPORT_INDEX] = NULL; 62 } 63 } 64 } 65 66 OMX_ERRORTYPE OMXVideoDecoderBase::InitInputPort(void) { 67 this->ports[INPORT_INDEX] = new PortVideo; 68 if (this->ports[INPORT_INDEX] == NULL) { 69 return OMX_ErrorInsufficientResources; 70 } 71 72 PortVideo *port = static_cast<PortVideo *>(this->ports[INPORT_INDEX]); 73 74 // OMX_PARAM_PORTDEFINITIONTYPE 75 OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionInput; 76 memset(¶mPortDefinitionInput, 0, sizeof(paramPortDefinitionInput)); 77 SetTypeHeader(¶mPortDefinitionInput, sizeof(paramPortDefinitionInput)); 78 paramPortDefinitionInput.nPortIndex = INPORT_INDEX; 79 paramPortDefinitionInput.eDir = OMX_DirInput; 80 paramPortDefinitionInput.nBufferCountActual = INPORT_ACTUAL_BUFFER_COUNT; 81 paramPortDefinitionInput.nBufferCountMin = INPORT_MIN_BUFFER_COUNT; 82 paramPortDefinitionInput.nBufferSize = INPORT_BUFFER_SIZE; 83 paramPortDefinitionInput.bEnabled = OMX_TRUE; 84 paramPortDefinitionInput.bPopulated = OMX_FALSE; 85 paramPortDefinitionInput.eDomain = OMX_PortDomainVideo; 86 paramPortDefinitionInput.format.video.cMIMEType = NULL; // to be overridden 87 paramPortDefinitionInput.format.video.pNativeRender = NULL; 88 paramPortDefinitionInput.format.video.nFrameWidth = 176; 89 paramPortDefinitionInput.format.video.nFrameHeight = 144; 90 paramPortDefinitionInput.format.video.nStride = 0; 91 paramPortDefinitionInput.format.video.nSliceHeight = 0; 92 paramPortDefinitionInput.format.video.nBitrate = 64000; 93 paramPortDefinitionInput.format.video.xFramerate = 15 << 16; 94 // TODO: check if we need to set bFlagErrorConcealment to OMX_TRUE 95 paramPortDefinitionInput.format.video.bFlagErrorConcealment = OMX_FALSE; 96 paramPortDefinitionInput.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; // to be overridden 97 paramPortDefinitionInput.format.video.eColorFormat = OMX_COLOR_FormatUnused; 98 paramPortDefinitionInput.format.video.pNativeWindow = NULL; 99 paramPortDefinitionInput.bBuffersContiguous = OMX_FALSE; 100 paramPortDefinitionInput.nBufferAlignment = 0; 101 102 // Derived class must implement this interface and override any field if needed. 103 // eCompressionFormat and and cMIMEType must be overridden 104 InitInputPortFormatSpecific(¶mPortDefinitionInput); 105 106 port->SetPortDefinition(¶mPortDefinitionInput, true); 107 108 // OMX_VIDEO_PARAM_PORTFORMATTYPE 109 OMX_VIDEO_PARAM_PORTFORMATTYPE paramPortFormat; 110 memset(¶mPortFormat, 0, sizeof(paramPortFormat)); 111 SetTypeHeader(¶mPortFormat, sizeof(paramPortFormat)); 112 paramPortFormat.nPortIndex = INPORT_INDEX; 113 paramPortFormat.nIndex = 0; 114 paramPortFormat.eCompressionFormat = paramPortDefinitionInput.format.video.eCompressionFormat; 115 paramPortFormat.eColorFormat = paramPortDefinitionInput.format.video.eColorFormat; 116 paramPortFormat.xFramerate = paramPortDefinitionInput.format.video.xFramerate; 117 118 port->SetPortVideoParam(¶mPortFormat, true); 119 120 return OMX_ErrorNone; 121 } 122 123 124 OMX_ERRORTYPE OMXVideoDecoderBase::InitOutputPort(void) { 125 this->ports[OUTPORT_INDEX] = new PortVideo; 126 if (this->ports[OUTPORT_INDEX] == NULL) { 127 return OMX_ErrorInsufficientResources; 128 } 129 130 PortVideo *port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]); 131 132 // OMX_PARAM_PORTDEFINITIONTYPE 133 OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionOutput; 134 135 memset(¶mPortDefinitionOutput, 0, sizeof(paramPortDefinitionOutput)); 136 SetTypeHeader(¶mPortDefinitionOutput, sizeof(paramPortDefinitionOutput)); 137 138 paramPortDefinitionOutput.nPortIndex = OUTPORT_INDEX; 139 paramPortDefinitionOutput.eDir = OMX_DirOutput; 140 paramPortDefinitionOutput.nBufferCountActual = OUTPORT_ACTUAL_BUFFER_COUNT; 141 paramPortDefinitionOutput.nBufferCountMin = OUTPORT_MIN_BUFFER_COUNT; 142 paramPortDefinitionOutput.nBufferSize = sizeof(VideoRenderBuffer); 143 144 paramPortDefinitionOutput.bEnabled = OMX_TRUE; 145 paramPortDefinitionOutput.bPopulated = OMX_FALSE; 146 paramPortDefinitionOutput.eDomain = OMX_PortDomainVideo; 147 paramPortDefinitionOutput.format.video.cMIMEType = (OMX_STRING)VA_RAW_MIME_TYPE; 148 paramPortDefinitionOutput.format.video.pNativeRender = NULL; 149 paramPortDefinitionOutput.format.video.nFrameWidth = 176; 150 paramPortDefinitionOutput.format.video.nFrameHeight = 144; 151 paramPortDefinitionOutput.format.video.nStride = 176; 152 paramPortDefinitionOutput.format.video.nSliceHeight = 144; 153 paramPortDefinitionOutput.format.video.nBitrate = 64000; 154 paramPortDefinitionOutput.format.video.xFramerate = 15 << 16; 155 paramPortDefinitionOutput.format.video.bFlagErrorConcealment = OMX_FALSE; 156 paramPortDefinitionOutput.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; 157 paramPortDefinitionOutput.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; 158 paramPortDefinitionOutput.format.video.pNativeWindow = NULL; 159 paramPortDefinitionOutput.bBuffersContiguous = OMX_FALSE; 160 paramPortDefinitionOutput.nBufferAlignment = 0; 161 162 // no format specific to initialize output port 163 InitOutputPortFormatSpecific(¶mPortDefinitionOutput); 164 165 port->SetPortDefinition(¶mPortDefinitionOutput, true); 166 167 // OMX_VIDEO_PARAM_PORTFORMATTYPE 168 OMX_VIDEO_PARAM_PORTFORMATTYPE paramPortFormat; 169 SetTypeHeader(¶mPortFormat, sizeof(paramPortFormat)); 170 paramPortFormat.nPortIndex = OUTPORT_INDEX; 171 paramPortFormat.nIndex = 0; 172 paramPortFormat.eCompressionFormat = paramPortDefinitionOutput.format.video.eCompressionFormat; 173 paramPortFormat.eColorFormat = paramPortDefinitionOutput.format.video.eColorFormat; 174 paramPortFormat.xFramerate = paramPortDefinitionOutput.format.video.xFramerate; 175 176 port->SetPortVideoParam(¶mPortFormat, true); 177 178 return OMX_ErrorNone; 179 } 180 181 OMX_ERRORTYPE OMXVideoDecoderBase::InitOutputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *) { 182 // no format specific to initialize output port 183 return OMX_ErrorNone; 184 } 185 186 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorInit(void) { 187 OMX_ERRORTYPE ret; 188 ret = OMXComponentCodecBase::ProcessorInit(); 189 CHECK_RETURN_VALUE("OMXComponentCodecBase::ProcessorInit"); 190 191 if (mVideoDecoder == NULL) { 192 LOGE("ProcessorInit: Video decoder is not created."); 193 return OMX_ErrorDynamicResourcesUnavailable; 194 } 195 196 VideoConfigBuffer configBuffer; 197 ret = PrepareConfigBuffer(&configBuffer); 198 CHECK_RETURN_VALUE("PrepareConfigBuffer"); 199 200 //pthread_mutex_lock(&mSerializationLock); 201 Decode_Status status = mVideoDecoder->start(&configBuffer); 202 //pthread_mutex_unlock(&mSerializationLock); 203 204 if (status != DECODE_SUCCESS) { 205 return TranslateDecodeStatus(status); 206 } 207 208 return OMX_ErrorNone; 209 } 210 211 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorReset(void) { 212 OMX_ERRORTYPE ret; 213 VideoConfigBuffer configBuffer; 214 // reset the configbuffer and set it to mix 215 ret = PrepareConfigBuffer(&configBuffer); 216 CHECK_RETURN_VALUE("PrepareConfigBuffer"); 217 mVideoDecoder->reset(&configBuffer); 218 return OMX_ErrorNone; 219 } 220 221 222 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorDeinit(void) { 223 if (mWorkingMode != GRAPHICBUFFER_MODE) { 224 if (mVideoDecoder == NULL) { 225 LOGE("ProcessorDeinit: Video decoder is not created."); 226 return OMX_ErrorDynamicResourcesUnavailable; 227 } 228 mVideoDecoder->stop(); 229 } 230 mOMXBufferHeaderTypePtrNum = 0; 231 memset(&mGraphicBufferParam, 0, sizeof(mGraphicBufferParam)); 232 mRotationDegrees = 0; 233 #ifdef TARGET_HAS_ISV 234 mVppBufferNum = 0; 235 #endif 236 return OMXComponentCodecBase::ProcessorDeinit(); 237 } 238 239 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorStart(void) { 240 return OMXComponentCodecBase::ProcessorStart(); 241 } 242 243 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorStop(void) { 244 // There is no need to return all retained buffers as we don't accumulate buffer 245 //this->ports[INPORT_INDEX]->ReturnAllRetainedBuffers(); 246 247 // TODO: this is new code 248 ProcessorFlush(OMX_ALL); 249 if (mWorkingMode == GRAPHICBUFFER_MODE) { 250 // for GRAPHICBUFFER_MODE mode, va_destroySurface need to lock the graphicbuffer, 251 // Make sure va_destroySurface is called(ExecutingToIdle) before graphicbuffer is freed(IdleToLoaded). 252 if (mVideoDecoder == NULL) { 253 LOGE("ProcessorStop: Video decoder is not created."); 254 return OMX_ErrorDynamicResourcesUnavailable; 255 } 256 mVideoDecoder->stop(); 257 } 258 return OMXComponentCodecBase::ProcessorStop(); 259 } 260 261 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorPause(void) { 262 return OMXComponentCodecBase::ProcessorPause(); 263 } 264 265 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorResume(void) { 266 return OMXComponentCodecBase::ProcessorResume(); 267 } 268 269 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorFlush(OMX_U32 portIndex) { 270 LOGI("Flushing port# %u.", portIndex); 271 if (mVideoDecoder == NULL) { 272 LOGE("ProcessorFlush: Video decoder is not created."); 273 return OMX_ErrorDynamicResourcesUnavailable; 274 } 275 276 // Portbase has returned all retained buffers. 277 if (portIndex == INPORT_INDEX || portIndex == OMX_ALL) { 278 //pthread_mutex_lock(&mSerializationLock); 279 LOGW("Flushing video pipeline."); 280 mVideoDecoder->flush(); 281 //pthread_mutex_unlock(&mSerializationLock); 282 } 283 // TODO: do we need to flush output port? 284 return OMX_ErrorNone; 285 } 286 287 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorPreFreeBuffer(OMX_U32 nPortIndex, OMX_BUFFERHEADERTYPE * pBuffer) { 288 if (mWorkingMode == GRAPHICBUFFER_MODE) 289 return OMX_ErrorNone; 290 291 if (nPortIndex == OUTPORT_INDEX && pBuffer->pPlatformPrivate) { 292 VideoRenderBuffer *p = (VideoRenderBuffer *)pBuffer->pPlatformPrivate; 293 p->renderDone = true; 294 pBuffer->pPlatformPrivate = NULL; 295 } 296 return OMX_ErrorNone; 297 } 298 299 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorPreFillBuffer(OMX_BUFFERHEADERTYPE* buffer) { 300 if (mWorkingMode == GRAPHICBUFFER_MODE && buffer->nOutputPortIndex == OUTPORT_INDEX){ 301 Decode_Status status; 302 if(mVideoDecoder == NULL){ 303 LOGW("ProcessorPreFillBuffer: Video decoder is not created"); 304 return OMX_ErrorDynamicResourcesUnavailable; 305 } 306 307 if (mAPMode == METADATA_MODE) { 308 bool found = false; 309 if (mOMXBufferHeaderTypePtrNum < mMetaDataBuffersNum) { 310 for (uint32_t i = 0; i < mOMXBufferHeaderTypePtrNum; i++) { 311 if (mOMXBufferHeaderTypePtrArray[i] == buffer) { 312 found = true; 313 break; 314 } 315 } 316 if (!found) { 317 mOMXBufferHeaderTypePtrArray[mOMXBufferHeaderTypePtrNum] = buffer; 318 mOMXBufferHeaderTypePtrNum++; 319 } 320 } 321 322 VideoDecoderOutputMetaData *metadata = (VideoDecoderOutputMetaData *)(buffer->pBuffer); 323 status = mVideoDecoder->signalRenderDone((void *)(metadata->pHandle), !found); 324 } else { 325 status = mVideoDecoder->signalRenderDone(buffer->pBuffer); 326 } 327 328 if (status != DECODE_SUCCESS) { 329 LOGW("ProcessorPreFillBuffer:: signalRenderDone return error"); 330 return TranslateDecodeStatus(status); 331 } 332 } else if (buffer->pPlatformPrivate && buffer->nOutputPortIndex == OUTPORT_INDEX){ 333 VideoRenderBuffer *p = (VideoRenderBuffer *)buffer->pPlatformPrivate; 334 p->renderDone = true; 335 buffer->pPlatformPrivate = NULL; 336 } 337 return OMX_ErrorNone; 338 } 339 340 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorProcess( 341 OMX_BUFFERHEADERTYPE ***pBuffers, 342 buffer_retain_t *retains, 343 OMX_U32) { 344 345 OMX_ERRORTYPE ret; 346 Decode_Status status; 347 OMX_BOOL isResolutionChange = OMX_FALSE; 348 // fill render buffer without draining decoder output queue 349 ret = FillRenderBuffer(pBuffers[OUTPORT_INDEX], &retains[OUTPORT_INDEX], 0, &isResolutionChange); 350 if (ret == OMX_ErrorNone) { 351 retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 352 if (isResolutionChange) { 353 HandleFormatChange(); 354 } 355 356 if (mFlushMode) { 357 LOGI("in mFlushMode, do HandleFormatChange."); 358 HandleFormatChange(); 359 } else { 360 // Actually, if mAPMode is set, mWorkingMode should be GRAPHICBUFFER_MODE. 361 if (((mAPMode == METADATA_MODE) && (mWorkingMode == GRAPHICBUFFER_MODE)) && mFormatChanged) { 362 if (((*pBuffers[OUTPORT_INDEX])->nFlags & OMX_BUFFERFLAG_EOS) || (mVideoDecoder->getOutputQueueLength() == 0)) { 363 // Format changed, set mFlushMode, clear eos 364 mFlushMode = true; 365 mFormatChanged = false; 366 (*pBuffers[OUTPORT_INDEX])->nFlags &= ~OMX_BUFFERFLAG_EOS; 367 } 368 } 369 } 370 371 // TODO: continue decoding 372 return ret; 373 } else if (ret != OMX_ErrorNotReady) { 374 return ret; 375 } 376 377 VideoDecodeBuffer decodeBuffer; 378 // PrepareDecodeBuffer will set retain to either BUFFER_RETAIN_GETAGAIN or BUFFER_RETAIN_NOT_RETAIN 379 ret = PrepareDecodeBuffer(*pBuffers[INPORT_INDEX], &retains[INPORT_INDEX], &decodeBuffer); 380 if (ret == OMX_ErrorNotReady) { 381 retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 382 return OMX_ErrorNone; 383 } else if (ret != OMX_ErrorNone) { 384 return ret; 385 } 386 387 if (decodeBuffer.size != 0) { 388 //pthread_mutex_lock(&mSerializationLock); 389 status = mVideoDecoder->decode(&decodeBuffer); 390 //pthread_mutex_unlock(&mSerializationLock); 391 392 if (status == DECODE_FORMAT_CHANGE) { 393 if ((mAPMode == METADATA_MODE) && (mWorkingMode == GRAPHICBUFFER_MODE)) { 394 mFormatChanged = true; 395 retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 396 } else { 397 ret = HandleFormatChange(); 398 CHECK_RETURN_VALUE("HandleFormatChange"); 399 ((*pBuffers[OUTPORT_INDEX]))->nFilledLen = 0; 400 retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 401 retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 402 // real dynamic resolution change will be handled later 403 // Here is just a temporary workaround 404 // don't use the output buffer if format is changed. 405 return OMX_ErrorNone; 406 } 407 } else if (status == DECODE_NO_CONFIG) { 408 LOGW("Decoder returns DECODE_NO_CONFIG."); 409 retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 410 return OMX_ErrorNone; 411 } else if (status == DECODE_NO_REFERENCE) { 412 LOGW("Decoder returns DECODE_NO_REFERENCE."); 413 //retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 414 //return OMX_ErrorNone; 415 } else if (status == DECODE_MULTIPLE_FRAME){ 416 if (decodeBuffer.ext != NULL && decodeBuffer.ext->extType == PACKED_FRAME_TYPE && decodeBuffer.ext->extData != NULL) { 417 PackedFrameData* nextFrame = (PackedFrameData*)decodeBuffer.ext->extData; 418 (*pBuffers[INPORT_INDEX])->nOffset += nextFrame->offSet; 419 (*pBuffers[INPORT_INDEX])->nTimeStamp = nextFrame->timestamp; 420 (*pBuffers[INPORT_INDEX])->nFilledLen -= nextFrame->offSet; 421 retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 422 LOGW("Find multiple frames in a buffer, next frame offset = %d, timestamp = %lld", (*pBuffers[INPORT_INDEX])->nOffset, (*pBuffers[INPORT_INDEX])->nTimeStamp); 423 } 424 } 425 else if (status != DECODE_SUCCESS && status != DECODE_FRAME_DROPPED) { 426 if (checkFatalDecoderError(status)) { 427 return TranslateDecodeStatus(status); 428 } else { 429 // For decoder errors that could be omitted, not throw error and continue to decode. 430 TranslateDecodeStatus(status); 431 432 ((*pBuffers[OUTPORT_INDEX]))->nFilledLen = 0; 433 434 // Do not return, and try to drain the output queue 435 // retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 436 // return OMX_ErrorNone; 437 } 438 } 439 } 440 // drain the decoder output queue when in EOS state and fill the render buffer 441 ret = FillRenderBuffer(pBuffers[OUTPORT_INDEX], &retains[OUTPORT_INDEX], 442 ((*pBuffers[INPORT_INDEX]))->nFlags,&isResolutionChange); 443 444 if (isResolutionChange) { 445 HandleFormatChange(); 446 } 447 448 if (mFlushMode) { 449 LOGI("in mFlushMode, do HandleFormatChange."); 450 HandleFormatChange(); 451 } else { 452 if (((mAPMode == METADATA_MODE) && (mWorkingMode == GRAPHICBUFFER_MODE)) && mFormatChanged) { 453 if (((*pBuffers[OUTPORT_INDEX])->nFlags & OMX_BUFFERFLAG_EOS) || (mVideoDecoder->getOutputQueueLength() == 0)) { 454 // Format changed, set mFlushMode, clear eos. 455 mFlushMode = true; 456 mFormatChanged = false; 457 (*pBuffers[OUTPORT_INDEX])->nFlags &= ~OMX_BUFFERFLAG_EOS; 458 } 459 } 460 } 461 462 bool inputEoS = ((*pBuffers[INPORT_INDEX])->nFlags & OMX_BUFFERFLAG_EOS); 463 bool outputEoS = ((*pBuffers[OUTPORT_INDEX])->nFlags & OMX_BUFFERFLAG_EOS); 464 // if output port is not eos, retain the input buffer until all the output buffers are drained. 465 if (inputEoS && !outputEoS) { 466 retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 467 // the input buffer is retained for draining purpose. Set nFilledLen to 0 so buffer will not be decoded again. 468 (*pBuffers[INPORT_INDEX])->nFilledLen = 0; 469 } 470 471 if (ret == OMX_ErrorNotReady) { 472 retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 473 ret = OMX_ErrorNone; 474 } 475 476 return ret; 477 } 478 479 bool OMXVideoDecoderBase::IsAllBufferAvailable(void) { 480 bool b = ComponentBase::IsAllBufferAvailable(); 481 if (b == false) { 482 return false; 483 } 484 485 PortVideo *port = NULL; 486 port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]); 487 const OMX_PARAM_PORTDEFINITIONTYPE* port_def = port->GetPortDefinition(); 488 // if output port is disabled, retain the input buffer 489 if (!port_def->bEnabled) { 490 return false; 491 } 492 493 if (mVideoDecoder) { 494 return mVideoDecoder->checkBufferAvail(); 495 } 496 return false; 497 } 498 499 OMX_ERRORTYPE OMXVideoDecoderBase::PrepareConfigBuffer(VideoConfigBuffer *p) { 500 // default config buffer preparation 501 memset(p, 0, sizeof(VideoConfigBuffer)); 502 503 const OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput = this->ports[INPORT_INDEX]->GetPortDefinition(); 504 if (paramPortDefinitionInput == NULL) { 505 return OMX_ErrorBadParameter; 506 } 507 508 if (mWorkingMode == GRAPHICBUFFER_MODE) { 509 if (mAPMode == METADATA_MODE) { 510 const OMX_PARAM_PORTDEFINITIONTYPE *def_output = this->ports[OUTPORT_INDEX]->GetPortDefinition(); 511 if (def_output == NULL) { 512 return OMX_ErrorBadParameter; 513 } 514 515 mMetaDataBuffersNum = def_output->nBufferCountActual; 516 mOMXBufferHeaderTypePtrNum = 0; 517 518 mGraphicBufferParam.graphicBufferColorFormat = def_output->format.video.eColorFormat; 519 mGraphicBufferParam.graphicBufferHStride = getStride(def_output->format.video.nFrameWidth); 520 mGraphicBufferParam.graphicBufferVStride = (def_output->format.video.nFrameHeight + 0x1f) & ~0x1f; 521 mGraphicBufferParam.graphicBufferWidth = def_output->format.video.nFrameWidth; 522 mGraphicBufferParam.graphicBufferHeight = def_output->format.video.nFrameHeight; 523 524 p->surfaceNumber = mMetaDataBuffersNum; 525 for (int i = 0; i < MAX_GRAPHIC_BUFFER_NUM; i++) { 526 p->graphicBufferHandler[i] = NULL; 527 } 528 p->flag |= WANT_STORE_META_DATA; 529 } else { 530 p->surfaceNumber = mOMXBufferHeaderTypePtrNum; 531 for (uint32_t i = 0; i < mOMXBufferHeaderTypePtrNum; i++){ 532 OMX_BUFFERHEADERTYPE *buffer_hdr = mOMXBufferHeaderTypePtrArray[i]; 533 p->graphicBufferHandler[i] = buffer_hdr->pBuffer; 534 LOGV("PrepareConfigBuffer bufferid = %p, handle = %p", buffer_hdr, buffer_hdr->pBuffer); 535 } 536 } 537 p->flag |= USE_NATIVE_GRAPHIC_BUFFER; 538 p->graphicBufferHStride = mGraphicBufferParam.graphicBufferHStride; 539 p->graphicBufferVStride = mGraphicBufferParam.graphicBufferVStride; 540 p->graphicBufferWidth = mGraphicBufferParam.graphicBufferWidth; 541 p->graphicBufferHeight = mGraphicBufferParam.graphicBufferHeight; 542 p->graphicBufferColorFormat = mGraphicBufferParam.graphicBufferColorFormat; 543 if (p->graphicBufferColorFormat == OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled 544 #ifdef USE_GEN_HW 545 || p->graphicBufferColorFormat == HAL_PIXEL_FORMAT_NV12_X_TILED_INTEL 546 #endif 547 ) 548 p->flag |= USE_TILING_MEMORY; 549 550 if (mEnableAdaptivePlayback) 551 p->flag |= WANT_ADAPTIVE_PLAYBACK; 552 553 PortVideo *port = NULL; 554 port = static_cast<PortVideo *>(this->ports[INPORT_INDEX]); 555 OMX_PARAM_PORTDEFINITIONTYPE port_def; 556 memcpy(&port_def, port->GetPortDefinition(), sizeof(port_def)); 557 558 if (port_def.format.video.pNativeWindow != NULL) { 559 p->nativeWindow = port_def.format.video.pNativeWindow; 560 LOGD("NativeWindow = %p", p->nativeWindow); 561 } 562 563 } 564 565 p->rotationDegrees = mRotationDegrees; 566 #ifdef TARGET_HAS_ISV 567 p->vppBufferNum = mVppBufferNum; 568 #endif 569 p->width = paramPortDefinitionInput->format.video.nFrameWidth; 570 p->height = paramPortDefinitionInput->format.video.nFrameHeight; 571 572 return OMX_ErrorNone; 573 } 574 575 OMX_ERRORTYPE OMXVideoDecoderBase::PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE *buffer, buffer_retain_t *retain, VideoDecodeBuffer *p) { 576 // default decode buffer preparation 577 memset(p, 0, sizeof(VideoDecodeBuffer)); 578 if (buffer->nFilledLen == 0) { 579 LOGW("Len of filled data to decode is 0."); 580 return OMX_ErrorNone; //OMX_ErrorBadParameter; 581 } 582 583 if (buffer->pBuffer == NULL) { 584 LOGE("Buffer to decode is empty."); 585 return OMX_ErrorBadParameter; 586 } 587 588 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { 589 LOGI("Buffer has OMX_BUFFERFLAG_CODECCONFIG flag."); 590 } 591 592 if (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) { 593 // TODO: Handle OMX_BUFFERFLAG_DECODEONLY : drop the decoded frame without rendering it. 594 LOGW("Buffer has OMX_BUFFERFLAG_DECODEONLY flag."); 595 } 596 597 p->data = buffer->pBuffer + buffer->nOffset; 598 p->size = buffer->nFilledLen; 599 p->timeStamp = buffer->nTimeStamp; 600 if (buffer->nFlags & (OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS)) { 601 // TODO: OMX_BUFFERFLAG_ENDOFFRAME can be used to indicate end of a NAL unit. 602 // setting this flag may cause corruption if buffer does not contain end-of-frame data. 603 p->flag = HAS_COMPLETE_FRAME; 604 } 605 606 if (buffer->nFlags & OMX_BUFFERFLAG_SYNCFRAME) { 607 p->flag |= IS_SYNC_FRAME; 608 } 609 610 if (buffer->pInputPortPrivate) { 611 uint32_t degree = 0; 612 memcpy ((void *) °ree, buffer->pInputPortPrivate, sizeof(uint32_t)); 613 p->rotationDegrees = degree; 614 LOGV("rotationDegrees = %d", p->rotationDegrees); 615 } else { 616 p->rotationDegrees = mRotationDegrees; 617 } 618 619 *retain= BUFFER_RETAIN_NOT_RETAIN; 620 return OMX_ErrorNone; 621 } 622 623 OMX_ERRORTYPE OMXVideoDecoderBase::PrepareDecodeNativeHandleBuffer(OMX_BUFFERHEADERTYPE *buffer, buffer_retain_t *retain, VideoDecodeBuffer *p) { 624 // default decode buffer preparation 625 626 memset(p, 0, sizeof(VideoDecodeBuffer)); 627 if (buffer->nFilledLen == 0) { 628 LOGW("Len of filled data to decode is 0."); 629 return OMX_ErrorNone; //OMX_ErrorBadParameter; 630 } 631 632 if (buffer->pBuffer == NULL) { 633 LOGE("Buffer to decode is empty."); 634 return OMX_ErrorBadParameter; 635 } 636 637 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { 638 LOGI("Buffer has OMX_BUFFERFLAG_CODECCONFIG flag."); 639 } 640 641 if (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) { 642 // TODO: Handle OMX_BUFFERFLAG_DECODEONLY : drop the decoded frame without rendering it. 643 LOGW("Buffer has OMX_BUFFERFLAG_DECODEONLY flag."); 644 } 645 //Get data pointer from native_handle 646 native_handle_t *native_handle = (native_handle_t *)buffer->pBuffer; 647 ProtectedDataBuffer *dataBuffer = (ProtectedDataBuffer *) native_handle->data[1]; 648 p->data = dataBuffer->data + buffer->nOffset; 649 650 651 652 p->size = buffer->nFilledLen; 653 p->timeStamp = buffer->nTimeStamp; 654 if (buffer->nFlags & (OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS)) { 655 // TODO: OMX_BUFFERFLAG_ENDOFFRAME can be used to indicate end of a NAL unit. 656 // setting this flag may cause corruption if buffer does not contain end-of-frame data. 657 p->flag = HAS_COMPLETE_FRAME; 658 } 659 660 if (buffer->nFlags & OMX_BUFFERFLAG_SYNCFRAME) { 661 p->flag |= IS_SYNC_FRAME; 662 } 663 664 if (buffer->pInputPortPrivate) { 665 uint32_t degree = 0; 666 memcpy ((void *) °ree, buffer->pInputPortPrivate, sizeof(uint32_t)); 667 p->rotationDegrees = degree; 668 LOGV("rotationDegrees = %d", p->rotationDegrees); 669 } else { 670 p->rotationDegrees = mRotationDegrees; 671 } 672 673 *retain= BUFFER_RETAIN_NOT_RETAIN; 674 return OMX_ErrorNone; 675 } 676 677 678 OMX_ERRORTYPE OMXVideoDecoderBase::FillRenderBuffer(OMX_BUFFERHEADERTYPE **pBuffer, buffer_retain_t *retain, OMX_U32 inportBufferFlags, OMX_BOOL *isResolutionChange) { 679 OMX_BUFFERHEADERTYPE *buffer = *pBuffer; 680 OMX_BUFFERHEADERTYPE *buffer_orign = buffer; 681 VideoErrorBuffer *ErrBufPtr = NULL; 682 683 if (mWorkingMode != GRAPHICBUFFER_MODE && buffer->pPlatformPrivate) { 684 VideoRenderBuffer *p = (VideoRenderBuffer *)buffer->pPlatformPrivate; 685 p->renderDone = true; 686 buffer->pPlatformPrivate = NULL; 687 } 688 689 if (mWorkingMode == GRAPHICBUFFER_MODE && mErrorReportEnabled) { 690 if (buffer->pOutputPortPrivate == NULL) 691 LOGE("The App doesn't provide the output buffer for error reporting"); 692 else 693 ErrBufPtr = (VideoErrorBuffer *)buffer->pOutputPortPrivate; 694 } 695 696 bool draining = (inportBufferFlags & OMX_BUFFERFLAG_EOS); 697 //pthread_mutex_lock(&mSerializationLock); 698 const VideoRenderBuffer *renderBuffer = NULL; 699 //pthread_mutex_unlock(&mSerializationLock); 700 701 // in mFlushMode, provide empty buffer. 702 if (mFlushMode) { 703 buffer->nFilledLen = 0; 704 return OMX_ErrorNone; 705 } 706 707 if (((mAPMode == METADATA_MODE) && (mWorkingMode == GRAPHICBUFFER_MODE)) && mFormatChanged) { 708 renderBuffer = mVideoDecoder->getOutput(true, ErrBufPtr); 709 } else { 710 renderBuffer = mVideoDecoder->getOutput(draining, ErrBufPtr); 711 } 712 if (renderBuffer == NULL) { 713 buffer->nFilledLen = 0; 714 if (draining) { 715 LOGI("output EOS received"); 716 buffer->nFlags = OMX_BUFFERFLAG_EOS; 717 return OMX_ErrorNone; 718 } 719 return OMX_ErrorNotReady; 720 } 721 722 if (mWorkingMode == GRAPHICBUFFER_MODE) { 723 buffer = *pBuffer = mOMXBufferHeaderTypePtrArray[renderBuffer->graphicBufferIndex]; 724 } 725 726 buffer->nFlags = OMX_BUFFERFLAG_ENDOFFRAME; 727 #ifdef DEINTERLACE_EXT 728 if (renderBuffer->scanFormat & (VA_TOP_FIELD | VA_BOTTOM_FIELD)) 729 buffer->nFlags |= OMX_BUFFERFLAG_TFF; 730 #endif 731 buffer->nTimeStamp = renderBuffer->timeStamp; 732 733 if (renderBuffer->flag & IS_EOS) { 734 buffer->nFlags |= OMX_BUFFERFLAG_EOS; 735 } 736 *isResolutionChange = (renderBuffer->flag & IS_RESOLUTION_CHANGE)? OMX_TRUE: OMX_FALSE; 737 738 if (mWorkingMode == GRAPHICBUFFER_MODE) { 739 if (buffer_orign != buffer) { 740 VideoErrorBuffer *ErrBufOutPtr = NULL; 741 ErrBufOutPtr = (VideoErrorBuffer *)buffer->pOutputPortPrivate; 742 if (ErrBufPtr && ErrBufOutPtr) { 743 memcpy(ErrBufOutPtr, ErrBufPtr, sizeof(VideoErrorBuffer)); 744 memset(ErrBufPtr, 0, sizeof(VideoErrorBuffer)); 745 } 746 *retain = BUFFER_RETAIN_OVERRIDDEN; 747 } 748 buffer->nFilledLen = sizeof(OMX_U8*); 749 } else { 750 uint32_t size = 0; 751 Decode_Status status = mVideoDecoder->getRawDataFromSurface(const_cast<VideoRenderBuffer *>(renderBuffer), buffer->pBuffer + buffer->nOffset, &size, false); 752 if (status != DECODE_SUCCESS) { 753 return TranslateDecodeStatus(status); 754 } 755 buffer->nFilledLen = size; 756 buffer->pPlatformPrivate = (void *)renderBuffer; 757 } 758 759 return OMX_ErrorNone; 760 } 761 762 OMX_ERRORTYPE OMXVideoDecoderBase::HandleFormatChange(void) { 763 LOGW("Video format is changed."); 764 //pthread_mutex_lock(&mSerializationLock); 765 const VideoFormatInfo *formatInfo = mVideoDecoder->getFormatInfo(); 766 //pthread_mutex_unlock(&mSerializationLock); 767 768 // Sync port definition as it may change. 769 OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionInput, paramPortDefinitionOutput; 770 771 memcpy(¶mPortDefinitionInput, 772 this->ports[INPORT_INDEX]->GetPortDefinition(), 773 sizeof(paramPortDefinitionInput)); 774 775 memcpy(¶mPortDefinitionOutput, 776 this->ports[OUTPORT_INDEX]->GetPortDefinition(), 777 sizeof(paramPortDefinitionOutput)); 778 779 uint32_t width = formatInfo->width; 780 uint32_t height = formatInfo->height; 781 uint32_t stride = formatInfo->width; 782 uint32_t sliceHeight = formatInfo->height; 783 784 uint32_t widthCropped = formatInfo->width - formatInfo->cropLeft - formatInfo->cropRight; 785 uint32_t heightCropped = formatInfo->height - formatInfo->cropTop - formatInfo->cropBottom; 786 if (strcasecmp(formatInfo->mimeType,"video/avc") == 0 || 787 strcasecmp(formatInfo->mimeType,"video/avc-secure") == 0 || 788 strcasecmp(formatInfo->mimeType,"video/h264") == 0) { 789 heightCropped = formatInfo->height; 790 widthCropped = formatInfo->width; 791 } 792 uint32_t strideCropped = widthCropped; 793 uint32_t sliceHeightCropped = heightCropped; 794 int force_realloc = 0; 795 bool isVP8 = false; 796 797 if (mAPMode == METADATA_MODE && mWorkingMode == GRAPHICBUFFER_MODE) { 798 #ifdef TARGET_HAS_ISV 799 if (paramPortDefinitionOutput.nBufferCountActual - mVppBufferNum < formatInfo->actualBufferNeeded) { 800 #else 801 if (paramPortDefinitionOutput.nBufferCountActual < formatInfo->actualBufferNeeded) { 802 #endif 803 paramPortDefinitionOutput.nBufferCountActual = mNativeBufferCount = formatInfo->actualBufferNeeded; 804 paramPortDefinitionOutput.nBufferCountMin = formatInfo->actualBufferNeeded - 4; 805 } 806 // input port 807 paramPortDefinitionInput.format.video.nFrameWidth = width; 808 paramPortDefinitionInput.format.video.nFrameHeight = height; 809 paramPortDefinitionInput.format.video.nStride = stride; 810 paramPortDefinitionInput.format.video.nSliceHeight = sliceHeight; 811 // output port 812 paramPortDefinitionOutput.format.video.nFrameWidth = width; 813 paramPortDefinitionOutput.format.video.nFrameHeight = height; 814 paramPortDefinitionOutput.format.video.eColorFormat = GetOutputColorFormat(paramPortDefinitionOutput.format.video.nFrameWidth); 815 paramPortDefinitionOutput.format.video.nStride = stride; 816 paramPortDefinitionOutput.format.video.nSliceHeight = sliceHeight; 817 818 paramPortDefinitionOutput.bEnabled = (OMX_BOOL)false; 819 mOMXBufferHeaderTypePtrNum = 0; 820 memset(&mGraphicBufferParam, 0, sizeof(mGraphicBufferParam)); 821 mMetaDataBuffersNum = 0; 822 823 this->ports[INPORT_INDEX]->SetPortDefinition(¶mPortDefinitionInput, true); 824 this->ports[OUTPORT_INDEX]->SetPortDefinition(¶mPortDefinitionOutput, true); 825 826 ProcessorFlush(INPORT_INDEX); 827 828 mVideoDecoder->freeSurfaceBuffers(); 829 830 this->ports[OUTPORT_INDEX]->ReportPortSettingsChanged(); 831 832 mFlushMode = false; 833 return OMX_ErrorNone; 834 } 835 836 #ifdef TARGET_HAS_ISV 837 LOGI("============== mVppBufferNum = %d\n", mVppBufferNum); 838 if (paramPortDefinitionOutput.nBufferCountActual - mVppBufferNum < formatInfo->actualBufferNeeded) { 839 #else 840 if (paramPortDefinitionOutput.nBufferCountActual < formatInfo->actualBufferNeeded) { 841 #endif 842 if (mWorkingMode == GRAPHICBUFFER_MODE) { 843 LOGV("output port buffer number is not enough: %d to %d", 844 paramPortDefinitionOutput.nBufferCountActual, 845 formatInfo->actualBufferNeeded); 846 paramPortDefinitionOutput.nBufferCountActual = mNativeBufferCount = formatInfo->actualBufferNeeded; 847 paramPortDefinitionOutput.nBufferCountMin = mNativeBufferCount; 848 force_realloc = 1; 849 } 850 } 851 852 LOGV("Original size = %u x %u, new size = %d x %d, cropped size = %d x %d", 853 paramPortDefinitionInput.format.video.nFrameWidth, 854 paramPortDefinitionInput.format.video.nFrameHeight, 855 width, height, widthCropped, heightCropped); 856 857 if (paramPortDefinitionInput.format.video.eCompressionFormat == OMX_VIDEO_CodingVP8) { 858 isVP8 = true; 859 } 860 861 if (!force_realloc && 862 widthCropped == paramPortDefinitionOutput.format.video.nFrameWidth && 863 heightCropped == paramPortDefinitionOutput.format.video.nFrameHeight) { 864 if (mWorkingMode == RAWDATA_MODE) { 865 LOGW("Change of portsetting is not reported as size is not changed."); 866 return OMX_ErrorNone; 867 } 868 } 869 870 paramPortDefinitionInput.format.video.nFrameWidth = width; 871 paramPortDefinitionInput.format.video.nFrameHeight = height; 872 paramPortDefinitionInput.format.video.nStride = stride; 873 paramPortDefinitionInput.format.video.nSliceHeight = sliceHeight; 874 875 if (mWorkingMode == RAWDATA_MODE) { 876 paramPortDefinitionOutput.format.video.nFrameWidth = widthCropped; 877 paramPortDefinitionOutput.format.video.nFrameHeight = heightCropped; 878 paramPortDefinitionOutput.format.video.nStride = strideCropped; 879 paramPortDefinitionOutput.format.video.nSliceHeight = sliceHeightCropped; 880 } else if (mWorkingMode == GRAPHICBUFFER_MODE) { 881 // when the width and height ES parse are not larger than allocated graphic buffer in outport, 882 // there is no need to reallocate graphic buffer,just report the crop info to omx client 883 if (!force_realloc && width <= formatInfo->surfaceWidth && height <= formatInfo->surfaceHeight) { 884 this->ports[INPORT_INDEX]->SetPortDefinition(¶mPortDefinitionInput, true); 885 this->ports[OUTPORT_INDEX]->ReportOutputCrop(); 886 return OMX_ErrorNone; 887 } 888 889 if (isVP8 || width > formatInfo->surfaceWidth || height > formatInfo->surfaceHeight) { 890 // update the real decoded resolution to outport instead of display resolution for graphic buffer reallocation 891 // when the width and height parsed from ES are larger than allocated graphic buffer in outport, 892 paramPortDefinitionOutput.format.video.nFrameWidth = width; 893 paramPortDefinitionOutput.format.video.nFrameHeight = height; 894 paramPortDefinitionOutput.format.video.eColorFormat = GetOutputColorFormat( 895 paramPortDefinitionOutput.format.video.nFrameWidth); 896 paramPortDefinitionOutput.format.video.nStride = stride; 897 paramPortDefinitionOutput.format.video.nSliceHeight = sliceHeight; 898 } 899 } 900 901 paramPortDefinitionOutput.bEnabled = (OMX_BOOL)false; 902 mOMXBufferHeaderTypePtrNum = 0; 903 memset(&mGraphicBufferParam, 0, sizeof(mGraphicBufferParam)); 904 905 this->ports[INPORT_INDEX]->SetPortDefinition(¶mPortDefinitionInput, true); 906 this->ports[OUTPORT_INDEX]->SetPortDefinition(¶mPortDefinitionOutput, true); 907 908 if (mWorkingMode == GRAPHICBUFFER_MODE) { 909 // Make sure va_destroySurface is called before graphicbuffer is freed in case of port setting changed 910 mVideoDecoder->freeSurfaceBuffers(); 911 912 // Also make sure all the reference frames are flushed 913 ProcessorFlush(INPORT_INDEX); 914 } 915 this->ports[OUTPORT_INDEX]->ReportPortSettingsChanged(); 916 return OMX_ErrorNone; 917 } 918 919 OMX_ERRORTYPE OMXVideoDecoderBase::TranslateDecodeStatus(Decode_Status status) { 920 switch (status) { 921 case DECODE_NEED_RESTART: 922 LOGE("Decoder returned DECODE_NEED_RESTART"); 923 return (OMX_ERRORTYPE)OMX_ErrorIntelVideoNotPermitted; 924 case DECODE_NO_CONFIG: 925 LOGE("Decoder returned DECODE_NO_CONFIG"); 926 return (OMX_ERRORTYPE)OMX_ErrorIntelMissingConfig; 927 case DECODE_NO_SURFACE: 928 LOGE("Decoder returned DECODE_NO_SURFACE"); 929 return OMX_ErrorDynamicResourcesUnavailable; 930 case DECODE_NO_REFERENCE: 931 LOGE("Decoder returned DECODE_NO_REFERENCE"); 932 return OMX_ErrorDynamicResourcesUnavailable; // TO DO 933 case DECODE_NO_PARSER: 934 LOGE("Decoder returned DECODE_NO_PARSER"); 935 return OMX_ErrorDynamicResourcesUnavailable; 936 case DECODE_INVALID_DATA: 937 LOGE("Decoder returned DECODE_INVALID_DATA"); 938 return OMX_ErrorBadParameter; 939 case DECODE_DRIVER_FAIL: 940 LOGE("Decoder returned DECODE_DRIVER_FAIL"); 941 return OMX_ErrorHardware; 942 case DECODE_PARSER_FAIL: 943 LOGE("Decoder returned DECODE_PARSER_FAIL"); 944 return (OMX_ERRORTYPE)OMX_ErrorIntelProcessStream; // OMX_ErrorStreamCorrupt 945 case DECODE_MEMORY_FAIL: 946 LOGE("Decoder returned DECODE_MEMORY_FAIL"); 947 return OMX_ErrorInsufficientResources; 948 case DECODE_FAIL: 949 LOGE("Decoder returned DECODE_FAIL"); 950 return OMX_ErrorUndefined; 951 case DECODE_SUCCESS: 952 return OMX_ErrorNone; 953 case DECODE_FORMAT_CHANGE: 954 LOGW("Decoder returned DECODE_FORMAT_CHANGE"); 955 return OMX_ErrorNone; 956 case DECODE_FRAME_DROPPED: 957 LOGI("Decoder returned DECODE_FRAME_DROPPED"); 958 return OMX_ErrorNone; 959 default: 960 LOGW("Decoder returned unknown error"); 961 return OMX_ErrorUndefined; 962 } 963 } 964 965 OMX_ERRORTYPE OMXVideoDecoderBase::BuildHandlerList(void) { 966 OMXComponentCodecBase::BuildHandlerList(); 967 AddHandler(OMX_IndexParamVideoPortFormat, GetParamVideoPortFormat, SetParamVideoPortFormat); 968 AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtGetNativeBufferUsage), GetNativeBufferUsage, SetNativeBufferUsage); 969 AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtUseNativeBuffer), GetNativeBuffer, SetNativeBuffer); 970 AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtEnableNativeBuffer), GetNativeBufferMode, SetNativeBufferMode); 971 AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtRotationDegrees), GetDecoderRotation, SetDecoderRotation); 972 #ifdef TARGET_HAS_ISV 973 AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtVppBufferNum), GetDecoderVppBufferNum, SetDecoderVppBufferNum); 974 #endif 975 AddHandler(OMX_IndexConfigCommonOutputCrop, GetDecoderOutputCrop, SetDecoderOutputCrop); 976 #ifdef USE_META_DATA 977 AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexStoreMetaDataInBuffers), GetStoreMetaDataMode, SetStoreMetaDataMode); 978 #endif 979 AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtEnableErrorReport), GetErrorReportMode, SetErrorReportMode); 980 AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexConfigPriority), GetCodecPriority, SetCodecPriority); 981 AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexConfigOperatingRate), GetDecoderOperatingRate, SetDecoderOperatingRate); 982 983 return OMX_ErrorNone; 984 } 985 986 OMX_ERRORTYPE OMXVideoDecoderBase::GetParamVideoPortFormat(OMX_PTR pStructure) { 987 OMX_ERRORTYPE ret; 988 OMX_VIDEO_PARAM_PORTFORMATTYPE *p = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pStructure; 989 990 CHECK_TYPE_HEADER(p); 991 CHECK_PORT_INDEX_RANGE(p); 992 CHECK_ENUMERATION_RANGE(p->nIndex, 1); 993 994 PortVideo *port = NULL; 995 port = static_cast<PortVideo *>(this->ports[p->nPortIndex]); 996 memcpy(p, port->GetPortVideoParam(), sizeof(*p)); 997 return OMX_ErrorNone; 998 } 999 1000 OMX_ERRORTYPE OMXVideoDecoderBase::SetParamVideoPortFormat(OMX_PTR pStructure) { 1001 OMX_ERRORTYPE ret; 1002 OMX_VIDEO_PARAM_PORTFORMATTYPE *p = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pStructure; 1003 1004 CHECK_TYPE_HEADER(p); 1005 CHECK_PORT_INDEX_RANGE(p); 1006 CHECK_SET_PARAM_STATE(); 1007 1008 // TODO: do we need to check if port is enabled? 1009 PortVideo *port = NULL; 1010 port = static_cast<PortVideo *>(this->ports[p->nPortIndex]); 1011 port->SetPortVideoParam(p, false); 1012 return OMX_ErrorNone; 1013 } 1014 1015 OMX_ERRORTYPE OMXVideoDecoderBase::GetNativeBufferUsageSpecific(OMX_PTR pStructure) { 1016 OMX_ERRORTYPE ret; 1017 GetAndroidNativeBufferUsageParams *param = (GetAndroidNativeBufferUsageParams*)pStructure; 1018 CHECK_TYPE_HEADER(param); 1019 // hardware usage: consumed by GLES and HWC 1020 param->nUsage |= GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER; 1021 // software usage: can be read/written by apps 1022 param->nUsage |= GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_RARELY; 1023 return OMX_ErrorNone; 1024 } 1025 OMX_ERRORTYPE OMXVideoDecoderBase::SetNativeBufferUsageSpecific(OMX_PTR) { 1026 CHECK_SET_PARAM_STATE(); 1027 return OMX_ErrorBadParameter; 1028 } 1029 1030 OMX_ERRORTYPE OMXVideoDecoderBase::GetNativeBufferUsage(OMX_PTR pStructure) { 1031 return this->GetNativeBufferUsageSpecific(pStructure); 1032 } 1033 OMX_ERRORTYPE OMXVideoDecoderBase::SetNativeBufferUsage(OMX_PTR pStructure) { 1034 return this->SetNativeBufferUsageSpecific(pStructure); 1035 } 1036 1037 OMX_ERRORTYPE OMXVideoDecoderBase::GetNativeBuffer(OMX_PTR) { 1038 return OMX_ErrorBadParameter; 1039 } 1040 1041 OMX_ERRORTYPE OMXVideoDecoderBase::SetNativeBuffer(OMX_PTR pStructure) { 1042 OMX_ERRORTYPE ret; 1043 UseAndroidNativeBufferParams *param = (UseAndroidNativeBufferParams*)pStructure; 1044 CHECK_TYPE_HEADER(param); 1045 if (param->nPortIndex != OUTPORT_INDEX) 1046 return OMX_ErrorBadParameter; 1047 OMX_BUFFERHEADERTYPE **buf_hdr = NULL; 1048 1049 mOMXBufferHeaderTypePtrNum++; 1050 if (mOMXBufferHeaderTypePtrNum > MAX_GRAPHIC_BUFFER_NUM) 1051 return OMX_ErrorOverflow; 1052 1053 buf_hdr = &mOMXBufferHeaderTypePtrArray[mOMXBufferHeaderTypePtrNum-1]; 1054 1055 ret = this->ports[OUTPORT_INDEX]->UseBuffer(buf_hdr, OUTPORT_INDEX, param->pAppPrivate, sizeof(OMX_U8*), 1056 const_cast<OMX_U8*>(reinterpret_cast<const OMX_U8*>(param->nativeBuffer->handle))); 1057 if (ret != OMX_ErrorNone) 1058 return ret; 1059 1060 if (mOMXBufferHeaderTypePtrNum == 1) { 1061 mGraphicBufferParam.graphicBufferColorFormat = param->nativeBuffer->format; 1062 mGraphicBufferParam.graphicBufferHStride = param->nativeBuffer->stride; 1063 // FIXME: use IMG_native_handle_t->aiVStride[0] instead.. 1064 mGraphicBufferParam.graphicBufferVStride = param->nativeBuffer->height; 1065 mGraphicBufferParam.graphicBufferWidth = param->nativeBuffer->width; 1066 mGraphicBufferParam.graphicBufferHeight = param->nativeBuffer->height; 1067 } 1068 1069 *(param->bufferHeader) = *buf_hdr; 1070 1071 return OMX_ErrorNone; 1072 } 1073 1074 OMX_ERRORTYPE OMXVideoDecoderBase::GetNativeBufferMode(OMX_PTR pStructure) { 1075 return this->GetNativeBufferModeSpecific(pStructure); 1076 } 1077 1078 OMX_ERRORTYPE OMXVideoDecoderBase::SetNativeBufferMode(OMX_PTR pStructure) { 1079 return this->SetNativeBufferModeSpecific(pStructure); 1080 } 1081 1082 OMX_ERRORTYPE OMXVideoDecoderBase::GetNativeBufferModeSpecific(OMX_PTR) { 1083 LOGE("GetNativeBufferMode is not implemented"); 1084 return OMX_ErrorNotImplemented; 1085 } 1086 1087 OMX_ERRORTYPE OMXVideoDecoderBase::SetNativeBufferModeSpecific(OMX_PTR pStructure) { 1088 OMX_ERRORTYPE ret; 1089 EnableAndroidNativeBuffersParams *param = (EnableAndroidNativeBuffersParams*)pStructure; 1090 1091 CHECK_TYPE_HEADER(param); 1092 CHECK_PORT_INDEX_RANGE(param); 1093 CHECK_SET_PARAM_STATE(); 1094 1095 PortVideo *port = NULL; 1096 port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]); 1097 OMX_PARAM_PORTDEFINITIONTYPE port_def; 1098 memcpy(&port_def,port->GetPortDefinition(),sizeof(port_def)); 1099 1100 if (!param->enable) { 1101 mWorkingMode = RAWDATA_MODE; 1102 // If it is fallback from native mode the color format has been 1103 // already set to INTEL format. 1104 // We need to set back the default color format and Native stuff. 1105 port_def.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; 1106 port_def.format.video.pNativeRender = NULL; 1107 port_def.format.video.pNativeWindow = NULL; 1108 port->SetPortDefinition(&port_def,true); 1109 return OMX_ErrorNone; 1110 } 1111 1112 mWorkingMode = GRAPHICBUFFER_MODE; 1113 port_def.nBufferCountMin = mNativeBufferCount; 1114 if (mEnableAdaptivePlayback) { 1115 SetMaxOutputBufferCount(&port_def); 1116 } else { 1117 port_def.nBufferCountActual = mNativeBufferCount; 1118 } 1119 port_def.format.video.cMIMEType = (OMX_STRING)VA_VED_RAW_MIME_TYPE; 1120 port_def.format.video.eColorFormat = OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar; 1121 port_def.format.video.nFrameHeight = port_def.format.video.nFrameHeight; 1122 1123 port_def.format.video.eColorFormat = GetOutputColorFormat( 1124 port_def.format.video.nFrameWidth); 1125 port->SetPortDefinition(&port_def,true); 1126 1127 return OMX_ErrorNone; 1128 } 1129 1130 OMX_ERRORTYPE OMXVideoDecoderBase::GetStoreMetaDataMode(OMX_PTR) { 1131 ALOGE("GetMetaDataMode is not implemented"); 1132 return OMX_ErrorNotImplemented; 1133 } 1134 1135 OMX_ERRORTYPE OMXVideoDecoderBase::SetStoreMetaDataMode(OMX_PTR pStructure) { 1136 #ifndef USE_META_DATA 1137 OMX_PARAM_PORTDEFINITIONTYPE defInput; 1138 memcpy(&defInput, 1139 this->ports[INPORT_INDEX]->GetPortDefinition(), 1140 sizeof(defInput)); 1141 if (defInput.format.video.eCompressionFormat == OMX_VIDEO_CodingVP9) { 1142 ALOGE("SetMetaDataMode for VP9 is not implemented"); 1143 return OMX_ErrorNotImplemented; 1144 } 1145 #endif 1146 OMX_ERRORTYPE ret; 1147 StoreMetaDataInBuffersParams *param = (StoreMetaDataInBuffersParams*)pStructure; 1148 1149 CHECK_TYPE_HEADER(param); 1150 CHECK_PORT_INDEX(param, OUTPORT_INDEX); 1151 CHECK_SET_PARAM_STATE(); 1152 1153 if (!param->bStoreMetaData) { 1154 mAPMode = LEGACY_MODE; 1155 // Don't return error which otherwise may cause framework crash 1156 return OMX_ErrorNone; 1157 } 1158 mAPMode = METADATA_MODE; 1159 ALOGI("We are in meta data mode!!!"); 1160 1161 return OMX_ErrorNone; 1162 } 1163 1164 OMX_ERRORTYPE OMXVideoDecoderBase::GetDecoderRotation(OMX_PTR) { 1165 return OMX_ErrorBadParameter; 1166 } 1167 OMX_ERRORTYPE OMXVideoDecoderBase::SetDecoderRotation(OMX_PTR pStructure) { 1168 CHECK_SET_PARAM_STATE(); 1169 int32_t rotationDegrees = 0; 1170 1171 if (pStructure) { 1172 rotationDegrees = *(static_cast<int32_t*>(pStructure)); 1173 mRotationDegrees = rotationDegrees; 1174 LOGI("Rotation Degree = %d", rotationDegrees); 1175 return OMX_ErrorNone; 1176 } else { 1177 return OMX_ErrorBadParameter; 1178 } 1179 } 1180 1181 #ifdef TARGET_HAS_ISV 1182 OMX_ERRORTYPE OMXVideoDecoderBase::GetDecoderVppBufferNum(OMX_PTR) { 1183 return OMX_ErrorBadParameter; 1184 } 1185 OMX_ERRORTYPE OMXVideoDecoderBase::SetDecoderVppBufferNum(OMX_PTR pStructure) { 1186 CHECK_SET_PARAM_STATE(); 1187 int32_t num = 0; 1188 1189 num = *(static_cast<int32_t*>(pStructure)); 1190 mVppBufferNum = num; 1191 1192 return OMX_ErrorNone; 1193 } 1194 #endif 1195 1196 OMX_ERRORTYPE OMXVideoDecoderBase::GetDecoderOutputCropSpecific(OMX_PTR pStructure) { 1197 OMX_ERRORTYPE ret; 1198 OMX_CONFIG_RECTTYPE *rectParams = (OMX_CONFIG_RECTTYPE *)pStructure; 1199 1200 CHECK_TYPE_HEADER(rectParams); 1201 1202 if (rectParams->nPortIndex != OUTPORT_INDEX) { 1203 return OMX_ErrorUndefined; 1204 } 1205 1206 PortVideo *port = NULL; 1207 port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]); 1208 OMX_PARAM_PORTDEFINITIONTYPE port_def; 1209 memcpy(&port_def,port->GetPortDefinition(),sizeof(port_def)); 1210 1211 const VideoFormatInfo *formatInfo = mVideoDecoder->getFormatInfo(); 1212 if (formatInfo->valid == true) { 1213 rectParams->nLeft = formatInfo->cropLeft; 1214 rectParams->nTop = formatInfo->cropTop; 1215 rectParams->nWidth = formatInfo->width - formatInfo->cropLeft - formatInfo->cropRight; 1216 rectParams->nHeight = formatInfo->height - formatInfo->cropTop - formatInfo->cropBottom; 1217 if (strcasecmp(formatInfo->mimeType,"video/avc") == 0 || 1218 strcasecmp(formatInfo->mimeType,"video/avc-secure") == 0 || 1219 strcasecmp(formatInfo->mimeType,"video/h264") == 0) { 1220 rectParams->nHeight = formatInfo->height; 1221 rectParams->nWidth = formatInfo->width; 1222 } 1223 1224 // if port width parsed from extractor is not as same as from SPS/PPS nalu header, 1225 // align it. 1226 if (port_def.format.video.nFrameWidth != rectParams->nWidth) { 1227 port_def.format.video.nFrameWidth = rectParams->nWidth; 1228 } 1229 port->SetPortDefinition(&port_def,true); 1230 return OMX_ErrorNone; 1231 } else { 1232 return OMX_ErrorFormatNotDetected; 1233 } 1234 } 1235 1236 OMX_ERRORTYPE OMXVideoDecoderBase::SetDecoderOutputCropSpecific(OMX_PTR) { 1237 return OMX_ErrorUnsupportedSetting; 1238 } 1239 1240 OMX_ERRORTYPE OMXVideoDecoderBase::SetDecoderOutputCrop(OMX_PTR pStructure) { 1241 return this->SetDecoderOutputCropSpecific(pStructure); 1242 } 1243 1244 OMX_ERRORTYPE OMXVideoDecoderBase::GetDecoderOutputCrop(OMX_PTR pStructure) { 1245 return this->GetDecoderOutputCropSpecific(pStructure); 1246 } 1247 1248 1249 OMX_ERRORTYPE OMXVideoDecoderBase::SetCodecPriority(OMX_PTR pStructure) { 1250 OMX_ERRORTYPE ret; 1251 OMX_PARAM_U32TYPE *priorityParam = (OMX_PARAM_U32TYPE *)pStructure; 1252 mCodecPriority = priorityParam->nU32; 1253 return OMX_ErrorNone; 1254 } 1255 1256 1257 OMX_ERRORTYPE OMXVideoDecoderBase::GetCodecPriority(OMX_PTR pStructure) { 1258 OMX_ERRORTYPE ret; 1259 OMX_PARAM_U32TYPE *priorityParam = (OMX_PARAM_U32TYPE *)pStructure; 1260 CHECK_TYPE_HEADER(priorityParam); 1261 priorityParam->nU32 = mCodecPriority; 1262 return OMX_ErrorNone; 1263 } 1264 1265 1266 OMX_ERRORTYPE OMXVideoDecoderBase::SetDecoderOperatingRate(OMX_PTR pStructure) { 1267 OMX_ERRORTYPE ret; 1268 OMX_PARAM_U32TYPE *operatingRateParam = (OMX_PARAM_U32TYPE *)pStructure; 1269 CHECK_TYPE_HEADER(operatingRateParam); 1270 mOperatingRate = operatingRateParam->nU32; 1271 return OMX_ErrorNone; 1272 } 1273 1274 OMX_ERRORTYPE OMXVideoDecoderBase::GetDecoderOperatingRate(OMX_PTR pStructure) { 1275 OMX_ERRORTYPE ret; 1276 OMX_PARAM_U32TYPE *operatingRateParam = (OMX_PARAM_U32TYPE *)pStructure; 1277 CHECK_TYPE_HEADER(operatingRateParam); 1278 operatingRateParam->nU32 = mOperatingRate; 1279 return OMX_ErrorNone; 1280 } 1281 1282 OMX_ERRORTYPE OMXVideoDecoderBase::GetErrorReportMode(OMX_PTR) { 1283 LOGE("GetErrorReportMode is not implemented"); 1284 return OMX_ErrorNotImplemented; 1285 } 1286 1287 OMX_ERRORTYPE OMXVideoDecoderBase::SetErrorReportMode(OMX_PTR pStructure) { 1288 OMX_ERRORTYPE ret; 1289 1290 OMX_VIDEO_CONFIG_INTEL_ERROR_REPORT *p = (OMX_VIDEO_CONFIG_INTEL_ERROR_REPORT *)pStructure; 1291 CHECK_TYPE_HEADER(p); 1292 CHECK_PORT_INDEX(p, OUTPORT_INDEX); 1293 1294 mErrorReportEnabled = p->bEnable; 1295 LOGD("Error reporting is %s", mErrorReportEnabled ? "enabled" : "disabled"); 1296 1297 mVideoDecoder->enableErrorReport(mErrorReportEnabled); 1298 return OMX_ErrorNone; 1299 } 1300 1301 OMX_COLOR_FORMATTYPE OMXVideoDecoderBase::GetOutputColorFormat(int width) { 1302 #ifndef VED_TILING 1303 return OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar; 1304 #else 1305 if (width > 1280 && width <= 2048) { 1306 LOGI("HD Video and use tiled format"); 1307 return OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled; 1308 } else { 1309 return OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar; 1310 } 1311 #endif 1312 } 1313 1314 OMX_ERRORTYPE OMXVideoDecoderBase::SetMaxOutputBufferCount(OMX_PARAM_PORTDEFINITIONTYPE *) { 1315 return OMX_ErrorNone; 1316 } 1317 1318 uint32_t OMXVideoDecoderBase::getStride(uint32_t width) { 1319 uint32_t stride = 0; 1320 1321 if (width <= 512) 1322 stride = 512; 1323 else if (width <= 1024) 1324 stride = 1024; 1325 else if (width <= 1280) { 1326 stride = 1280; 1327 } else if (width <= 2048) 1328 stride = 2048; 1329 else if (width <= 4096) 1330 stride = 4096; 1331 else 1332 stride = (width + 0x3f) & ~0x3f; 1333 1334 return stride; 1335 } 1336