avcenc_api.cpp revision 23da4cf305b9bfff07954711a8a2d9ec040865af
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/* ======================================================================== */
29OSCL_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/* ======================================================================== */
56OSCL_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
262OSCL_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/* ======================================================================== */
284OSCL_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
328RECALL_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/* ======================================================================== */
376OSCL_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/* ======================================================================== */
529OSCL_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/* ======================================================================== */
558OSCL_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 = (intptr_t) currFS->base_dpb; /* use the pointer as the id */
577
578    currFS->IsOutputted |= 1;
579
580    return AVCENC_SUCCESS;
581}
582
583OSCL_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/* ======================================================================== */
599OSCL_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, encvid->functionPointer);
614        }
615
616        if (encvid->min_cost)
617        {
618            avcHandle->CBAVC_Free(userData, encvid->min_cost);
619        }
620
621        if (encvid->intraSearch)
622        {
623            avcHandle->CBAVC_Free(userData, encvid->intraSearch);
624        }
625
626        if (encvid->mot16x16)
627        {
628            avcHandle->CBAVC_Free(userData, encvid->mot16x16);
629        }
630
631        if (encvid->rateCtrl)
632        {
633            avcHandle->CBAVC_Free(userData, encvid->rateCtrl);
634        }
635
636        if (encvid->overrunBuffer)
637        {
638            avcHandle->CBAVC_Free(userData, encvid->overrunBuffer);
639        }
640
641        video = encvid->common;
642        if (video != NULL)
643        {
644            if (video->MbToSliceGroupMap)
645            {
646                avcHandle->CBAVC_Free(userData, video->MbToSliceGroupMap);
647            }
648            if (video->mblock != NULL)
649            {
650                avcHandle->CBAVC_Free(userData, video->mblock);
651            }
652            if (video->decPicBuf != NULL)
653            {
654                CleanUpDPB(avcHandle, video);
655                avcHandle->CBAVC_Free(userData, video->decPicBuf);
656            }
657            if (video->sliceHdr != NULL)
658            {
659                avcHandle->CBAVC_Free(userData, video->sliceHdr);
660            }
661            if (video->currPicParams != NULL)
662            {
663                if (video->currPicParams->slice_group_id)
664                {
665                    avcHandle->CBAVC_Free(userData, video->currPicParams->slice_group_id);
666                }
667
668                avcHandle->CBAVC_Free(userData, video->currPicParams);
669            }
670            if (video->currSeqParams != NULL)
671            {
672                avcHandle->CBAVC_Free(userData, video->currSeqParams);
673            }
674            if (encvid->bitstream != NULL)
675            {
676                avcHandle->CBAVC_Free(userData, encvid->bitstream);
677            }
678            if (video != NULL)
679            {
680                avcHandle->CBAVC_Free(userData, video);
681            }
682        }
683
684        avcHandle->CBAVC_Free(userData, encvid);
685
686        avcHandle->AVCObject = NULL;
687    }
688
689    return ;
690}
691
692OSCL_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
700OSCL_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
709OSCL_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
717OSCL_EXPORT_REF AVCEnc_Status PVAVCEncIDRRequest(AVCHandle *avcHandle)
718{
719    OSCL_UNUSED_ARG(avcHandle);
720
721    return AVCENC_FAIL;
722}
723
724OSCL_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
732void 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