Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      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
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 #include "avcenc_api.h"
     19 #include "avcenc_lib.h"
     20 
     21 /* ======================================================================== */
     22 /*  Function : PVAVCGetNALType()                                            */
     23 /*  Date     : 11/4/2003                                                    */
     24 /*  Purpose  : Sniff NAL type from the bitstream                            */
     25 /*  In/out   :                                                              */
     26 /*  Return   : AVCENC_SUCCESS if succeed, AVCENC_FAIL if fail.              */
     27 /*  Modified :                                                              */
     28 /* ======================================================================== */
     29 OSCL_EXPORT_REF AVCEnc_Status PVAVCEncGetNALType(unsigned char *bitstream, int size,
     30         int *nal_type, int *nal_ref_idc)
     31 {
     32     int forbidden_zero_bit;
     33     if (size > 0)
     34     {
     35         forbidden_zero_bit = bitstream[0] >> 7;
     36         if (forbidden_zero_bit != 0)
     37             return AVCENC_FAIL;
     38         *nal_ref_idc = (bitstream[0] & 0x60) >> 5;
     39         *nal_type = bitstream[0] & 0x1F;
     40         return AVCENC_SUCCESS;
     41     }
     42 
     43     return AVCENC_FAIL;
     44 }
     45 
     46 
     47 /* ======================================================================== */
     48 /*  Function : PVAVCEncInitialize()                                         */
     49 /*  Date     : 3/18/2004                                                    */
     50 /*  Purpose  : Initialize the encoder library, allocate memory and verify   */
     51 /*              the profile/level support/settings.                         */
     52 /*  In/out   : Encoding parameters.                                         */
     53 /*  Return   : AVCENC_SUCCESS for success.                                  */
     54 /*  Modified :                                                              */
     55 /* ======================================================================== */
     56 OSCL_EXPORT_REF AVCEnc_Status PVAVCEncInitialize(AVCHandle *avcHandle, AVCEncParams *encParam,
     57         void* extSPS, void* extPPS)
     58 {
     59     AVCEnc_Status status;
     60     AVCEncObject *encvid;
     61     AVCCommonObj *video;
     62     uint32 *userData = (uint32*) avcHandle->userData;
     63     int framesize;
     64 
     65     if (avcHandle->AVCObject != NULL)
     66     {
     67         return AVCENC_ALREADY_INITIALIZED; /* It's already initialized, need to cleanup first */
     68     }
     69 
     70     /* not initialized */
     71 
     72     /* allocate videoObject */
     73     avcHandle->AVCObject = (void*)avcHandle->CBAVC_Malloc(userData, sizeof(AVCEncObject), DEFAULT_ATTR);
     74     if (avcHandle->AVCObject == NULL)
     75     {
     76         return AVCENC_MEMORY_FAIL;
     77     }
     78 
     79     encvid = (AVCEncObject*) avcHandle->AVCObject;
     80 
     81     encvid->enc_state = AVCEnc_Initializing;
     82 
     83     encvid->avcHandle = avcHandle;
     84 
     85     encvid->common = (AVCCommonObj*) avcHandle->CBAVC_Malloc(userData, sizeof(AVCCommonObj), DEFAULT_ATTR);
     86     if (encvid->common == NULL)
     87     {
     88         return AVCENC_MEMORY_FAIL;
     89     }
     90 
     91     video = encvid->common;
     92 
     93     /* allocate bitstream structure */
     94     encvid->bitstream = (AVCEncBitstream*) avcHandle->CBAVC_Malloc(userData, sizeof(AVCEncBitstream), DEFAULT_ATTR);
     95     if (encvid->bitstream == NULL)
     96     {
     97         return AVCENC_MEMORY_FAIL;
     98     }
     99     encvid->bitstream->encvid = encvid; /* to point back for reallocation */
    100 
    101     /* allocate sequence parameter set structure */
    102     video->currSeqParams = (AVCSeqParamSet*) avcHandle->CBAVC_Malloc(userData, sizeof(AVCSeqParamSet), DEFAULT_ATTR);
    103     if (video->currSeqParams == NULL)
    104     {
    105         return AVCENC_MEMORY_FAIL;
    106     }
    107 
    108     /* allocate picture parameter set structure */
    109     video->currPicParams = (AVCPicParamSet*) avcHandle->CBAVC_Malloc(userData, sizeof(AVCPicParamSet), DEFAULT_ATTR);
    110     if (video->currPicParams == NULL)
    111     {
    112         return AVCENC_MEMORY_FAIL;
    113     }
    114 
    115     /* allocate slice header structure */
    116     video->sliceHdr = (AVCSliceHeader*) avcHandle->CBAVC_Malloc(userData, sizeof(AVCSliceHeader), DEFAULT_ATTR);
    117     if (video->sliceHdr == NULL)
    118     {
    119         return AVCENC_MEMORY_FAIL;
    120     }
    121 
    122     /* allocate encoded picture buffer structure*/
    123     video->decPicBuf = (AVCDecPicBuffer*) avcHandle->CBAVC_Malloc(userData, sizeof(AVCDecPicBuffer), DEFAULT_ATTR);
    124     if (video->decPicBuf == NULL)
    125     {
    126         return AVCENC_MEMORY_FAIL;
    127     }
    128 
    129     /* allocate rate control structure */
    130     encvid->rateCtrl = (AVCRateControl*) avcHandle->CBAVC_Malloc(userData, sizeof(AVCRateControl), DEFAULT_ATTR);
    131     if (encvid->rateCtrl == NULL)
    132     {
    133         return AVCENC_MEMORY_FAIL;
    134     }
    135 
    136     /* reset frame list, not really needed */
    137     video->currPic = NULL;
    138     video->currFS = NULL;
    139     encvid->currInput = NULL;
    140     video->prevRefPic = NULL;
    141 
    142     /* now read encParams, and allocate dimension-dependent variables */
    143     /* such as mblock */
    144     status = SetEncodeParam(avcHandle, encParam, extSPS, extPPS); /* initialized variables to be used in SPS*/
    145     if (status != AVCENC_SUCCESS)
    146     {
    147         return status;
    148     }
    149 
    150     if (encParam->use_overrun_buffer == AVC_ON)
    151     {
    152         /* allocate overrun buffer */
    153         encvid->oBSize = encvid->rateCtrl->cpbSize;
    154         if (encvid->oBSize > DEFAULT_OVERRUN_BUFFER_SIZE)
    155         {
    156             encvid->oBSize = DEFAULT_OVERRUN_BUFFER_SIZE;
    157         }
    158         encvid->overrunBuffer = (uint8*) avcHandle->CBAVC_Malloc(userData, encvid->oBSize, DEFAULT_ATTR);
    159         if (encvid->overrunBuffer == NULL)
    160         {
    161             return AVCENC_MEMORY_FAIL;
    162         }
    163     }
    164     else
    165     {
    166         encvid->oBSize = 0;
    167         encvid->overrunBuffer = NULL;
    168     }
    169 
    170     /* allocate frame size dependent structures */
    171     framesize = video->FrameHeightInMbs * video->PicWidthInMbs;
    172 
    173     video->mblock = (AVCMacroblock*) avcHandle->CBAVC_Malloc(userData, sizeof(AVCMacroblock) * framesize, DEFAULT_ATTR);
    174     if (video->mblock == NULL)
    175     {
    176         return AVCENC_MEMORY_FAIL;
    177     }
    178 
    179     video->MbToSliceGroupMap = (int*) avcHandle->CBAVC_Malloc(userData, sizeof(uint) * video->PicSizeInMapUnits * 2, DEFAULT_ATTR);
    180     if (video->MbToSliceGroupMap == NULL)
    181     {
    182         return AVCENC_MEMORY_FAIL;
    183     }
    184 
    185     encvid->mot16x16 = (AVCMV*) avcHandle->CBAVC_Malloc(userData, sizeof(AVCMV) * framesize, DEFAULT_ATTR);
    186     if (encvid->mot16x16 == NULL)
    187     {
    188         return AVCENC_MEMORY_FAIL;
    189     }
    190 
    191     encvid->intraSearch = (uint8*) avcHandle->CBAVC_Malloc(userData, sizeof(uint8) * framesize, DEFAULT_ATTR);
    192     if (encvid->intraSearch == NULL)
    193     {
    194         return AVCENC_MEMORY_FAIL;
    195     }
    196 
    197     encvid->min_cost = (int*) avcHandle->CBAVC_Malloc(userData, sizeof(int) * framesize, DEFAULT_ATTR);
    198     if (encvid->min_cost == NULL)
    199     {
    200         return AVCENC_MEMORY_FAIL;
    201     }
    202 
    203     /* initialize motion search related memory */
    204     if (AVCENC_SUCCESS != InitMotionSearchModule(avcHandle))
    205     {
    206         return AVCENC_MEMORY_FAIL;
    207     }
    208 
    209     if (AVCENC_SUCCESS != InitRateControlModule(avcHandle))
    210     {
    211         return AVCENC_MEMORY_FAIL;
    212     }
    213 
    214     /* intialize function pointers */
    215     encvid->functionPointer = (AVCEncFuncPtr*) avcHandle->CBAVC_Malloc(userData, sizeof(AVCEncFuncPtr), DEFAULT_ATTR);
    216     if (encvid->functionPointer == NULL)
    217     {
    218         return AVCENC_MEMORY_FAIL;
    219     }
    220     encvid->functionPointer->SAD_Macroblock = &AVCSAD_Macroblock_C;
    221     encvid->functionPointer->SAD_MB_HalfPel[0] = NULL;
    222     encvid->functionPointer->SAD_MB_HalfPel[1] = &AVCSAD_MB_HalfPel_Cxh;
    223     encvid->functionPointer->SAD_MB_HalfPel[2] = &AVCSAD_MB_HalfPel_Cyh;
    224     encvid->functionPointer->SAD_MB_HalfPel[3] = &AVCSAD_MB_HalfPel_Cxhyh;
    225 
    226     /* initialize timing control */
    227     encvid->modTimeRef = 0;     /* ALWAYS ASSUME THAT TIMESTAMP START FROM 0 !!!*/
    228     video->prevFrameNum = 0;
    229     encvid->prevCodedFrameNum = 0;
    230     encvid->dispOrdPOCRef = 0;
    231 
    232     if (encvid->outOfBandParamSet == TRUE)
    233     {
    234         encvid->enc_state = AVCEnc_Encoding_SPS;
    235     }
    236     else
    237     {
    238         encvid->enc_state = AVCEnc_Analyzing_Frame;
    239     }
    240 
    241     return AVCENC_SUCCESS;
    242 }
    243 
    244 /* ======================================================================== */
    245 /*  Function : PVAVCEncGetMaxOutputSize()                                   */
    246 /*  Date     : 11/29/2008                                                   */
    247 /*  Purpose  : Return max output buffer size that apps should allocate for  */
    248 /*              output buffer.                                              */
    249 /*  In/out   :                                                              */
    250 /*  Return   : AVCENC_SUCCESS for success.                                  */
    251 /*  Modified :   size                                                       */
    252 /* ======================================================================== */
    253 
    254 OSCL_EXPORT_REF AVCEnc_Status PVAVCEncGetMaxOutputBufferSize(AVCHandle *avcHandle, int* size)
    255 {
    256     AVCEncObject *encvid = (AVCEncObject*)avcHandle->AVCObject;
    257 
    258     if (encvid == NULL)
    259     {
    260         return AVCENC_UNINITIALIZED;
    261     }
    262 
    263     *size = encvid->rateCtrl->cpbSize;
    264 
    265     return AVCENC_SUCCESS;
    266 }
    267 
    268 /* ======================================================================== */
    269 /*  Function : PVAVCEncSetInput()                                           */
    270 /*  Date     : 4/18/2004                                                    */
    271 /*  Purpose  : To feed an unencoded original frame to the encoder library.  */
    272 /*  In/out   :                                                              */
    273 /*  Return   : AVCENC_SUCCESS for success.                                  */
    274 /*  Modified :                                                              */
    275 /* ======================================================================== */
    276 OSCL_EXPORT_REF AVCEnc_Status PVAVCEncSetInput(AVCHandle *avcHandle, AVCFrameIO *input)
    277 {
    278     AVCEncObject *encvid = (AVCEncObject*)avcHandle->AVCObject;
    279     AVCCommonObj *video = encvid->common;
    280     AVCRateControl *rateCtrl = encvid->rateCtrl;
    281 
    282     AVCEnc_Status status;
    283     uint frameNum;
    284 
    285     if (encvid == NULL)
    286     {
    287         return AVCENC_UNINITIALIZED;
    288     }
    289 
    290     if (encvid->enc_state == AVCEnc_WaitingForBuffer)
    291     {
    292         goto RECALL_INITFRAME;
    293     }
    294     else if (encvid->enc_state != AVCEnc_Analyzing_Frame)
    295     {
    296         return AVCENC_FAIL;
    297     }
    298 
    299     if (input->pitch > 0xFFFF)
    300     {
    301         return AVCENC_NOT_SUPPORTED; // we use 2-bytes for pitch
    302     }
    303 
    304     /***********************************/
    305 
    306     /* Let's rate control decide whether to encode this frame or not */
    307     /* Also set video->nal_unit_type, sliceHdr->slice_type, video->slice_type */
    308     if (AVCENC_SUCCESS != RCDetermineFrameNum(encvid, rateCtrl, input->coding_timestamp, &frameNum))
    309     {
    310         return AVCENC_SKIPPED_PICTURE; /* not time to encode, thus skipping */
    311     }
    312 
    313     /* we may not need this line */
    314     //nextFrmModTime = (uint32)((((frameNum+1)*1000)/rateCtrl->frame_rate) + modTimeRef); /* rec. time */
    315     //encvid->nextModTime = nextFrmModTime - (encvid->frameInterval>>1) - 1; /* between current and next frame */
    316 
    317     encvid->currInput = input;
    318     encvid->currInput->coding_order = frameNum;
    319 
    320 RECALL_INITFRAME:
    321     /* initialize and analyze the frame */
    322     status = InitFrame(encvid);
    323 
    324     if (status == AVCENC_SUCCESS)
    325     {
    326         encvid->enc_state = AVCEnc_Encoding_Frame;
    327     }
    328     else if (status == AVCENC_NEW_IDR)
    329     {
    330         if (encvid->outOfBandParamSet == TRUE)
    331         {
    332             encvid->enc_state = AVCEnc_Encoding_Frame;
    333         }
    334         else // assuming that in-band paramset keeps sending new SPS and PPS.
    335         {
    336             encvid->enc_state = AVCEnc_Encoding_SPS;
    337             //video->currSeqParams->seq_parameter_set_id++;
    338             //if(video->currSeqParams->seq_parameter_set_id > 31) // range check
    339             {
    340                 video->currSeqParams->seq_parameter_set_id = 0;  // reset
    341             }
    342         }
    343 
    344         video->sliceHdr->idr_pic_id++;
    345         if (video->sliceHdr->idr_pic_id > 65535) // range check
    346         {
    347             video->sliceHdr->idr_pic_id = 0;  // reset
    348         }
    349     }
    350     /* the following logics need to be revisited */
    351     else if (status == AVCENC_PICTURE_READY) // no buffers returned back to the encoder
    352     {
    353         encvid->enc_state = AVCEnc_WaitingForBuffer; // Input accepted but can't continue
    354         // need to free up some memory before proceeding with Encode
    355     }
    356 
    357     return status; // return status, including the AVCENC_FAIL case and all 3 above.
    358 }
    359 
    360 /* ======================================================================== */
    361 /*  Function : PVAVCEncodeNAL()                                             */
    362 /*  Date     : 4/29/2004                                                    */
    363 /*  Purpose  : To encode one NAL/slice.                                     */
    364 /*  In/out   :                                                              */
    365 /*  Return   : AVCENC_SUCCESS for success.                                  */
    366 /*  Modified :                                                              */
    367 /* ======================================================================== */
    368 OSCL_EXPORT_REF AVCEnc_Status PVAVCEncodeNAL(AVCHandle *avcHandle, unsigned char *buffer, unsigned int *buf_nal_size, int *nal_type)
    369 {
    370     AVCEncObject *encvid = (AVCEncObject*)avcHandle->AVCObject;
    371     AVCCommonObj *video = encvid->common;
    372     AVCEncBitstream *bitstream = encvid->bitstream;
    373     AVCEnc_Status status;
    374 
    375     if (encvid == NULL)
    376     {
    377         return AVCENC_UNINITIALIZED;
    378     }
    379 
    380     switch (encvid->enc_state)
    381     {
    382         case AVCEnc_Initializing:
    383             return AVCENC_UNINITIALIZED;
    384         case AVCEnc_Encoding_SPS:
    385             /* initialized the structure */
    386             BitstreamEncInit(bitstream, buffer, *buf_nal_size, NULL, 0);
    387             BitstreamWriteBits(bitstream, 8, (1 << 5) | AVC_NALTYPE_SPS);
    388 
    389             /* encode SPS */
    390             status = EncodeSPS(encvid, bitstream);
    391             if (status != AVCENC_SUCCESS)
    392             {
    393                 return status;
    394             }
    395 
    396             /* closing the NAL with trailing bits */
    397             status = BitstreamTrailingBits(bitstream, buf_nal_size);
    398             if (status == AVCENC_SUCCESS)
    399             {
    400                 encvid->enc_state = AVCEnc_Encoding_PPS;
    401                 video->currPicParams->seq_parameter_set_id = video->currSeqParams->seq_parameter_set_id;
    402                 video->currPicParams->pic_parameter_set_id++;
    403                 *nal_type = AVC_NALTYPE_SPS;
    404                 *buf_nal_size = bitstream->write_pos;
    405             }
    406             break;
    407         case AVCEnc_Encoding_PPS:
    408             /* initialized the structure */
    409             BitstreamEncInit(bitstream, buffer, *buf_nal_size, NULL, 0);
    410             BitstreamWriteBits(bitstream, 8, (1 << 5) | AVC_NALTYPE_PPS);
    411 
    412             /* encode PPS */
    413             status = EncodePPS(encvid, bitstream);
    414             if (status != AVCENC_SUCCESS)
    415             {
    416                 return status;
    417             }
    418 
    419             /* closing the NAL with trailing bits */
    420             status = BitstreamTrailingBits(bitstream, buf_nal_size);
    421             if (status == AVCENC_SUCCESS)
    422             {
    423                 if (encvid->outOfBandParamSet == TRUE) // already extract PPS, SPS
    424                 {
    425                     encvid->enc_state = AVCEnc_Analyzing_Frame;
    426                 }
    427                 else    // SetInput has been called before SPS and PPS.
    428                 {
    429                     encvid->enc_state = AVCEnc_Encoding_Frame;
    430                 }
    431 
    432                 *nal_type = AVC_NALTYPE_PPS;
    433                 *buf_nal_size = bitstream->write_pos;
    434             }
    435             break;
    436 
    437         case AVCEnc_Encoding_Frame:
    438             /* initialized the structure */
    439             BitstreamEncInit(bitstream, buffer, *buf_nal_size, encvid->overrunBuffer, encvid->oBSize);
    440             BitstreamWriteBits(bitstream, 8, (video->nal_ref_idc << 5) | (video->nal_unit_type));
    441 
    442             /* Re-order the reference list according to the ref_pic_list_reordering() */
    443             /* We don't have to reorder the list for the encoder here. This can only be done
    444             after we encode this slice. We can run thru a second-pass to see if new ordering
    445             would save more bits. Too much delay !! */
    446             /* status = ReOrderList(video);*/
    447             status = InitSlice(encvid);
    448             if (status != AVCENC_SUCCESS)
    449             {
    450                 return status;
    451             }
    452 
    453             /* when we have everything, we encode the slice header */
    454             status = EncodeSliceHeader(encvid, bitstream);
    455             if (status != AVCENC_SUCCESS)
    456             {
    457                 return status;
    458             }
    459 
    460             status = AVCEncodeSlice(encvid);
    461 
    462             video->slice_id++;
    463 
    464             /* closing the NAL with trailing bits */
    465             BitstreamTrailingBits(bitstream, buf_nal_size);
    466 
    467             *buf_nal_size = bitstream->write_pos;
    468 
    469             encvid->rateCtrl->numFrameBits += ((*buf_nal_size) << 3);
    470 
    471             *nal_type = video->nal_unit_type;
    472 
    473             if (status == AVCENC_PICTURE_READY)
    474             {
    475                 status = RCUpdateFrame(encvid);
    476                 if (status == AVCENC_SKIPPED_PICTURE) /* skip current frame */
    477                 {
    478                     DPBReleaseCurrentFrame(avcHandle, video);
    479                     encvid->enc_state = AVCEnc_Analyzing_Frame;
    480 
    481                     return status;
    482                 }
    483 
    484                 /* perform loop-filtering on the entire frame */
    485                 DeblockPicture(video);
    486 
    487                 /* update the original frame array */
    488                 encvid->prevCodedFrameNum = encvid->currInput->coding_order;
    489 
    490                 /* store the encoded picture in the DPB buffer */
    491                 StorePictureInDPB(avcHandle, video);
    492 
    493                 if (video->currPic->isReference)
    494                 {
    495                     video->PrevRefFrameNum = video->sliceHdr->frame_num;
    496                 }
    497 
    498                 /* update POC related variables */
    499                 PostPOC(video);
    500 
    501                 encvid->enc_state = AVCEnc_Analyzing_Frame;
    502                 status = AVCENC_PICTURE_READY;
    503 
    504             }
    505             break;
    506         default:
    507             status = AVCENC_WRONG_STATE;
    508     }
    509 
    510     return status;
    511 }
    512 
    513 /* ======================================================================== */
    514 /*  Function : PVAVCEncGetOverrunBuffer()                                   */
    515 /*  Purpose  : To retrieve the overrun buffer. Check whether overrun buffer */
    516 /*              is used or not before returning                             */
    517 /*  In/out   :                                                              */
    518 /*  Return   : Pointer to the internal overrun buffer.                      */
    519 /*  Modified :                                                              */
    520 /* ======================================================================== */
    521 OSCL_EXPORT_REF uint8* PVAVCEncGetOverrunBuffer(AVCHandle* avcHandle)
    522 {
    523     AVCEncObject *encvid = (AVCEncObject*)avcHandle->AVCObject;
    524     AVCEncBitstream *bitstream = encvid->bitstream;
    525 
    526     if (bitstream->overrunBuffer == bitstream->bitstreamBuffer) /* OB is used */
    527     {
    528         return encvid->overrunBuffer;
    529     }
    530     else
    531     {
    532         return NULL;
    533     }
    534 }
    535 
    536 
    537 /* ======================================================================== */
    538 /*  Function : PVAVCEncGetRecon()                                           */
    539 /*  Date     : 4/29/2004                                                    */
    540 /*  Purpose  : To retrieve the most recently encoded frame.                 */
    541 /*              assume that user will make a copy if they want to hold on   */
    542 /*              to it. Otherwise, it is not guaranteed to be reserved.      */
    543 /*              Most applications prefer to see original frame rather than  */
    544 /*              reconstructed frame. So, we are staying aware from complex  */
    545 /*              buffering mechanism. If needed, can be added later.         */
    546 /*  In/out   :                                                              */
    547 /*  Return   : AVCENC_SUCCESS for success.                                  */
    548 /*  Modified :                                                              */
    549 /* ======================================================================== */
    550 OSCL_EXPORT_REF AVCEnc_Status PVAVCEncGetRecon(AVCHandle *avcHandle, AVCFrameIO *recon)
    551 {
    552     AVCEncObject *encvid = (AVCEncObject*)avcHandle->AVCObject;
    553     AVCCommonObj *video = encvid->common;
    554     AVCFrameStore *currFS = video->currFS;
    555 
    556     if (encvid == NULL)
    557     {
    558         return AVCENC_UNINITIALIZED;
    559     }
    560 
    561     recon->YCbCr[0] = currFS->frame.Sl;
    562     recon->YCbCr[1] = currFS->frame.Scb;
    563     recon->YCbCr[2] = currFS->frame.Scr;
    564     recon->height = currFS->frame.height;
    565     recon->pitch = currFS->frame.pitch;
    566     recon->disp_order = currFS->PicOrderCnt;
    567     recon->coding_order = currFS->FrameNum;
    568     recon->id = (intptr_t) currFS->base_dpb; /* use the pointer as the id */
    569 
    570     currFS->IsOutputted |= 1;
    571 
    572     return AVCENC_SUCCESS;
    573 }
    574 
    575 OSCL_EXPORT_REF AVCEnc_Status PVAVCEncReleaseRecon(AVCHandle *avcHandle, AVCFrameIO *recon)
    576 {
    577     OSCL_UNUSED_ARG(avcHandle);
    578     OSCL_UNUSED_ARG(recon);
    579 
    580     return AVCENC_SUCCESS; //for now
    581 }
    582 
    583 /* ======================================================================== */
    584 /*  Function : PVAVCCleanUpEncoder()                                        */
    585 /*  Date     : 4/18/2004                                                    */
    586 /*  Purpose  : To clean up memories allocated by PVAVCEncInitialize()       */
    587 /*  In/out   :                                                              */
    588 /*  Return   : AVCENC_SUCCESS for success.                                  */
    589 /*  Modified :                                                              */
    590 /* ======================================================================== */
    591 OSCL_EXPORT_REF void    PVAVCCleanUpEncoder(AVCHandle *avcHandle)
    592 {
    593     AVCEncObject *encvid = (AVCEncObject*) avcHandle->AVCObject;
    594     AVCCommonObj *video;
    595     uint32 *userData = (uint32*) avcHandle->userData;
    596 
    597     if (encvid != NULL)
    598     {
    599         CleanMotionSearchModule(avcHandle);
    600 
    601         CleanupRateControlModule(avcHandle);
    602 
    603         if (encvid->functionPointer != NULL)
    604         {
    605             avcHandle->CBAVC_Free(userData, encvid->functionPointer);
    606         }
    607 
    608         if (encvid->min_cost)
    609         {
    610             avcHandle->CBAVC_Free(userData, encvid->min_cost);
    611         }
    612 
    613         if (encvid->intraSearch)
    614         {
    615             avcHandle->CBAVC_Free(userData, encvid->intraSearch);
    616         }
    617 
    618         if (encvid->mot16x16)
    619         {
    620             avcHandle->CBAVC_Free(userData, encvid->mot16x16);
    621         }
    622 
    623         if (encvid->rateCtrl)
    624         {
    625             avcHandle->CBAVC_Free(userData, encvid->rateCtrl);
    626         }
    627 
    628         if (encvid->overrunBuffer)
    629         {
    630             avcHandle->CBAVC_Free(userData, encvid->overrunBuffer);
    631         }
    632 
    633         video = encvid->common;
    634         if (video != NULL)
    635         {
    636             if (video->MbToSliceGroupMap)
    637             {
    638                 avcHandle->CBAVC_Free(userData, video->MbToSliceGroupMap);
    639             }
    640             if (video->mblock != NULL)
    641             {
    642                 avcHandle->CBAVC_Free(userData, video->mblock);
    643             }
    644             if (video->decPicBuf != NULL)
    645             {
    646                 CleanUpDPB(avcHandle, video);
    647                 avcHandle->CBAVC_Free(userData, video->decPicBuf);
    648             }
    649             if (video->sliceHdr != NULL)
    650             {
    651                 avcHandle->CBAVC_Free(userData, video->sliceHdr);
    652             }
    653             if (video->currPicParams != NULL)
    654             {
    655                 if (video->currPicParams->slice_group_id)
    656                 {
    657                     avcHandle->CBAVC_Free(userData, video->currPicParams->slice_group_id);
    658                 }
    659 
    660                 avcHandle->CBAVC_Free(userData, video->currPicParams);
    661             }
    662             if (video->currSeqParams != NULL)
    663             {
    664                 avcHandle->CBAVC_Free(userData, video->currSeqParams);
    665             }
    666             if (encvid->bitstream != NULL)
    667             {
    668                 avcHandle->CBAVC_Free(userData, encvid->bitstream);
    669             }
    670             if (video != NULL)
    671             {
    672                 avcHandle->CBAVC_Free(userData, video);
    673             }
    674         }
    675 
    676         avcHandle->CBAVC_Free(userData, encvid);
    677 
    678         avcHandle->AVCObject = NULL;
    679     }
    680 
    681     return ;
    682 }
    683 
    684 OSCL_EXPORT_REF AVCEnc_Status PVAVCEncUpdateBitRate(AVCHandle *avcHandle, uint32 bitrate)
    685 {
    686     OSCL_UNUSED_ARG(avcHandle);
    687     OSCL_UNUSED_ARG(bitrate);
    688 
    689     return AVCENC_FAIL;
    690 }
    691 
    692 OSCL_EXPORT_REF AVCEnc_Status PVAVCEncUpdateFrameRate(AVCHandle *avcHandle, uint32 num, uint32 denom)
    693 {
    694     OSCL_UNUSED_ARG(avcHandle);
    695     OSCL_UNUSED_ARG(num);
    696     OSCL_UNUSED_ARG(denom);
    697 
    698     return AVCENC_FAIL;
    699 }
    700 
    701 OSCL_EXPORT_REF AVCEnc_Status PVAVCEncUpdateIDRInterval(AVCHandle *avcHandle, int IDRInterval)
    702 {
    703     OSCL_UNUSED_ARG(avcHandle);
    704     OSCL_UNUSED_ARG(IDRInterval);
    705 
    706     return AVCENC_FAIL;
    707 }
    708 
    709 OSCL_EXPORT_REF AVCEnc_Status PVAVCEncIDRRequest(AVCHandle *avcHandle)
    710 {
    711     OSCL_UNUSED_ARG(avcHandle);
    712 
    713     return AVCENC_FAIL;
    714 }
    715 
    716 OSCL_EXPORT_REF AVCEnc_Status PVAVCEncUpdateIMBRefresh(AVCHandle *avcHandle, int numMB)
    717 {
    718     OSCL_UNUSED_ARG(avcHandle);
    719     OSCL_UNUSED_ARG(numMB);
    720 
    721     return AVCENC_FAIL;
    722 }
    723 
    724 void PVAVCEncGetFrameStats(AVCHandle *avcHandle, AVCEncFrameStats *avcStats)
    725 {
    726     AVCEncObject *encvid = (AVCEncObject*) avcHandle->AVCObject;
    727     AVCRateControl *rateCtrl = encvid->rateCtrl;
    728 
    729     avcStats->avgFrameQP = GetAvgFrameQP(rateCtrl);
    730     avcStats->numIntraMBs = encvid->numIntraMB;
    731 
    732     return ;
    733 }
    734 
    735 
    736 
    737