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