Home | History | Annotate | Download | only in videocodec
      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       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 
     42 OMXVideoDecoderBase::~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 
     58 OMX_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(&paramPortDefinitionInput, 0, sizeof(paramPortDefinitionInput));
     69     SetTypeHeader(&paramPortDefinitionInput, 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(&paramPortDefinitionInput);
     97 
     98     port->SetPortDefinition(&paramPortDefinitionInput, true);
     99 
    100     // OMX_VIDEO_PARAM_PORTFORMATTYPE
    101     OMX_VIDEO_PARAM_PORTFORMATTYPE paramPortFormat;
    102     memset(&paramPortFormat, 0, sizeof(paramPortFormat));
    103     SetTypeHeader(&paramPortFormat, 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(&paramPortFormat, true);
    111 
    112     return OMX_ErrorNone;
    113 }
    114 
    115 
    116 OMX_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(&paramPortDefinitionOutput, 0, sizeof(paramPortDefinitionOutput));
    128     SetTypeHeader(&paramPortDefinitionOutput, 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(&paramPortDefinitionOutput);
    156 
    157     port->SetPortDefinition(&paramPortDefinitionOutput, true);
    158 
    159     // OMX_VIDEO_PARAM_PORTFORMATTYPE
    160     OMX_VIDEO_PARAM_PORTFORMATTYPE paramPortFormat;
    161     SetTypeHeader(&paramPortFormat, 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(&paramPortFormat, true);
    169 
    170     return OMX_ErrorNone;
    171 }
    172 
    173 OMX_ERRORTYPE OMXVideoDecoderBase::InitOutputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *) {
    174     // no format specific to initialize output port
    175     return OMX_ErrorNone;
    176 }
    177 
    178 OMX_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 
    203 OMX_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 
    214 OMX_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 
    231 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorStart(void) {
    232     return OMXComponentCodecBase::ProcessorStart();
    233 }
    234 
    235 OMX_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 
    253 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorPause(void) {
    254     return OMXComponentCodecBase::ProcessorPause();
    255 }
    256 
    257 OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorResume(void) {
    258     return OMXComponentCodecBase::ProcessorResume();
    259 }
    260 
    261 OMX_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 
    279 OMX_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 
    312 OMX_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 
    416 bool 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 
    436 OMX_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 
    489 OMX_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 *) &degree, 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 
    537 OMX_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 
    610 OMX_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(&paramPortDefinitionInput,
    620         this->ports[INPORT_INDEX]->GetPortDefinition(),
    621         sizeof(paramPortDefinitionInput));
    622 
    623     memcpy(&paramPortDefinitionOutput,
    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(&paramPortDefinitionInput, 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(&paramPortDefinitionInput, true);
    709     this->ports[OUTPORT_INDEX]->SetPortDefinition(&paramPortDefinitionOutput, 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 
    722 OMX_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 
    768 OMX_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 
    784 OMX_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 
    798 OMX_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 
    813 OMX_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 }
    820 OMX_ERRORTYPE OMXVideoDecoderBase::SetNativeBufferUsageSpecific(OMX_PTR) {
    821     CHECK_SET_PARAM_STATE();
    822     return OMX_ErrorBadParameter;
    823 }
    824 
    825 OMX_ERRORTYPE OMXVideoDecoderBase::GetNativeBufferUsage(OMX_PTR pStructure) {
    826     return this->GetNativeBufferUsageSpecific(pStructure);
    827 }
    828 OMX_ERRORTYPE OMXVideoDecoderBase::SetNativeBufferUsage(OMX_PTR pStructure) {
    829     return this->SetNativeBufferUsageSpecific(pStructure);
    830 }
    831 
    832 OMX_ERRORTYPE OMXVideoDecoderBase::GetNativeBuffer(OMX_PTR) {
    833     return OMX_ErrorBadParameter;
    834 }
    835 
    836 OMX_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 
    867 OMX_ERRORTYPE OMXVideoDecoderBase::GetNativeBufferMode(OMX_PTR pStructure) {
    868     return this->GetNativeBufferModeSpecific(pStructure);
    869 }
    870 
    871 OMX_ERRORTYPE OMXVideoDecoderBase::SetNativeBufferMode(OMX_PTR pStructure) {
    872     return this->SetNativeBufferModeSpecific(pStructure);
    873 }
    874 
    875 OMX_ERRORTYPE OMXVideoDecoderBase::GetNativeBufferModeSpecific(OMX_PTR) {
    876     LOGE("GetNativeBufferMode is not implemented");
    877     return OMX_ErrorNotImplemented;
    878 }
    879 
    880 OMX_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 
    922 OMX_ERRORTYPE OMXVideoDecoderBase::GetDecoderRotation(OMX_PTR) {
    923     return OMX_ErrorBadParameter;
    924 }
    925 OMX_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
    940 OMX_ERRORTYPE OMXVideoDecoderBase::GetDecoderVppBufferNum(OMX_PTR) {
    941     return OMX_ErrorBadParameter;
    942 }
    943 OMX_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 
    954 OMX_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 
    975 OMX_ERRORTYPE OMXVideoDecoderBase::SetDecoderOutputCropSpecific(OMX_PTR) {
    976     return OMX_ErrorUnsupportedSetting;
    977 }
    978 
    979 OMX_ERRORTYPE OMXVideoDecoderBase::SetDecoderOutputCrop(OMX_PTR pStructure) {
    980     return this->SetDecoderOutputCropSpecific(pStructure);
    981 }
    982 
    983 OMX_ERRORTYPE OMXVideoDecoderBase::GetDecoderOutputCrop(OMX_PTR pStructure) {
    984     return this->GetDecoderOutputCropSpecific(pStructure);
    985 }
    986 
    987 OMX_ERRORTYPE OMXVideoDecoderBase::GetErrorReportMode(OMX_PTR) {
    988     LOGE("GetErrorReportMode is not implemented");
    989     return OMX_ErrorNotImplemented;
    990 }
    991 
    992 OMX_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 
   1006 OMX_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 
   1019 OMX_ERRORTYPE OMXVideoDecoderBase::SetMaxOutputBufferCount(OMX_PARAM_PORTDEFINITIONTYPE *) {
   1020     return OMX_ErrorNone;
   1021 }
   1022