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_TAG "OMXVideoEncoderAVC"
     18 #include "OMXVideoEncoderAVC.h"
     19 #include "IntelMetadataBuffer.h"
     20 
     21 static const char *AVC_MIME_TYPE = "video/h264";
     22 
     23 struct ProfileMap {
     24     OMX_VIDEO_AVCPROFILETYPE key;
     25     VAProfile value;
     26     const char *name;
     27 };
     28 
     29 struct LevelMap {
     30     OMX_VIDEO_AVCLEVELTYPE key;
     31     uint32_t value;
     32     const char *name;
     33 };
     34 
     35 static ProfileMap ProfileTable[] = {
     36     { OMX_VIDEO_AVCProfileBaseline, VAProfileH264Baseline, "AVC Baseline" },
     37     { OMX_VIDEO_AVCProfileMain, VAProfileH264Main, "AVC Main" },
     38     { OMX_VIDEO_AVCProfileHigh, VAProfileH264High, "AVC High" },
     39     { (OMX_VIDEO_AVCPROFILETYPE) 0, (VAProfile) 0, "Not Supported" },
     40 };
     41 
     42 static LevelMap LevelTable[] = {
     43     { OMX_VIDEO_AVCLevel4, 40, "AVC Level4" },
     44     { OMX_VIDEO_AVCLevel41, 41, "AVC Level41" },
     45     { OMX_VIDEO_AVCLevel42, 42, "AVC Level42" },
     46     { OMX_VIDEO_AVCLevel5, 50, "AVC Level5" },
     47     { OMX_VIDEO_AVCLevel51, 51, "AVC Level51" },
     48     { (OMX_VIDEO_AVCLEVELTYPE) 0, 0, "Not Supported" },
     49 };
     50 
     51 #define FIND_BYKEY(table, x, y)  {\
     52         for(int ii = 0; ; ii++) { \
     53             if (table[ii].key == x || table[ii].key == 0) { \
     54                 y = ii; \
     55                 break; \
     56             } \
     57         } \
     58     }\
     59 
     60 #define FIND_BYVALUE(table, x, y)  {\
     61         for(int ii = 0; ; ii++) { \
     62             if (table[ii].value == x || table[ii].value == 0) { \
     63                 y = ii; \
     64                 break; \
     65             } \
     66         } \
     67     } \
     68 
     69 OMXVideoEncoderAVC::OMXVideoEncoderAVC() {
     70     BuildHandlerList();
     71     mVideoEncoder = createVideoEncoder(AVC_MIME_TYPE);
     72     if (!mVideoEncoder) {
     73         LOGE("OMX_ErrorInsufficientResources");
     74         return;
     75     }
     76 
     77     mAVCParams = new VideoParamsAVC();
     78     if (!mAVCParams) {
     79         LOGE("OMX_ErrorInsufficientResources");
     80         return;
     81     }
     82 
     83     //Query supported Profile/Level
     84     mPLTableCount = 0;
     85 
     86     VAProfile profiles[MAX_H264_PROFILE] = {VAProfileH264High, VAProfileH264Main, VAProfileH264Baseline};
     87 
     88     VideoParamsProfileLevel pl;
     89     for (int i=0; i < MAX_H264_PROFILE; i++) {
     90         pl.profile = profiles[i];
     91         pl.level = 0;
     92         pl.isSupported = false;
     93 
     94         mVideoEncoder->getParameters(&pl);
     95         if (pl.isSupported) {
     96             uint32_t profile_index;
     97             uint32_t level_index;
     98 
     99             FIND_BYVALUE(ProfileTable, pl.profile,  profile_index);
    100             if (ProfileTable[profile_index].key == (OMX_VIDEO_AVCPROFILETYPE) 0)
    101                 continue;
    102 
    103             FIND_BYVALUE(LevelTable, pl.level,  level_index);
    104             if (LevelTable[level_index].key == (OMX_VIDEO_AVCLEVELTYPE) 0)
    105                 continue;
    106 
    107             mPLTable[mPLTableCount].profile = ProfileTable[profile_index].key;
    108             mPLTable[mPLTableCount].level = LevelTable[level_index].key;
    109             mPLTableCount ++;
    110             LOGV("Support Profile:%s, Level:%s\n", ProfileTable[profile_index].name, LevelTable[level_index].name);
    111         }
    112     }
    113 
    114     mEmptyEOSBuf = OMX_FALSE;
    115 }
    116 
    117 OMXVideoEncoderAVC::~OMXVideoEncoderAVC() {
    118     if(mAVCParams) {
    119         delete mAVCParams;
    120         mAVCParams = NULL;
    121     }
    122 }
    123 
    124 OMX_ERRORTYPE OMXVideoEncoderAVC::InitOutputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionOutput) {
    125     // OMX_VIDEO_PARAM_AVCTYPE
    126     memset(&mParamAvc, 0, sizeof(mParamAvc));
    127     SetTypeHeader(&mParamAvc, sizeof(mParamAvc));
    128     mParamAvc.nPortIndex = OUTPORT_INDEX;
    129 
    130     if (mPLTableCount > 0) {
    131         mParamAvc.eProfile = (OMX_VIDEO_AVCPROFILETYPE) mPLTable[0].profile;
    132         mParamAvc.eLevel = (OMX_VIDEO_AVCLEVELTYPE)mPLTable[0].level;
    133     } else {
    134         LOGE("No supported profile/level\n");
    135         return OMX_ErrorUndefined;
    136     }
    137     mParamAvc.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
    138     mParamAvc.nPFrames = 29;
    139     mParamAvc.nBFrames = 0;
    140 
    141     // OMX_NALSTREAMFORMATTYPE
    142     memset(&mNalStreamFormat, 0, sizeof(mNalStreamFormat));
    143     SetTypeHeader(&mNalStreamFormat, sizeof(mNalStreamFormat));
    144     mNalStreamFormat.nPortIndex = OUTPORT_INDEX;
    145     // TODO: check if this is desired Nalu Format
    146     //mNalStreamFormat.eNaluFormat = OMX_NaluFormatLengthPrefixedSeparateFirstHeader;
    147     // OMX_VIDEO_CONFIG_AVCINTRAPERIOD
    148     memset(&mConfigAvcIntraPeriod, 0, sizeof(mConfigAvcIntraPeriod));
    149     SetTypeHeader(&mConfigAvcIntraPeriod, sizeof(mConfigAvcIntraPeriod));
    150     mConfigAvcIntraPeriod.nPortIndex = OUTPORT_INDEX;
    151     // TODO: need to be populated from Video Encoder
    152     mConfigAvcIntraPeriod.nIDRPeriod = 1;
    153     mConfigAvcIntraPeriod.nPFrames = 29;
    154 
    155     // OMX_VIDEO_CONFIG_NALSIZE
    156     memset(&mConfigNalSize, 0, sizeof(mConfigNalSize));
    157     SetTypeHeader(&mConfigNalSize, sizeof(mConfigNalSize));
    158     mConfigNalSize.nPortIndex = OUTPORT_INDEX;
    159     mConfigNalSize.nNaluBytes = 0;
    160 
    161     // OMX_VIDEO_PARAM_INTEL_AVCVUI
    162     memset(&mParamIntelAvcVui, 0, sizeof(mParamIntelAvcVui));
    163     SetTypeHeader(&mParamIntelAvcVui, sizeof(mParamIntelAvcVui));
    164     mParamIntelAvcVui.nPortIndex = OUTPORT_INDEX;
    165     mParamIntelAvcVui.bVuiGeneration = OMX_FALSE;
    166 
    167     // OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS
    168     memset(&mConfigIntelSliceNumbers, 0, sizeof(mConfigIntelSliceNumbers));
    169     SetTypeHeader(&mConfigIntelSliceNumbers, sizeof(mConfigIntelSliceNumbers));
    170     mConfigIntelSliceNumbers.nPortIndex = OUTPORT_INDEX;
    171     mConfigIntelSliceNumbers.nISliceNumber = 1;
    172     mConfigIntelSliceNumbers.nPSliceNumber = 1;
    173 
    174     // Override OMX_PARAM_PORTDEFINITIONTYPE
    175     paramPortDefinitionOutput->nBufferCountActual = OUTPORT_ACTUAL_BUFFER_COUNT;
    176     paramPortDefinitionOutput->nBufferCountMin = OUTPORT_MIN_BUFFER_COUNT;
    177     paramPortDefinitionOutput->nBufferSize = OUTPORT_BUFFER_SIZE;
    178     paramPortDefinitionOutput->format.video.cMIMEType = (OMX_STRING)AVC_MIME_TYPE;
    179     paramPortDefinitionOutput->format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
    180 
    181     // Override OMX_VIDEO_PARAM_PROFILELEVELTYPE
    182     // TODO: check if profile/level supported is correct
    183     mParamProfileLevel.eProfile = mParamAvc.eProfile;
    184     mParamProfileLevel.eLevel = mParamAvc.eLevel;
    185 
    186     // Override OMX_VIDEO_PARAM_BITRATETYPE
    187     mParamBitrate.nTargetBitrate = 192000;
    188 
    189     // Override OMX_VIDEO_CONFIG_INTEL_BITRATETYPE
    190     mConfigIntelBitrate.nInitialQP = 0;  // Initial QP for I frames
    191 
    192     return OMX_ErrorNone;
    193 }
    194 
    195 OMX_ERRORTYPE OMXVideoEncoderAVC::SetVideoEncoderParam(void) {
    196 
    197     Encode_Status ret = ENCODE_SUCCESS;
    198     LOGV("OMXVideoEncoderAVC::SetVideoEncoderParam");
    199 
    200     if (!mEncoderParams) {
    201         LOGE("NULL pointer: mEncoderParams");
    202         return OMX_ErrorBadParameter;
    203     }
    204 
    205     mVideoEncoder->getParameters(mEncoderParams);
    206     uint32_t index;
    207     FIND_BYKEY(ProfileTable, mParamAvc.eProfile, index);
    208     if (ProfileTable[index].value != 0)
    209         mEncoderParams->profile = ProfileTable[index].value;
    210 
    211     if (mParamAvc.nAllowedPictureTypes & OMX_VIDEO_PictureTypeB)
    212         mEncoderParams->intraPeriod = mParamAvc.nPFrames + mParamAvc.nBFrames;
    213     else
    214         mEncoderParams->intraPeriod = mParamAvc.nPFrames + 1;
    215 
    216     // 0 - all luma and chroma block edges of the slice are filtered
    217     // 1 - deblocking is disabled for all block edges of the slice
    218     // 2 - all luma and chroma block edges of the slice are filtered
    219     // with exception of the block edges that coincide with slice boundaries
    220     mEncoderParams->disableDeblocking = 0;
    221 
    222     OMXVideoEncoderBase::SetVideoEncoderParam();
    223 
    224     mVideoEncoder->getParameters(mAVCParams);
    225     if(mParamIntelAvcVui.bVuiGeneration == OMX_TRUE) {
    226         mAVCParams->VUIFlag = 1;
    227     }
    228     // For resolution below VGA, single core can hit the performance target and provide VQ gain
    229     if (mEncoderParams->resolution.width <= 640 && mEncoderParams->resolution.height <= 480) {
    230         mConfigIntelSliceNumbers.nISliceNumber = 1;
    231         mConfigIntelSliceNumbers.nPSliceNumber = 1;
    232     }
    233     mAVCParams->sliceNum.iSliceNum = mConfigIntelSliceNumbers.nISliceNumber;
    234     mAVCParams->sliceNum.pSliceNum = mConfigIntelSliceNumbers.nPSliceNumber;
    235     mAVCParams->maxSliceSize = mConfigNalSize.nNaluBytes * 8;
    236 
    237     if (mEncoderParams->intraPeriod == 0) {
    238         mAVCParams->idrInterval = 0;
    239         mAVCParams->ipPeriod = 1;
    240     } else {
    241         mAVCParams->idrInterval = mConfigAvcIntraPeriod.nIDRPeriod; //idrinterval
    242         if (mParamAvc.nAllowedPictureTypes & OMX_VIDEO_PictureTypeB)
    243             mAVCParams->ipPeriod = mEncoderParams->intraPeriod / mParamAvc.nPFrames;
    244         else
    245             mAVCParams->ipPeriod = 1;
    246     }
    247 
    248     ret = mVideoEncoder ->setParameters(mAVCParams);
    249     CHECK_ENCODE_STATUS("setParameters");
    250 
    251     LOGV("VUIFlag = %d\n", mAVCParams->VUIFlag);
    252     LOGV("sliceNum.iSliceNum = %d\n", mAVCParams->sliceNum.iSliceNum);
    253     LOGV("sliceNum.pSliceNum = %d\n", mAVCParams->sliceNum.pSliceNum);
    254     LOGV("maxSliceSize = %d\n ", mAVCParams->maxSliceSize);
    255     LOGV("intraPeriod = %d\n ", mEncoderParams->intraPeriod);
    256     LOGV("idrInterval = %d\n ", mAVCParams->idrInterval);
    257     LOGV("ipPeriod = %d\n ", mAVCParams->ipPeriod);
    258     return OMX_ErrorNone;
    259 }
    260 
    261 OMX_ERRORTYPE OMXVideoEncoderAVC::ProcessorInit(void) {
    262     mCSDOutputted = OMX_FALSE;
    263     mInputPictureCount = 0;
    264     mFrameEncodedCount = 0;
    265     return  OMXVideoEncoderBase::ProcessorInit();
    266 }
    267 
    268 OMX_ERRORTYPE OMXVideoEncoderAVC::ProcessorDeinit(void) {
    269     return OMXVideoEncoderBase::ProcessorDeinit();
    270 }
    271 
    272 OMX_ERRORTYPE OMXVideoEncoderAVC::ProcessorStop(void) {
    273     OMX_BUFFERHEADERTYPE *omxbuf = NULL;
    274 
    275     while(!mBFrameList.empty()) {
    276         omxbuf = * mBFrameList.begin();
    277         this->ports[INPORT_INDEX]->ReturnThisBuffer(omxbuf);
    278         mBFrameList.erase(mBFrameList.begin());
    279     }
    280 
    281     mEmptyEOSBuf = OMX_FALSE;
    282     return OMXVideoEncoderBase::ProcessorStop();
    283 }
    284 
    285 OMX_ERRORTYPE OMXVideoEncoderAVC::ProcessorPreEmptyBuffer(OMX_BUFFERHEADERTYPE* buffer) {
    286     OMX_U32 EncodeInfo = 0;
    287     OMX_U32 EncodeFrameType = 0;
    288 
    289     uint32_t poc = 0;
    290     uint32_t idrPeriod = mAVCParams->idrInterval;
    291     uint32_t IntraPeriod = mEncoderParams->intraPeriod;
    292     uint32_t IpPeriod = mAVCParams->ipPeriod;
    293     bool BFrameEnabled = IpPeriod > 1;
    294     uint32_t GOP = 0;
    295 
    296     if (idrPeriod == 0 || IntraPeriod == 0) {
    297         GOP = 0xFFFFFFFF;
    298         if (IntraPeriod == 0)
    299             IntraPeriod = 0xFFFFFFFF;
    300     } else if (BFrameEnabled)
    301         GOP = IntraPeriod*idrPeriod + 1;
    302     else
    303         GOP = IntraPeriod*idrPeriod;
    304 
    305     LOGV("ProcessorPreEmptyBuffer idrPeriod=%d, IntraPeriod=%d, IpPeriod=%d, BFrameEnabled=%d\n", idrPeriod, IntraPeriod, IpPeriod, BFrameEnabled);
    306 
    307     //decide frame type, refer Merrifield Video Encoder Driver HLD Chapter 3.17
    308     poc = mInputPictureCount % GOP;
    309 
    310     if (poc == 0 /*IDR*/) {
    311             EncodeFrameType = F_IDR;
    312     } else if (IntraPeriod == 1) {
    313             EncodeFrameType = F_I;
    314     }else if ((poc > IpPeriod) && ((poc - IpPeriod) % IntraPeriod == 0))/*I*/{
    315             EncodeFrameType = F_I;
    316             if (BFrameEnabled)
    317                 SET_CO(EncodeInfo, CACHE_POP);
    318     } else if ((poc % IpPeriod == 0) /*P*/ || (buffer->nFlags & OMX_BUFFERFLAG_EOS)/*EOS,always P*/) {
    319             EncodeFrameType = F_P;
    320             if (BFrameEnabled)
    321                 SET_CO(EncodeInfo, CACHE_POP);
    322     } else { /*B*/
    323             EncodeFrameType = F_B;
    324             SET_CO(EncodeInfo, CACHE_PUSH);
    325     }
    326 
    327     SET_FT(EncodeInfo, EncodeFrameType);
    328     SET_FC(EncodeInfo, mInputPictureCount);
    329 
    330     buffer->pPlatformPrivate = (OMX_PTR) EncodeInfo;
    331 
    332     LOGV("ProcessorPreEmptyBuffer Frame %d, Type %s, EncodeInfo %x\n", mInputPictureCount, FrameTypeStr[EncodeFrameType], EncodeInfo);
    333 
    334     mInputPictureCount ++;
    335     return OMX_ErrorNone;
    336 }
    337 
    338 OMX_BOOL OMXVideoEncoderAVC::ProcessCacheOperation(OMX_BUFFERHEADERTYPE **buffers) {
    339 
    340     OMX_BOOL Cached = OMX_FALSE;
    341 
    342     //get frame encode info
    343     Encode_Info eInfo;
    344     uint32_t encodeInfo 	= (uint32_t) buffers[INPORT_INDEX]->pPlatformPrivate;
    345     eInfo.FrameType 		   = GET_FT(encodeInfo);
    346 
    347     eInfo.CacheOperation	= GET_CO(encodeInfo);
    348     eInfo.NotStopFrame		= encodeInfo & ENC_NSTOP;
    349     eInfo.FrameCount		 = GET_FC(encodeInfo);
    350 
    351     LOGV("ProcessCacheOperation Frame %d, type:%s, CacheOps:%s, NoSTOP=%d, EOS=%d\n",
    352             eInfo.FrameCount, FrameTypeStr[eInfo.FrameType], CacheOperationStr[eInfo.CacheOperation],
    353             eInfo.NotStopFrame, buffers[INPORT_INDEX]->nFlags & OMX_BUFFERFLAG_EOS);
    354 
    355     OMX_BOOL emptyEOSBuf = OMX_FALSE;
    356     if (buffers[INPORT_INDEX]->nFilledLen == 0 && buffers[INPORT_INDEX]->nFlags & OMX_BUFFERFLAG_EOS) {
    357         //meet an empty EOS buffer
    358         emptyEOSBuf = OMX_TRUE;
    359         LOGV("ProcessCacheOperation: This frame is Empty EOS buffer\n");
    360     }
    361 
    362     if (eInfo.CacheOperation == CACHE_NONE) {
    363         //nothing to do
    364     } else if (eInfo.CacheOperation == CACHE_PUSH) {
    365         mBFrameList.push_front(buffers[INPORT_INDEX]);
    366         Cached = OMX_TRUE;
    367         LOGV("ProcessCacheOperation: This B frame is cached\n");
    368 
    369     } else if (eInfo.CacheOperation == CACHE_POP) {
    370         eInfo.NotStopFrame = true;  //it is also a nstop frame
    371 
    372         OMX_BUFFERHEADERTYPE *omxbuf = NULL;
    373         uint32_t i = 0;
    374         uint32_t bframecount = mBFrameList.size();
    375 
    376         LOGV("BFrameList size = %d\n", bframecount);
    377 
    378         while(!mBFrameList.empty()) {
    379             /*TODO: need to handle null data buffer with EOS
    380                      !NULL EOS case:   B1 B2 P(EOS)     ->    P B1 B2(EOS)
    381                      NULL EOS case: B1 B2 NULL(EOS)    ->    B2 B1 NULL(EOS)
    382             */
    383 
    384             if (emptyEOSBuf) {
    385                 omxbuf = *mBFrameList.begin();
    386                 ports[INPORT_INDEX]->PushThisBuffer(omxbuf);
    387                 mBFrameList.erase(mBFrameList.begin()); //clear it from internal queue
    388 
    389             } else {
    390                 omxbuf = *mBFrameList.begin();
    391 
    392                 if (buffers[INPORT_INDEX]->nFlags & OMX_BUFFERFLAG_EOS && i == 0 )  {
    393                     //this is final encode frame, mark it is new EOS and remove original EOS
    394                     omxbuf->nFlags |= OMX_BUFFERFLAG_EOS;
    395 				    buffers[INPORT_INDEX]->nFlags &= ~OMX_BUFFERFLAG_EOS;
    396                 } else {
    397                     //all these frames except final B frame in miniGOP can't be stopped at any time
    398                     //to avoid not breaking miniGOP integrity
    399                     if (i > 0) {
    400                         uint32_t tmp = (uint32_t) omxbuf->pPlatformPrivate;
    401                         tmp |= ENC_NSTOP;
    402                         omxbuf->pPlatformPrivate = (OMX_PTR) tmp;
    403                     }
    404                 }
    405                 ports[INPORT_INDEX]->RetainThisBuffer(omxbuf, false); //push bufferq head
    406 
    407                 mBFrameList.erase(mBFrameList.begin()); //clear it from internal queue
    408             }
    409 
    410             i++;
    411         }
    412 
    413         if (emptyEOSBuf)
    414             ports[INPORT_INDEX]->PushThisBuffer(buffers[INPORT_INDEX]); //put it at the tail
    415 
    416     } else if (eInfo.CacheOperation == CACHE_RESET) {
    417 //        mBFrameList.clear();
    418     }
    419 
    420     eInfo.CacheOperation = CACHE_NONE;
    421 
    422     /* restore all states into input OMX buffer
    423     */
    424     if (eInfo.NotStopFrame)
    425         encodeInfo |= ENC_NSTOP;
    426     else
    427         encodeInfo &= ~ENC_NSTOP;
    428 
    429     SET_CO(encodeInfo, eInfo.CacheOperation);
    430     buffers[INPORT_INDEX]->pPlatformPrivate = (OMX_PTR) encodeInfo;
    431 
    432     LOGV("ProcessCacheOperation Completed return %d\n", Cached);
    433     return Cached;
    434 }
    435 
    436 OMX_ERRORTYPE OMXVideoEncoderAVC::ProcessDataRetrieve(
    437     OMX_BUFFERHEADERTYPE **buffers, OMX_BOOL *outBufReturned) {
    438 
    439     OMX_NALUFORMATSTYPE NaluFormat = mNalStreamFormat.eNaluFormat;
    440 
    441     // NaluFormat not set, setting default
    442     if (NaluFormat == 0) {
    443         NaluFormat = (OMX_NALUFORMATSTYPE)OMX_NaluFormatStartCodesSeparateFirstHeader;
    444         mNalStreamFormat.eNaluFormat = NaluFormat;
    445     }
    446 
    447     VideoEncOutputBuffer outBuf;
    448     outBuf.data = buffers[OUTPORT_INDEX]->pBuffer;
    449     outBuf.bufferSize = buffers[OUTPORT_INDEX]->nAllocLen;
    450     outBuf.dataSize = 0;
    451     outBuf.remainingSize = 0;
    452     outBuf.flag = 0;
    453     outBuf.timeStamp = 0;
    454     outBuf.offset = 0;
    455 
    456     switch (NaluFormat) {
    457         case OMX_NaluFormatStartCodes:
    458             outBuf.format = OUTPUT_EVERYTHING;
    459             break;
    460 
    461         case OMX_NaluFormatOneNaluPerBuffer:
    462             outBuf.format = OUTPUT_ONE_NAL;
    463             break;
    464 
    465         default:
    466             if (NaluFormat == (OMX_NALUFORMATSTYPE)OMX_NaluFormatStartCodesSeparateFirstHeader||
    467                 NaluFormat == (OMX_NALUFORMATSTYPE)OMX_NaluFormatLengthPrefixedSeparateFirstHeader){
    468                 if(!mCSDOutputted) {
    469                     LOGV("Output codec data for first frame\n");
    470                     outBuf.format = OUTPUT_CODEC_DATA;
    471                 } else {
    472                     if (NaluFormat == (OMX_NALUFORMATSTYPE)OMX_NaluFormatStartCodesSeparateFirstHeader)
    473                         outBuf.format = OUTPUT_EVERYTHING;
    474                     else
    475                         outBuf.format = OUTPUT_NALULENGTHS_PREFIXED;
    476                 }
    477                 break;
    478             } else {
    479                 return OMX_ErrorUndefined;
    480             }
    481     }
    482 
    483     //start getOutput
    484     Encode_Status ret = mVideoEncoder->getOutput(&outBuf, FUNC_NONBLOCK);
    485 
    486     if (ret < ENCODE_SUCCESS) {
    487         LOGE("libMIX getOutput Failed. ret = 0x%08x\n", ret);
    488         outBuf.dataSize = 0;
    489         outBuf.flag |= ENCODE_BUFFERFLAG_ENDOFFRAME;
    490         if (ret == ENCODE_NO_REQUEST_DATA) {
    491             if (mEmptyEOSBuf) {
    492                 //make sure no data encoding in HW, then emit one empty out buffer with EOS
    493                 outBuf.flag |= ENCODE_BUFFERFLAG_ENDOFSTREAM;
    494                 LOGV("no more data encoding, will signal empty EOS output buf\n");
    495             } else {
    496                 //if not meet Empty EOS buffer, shouldn't get this error
    497                 LOGE("sever error, should not happend here\n");
    498                 //return OMX_ErrorUndefined; //not return error here to avoid omxcodec crash
    499             }
    500         }
    501 
    502     } else if (ret == ENCODE_BUFFER_TOO_SMALL) {
    503         LOGE("output buffer too small\n");
    504         // Return code could not be ENCODE_BUFFER_TOO_SMALL, or we will have dead lock issue
    505         return OMX_ErrorUndefined;
    506     } else if (ret == ENCODE_DATA_NOT_READY) {
    507         LOGV("Call libMIX getOutput againe due to 'data not ready'\n");
    508         ret = mVideoEncoder->getOutput(&outBuf);
    509     }
    510 
    511     LOGV("libMIX getOutput data size= %d, flag=0x%08x", outBuf.dataSize, outBuf.flag);
    512     OMX_U32 outfilledlen = outBuf.dataSize;
    513     OMX_U32 outoffset = outBuf.offset;
    514     OMX_S64 outtimestamp = outBuf.timeStamp;
    515     OMX_U32 outflags = 0;
    516 
    517     //if codecconfig
    518     if (outBuf.flag & ENCODE_BUFFERFLAG_CODECCONFIG)
    519         outflags |= OMX_BUFFERFLAG_CODECCONFIG;
    520 
    521     //if syncframe
    522     if (outBuf.flag & ENCODE_BUFFERFLAG_SYNCFRAME)
    523         outflags |= OMX_BUFFERFLAG_SYNCFRAME;
    524 
    525     //if eos
    526     if (outBuf.flag & ENCODE_BUFFERFLAG_ENDOFSTREAM)
    527         outflags |= OMX_BUFFERFLAG_EOS;
    528 
    529     //if full encoded data retrieved
    530     if(outBuf.flag & ENCODE_BUFFERFLAG_ENDOFFRAME) {
    531         LOGV("got a complete libmix Frame\n");
    532         outflags |= OMX_BUFFERFLAG_ENDOFFRAME;
    533 
    534         if ((NaluFormat == (OMX_NALUFORMATSTYPE)OMX_NaluFormatStartCodesSeparateFirstHeader
    535              || NaluFormat == (OMX_NALUFORMATSTYPE)OMX_NaluFormatLengthPrefixedSeparateFirstHeader )
    536              && !mCSDOutputted && outfilledlen > 0) {
    537             mCSDOutputted = OMX_TRUE;
    538 
    539         } else {
    540             ports[INPORT_INDEX]->ReturnOneRetainedBuffer();  //return one retained frame from head
    541             mFrameOutputCount  ++;
    542         }
    543     }
    544 
    545     if (outfilledlen == 0) {
    546         if (mEmptyEOSBuf) {
    547             //emit empty EOS out buf since meet empty EOS input buf
    548             buffers[OUTPORT_INDEX]->nFilledLen = 0;
    549             buffers[OUTPORT_INDEX]->nTimeStamp = 0;
    550             buffers[OUTPORT_INDEX]->nFlags = outflags;
    551             *outBufReturned = OMX_TRUE;
    552             LOGV("emit one empty EOS OMX output buf = %p:%d, flag = 0x%08x, ts=%lld", buffers[OUTPORT_INDEX]->pBuffer, outfilledlen, outflags, outtimestamp);
    553         } else
    554             //not emit out buf since something wrong
    555             *outBufReturned = OMX_FALSE;
    556 
    557     } else {
    558         buffers[OUTPORT_INDEX]->nOffset = outoffset;
    559         buffers[OUTPORT_INDEX]->nFilledLen = outfilledlen;
    560         buffers[OUTPORT_INDEX]->nTimeStamp = outtimestamp;
    561         buffers[OUTPORT_INDEX]->nFlags = outflags;
    562         if (outBuf.flag & ENCODE_BUFFERFLAG_NSTOPFRAME)
    563             buffers[OUTPORT_INDEX]->pPlatformPrivate = (OMX_PTR) 0x00000001;  //indicate it is nstop frame
    564         *outBufReturned = OMX_TRUE;
    565         LOGV("emit one OMX output buf = %p:%d, flag = 0x%08x, ts=%lld", buffers[OUTPORT_INDEX]->pBuffer, outfilledlen, outflags, outtimestamp);
    566 
    567     }
    568 
    569     LOGV("ProcessDataRetrieve OK, mFrameEncodedCount=%d , mFrameOutputCount=%d\n", mFrameEncodedCount, mFrameOutputCount);
    570     return OMX_ErrorNone;
    571 }
    572 
    573 OMX_ERRORTYPE OMXVideoEncoderAVC::ProcessorProcess(
    574     OMX_BUFFERHEADERTYPE **buffers,
    575     buffer_retain_t *retains,
    576     OMX_U32) {
    577 
    578     OMX_ERRORTYPE oret = OMX_ErrorNone;
    579     Encode_Status ret = ENCODE_SUCCESS;
    580 
    581     bool FrameEncoded = false;
    582 
    583     if (buffers[INPORT_INDEX]) {
    584         LOGV("input buffer has new frame\n");
    585 
    586         //get frame encode info
    587         Encode_Info eInfo;
    588         uint32_t encodeInfo 	= (uint32_t) buffers[INPORT_INDEX]->pPlatformPrivate;
    589         eInfo.FrameType 		   = GET_FT(encodeInfo);
    590         eInfo.CacheOperation	= GET_CO(encodeInfo);
    591         eInfo.NotStopFrame		= encodeInfo & ENC_NSTOP;
    592         eInfo.FrameCount		 = GET_FC(encodeInfo);
    593 
    594         //handle frame cache operation
    595         if (ProcessCacheOperation(buffers)) {
    596             //frame is cached, nothing should be done in this case, just store status and return
    597             retains[INPORT_INDEX] = BUFFER_RETAIN_CACHE;
    598             retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
    599             return OMX_ErrorNone;
    600         }
    601 
    602         //try encode if frame is not cached
    603         VideoEncRawBuffer inBuf;
    604 
    605         inBuf.data = buffers[INPORT_INDEX]->pBuffer + buffers[INPORT_INDEX]->nOffset;
    606         inBuf.size = buffers[INPORT_INDEX]->nFilledLen;
    607         inBuf.flag = 0;
    608         inBuf.timeStamp = buffers[INPORT_INDEX]->nTimeStamp;
    609 
    610         if (inBuf.size == 0 && buffers[INPORT_INDEX]->nFlags & OMX_BUFFERFLAG_EOS) {
    611             //meet an empty EOS buffer, retain it directly and return from here
    612             retains[INPORT_INDEX] = BUFFER_RETAIN_ACCUMULATE;
    613             retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
    614             mEmptyEOSBuf = OMX_TRUE;
    615             return OMX_ErrorNone;
    616         }
    617 
    618         if (buffers[INPORT_INDEX]->nFlags & OMX_BUFFERFLAG_EOS)
    619             inBuf.flag |= ENCODE_BUFFERFLAG_ENDOFSTREAM;
    620         if (eInfo.NotStopFrame)
    621             inBuf.flag |= ENCODE_BUFFERFLAG_NSTOPFRAME;
    622         inBuf.type = (FrameType) eInfo.FrameType;
    623 
    624         LOGV("start libmix encoding\n");
    625         // encode and setConfig need to be thread safe
    626         pthread_mutex_lock(&mSerializationLock);
    627         ret = mVideoEncoder->encode(&inBuf, FUNC_NONBLOCK);
    628         pthread_mutex_unlock(&mSerializationLock);
    629         LOGV("end libmix encoding\n");
    630 
    631 		retains[INPORT_INDEX] = BUFFER_RETAIN_NOT_RETAIN;
    632         if (ret == ENCODE_DEVICE_BUSY) {
    633 			//encoder is busy, put buf back and come again
    634             LOGV("encoder is busy, push buffer back to get again\n");
    635             retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
    636         } else {
    637             //if error, this buf will be returned
    638             CHECK_ENCODE_STATUS("encode");
    639 
    640             LOGV("put buffer to encoder and retain this buffer\n");
    641             mFrameEncodedCount ++;
    642             FrameEncoded = true;
    643             retains[INPORT_INDEX] = BUFFER_RETAIN_ACCUMULATE;
    644         }
    645 
    646     } else {
    647         //no new coming frames, but maybe still have frames not outputted
    648         LOGV("input buffer is null\n");
    649     }
    650 
    651     retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; //set to default value
    652     //just call getoutput if no frame encoded in this cycle to avoid retained buffer queue wrong state
    653     if (!FrameEncoded) {
    654         OMX_BOOL OutBufReturned = OMX_FALSE;
    655         oret = ProcessDataRetrieve(buffers, &OutBufReturned);
    656         if (OutBufReturned)
    657             retains[OUTPORT_INDEX] = BUFFER_RETAIN_NOT_RETAIN;
    658     }
    659 
    660     LOGV("ProcessorProcess ret=%x", oret);
    661     return oret;
    662 
    663 }
    664 
    665 OMX_ERRORTYPE OMXVideoEncoderAVC::BuildHandlerList(void) {
    666     OMXVideoEncoderBase::BuildHandlerList();
    667     AddHandler(OMX_IndexParamVideoAvc, GetParamVideoAvc, SetParamVideoAvc);
    668     AddHandler((OMX_INDEXTYPE)OMX_IndexParamNalStreamFormat, GetParamNalStreamFormat, SetParamNalStreamFormat);
    669     AddHandler((OMX_INDEXTYPE)OMX_IndexParamNalStreamFormatSupported, GetParamNalStreamFormatSupported, SetParamNalStreamFormatSupported);
    670     AddHandler((OMX_INDEXTYPE)OMX_IndexParamNalStreamFormatSelect, GetParamNalStreamFormatSelect, SetParamNalStreamFormatSelect);
    671     AddHandler(OMX_IndexConfigVideoAVCIntraPeriod, GetConfigVideoAVCIntraPeriod, SetConfigVideoAVCIntraPeriod);
    672     AddHandler(OMX_IndexConfigVideoNalSize, GetConfigVideoNalSize, SetConfigVideoNalSize);
    673     AddHandler((OMX_INDEXTYPE)OMX_IndexConfigIntelSliceNumbers, GetConfigIntelSliceNumbers, SetConfigIntelSliceNumbers);
    674     AddHandler((OMX_INDEXTYPE)OMX_IndexParamIntelAVCVUI, GetParamIntelAVCVUI, SetParamIntelAVCVUI);
    675     AddHandler((OMX_INDEXTYPE)OMX_IndexParamVideoBytestream, GetParamVideoBytestream, SetParamVideoBytestream);
    676     AddHandler((OMX_INDEXTYPE)OMX_IndexParamVideoProfileLevelQuerySupported, GetParamVideoProfileLevelQuerySupported, SetParamVideoProfileLevelQuerySupported);
    677     return OMX_ErrorNone;
    678 }
    679 
    680 OMX_ERRORTYPE OMXVideoEncoderAVC::GetParamVideoProfileLevelQuerySupported(OMX_PTR pStructure) {
    681     OMX_ERRORTYPE ret;
    682     OMX_VIDEO_PARAM_PROFILELEVELTYPE *p = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pStructure;
    683     CHECK_TYPE_HEADER(p);
    684     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    685 
    686     CHECK_ENUMERATION_RANGE(p->nProfileIndex,mPLTableCount);
    687 
    688     p->eProfile = mPLTable[p->nProfileIndex].profile;
    689     p->eLevel = mPLTable[p->nProfileIndex].level;
    690 
    691     return OMX_ErrorNone;
    692 }
    693 
    694 OMX_ERRORTYPE OMXVideoEncoderAVC::SetParamVideoProfileLevelQuerySupported(OMX_PTR) {
    695     LOGW("SetParamVideoAVCProfileLevel is not supported.");
    696     return OMX_ErrorUnsupportedSetting;
    697 }
    698 
    699 OMX_ERRORTYPE OMXVideoEncoderAVC::GetParamVideoAvc(OMX_PTR pStructure) {
    700     OMX_ERRORTYPE ret;
    701     OMX_VIDEO_PARAM_AVCTYPE *p = (OMX_VIDEO_PARAM_AVCTYPE *)pStructure;
    702     CHECK_TYPE_HEADER(p);
    703     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    704 
    705     mVideoEncoder->getParameters(mAVCParams);
    706     if(mParamAvc.eProfile == OMX_VIDEO_AVCProfileHigh)
    707     {
    708         mAVCParams->bEntropyCodingCABAC = 1;
    709         mAVCParams->bDirect8x8Inference = 1;
    710     }
    711     mParamAvc.bEntropyCodingCABAC = (OMX_BOOL)mAVCParams->bEntropyCodingCABAC;
    712     mParamAvc.bWeightedPPrediction = (OMX_BOOL)mAVCParams->bWeightedPPrediction;
    713     mParamAvc.nRefIdx10ActiveMinus1 = mAVCParams->refIdx10ActiveMinus1;
    714     mParamAvc.nRefIdx11ActiveMinus1 = mAVCParams->refIdx11ActiveMinus1;
    715     mParamAvc.nWeightedBipredicitonMode = mAVCParams->weightedBipredicitonMode;
    716     mParamAvc.bDirect8x8Inference = (OMX_BOOL)mAVCParams->bDirect8x8Inference;
    717     mParamAvc.bDirectSpatialTemporal = (OMX_BOOL)mAVCParams->bDirectSpatialTemporal;
    718     mParamAvc.nCabacInitIdc = mAVCParams->cabacInitIdc;
    719     mParamAvc.bFrameMBsOnly = (OMX_BOOL)mAVCParams->bFrameMBsOnly;
    720     mParamAvc.bconstIpred = (OMX_BOOL)mAVCParams->bConstIpred;
    721     memcpy(p, &mParamAvc, sizeof(*p));
    722     return OMX_ErrorNone;
    723 }
    724 
    725 OMX_ERRORTYPE OMXVideoEncoderAVC::SetParamVideoAvc(OMX_PTR pStructure) {
    726     OMX_ERRORTYPE ret;
    727     OMX_VIDEO_PARAM_AVCTYPE *p = (OMX_VIDEO_PARAM_AVCTYPE *)pStructure;
    728     CHECK_TYPE_HEADER(p);
    729     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    730     CHECK_SET_PARAM_STATE();
    731 
    732     //Check if parameters are valid
    733 
    734     if(p->bEnableASO == OMX_TRUE)
    735         return OMX_ErrorUnsupportedSetting;
    736 
    737     if(p->bEnableFMO == OMX_TRUE)
    738         return OMX_ErrorUnsupportedSetting;
    739 
    740     if(p->bEnableUEP == OMX_TRUE)
    741         return OMX_ErrorUnsupportedSetting;
    742 
    743     if(p->bEnableRS == OMX_TRUE)
    744         return OMX_ErrorUnsupportedSetting;
    745 
    746     if (p->eProfile == OMX_VIDEO_AVCProfileBaseline &&
    747             (p->nAllowedPictureTypes & OMX_VIDEO_PictureTypeB) )
    748         return OMX_ErrorBadParameter;
    749 
    750     if (p->nAllowedPictureTypes & OMX_VIDEO_PictureTypeP && (p->nPFrames == 0))
    751         return OMX_ErrorBadParameter;
    752 
    753     if (p->nAllowedPictureTypes & OMX_VIDEO_PictureTypeB ) {
    754         if (p->nBFrames == 0)
    755             return OMX_ErrorBadParameter;
    756 
    757         //IpPeriod must be integer
    758         uint32_t IntraPeriod = mParamAvc.nPFrames + mParamAvc.nBFrames ;
    759         if (IntraPeriod % mParamAvc.nPFrames != 0)
    760             return OMX_ErrorBadParameter;
    761 
    762         //IntraPeriod must be multipe of IpPeriod.
    763         uint32_t IpPeriod = IntraPeriod /mParamAvc.nPFrames;
    764         if (IntraPeriod % IpPeriod != 0)
    765             return OMX_ErrorBadParameter;
    766     }
    767 
    768     // TODO: do we need to check if port is enabled?
    769     // TODO: see SetPortAvcParam implementation - Can we make simple copy????
    770     memcpy(&mParamAvc, p, sizeof(mParamAvc));
    771     mVideoEncoder->getParameters(mAVCParams);
    772     mAVCParams->bEntropyCodingCABAC = mParamAvc.bEntropyCodingCABAC;
    773     mAVCParams->bDirect8x8Inference = mParamAvc.bDirect8x8Inference;
    774     if(mParamAvc.eProfile == OMX_VIDEO_AVCProfileBaseline){
    775         mAVCParams->bEntropyCodingCABAC = 0;
    776         mAVCParams->bDirect8x8Inference = 0;
    777     }
    778     mVideoEncoder->setParameters(mAVCParams);
    779 
    780 
    781     return OMX_ErrorNone;
    782 }
    783 
    784 OMX_ERRORTYPE OMXVideoEncoderAVC::GetParamNalStreamFormat(OMX_PTR pStructure) {
    785     OMX_ERRORTYPE ret;
    786     OMX_NALSTREAMFORMATTYPE *p = (OMX_NALSTREAMFORMATTYPE *)pStructure;
    787 
    788     CHECK_TYPE_HEADER(p);
    789     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    790     // TODO: check if this is desired format
    791     p->eNaluFormat = mNalStreamFormat.eNaluFormat; //OMX_NaluFormatStartCodes;
    792     return OMX_ErrorNone;
    793 }
    794 
    795 OMX_ERRORTYPE OMXVideoEncoderAVC::SetParamNalStreamFormat(OMX_PTR pStructure) {
    796     OMX_ERRORTYPE ret;
    797     OMX_NALSTREAMFORMATTYPE *p = (OMX_NALSTREAMFORMATTYPE *)pStructure;
    798 
    799     CHECK_TYPE_HEADER(p);
    800     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    801     LOGV("p->eNaluFormat =%d\n",p->eNaluFormat);
    802     if(p->eNaluFormat != OMX_NaluFormatStartCodes &&
    803             p->eNaluFormat != (OMX_NALUFORMATSTYPE)OMX_NaluFormatStartCodesSeparateFirstHeader &&
    804             p->eNaluFormat != OMX_NaluFormatOneNaluPerBuffer &&
    805             p->eNaluFormat != (OMX_NALUFORMATSTYPE)OMX_NaluFormatLengthPrefixedSeparateFirstHeader) {
    806         LOGE("Format not support\n");
    807         return OMX_ErrorUnsupportedSetting;
    808     }
    809     mNalStreamFormat.eNaluFormat = p->eNaluFormat;
    810     return OMX_ErrorNone;
    811 }
    812 
    813 OMX_ERRORTYPE OMXVideoEncoderAVC::GetParamNalStreamFormatSupported(OMX_PTR pStructure) {
    814     OMX_ERRORTYPE ret;
    815     OMX_NALSTREAMFORMATTYPE *p = (OMX_NALSTREAMFORMATTYPE *)pStructure;
    816 
    817     CHECK_TYPE_HEADER(p);
    818     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    819     p->eNaluFormat = (OMX_NALUFORMATSTYPE)
    820                      (OMX_NaluFormatStartCodes |
    821                       OMX_NaluFormatStartCodesSeparateFirstHeader |
    822                       OMX_NaluFormatOneNaluPerBuffer|
    823                       OMX_NaluFormatLengthPrefixedSeparateFirstHeader);
    824 
    825     // TODO: check if this is desired format
    826     // OMX_NaluFormatFourByteInterleaveLength |
    827     // OMX_NaluFormatZeroByteInterleaveLength);
    828     return OMX_ErrorNone;
    829 }
    830 
    831 OMX_ERRORTYPE OMXVideoEncoderAVC::SetParamNalStreamFormatSupported(OMX_PTR) {
    832     LOGW("SetParamNalStreamFormatSupported is not supported.");
    833     return OMX_ErrorUnsupportedSetting;
    834 }
    835 
    836 OMX_ERRORTYPE OMXVideoEncoderAVC::GetParamNalStreamFormatSelect(OMX_PTR) {
    837     LOGW("GetParamNalStreamFormatSelect is not supported.");
    838     return OMX_ErrorUnsupportedSetting;
    839 }
    840 
    841 OMX_ERRORTYPE OMXVideoEncoderAVC::SetParamNalStreamFormatSelect(OMX_PTR pStructure) {
    842     OMX_ERRORTYPE ret;
    843     OMX_NALSTREAMFORMATTYPE *p = (OMX_NALSTREAMFORMATTYPE *)pStructure;
    844     CHECK_TYPE_HEADER(p);
    845     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    846 
    847     // return OMX_ErrorIncorrectStateOperation if not in Loaded state
    848     CHECK_SET_PARAM_STATE();
    849 
    850     if (p->eNaluFormat != OMX_NaluFormatStartCodes &&
    851             p->eNaluFormat != (OMX_NALUFORMATSTYPE)OMX_NaluFormatStartCodesSeparateFirstHeader &&
    852             p->eNaluFormat != OMX_NaluFormatOneNaluPerBuffer&&
    853             p->eNaluFormat != (OMX_NALUFORMATSTYPE)OMX_NaluFormatLengthPrefixedSeparateFirstHeader) {
    854         //p->eNaluFormat != OMX_NaluFormatFourByteInterleaveLength &&
    855         //p->eNaluFormat != OMX_NaluFormatZeroByteInterleaveLength) {
    856         // TODO: check if this is desried
    857         return OMX_ErrorBadParameter;
    858     }
    859 
    860     mNalStreamFormat = *p;
    861     return OMX_ErrorNone;
    862 }
    863 
    864 OMX_ERRORTYPE OMXVideoEncoderAVC::GetConfigVideoAVCIntraPeriod(OMX_PTR pStructure) {
    865     OMX_ERRORTYPE ret;
    866     OMX_VIDEO_CONFIG_AVCINTRAPERIOD *p = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD *)pStructure;
    867 
    868     CHECK_TYPE_HEADER(p);
    869     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    870     // TODO: populate mConfigAvcIntraPeriod from VideoEncoder
    871     // return OMX_ErrorNotReady if VideoEncoder is not created.
    872     memcpy(p, &mConfigAvcIntraPeriod, sizeof(*p));
    873     return OMX_ErrorNone;
    874 }
    875 
    876 OMX_ERRORTYPE OMXVideoEncoderAVC::SetConfigVideoAVCIntraPeriod(OMX_PTR pStructure) {
    877     OMX_ERRORTYPE ret;
    878     Encode_Status retStatus = ENCODE_SUCCESS;
    879     OMX_VIDEO_CONFIG_AVCINTRAPERIOD *p = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD *)pStructure;
    880     CHECK_TYPE_HEADER(p);
    881     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    882 
    883     // return OMX_ErrorNone if not in Executing state
    884     // TODO:  return OMX_ErrorIncorrectStateOperation?
    885     CHECK_SET_CONFIG_STATE();
    886 
    887     //check if parameters are valid
    888     if ( ( (mParamAvc.nAllowedPictureTypes & OMX_VIDEO_PictureTypeP) ||
    889            (mParamAvc.nAllowedPictureTypes & OMX_VIDEO_PictureTypeB) ) &&
    890          p->nPFrames == 0 )
    891         return OMX_ErrorBadParameter;
    892 
    893     // TODO: apply AVC Intra Period configuration in Executing state
    894     VideoConfigAVCIntraPeriod avcIntraPreriod;
    895 
    896     if (mParamAvc.nAllowedPictureTypes & OMX_VIDEO_PictureTypeB) {
    897         avcIntraPreriod.intraPeriod = p->nPFrames;
    898         if (p->nPFrames % mParamAvc.nBFrames != 0)
    899             return OMX_ErrorBadParameter;
    900         avcIntraPreriod.ipPeriod = p->nPFrames / mParamAvc.nBFrames;
    901 
    902         if (avcIntraPreriod.intraPeriod % avcIntraPreriod.ipPeriod != 0)
    903             return OMX_ErrorBadParameter;
    904 
    905         avcIntraPreriod.idrInterval = p->nIDRPeriod;
    906     } else {
    907         avcIntraPreriod.intraPeriod = p->nPFrames + 1;
    908         avcIntraPreriod.ipPeriod = 1;
    909         if (avcIntraPreriod.intraPeriod == 0)
    910             avcIntraPreriod.idrInterval = 0;
    911         else
    912             avcIntraPreriod.idrInterval = p->nIDRPeriod;
    913     }
    914 
    915     retStatus = mVideoEncoder->setConfig(&avcIntraPreriod);
    916     if(retStatus !=  ENCODE_SUCCESS) {
    917         LOGW("set avc intra period config failed");
    918     }
    919 
    920     mEncoderParams->intraPeriod = avcIntraPreriod.intraPeriod;
    921     mAVCParams->idrInterval = avcIntraPreriod.idrInterval;
    922     mAVCParams->ipPeriod = avcIntraPreriod.ipPeriod;
    923 
    924     mConfigAvcIntraPeriod = *p;
    925     mConfigAvcIntraPeriod.nIDRPeriod = avcIntraPreriod.idrInterval;
    926 
    927     return OMX_ErrorNone;
    928 }
    929 
    930 OMX_ERRORTYPE OMXVideoEncoderAVC::GetConfigVideoNalSize(OMX_PTR pStructure) {
    931     OMX_ERRORTYPE ret;
    932     OMX_VIDEO_CONFIG_NALSIZE *p = (OMX_VIDEO_CONFIG_NALSIZE *)pStructure;
    933 
    934     CHECK_TYPE_HEADER(p);
    935     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    936     memcpy(p, &mConfigNalSize, sizeof(*p));
    937     return OMX_ErrorNone;
    938 }
    939 
    940 OMX_ERRORTYPE OMXVideoEncoderAVC::SetConfigVideoNalSize(OMX_PTR pStructure) {
    941     OMX_ERRORTYPE ret;
    942     Encode_Status retStatus = ENCODE_SUCCESS;
    943     if (mParamBitrate.eControlRate == OMX_Video_ControlRateMax) {
    944         LOGE("SetConfigVideoNalSize failed. Feature is disabled.");
    945         return OMX_ErrorUnsupportedIndex;
    946     }
    947     OMX_VIDEO_CONFIG_NALSIZE *p = (OMX_VIDEO_CONFIG_NALSIZE *)pStructure;
    948     CHECK_TYPE_HEADER(p);
    949     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    950 
    951     // set in either Loaded  state (ComponentSetParam) or Executing state (ComponentSetConfig)
    952     mConfigNalSize = *p;
    953 
    954     // return OMX_ErrorNone if not in Executing state
    955     // TODO: return OMX_ErrorIncorrectStateOperation?
    956     CHECK_SET_CONFIG_STATE();
    957 
    958     if (mParamBitrate.eControlRate != (OMX_VIDEO_CONTROLRATETYPE)OMX_Video_Intel_ControlRateVideoConferencingMode) {
    959         LOGE("SetConfigVideoNalSize failed. Feature is supported only in VCM.");
    960         return OMX_ErrorUnsupportedSetting;
    961     }
    962     VideoConfigNALSize configNalSize;
    963     configNalSize.maxSliceSize = mConfigNalSize.nNaluBytes * 8;
    964     retStatus = mVideoEncoder->setConfig(&configNalSize);
    965     if(retStatus != ENCODE_SUCCESS) {
    966         LOGW("set NAL size config failed");
    967     }
    968     return OMX_ErrorNone;
    969 }
    970 
    971 OMX_ERRORTYPE OMXVideoEncoderAVC::GetConfigIntelSliceNumbers(OMX_PTR pStructure) {
    972     OMX_ERRORTYPE ret;
    973     OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS *p = (OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS *)pStructure;
    974 
    975     CHECK_TYPE_HEADER(p);
    976     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    977     memcpy(p, &mConfigIntelSliceNumbers, sizeof(*p));
    978     return OMX_ErrorNone;
    979 }
    980 
    981 OMX_ERRORTYPE OMXVideoEncoderAVC::SetConfigIntelSliceNumbers(OMX_PTR pStructure) {
    982     OMX_ERRORTYPE ret;
    983     Encode_Status retStatus = ENCODE_SUCCESS;
    984     if (mParamBitrate.eControlRate == OMX_Video_ControlRateMax) {
    985         LOGE("SetConfigIntelSliceNumbers failed. Feature is disabled.");
    986         return OMX_ErrorUnsupportedIndex;
    987     }
    988     OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS *p = (OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS *)pStructure;
    989     CHECK_TYPE_HEADER(p);
    990     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
    991 
    992     // set in either Loaded  state (ComponentSetParam) or Executing state (ComponentSetConfig)
    993     mConfigIntelSliceNumbers = *p;
    994 
    995     // return OMX_ErrorNone if not in Executing state
    996     // TODO: return OMX_ErrorIncorrectStateOperation?
    997     CHECK_SET_CONFIG_STATE();
    998 
    999     if (mParamBitrate.eControlRate != (OMX_VIDEO_CONTROLRATETYPE)OMX_Video_Intel_ControlRateVideoConferencingMode) {
   1000         LOGE("SetConfigIntelSliceNumbers failed. Feature is supported only in VCM.");
   1001         return OMX_ErrorUnsupportedSetting;
   1002     }
   1003     VideoConfigSliceNum sliceNum;
   1004     sliceNum.sliceNum.iSliceNum = mConfigIntelSliceNumbers.nISliceNumber;
   1005     sliceNum.sliceNum.pSliceNum = mConfigIntelSliceNumbers.nPSliceNumber;
   1006     retStatus = mVideoEncoder->setConfig(&sliceNum);
   1007     if(retStatus != ENCODE_SUCCESS) {
   1008         LOGW("set silce num config failed!\n");
   1009     }
   1010     return OMX_ErrorNone;
   1011 }
   1012 
   1013 OMX_ERRORTYPE OMXVideoEncoderAVC::GetParamIntelAVCVUI(OMX_PTR pStructure) {
   1014 
   1015     OMX_ERRORTYPE ret;
   1016     OMX_VIDEO_PARAM_INTEL_AVCVUI *p = (OMX_VIDEO_PARAM_INTEL_AVCVUI *)pStructure;
   1017 
   1018     CHECK_TYPE_HEADER(p);
   1019     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
   1020     memcpy(p, &mParamIntelAvcVui, sizeof(*p));
   1021 
   1022     return OMX_ErrorNone;
   1023 }
   1024 
   1025 OMX_ERRORTYPE OMXVideoEncoderAVC::SetParamIntelAVCVUI(OMX_PTR pStructure) {
   1026 
   1027     OMX_ERRORTYPE ret;
   1028     OMX_VIDEO_PARAM_INTEL_AVCVUI *p = (OMX_VIDEO_PARAM_INTEL_AVCVUI *)pStructure;
   1029     CHECK_TYPE_HEADER(p);
   1030     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
   1031 
   1032     // set only in Loaded state (ComponentSetParam)
   1033     CHECK_SET_PARAM_STATE();
   1034 
   1035     mParamIntelAvcVui = *p;
   1036     return OMX_ErrorNone;
   1037 }
   1038 
   1039 OMX_ERRORTYPE OMXVideoEncoderAVC::GetParamVideoBytestream(OMX_PTR) {
   1040     return OMX_ErrorUnsupportedSetting;
   1041 }
   1042 
   1043 OMX_ERRORTYPE OMXVideoEncoderAVC::SetParamVideoBytestream(OMX_PTR pStructure) {
   1044     OMX_ERRORTYPE ret;
   1045     OMX_VIDEO_PARAM_BYTESTREAMTYPE *p = (OMX_VIDEO_PARAM_BYTESTREAMTYPE *)pStructure;
   1046     CHECK_TYPE_HEADER(p);
   1047     CHECK_PORT_INDEX(p, OUTPORT_INDEX);
   1048 
   1049     // set only in Loaded state (ComponentSetParam)
   1050     CHECK_SET_PARAM_STATE();
   1051 
   1052     if (p->bBytestream == OMX_TRUE) {
   1053         mNalStreamFormat.eNaluFormat = OMX_NaluFormatStartCodes;
   1054     } else {
   1055         // TODO: do we need to override the Nalu format?
   1056         mNalStreamFormat.eNaluFormat = (OMX_NALUFORMATSTYPE)OMX_NaluFormatZeroByteInterleaveLength;
   1057     }
   1058 
   1059     return OMX_ErrorNone;
   1060 }
   1061 
   1062 
   1063 DECLARE_OMX_COMPONENT("OMX.Intel.VideoEncoder.AVC", "video_encoder.avc", OMXVideoEncoderAVC);
   1064