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