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 /* ======================================================================== */
PVAVCEncGetNALType(unsigned char * bitstream,int size,int * nal_type,int * nal_ref_idc)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 /* ======================================================================== */
PVAVCEncInitialize(AVCHandle * avcHandle,AVCEncParams * encParam,void * extSPS,void * extPPS)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 
PVAVCEncGetMaxOutputBufferSize(AVCHandle * avcHandle,int * size)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 /* ======================================================================== */
PVAVCEncSetInput(AVCHandle * avcHandle,AVCFrameIO * input)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 /* ======================================================================== */
PVAVCEncodeNAL(AVCHandle * avcHandle,unsigned char * buffer,unsigned int * buf_nal_size,int * nal_type)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 /* ======================================================================== */
PVAVCEncGetOverrunBuffer(AVCHandle * avcHandle)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 /* ======================================================================== */
PVAVCEncGetRecon(AVCHandle * avcHandle,AVCFrameIO * recon)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 
PVAVCEncReleaseRecon(AVCHandle * avcHandle,AVCFrameIO * recon)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 /* ======================================================================== */
PVAVCCleanUpEncoder(AVCHandle * avcHandle)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 
PVAVCEncUpdateBitRate(AVCHandle * avcHandle,uint32 bitrate)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 
PVAVCEncUpdateFrameRate(AVCHandle * avcHandle,uint32 num,uint32 denom)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 
PVAVCEncUpdateIDRInterval(AVCHandle * avcHandle,int IDRInterval)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 
PVAVCEncIDRRequest(AVCHandle * avcHandle)709 OSCL_EXPORT_REF AVCEnc_Status PVAVCEncIDRRequest(AVCHandle *avcHandle)
710 {
711     OSCL_UNUSED_ARG(avcHandle);
712 
713     return AVCENC_FAIL;
714 }
715 
PVAVCEncUpdateIMBRefresh(AVCHandle * avcHandle,int numMB)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 
PVAVCEncGetFrameStats(AVCHandle * avcHandle,AVCEncFrameStats * avcStats)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