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/h264") == 0) { 788 heightCropped = formatInfo->height; 789 widthCropped = formatInfo->width; 790 } 791 uint32_t strideCropped = widthCropped; 792 uint32_t sliceHeightCropped = heightCropped; 793 int force_realloc = 0; 794 bool isVP8 = false; 795 796 if (mAPMode == METADATA_MODE && mWorkingMode == GRAPHICBUFFER_MODE) { 797 #ifdef TARGET_HAS_ISV 798 if (paramPortDefinitionOutput.nBufferCountActual - mVppBufferNum < formatInfo->actualBufferNeeded) { 799 #else 800 if (paramPortDefinitionOutput.nBufferCountActual < formatInfo->actualBufferNeeded) { 801 #endif 802 paramPortDefinitionOutput.nBufferCountActual = mNativeBufferCount = formatInfo->actualBufferNeeded; 803 paramPortDefinitionOutput.nBufferCountMin = formatInfo->actualBufferNeeded - 4; 804 } 805 // input port 806 paramPortDefinitionInput.format.video.nFrameWidth = width; 807 paramPortDefinitionInput.format.video.nFrameHeight = height; 808 paramPortDefinitionInput.format.video.nStride = stride; 809 paramPortDefinitionInput.format.video.nSliceHeight = sliceHeight; 810 // output port 811 paramPortDefinitionOutput.format.video.nFrameWidth = width; 812 paramPortDefinitionOutput.format.video.nFrameHeight = height; 813 paramPortDefinitionOutput.format.video.eColorFormat = GetOutputColorFormat(paramPortDefinitionOutput.format.video.nFrameWidth); 814 paramPortDefinitionOutput.format.video.nStride = stride; 815 paramPortDefinitionOutput.format.video.nSliceHeight = sliceHeight; 816 817 paramPortDefinitionOutput.bEnabled = (OMX_BOOL)false; 818 mOMXBufferHeaderTypePtrNum = 0; 819 memset(&mGraphicBufferParam, 0, sizeof(mGraphicBufferParam)); 820 mMetaDataBuffersNum = 0; 821 822 this->ports[INPORT_INDEX]->SetPortDefinition(¶mPortDefinitionInput, true); 823 this->ports[OUTPORT_INDEX]->SetPortDefinition(¶mPortDefinitionOutput, true); 824 825 ProcessorFlush(INPORT_INDEX); 826 827 mVideoDecoder->freeSurfaceBuffers(); 828 829 this->ports[OUTPORT_INDEX]->ReportPortSettingsChanged(); 830 831 mFlushMode = false; 832 return OMX_ErrorNone; 833 } 834 835 #ifdef TARGET_HAS_ISV 836 LOGI("============== mVppBufferNum = %d\n", mVppBufferNum); 837 if (paramPortDefinitionOutput.nBufferCountActual - mVppBufferNum < formatInfo->actualBufferNeeded) { 838 #else 839 if (paramPortDefinitionOutput.nBufferCountActual < formatInfo->actualBufferNeeded) { 840 #endif 841 if (mWorkingMode == GRAPHICBUFFER_MODE) { 842 LOGV("output port buffer number is not enough: %d to %d", 843 paramPortDefinitionOutput.nBufferCountActual, 844 formatInfo->actualBufferNeeded); 845 paramPortDefinitionOutput.nBufferCountActual = mNativeBufferCount = formatInfo->actualBufferNeeded; 846 paramPortDefinitionOutput.nBufferCountMin = mNativeBufferCount; 847 force_realloc = 1; 848 } 849 } 850 851 LOGV("Original size = %u x %u, new size = %d x %d, cropped size = %d x %d", 852 paramPortDefinitionInput.format.video.nFrameWidth, 853 paramPortDefinitionInput.format.video.nFrameHeight, 854 width, height, widthCropped, heightCropped); 855 856 if (paramPortDefinitionInput.format.video.eCompressionFormat == OMX_VIDEO_CodingVP8) { 857 isVP8 = true; 858 } 859 860 if (!force_realloc && 861 widthCropped == paramPortDefinitionOutput.format.video.nFrameWidth && 862 heightCropped == paramPortDefinitionOutput.format.video.nFrameHeight) { 863 if (mWorkingMode == RAWDATA_MODE) { 864 LOGW("Change of portsetting is not reported as size is not changed."); 865 return OMX_ErrorNone; 866 } 867 } 868 869 paramPortDefinitionInput.format.video.nFrameWidth = width; 870 paramPortDefinitionInput.format.video.nFrameHeight = height; 871 paramPortDefinitionInput.format.video.nStride = stride; 872 paramPortDefinitionInput.format.video.nSliceHeight = sliceHeight; 873 874 if (mWorkingMode == RAWDATA_MODE) { 875 paramPortDefinitionOutput.format.video.nFrameWidth = widthCropped; 876 paramPortDefinitionOutput.format.video.nFrameHeight = heightCropped; 877 paramPortDefinitionOutput.format.video.nStride = strideCropped; 878 paramPortDefinitionOutput.format.video.nSliceHeight = sliceHeightCropped; 879 } else if (mWorkingMode == GRAPHICBUFFER_MODE) { 880 // when the width and height ES parse are not larger than allocated graphic buffer in outport, 881 // there is no need to reallocate graphic buffer,just report the crop info to omx client 882 if (!force_realloc && width <= formatInfo->surfaceWidth && height <= formatInfo->surfaceHeight) { 883 this->ports[INPORT_INDEX]->SetPortDefinition(¶mPortDefinitionInput, true); 884 this->ports[OUTPORT_INDEX]->ReportOutputCrop(); 885 return OMX_ErrorNone; 886 } 887 888 if (isVP8 || width > formatInfo->surfaceWidth || height > formatInfo->surfaceHeight) { 889 // update the real decoded resolution to outport instead of display resolution for graphic buffer reallocation 890 // when the width and height parsed from ES are larger than allocated graphic buffer in outport, 891 paramPortDefinitionOutput.format.video.nFrameWidth = width; 892 paramPortDefinitionOutput.format.video.nFrameHeight = height; 893 paramPortDefinitionOutput.format.video.eColorFormat = GetOutputColorFormat( 894 paramPortDefinitionOutput.format.video.nFrameWidth); 895 paramPortDefinitionOutput.format.video.nStride = stride; 896 paramPortDefinitionOutput.format.video.nSliceHeight = sliceHeight; 897 } 898 } 899 900 paramPortDefinitionOutput.bEnabled = (OMX_BOOL)false; 901 mOMXBufferHeaderTypePtrNum = 0; 902 memset(&mGraphicBufferParam, 0, sizeof(mGraphicBufferParam)); 903 904 this->ports[INPORT_INDEX]->SetPortDefinition(¶mPortDefinitionInput, true); 905 this->ports[OUTPORT_INDEX]->SetPortDefinition(¶mPortDefinitionOutput, true); 906 907 if (mWorkingMode == GRAPHICBUFFER_MODE) { 908 // Make sure va_destroySurface is called before graphicbuffer is freed in case of port setting changed 909 mVideoDecoder->freeSurfaceBuffers(); 910 911 // Also make sure all the reference frames are flushed 912 ProcessorFlush(INPORT_INDEX); 913 } 914 this->ports[OUTPORT_INDEX]->ReportPortSettingsChanged(); 915 return OMX_ErrorNone; 916 } 917 918 OMX_ERRORTYPE OMXVideoDecoderBase::TranslateDecodeStatus(Decode_Status status) { 919 switch (status) { 920 case DECODE_NEED_RESTART: 921 LOGE("Decoder returned DECODE_NEED_RESTART"); 922 return (OMX_ERRORTYPE)OMX_ErrorIntelVideoNotPermitted; 923 case DECODE_NO_CONFIG: 924 LOGE("Decoder returned DECODE_NO_CONFIG"); 925 return (OMX_ERRORTYPE)OMX_ErrorIntelMissingConfig; 926 case DECODE_NO_SURFACE: 927 LOGE("Decoder returned DECODE_NO_SURFACE"); 928 return OMX_ErrorDynamicResourcesUnavailable; 929 case DECODE_NO_REFERENCE: 930 LOGE("Decoder returned DECODE_NO_REFERENCE"); 931 return OMX_ErrorDynamicResourcesUnavailable; // TO DO 932 case DECODE_NO_PARSER: 933 LOGE("Decoder returned DECODE_NO_PARSER"); 934 return OMX_ErrorDynamicResourcesUnavailable; 935 case DECODE_INVALID_DATA: 936 LOGE("Decoder returned DECODE_INVALID_DATA"); 937 return OMX_ErrorBadParameter; 938 case DECODE_DRIVER_FAIL: 939 LOGE("Decoder returned DECODE_DRIVER_FAIL"); 940 return OMX_ErrorHardware; 941 case DECODE_PARSER_FAIL: 942 LOGE("Decoder returned DECODE_PARSER_FAIL"); 943 return (OMX_ERRORTYPE)OMX_ErrorIntelProcessStream; // OMX_ErrorStreamCorrupt 944 case DECODE_MEMORY_FAIL: 945 LOGE("Decoder returned DECODE_MEMORY_FAIL"); 946 return OMX_ErrorInsufficientResources; 947 case DECODE_FAIL: 948 LOGE("Decoder returned DECODE_FAIL"); 949 return OMX_ErrorUndefined; 950 case DECODE_SUCCESS: 951 return OMX_ErrorNone; 952 case DECODE_FORMAT_CHANGE: 953 LOGW("Decoder returned DECODE_FORMAT_CHANGE"); 954 return OMX_ErrorNone; 955 case DECODE_FRAME_DROPPED: 956 LOGI("Decoder returned DECODE_FRAME_DROPPED"); 957 return OMX_ErrorNone; 958 default: 959 LOGW("Decoder returned unknown error"); 960 return OMX_ErrorUndefined; 961 } 962 } 963 964 OMX_ERRORTYPE OMXVideoDecoderBase::BuildHandlerList(void) { 965 OMXComponentCodecBase::BuildHandlerList(); 966 AddHandler(OMX_IndexParamVideoPortFormat, GetParamVideoPortFormat, SetParamVideoPortFormat); 967 AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtGetNativeBufferUsage), GetNativeBufferUsage, SetNativeBufferUsage); 968 AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtUseNativeBuffer), GetNativeBuffer, SetNativeBuffer); 969 AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtEnableNativeBuffer), GetNativeBufferMode, SetNativeBufferMode); 970 AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtRotationDegrees), GetDecoderRotation, SetDecoderRotation); 971 #ifdef TARGET_HAS_ISV 972 AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtVppBufferNum), GetDecoderVppBufferNum, SetDecoderVppBufferNum); 973 #endif 974 AddHandler(OMX_IndexConfigCommonOutputCrop, GetDecoderOutputCrop, SetDecoderOutputCrop); 975 #ifdef USE_META_DATA 976 AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexStoreMetaDataInBuffers), GetStoreMetaDataMode, SetStoreMetaDataMode); 977 #endif 978 AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtEnableErrorReport), GetErrorReportMode, SetErrorReportMode); 979 AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexConfigPriority), GetCodecPriority, SetCodecPriority); 980 AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexConfigOperatingRate), GetDecoderOperatingRate, SetDecoderOperatingRate); 981 982 return OMX_ErrorNone; 983 } 984 985 OMX_ERRORTYPE OMXVideoDecoderBase::GetParamVideoPortFormat(OMX_PTR pStructure) { 986 OMX_ERRORTYPE ret; 987 OMX_VIDEO_PARAM_PORTFORMATTYPE *p = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pStructure; 988 989 CHECK_TYPE_HEADER(p); 990 CHECK_PORT_INDEX_RANGE(p); 991 CHECK_ENUMERATION_RANGE(p->nIndex, 1); 992 993 PortVideo *port = NULL; 994 port = static_cast<PortVideo *>(this->ports[p->nPortIndex]); 995 memcpy(p, port->GetPortVideoParam(), sizeof(*p)); 996 return OMX_ErrorNone; 997 } 998 999 OMX_ERRORTYPE OMXVideoDecoderBase::SetParamVideoPortFormat(OMX_PTR pStructure) { 1000 OMX_ERRORTYPE ret; 1001 OMX_VIDEO_PARAM_PORTFORMATTYPE *p = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pStructure; 1002 1003 CHECK_TYPE_HEADER(p); 1004 CHECK_PORT_INDEX_RANGE(p); 1005 CHECK_SET_PARAM_STATE(); 1006 1007 // TODO: do we need to check if port is enabled? 1008 PortVideo *port = NULL; 1009 port = static_cast<PortVideo *>(this->ports[p->nPortIndex]); 1010 port->SetPortVideoParam(p, false); 1011 return OMX_ErrorNone; 1012 } 1013 1014 OMX_ERRORTYPE OMXVideoDecoderBase::GetNativeBufferUsageSpecific(OMX_PTR pStructure) { 1015 OMX_ERRORTYPE ret; 1016 GetAndroidNativeBufferUsageParams *param = (GetAndroidNativeBufferUsageParams*)pStructure; 1017 CHECK_TYPE_HEADER(param); 1018 // hardware usage: consumed by GLES and HWC 1019 param->nUsage |= GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER; 1020 // software usage: can be read/written by apps 1021 param->nUsage |= GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_RARELY; 1022 return OMX_ErrorNone; 1023 } 1024 OMX_ERRORTYPE OMXVideoDecoderBase::SetNativeBufferUsageSpecific(OMX_PTR) { 1025 CHECK_SET_PARAM_STATE(); 1026 return OMX_ErrorBadParameter; 1027 } 1028 1029 OMX_ERRORTYPE OMXVideoDecoderBase::GetNativeBufferUsage(OMX_PTR pStructure) { 1030 return this->GetNativeBufferUsageSpecific(pStructure); 1031 } 1032 OMX_ERRORTYPE OMXVideoDecoderBase::SetNativeBufferUsage(OMX_PTR pStructure) { 1033 return this->SetNativeBufferUsageSpecific(pStructure); 1034 } 1035 1036 OMX_ERRORTYPE OMXVideoDecoderBase::GetNativeBuffer(OMX_PTR) { 1037 return OMX_ErrorBadParameter; 1038 } 1039 1040 OMX_ERRORTYPE OMXVideoDecoderBase::SetNativeBuffer(OMX_PTR pStructure) { 1041 OMX_ERRORTYPE ret; 1042 UseAndroidNativeBufferParams *param = (UseAndroidNativeBufferParams*)pStructure; 1043 CHECK_TYPE_HEADER(param); 1044 if (param->nPortIndex != OUTPORT_INDEX) 1045 return OMX_ErrorBadParameter; 1046 OMX_BUFFERHEADERTYPE **buf_hdr = NULL; 1047 1048 mOMXBufferHeaderTypePtrNum++; 1049 if (mOMXBufferHeaderTypePtrNum > MAX_GRAPHIC_BUFFER_NUM) 1050 return OMX_ErrorOverflow; 1051 1052 buf_hdr = &mOMXBufferHeaderTypePtrArray[mOMXBufferHeaderTypePtrNum-1]; 1053 1054 ret = this->ports[OUTPORT_INDEX]->UseBuffer(buf_hdr, OUTPORT_INDEX, param->pAppPrivate, sizeof(OMX_U8*), 1055 const_cast<OMX_U8*>(reinterpret_cast<const OMX_U8*>(param->nativeBuffer->handle))); 1056 if (ret != OMX_ErrorNone) 1057 return ret; 1058 1059 if (mOMXBufferHeaderTypePtrNum == 1) { 1060 mGraphicBufferParam.graphicBufferColorFormat = param->nativeBuffer->format; 1061 mGraphicBufferParam.graphicBufferHStride = param->nativeBuffer->stride; 1062 // FIXME: use IMG_native_handle_t->aiVStride[0] instead.. 1063 mGraphicBufferParam.graphicBufferVStride = param->nativeBuffer->height; 1064 mGraphicBufferParam.graphicBufferWidth = param->nativeBuffer->width; 1065 mGraphicBufferParam.graphicBufferHeight = param->nativeBuffer->height; 1066 } 1067 1068 *(param->bufferHeader) = *buf_hdr; 1069 1070 return OMX_ErrorNone; 1071 } 1072 1073 OMX_ERRORTYPE OMXVideoDecoderBase::GetNativeBufferMode(OMX_PTR pStructure) { 1074 return this->GetNativeBufferModeSpecific(pStructure); 1075 } 1076 1077 OMX_ERRORTYPE OMXVideoDecoderBase::SetNativeBufferMode(OMX_PTR pStructure) { 1078 return this->SetNativeBufferModeSpecific(pStructure); 1079 } 1080 1081 OMX_ERRORTYPE OMXVideoDecoderBase::GetNativeBufferModeSpecific(OMX_PTR) { 1082 LOGE("GetNativeBufferMode is not implemented"); 1083 return OMX_ErrorNotImplemented; 1084 } 1085 1086 OMX_ERRORTYPE OMXVideoDecoderBase::SetNativeBufferModeSpecific(OMX_PTR pStructure) { 1087 OMX_ERRORTYPE ret; 1088 EnableAndroidNativeBuffersParams *param = (EnableAndroidNativeBuffersParams*)pStructure; 1089 1090 CHECK_TYPE_HEADER(param); 1091 CHECK_PORT_INDEX_RANGE(param); 1092 CHECK_SET_PARAM_STATE(); 1093 1094 PortVideo *port = NULL; 1095 port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]); 1096 OMX_PARAM_PORTDEFINITIONTYPE port_def; 1097 memcpy(&port_def,port->GetPortDefinition(),sizeof(port_def)); 1098 1099 if (!param->enable) { 1100 mWorkingMode = RAWDATA_MODE; 1101 // If it is fallback from native mode the color format has been 1102 // already set to INTEL format. 1103 // We need to set back the default color format and Native stuff. 1104 port_def.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; 1105 port_def.format.video.pNativeRender = NULL; 1106 port_def.format.video.pNativeWindow = NULL; 1107 port->SetPortDefinition(&port_def,true); 1108 return OMX_ErrorNone; 1109 } 1110 1111 mWorkingMode = GRAPHICBUFFER_MODE; 1112 port_def.nBufferCountMin = mNativeBufferCount; 1113 if (mEnableAdaptivePlayback) { 1114 SetMaxOutputBufferCount(&port_def); 1115 } else { 1116 port_def.nBufferCountActual = mNativeBufferCount; 1117 } 1118 port_def.format.video.cMIMEType = (OMX_STRING)VA_VED_RAW_MIME_TYPE; 1119 port_def.format.video.eColorFormat = OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar; 1120 port_def.format.video.nFrameHeight = port_def.format.video.nFrameHeight; 1121 1122 port_def.format.video.eColorFormat = GetOutputColorFormat( 1123 port_def.format.video.nFrameWidth); 1124 port->SetPortDefinition(&port_def,true); 1125 1126 return OMX_ErrorNone; 1127 } 1128 1129 OMX_ERRORTYPE OMXVideoDecoderBase::GetStoreMetaDataMode(OMX_PTR) { 1130 ALOGE("GetMetaDataMode is not implemented"); 1131 return OMX_ErrorNotImplemented; 1132 } 1133 1134 OMX_ERRORTYPE OMXVideoDecoderBase::SetStoreMetaDataMode(OMX_PTR pStructure) { 1135 #ifndef USE_META_DATA 1136 OMX_PARAM_PORTDEFINITIONTYPE defInput; 1137 memcpy(&defInput, 1138 this->ports[INPORT_INDEX]->GetPortDefinition(), 1139 sizeof(defInput)); 1140 if (defInput.format.video.eCompressionFormat == OMX_VIDEO_CodingVP9) { 1141 ALOGE("SetMetaDataMode for VP9 is not implemented"); 1142 return OMX_ErrorNotImplemented; 1143 } 1144 #endif 1145 OMX_ERRORTYPE ret; 1146 StoreMetaDataInBuffersParams *param = (StoreMetaDataInBuffersParams*)pStructure; 1147 1148 CHECK_TYPE_HEADER(param); 1149 CHECK_PORT_INDEX(param, OUTPORT_INDEX); 1150 CHECK_SET_PARAM_STATE(); 1151 1152 if (!param->bStoreMetaData) { 1153 mAPMode = LEGACY_MODE; 1154 // Don't return error which otherwise may cause framework crash 1155 return OMX_ErrorNone; 1156 } 1157 mAPMode = METADATA_MODE; 1158 ALOGI("We are in meta data mode!!!"); 1159 1160 return OMX_ErrorNone; 1161 } 1162 1163 OMX_ERRORTYPE OMXVideoDecoderBase::GetDecoderRotation(OMX_PTR) { 1164 return OMX_ErrorBadParameter; 1165 } 1166 OMX_ERRORTYPE OMXVideoDecoderBase::SetDecoderRotation(OMX_PTR pStructure) { 1167 CHECK_SET_PARAM_STATE(); 1168 int32_t rotationDegrees = 0; 1169 1170 if (pStructure) { 1171 rotationDegrees = *(static_cast<int32_t*>(pStructure)); 1172 mRotationDegrees = rotationDegrees; 1173 LOGI("Rotation Degree = %d", rotationDegrees); 1174 return OMX_ErrorNone; 1175 } else { 1176 return OMX_ErrorBadParameter; 1177 } 1178 } 1179 1180 #ifdef TARGET_HAS_ISV 1181 OMX_ERRORTYPE OMXVideoDecoderBase::GetDecoderVppBufferNum(OMX_PTR) { 1182 return OMX_ErrorBadParameter; 1183 } 1184 OMX_ERRORTYPE OMXVideoDecoderBase::SetDecoderVppBufferNum(OMX_PTR pStructure) { 1185 CHECK_SET_PARAM_STATE(); 1186 int32_t num = 0; 1187 1188 num = *(static_cast<int32_t*>(pStructure)); 1189 mVppBufferNum = num; 1190 1191 return OMX_ErrorNone; 1192 } 1193 #endif 1194 1195 OMX_ERRORTYPE OMXVideoDecoderBase::GetDecoderOutputCropSpecific(OMX_PTR pStructure) { 1196 OMX_ERRORTYPE ret; 1197 OMX_CONFIG_RECTTYPE *rectParams = (OMX_CONFIG_RECTTYPE *)pStructure; 1198 1199 CHECK_TYPE_HEADER(rectParams); 1200 1201 if (rectParams->nPortIndex != OUTPORT_INDEX) { 1202 return OMX_ErrorUndefined; 1203 } 1204 1205 PortVideo *port = NULL; 1206 port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]); 1207 OMX_PARAM_PORTDEFINITIONTYPE port_def; 1208 memcpy(&port_def,port->GetPortDefinition(),sizeof(port_def)); 1209 1210 const VideoFormatInfo *formatInfo = mVideoDecoder->getFormatInfo(); 1211 if (formatInfo->valid == true) { 1212 rectParams->nLeft = formatInfo->cropLeft; 1213 rectParams->nTop = formatInfo->cropTop; 1214 rectParams->nWidth = formatInfo->width - formatInfo->cropLeft - formatInfo->cropRight; 1215 rectParams->nHeight = formatInfo->height - formatInfo->cropTop - formatInfo->cropBottom; 1216 if (strcasecmp(formatInfo->mimeType,"video/avc") == 0 || 1217 strcasecmp(formatInfo->mimeType,"video/h264") == 0) { 1218 rectParams->nHeight = formatInfo->height; 1219 rectParams->nWidth = formatInfo->width; 1220 } 1221 1222 // if port width parsed from extractor is not as same as from SPS/PPS nalu header, 1223 // align it. 1224 if (port_def.format.video.nFrameWidth != rectParams->nWidth) { 1225 port_def.format.video.nFrameWidth = rectParams->nWidth; 1226 } 1227 port->SetPortDefinition(&port_def,true); 1228 return OMX_ErrorNone; 1229 } else { 1230 return OMX_ErrorFormatNotDetected; 1231 } 1232 } 1233 1234 OMX_ERRORTYPE OMXVideoDecoderBase::SetDecoderOutputCropSpecific(OMX_PTR) { 1235 return OMX_ErrorUnsupportedSetting; 1236 } 1237 1238 OMX_ERRORTYPE OMXVideoDecoderBase::SetDecoderOutputCrop(OMX_PTR pStructure) { 1239 return this->SetDecoderOutputCropSpecific(pStructure); 1240 } 1241 1242 OMX_ERRORTYPE OMXVideoDecoderBase::GetDecoderOutputCrop(OMX_PTR pStructure) { 1243 return this->GetDecoderOutputCropSpecific(pStructure); 1244 } 1245 1246 1247 OMX_ERRORTYPE OMXVideoDecoderBase::SetCodecPriority(OMX_PTR pStructure) { 1248 OMX_ERRORTYPE ret; 1249 OMX_PARAM_U32TYPE *priorityParam = (OMX_PARAM_U32TYPE *)pStructure; 1250 mCodecPriority = priorityParam->nU32; 1251 return OMX_ErrorNone; 1252 } 1253 1254 1255 OMX_ERRORTYPE OMXVideoDecoderBase::GetCodecPriority(OMX_PTR pStructure) { 1256 OMX_ERRORTYPE ret; 1257 OMX_PARAM_U32TYPE *priorityParam = (OMX_PARAM_U32TYPE *)pStructure; 1258 CHECK_TYPE_HEADER(priorityParam); 1259 priorityParam->nU32 = mCodecPriority; 1260 return OMX_ErrorNone; 1261 } 1262 1263 1264 OMX_ERRORTYPE OMXVideoDecoderBase::SetDecoderOperatingRate(OMX_PTR pStructure) { 1265 OMX_ERRORTYPE ret; 1266 OMX_PARAM_U32TYPE *operatingRateParam = (OMX_PARAM_U32TYPE *)pStructure; 1267 CHECK_TYPE_HEADER(operatingRateParam); 1268 mOperatingRate = operatingRateParam->nU32; 1269 return OMX_ErrorNone; 1270 } 1271 1272 OMX_ERRORTYPE OMXVideoDecoderBase::GetDecoderOperatingRate(OMX_PTR pStructure) { 1273 OMX_ERRORTYPE ret; 1274 OMX_PARAM_U32TYPE *operatingRateParam = (OMX_PARAM_U32TYPE *)pStructure; 1275 CHECK_TYPE_HEADER(operatingRateParam); 1276 operatingRateParam->nU32 = mOperatingRate; 1277 return OMX_ErrorNone; 1278 } 1279 1280 OMX_ERRORTYPE OMXVideoDecoderBase::GetErrorReportMode(OMX_PTR) { 1281 LOGE("GetErrorReportMode is not implemented"); 1282 return OMX_ErrorNotImplemented; 1283 } 1284 1285 OMX_ERRORTYPE OMXVideoDecoderBase::SetErrorReportMode(OMX_PTR pStructure) { 1286 OMX_ERRORTYPE ret; 1287 1288 OMX_VIDEO_CONFIG_INTEL_ERROR_REPORT *p = (OMX_VIDEO_CONFIG_INTEL_ERROR_REPORT *)pStructure; 1289 CHECK_TYPE_HEADER(p); 1290 CHECK_PORT_INDEX(p, OUTPORT_INDEX); 1291 1292 mErrorReportEnabled = p->bEnable; 1293 LOGD("Error reporting is %s", mErrorReportEnabled ? "enabled" : "disabled"); 1294 1295 mVideoDecoder->enableErrorReport(mErrorReportEnabled); 1296 return OMX_ErrorNone; 1297 } 1298 1299 OMX_COLOR_FORMATTYPE OMXVideoDecoderBase::GetOutputColorFormat(int width) { 1300 #ifndef VED_TILING 1301 return OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar; 1302 #else 1303 if (width > 1280 && width <= 2048) { 1304 LOGI("HD Video and use tiled format"); 1305 return OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled; 1306 } else { 1307 return OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar; 1308 } 1309 #endif 1310 } 1311 1312 OMX_ERRORTYPE OMXVideoDecoderBase::SetMaxOutputBufferCount(OMX_PARAM_PORTDEFINITIONTYPE *) { 1313 return OMX_ErrorNone; 1314 } 1315 1316 uint32_t OMXVideoDecoderBase::getStride(uint32_t width) { 1317 uint32_t stride = 0; 1318 1319 if (width <= 512) 1320 stride = 512; 1321 else if (width <= 1024) 1322 stride = 1024; 1323 else if (width <= 1280) { 1324 stride = 1280; 1325 } else if (width <= 2048) 1326 stride = 2048; 1327 else if (width <= 4096) 1328 stride = 4096; 1329 else 1330 stride = (width + 0x3f) & ~0x3f; 1331 1332 return stride; 1333 } 1334