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