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