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 
     18 #define LOG_TAG "OMXVideoEncoderBase"
     19 #include "OMXVideoEncoderBase.h"
     20 #include "IntelMetadataBuffer.h"
     21 #include <cutils/properties.h>
     22 #include <wrs_omxil_core/log.h>
     23 #include <media/stagefright/foundation/AUtils.h>
     24 
     25 static const char *RAW_MIME_TYPE = "video/raw";
     26 
     27 OMXVideoEncoderBase::OMXVideoEncoderBase()
     28     :mVideoEncoder(NULL)
     29     ,mEncoderParams(NULL)
     30     ,mFrameInputCount(0)
     31     ,mFrameOutputCount(0)
     32     ,mFirstFrame(OMX_TRUE)
     33     ,mFrameRetrieved(OMX_TRUE)
     34     ,mStoreMetaDataInBuffers(OMX_FALSE)
     35     ,mSyncEncoding(OMX_TRUE)
     36     ,mOmxLogLevel(0)
     37     ,mBlackFramePointer(NULL) {
     38     mEncoderParams = new VideoParamsCommon();
     39     if (!mEncoderParams) LOGE("OMX_ErrorInsufficientResources");
     40 
     41     char logLevelProp[128];
     42     if (property_get("omxenc.debug", logLevelProp, NULL)) {
     43         mOmxLogLevel = atoi(logLevelProp);
     44         LOGD("Debug level is %d", mOmxLogLevel);
     45     }
     46 
     47     LOGV("OMXVideoEncoderBase::OMXVideoEncoderBase end");
     48 }
     49 
     50 OMXVideoEncoderBase::~OMXVideoEncoderBase() {
     51 
     52     // destroy ports
     53     if (this->ports) {
     54         if (this->ports[INPORT_INDEX]) {
     55             delete this->ports[INPORT_INDEX];
     56             this->ports[INPORT_INDEX] = NULL;
     57         }
     58 
     59         if (this->ports[OUTPORT_INDEX]) {
     60             delete this->ports[OUTPORT_INDEX];
     61             this->ports[OUTPORT_INDEX] = NULL;
     62         }
     63     }
     64 
     65     if (mBlackFramePointer) {
     66         free(mBlackFramePointer);
     67         mBlackFramePointer = NULL;
     68     }
     69     // Release video encoder object
     70     if(mVideoEncoder) {
     71         releaseVideoEncoder(mVideoEncoder);
     72         mVideoEncoder = NULL;
     73     }
     74 
     75     if(mEncoderParams) {
     76         delete mEncoderParams;
     77         mEncoderParams = NULL;
     78     }
     79 
     80 }
     81 
     82 OMX_ERRORTYPE OMXVideoEncoderBase::InitInputPort(void) {
     83     this->ports[INPORT_INDEX] = new PortVideo;
     84     if (this->ports[INPORT_INDEX] == NULL) {
     85         return OMX_ErrorInsufficientResources;
     86     }
     87 
     88     PortVideo *port = static_cast<PortVideo *>(this->ports[INPORT_INDEX]);
     89 
     90     // OMX_PARAM_PORTDEFINITIONTYPE
     91     OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionInput;
     92     memset(&paramPortDefinitionInput, 0, sizeof(paramPortDefinitionInput));
     93     SetTypeHeader(&paramPortDefinitionInput, sizeof(paramPortDefinitionInput));
     94     paramPortDefinitionInput.nPortIndex = INPORT_INDEX;
     95     paramPortDefinitionInput.eDir = OMX_DirInput;
     96     paramPortDefinitionInput.nBufferCountActual = INPORT_ACTUAL_BUFFER_COUNT;
     97     paramPortDefinitionInput.nBufferCountMin = INPORT_MIN_BUFFER_COUNT;
     98     paramPortDefinitionInput.nBufferSize = INPORT_BUFFER_SIZE;
     99     paramPortDefinitionInput.bEnabled = OMX_TRUE;
    100     paramPortDefinitionInput.bPopulated = OMX_FALSE;
    101     paramPortDefinitionInput.eDomain = OMX_PortDomainVideo;
    102     paramPortDefinitionInput.format.video.cMIMEType = (OMX_STRING)RAW_MIME_TYPE;
    103     paramPortDefinitionInput.format.video.pNativeRender = NULL;
    104     paramPortDefinitionInput.format.video.nFrameWidth = 176;
    105     paramPortDefinitionInput.format.video.nFrameHeight = 144;
    106     paramPortDefinitionInput.format.video.nStride = 0;
    107     paramPortDefinitionInput.format.video.nSliceHeight = 0;
    108     paramPortDefinitionInput.format.video.nBitrate = 64000;
    109     paramPortDefinitionInput.format.video.xFramerate = 15 << 16;
    110     paramPortDefinitionInput.format.video.bFlagErrorConcealment = OMX_FALSE;
    111     paramPortDefinitionInput.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
    112     paramPortDefinitionInput.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
    113     paramPortDefinitionInput.format.video.pNativeWindow = NULL;
    114     paramPortDefinitionInput.bBuffersContiguous = OMX_FALSE;
    115     paramPortDefinitionInput.nBufferAlignment = 0;
    116 
    117     // Nothing specific to initialize input port.
    118     InitInputPortFormatSpecific(&paramPortDefinitionInput);
    119 
    120     port->SetPortDefinition(&paramPortDefinitionInput, true);
    121 
    122     // Set port buffer 4k aligned
    123     port->SetMemAlignment(4096);
    124 
    125     // OMX_VIDEO_PARAM_PORTFORMATTYPE
    126     OMX_VIDEO_PARAM_PORTFORMATTYPE paramPortFormat;
    127     memset(&paramPortFormat, 0, sizeof(paramPortFormat));
    128     SetTypeHeader(&paramPortFormat, sizeof(paramPortFormat));
    129     paramPortFormat.nPortIndex = INPORT_INDEX;
    130     paramPortFormat.nIndex = 0;
    131     paramPortFormat.eCompressionFormat = paramPortDefinitionInput.format.video.eCompressionFormat;
    132     paramPortFormat.eColorFormat = paramPortDefinitionInput.format.video.eColorFormat;
    133     paramPortFormat.xFramerate = paramPortDefinitionInput.format.video.xFramerate;
    134 
    135     port->SetPortVideoParam(&paramPortFormat, true);
    136 
    137     return OMX_ErrorNone;
    138 }
    139 
    140 
    141 OMX_ERRORTYPE OMXVideoEncoderBase::InitOutputPort(void) {
    142     this->ports[OUTPORT_INDEX] = new PortVideo;
    143     if (this->ports[OUTPORT_INDEX] == NULL) {
    144         return OMX_ErrorInsufficientResources;
    145     }
    146 
    147     PortVideo *port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]);
    148 
    149     // OMX_VIDEO_PARAM_BITRATETYPE
    150     memset(&mParamBitrate, 0, sizeof(mParamBitrate));
    151     SetTypeHeader(&mParamBitrate, sizeof(mParamBitrate));
    152     mParamBitrate.nPortIndex = OUTPORT_INDEX;
    153     mParamBitrate.eControlRate = OMX_Video_ControlRateVariable;
    154     mParamBitrate.nTargetBitrate = 192000; // to be overridden
    155 
    156     // OMX_VIDEO_CONFIG_PRI_INFOTYPE
    157     memset(&mConfigPriInfo, 0, sizeof(mConfigPriInfo));
    158     SetTypeHeader(&mConfigPriInfo, sizeof(mConfigPriInfo));
    159     mConfigPriInfo.nPortIndex = OUTPORT_INDEX;
    160     mConfigPriInfo.nCapacity = 0;
    161     mConfigPriInfo.nHolder = NULL;
    162 
    163     // OMX_VIDEO_CONFIG_INTEL_BITRATETYPE
    164     memset(&mConfigIntelBitrate, 0, sizeof(mConfigIntelBitrate));
    165     SetTypeHeader(&mConfigIntelBitrate, sizeof(mConfigIntelBitrate));
    166     mConfigIntelBitrate.nPortIndex = OUTPORT_INDEX;
    167     mConfigIntelBitrate.nMaxEncodeBitrate = 0; // Maximum bitrate
    168     mConfigIntelBitrate.nTargetPercentage = 95; // Target bitrate as percentage of maximum bitrate; e.g. 95 is 95%
    169     mConfigIntelBitrate.nWindowSize = 0; // Window size in milliseconds allowed for bitrate to reach target
    170     mConfigIntelBitrate.nInitialQP = 0;  // Initial QP for I frames
    171     mConfigIntelBitrate.nMinQP = 0;
    172     mConfigIntelBitrate.nMaxQP = 0;
    173     mConfigIntelBitrate.nFrameRate = 0;
    174     mConfigIntelBitrate.nTemporalID = 0;
    175 
    176     // OMX_VIDEO_CONFIG_BITRATETYPE
    177     memset(&mConfigBitrate, 0, sizeof(mConfigBitrate));
    178     SetTypeHeader(&mConfigBitrate, sizeof(mConfigBitrate));
    179     mConfigBitrate.nPortIndex = OUTPORT_INDEX;
    180     mConfigBitrate.nEncodeBitrate = 0; // Maximum bitrate
    181 
    182     // OMX_VIDEO_CONFIG_INTEL_AIR
    183     memset(&mConfigIntelAir, 0, sizeof(mConfigIntelAir));
    184     SetTypeHeader(&mConfigIntelAir, sizeof(mConfigIntelAir));
    185     mConfigIntelAir.nPortIndex = OUTPORT_INDEX;
    186     mConfigIntelAir.bAirEnable = OMX_FALSE;
    187     mConfigIntelAir.bAirAuto = OMX_FALSE;
    188     mConfigIntelAir.nAirMBs = 0;
    189     mConfigIntelAir.nAirThreshold = 0;
    190 
    191     // OMX_VIDEO_CONFIG_INTEL_AIR
    192     memset(&mParamVideoRefresh, 0, sizeof(mParamVideoRefresh));
    193     SetTypeHeader(&mParamVideoRefresh, sizeof(mParamVideoRefresh));
    194     mParamVideoRefresh.nPortIndex = OUTPORT_INDEX;
    195     mParamVideoRefresh.eRefreshMode = OMX_VIDEO_IntraRefreshAdaptive;
    196     mParamVideoRefresh.nAirMBs = 0;
    197     mParamVideoRefresh.nAirRef = 0;
    198     mParamVideoRefresh.nCirMBs = 0;
    199 
    200     // OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESH
    201     memset(&mConfigAndroidIntraRefresh, 0, sizeof(mConfigAndroidIntraRefresh));
    202     SetTypeHeader(&mConfigAndroidIntraRefresh, sizeof(mConfigAndroidIntraRefresh));
    203     mConfigAndroidIntraRefresh.nPortIndex = OUTPORT_INDEX;
    204     mConfigAndroidIntraRefresh.nRefreshPeriod = 0; // default feature closed
    205 
    206     // OMX_CONFIG_FRAMERATETYPE
    207     memset(&mConfigFramerate, 0, sizeof(mConfigFramerate));
    208     SetTypeHeader(&mConfigFramerate, sizeof(mConfigFramerate));
    209     mConfigFramerate.nPortIndex = OUTPORT_INDEX;
    210     mConfigFramerate.xEncodeFramerate =  0; // Q16 format
    211 
    212     // OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL
    213     memset(&mParamIntelAdaptiveSliceControl, 0, sizeof(mParamIntelAdaptiveSliceControl));
    214     SetTypeHeader(&mParamIntelAdaptiveSliceControl, sizeof(mParamIntelAdaptiveSliceControl));
    215     mParamIntelAdaptiveSliceControl.nPortIndex = OUTPORT_INDEX;
    216     mParamIntelAdaptiveSliceControl.bEnable = OMX_FALSE;
    217     mParamIntelAdaptiveSliceControl.nMinPSliceNumber = 5;
    218     mParamIntelAdaptiveSliceControl.nNumPFramesToSkip = 8;
    219     mParamIntelAdaptiveSliceControl.nSliceSizeThreshold = 1200;
    220 
    221     // OMX_VIDEO_PARAM_PROFILELEVELTYPE
    222     memset(&mParamProfileLevel, 0, sizeof(mParamProfileLevel));
    223     SetTypeHeader(&mParamProfileLevel, sizeof(mParamProfileLevel));
    224     mParamProfileLevel.nPortIndex = OUTPORT_INDEX;
    225     mParamProfileLevel.eProfile = 0; // undefined profile, to be overridden
    226     mParamProfileLevel.eLevel = 0; // undefined level, to be overridden
    227 
    228     // OMX_PARAM_PORTDEFINITIONTYPE
    229     OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionOutput;
    230     memset(&paramPortDefinitionOutput, 0, sizeof(paramPortDefinitionOutput));
    231     SetTypeHeader(&paramPortDefinitionOutput, sizeof(paramPortDefinitionOutput));
    232     paramPortDefinitionOutput.nPortIndex = OUTPORT_INDEX;
    233     paramPortDefinitionOutput.eDir = OMX_DirOutput;
    234     paramPortDefinitionOutput.nBufferCountActual = OUTPORT_ACTUAL_BUFFER_COUNT; // to be overridden
    235     paramPortDefinitionOutput.nBufferCountMin = OUTPORT_MIN_BUFFER_COUNT;
    236     paramPortDefinitionOutput.nBufferSize = OUTPORT_BUFFER_SIZE; // to be overridden
    237     paramPortDefinitionOutput.bEnabled = OMX_TRUE;
    238     paramPortDefinitionOutput.bPopulated = OMX_FALSE;
    239     paramPortDefinitionOutput.eDomain = OMX_PortDomainVideo;
    240     paramPortDefinitionOutput.format.video.cMIMEType = NULL; // to be overridden
    241     paramPortDefinitionOutput.format.video.pNativeRender = NULL;
    242     paramPortDefinitionOutput.format.video.nFrameWidth = 176;
    243     paramPortDefinitionOutput.format.video.nFrameHeight = 144;
    244     paramPortDefinitionOutput.format.video.nStride = 176;
    245     paramPortDefinitionOutput.format.video.nSliceHeight = 144;
    246     paramPortDefinitionOutput.format.video.nBitrate = 64000;
    247     paramPortDefinitionOutput.format.video.xFramerate = 15 << 16;
    248     paramPortDefinitionOutput.format.video.bFlagErrorConcealment = OMX_FALSE;
    249     paramPortDefinitionOutput.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; // to be overridden
    250     paramPortDefinitionOutput.format.video.eColorFormat = OMX_COLOR_FormatUnused;
    251     paramPortDefinitionOutput.format.video.pNativeWindow = NULL;
    252     paramPortDefinitionOutput.bBuffersContiguous = OMX_FALSE;
    253     paramPortDefinitionOutput.nBufferAlignment = 0;
    254 
    255     InitOutputPortFormatSpecific(&paramPortDefinitionOutput);
    256 
    257     port->SetPortDefinition(&paramPortDefinitionOutput, true);
    258     port->SetPortBitrateParam(&mParamBitrate, true);
    259 
    260     // OMX_VIDEO_PARAM_PORTFORMATTYPE
    261     OMX_VIDEO_PARAM_PORTFORMATTYPE paramPortFormat;
    262     memset(&paramPortFormat, 0, sizeof(paramPortFormat));
    263     SetTypeHeader(&paramPortFormat, sizeof(paramPortFormat));
    264     paramPortFormat.nPortIndex = OUTPORT_INDEX;
    265     paramPortFormat.nIndex = 0;
    266     paramPortFormat.eCompressionFormat = paramPortDefinitionOutput.format.video.eCompressionFormat;
    267     paramPortFormat.eColorFormat = paramPortDefinitionOutput.format.video.eColorFormat;
    268     paramPortFormat.xFramerate = paramPortDefinitionOutput.format.video.xFramerate;
    269 
    270     port->SetPortVideoParam(&paramPortFormat, true);
    271     return OMX_ErrorNone;
    272 }
    273 
    274 OMX_ERRORTYPE OMXVideoEncoderBase::InitInputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *) {
    275     // no format specific to initialize input
    276     return OMX_ErrorNone;
    277 }
    278 
    279 OMX_ERRORTYPE OMXVideoEncoderBase::SetVideoEncoderParam() {
    280 
    281     Encode_Status ret = ENCODE_SUCCESS;
    282     PortVideo *port_in = NULL;
    283     const OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput = NULL;
    284     LOGV("OMXVideoEncoderBase::SetVideoEncoderParam called\n");
    285 
    286     port_in = static_cast<PortVideo *>(ports[INPORT_INDEX]);
    287     paramPortDefinitionInput = port_in->GetPortDefinition();
    288     mEncoderParams->resolution.height = paramPortDefinitionInput->format.video.nFrameHeight;
    289     mEncoderParams->resolution.width = paramPortDefinitionInput->format.video.nFrameWidth;
    290 
    291     mEncoderParams->frameRate.frameRateDenom = 1;
    292     if(mConfigFramerate.xEncodeFramerate != 0) {
    293         mEncoderParams->frameRate.frameRateNum = mConfigFramerate.xEncodeFramerate;
    294     } else {
    295         mEncoderParams->frameRate.frameRateNum = paramPortDefinitionInput->format.video.xFramerate >> 16;
    296         mConfigFramerate.xEncodeFramerate = paramPortDefinitionInput->format.video.xFramerate >> 16;
    297     }
    298 
    299     if(mEncoderParams->intraPeriod == 0) {
    300         OMX_U32 intraPeriod = mEncoderParams->frameRate.frameRateNum / 2;
    301         mEncoderParams->intraPeriod = (intraPeriod < 15) ? 15 : intraPeriod;   // Limit intra frame period to ensure video quality for low bitrate application.
    302     }
    303 
    304     if (paramPortDefinitionInput->format.video.eColorFormat == OMX_COLOR_FormatAndroidOpaque)
    305         mEncoderParams->rawFormat = RAW_FORMAT_OPAQUE;
    306     else
    307         mEncoderParams->rawFormat = RAW_FORMAT_NV12;
    308 
    309     LOGV("frameRate.frameRateDenom = %d\n", mEncoderParams->frameRate.frameRateDenom);
    310     LOGV("frameRate.frameRateNum = %d\n", mEncoderParams->frameRate.frameRateNum);
    311     LOGV("intraPeriod = %d\n ", mEncoderParams->intraPeriod);
    312     mEncoderParams->rcParams.initQP = mConfigIntelBitrate.nInitialQP;
    313     mEncoderParams->rcParams.minQP = mConfigIntelBitrate.nMinQP;
    314     mEncoderParams->rcParams.maxQP = 0;
    315     mEncoderParams->rcParams.I_minQP = 0;
    316     mEncoderParams->rcParams.I_maxQP = 0;
    317     mEncoderParams->rcParams.windowSize = mConfigIntelBitrate.nWindowSize;
    318     mEncoderParams->rcParams.targetPercentage = mConfigIntelBitrate.nTargetPercentage;
    319     mEncoderParams->rcParams.enableIntraFrameQPControl = 0;
    320 
    321     mEncoderParams->rcParams.bitRate = mParamBitrate.nTargetBitrate;
    322     if ((mParamBitrate.eControlRate == OMX_Video_ControlRateConstant )||
    323             (mParamBitrate.eControlRate == OMX_Video_ControlRateConstantSkipFrames)) {
    324         LOGV("%s(), eControlRate == OMX_Video_Intel_ControlRateConstant", __func__);
    325         mEncoderParams->rcMode = RATE_CONTROL_CBR;
    326     } else if ((mParamBitrate.eControlRate == OMX_Video_ControlRateVariable) ||
    327             (mParamBitrate.eControlRate == OMX_Video_ControlRateVariableSkipFrames)) {
    328         LOGV("%s(), eControlRate == OMX_Video_Intel_ControlRateVariable", __func__);
    329         mEncoderParams->rcMode = RATE_CONTROL_VBR;
    330     } else if (mParamBitrate.eControlRate == (OMX_VIDEO_CONTROLRATETYPE)OMX_Video_Intel_ControlRateVideoConferencingMode) {
    331         LOGV("%s(), eControlRate == OMX_Video_Intel_ControlRateVideoConferencingMode ", __func__);
    332         mEncoderParams->rcMode = RATE_CONTROL_VCM;
    333         if(mConfigIntelBitrate.nMaxEncodeBitrate >0)
    334             mEncoderParams->rcParams.bitRate = mConfigIntelBitrate.nMaxEncodeBitrate;
    335         if(mConfigIntelAir.bAirEnable == OMX_TRUE) {
    336             mEncoderParams->airParams.airAuto = mConfigIntelAir.bAirAuto;
    337             mEncoderParams->airParams.airMBs = mConfigIntelAir.nAirMBs;
    338             mEncoderParams->airParams.airThreshold = mConfigIntelAir.nAirThreshold;
    339             mEncoderParams->refreshType = VIDEO_ENC_AIR;
    340         } else {
    341             mEncoderParams->refreshType = VIDEO_ENC_NONIR;
    342         }
    343         LOGV("refreshType = %d\n", mEncoderParams->refreshType);
    344     } else {
    345         mEncoderParams->rcMode = RATE_CONTROL_NONE;
    346     }
    347 
    348     ret = mVideoEncoder->setParameters(mEncoderParams);
    349     CHECK_ENCODE_STATUS("setParameters");
    350     return OMX_ErrorNone;
    351 }
    352 
    353 OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorInit(void) {
    354     OMX_ERRORTYPE ret = OMX_ErrorNone;
    355     ret = SetVideoEncoderParam();
    356     CHECK_STATUS("SetVideoEncoderParam");
    357 
    358     Encode_Status status = mVideoEncoder->start();
    359     if (status != ENCODE_SUCCESS) {
    360         LOGE("Start failed, status = 0x%08x\n", status);
    361         return OMX_ErrorUndefined;
    362     }
    363 
    364     return OMX_ErrorNone;
    365 }
    366 
    367 OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorDeinit(void) {
    368     if(mVideoEncoder) {
    369         mVideoEncoder->stop();
    370     }
    371 
    372     return OMX_ErrorNone;
    373 }
    374 
    375 OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorStop(void) {
    376 
    377     this->ports[INPORT_INDEX]->ReturnAllRetainedBuffers();
    378     return OMX_ErrorNone;
    379 }
    380 OMX_ERRORTYPE OMXVideoEncoderBase:: ProcessorProcess(
    381     OMX_BUFFERHEADERTYPE **,
    382     buffer_retain_t *,
    383     OMX_U32) {
    384 
    385     LOGV("OMXVideoEncoderBase:: ProcessorProcess \n");
    386     return OMX_ErrorNone;
    387 }
    388 
    389 OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorFlush(OMX_U32 portIndex) {
    390     LOGV("OMXVideoEncoderBase::ProcessorFlush\n");
    391     if (portIndex == INPORT_INDEX || portIndex == OMX_ALL) {
    392         this->ports[INPORT_INDEX]->ReturnAllRetainedBuffers();
    393         mVideoEncoder->flush();
    394     }
    395     return OMX_ErrorNone;
    396 }
    397 
    398 OMX_ERRORTYPE OMXVideoEncoderBase::BuildHandlerList(void) {
    399     OMXComponentCodecBase::BuildHandlerList();
    400     AddHandler(OMX_IndexParamVideoPortFormat, GetParamVideoPortFormat, SetParamVideoPortFormat);
    401     AddHandler(OMX_IndexParamVideoBitrate, GetParamVideoBitrate, SetParamVideoBitrate);
    402     AddHandler((OMX_INDEXTYPE)OMX_IndexIntelPrivateInfo, GetIntelPrivateInfo, SetIntelPrivateInfo);
    403     AddHandler((OMX_INDEXTYPE)OMX_IndexConfigIntelBitrate, GetConfigIntelBitrate, SetConfigIntelBitrate);
    404     AddHandler((OMX_INDEXTYPE)OMX_IndexConfigIntelAIR, GetConfigIntelAIR, SetConfigIntelAIR);
    405     AddHandler((OMX_INDEXTYPE)OMX_IndexParamVideoIntraRefresh, GetParamVideoIntraRefresh, SetParamVideoIntraRefresh);
    406     AddHandler(OMX_IndexConfigVideoFramerate, GetConfigVideoFramerate, SetConfigVideoFramerate);
    407     AddHandler(OMX_IndexConfigVideoIntraVOPRefresh, GetConfigVideoIntraVOPRefresh, SetConfigVideoIntraVOPRefresh);
    408     //AddHandler(OMX_IndexParamIntelAdaptiveSliceControl, GetParamIntelAdaptiveSliceControl, SetParamIntelAdaptiveSliceControl);
    409     //AddHandler(OMX_IndexParamVideoProfileLevelQuerySupported, GetParamVideoProfileLevelQuerySupported, SetParamVideoProfileLevelQuerySupported);
    410     AddHandler((OMX_INDEXTYPE)OMX_IndexStoreMetaDataInBuffers, GetStoreMetaDataInBuffers, SetStoreMetaDataInBuffers);
    411     AddHandler((OMX_INDEXTYPE)OMX_IndexExtSyncEncoding, GetSyncEncoding, SetSyncEncoding);
    412     AddHandler((OMX_INDEXTYPE)OMX_IndexExtPrependSPSPPS, GetPrependSPSPPS, SetPrependSPSPPS);
    413     AddHandler((OMX_INDEXTYPE)OMX_IndexExtTemporalLayer, GetTemporalLayer,SetTemporalLayer);
    414     AddHandler((OMX_INDEXTYPE)OMX_IndexConfigVideoBitrate, GetConfigVideoBitrate, SetConfigVideoBitrate);
    415     AddHandler((OMX_INDEXTYPE)OMX_IndexExtRequestBlackFramePointer, GetBlackFramePointer, GetBlackFramePointer);
    416     AddHandler((OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, GetConfigAndroidIntraRefresh, SetConfigAndroidIntraRefresh);
    417     return OMX_ErrorNone;
    418 }
    419 
    420 OMX_ERRORTYPE OMXVideoEncoderBase::GetParamVideoPortFormat(OMX_PTR pStructure) {
    421     OMX_ERRORTYPE ret;
    422     OMX_U32 index;
    423     OMX_VIDEO_PARAM_PORTFORMATTYPE *p = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pStructure;
    424 
    425     CHECK_TYPE_HEADER(p);
    426     CHECK_PORT_INDEX_RANGE(p);
    427     CHECK_ENUMERATION_RANGE(p->nIndex, 2);
    428 
    429     PortVideo *port = NULL;
    430     port = static_cast<PortVideo *>(this->ports[p->nPortIndex]);
    431     index = p->nIndex;
    432     memcpy(p, port->GetPortVideoParam(), sizeof(*p));
    433     // port supports OMX_COLOR_FormatYUV420SemiPlanar & OMX_COLOR_FormatAndroidOpaque
    434     if (index == 1) {
    435         p->nIndex = 1;
    436         p->eColorFormat = OMX_COLOR_FormatAndroidOpaque;
    437     }
    438     return OMX_ErrorNone;
    439 }
    440 
    441 OMX_ERRORTYPE OMXVideoEncoderBase::SetParamVideoPortFormat(OMX_PTR pStructure) {
    442     OMX_ERRORTYPE ret;
    443     OMX_VIDEO_PARAM_PORTFORMATTYPE *p = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pStructure;
    444 
    445     CHECK_TYPE_HEADER(p);
    446     CHECK_PORT_INDEX_RANGE(p);
    447     CHECK_SET_PARAM_STATE();
    448 
    449     // TODO: do we need to check if port is enabled?
    450     PortVideo *port = NULL;
    451     port = static_cast<PortVideo *>(this->ports[p->nPortIndex]);
    452 #if 0
    453     if (p->eColorFormat ==  OMX_COLOR_FormatAndroidOpaque) {
    454         p->nIndex = 0;
    455         p->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
    456     }
    457 #endif
    458     port->SetPortVideoParam(p, false);
    459     return OMX_ErrorNone;
    460 }
    461 
    462 OMX_ERRORTYPE OMXVideoEncoderBase::GetParamVideoBitrate(OMX_PTR pStructure) {
    463     OMX_ERRORTYPE ret;
    464     OMX_VIDEO_PARAM_BITRATETYPE *p = (OMX_VIDEO_PARAM_BITRATETYPE *)pStructure;
    465 
    466     CHECK_TYPE_HEADER(p);
    467     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    468     memcpy(p, &mParamBitrate, sizeof(*p));
    469     return OMX_ErrorNone;
    470 }
    471 
    472 OMX_ERRORTYPE OMXVideoEncoderBase::SetParamVideoBitrate(OMX_PTR pStructure) {
    473     OMX_ERRORTYPE ret;
    474     OMX_VIDEO_PARAM_BITRATETYPE *p = (OMX_VIDEO_PARAM_BITRATETYPE *)pStructure;
    475     CHECK_TYPE_HEADER(p);
    476     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    477     CHECK_SET_PARAM_STATE();
    478     OMX_U32 index = p->nPortIndex;
    479     PortVideo *port = NULL;
    480     // This disables other type of bitrate control mechanism
    481     // TODO: check if it is desired
    482 
    483     // TODO: can we override  mParamBitrate.nPortIndex (See SetPortBitrateParam)
    484     mParamBitrate.eControlRate = p->eControlRate;
    485     mParamBitrate.nTargetBitrate = p->nTargetBitrate;
    486 
    487     port = static_cast<PortVideo *>(ports[index]);
    488     ret = port->SetPortBitrateParam(p, false);
    489     return OMX_ErrorNone;
    490 }
    491 
    492 OMX_ERRORTYPE OMXVideoEncoderBase::GetIntelPrivateInfo(OMX_PTR pStructure) {
    493     OMX_ERRORTYPE ret;
    494     OMX_VIDEO_CONFIG_PRI_INFOTYPE *p = (OMX_VIDEO_CONFIG_PRI_INFOTYPE *)pStructure;
    495 
    496     CHECK_TYPE_HEADER(p);
    497     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    498     memcpy(p, &mConfigPriInfo, sizeof(*p));
    499     return OMX_ErrorNone;
    500 }
    501 
    502 OMX_ERRORTYPE OMXVideoEncoderBase::SetIntelPrivateInfo(OMX_PTR pStructure) {
    503     OMX_ERRORTYPE ret;
    504     OMX_VIDEO_CONFIG_PRI_INFOTYPE *p = (OMX_VIDEO_CONFIG_PRI_INFOTYPE *)pStructure;
    505     CHECK_TYPE_HEADER(p);
    506     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    507 
    508     // OMX_VIDEO_CONFIG_PRI_INFOTYPE is static parameter?
    509     CHECK_SET_PARAM_STATE();
    510 
    511     // TODO: can we override  mConfigPriInfo.nPortIndex (See SetPortPrivateInfoParam)
    512 
    513     if(p->nHolder != NULL) {
    514         // TODO: do we need to free nHolder?
    515         if (mConfigPriInfo.nHolder) {
    516             free(mConfigPriInfo.nHolder);
    517         }
    518         mConfigPriInfo.nCapacity = p->nCapacity;
    519         // TODO: nCapacity is in 8-bit unit or 32-bit unit?
    520         // TODO: check memory allocation
    521         mConfigPriInfo.nHolder = (OMX_PTR)malloc(sizeof(OMX_U32) * p->nCapacity);
    522         memcpy(mConfigPriInfo.nHolder, p->nHolder, sizeof(OMX_U32) * p->nCapacity);
    523     } else {
    524         mConfigPriInfo.nCapacity = 0;
    525         mConfigPriInfo.nHolder = NULL;
    526     }
    527 
    528     return OMX_ErrorNone;
    529 }
    530 
    531 OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigIntelBitrate(OMX_PTR pStructure) {
    532     OMX_ERRORTYPE ret;
    533     OMX_VIDEO_CONFIG_INTEL_BITRATETYPE *p = (OMX_VIDEO_CONFIG_INTEL_BITRATETYPE *)pStructure;
    534 
    535     CHECK_TYPE_HEADER(p);
    536     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    537     memcpy(p, &mConfigIntelBitrate, sizeof(*p));
    538     return OMX_ErrorNone;
    539 }
    540 
    541 OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigIntelBitrate(OMX_PTR pStructure) {
    542     OMX_ERRORTYPE ret;
    543     Encode_Status retStatus = ENCODE_SUCCESS;
    544     if (mParamBitrate.eControlRate == OMX_Video_ControlRateMax){
    545         LOGE("SetConfigIntelBitrate failed. Feature is disabled.");
    546         return OMX_ErrorUnsupportedIndex;
    547     }
    548     OMX_VIDEO_CONFIG_INTEL_BITRATETYPE *p = (OMX_VIDEO_CONFIG_INTEL_BITRATETYPE *)pStructure;
    549     CHECK_TYPE_HEADER(p);
    550     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    551 
    552     // set in either Loaded state (ComponentSetParam) or Executing state (ComponentSetConfig)
    553     mConfigIntelBitrate = *p;
    554 
    555     // return OMX_ErrorNone if not in Executing state
    556     // TODO: return OMX_ErrorIncorrectStateOperation?
    557     CHECK_SET_CONFIG_STATE();
    558 
    559     VideoConfigBitRate configBitRate;
    560     configBitRate.rcParams.bitRate = mConfigIntelBitrate.nMaxEncodeBitrate;
    561     configBitRate.rcParams.initQP = mConfigIntelBitrate.nInitialQP;
    562     configBitRate.rcParams.minQP = mConfigIntelBitrate.nMinQP;
    563     configBitRate.rcParams.maxQP = mConfigIntelBitrate.nMaxQP;
    564     configBitRate.rcParams.I_minQP = 0;
    565     configBitRate.rcParams.I_maxQP = 0;
    566     configBitRate.rcParams.windowSize = mConfigIntelBitrate.nWindowSize;
    567     configBitRate.rcParams.targetPercentage = mConfigIntelBitrate.nTargetPercentage;
    568     configBitRate.rcParams.enableIntraFrameQPControl = 0;
    569     configBitRate.rcParams.temporalFrameRate = mConfigIntelBitrate.nFrameRate;
    570     configBitRate.rcParams.temporalID = mConfigIntelBitrate.nTemporalID;
    571     retStatus = mVideoEncoder->setConfig(&configBitRate);
    572     if(retStatus != ENCODE_SUCCESS) {
    573         LOGW("failed to set IntelBitrate");
    574     }
    575     return OMX_ErrorNone;
    576 }
    577 
    578 OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigIntelAIR(OMX_PTR pStructure) {
    579     OMX_ERRORTYPE ret;
    580     OMX_VIDEO_CONFIG_INTEL_AIR *p = (OMX_VIDEO_CONFIG_INTEL_AIR *)pStructure;
    581 
    582     CHECK_TYPE_HEADER(p);
    583     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    584     memcpy(p, &mConfigIntelAir, sizeof(*p));
    585     return OMX_ErrorNone;
    586 }
    587 
    588 OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigIntelAIR(OMX_PTR pStructure) {
    589     OMX_ERRORTYPE ret;
    590     Encode_Status retStatus = ENCODE_SUCCESS;
    591 
    592     OMX_VIDEO_CONFIG_INTEL_AIR *p = (OMX_VIDEO_CONFIG_INTEL_AIR *)pStructure;
    593     CHECK_TYPE_HEADER(p);
    594     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    595 
    596     // set in either Loaded  state (ComponentSetParam) or Executing state (ComponentSetConfig)
    597     mConfigIntelAir = *p;
    598 
    599     // return OMX_ErrorNone if not in Executing state
    600     // TODO: return OMX_ErrorIncorrectStateOperation?
    601     CHECK_SET_CONFIG_STATE();
    602 
    603     VideoConfigAIR configAIR;
    604     VideoConfigIntraRefreshType configIntraRefreshType;
    605     if(mConfigIntelAir.bAirEnable == OMX_TRUE) {
    606         configAIR.airParams.airAuto = mConfigIntelAir.bAirAuto;
    607         configAIR.airParams.airMBs = mConfigIntelAir.nAirMBs;
    608         configAIR.airParams.airThreshold = mConfigIntelAir.nAirThreshold;
    609         configIntraRefreshType.refreshType = VIDEO_ENC_AIR;
    610     } else {
    611         configIntraRefreshType.refreshType = VIDEO_ENC_NONIR;
    612     }
    613 
    614     retStatus = mVideoEncoder->setConfig(&configAIR);
    615     if(retStatus != ENCODE_SUCCESS) {
    616         LOGW("Failed to set AIR config");
    617     }
    618 
    619     retStatus = mVideoEncoder->setConfig(&configIntraRefreshType);
    620     if(retStatus != ENCODE_SUCCESS) {
    621         LOGW("Failed to set refresh config");
    622     }
    623     return OMX_ErrorNone;
    624 }
    625 
    626 OMX_ERRORTYPE OMXVideoEncoderBase::GetParamVideoIntraRefresh(OMX_PTR pStructure) {
    627     OMX_ERRORTYPE ret;
    628     OMX_VIDEO_PARAM_INTRAREFRESHTYPE *p = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)pStructure;
    629 
    630     CHECK_TYPE_HEADER(p);
    631     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    632     memcpy(p, &mParamVideoRefresh, sizeof(*p));
    633     return OMX_ErrorNone;
    634 }
    635 
    636 OMX_ERRORTYPE OMXVideoEncoderBase::SetParamVideoIntraRefresh(OMX_PTR pStructure) {
    637     OMX_ERRORTYPE ret;
    638     Encode_Status retStatus = ENCODE_SUCCESS;
    639 
    640     OMX_VIDEO_PARAM_INTRAREFRESHTYPE *p = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)pStructure;
    641     CHECK_TYPE_HEADER(p);
    642     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    643 
    644     // set in either Loaded  state (ComponentSetParam) or Executing state (ComponentSetConfig)
    645     mParamVideoRefresh = *p;
    646 
    647     // return OMX_ErrorNone if not in Executing state
    648     // TODO: return OMX_ErrorIncorrectStateOperation?
    649     CHECK_SET_PARAM_STATE();
    650 
    651     VideoConfigIntraRefreshType configIntraRefreshType;
    652     configIntraRefreshType.refreshType = (VideoIntraRefreshType)(mParamVideoRefresh.eRefreshMode + 1);
    653     if(configIntraRefreshType.refreshType == VIDEO_ENC_CIR){
    654      VideoConfigCIR configCIR;
    655         VideoConfigIntraRefreshType configIntraRefreshType;
    656         configCIR.cirParams.cir_num_mbs = mParamVideoRefresh.nCirMBs;
    657         configIntraRefreshType.refreshType = VIDEO_ENC_CIR;
    658 
    659         retStatus = mVideoEncoder->setConfig(&configCIR);
    660         if(retStatus != ENCODE_SUCCESS) {
    661             LOGW("Failed to set CIR config");
    662         }
    663     }else{
    664         VideoConfigAIR configAIR;
    665 
    666         configAIR.airParams.airMBs = mParamVideoRefresh.nAirMBs;
    667         configAIR.airParams.airThreshold = mParamVideoRefresh.nAirRef;
    668 
    669         retStatus = mVideoEncoder->setConfig(&configAIR);
    670         if(retStatus != ENCODE_SUCCESS) {
    671             LOGW("Failed to set AIR config");
    672         }
    673 
    674     }
    675 
    676     retStatus = mVideoEncoder->setConfig(&configIntraRefreshType);
    677     if(retStatus != ENCODE_SUCCESS) {
    678         LOGW("Failed to set refresh config");
    679     }
    680 
    681     return OMX_ErrorNone;
    682 }
    683 
    684 OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigVideoFramerate(OMX_PTR pStructure) {
    685     OMX_ERRORTYPE ret;
    686     OMX_CONFIG_FRAMERATETYPE *p = (OMX_CONFIG_FRAMERATETYPE *)pStructure;
    687 
    688     CHECK_TYPE_HEADER(p);
    689     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    690     memcpy(p, &mConfigFramerate, sizeof(*p));
    691     return OMX_ErrorNone;
    692 }
    693 
    694 OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigVideoFramerate(OMX_PTR pStructure) {
    695     OMX_ERRORTYPE ret;
    696     Encode_Status retStatus = ENCODE_SUCCESS;
    697     if (mParamBitrate.eControlRate == OMX_Video_ControlRateMax){
    698         LOGE("SetConfigVideoFramerate failed. Feature is disabled.");
    699         return OMX_ErrorUnsupportedIndex;
    700     }
    701     OMX_CONFIG_FRAMERATETYPE *p = (OMX_CONFIG_FRAMERATETYPE *)pStructure;
    702     CHECK_TYPE_HEADER(p);
    703     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    704 
    705     // set in either Loaded state  (ComponentSetParam) or Executing state (ComponentSetConfig)
    706     mConfigFramerate = *p;
    707 
    708     // return OMX_ErrorNone if not in Executing state
    709     // TODO, return OMX_ErrorIncorrectStateOperation?
    710     CHECK_SET_CONFIG_STATE();
    711 
    712     VideoConfigFrameRate framerate;
    713     framerate.frameRate.frameRateDenom = 1;
    714     framerate.frameRate.frameRateNum = mConfigFramerate.xEncodeFramerate >> 16;
    715     retStatus = mVideoEncoder->setConfig(&framerate);
    716     if(retStatus != ENCODE_SUCCESS) {
    717         LOGW("Failed to set frame rate config");
    718     }
    719     return OMX_ErrorNone;
    720 }
    721 
    722 OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigVideoIntraVOPRefresh(OMX_PTR) {
    723     LOGW("GetConfigVideoIntraVOPRefresh is not supported.");
    724     return OMX_ErrorUnsupportedSetting;
    725 }
    726 
    727 OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigVideoIntraVOPRefresh(OMX_PTR pStructure) {
    728     OMX_ERRORTYPE ret;
    729     Encode_Status retStatus = ENCODE_SUCCESS;
    730     OMX_CONFIG_INTRAREFRESHVOPTYPE *p = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)pStructure;
    731     CHECK_TYPE_HEADER(p);
    732     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    733 
    734     // return OMX_ErrorNone if not in Executing state
    735     // TODO: return OMX_ErrorIncorrectStateOperation?
    736     CHECK_SET_CONFIG_STATE();
    737 
    738     if(p->IntraRefreshVOP == OMX_TRUE) {
    739         VideoParamConfigSet configIDRRequest;
    740         configIDRRequest.type = VideoConfigTypeIDRRequest;
    741         retStatus = mVideoEncoder->setConfig(&configIDRRequest);
    742         if(retStatus != ENCODE_SUCCESS) {
    743             LOGW("Failed to set refresh config");
    744         }
    745     }
    746 
    747     return OMX_ErrorNone;
    748 }
    749 
    750 OMX_ERRORTYPE OMXVideoEncoderBase::GetParamIntelAdaptiveSliceControl(OMX_PTR pStructure) {
    751 
    752     OMX_ERRORTYPE ret;
    753     OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL *p = (OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL *)pStructure;
    754 
    755     CHECK_TYPE_HEADER(p);
    756     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    757     memcpy(p, &mParamIntelAdaptiveSliceControl, sizeof(*p));
    758 
    759     return OMX_ErrorNone;
    760 }
    761 
    762 OMX_ERRORTYPE OMXVideoEncoderBase::SetParamIntelAdaptiveSliceControl(OMX_PTR pStructure) {
    763 
    764     OMX_ERRORTYPE ret;
    765     if (mParamBitrate.eControlRate == OMX_Video_ControlRateMax) {
    766         LOGE("SetParamIntelAdaptiveSliceControl failed. Feature is disabled.");
    767         return OMX_ErrorUnsupportedIndex;
    768     }
    769     OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL *p = (OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL *)pStructure;
    770     CHECK_TYPE_HEADER(p);
    771     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    772 
    773     // set only in Loaded state (ComponentSetParam)
    774     CHECK_SET_PARAM_STATE();
    775 
    776     mParamIntelAdaptiveSliceControl = *p;
    777 
    778     return OMX_ErrorNone;
    779 }
    780 
    781 /*
    782 OMX_ERRORTYPE OMXVideoEncoderBase::GetParamVideoProfileLevelQuerySupported(OMX_PTR pStructure) {
    783     OMX_ERRORTYPE ret;
    784     OMX_VIDEO_PARAM_PROFILELEVELTYPE *p = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pStructure;
    785 
    786     CHECK_TYPE_HEADER(p);
    787     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    788 
    789     // assign values instead of memory coping to avoid nProfileIndex being overridden
    790     p->eProfile = mParamProfileLevel.eProfile;
    791     p->eLevel = mParamProfileLevel.eLevel;
    792 
    793     return OMX_ErrorNone;
    794 }
    795 
    796 OMX_ERRORTYPE OMXVideoEncoderBase::SetParamVideoProfileLevelQuerySupported(OMX_PTR pStructure) {
    797     LOGW("SetParamVideoProfileLevelQuerySupported is not supported.");
    798     return OMX_ErrorUnsupportedSetting;
    799 }
    800 */
    801 
    802 OMX_ERRORTYPE OMXVideoEncoderBase::GetStoreMetaDataInBuffers(OMX_PTR pStructure) {
    803     OMX_ERRORTYPE ret;
    804     StoreMetaDataInBuffersParams *p = (StoreMetaDataInBuffersParams *)pStructure;
    805 
    806     CHECK_TYPE_HEADER(p);
    807     CHECK_PORT_INDEX(p, INPORT_INDEX);
    808 
    809     p->bStoreMetaData = mStoreMetaDataInBuffers;
    810 
    811     return OMX_ErrorNone;
    812 };
    813 OMX_ERRORTYPE OMXVideoEncoderBase::SetStoreMetaDataInBuffers(OMX_PTR pStructure) {
    814     OMX_ERRORTYPE ret;
    815     StoreMetaDataInBuffersParams *p = (StoreMetaDataInBuffersParams *)pStructure;
    816     VideoParamsStoreMetaDataInBuffers StoreMetaDataInBuffers;
    817     PortVideo *port = static_cast<PortVideo *>(this->ports[INPORT_INDEX]);
    818 
    819     CHECK_TYPE_HEADER(p);
    820     CHECK_PORT_INDEX(p, INPORT_INDEX);
    821 
    822     LOGD("SetStoreMetaDataInBuffers (enabled = %x)", p->bStoreMetaData);
    823     if(mStoreMetaDataInBuffers == p->bStoreMetaData)
    824         return OMX_ErrorNone;
    825 
    826     StoreMetaDataInBuffers.isEnabled = p->bStoreMetaData;
    827     if (mVideoEncoder->setParameters(&StoreMetaDataInBuffers) != ENCODE_SUCCESS)
    828         return OMX_ErrorNotReady;
    829 
    830     mStoreMetaDataInBuffers = p->bStoreMetaData;
    831 
    832     if(mStoreMetaDataInBuffers){
    833         // for input port buffer
    834         OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput;
    835         const OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput_get;
    836 
    837         paramPortDefinitionInput_get = port->GetPortDefinition();
    838         paramPortDefinitionInput = (OMX_PARAM_PORTDEFINITIONTYPE *)paramPortDefinitionInput_get;
    839         paramPortDefinitionInput->nBufferSize = IntelMetadataBuffer::GetMaxBufferSize();
    840     }
    841     else
    842     {
    843         const OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput_get;
    844 
    845         paramPortDefinitionInput_get = port->GetPortDefinition();
    846         port->SetPortDefinition(paramPortDefinitionInput_get, true);
    847     }
    848 
    849     LOGD("SetStoreMetaDataInBuffers success");
    850     return OMX_ErrorNone;
    851 };
    852 
    853 OMX_ERRORTYPE OMXVideoEncoderBase::GetSyncEncoding(OMX_PTR pStructure) {
    854     OMX_BOOL* syncEncoding = static_cast<OMX_BOOL*>(pStructure);
    855 
    856     *syncEncoding = mSyncEncoding;
    857 
    858     return OMX_ErrorNone;
    859 };
    860 
    861 OMX_ERRORTYPE OMXVideoEncoderBase::SetSyncEncoding(OMX_PTR pStructure) {
    862     CHECK_SET_PARAM_STATE();
    863 
    864     mSyncEncoding = *(static_cast<OMX_BOOL*>(pStructure));
    865 
    866     LOGD("SetSyncEncoding %d", mSyncEncoding);
    867 
    868     return OMX_ErrorNone;
    869 };
    870 
    871 OMX_ERRORTYPE OMXVideoEncoderBase::GetPrependSPSPPS(OMX_PTR) {
    872     return OMX_ErrorNone;
    873 };
    874 
    875 OMX_ERRORTYPE OMXVideoEncoderBase::SetPrependSPSPPS(OMX_PTR) {
    876     LOGD("SetPrependSPSPPS success");
    877     return OMX_ErrorNone;
    878 };
    879 
    880 OMX_ERRORTYPE OMXVideoEncoderBase::GetTemporalLayer(OMX_PTR pStructure) {
    881     OMX_ERRORTYPE ret;
    882     OMX_VIDEO_PARAM_INTEL_TEMPORAL_LAYER* p = static_cast<OMX_VIDEO_PARAM_INTEL_TEMPORAL_LAYER*>(pStructure);
    883 
    884     CHECK_TYPE_HEADER(p);
    885     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    886     memcpy(p, &mTemporalLayer, sizeof(*p));
    887     return OMX_ErrorNone;
    888 }
    889 
    890 OMX_ERRORTYPE OMXVideoEncoderBase::SetTemporalLayer(OMX_PTR pStructure) {
    891     OMX_ERRORTYPE ret;
    892     OMX_VIDEO_PARAM_INTEL_TEMPORAL_LAYER *p = (OMX_VIDEO_PARAM_INTEL_TEMPORAL_LAYER *)pStructure;
    893     VideoParamsTemporalLayer TemporalLayer;
    894     OMX_U32 i;
    895 
    896     CHECK_TYPE_HEADER(p);
    897     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    898 
    899     LOGE("SetTemporalLayer (enabled = %d)", p->nNumberOfTemporalLayer);
    900 
    901     TemporalLayer.numberOfLayer = p->nNumberOfTemporalLayer;
    902     TemporalLayer.nPeriodicity = p->nPeriodicity;
    903     for(i=0;i<p->nPeriodicity;i++)
    904         TemporalLayer.nLayerID[i] = p->nLayerID[i];
    905 
    906     if (mVideoEncoder->setParameters(&TemporalLayer) != ENCODE_SUCCESS)
    907         return OMX_ErrorNotReady;
    908 
    909     LOGE("SetTemporalLayer success");
    910     return OMX_ErrorNone;
    911 }
    912 
    913 OMX_ERRORTYPE OMXVideoEncoderBase::GetBlackFramePointer(OMX_PTR pStructure) {
    914     OMX_ERRORTYPE ret;
    915     OMX_VIDEO_INTEL_REQUEST_BALCK_FRAME_POINTER *p = (OMX_VIDEO_INTEL_REQUEST_BALCK_FRAME_POINTER *)pStructure;
    916 
    917     CHECK_TYPE_HEADER(p);
    918     CHECK_PORT_INDEX(p, INPORT_INDEX);
    919 
    920     PortVideo *port_in = static_cast<PortVideo *>(ports[INPORT_INDEX]);
    921     const OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput = port_in->GetPortDefinition();
    922     OMX_U32 width = paramPortDefinitionInput->format.video.nFrameWidth;
    923     OMX_U32 height = paramPortDefinitionInput->format.video.nFrameHeight;
    924     OMX_U32 lumaSize = width * height;
    925     OMX_U32 bufferSize = width * height * 3 / 2;
    926 
    927     if(mBlackFramePointer) {
    928         free(mBlackFramePointer);
    929         mBlackFramePointer = NULL;
    930     } else {
    931         mBlackFramePointer = (OMX_PTR)memalign(4096, bufferSize); // align to page size
    932         if(!mBlackFramePointer) {
    933             return OMX_ErrorInsufficientResources;
    934         }
    935         memset(mBlackFramePointer, 0x0, lumaSize);
    936         memset((OMX_PTR)((uint64_t)mBlackFramePointer + lumaSize), 0x80, lumaSize / 2);
    937         p->nFramePointer = (OMX_U32)mBlackFramePointer;
    938     }
    939     return OMX_ErrorNone;
    940 }
    941 
    942 OMX_ERRORTYPE OMXVideoEncoderBase::SetBlackFramePointer(OMX_PTR) {
    943     return OMX_ErrorUnsupportedSetting;
    944 }
    945 
    946 OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigVideoBitrate(OMX_PTR pStructure) {
    947 
    948     OMX_ERRORTYPE ret;
    949     OMX_VIDEO_CONFIG_BITRATETYPE *p = (OMX_VIDEO_CONFIG_BITRATETYPE *)pStructure;
    950 
    951     CHECK_TYPE_HEADER(p);
    952     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    953     memcpy(p, &mConfigBitrate, sizeof(*p));
    954     return OMX_ErrorNone;
    955 }
    956 OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigVideoBitrate(OMX_PTR pStructure){
    957     OMX_ERRORTYPE ret;
    958     Encode_Status retStatus = ENCODE_SUCCESS;
    959     if (mParamBitrate.eControlRate == OMX_Video_ControlRateMax){
    960         LOGE("SetConfigIntelBitrate failed. Feature is disabled.");
    961         return OMX_ErrorUnsupportedIndex;
    962     }
    963     OMX_VIDEO_CONFIG_BITRATETYPE *p = (OMX_VIDEO_CONFIG_BITRATETYPE *)pStructure;
    964     CHECK_TYPE_HEADER(p);
    965     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    966 
    967     // set in either Loaded state (ComponentSetParam) or Executing state (ComponentSetConfig)
    968     mConfigBitrate = *p;
    969 
    970     // return OMX_ErrorNone if not in Executing state
    971     // TODO: return OMX_ErrorIncorrectStateOperation?
    972     // CHECK_SET_CONFIG_STATE();
    973 
    974     VideoConfigBitRate configBitRate;
    975     configBitRate.rcParams.bitRate = mConfigBitrate.nEncodeBitrate;
    976     configBitRate.rcParams.temporalID = 0;
    977     retStatus = mVideoEncoder->setConfig(&configBitRate);
    978     if(retStatus != ENCODE_SUCCESS) {
    979         LOGW("failed to set IntelBitrate");
    980     }
    981     return OMX_ErrorNone;
    982 }
    983 
    984 OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigAndroidIntraRefresh(OMX_PTR pStructure) {
    985     OMX_ERRORTYPE ret;
    986     OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *p = (OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *)pStructure;
    987 
    988     CHECK_TYPE_HEADER(p);
    989     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    990 
    991     memcpy(p, &mConfigAndroidIntraRefresh, sizeof(*p));
    992     return OMX_ErrorNone;
    993 }
    994 
    995 OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigAndroidIntraRefresh(OMX_PTR pStructure) {
    996     OMX_ERRORTYPE ret;
    997 
    998     OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *p = (OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *)pStructure;
    999 
   1000     CHECK_TYPE_HEADER(p);
   1001     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
   1002 
   1003     // set in either Loaded state (ComponentSetParam) or Executing state (ComponentSetConfig)
   1004     mConfigAndroidIntraRefresh = *p;
   1005 
   1006     // return OMX_ErrorNone if not in Executing state
   1007     // TODO: return OMX_ErrorIncorrectStateOperation?
   1008     CHECK_SET_PARAM_STATE();
   1009 
   1010     OMX_VIDEO_PARAM_INTRAREFRESHTYPE intraRefresh;
   1011     memset(&intraRefresh, 0, sizeof(intraRefresh));
   1012     intraRefresh.nSize = sizeof(intraRefresh);
   1013     intraRefresh.nVersion = p->nVersion;
   1014     intraRefresh.nPortIndex = mConfigAndroidIntraRefresh.nPortIndex;
   1015     intraRefresh.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
   1016     intraRefresh.nAirMBs = 0;
   1017     intraRefresh.nAirRef = 0;
   1018 
   1019     if (0 == mConfigAndroidIntraRefresh.nRefreshPeriod) {
   1020         intraRefresh.nCirMBs = 0;
   1021     } else {
   1022         OMX_PARAM_PORTDEFINITIONTYPE def;
   1023 
   1024         if (intraRefresh.nPortIndex < nr_ports) {
   1025             memcpy(&def, ports[intraRefresh.nPortIndex]->GetPortDefinition(),sizeof(def));
   1026         } else {
   1027             LOGW("Failed tp set AIR config, bad port index");
   1028             return OMX_ErrorBadPortIndex;
   1029         }
   1030 
   1031         intraRefresh.nCirMBs = divUp((divUp(def.format.video.nFrameWidth, 16u) * divUp(def.format.video.nFrameHeight,16u)), mConfigAndroidIntraRefresh.nRefreshPeriod);
   1032     }
   1033     return SetParamVideoIntraRefresh(&intraRefresh);
   1034 }
   1035