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       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(&paramPortDefinitionInput, 0, sizeof(paramPortDefinitionInput));
     74     SetTypeHeader(&paramPortDefinitionInput, 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(&paramPortDefinitionInput);
    102 
    103     port->SetPortDefinition(&paramPortDefinitionInput, true);
    104 
    105     // OMX_VIDEO_PARAM_PORTFORMATTYPE
    106     OMX_VIDEO_PARAM_PORTFORMATTYPE paramPortFormat;
    107     memset(&paramPortFormat, 0, sizeof(paramPortFormat));
    108     SetTypeHeader(&paramPortFormat, 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(&paramPortFormat, 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(&paramPortDefinitionOutput, 0, sizeof(paramPortDefinitionOutput));
    133     SetTypeHeader(&paramPortDefinitionOutput, 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(&paramPortDefinitionOutput);
    161 
    162     port->SetPortDefinition(&paramPortDefinitionOutput, true);
    163 
    164     // OMX_VIDEO_PARAM_PORTFORMATTYPE
    165     OMX_VIDEO_PARAM_PORTFORMATTYPE paramPortFormat;
    166     SetTypeHeader(&paramPortFormat, 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(&paramPortFormat, 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 *) &degree, 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(&paramPortDefinitionInput,
    689         this->ports[INPORT_INDEX]->GetPortDefinition(),
    690         sizeof(paramPortDefinitionInput));
    691 
    692     memcpy(&paramPortDefinitionOutput,
    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(&paramPortDefinitionInput, true);
    735         this->ports[OUTPORT_INDEX]->SetPortDefinition(&paramPortDefinitionOutput, 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(&paramPortDefinitionInput, 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(&paramPortDefinitionInput, true);
    816     this->ports[OUTPORT_INDEX]->SetPortDefinition(&paramPortDefinitionOutput, 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