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 
19 #include "mp4enc_lib.h"
20 #include "bitstream_io.h"
21 #include "rate_control.h"
22 #include "m4venc_oscl.h"
23 
24 #ifndef INT32_MAX
25 #define INT32_MAX 0x7fffffff
26 #endif
27 
28 #ifndef SIZE_MAX
29 #define SIZE_MAX ((size_t) -1)
30 #endif
31 
32 /* Inverse normal zigzag */
33 const static Int zigzag_i[NCOEFF_BLOCK] =
34 {
35     0, 1, 8, 16, 9, 2, 3, 10,
36     17, 24, 32, 25, 18, 11, 4, 5,
37     12, 19, 26, 33, 40, 48, 41, 34,
38     27, 20, 13, 6, 7, 14, 21, 28,
39     35, 42, 49, 56, 57, 50, 43, 36,
40     29, 22, 15, 23, 30, 37, 44, 51,
41     58, 59, 52, 45, 38, 31, 39, 46,
42     53, 60, 61, 54, 47, 55, 62, 63
43 };
44 
45 /* INTRA */
46 const static Int mpeg_iqmat_def[NCOEFF_BLOCK] =
47     {  8, 17, 18, 19, 21, 23, 25, 27,
48        17, 18, 19, 21, 23, 25, 27, 28,
49        20, 21, 22, 23, 24, 26, 28, 30,
50        21, 22, 23, 24, 26, 28, 30, 32,
51        22, 23, 24, 26, 28, 30, 32, 35,
52        23, 24, 26, 28, 30, 32, 35, 38,
53        25, 26, 28, 30, 32, 35, 38, 41,
54        27, 28, 30, 32, 35, 38, 41, 45
55     };
56 
57 /* INTER */
58 const static Int mpeg_nqmat_def[64]  =
59     { 16, 17, 18, 19, 20, 21, 22, 23,
60       17, 18, 19, 20, 21, 22, 23, 24,
61       18, 19, 20, 21, 22, 23, 24, 25,
62       19, 20, 21, 22, 23, 24, 26, 27,
63       20, 21, 22, 23, 25, 26, 27, 28,
64       21, 22, 23, 24, 26, 27, 28, 30,
65       22, 23, 24, 26, 27, 28, 30, 31,
66       23, 24, 25, 27, 28, 30, 31, 33
67     };
68 
69 /* Profiles and levels */
70 /* Simple profile(level 0-3) and Core profile (level 1-2) */
71 /* {SPL0, SPL1, SPL2, SPL3, CPL1, CPL2, CPL2, CPL2} , SPL0: Simple Profile@Level0, CPL1: Core Profile@Level1, the last two are redundant for easy table manipulation */
72 const static Int profile_level_code[8] =
73 {
74     0x08, 0x01, 0x02, 0x03, 0x21, 0x22, 0x22, 0x22
75 };
76 
77 const static Int profile_level_max_bitrate[8] =
78 {
79     64000, 64000, 128000, 384000, 384000, 2000000, 2000000, 2000000
80 };
81 
82 const static Int profile_level_max_packet_size[8] =
83 {
84     2048, 2048, 4096, 8192, 4096, 8192, 8192, 8192
85 };
86 
87 const static Int profile_level_max_mbsPerSec[8] =
88 {
89     1485, 1485, 5940, 11880, 5940, 23760, 23760, 23760
90 };
91 
92 const static Int profile_level_max_VBV_size[8] =
93 {
94     163840, 163840, 655360, 655360, 262144, 1310720, 1310720, 1310720
95 };
96 
97 
98 /* Simple scalable profile (level 0-2) and Core scalable profile (level 1-3) */
99 /* {SSPL0, SSPL1, SSPL2, SSPL2, CSPL1, CSPL2, CSPL3, CSPL3} , SSPL0: Simple Scalable Profile@Level0, CSPL1: Core Scalable Profile@Level1, the fourth is redundant for easy table manipulation */
100 
101 const static Int scalable_profile_level_code[8] =
102 {
103     0x10, 0x11, 0x12, 0x12, 0xA1, 0xA2, 0xA3, 0xA3
104 };
105 
106 const static Int scalable_profile_level_max_bitrate[8] =
107 {
108     128000, 128000, 256000, 256000, 768000, 1500000, 4000000, 4000000
109 };
110 
111 /* in bits */
112 const static Int scalable_profile_level_max_packet_size[8] =
113 {
114     2048, 2048, 4096, 4096, 4096, 4096, 16384, 16384
115 };
116 
117 const static Int scalable_profile_level_max_mbsPerSec[8] =
118 {
119     1485, 7425, 23760, 23760, 14850, 29700, 120960, 120960
120 };
121 
122 const static Int scalable_profile_level_max_VBV_size[8] =
123 {
124     163840, 655360, 655360, 655360, 1048576, 1310720, 1310720, 1310720
125 };
126 
127 
128 /* H263 profile 0 @ level 10-70 */
129 const static Int   h263Level[8] = {0, 10, 20, 30, 40, 50, 60, 70};
130 const static float rBR_bound[8] = {0, 1, 2, 6, 32, 64, 128, 256};
131 const static float max_h263_framerate[2] = {(float)30000 / (float)2002,
132         (float)30000 / (float)1001
133                                            };
134 const static Int   max_h263_width[2]  = {176, 352};
135 const static Int   max_h263_height[2] = {144, 288};
136 
137 /* 6/2/2001, newly added functions to make PVEncodeVop more readable. */
138 Int DetermineCodingLayer(VideoEncData *video, Int *nLayer, ULong modTime);
139 void DetermineVopType(VideoEncData *video, Int currLayer);
140 Int UpdateSkipNextFrame(VideoEncData *video, ULong *modTime, Int *size, PV_STATUS status);
141 Bool SetProfile_BufferSize(VideoEncData *video, float delay, Int bInitialized);
142 
143 #ifdef PRINT_RC_INFO
144 extern FILE *facct;
145 extern int tiTotalNumBitsGenerated;
146 extern int iStuffBits;
147 #endif
148 
149 #ifdef PRINT_EC
150 extern FILE *fec;
151 #endif
152 
153 
154 /* ======================================================================== */
155 /*  Function : PVGetDefaultEncOption()                                      */
156 /*  Date     : 12/12/2005                                                   */
157 /*  Purpose  :                                                              */
158 /*  In/out   :                                                              */
159 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
160 /*  Modified :                                                              */
161 /*                                                                          */
162 /* ======================================================================== */
163 
PVGetDefaultEncOption(VideoEncOptions * encOption,Int encUseCase)164 OSCL_EXPORT_REF Bool PVGetDefaultEncOption(VideoEncOptions *encOption, Int encUseCase)
165 {
166     VideoEncOptions defaultUseCase = {H263_MODE, profile_level_max_packet_size[SIMPLE_PROFILE_LEVEL0] >> 3,
167                                       SIMPLE_PROFILE_LEVEL0, PV_OFF, 0, 1, 1000, 33, {144, 144}, {176, 176}, {15, 30}, {64000, 128000},
168                                       {10, 10}, {12, 12}, {0, 0}, CBR_1, 0.0, PV_OFF, -1, 0, PV_OFF, 16, PV_OFF, 0, PV_ON
169                                      };
170 
171     OSCL_UNUSED_ARG(encUseCase); // unused for now. Later we can add more defaults setting and use this
172     // argument to select the right one.
173     /* in the future we can create more meaningful use-cases */
174     if (encOption == NULL)
175     {
176         return PV_FALSE;
177     }
178 
179     M4VENC_MEMCPY(encOption, &defaultUseCase, sizeof(VideoEncOptions));
180 
181     return PV_TRUE;
182 }
183 
184 /* ======================================================================== */
185 /*  Function : PVInitVideoEncoder()                                         */
186 /*  Date     : 08/22/2000                                                   */
187 /*  Purpose  : Initialization of MP4 Encoder and VO bitstream               */
188 /*  In/out   :                                                              */
189 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
190 /*  Modified :  5/21/01, allocate only yChan and assign uChan & vChan   */
191 /*              12/12/05, add encoding option as input argument         */
192 /* ======================================================================== */
PVInitVideoEncoder(VideoEncControls * encoderControl,VideoEncOptions * encOption)193 OSCL_EXPORT_REF Bool    PVInitVideoEncoder(VideoEncControls *encoderControl, VideoEncOptions *encOption)
194 {
195 
196     Bool        status = PV_TRUE;
197     Int         nLayers, idx, i, j;
198     Int         max = 0, max_width = 0, max_height = 0, pitch, offset;
199     Int         size = 0, nTotalMB = 0;
200     VideoEncData *video;
201     Vol         *pVol;
202     VideoEncParams  *pEncParams;
203     Int         temp_w, temp_h, mbsPerSec;
204 
205     /******************************************/
206     /*      this part use to be PVSetEncode() */
207     Int profile_table_index, *profile_level_table;
208     Int profile_level = encOption->profile_level;
209     Int PacketSize = encOption->packetSize << 3;
210     Int timeInc, timeIncRes;
211     float profile_max_framerate;
212     VideoEncParams *encParams;
213 
214     if (encoderControl->videoEncoderData) /* this has been called */
215     {
216         if (encoderControl->videoEncoderInit) /* check if PVInitVideoEncoder() has been called  */
217         {
218             PVCleanUpVideoEncoder(encoderControl);
219             encoderControl->videoEncoderInit = 0;
220         }
221 
222         M4VENC_FREE(encoderControl->videoEncoderData);
223         encoderControl->videoEncoderData = NULL;
224     }
225     encoderControl->videoEncoderInit = 0;   /* reset this value */
226 
227     video = (VideoEncData *)M4VENC_MALLOC(sizeof(VideoEncData)); /* allocate memory for encData */
228 
229     if (video == NULL)
230         return PV_FALSE;
231 
232     M4VENC_MEMSET(video, 0, sizeof(VideoEncData));
233 
234     encoderControl->videoEncoderData = (void *) video;         /* set up pointer in VideoEncData structure */
235 
236     video->encParams = (VideoEncParams *)M4VENC_MALLOC(sizeof(VideoEncParams));
237     if (video->encParams == NULL)
238         goto CLEAN_UP;
239 
240     M4VENC_MEMSET(video->encParams, 0, sizeof(VideoEncParams));
241 
242     encParams = video->encParams;
243     encParams->nLayers = encOption->numLayers;
244 
245     /* Check whether the input packetsize is valid (Note: put code here (before any memory allocation) in order to avoid memory leak */
246     if ((Int)profile_level < (Int)(SIMPLE_SCALABLE_PROFILE_LEVEL0))  /* non-scalable profile */
247     {
248         profile_level_table = (Int *)profile_level_max_packet_size;
249         profile_table_index = (Int)profile_level;
250         if (encParams->nLayers != 1)
251         {
252             goto CLEAN_UP;
253         }
254 
255         encParams->LayerMaxMbsPerSec[0] = profile_level_max_mbsPerSec[profile_table_index];
256 
257     }
258     else   /* scalable profile */
259     {
260         profile_level_table = (Int *)scalable_profile_level_max_packet_size;
261         profile_table_index = (Int)profile_level - (Int)(SIMPLE_SCALABLE_PROFILE_LEVEL0);
262         if (encParams->nLayers < 2)
263         {
264             goto CLEAN_UP;
265         }
266         for (i = 0; i < encParams->nLayers; i++)
267         {
268             encParams->LayerMaxMbsPerSec[i] = scalable_profile_level_max_mbsPerSec[profile_table_index];
269         }
270 
271     }
272 
273     /* cannot have zero size packet with these modes */
274     if (PacketSize == 0)
275     {
276         if (encOption->encMode == DATA_PARTITIONING_MODE)
277         {
278             goto CLEAN_UP;
279         }
280         if (encOption->encMode == COMBINE_MODE_WITH_ERR_RES)
281         {
282             encOption->encMode = COMBINE_MODE_NO_ERR_RES;
283         }
284     }
285 
286     if (encOption->gobHeaderInterval == 0)
287     {
288         if (encOption->encMode == H263_MODE_WITH_ERR_RES)
289         {
290             encOption->encMode = H263_MODE;
291         }
292 
293         if (encOption->encMode == SHORT_HEADER_WITH_ERR_RES)
294         {
295             encOption->encMode = SHORT_HEADER;
296         }
297     }
298 
299     if (PacketSize > profile_level_table[profile_table_index])
300         goto CLEAN_UP;
301 
302     /* Initial Defaults for all Modes */
303 
304     encParams->SequenceStartCode = 1;
305     encParams->GOV_Enabled = 0;
306     encParams->RoundingType = 0;
307     encParams->IntraDCVlcThr = PV_MAX(PV_MIN(encOption->intraDCVlcTh, 7), 0);
308     encParams->ACDCPrediction = ((encOption->useACPred == PV_ON) ? TRUE : FALSE);
309     encParams->RC_Type = encOption->rcType;
310     encParams->Refresh = encOption->numIntraMB;
311     encParams->ResyncMarkerDisable = 0; /* Enable Resync Marker */
312 
313     for (i = 0; i < encOption->numLayers; i++)
314     {
315 #ifdef NO_MPEG_QUANT
316         encParams->QuantType[i] = 0;
317 #else
318         encParams->QuantType[i] = encOption->quantType[i];      /* H263 */
319 #endif
320         if (encOption->pQuant[i] >= 1 && encOption->pQuant[i] <= 31)
321         {
322             encParams->InitQuantPvop[i] = encOption->pQuant[i];
323         }
324         else
325         {
326             goto CLEAN_UP;
327         }
328         if (encOption->iQuant[i] >= 1 && encOption->iQuant[i] <= 31)
329         {
330             encParams->InitQuantIvop[i] = encOption->iQuant[i];
331         }
332         else
333         {
334             goto CLEAN_UP;
335         }
336     }
337 
338     encParams->HalfPel_Enabled = 1;
339     encParams->SearchRange = encOption->searchRange; /* 4/16/2001 */
340     encParams->FullSearch_Enabled = 0;
341 #ifdef NO_INTER4V
342     encParams->MV8x8_Enabled = 0;
343 #else
344     encParams->MV8x8_Enabled = 0;// comment out for now!! encOption->mv8x8Enable;
345 #endif
346     encParams->H263_Enabled = 0;
347     encParams->GOB_Header_Interval = 0; // need to be reset to 0
348     encParams->IntraPeriod = encOption->intraPeriod;    /* Intra update period update default*/
349     encParams->SceneChange_Det = encOption->sceneDetect;
350     encParams->FineFrameSkip_Enabled = 0;
351     encParams->NoFrameSkip_Enabled = encOption->noFrameSkipped;
352     encParams->NoPreSkip_Enabled = encOption->noFrameSkipped;
353     encParams->GetVolHeader[0] = 0;
354     encParams->GetVolHeader[1] = 0;
355     encParams->ResyncPacketsize = encOption->packetSize << 3;
356     encParams->LayerMaxBitRate[0] = 0;
357     encParams->LayerMaxBitRate[1] = 0;
358     encParams->LayerMaxFrameRate[0] = (float)0.0;
359     encParams->LayerMaxFrameRate[1] = (float)0.0;
360     encParams->VBV_delay = encOption->vbvDelay;  /* 2sec VBV buffer size */
361 
362     switch (encOption->encMode)
363     {
364 
365         case SHORT_HEADER:
366         case SHORT_HEADER_WITH_ERR_RES:
367 
368             /* From Table 6-26 */
369             encParams->nLayers = 1;
370             encParams->QuantType[0] = 0;    /*H263 */
371             encParams->ResyncMarkerDisable = 1; /* Disable Resync Marker */
372             encParams->DataPartitioning = 0; /* Combined Mode */
373             encParams->ReversibleVLC = 0;   /* Disable RVLC */
374             encParams->RoundingType = 0;
375             encParams->IntraDCVlcThr = 7;   /* use_intra_dc_vlc = 0 */
376             encParams->MV8x8_Enabled = 0;
377 
378             encParams->GOB_Header_Interval = encOption->gobHeaderInterval;
379             encParams->H263_Enabled = 2;
380             encParams->GOV_Enabled = 0;
381             encParams->TimeIncrementRes = 30000;        /* timeIncrementRes for H263 */
382             break;
383 
384         case H263_MODE:
385         case H263_MODE_WITH_ERR_RES:
386 
387             /* From Table 6-26 */
388             encParams->nLayers = 1;
389             encParams->QuantType[0] = 0;    /*H263 */
390             encParams->ResyncMarkerDisable = 1; /* Disable Resync Marker */
391             encParams->DataPartitioning = 0; /* Combined Mode */
392             encParams->ReversibleVLC = 0;   /* Disable RVLC */
393             encParams->RoundingType = 0;
394             encParams->IntraDCVlcThr = 7;   /* use_intra_dc_vlc = 0 */
395             encParams->MV8x8_Enabled = 0;
396 
397             encParams->H263_Enabled = 1;
398             encParams->GOV_Enabled = 0;
399             encParams->TimeIncrementRes = 30000;        /* timeIncrementRes for H263 */
400 
401             break;
402 #ifndef H263_ONLY
403         case DATA_PARTITIONING_MODE:
404 
405             encParams->DataPartitioning = 1;        /* Base Layer Data Partitioning */
406             encParams->ResyncMarkerDisable = 0; /* Resync Marker */
407 #ifdef NO_RVLC
408             encParams->ReversibleVLC = 0;
409 #else
410             encParams->ReversibleVLC = (encOption->rvlcEnable == PV_ON); /* RVLC when Data Partitioning */
411 #endif
412             encParams->ResyncPacketsize = PacketSize;
413             break;
414 
415         case COMBINE_MODE_WITH_ERR_RES:
416 
417             encParams->DataPartitioning = 0;        /* Combined Mode */
418             encParams->ResyncMarkerDisable = 0; /* Resync Marker */
419             encParams->ReversibleVLC = 0;           /* No RVLC */
420             encParams->ResyncPacketsize = PacketSize;
421             break;
422 
423         case COMBINE_MODE_NO_ERR_RES:
424 
425             encParams->DataPartitioning = 0;        /* Combined Mode */
426             encParams->ResyncMarkerDisable = 1; /* Disable Resync Marker */
427             encParams->ReversibleVLC = 0;           /* No RVLC */
428             break;
429 #endif
430         default:
431             goto CLEAN_UP;
432     }
433     /* Set the constraints (maximum values) according to the input profile and level */
434     /* Note that profile_table_index is already figured out above */
435 
436     /* base layer */
437     encParams->profile_table_index    = profile_table_index; /* Used to limit the profile and level in SetProfile_BufferSize() */
438 
439     /* check timeIncRes */
440     timeIncRes = encOption->timeIncRes;
441     timeInc = encOption->tickPerSrc;
442 
443     if ((timeIncRes >= 1) && (timeIncRes <= 65536) && (timeInc < timeIncRes) && (timeInc != 0))
444     {
445         if (!encParams->H263_Enabled)
446         {
447             encParams->TimeIncrementRes = timeIncRes;
448         }
449         else
450         {
451             encParams->TimeIncrementRes = 30000;
452 //          video->FrameRate = 30000/(float)1001; /* fix it to 29.97 fps */
453         }
454         video->FrameRate = timeIncRes / ((float)timeInc);
455     }
456     else
457     {
458         goto CLEAN_UP;
459     }
460 
461     /* check frame dimension */
462     if (encParams->H263_Enabled)
463     {
464         switch (encOption->encWidth[0])
465         {
466             case 128:
467                 if (encOption->encHeight[0] != 96) /* source_format = 1 */
468                     goto CLEAN_UP;
469                 break;
470             case 176:
471                 if (encOption->encHeight[0] != 144) /* source_format = 2 */
472                     goto CLEAN_UP;
473                 break;
474             case 352:
475                 if (encOption->encHeight[0] != 288) /* source_format = 2 */
476                     goto CLEAN_UP;
477                 break;
478 
479             case 704:
480                 if (encOption->encHeight[0] != 576) /* source_format = 2 */
481                     goto CLEAN_UP;
482                 break;
483             case 1408:
484                 if (encOption->encHeight[0] != 1152) /* source_format = 2 */
485                     goto CLEAN_UP;
486                 break;
487 
488             default:
489                 goto CLEAN_UP;
490         }
491     }
492     for (i = 0; i < encParams->nLayers; i++)
493     {
494         if (encOption->encHeight[i] == 0 || encOption->encWidth[i] == 0 ||
495                 encOption->encHeight[i] % 16 != 0 || encOption->encWidth[i] % 16 != 0)
496             goto CLEAN_UP;
497         encParams->LayerHeight[i] = encOption->encHeight[i];
498         encParams->LayerWidth[i] = encOption->encWidth[i];
499     }
500 
501     /* check frame rate */
502     for (i = 0; i < encParams->nLayers; i++)
503     {
504         encParams->LayerFrameRate[i] = encOption->encFrameRate[i];
505     }
506 
507     if (encParams->nLayers > 1)
508     {
509         if (encOption->encFrameRate[0] == encOption->encFrameRate[1] ||
510                 encOption->encFrameRate[0] == 0. || encOption->encFrameRate[1] == 0.) /* 7/31/03 */
511             goto CLEAN_UP;
512     }
513     /* set max frame rate */
514     for (i = 0; i < encParams->nLayers; i++)
515     {
516 
517         /* Make sure the maximum framerate is consistent with the given profile and level */
518         nTotalMB = ((encParams->LayerWidth[i] + 15) / 16) * ((encParams->LayerHeight[i] + 15) / 16);
519 
520         if (nTotalMB > 0)
521             profile_max_framerate = (float)encParams->LayerMaxMbsPerSec[i] / (float)nTotalMB;
522 
523         else
524             profile_max_framerate = (float)30.0;
525 
526         encParams->LayerMaxFrameRate[i] = PV_MIN(profile_max_framerate, encParams->LayerFrameRate[i]);
527     }
528 
529     /* check bit rate */
530     for (i = 0; i < encParams->nLayers; i++)
531     {
532         encParams->LayerBitRate[i] = encOption->bitRate[i];
533     }
534     if (encParams->nLayers > 1)
535     {
536         if (encOption->bitRate[0] == encOption->bitRate[1] ||
537                 encOption->bitRate[0] == 0 || encOption->bitRate[1] == 0) /* 7/31/03 */
538             goto CLEAN_UP;
539     }
540     /* check rate control and vbv delay*/
541     encParams->RC_Type = encOption->rcType;
542 
543     if (encOption->vbvDelay == 0.0) /* set to default */
544     {
545         switch (encOption->rcType)
546         {
547             case CBR_1:
548             case CBR_2:
549                 encParams->VBV_delay = (float)2.0; /* default 2sec VBV buffer size */
550                 break;
551 
552             case CBR_LOWDELAY:
553                 encParams->VBV_delay = (float)0.5; /* default 0.5sec VBV buffer size */
554                 break;
555 
556             case VBR_1:
557             case VBR_2:
558                 encParams->VBV_delay = (float)10.0; /* default 10sec VBV buffer size */
559                 break;
560             default:
561                 break;
562         }
563     }
564     else /* force this value */
565     {
566         encParams->VBV_delay = encOption->vbvDelay;
567     }
568 
569     /* check search range */
570     if (encParams->H263_Enabled && encOption->searchRange > 16)
571     {
572         encParams->SearchRange = 16; /* 4/16/2001 */
573     }
574 
575     /*****************************************/
576     /* checking for conflict between options */
577     /*****************************************/
578 
579     if (video->encParams->RC_Type == CBR_1 || video->encParams->RC_Type == CBR_2 || video->encParams->RC_Type == CBR_LOWDELAY)  /* if CBR */
580     {
581 #ifdef _PRINT_STAT
582         if (video->encParams->NoFrameSkip_Enabled == PV_ON ||
583                 video->encParams->NoPreSkip_Enabled == PV_ON) /* don't allow frame skip*/
584             printf("WARNING!!!! CBR with NoFrameSkip\n");
585 #endif
586     }
587     else if (video->encParams->RC_Type == CONSTANT_Q)   /* constant_Q */
588     {
589         video->encParams->NoFrameSkip_Enabled = PV_ON;  /* no frame skip */
590         video->encParams->NoPreSkip_Enabled = PV_ON;    /* no frame skip */
591 #ifdef _PRINT_STAT
592         printf("Turn on NoFrameSkip\n");
593 #endif
594     }
595 
596     if (video->encParams->NoFrameSkip_Enabled == PV_ON) /* if no frame skip */
597     {
598         video->encParams->FineFrameSkip_Enabled = PV_OFF;
599 #ifdef _PRINT_STAT
600         printf("NoFrameSkip !!! may violate VBV_BUFFER constraint.\n");
601         printf("Turn off FineFrameSkip\n");
602 #endif
603     }
604 
605     /******************************************/
606     /******************************************/
607 
608     nLayers = video->encParams->nLayers; /* Number of Layers to be encoded */
609 
610     /* Find the maximum width*height for memory allocation of the VOPs */
611     for (idx = 0; idx < nLayers; idx++)
612     {
613         temp_w = ((video->encParams->LayerWidth[idx] + 15) >> 4) << 4;
614         temp_h = ((video->encParams->LayerHeight[idx] + 15) >> 4) << 4;
615 
616         if (temp_w > 2048 || temp_h > 2048) {
617             goto CLEAN_UP;
618         }
619 
620         if ((temp_w*temp_h) > max)
621         {
622             max = temp_w * temp_h;
623             max_width = temp_w;
624             max_height = temp_h;
625 
626             nTotalMB = ((max_width * max_height) >> 8);
627         }
628 
629         /* Check if the video size and framerate(MBsPerSec) are vald */
630         mbsPerSec = (Int)(nTotalMB * video->encParams->LayerFrameRate[idx]);
631         if (mbsPerSec > video->encParams->LayerMaxMbsPerSec[idx]) status = PV_FALSE;
632     }
633 
634     /****************************************************/
635     /* Set Profile and Video Buffer Size for each layer */
636     /****************************************************/
637     if (video->encParams->RC_Type == CBR_LOWDELAY) video->encParams->VBV_delay = 0.5; /* For CBR_LOWDELAY, we set 0.5sec buffer */
638     status = SetProfile_BufferSize(video, video->encParams->VBV_delay, 1);
639     if (status != PV_TRUE)
640         goto CLEAN_UP;
641 
642     /****************************************/
643     /* memory allocation and initialization */
644     /****************************************/
645 
646     if (video == NULL) goto CLEAN_UP;
647 
648     /* cyclic reference for passing through both structures */
649     video->videoEncControls = encoderControl;
650 
651     //video->currLayer = 0; /* Set current Layer to 0 */
652     //video->currFrameNo = 0; /* Set current frame Number to 0 */
653     video->nextModTime = 0;
654     video->nextEncIVop = 0; /* Sets up very first frame to be I-VOP! */
655     video->numVopsInGOP = 0; /* counter for Vops in Gop, 2/8/01 */
656 
657     //video->frameRate = video->encParams->LayerFrameRate[0]; /* Set current layer frame rate */
658 
659     video->QPMB = (UChar *) M4VENC_MALLOC(nTotalMB * sizeof(UChar)); /* Memory for MB quantizers */
660     if (video->QPMB == NULL) goto CLEAN_UP;
661 
662 
663     video->headerInfo.Mode = (UChar *) M4VENC_MALLOC(sizeof(UChar) * nTotalMB); /* Memory for MB Modes */
664     if (video->headerInfo.Mode == NULL) goto CLEAN_UP;
665     video->headerInfo.CBP = (UChar *) M4VENC_MALLOC(sizeof(UChar) * nTotalMB);   /* Memory for CBP (Y and C) of each MB */
666     if (video->headerInfo.CBP == NULL) goto CLEAN_UP;
667 
668     /* Allocating motion vector space and interpolation memory*/
669 
670     if ((size_t)nTotalMB > SIZE_MAX / sizeof(MOT *)) {
671         goto CLEAN_UP;
672     }
673     video->mot = (MOT **)M4VENC_MALLOC(sizeof(MOT *) * nTotalMB);
674     if (video->mot == NULL) goto CLEAN_UP;
675 
676     for (idx = 0; idx < nTotalMB; idx++)
677     {
678         video->mot[idx] = (MOT *)M4VENC_MALLOC(sizeof(MOT) * 8);
679         if (video->mot[idx] == NULL)
680         {
681             goto CLEAN_UP;
682         }
683     }
684 
685     video->intraArray = (UChar *)M4VENC_MALLOC(sizeof(UChar) * nTotalMB);
686     if (video->intraArray == NULL) goto CLEAN_UP;
687 
688     video->sliceNo = (UChar *) M4VENC_MALLOC(nTotalMB); /* Memory for Slice Numbers */
689     if (video->sliceNo == NULL) goto CLEAN_UP;
690     /* Allocating space for predDCAC[][8][16], Not that I intentionally  */
691     /*    increase the dimension of predDCAC from [][6][15] to [][8][16] */
692     /*    so that compilers can generate faster code to indexing the     */
693     /*    data inside (by using << instead of *).         04/14/2000. */
694     /* 5/29/01, use  decoder lib ACDC prediction memory scheme.  */
695     if ((size_t)nTotalMB > SIZE_MAX / sizeof(typeDCStore)) {
696         goto CLEAN_UP;
697     }
698     video->predDC = (typeDCStore *) M4VENC_MALLOC(nTotalMB * sizeof(typeDCStore));
699     if (video->predDC == NULL) goto CLEAN_UP;
700 
701     if (!video->encParams->H263_Enabled)
702     {
703         if ((size_t)((max_width >> 4) + 1) > SIZE_MAX / sizeof(typeDCACStore)) {
704             goto CLEAN_UP;
705         }
706         video->predDCAC_col = (typeDCACStore *) M4VENC_MALLOC(((max_width >> 4) + 1) * sizeof(typeDCACStore));
707         if (video->predDCAC_col == NULL) goto CLEAN_UP;
708 
709         /* element zero will be used for storing vertical (col) AC coefficients */
710         /*  the rest will be used for storing horizontal (row) AC coefficients  */
711         video->predDCAC_row = video->predDCAC_col + 1;        /*  ACDC */
712 
713         if ((size_t)nTotalMB > SIZE_MAX / sizeof(Int)) {
714             goto CLEAN_UP;
715         }
716         video->acPredFlag = (Int *) M4VENC_MALLOC(nTotalMB * sizeof(Int)); /* Memory for acPredFlag */
717         if (video->acPredFlag == NULL) goto CLEAN_UP;
718     }
719 
720     video->outputMB = (MacroBlock *) M4VENC_MALLOC(sizeof(MacroBlock)); /* Allocating macroblock space */
721     if (video->outputMB == NULL) goto CLEAN_UP;
722     M4VENC_MEMSET(video->outputMB->block[0], 0, (sizeof(Short) << 6)*6);
723 
724     M4VENC_MEMSET(video->dataBlock, 0, sizeof(Short) << 7);
725     /* Allocate (2*packetsize) working bitstreams */
726 
727     video->bitstream1 = BitStreamCreateEnc(2 * 4096); /*allocate working stream 1*/
728     if (video->bitstream1 == NULL) goto CLEAN_UP;
729     video->bitstream2 = BitStreamCreateEnc(2 * 4096); /*allocate working stream 2*/
730     if (video->bitstream2 == NULL) goto CLEAN_UP;
731     video->bitstream3 = BitStreamCreateEnc(2 * 4096); /*allocate working stream 3*/
732     if (video->bitstream3 == NULL) goto CLEAN_UP;
733 
734     /* allocate overrun buffer */
735     // this buffer is used when user's buffer is too small to hold one frame.
736     // It is not needed for slice-based encoding.
737     if (nLayers == 1)
738     {
739         video->oBSize = encParams->BufferSize[0] >> 3;
740     }
741     else
742     {
743         video->oBSize = PV_MAX((encParams->BufferSize[0] >> 3), (encParams->BufferSize[1] >> 3));
744     }
745 
746     if (video->oBSize > DEFAULT_OVERRUN_BUFFER_SIZE || encParams->RC_Type == CONSTANT_Q) // set limit
747     {
748         video->oBSize = DEFAULT_OVERRUN_BUFFER_SIZE;
749     }
750     video->overrunBuffer = (UChar*) M4VENC_MALLOC(sizeof(UChar) * video->oBSize);
751     if (video->overrunBuffer == NULL) goto CLEAN_UP;
752 
753 
754     video->currVop = (Vop *) M4VENC_MALLOC(sizeof(Vop)); /* Memory for Current VOP */
755     if (video->currVop == NULL) goto CLEAN_UP;
756 
757     /* add padding, 09/19/05 */
758     if (video->encParams->H263_Enabled) /* make it conditional  11/28/05 */
759     {
760         pitch = max_width;
761         offset = 0;
762     }
763     else
764     {
765         pitch = max_width + 32;
766         offset = (pitch << 4) + 16;
767         max_height += 32;
768     }
769     if (((uint64_t)pitch * max_height) > (uint64_t)INT32_MAX) {
770         goto CLEAN_UP;
771     }
772     size = pitch * max_height;
773 
774     if (size > INT32_MAX - (size >> 1)
775             || (size_t)(size + (size >> 1)) > SIZE_MAX / sizeof(PIXEL)) {
776         goto CLEAN_UP;
777     }
778     video->currVop->allChan = video->currVop->yChan = (PIXEL *)M4VENC_MALLOC(sizeof(PIXEL) * (size + (size >> 1))); /* Memory for currVop Y */
779     if (video->currVop->yChan == NULL) goto CLEAN_UP;
780     video->currVop->uChan = video->currVop->yChan + size;/* Memory for currVop U */
781     video->currVop->vChan = video->currVop->uChan + (size >> 2);/* Memory for currVop V */
782 
783     /* shift for the offset */
784     if (offset)
785     {
786         video->currVop->yChan += offset; /* offset to the origin.*/
787         video->currVop->uChan += (offset >> 2) + 4;
788         video->currVop->vChan += (offset >> 2) + 4;
789     }
790 
791     video->forwardRefVop = video->currVop;      /*  Initialize forwardRefVop */
792     video->backwardRefVop = video->currVop;     /*  Initialize backwardRefVop */
793 
794     video->prevBaseVop = (Vop *) M4VENC_MALLOC(sizeof(Vop));         /* Memory for Previous Base Vop */
795     if (video->prevBaseVop == NULL) goto CLEAN_UP;
796     video->prevBaseVop->allChan = video->prevBaseVop->yChan = (PIXEL *) M4VENC_MALLOC(sizeof(PIXEL) * (size + (size >> 1))); /* Memory for prevBaseVop Y */
797     if (video->prevBaseVop->yChan == NULL) goto CLEAN_UP;
798     video->prevBaseVop->uChan = video->prevBaseVop->yChan + size; /* Memory for prevBaseVop U */
799     video->prevBaseVop->vChan = video->prevBaseVop->uChan + (size >> 2); /* Memory for prevBaseVop V */
800 
801     if (offset)
802     {
803         video->prevBaseVop->yChan += offset; /* offset to the origin.*/
804         video->prevBaseVop->uChan += (offset >> 2) + 4;
805         video->prevBaseVop->vChan += (offset >> 2) + 4;
806     }
807 
808 
809     if (0) /* If B Frames */
810     {
811         video->nextBaseVop = (Vop *) M4VENC_MALLOC(sizeof(Vop));         /* Memory for Next Base Vop */
812         if (video->nextBaseVop == NULL) goto CLEAN_UP;
813         video->nextBaseVop->allChan = video->nextBaseVop->yChan = (PIXEL *) M4VENC_MALLOC(sizeof(PIXEL) * (size + (size >> 1))); /* Memory for nextBaseVop Y */
814         if (video->nextBaseVop->yChan == NULL) goto CLEAN_UP;
815         video->nextBaseVop->uChan = video->nextBaseVop->yChan + size; /* Memory for nextBaseVop U */
816         video->nextBaseVop->vChan = video->nextBaseVop->uChan + (size >> 2); /* Memory for nextBaseVop V */
817 
818         if (offset)
819         {
820             video->nextBaseVop->yChan += offset; /* offset to the origin.*/
821             video->nextBaseVop->uChan += (offset >> 2) + 4;
822             video->nextBaseVop->vChan += (offset >> 2) + 4;
823         }
824     }
825 
826     if (nLayers > 1)   /* If enhancement layers */
827     {
828         video->prevEnhanceVop = (Vop *) M4VENC_MALLOC(sizeof(Vop));      /* Memory for Previous Enhancement Vop */
829         if (video->prevEnhanceVop == NULL) goto CLEAN_UP;
830         video->prevEnhanceVop->allChan = video->prevEnhanceVop->yChan = (PIXEL *) M4VENC_MALLOC(sizeof(PIXEL) * (size + (size >> 1))); /* Memory for Previous Ehancement Y */
831         if (video->prevEnhanceVop->yChan == NULL) goto CLEAN_UP;
832         video->prevEnhanceVop->uChan = video->prevEnhanceVop->yChan + size; /* Memory for Previous Enhancement U */
833         video->prevEnhanceVop->vChan = video->prevEnhanceVop->uChan + (size >> 2); /* Memory for Previous Enhancement V */
834 
835         if (offset)
836         {
837             video->prevEnhanceVop->yChan += offset; /* offset to the origin.*/
838             video->prevEnhanceVop->uChan += (offset >> 2) + 4;
839             video->prevEnhanceVop->vChan += (offset >> 2) + 4;
840         }
841     }
842 
843     video->numberOfLayers = nLayers; /* Number of Layers */
844     video->sumMAD = 0;
845 
846 
847     /* 04/09/01, for Vops in the use multipass processing */
848     for (idx = 0; idx < nLayers; idx++)
849     {
850         video->pMP[idx] = (MultiPass *)M4VENC_MALLOC(sizeof(MultiPass));
851         if (video->pMP[idx] == NULL)    goto CLEAN_UP;
852         M4VENC_MEMSET(video->pMP[idx], 0, sizeof(MultiPass));
853 
854         video->pMP[idx]->encoded_frames = -1; /* forget about the very first I frame */
855 
856 
857         /* RDInfo **pRDSamples */
858         video->pMP[idx]->pRDSamples = (RDInfo **)M4VENC_MALLOC(30 * sizeof(RDInfo *));
859         if (video->pMP[idx]->pRDSamples == NULL)    goto CLEAN_UP;
860         for (i = 0; i < 30; i++)
861         {
862             video->pMP[idx]->pRDSamples[i] = (RDInfo *)M4VENC_MALLOC(32 * sizeof(RDInfo));
863             if (video->pMP[idx]->pRDSamples[i] == NULL) goto CLEAN_UP;
864             for (j = 0; j < 32; j++)    M4VENC_MEMSET(&(video->pMP[idx]->pRDSamples[i][j]), 0, sizeof(RDInfo));
865         }
866         video->pMP[idx]->frameRange = (Int)(video->encParams->LayerFrameRate[idx] * 1.0); /* 1.0s time frame*/
867         video->pMP[idx]->frameRange = PV_MAX(video->pMP[idx]->frameRange, 5);
868         video->pMP[idx]->frameRange = PV_MIN(video->pMP[idx]->frameRange, 30);
869 
870         video->pMP[idx]->framePos = -1;
871 
872     }
873     /* /// End /////////////////////////////////////// */
874 
875 
876     if ((size_t)nLayers > SIZE_MAX / sizeof(Vol *)) {
877         goto CLEAN_UP;
878     }
879     video->vol = (Vol **)M4VENC_MALLOC(nLayers * sizeof(Vol *)); /* Memory for VOL pointers */
880 
881     /* Memory allocation and Initialization of Vols and writing of headers */
882     if (video->vol == NULL) goto CLEAN_UP;
883 
884     for (idx = 0; idx < nLayers; idx++)
885     {
886         video->volInitialize[idx] = 1;
887         video->refTick[idx] = 0;
888         video->relLayerCodeTime[idx] = 1000;
889         video->vol[idx] = (Vol *)M4VENC_MALLOC(sizeof(Vol));
890         if (video->vol[idx] == NULL)  goto CLEAN_UP;
891 
892         pVol = video->vol[idx];
893         pEncParams = video->encParams;
894 
895         M4VENC_MEMSET(video->vol[idx], 0, sizeof(Vol));
896         /* Initialize some VOL parameters */
897         pVol->volID = idx;  /* Set VOL ID */
898         pVol->shortVideoHeader = pEncParams->H263_Enabled; /*Short Header */
899         pVol->GOVStart = pEncParams->GOV_Enabled; /* GOV Header */
900         pVol->timeIncrementResolution = video->encParams->TimeIncrementRes;
901         pVol->nbitsTimeIncRes = 1;
902         while (pVol->timeIncrementResolution > (1 << pVol->nbitsTimeIncRes))
903         {
904             pVol->nbitsTimeIncRes++;
905         }
906 
907         /* timing stuff */
908         pVol->timeIncrement = 0;
909         pVol->moduloTimeBase = 0;
910         pVol->fixedVopRate = 0; /* No fixed VOP rate */
911         pVol->stream = (BitstreamEncVideo *)M4VENC_MALLOC(sizeof(BitstreamEncVideo)); /* allocate BitstreamEncVideo Instance */
912         if (pVol->stream == NULL)  goto CLEAN_UP;
913 
914         pVol->width = pEncParams->LayerWidth[idx];      /* Layer Width */
915         pVol->height = pEncParams->LayerHeight[idx];    /* Layer Height */
916         //  pVol->intra_acdcPredDisable = pEncParams->ACDCPrediction; /* ACDC Prediction */
917         pVol->ResyncMarkerDisable = pEncParams->ResyncMarkerDisable; /* Resync Marker Mode */
918         pVol->dataPartitioning = pEncParams->DataPartitioning; /* Data Partitioning */
919         pVol->useReverseVLC = pEncParams->ReversibleVLC; /* RVLC */
920         if (idx > 0) /* Scalability layers */
921         {
922             pVol->ResyncMarkerDisable = 1;
923             pVol->dataPartitioning = 0;
924             pVol->useReverseVLC = 0; /*  No RVLC */
925         }
926         pVol->quantType = pEncParams->QuantType[idx];           /* Quantizer Type */
927 
928         /* no need to init Quant Matrices */
929 
930         pVol->scalability = 0;  /* Vol Scalability */
931         if (idx > 0)
932             pVol->scalability = 1; /* Multiple layers => Scalability */
933 
934         /* Initialize Vol to Temporal scalability.  It can change during encoding */
935         pVol->scalType = 1;
936         /* Initialize reference Vol ID to the base layer = 0 */
937         pVol->refVolID = 0;
938         /* Initialize layer resolution to same as the reference */
939         pVol->refSampDir = 0;
940         pVol->horSamp_m = 1;
941         pVol->horSamp_n = 1;
942         pVol->verSamp_m = 1;
943         pVol->verSamp_n = 1;
944         pVol->enhancementType = 0; /* We always enhance the entire region */
945 
946         pVol->nMBPerRow = (pVol->width + 15) / 16;
947         pVol->nMBPerCol = (pVol->height + 15) / 16;
948         pVol->nTotalMB = pVol->nMBPerRow * pVol->nMBPerCol;
949 
950         if (pVol->nTotalMB >= 1)
951             pVol->nBitsForMBID = 1;
952         if (pVol->nTotalMB >= 3)
953             pVol->nBitsForMBID = 2;
954         if (pVol->nTotalMB >= 5)
955             pVol->nBitsForMBID = 3;
956         if (pVol->nTotalMB >= 9)
957             pVol->nBitsForMBID = 4;
958         if (pVol->nTotalMB >= 17)
959             pVol->nBitsForMBID = 5;
960         if (pVol->nTotalMB >= 33)
961             pVol->nBitsForMBID = 6;
962         if (pVol->nTotalMB >= 65)
963             pVol->nBitsForMBID = 7;
964         if (pVol->nTotalMB >= 129)
965             pVol->nBitsForMBID = 8;
966         if (pVol->nTotalMB >= 257)
967             pVol->nBitsForMBID = 9;
968         if (pVol->nTotalMB >= 513)
969             pVol->nBitsForMBID = 10;
970         if (pVol->nTotalMB >= 1025)
971             pVol->nBitsForMBID = 11;
972         if (pVol->nTotalMB >= 2049)
973             pVol->nBitsForMBID = 12;
974         if (pVol->nTotalMB >= 4097)
975             pVol->nBitsForMBID = 13;
976         if (pVol->nTotalMB >= 8193)
977             pVol->nBitsForMBID = 14;
978         if (pVol->nTotalMB >= 16385)
979             pVol->nBitsForMBID = 15;
980         if (pVol->nTotalMB >= 32769)
981             pVol->nBitsForMBID = 16;
982         if (pVol->nTotalMB >= 65537)
983             pVol->nBitsForMBID = 17;
984         if (pVol->nTotalMB >= 131073)
985             pVol->nBitsForMBID = 18;
986 
987         if (pVol->shortVideoHeader)
988         {
989             switch (pVol->width)
990             {
991                 case 128:
992                     if (pVol->height == 96)  /* source_format = 1 */
993                     {
994                         pVol->nGOBinVop = 6;
995                         pVol->nMBinGOB = 8;
996                     }
997                     else
998                         status = PV_FALSE;
999                     break;
1000 
1001                 case 176:
1002                     if (pVol->height == 144)  /* source_format = 2 */
1003                     {
1004                         pVol->nGOBinVop = 9;
1005                         pVol->nMBinGOB = 11;
1006                     }
1007                     else
1008                         status = PV_FALSE;
1009                     break;
1010                 case 352:
1011                     if (pVol->height == 288)  /* source_format = 2 */
1012                     {
1013                         pVol->nGOBinVop = 18;
1014                         pVol->nMBinGOB = 22;
1015                     }
1016                     else
1017                         status = PV_FALSE;
1018                     break;
1019 
1020                 case 704:
1021                     if (pVol->height == 576)  /* source_format = 2 */
1022                     {
1023                         pVol->nGOBinVop = 18;
1024                         pVol->nMBinGOB = 88;
1025                     }
1026                     else
1027                         status = PV_FALSE;
1028                     break;
1029                 case 1408:
1030                     if (pVol->height == 1152)  /* source_format = 2 */
1031                     {
1032                         pVol->nGOBinVop = 18;
1033                         pVol->nMBinGOB = 352;
1034                     }
1035                     else
1036                         status = PV_FALSE;
1037                     break;
1038 
1039                 default:
1040                     status = PV_FALSE;
1041                     break;
1042             }
1043         }
1044     }
1045 
1046     /***************************************************/
1047     /* allocate and initialize rate control parameters */
1048     /***************************************************/
1049 
1050     /* BEGIN INITIALIZATION OF ANNEX L RATE CONTROL */
1051     if (video->encParams->RC_Type != CONSTANT_Q)
1052     {
1053         for (idx = 0; idx < nLayers; idx++) /* 12/25/00 */
1054         {
1055             video->rc[idx] =
1056                 (rateControl *)M4VENC_MALLOC(sizeof(rateControl));
1057 
1058             if (video->rc[idx] == NULL) goto CLEAN_UP;
1059 
1060             M4VENC_MEMSET(video->rc[idx], 0, sizeof(rateControl));
1061         }
1062         if (PV_SUCCESS != RC_Initialize(video))
1063         {
1064             goto CLEAN_UP;
1065         }
1066         /* initialization for 2-pass rate control */
1067     }
1068     /* END INITIALIZATION OF ANNEX L RATE CONTROL */
1069 
1070     /********** assign platform dependent functions ***********************/
1071     /* 1/23/01 */
1072     /* This must be done at run-time not a compile time */
1073     video->functionPointer = (FuncPtr*) M4VENC_MALLOC(sizeof(FuncPtr));
1074     if (video->functionPointer == NULL) goto CLEAN_UP;
1075 
1076     video->functionPointer->ComputeMBSum = &ComputeMBSum_C;
1077     video->functionPointer->SAD_MB_HalfPel[0] = NULL;
1078     video->functionPointer->SAD_MB_HalfPel[1] = &SAD_MB_HalfPel_Cxh;
1079     video->functionPointer->SAD_MB_HalfPel[2] = &SAD_MB_HalfPel_Cyh;
1080     video->functionPointer->SAD_MB_HalfPel[3] = &SAD_MB_HalfPel_Cxhyh;
1081 
1082 #ifndef NO_INTER4V
1083     video->functionPointer->SAD_Blk_HalfPel = &SAD_Blk_HalfPel_C;
1084     video->functionPointer->SAD_Block = &SAD_Block_C;
1085 #endif
1086     video->functionPointer->SAD_Macroblock = &SAD_Macroblock_C;
1087     video->functionPointer->ChooseMode = &ChooseMode_C;
1088     video->functionPointer->GetHalfPelMBRegion = &GetHalfPelMBRegion_C;
1089 //  video->functionPointer->SAD_MB_PADDING = &SAD_MB_PADDING; /* 4/21/01 */
1090 
1091 
1092     encoderControl->videoEncoderInit = 1;  /* init done! */
1093 
1094     return PV_TRUE;
1095 
1096 CLEAN_UP:
1097     PVCleanUpVideoEncoder(encoderControl);
1098 
1099     return PV_FALSE;
1100 }
1101 
1102 
1103 /* ======================================================================== */
1104 /*  Function : PVCleanUpVideoEncoder()                                      */
1105 /*  Date     : 08/22/2000                                                   */
1106 /*  Purpose  : Deallocates allocated memory from InitVideoEncoder()         */
1107 /*  In/out   :                                                              */
1108 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
1109 /*  Modified : 5/21/01, free only yChan in Vop                          */
1110 /*                                                                          */
1111 /* ======================================================================== */
1112 
PVCleanUpVideoEncoder(VideoEncControls * encoderControl)1113 OSCL_EXPORT_REF Bool    PVCleanUpVideoEncoder(VideoEncControls *encoderControl)
1114 {
1115     Int idx, i;
1116     VideoEncData *video = (VideoEncData *)encoderControl->videoEncoderData;
1117     int nTotalMB;
1118     int max_width, offset;
1119 
1120 #ifdef PRINT_RC_INFO
1121     if (facct != NULL)
1122     {
1123         fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
1124         fprintf(facct, "TOTAL NUM BITS GENERATED %d\n", tiTotalNumBitsGenerated);
1125         fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
1126         fprintf(facct, "TOTAL NUMBER OF FRAMES CODED %d\n",
1127                 video->encParams->rc[0]->totalFrameNumber);
1128         fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
1129         fprintf(facct, "Average BitRate %d\n",
1130                 (tiTotalNumBitsGenerated / (90 / 30)));
1131         fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
1132         fprintf(facct, "TOTAL NUMBER OF STUFF BITS %d\n", (iStuffBits + 10740));
1133         fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
1134         fprintf(facct, "TOTAL NUMBER OF BITS TO NETWORK %d\n", (35800*90 / 30));;
1135         fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
1136         fprintf(facct, "SUM OF STUFF BITS AND GENERATED BITS %d\n",
1137                 (tiTotalNumBitsGenerated + iStuffBits + 10740));
1138         fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
1139         fprintf(facct, "UNACCOUNTED DIFFERENCE %d\n",
1140                 ((35800*90 / 30) - (tiTotalNumBitsGenerated + iStuffBits + 10740)));
1141         fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
1142         fclose(facct);
1143     }
1144 #endif
1145 
1146 #ifdef PRINT_EC
1147     fclose(fec);
1148 #endif
1149 
1150     if (video != NULL)
1151     {
1152 
1153         if (video->QPMB) M4VENC_FREE(video->QPMB);
1154         if (video->headerInfo.Mode)M4VENC_FREE(video->headerInfo.Mode);
1155         if (video->headerInfo.CBP)M4VENC_FREE(video->headerInfo.CBP);
1156 
1157 
1158         if (video->mot)
1159         {
1160             nTotalMB = video->vol[0]->nTotalMB;
1161             for (idx = 1; idx < video->currLayer; idx++)
1162                 if (video->vol[idx]->nTotalMB > nTotalMB)
1163                     nTotalMB = video->vol[idx]->nTotalMB;
1164             for (idx = 0; idx < nTotalMB; idx++)
1165             {
1166                 if (video->mot[idx])
1167                     M4VENC_FREE(video->mot[idx]);
1168             }
1169             M4VENC_FREE(video->mot);
1170         }
1171 
1172         if (video->intraArray) M4VENC_FREE(video->intraArray);
1173 
1174         if (video->sliceNo)M4VENC_FREE(video->sliceNo);
1175         if (video->acPredFlag)M4VENC_FREE(video->acPredFlag);
1176 //      if(video->predDCAC)M4VENC_FREE(video->predDCAC);
1177         if (video->predDC) M4VENC_FREE(video->predDC);
1178         video->predDCAC_row = NULL;
1179         if (video->predDCAC_col) M4VENC_FREE(video->predDCAC_col);
1180         if (video->outputMB)M4VENC_FREE(video->outputMB);
1181 
1182         if (video->bitstream1)BitstreamCloseEnc(video->bitstream1);
1183         if (video->bitstream2)BitstreamCloseEnc(video->bitstream2);
1184         if (video->bitstream3)BitstreamCloseEnc(video->bitstream3);
1185 
1186         if (video->overrunBuffer) M4VENC_FREE(video->overrunBuffer);
1187 
1188         max_width = video->encParams->LayerWidth[0];
1189         max_width = (((max_width + 15) >> 4) << 4); /* 09/19/05 */
1190         if (video->encParams->H263_Enabled)
1191         {
1192             offset = 0;
1193         }
1194         else
1195         {
1196             offset = ((max_width + 32) << 4) + 16;
1197         }
1198 
1199         if (video->currVop)
1200         {
1201             if (video->currVop->allChan)
1202             {
1203                 M4VENC_FREE(video->currVop->allChan);
1204             }
1205             M4VENC_FREE(video->currVop);
1206         }
1207 
1208         if (video->nextBaseVop)
1209         {
1210             if (video->nextBaseVop->allChan)
1211             {
1212                 M4VENC_FREE(video->nextBaseVop->allChan);
1213             }
1214             M4VENC_FREE(video->nextBaseVop);
1215         }
1216 
1217         if (video->prevBaseVop)
1218         {
1219             if (video->prevBaseVop->allChan)
1220             {
1221                 M4VENC_FREE(video->prevBaseVop->allChan);
1222             }
1223             M4VENC_FREE(video->prevBaseVop);
1224         }
1225         if (video->prevEnhanceVop)
1226         {
1227             if (video->prevEnhanceVop->allChan)
1228             {
1229                 M4VENC_FREE(video->prevEnhanceVop->allChan);
1230             }
1231             M4VENC_FREE(video->prevEnhanceVop);
1232         }
1233 
1234         /* 04/09/01, for Vops in the use multipass processing */
1235         for (idx = 0; idx < video->encParams->nLayers; idx++)
1236         {
1237             if (video->pMP[idx])
1238             {
1239                 if (video->pMP[idx]->pRDSamples)
1240                 {
1241                     for (i = 0; i < 30; i++)
1242                     {
1243                         if (video->pMP[idx]->pRDSamples[i])
1244                             M4VENC_FREE(video->pMP[idx]->pRDSamples[i]);
1245                     }
1246                     M4VENC_FREE(video->pMP[idx]->pRDSamples);
1247                 }
1248 
1249                 M4VENC_MEMSET(video->pMP[idx], 0, sizeof(MultiPass));
1250                 M4VENC_FREE(video->pMP[idx]);
1251             }
1252         }
1253         /* //  End /////////////////////////////////////// */
1254 
1255         if (video->vol)
1256         {
1257             for (idx = 0; idx < video->encParams->nLayers; idx++)
1258             {
1259                 if (video->vol[idx])
1260                 {
1261                     if (video->vol[idx]->stream)
1262                         M4VENC_FREE(video->vol[idx]->stream);
1263                     M4VENC_FREE(video->vol[idx]);
1264                 }
1265             }
1266             M4VENC_FREE(video->vol);
1267         }
1268 
1269         /***************************************************/
1270         /* stop rate control parameters */
1271         /***************************************************/
1272 
1273         /* ANNEX L RATE CONTROL */
1274         if (video->encParams->RC_Type != CONSTANT_Q)
1275         {
1276             RC_Cleanup(video->rc, video->encParams->nLayers);
1277 
1278             for (idx = 0; idx < video->encParams->nLayers; idx++)
1279             {
1280                 if (video->rc[idx])
1281                     M4VENC_FREE(video->rc[idx]);
1282             }
1283         }
1284 
1285         if (video->functionPointer) M4VENC_FREE(video->functionPointer);
1286 
1287         /* If application has called PVCleanUpVideoEncoder then we deallocate */
1288         /* If PVInitVideoEncoder class it, then we DO NOT deallocate */
1289         if (video->encParams)
1290         {
1291             M4VENC_FREE(video->encParams);
1292         }
1293 
1294         M4VENC_FREE(video);
1295         encoderControl->videoEncoderData = NULL; /* video */
1296     }
1297 
1298     encoderControl->videoEncoderInit = 0;
1299 
1300     return PV_TRUE;
1301 }
1302 
1303 /* ======================================================================== */
1304 /*  Function : PVGetVolHeader()                                             */
1305 /*  Date     : 7/17/2001,                                                   */
1306 /*  Purpose  :                                                              */
1307 /*  In/out   :                                                              */
1308 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
1309 /*  Modified :                                                              */
1310 /*                                                                          */
1311 /* ======================================================================== */
1312 
PVGetVolHeader(VideoEncControls * encCtrl,UChar * volHeader,Int * size,Int layer)1313 OSCL_EXPORT_REF Bool PVGetVolHeader(VideoEncControls *encCtrl, UChar *volHeader, Int *size, Int layer)
1314 {
1315     VideoEncData    *encData;
1316     PV_STATUS   EncodeVOS_Start(VideoEncControls *encCtrl);
1317     encData = (VideoEncData *)encCtrl->videoEncoderData;
1318 
1319 
1320     if (encData == NULL)
1321         return PV_FALSE;
1322     if (encData->encParams == NULL)
1323         return PV_FALSE;
1324 
1325 
1326     encData->currLayer = layer; /* Set Layer */
1327     /*pv_status = */
1328     EncodeVOS_Start(encCtrl); /* Encode VOL Header */
1329 
1330     encData->encParams->GetVolHeader[layer] = 1; /* Set usage flag: Needed to support old method*/
1331 
1332     /* Copy bitstream to buffer and set the size */
1333 
1334     if (*size > encData->bitstream1->byteCount)
1335     {
1336         *size = encData->bitstream1->byteCount;
1337         M4VENC_MEMCPY(volHeader, encData->bitstream1->bitstreamBuffer, *size);
1338     }
1339     else
1340         return PV_FALSE;
1341 
1342     /* Reset bitstream1 buffer parameters */
1343     BitstreamEncReset(encData->bitstream1);
1344 
1345     return PV_TRUE;
1346 }
1347 
1348 /* ======================================================================== */
1349 /*  Function : PVGetOverrunBuffer()                                         */
1350 /*  Purpose  : Get the overrun buffer `                                     */
1351 /*  In/out   :                                                              */
1352 /*  Return   : Pointer to overrun buffer.                                   */
1353 /*  Modified :                                                              */
1354 /* ======================================================================== */
1355 
PVGetOverrunBuffer(VideoEncControls * encCtrl)1356 OSCL_EXPORT_REF UChar* PVGetOverrunBuffer(VideoEncControls *encCtrl)
1357 {
1358     VideoEncData *video = (VideoEncData *)encCtrl->videoEncoderData;
1359     Int currLayer = video->currLayer;
1360     Vol *currVol = video->vol[currLayer];
1361 
1362     if (currVol->stream->bitstreamBuffer != video->overrunBuffer) // not used
1363     {
1364         return NULL;
1365     }
1366 
1367     return video->overrunBuffer;
1368 }
1369 
1370 
1371 
1372 
1373 /* ======================================================================== */
1374 /*  Function : EncodeVideoFrame()                                           */
1375 /*  Date     : 08/22/2000                                                   */
1376 /*  Purpose  : Encode video frame and return bitstream                      */
1377 /*  In/out   :                                                              */
1378 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
1379 /*  Modified :                                                              */
1380 /*  02.14.2001                                      */
1381 /*              Finishing new timestamp 32-bit input                        */
1382 /*              Applications need to take care of wrap-around               */
1383 /* ======================================================================== */
PVEncodeVideoFrame(VideoEncControls * encCtrl,VideoEncFrameIO * vid_in,VideoEncFrameIO * vid_out,ULong * nextModTime,UChar * bstream,Int * size,Int * nLayer)1384 OSCL_EXPORT_REF Bool PVEncodeVideoFrame(VideoEncControls *encCtrl, VideoEncFrameIO *vid_in, VideoEncFrameIO *vid_out,
1385                                         ULong *nextModTime, UChar *bstream, Int *size, Int *nLayer)
1386 {
1387     Bool status = PV_TRUE;
1388     PV_STATUS pv_status;
1389     VideoEncData *video = (VideoEncData *)encCtrl->videoEncoderData;
1390     VideoEncParams *encParams = video->encParams;
1391     Vol *currVol;
1392     Vop *tempForwRefVop = NULL;
1393     Int tempRefSelCode = 0;
1394     PV_STATUS   EncodeVOS_Start(VideoEncControls *encCtrl);
1395     Int width_16, height_16;
1396     Int width, height;
1397     Vop *temp;
1398     Int encodeVop = 0;
1399     void  PaddingEdge(Vop *padVop);
1400     Int currLayer = -1;
1401     //Int nLayers = encParams->nLayers;
1402 
1403     ULong modTime = vid_in->timestamp;
1404 
1405 #ifdef RANDOM_REFSELCODE   /* add random selection of reference Vop */
1406     Int random_val[30] = {0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0};
1407     static Int rand_idx = 0;
1408 #endif
1409 
1410     /*******************************************************/
1411     /* Determine Next Vop to encode, if any, and nLayer    */
1412     /*******************************************************/
1413     //i = nLayers-1;
1414 
1415     if (video->volInitialize[0]) /* first vol to code */
1416     {
1417         video->nextModTime = video->modTimeRef = ((modTime) - ((modTime) % 1000));
1418     }
1419 
1420     encodeVop = DetermineCodingLayer(video, nLayer, modTime);
1421     currLayer = *nLayer;
1422     if ((currLayer < 0) || (currLayer > encParams->nLayers - 1))
1423         return PV_FALSE;
1424 
1425     /******************************************/
1426     /* If post-skipping still effective --- return */
1427     /******************************************/
1428 
1429     if (!encodeVop) /* skip enh layer, no base layer coded --- return */
1430     {
1431 #ifdef _PRINT_STAT
1432         printf("No frame coded. Continue to next frame.");
1433 #endif
1434         /* expected next code time, convert back to millisec */
1435         *nextModTime = video->nextModTime;
1436 
1437 #ifdef ALLOW_VOP_NOT_CODED
1438         if (video->vol[0]->shortVideoHeader) /* Short Video Header = 1 */
1439         {
1440             *size = 0;
1441             *nLayer = -1;
1442         }
1443         else
1444         {
1445             *nLayer = 0;
1446             EncodeVopNotCoded(video, bstream, size, modTime);
1447             *size = video->vol[0]->stream->byteCount;
1448         }
1449 #else
1450         *size = 0;
1451         *nLayer = -1;
1452 #endif
1453         return status;
1454     }
1455 
1456 
1457 //ENCODE_VOP_AGAIN:  /* 12/30/00 */
1458 
1459     /**************************************************************/
1460     /* Initialize Vol stream structure with application bitstream */
1461     /**************************************************************/
1462 
1463     currVol = video->vol[currLayer];
1464     currVol->stream->bitstreamBuffer = bstream;
1465     currVol->stream->bufferSize = *size;
1466     BitstreamEncReset(currVol->stream);
1467     BitstreamSetOverrunBuffer(currVol->stream, video->overrunBuffer, video->oBSize, video);
1468 
1469     /***********************************************************/
1470     /* Encode VOS and VOL Headers on first call for each layer */
1471     /***********************************************************/
1472 
1473     if (video->volInitialize[currLayer])
1474     {
1475         video->currVop->timeInc = 0;
1476         video->prevBaseVop->timeInc = 0;
1477         if (!video->encParams->GetVolHeader[currLayer])
1478             pv_status = EncodeVOS_Start(encCtrl);
1479     }
1480 
1481     /***************************************************/
1482     /* Copy Input Video Frame to Internal Video Buffer */
1483     /***************************************************/
1484     /* Determine Width and Height of Vop Layer */
1485 
1486     width = encParams->LayerWidth[currLayer];   /* Get input width */
1487     height = encParams->LayerHeight[currLayer]; /* Get input height */
1488     /* Round Up to nearest multiple of 16 : MPEG-4 Standard */
1489 
1490     width_16 = ((width + 15) / 16) * 16;            /* Round up to nearest multiple of 16 */
1491     height_16 = ((height + 15) / 16) * 16;          /* Round up to nearest multiple of 16 */
1492 
1493     video->input = vid_in;  /* point to the frame input */
1494 
1495     /*//  End ////////////////////////////// */
1496 
1497 
1498     /**************************************/
1499     /* Determine VOP Type                 */
1500     /* 6/2/2001, separate function      */
1501     /**************************************/
1502     DetermineVopType(video, currLayer);
1503 
1504     /****************************/
1505     /*    Initialize VOP        */
1506     /****************************/
1507     video->currVop->volID = currVol->volID;
1508     video->currVop->width = width_16;
1509     video->currVop->height = height_16;
1510     if (video->encParams->H263_Enabled) /*  11/28/05 */
1511     {
1512         video->currVop->pitch = width_16;
1513     }
1514     else
1515     {
1516         video->currVop->pitch = width_16 + 32;
1517     }
1518     video->currVop->timeInc = currVol->timeIncrement;
1519     video->currVop->vopCoded = 1;
1520     video->currVop->roundingType = 0;
1521     video->currVop->intraDCVlcThr = encParams->IntraDCVlcThr;
1522 
1523     if (currLayer == 0
1524 #ifdef RANDOM_REFSELCODE   /* add random selection of reference Vop */
1525             || random_val[rand_idx] || video->volInitialize[currLayer]
1526 #endif
1527        )
1528     {
1529         tempForwRefVop = video->forwardRefVop; /* keep initial state */
1530         if (tempForwRefVop != NULL) tempRefSelCode = tempForwRefVop->refSelectCode;
1531 
1532         video->forwardRefVop = video->prevBaseVop;
1533         video->forwardRefVop->refSelectCode = 1;
1534     }
1535 #ifdef RANDOM_REFSELCODE
1536     else
1537     {
1538         tempForwRefVop = video->forwardRefVop; /* keep initial state */
1539         if (tempForwRefVop != NULL) tempRefSelCode = tempForwRefVop->refSelectCode;
1540 
1541         video->forwardRefVop = video->prevEnhanceVop;
1542         video->forwardRefVop->refSelectCode = 0;
1543     }
1544     rand_idx++;
1545     rand_idx %= 30;
1546 #endif
1547 
1548     video->currVop->refSelectCode = video->forwardRefVop->refSelectCode;
1549     video->currVop->gobNumber = 0;
1550     video->currVop->gobFrameID = video->currVop->predictionType;
1551     video->currVop->temporalRef = (modTime * 30 / 1001) % 256;
1552 
1553     video->currVop->temporalInterval = 0;
1554 
1555     if (video->currVop->predictionType == I_VOP)
1556         video->currVop->quantizer = encParams->InitQuantIvop[currLayer];
1557     else
1558         video->currVop->quantizer = encParams->InitQuantPvop[currLayer];
1559 
1560 
1561     /****************/
1562     /* Encode Vop */
1563     /****************/
1564     video->slice_coding = 0;
1565 
1566     pv_status = EncodeVop(video);
1567 #ifdef _PRINT_STAT
1568     if (video->currVop->predictionType == I_VOP)
1569         printf(" I-VOP ");
1570     else
1571         printf(" P-VOP (ref.%d)", video->forwardRefVop->refSelectCode);
1572 #endif
1573 
1574     /************************************/
1575     /* Update Skip Next Frame           */
1576     /************************************/
1577     *nLayer = UpdateSkipNextFrame(video, nextModTime, size, pv_status);
1578     if (*nLayer == -1) /* skip current frame */
1579     {
1580         /* make sure that pointers are restored to the previous state */
1581         if (currLayer == 0)
1582         {
1583             video->forwardRefVop = tempForwRefVop; /* For P-Vop base only */
1584             if (video->forwardRefVop != NULL) video->forwardRefVop->refSelectCode = tempRefSelCode;
1585         }
1586 
1587         return status;
1588     }
1589 
1590     /* If I-VOP was encoded, reset IntraPeriod */
1591     if ((currLayer == 0) && (encParams->IntraPeriod > 0) && (video->currVop->predictionType == I_VOP))
1592         video->nextEncIVop = encParams->IntraPeriod;
1593 
1594     /* Set HintTrack Information */
1595     if (currLayer != -1)
1596     {
1597         if (currVol->prevModuloTimeBase)
1598             video->hintTrackInfo.MTB = 1;
1599         else
1600             video->hintTrackInfo.MTB = 0;
1601         video->hintTrackInfo.LayerID = (UChar)currVol->volID;
1602         video->hintTrackInfo.CodeType = (UChar)video->currVop->predictionType;
1603         video->hintTrackInfo.RefSelCode = (UChar)video->currVop->refSelectCode;
1604     }
1605 
1606     /************************************************/
1607     /* Determine nLayer and timeInc for next encode */
1608     /* 12/27/00 always go by the highest layer*/
1609     /************************************************/
1610 
1611     /**********************************************************/
1612     /* Copy Reconstructed Buffer to Output Video Frame Buffer */
1613     /**********************************************************/
1614     vid_out->yChan = video->currVop->yChan;
1615     vid_out->uChan = video->currVop->uChan;
1616     vid_out->vChan = video->currVop->vChan;
1617     if (video->encParams->H263_Enabled)
1618     {
1619         vid_out->height = video->currVop->height; /* padded height */
1620         vid_out->pitch = video->currVop->width; /* padded width */
1621     }
1622     else
1623     {
1624         vid_out->height = video->currVop->height + 32; /* padded height */
1625         vid_out->pitch = video->currVop->width + 32; /* padded width */
1626     }
1627     //video_out->timestamp = video->modTime;
1628     vid_out->timestamp = (ULong)(((video->prevFrameNum[currLayer] * 1000) / encParams->LayerFrameRate[currLayer]) + video->modTimeRef + 0.5);
1629 
1630     /*// End /////////////////////// */
1631 
1632     /***********************************/
1633     /* Update Ouput bstream byte count */
1634     /***********************************/
1635 
1636     *size = currVol->stream->byteCount;
1637 
1638     /****************************************/
1639     /* Swap Vop Pointers for Base Layer     */
1640     /****************************************/
1641     if (currLayer == 0)
1642     {
1643         temp = video->prevBaseVop;
1644         video->prevBaseVop = video->currVop;
1645         video->prevBaseVop->padded = 0; /* not padded */
1646         video->currVop  = temp;
1647         video->forwardRefVop = video->prevBaseVop; /* For P-Vop base only */
1648         video->forwardRefVop->refSelectCode = 1;
1649     }
1650     else
1651     {
1652         temp = video->prevEnhanceVop;
1653         video->prevEnhanceVop = video->currVop;
1654         video->prevEnhanceVop->padded = 0; /* not padded */
1655         video->currVop = temp;
1656         video->forwardRefVop = video->prevEnhanceVop;
1657         video->forwardRefVop->refSelectCode = 0;
1658     }
1659 
1660     /****************************************/
1661     /* Modify the intialize flag at the end.*/
1662     /****************************************/
1663     if (video->volInitialize[currLayer])
1664         video->volInitialize[currLayer] = 0;
1665 
1666     return status;
1667 }
1668 
1669 #ifndef NO_SLICE_ENCODE
1670 /* ======================================================================== */
1671 /*  Function : PVEncodeFrameSet()                                           */
1672 /*  Date     : 04/18/2000                                                   */
1673 /*  Purpose  : Enter a video frame and perform front-end time check plus ME */
1674 /*  In/out   :                                                              */
1675 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
1676 /*  Modified :                                                              */
1677 /*                                                                          */
1678 /* ======================================================================== */
PVEncodeFrameSet(VideoEncControls * encCtrl,VideoEncFrameIO * vid_in,ULong * nextModTime,Int * nLayer)1679 OSCL_EXPORT_REF Bool PVEncodeFrameSet(VideoEncControls *encCtrl, VideoEncFrameIO *vid_in, ULong *nextModTime, Int *nLayer)
1680 {
1681     Bool status = PV_TRUE;
1682     VideoEncData *video = (VideoEncData *)encCtrl->videoEncoderData;
1683     VideoEncParams *encParams = video->encParams;
1684     Vol *currVol;
1685     PV_STATUS   EncodeVOS_Start(VideoEncControls *encCtrl);
1686     Int width_16, height_16;
1687     Int width, height;
1688     Int encodeVop = 0;
1689     void  PaddingEdge(Vop *padVop);
1690     Int currLayer = -1;
1691     //Int nLayers = encParams->nLayers;
1692 
1693     ULong   modTime = vid_in->timestamp;
1694 
1695 #ifdef RANDOM_REFSELCODE   /* add random selection of reference Vop */
1696     Int random_val[30] = {0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0};
1697     static Int rand_idx = 0;
1698 #endif
1699     /*******************************************************/
1700     /* Determine Next Vop to encode, if any, and nLayer    */
1701     /*******************************************************/
1702 
1703     video->modTime = modTime;
1704 
1705     //i = nLayers-1;
1706 
1707     if (video->volInitialize[0]) /* first vol to code */
1708     {
1709         video->nextModTime = video->modTimeRef = ((modTime) - ((modTime) % 1000));
1710     }
1711 
1712 
1713     encodeVop = DetermineCodingLayer(video, nLayer, modTime);
1714 
1715     currLayer = *nLayer;
1716 
1717     /******************************************/
1718     /* If post-skipping still effective --- return */
1719     /******************************************/
1720 
1721     if (!encodeVop) /* skip enh layer, no base layer coded --- return */
1722     {
1723 #ifdef _PRINT_STAT
1724         printf("No frame coded. Continue to next frame.");
1725 #endif
1726         *nLayer = -1;
1727 
1728         /* expected next code time, convert back to millisec */
1729         *nextModTime = video->nextModTime;;
1730         return status;
1731     }
1732 
1733     /**************************************************************/
1734     /* Initialize Vol stream structure with application bitstream */
1735     /**************************************************************/
1736 
1737     currVol = video->vol[currLayer];
1738     currVol->stream->bufferSize = 0;
1739     BitstreamEncReset(currVol->stream);
1740 
1741     /***********************************************************/
1742     /* Encode VOS and VOL Headers on first call for each layer */
1743     /***********************************************************/
1744 
1745     if (video->volInitialize[currLayer])
1746     {
1747         video->currVop->timeInc = 0;
1748         video->prevBaseVop->timeInc = 0;
1749     }
1750 
1751     /***************************************************/
1752     /* Copy Input Video Frame to Internal Video Buffer */
1753     /***************************************************/
1754     /* Determine Width and Height of Vop Layer */
1755 
1756     width = encParams->LayerWidth[currLayer];   /* Get input width */
1757     height = encParams->LayerHeight[currLayer]; /* Get input height */
1758     /* Round Up to nearest multiple of 16 : MPEG-4 Standard */
1759 
1760     width_16 = ((width + 15) / 16) * 16;            /* Round up to nearest multiple of 16 */
1761     height_16 = ((height + 15) / 16) * 16;          /* Round up to nearest multiple of 16 */
1762 
1763     video->input = vid_in;  /* point to the frame input */
1764 
1765     /*//  End ////////////////////////////// */
1766 
1767 
1768     /**************************************/
1769     /* Determine VOP Type                 */
1770     /* 6/2/2001, separate function      */
1771     /**************************************/
1772     DetermineVopType(video, currLayer);
1773 
1774     /****************************/
1775     /*    Initialize VOP        */
1776     /****************************/
1777     video->currVop->volID = currVol->volID;
1778     video->currVop->width = width_16;
1779     video->currVop->height = height_16;
1780     if (video->encParams->H263_Enabled) /*  11/28/05 */
1781     {
1782         video->currVop->pitch = width_16;
1783     }
1784     else
1785     {
1786         video->currVop->pitch = width_16 + 32;
1787     }
1788     video->currVop->timeInc = currVol->timeIncrement;
1789     video->currVop->vopCoded = 1;
1790     video->currVop->roundingType = 0;
1791     video->currVop->intraDCVlcThr = encParams->IntraDCVlcThr;
1792 
1793     if (currLayer == 0
1794 #ifdef RANDOM_REFSELCODE   /* add random selection of reference Vop */
1795             || random_val[rand_idx] || video->volInitialize[currLayer]
1796 #endif
1797        )
1798     {
1799         video->tempForwRefVop = video->forwardRefVop; /* keep initial state */
1800         if (video->tempForwRefVop != NULL) video->tempRefSelCode = video->tempForwRefVop->refSelectCode;
1801 
1802         video->forwardRefVop = video->prevBaseVop;
1803         video->forwardRefVop->refSelectCode = 1;
1804     }
1805 #ifdef RANDOM_REFSELCODE
1806     else
1807     {
1808         video->tempForwRefVop = video->forwardRefVop; /* keep initial state */
1809         if (video->tempForwRefVop != NULL) video->tempRefSelCode = video->tempForwRefVop->refSelectCode;
1810 
1811         video->forwardRefVop = video->prevEnhanceVop;
1812         video->forwardRefVop->refSelectCode = 0;
1813     }
1814     rand_idx++;
1815     rand_idx %= 30;
1816 #endif
1817 
1818     video->currVop->refSelectCode = video->forwardRefVop->refSelectCode;
1819     video->currVop->gobNumber = 0;
1820     video->currVop->gobFrameID = video->currVop->predictionType;
1821     video->currVop->temporalRef = ((modTime) * 30 / 1001) % 256;
1822 
1823     video->currVop->temporalInterval = 0;
1824 
1825     if (video->currVop->predictionType == I_VOP)
1826         video->currVop->quantizer = encParams->InitQuantIvop[currLayer];
1827     else
1828         video->currVop->quantizer = encParams->InitQuantPvop[currLayer];
1829 
1830     /****************/
1831     /* Encode Vop   */
1832     /****************/
1833     video->slice_coding = 1;
1834 
1835     /*pv_status =*/
1836     EncodeVop(video);
1837 
1838 #ifdef _PRINT_STAT
1839     if (video->currVop->predictionType == I_VOP)
1840         printf(" I-VOP ");
1841     else
1842         printf(" P-VOP (ref.%d)", video->forwardRefVop->refSelectCode);
1843 #endif
1844 
1845     /* Set HintTrack Information */
1846     if (currVol->prevModuloTimeBase)
1847         video->hintTrackInfo.MTB = 1;
1848     else
1849         video->hintTrackInfo.MTB = 0;
1850 
1851     video->hintTrackInfo.LayerID = (UChar)currVol->volID;
1852     video->hintTrackInfo.CodeType = (UChar)video->currVop->predictionType;
1853     video->hintTrackInfo.RefSelCode = (UChar)video->currVop->refSelectCode;
1854 
1855     return status;
1856 }
1857 #endif /* NO_SLICE_ENCODE */
1858 
1859 #ifndef NO_SLICE_ENCODE
1860 /* ======================================================================== */
1861 /*  Function : PVEncodePacket()                                             */
1862 /*  Date     : 04/18/2002                                                   */
1863 /*  Purpose  : Encode one packet and return bitstream                       */
1864 /*  In/out   :                                                              */
1865 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
1866 /*  Modified :                                                              */
1867 /*                                                                          */
1868 /* ======================================================================== */
PVEncodeSlice(VideoEncControls * encCtrl,UChar * bstream,Int * size,Int * endofFrame,VideoEncFrameIO * vid_out,ULong * nextModTime)1869 OSCL_EXPORT_REF Bool PVEncodeSlice(VideoEncControls *encCtrl, UChar *bstream, Int *size,
1870                                    Int *endofFrame, VideoEncFrameIO *vid_out, ULong *nextModTime)
1871 {
1872     PV_STATUS pv_status;
1873     VideoEncData *video = (VideoEncData *)encCtrl->videoEncoderData;
1874     VideoEncParams *encParams = video->encParams;
1875     Vol *currVol;
1876     PV_STATUS   EncodeVOS_Start(VideoEncControls *encCtrl);
1877     Vop *temp;
1878     void  PaddingEdge(Vop *padVop);
1879     Int currLayer = video->currLayer;
1880     Int pre_skip;
1881     Int pre_size;
1882     /**************************************************************/
1883     /* Initialize Vol stream structure with application bitstream */
1884     /**************************************************************/
1885 
1886     currVol = video->vol[currLayer];
1887     currVol->stream->bitstreamBuffer = bstream;
1888     pre_size = currVol->stream->byteCount;
1889     currVol->stream->bufferSize = pre_size + (*size);
1890 
1891     /***********************************************************/
1892     /* Encode VOS and VOL Headers on first call for each layer */
1893     /***********************************************************/
1894 
1895     if (video->volInitialize[currLayer])
1896     {
1897         if (!video->encParams->GetVolHeader[currLayer])
1898             pv_status = EncodeVOS_Start(encCtrl);
1899     }
1900 
1901     /****************/
1902     /* Encode Slice */
1903     /****************/
1904     pv_status = EncodeSlice(video);
1905 
1906     *endofFrame = 0;
1907 
1908     if (video->mbnum >= currVol->nTotalMB && !video->end_of_buf)
1909     {
1910         *endofFrame = 1;
1911 
1912         /************************************/
1913         /* Update Skip Next Frame           */
1914         /************************************/
1915         pre_skip = UpdateSkipNextFrame(video, nextModTime, size, pv_status); /* modified such that no pre-skipped */
1916 
1917         if (pre_skip == -1) /* error */
1918         {
1919             *endofFrame = -1;
1920             /* make sure that pointers are restored to the previous state */
1921             if (currLayer == 0)
1922             {
1923                 video->forwardRefVop = video->tempForwRefVop; /* For P-Vop base only */
1924                 video->forwardRefVop->refSelectCode = video->tempRefSelCode;
1925             }
1926 
1927             return pv_status;
1928         }
1929 
1930         /* If I-VOP was encoded, reset IntraPeriod */
1931         if ((currLayer == 0) && (encParams->IntraPeriod > 0) && (video->currVop->predictionType == I_VOP))
1932             video->nextEncIVop = encParams->IntraPeriod;
1933 
1934         /**********************************************************/
1935         /* Copy Reconstructed Buffer to Output Video Frame Buffer */
1936         /**********************************************************/
1937         vid_out->yChan = video->currVop->yChan;
1938         vid_out->uChan = video->currVop->uChan;
1939         vid_out->vChan = video->currVop->vChan;
1940         if (video->encParams->H263_Enabled)
1941         {
1942             vid_out->height = video->currVop->height; /* padded height */
1943             vid_out->pitch = video->currVop->width; /* padded width */
1944         }
1945         else
1946         {
1947             vid_out->height = video->currVop->height + 32; /* padded height */
1948             vid_out->pitch = video->currVop->width + 32; /* padded width */
1949         }
1950         //vid_out->timestamp = video->modTime;
1951         vid_out->timestamp = (ULong)(((video->prevFrameNum[currLayer] * 1000) / encParams->LayerFrameRate[currLayer]) + video->modTimeRef + 0.5);
1952 
1953         /*// End /////////////////////// */
1954 
1955         /****************************************/
1956         /* Swap Vop Pointers for Base Layer     */
1957         /****************************************/
1958 
1959         if (currLayer == 0)
1960         {
1961             temp = video->prevBaseVop;
1962             video->prevBaseVop = video->currVop;
1963             video->prevBaseVop->padded = 0; /* not padded */
1964             video->currVop = temp;
1965             video->forwardRefVop = video->prevBaseVop; /* For P-Vop base only */
1966             video->forwardRefVop->refSelectCode = 1;
1967         }
1968         else
1969         {
1970             temp = video->prevEnhanceVop;
1971             video->prevEnhanceVop = video->currVop;
1972             video->prevEnhanceVop->padded = 0; /* not padded */
1973             video->currVop = temp;
1974             video->forwardRefVop = video->prevEnhanceVop;
1975             video->forwardRefVop->refSelectCode = 0;
1976         }
1977     }
1978 
1979     /***********************************/
1980     /* Update Ouput bstream byte count */
1981     /***********************************/
1982 
1983     *size = currVol->stream->byteCount - pre_size;
1984 
1985     /****************************************/
1986     /* Modify the intialize flag at the end.*/
1987     /****************************************/
1988     if (video->volInitialize[currLayer])
1989         video->volInitialize[currLayer] = 0;
1990 
1991     return pv_status;
1992 }
1993 #endif /* NO_SLICE_ENCODE */
1994 
1995 
1996 /* ======================================================================== */
1997 /*  Function : PVGetH263ProfileLevelID()                                    */
1998 /*  Date     : 02/05/2003                                                   */
1999 /*  Purpose  : Get H.263 Profile ID and level ID for profile 0              */
2000 /*  In/out   : Profile ID=0, levelID is what we want                        */
2001 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
2002 /*  Modified :                                                              */
2003 /*  Note     : h263Level[8], rBR_bound[8], max_h263_framerate[2]            */
2004 /*             max_h263_width[2], max_h263_height[2] are global             */
2005 /*                                                                          */
2006 /* ======================================================================== */
PVGetH263ProfileLevelID(VideoEncControls * encCtrl,Int * profileID,Int * levelID)2007 OSCL_EXPORT_REF Bool PVGetH263ProfileLevelID(VideoEncControls *encCtrl, Int *profileID, Int *levelID)
2008 {
2009     VideoEncData *encData;
2010     Int width, height;
2011     float bitrate_r, framerate;
2012 
2013 
2014     /* For this version, we only support H.263 profile 0 */
2015     *profileID = 0;
2016 
2017     *levelID = 0;
2018     encData = (VideoEncData *)encCtrl->videoEncoderData;
2019 
2020     if (encData == NULL)
2021         return PV_FALSE;
2022     if (encData->encParams == NULL)
2023         return PV_FALSE;
2024 
2025     if (!encData->encParams->H263_Enabled) return PV_FALSE;
2026 
2027 
2028     /* get image width, height, bitrate and framerate */
2029     width     = encData->encParams->LayerWidth[0];
2030     height    = encData->encParams->LayerHeight[0];
2031     bitrate_r = (float)(encData->encParams->LayerBitRate[0]) / (float)64000.0;
2032     framerate = encData->encParams->LayerFrameRate[0];
2033     if (!width || !height || !(bitrate_r > 0 && framerate > 0)) return PV_FALSE;
2034 
2035     /* This is the most frequent case : level 10 */
2036     if (bitrate_r <= rBR_bound[1] && framerate <= max_h263_framerate[0] &&
2037             (width <= max_h263_width[0] && height <= max_h263_height[0]))
2038     {
2039         *levelID = h263Level[1];
2040         return PV_TRUE;
2041     }
2042     else if (bitrate_r > rBR_bound[4] ||
2043              (width > max_h263_width[1] || height > max_h263_height[1]) ||
2044              framerate > max_h263_framerate[1])    /* check the highest level 70 */
2045     {
2046         *levelID = h263Level[7];
2047         return PV_TRUE;
2048     }
2049     else   /* search level 20, 30, 40 */
2050     {
2051 
2052         /* pick out level 20 */
2053         if (bitrate_r <= rBR_bound[2] &&
2054                 ((width <= max_h263_width[0] && height <= max_h263_height[0] && framerate <= max_h263_framerate[1]) ||
2055                  (width <= max_h263_width[1] && height <= max_h263_height[1] && framerate <= max_h263_framerate[0])))
2056         {
2057             *levelID = h263Level[2];
2058             return PV_TRUE;
2059         }
2060         else   /* width, height and framerate are ok, now choose level 30 or 40 */
2061         {
2062             *levelID = (bitrate_r <= rBR_bound[3] ? h263Level[3] : h263Level[4]);
2063             return PV_TRUE;
2064         }
2065     }
2066 }
2067 
2068 /* ======================================================================== */
2069 /*  Function : PVGetMPEG4ProfileLevelID()                                   */
2070 /*  Date     : 26/06/2008                                                   */
2071 /*  Purpose  : Get MPEG4 Level after initialized                            */
2072 /*  In/out   : profile_level according to interface                         */
2073 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
2074 /*  Modified :                                                              */
2075 /*                                                                          */
2076 /* ======================================================================== */
PVGetMPEG4ProfileLevelID(VideoEncControls * encCtrl,Int * profile_level,Int nLayer)2077 OSCL_EXPORT_REF Bool PVGetMPEG4ProfileLevelID(VideoEncControls *encCtrl, Int *profile_level, Int nLayer)
2078 {
2079     VideoEncData* video;
2080     Int i;
2081 
2082     video = (VideoEncData *)encCtrl->videoEncoderData;
2083 
2084     if (nLayer == 0)
2085     {
2086         for (i = 0; i < 8; i++)
2087         {
2088             if (video->encParams->ProfileLevel[0] == profile_level_code[i])
2089             {
2090                 break;
2091             }
2092         }
2093         *profile_level = i;
2094     }
2095     else
2096     {
2097         for (i = 0; i < 8; i++)
2098         {
2099             if (video->encParams->ProfileLevel[0] == scalable_profile_level_code[i])
2100             {
2101                 break;
2102             }
2103         }
2104         *profile_level = i + SIMPLE_SCALABLE_PROFILE_LEVEL0;
2105     }
2106 
2107     return true;
2108 }
2109 
2110 #ifndef LIMITED_API
2111 /* ======================================================================== */
2112 /*  Function : PVUpdateEncFrameRate                                         */
2113 /*  Date     : 04/08/2002                                                   */
2114 /*  Purpose  : Update target frame rates of the encoded base and enhance    */
2115 /*             layer(if any) while encoding operation is ongoing            */
2116 /*  In/out   :                                                              */
2117 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
2118 /*  Modified :                                                              */
2119 /*                                                                          */
2120 /* ======================================================================== */
2121 
PVUpdateEncFrameRate(VideoEncControls * encCtrl,float * frameRate)2122 OSCL_EXPORT_REF Bool PVUpdateEncFrameRate(VideoEncControls *encCtrl, float *frameRate)
2123 {
2124     VideoEncData    *encData;
2125     Int i;// nTotalMB, mbPerSec;
2126 
2127     encData = (VideoEncData *)encCtrl->videoEncoderData;
2128 
2129     if (encData == NULL)
2130         return PV_FALSE;
2131     if (encData->encParams == NULL)
2132         return PV_FALSE;
2133 
2134     /* Update the framerates for all the layers */
2135     for (i = 0; i < encData->encParams->nLayers; i++)
2136     {
2137 
2138         /* New check: encoding framerate should be consistent with the given profile and level */
2139         //nTotalMB = (((encData->encParams->LayerWidth[i]+15)/16)*16)*(((encData->encParams->LayerHeight[i]+15)/16)*16)/(16*16);
2140         //mbPerSec = (Int)(nTotalMB * frameRate[i]);
2141         //if(mbPerSec > encData->encParams->LayerMaxMbsPerSec[i]) return PV_FALSE;
2142         if (frameRate[i] > encData->encParams->LayerMaxFrameRate[i]) return PV_FALSE; /* set by users or profile */
2143 
2144         encData->encParams->LayerFrameRate[i] = frameRate[i];
2145     }
2146 
2147     return RC_UpdateBXRCParams((void*) encData);
2148 
2149 }
2150 #endif
2151 #ifndef LIMITED_API
2152 /* ======================================================================== */
2153 /*  Function : PVUpdateBitRate                                              */
2154 /*  Date     : 04/08/2002                                                   */
2155 /*  Purpose  : Update target bit rates of the encoded base and enhance      */
2156 /*             layer(if any) while encoding operation is ongoing            */
2157 /*  In/out   :                                                              */
2158 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
2159 /*  Modified :                                                              */
2160 /*                                                                          */
2161 /* ======================================================================== */
2162 
PVUpdateBitRate(VideoEncControls * encCtrl,Int * bitRate)2163 OSCL_EXPORT_REF Bool PVUpdateBitRate(VideoEncControls *encCtrl, Int *bitRate)
2164 {
2165     VideoEncData    *encData;
2166     Int i;
2167 
2168     encData = (VideoEncData *)encCtrl->videoEncoderData;
2169 
2170     if (encData == NULL)
2171         return PV_FALSE;
2172     if (encData->encParams == NULL)
2173         return PV_FALSE;
2174 
2175     /* Update the bitrates for all the layers */
2176     for (i = 0; i < encData->encParams->nLayers; i++)
2177     {
2178         if (bitRate[i] > encData->encParams->LayerMaxBitRate[i]) /* set by users or profile */
2179         {
2180             return PV_FALSE;
2181         }
2182         encData->encParams->LayerBitRate[i] = bitRate[i];
2183     }
2184 
2185     return RC_UpdateBXRCParams((void*) encData);
2186 
2187 }
2188 #endif
2189 #ifndef LIMITED_API
2190 /* ============================================================================ */
2191 /*  Function : PVUpdateVBVDelay()                                                   */
2192 /*  Date     : 4/23/2004                                                        */
2193 /*  Purpose  : Update VBV buffer size(in delay)                                 */
2194 /*  In/out   :                                                                  */
2195 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                        */
2196 /*  Modified :                                                                  */
2197 /*                                                                              */
2198 /* ============================================================================ */
2199 
PVUpdateVBVDelay(VideoEncControls * encCtrl,float delay)2200 Bool PVUpdateVBVDelay(VideoEncControls *encCtrl, float delay)
2201 {
2202 
2203     VideoEncData    *encData;
2204     Int total_bitrate, max_buffer_size;
2205     int index;
2206 
2207     encData = (VideoEncData *)encCtrl->videoEncoderData;
2208 
2209     if (encData == NULL)
2210         return PV_FALSE;
2211     if (encData->encParams == NULL)
2212         return PV_FALSE;
2213 
2214     /* Check whether the input delay is valid based on the given profile */
2215     total_bitrate   = (encData->encParams->nLayers == 1 ? encData->encParams->LayerBitRate[0] :
2216                        encData->encParams->LayerBitRate[1]);
2217     index = encData->encParams->profile_table_index;
2218     max_buffer_size = (encData->encParams->nLayers == 1 ? profile_level_max_VBV_size[index] :
2219                        scalable_profile_level_max_VBV_size[index]);
2220 
2221     if (total_bitrate*delay > (float)max_buffer_size)
2222         return PV_FALSE;
2223 
2224     encData->encParams->VBV_delay = delay;
2225     return PV_TRUE;
2226 
2227 }
2228 #endif
2229 #ifndef LIMITED_API
2230 /* ======================================================================== */
2231 /*  Function : PVUpdateIFrameInterval()                                         */
2232 /*  Date     : 04/10/2002                                                   */
2233 /*  Purpose  : updates the INTRA frame refresh interval while encoding      */
2234 /*             is ongoing                                                   */
2235 /*  In/out   :                                                              */
2236 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
2237 /*  Modified :                                                              */
2238 /*                                                                          */
2239 /* ======================================================================== */
2240 
PVUpdateIFrameInterval(VideoEncControls * encCtrl,Int aIFramePeriod)2241 OSCL_EXPORT_REF Bool PVUpdateIFrameInterval(VideoEncControls *encCtrl, Int aIFramePeriod)
2242 {
2243     VideoEncData    *encData;
2244 
2245     encData = (VideoEncData *)encCtrl->videoEncoderData;
2246 
2247     if (encData == NULL)
2248         return PV_FALSE;
2249     if (encData->encParams == NULL)
2250         return PV_FALSE;
2251 
2252     encData->encParams->IntraPeriod = aIFramePeriod;
2253     return PV_TRUE;
2254 }
2255 #endif
2256 #ifndef LIMITED_API
2257 /* ======================================================================== */
2258 /*  Function : PVSetNumIntraMBRefresh()                                     */
2259 /*  Date     : 08/05/2003                                                   */
2260 /*  Purpose  :                                                              */
2261 /*  In/out   :                                                              */
2262 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
2263 /*  Modified :                                                              */
2264 /*                                                                          */
2265 /* ======================================================================== */
PVUpdateNumIntraMBRefresh(VideoEncControls * encCtrl,Int numMB)2266 OSCL_EXPORT_REF Bool    PVUpdateNumIntraMBRefresh(VideoEncControls *encCtrl, Int numMB)
2267 {
2268     VideoEncData    *encData;
2269 
2270     encData = (VideoEncData *)encCtrl->videoEncoderData;
2271 
2272     if (encData == NULL)
2273         return PV_FALSE;
2274 
2275     encData->encParams->Refresh = numMB;
2276 
2277     return PV_TRUE;
2278 }
2279 #endif
2280 #ifndef LIMITED_API
2281 /* ======================================================================== */
2282 /*  Function : PVIFrameRequest()                                            */
2283 /*  Date     : 04/10/2002                                                   */
2284 /*  Purpose  : encodes the next base frame as an I-Vop                      */
2285 /*  In/out   :                                                              */
2286 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
2287 /*  Modified :                                                              */
2288 /*                                                                          */
2289 /* ======================================================================== */
2290 
PVIFrameRequest(VideoEncControls * encCtrl)2291 OSCL_EXPORT_REF Bool PVIFrameRequest(VideoEncControls *encCtrl)
2292 {
2293     VideoEncData    *encData;
2294 
2295     encData = (VideoEncData *)encCtrl->videoEncoderData;
2296 
2297     if (encData == NULL)
2298         return PV_FALSE;
2299     if (encData->encParams == NULL)
2300         return PV_FALSE;
2301 
2302     encData->nextEncIVop = 1;
2303     return PV_TRUE;
2304 }
2305 #endif
2306 #ifndef LIMITED_API
2307 /* ======================================================================== */
2308 /*  Function : PVGetEncMemoryUsage()                                        */
2309 /*  Date     : 10/17/2000                                                   */
2310 /*  Purpose  :                                                              */
2311 /*  In/out   :                                                              */
2312 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
2313 /*  Modified :                                                              */
2314 /*                                                                          */
2315 /* ======================================================================== */
2316 
PVGetEncMemoryUsage(VideoEncControls * encCtrl)2317 OSCL_EXPORT_REF Int PVGetEncMemoryUsage(VideoEncControls *encCtrl)
2318 {
2319     VideoEncData    *encData;
2320 
2321     encData = (VideoEncData *)encCtrl->videoEncoderData;
2322 
2323     if (encData == NULL)
2324         return PV_FALSE;
2325     if (encData->encParams == NULL)
2326         return PV_FALSE;
2327     return encData->encParams->MemoryUsage;
2328 }
2329 #endif
2330 
2331 /* ======================================================================== */
2332 /*  Function : PVGetHintTrack()                                             */
2333 /*  Date     : 1/17/2001,                                                   */
2334 /*  Purpose  :                                                              */
2335 /*  In/out   :                                                              */
2336 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
2337 /*  Modified :                                                              */
2338 /*                                                                          */
2339 /* ======================================================================== */
2340 
PVGetHintTrack(VideoEncControls * encCtrl,MP4HintTrack * info)2341 OSCL_EXPORT_REF Bool PVGetHintTrack(VideoEncControls *encCtrl, MP4HintTrack *info)
2342 {
2343     VideoEncData    *encData;
2344 
2345     encData = (VideoEncData *)encCtrl->videoEncoderData;
2346 
2347     if (encData == NULL)
2348         return PV_FALSE;
2349     if (encData->encParams == NULL)
2350         return PV_FALSE;
2351     info->MTB = encData->hintTrackInfo.MTB;
2352     info->LayerID = encData->hintTrackInfo.LayerID;
2353     info->CodeType = encData->hintTrackInfo.CodeType;
2354     info->RefSelCode = encData->hintTrackInfo.RefSelCode;
2355 
2356     return PV_TRUE;
2357 }
2358 
2359 /* ======================================================================== */
2360 /*  Function : PVGetMaxVideoFrameSize()                                     */
2361 /*  Date     : 7/17/2001,                                                   */
2362 /*  Purpose  : Function merely returns the maximum buffer size              */
2363 /*  In/out   :                                                              */
2364 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
2365 /*  Modified :                                                              */
2366 /*                                                                          */
2367 /* ======================================================================== */
2368 
PVGetMaxVideoFrameSize(VideoEncControls * encCtrl,Int * maxVideoFrameSize)2369 OSCL_EXPORT_REF Bool PVGetMaxVideoFrameSize(VideoEncControls *encCtrl, Int *maxVideoFrameSize)
2370 {
2371     VideoEncData    *encData;
2372 
2373     encData = (VideoEncData *)encCtrl->videoEncoderData;
2374 
2375     if (encData == NULL)
2376         return PV_FALSE;
2377     if (encData->encParams == NULL)
2378         return PV_FALSE;
2379 
2380 
2381 
2382     *maxVideoFrameSize = encData->encParams->BufferSize[0];
2383 
2384     if (encData->encParams->nLayers == 2)
2385         if (*maxVideoFrameSize < encData->encParams->BufferSize[1])
2386             *maxVideoFrameSize = encData->encParams->BufferSize[1];
2387     *maxVideoFrameSize >>= 3;   /* Convert to Bytes */
2388 
2389     if (*maxVideoFrameSize <= 4000)
2390         *maxVideoFrameSize = 4000;
2391 
2392     return PV_TRUE;
2393 }
2394 #ifndef LIMITED_API
2395 /* ======================================================================== */
2396 /*  Function : PVGetVBVSize()                                               */
2397 /*  Date     : 4/15/2002                                                    */
2398 /*  Purpose  : Function merely returns the maximum buffer size              */
2399 /*  In/out   :                                                              */
2400 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
2401 /*  Modified :                                                              */
2402 /*                                                                          */
2403 /* ======================================================================== */
2404 
PVGetVBVSize(VideoEncControls * encCtrl,Int * VBVSize)2405 OSCL_EXPORT_REF Bool PVGetVBVSize(VideoEncControls *encCtrl, Int *VBVSize)
2406 {
2407     VideoEncData    *encData;
2408 
2409     encData = (VideoEncData *)encCtrl->videoEncoderData;
2410 
2411     if (encData == NULL)
2412         return PV_FALSE;
2413     if (encData->encParams == NULL)
2414         return PV_FALSE;
2415 
2416     *VBVSize = encData->encParams->BufferSize[0];
2417     if (encData->encParams->nLayers == 2)
2418         *VBVSize += encData->encParams->BufferSize[1];
2419 
2420     return PV_TRUE;
2421 
2422 }
2423 #endif
2424 /* ======================================================================== */
2425 /*  Function : EncodeVOS_Start()                                            */
2426 /*  Date     : 08/22/2000                                                   */
2427 /*  Purpose  : Encodes the VOS,VO, and VOL or Short Headers                 */
2428 /*  In/out   :                                                              */
2429 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
2430 /*  Modified :                                                              */
2431 /*                                                                          */
2432 /* ======================================================================== */
EncodeVOS_Start(VideoEncControls * encoderControl)2433 PV_STATUS EncodeVOS_Start(VideoEncControls *encoderControl)
2434 {
2435 
2436     VideoEncData *video = (VideoEncData *)encoderControl->videoEncoderData;
2437     Vol         *currVol = video->vol[video->currLayer];
2438     PV_STATUS status = PV_SUCCESS;
2439     //int profile_level=0x01;
2440     BitstreamEncVideo *stream = video->bitstream1;
2441     int i, j;
2442 
2443     /********************************/
2444     /* Check for short_video_header */
2445     /********************************/
2446     if (currVol->shortVideoHeader == 1)
2447         return status;
2448     else
2449     {
2450         /* Short Video Header or M4V */
2451 
2452         /**************************/
2453         /* VisualObjectSequence ()*/
2454         /**************************/
2455         status = BitstreamPutGT16Bits(stream, 32, SESSION_START_CODE);
2456         /*  Determine profile_level */
2457         status = BitstreamPutBits(stream, 8, video->encParams->ProfileLevel[video->currLayer]);
2458 
2459         /******************/
2460         /* VisualObject() */
2461         /******************/
2462 
2463         status = BitstreamPutGT16Bits(stream, 32, VISUAL_OBJECT_START_CODE);
2464         status = BitstreamPut1Bits(stream, 0x00); /* visual object identifier */
2465         status = BitstreamPutBits(stream, 4, 0x01); /* visual object Type == "video ID" */
2466         status = BitstreamPut1Bits(stream, 0x00); /* no video signal type */
2467 
2468         /*temp   = */
2469         BitstreamMpeg4ByteAlignStuffing(stream);
2470 
2471 
2472         status = BitstreamPutGT16Bits(stream, 27, VO_START_CODE);/* byte align: should be 2 bits */
2473         status = BitstreamPutBits(stream, 5, 0x00);/*  Video ID = 0  */
2474 
2475 
2476 
2477         /**********************/
2478         /* VideoObjectLayer() */
2479         /**********************/
2480         if (currVol->shortVideoHeader == 0)
2481         { /* M4V  else Short Video Header */
2482             status = BitstreamPutGT16Bits(stream, VOL_START_CODE_LENGTH, VOL_START_CODE);
2483             status = BitstreamPutBits(stream, 4, currVol->volID);/*  video_object_layer_id */
2484             status = BitstreamPut1Bits(stream, 0x00);/*  Random Access = 0  */
2485 
2486             if (video->currLayer == 0)
2487                 status = BitstreamPutBits(stream, 8, 0x01);/* Video Object Type Indication = 1  ... Simple Object Type */
2488             else
2489                 status = BitstreamPutBits(stream, 8, 0x02);/* Video Object Type Indication = 2  ... Simple Scalable Object Type */
2490 
2491             status = BitstreamPut1Bits(stream, 0x00);/*  is_object_layer_identifer = 0 */
2492 
2493 
2494             status = BitstreamPutBits(stream, 4, 0x01); /* aspect_ratio_info = 1 ... 1:1(Square) */
2495             status = BitstreamPut1Bits(stream, 0x00);/* vol_control_parameters = 0 */
2496             status = BitstreamPutBits(stream, 2, 0x00);/* video_object_layer_shape = 00 ... rectangular */
2497             status = BitstreamPut1Bits(stream, 0x01);/* marker bit */
2498             status = BitstreamPutGT8Bits(stream, 16, currVol->timeIncrementResolution);/* vop_time_increment_resolution */
2499             status = BitstreamPut1Bits(stream, 0x01);/* marker bit */
2500             status = BitstreamPut1Bits(stream, currVol->fixedVopRate);/* fixed_vop_rate = 0 */
2501 
2502             /* For Rectangular VO layer shape */
2503             status = BitstreamPut1Bits(stream, 0x01);/* marker bit */
2504             status = BitstreamPutGT8Bits(stream, 13, currVol->width);/* video_object_layer_width */
2505             status = BitstreamPut1Bits(stream, 0x01);/* marker bit */
2506             status = BitstreamPutGT8Bits(stream, 13, currVol->height);/* video_object_layer_height */
2507             status = BitstreamPut1Bits(stream, 0x01);/*marker bit */
2508 
2509             status = BitstreamPut1Bits(stream, 0x00);/*interlaced = 0 */
2510             status = BitstreamPut1Bits(stream, 0x01);/* obmc_disable = 1 */
2511             status = BitstreamPut1Bits(stream, 0x00);/* sprite_enable = 0 */
2512             status = BitstreamPut1Bits(stream, 0x00);/* not_8_bit = 0 */
2513             status = BitstreamPut1Bits(stream, currVol->quantType);/*   quant_type */
2514 
2515             if (currVol->quantType)
2516             {
2517                 status = BitstreamPut1Bits(stream, currVol->loadIntraQuantMat); /* Intra quant matrix */
2518                 if (currVol->loadIntraQuantMat)
2519                 {
2520                     for (j = 63; j >= 1; j--)
2521                         if (currVol->iqmat[*(zigzag_i+j)] != currVol->iqmat[*(zigzag_i+j-1)])
2522                             break;
2523                     if ((j == 1) && (currVol->iqmat[*(zigzag_i+j)] == currVol->iqmat[*(zigzag_i+j-1)]))
2524                         j = 0;
2525                     for (i = 0; i < j + 1; i++)
2526                         BitstreamPutBits(stream, 8, currVol->iqmat[*(zigzag_i+i)]);
2527                     if (j < 63)
2528                         BitstreamPutBits(stream, 8, 0);
2529                 }
2530                 else
2531                 {
2532                     for (j = 0; j < 64; j++)
2533                         currVol->iqmat[j] = mpeg_iqmat_def[j];
2534 
2535                 }
2536                 status = BitstreamPut1Bits(stream, currVol->loadNonIntraQuantMat); /* Non-Intra quant matrix */
2537                 if (currVol->loadNonIntraQuantMat)
2538                 {
2539                     for (j = 63; j >= 1; j--)
2540                         if (currVol->niqmat[*(zigzag_i+j)] != currVol->niqmat[*(zigzag_i+j-1)])
2541                             break;
2542                     if ((j == 1) && (currVol->niqmat[*(zigzag_i+j)] == currVol->niqmat[*(zigzag_i+j-1)]))
2543                         j = 0;
2544                     for (i = 0; i < j + 1; i++)
2545                         BitstreamPutBits(stream, 8, currVol->niqmat[*(zigzag_i+i)]);
2546                     if (j < 63)
2547                         BitstreamPutBits(stream, 8, 0);
2548                 }
2549                 else
2550                 {
2551                     for (j = 0; j < 64; j++)
2552                         currVol->niqmat[j] = mpeg_nqmat_def[j];
2553                 }
2554             }
2555 
2556             status = BitstreamPut1Bits(stream, 0x01);   /* complexity_estimation_disable = 1 */
2557             status = BitstreamPut1Bits(stream, currVol->ResyncMarkerDisable);/* Resync_marker_disable */
2558             status = BitstreamPut1Bits(stream, currVol->dataPartitioning);/* Data partitioned */
2559 
2560             if (currVol->dataPartitioning)
2561                 status = BitstreamPut1Bits(stream, currVol->useReverseVLC); /* Reversible_vlc */
2562 
2563 
2564             if (currVol->scalability) /* Scalability*/
2565             {
2566 
2567                 status = BitstreamPut1Bits(stream, currVol->scalability);/* Scalability = 1 */
2568                 status = BitstreamPut1Bits(stream, currVol->scalType);/* hierarchy _type ... Spatial= 0 and Temporal = 1 */
2569                 status = BitstreamPutBits(stream, 4, currVol->refVolID);/* ref_layer_id  */
2570                 status = BitstreamPut1Bits(stream, currVol->refSampDir);/* ref_layer_sampling_direc*/
2571                 status = BitstreamPutBits(stream, 5, currVol->horSamp_n);/*hor_sampling_factor_n*/
2572                 status = BitstreamPutBits(stream, 5, currVol->horSamp_m);/*hor_sampling_factor_m*/
2573                 status = BitstreamPutBits(stream, 5, currVol->verSamp_n);/*vert_sampling_factor_n*/
2574                 status = BitstreamPutBits(stream, 5, currVol->verSamp_m);/*vert_sampling_factor_m*/
2575                 status = BitstreamPut1Bits(stream, currVol->enhancementType);/* enhancement_type*/
2576             }
2577             else /* No Scalability */
2578                 status = BitstreamPut1Bits(stream, currVol->scalability);/* Scalability = 0 */
2579 
2580             /*temp = */
2581             BitstreamMpeg4ByteAlignStuffing(stream); /* Byte align Headers for VOP */
2582         }
2583     }
2584 
2585     return status;
2586 }
2587 
2588 /* ======================================================================== */
2589 /*  Function : VOS_End()                                                    */
2590 /*  Date     : 08/22/2000                                                   */
2591 /*  Purpose  : Visual Object Sequence End                                   */
2592 /*  In/out   :                                                              */
2593 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
2594 /*  Modified :                                                              */
2595 /*                                                                          */
2596 /* ======================================================================== */
2597 
VOS_End(VideoEncControls * encoderControl)2598 PV_STATUS VOS_End(VideoEncControls *encoderControl)
2599 {
2600     PV_STATUS status = PV_SUCCESS;
2601     VideoEncData *video = (VideoEncData *)encoderControl->videoEncoderData;
2602     Vol         *currVol = video->vol[video->currLayer];
2603     BitstreamEncVideo *stream = currVol->stream;
2604 
2605 
2606     status = BitstreamPutBits(stream, SESSION_END_CODE, 32);
2607 
2608     return status;
2609 }
2610 
2611 /* ======================================================================== */
2612 /*  Function : DetermineCodingLayer                                         */
2613 /*  Date     : 06/02/2001                                                   */
2614 /*  Purpose  : Find layer to code based on current mod time, assuming that
2615                it's time to encode enhanced layer.                          */
2616 /*  In/out   :                                                              */
2617 /*  Return   : Number of layer to code.                                     */
2618 /*  Modified :                                                              */
2619 /*                                                                          */
2620 /* ======================================================================== */
2621 
DetermineCodingLayer(VideoEncData * video,Int * nLayer,ULong modTime)2622 Int DetermineCodingLayer(VideoEncData *video, Int *nLayer, ULong modTime)
2623 {
2624     Vol **vol = video->vol;
2625     VideoEncParams *encParams = video->encParams;
2626     Int numLayers = encParams->nLayers;
2627     UInt modTimeRef = video->modTimeRef;
2628     float *LayerFrameRate = encParams->LayerFrameRate;
2629     UInt frameNum[4], frameTick;
2630     ULong frameModTime, nextFrmModTime;
2631 #ifdef REDUCE_FRAME_VARIANCE    /* To limit how close 2 frames can be */
2632     float frameInterval;
2633 #endif
2634     float srcFrameInterval;
2635     Int frameInc;
2636     Int i, extra_skip;
2637     Int encodeVop = 0;
2638 
2639     i = numLayers - 1;
2640 
2641     if (modTime - video->nextModTime > ((ULong)(-1)) >> 1) /* next time wrapped around */
2642         return 0; /* not time to code it yet */
2643 
2644     video->relLayerCodeTime[i] -= 1000;
2645     video->nextEncIVop--;  /* number of Vops in highest layer resolution. */
2646     video->numVopsInGOP++;
2647 
2648     /* from this point frameModTime and nextFrmModTime are internal */
2649 
2650     frameNum[i] = (UInt)((modTime - modTimeRef) * LayerFrameRate[i] + 500) / 1000;
2651     if (video->volInitialize[i])
2652     {
2653         video->prevFrameNum[i] = frameNum[i] - 1;
2654     }
2655     else if (frameNum[i] <= video->prevFrameNum[i])
2656     {
2657         return 0; /* do not encode this frame */
2658     }
2659 
2660     /**** this part computes expected next frame *******/
2661     frameModTime = (ULong)(((frameNum[i] * 1000) / LayerFrameRate[i]) + modTimeRef + 0.5); /* rec. time */
2662     nextFrmModTime = (ULong)((((frameNum[i] + 1) * 1000) / LayerFrameRate[i]) + modTimeRef + 0.5); /* rec. time */
2663 
2664     srcFrameInterval = 1000 / video->FrameRate;
2665 
2666     video->nextModTime = nextFrmModTime - (ULong)(srcFrameInterval / 2.) - 1; /* between current and next frame */
2667 
2668 #ifdef REDUCE_FRAME_VARIANCE    /* To limit how close 2 frames can be */
2669     frameInterval = 1000 / LayerFrameRate[i]; /* next rec. time */
2670     delta = (Int)(frameInterval / 4); /* empirical number */
2671     if (video->nextModTime - modTime  < (ULong)delta) /* need to move nextModTime further. */
2672     {
2673         video->nextModTime += ((delta - video->nextModTime + modTime)); /* empirical formula  */
2674     }
2675 #endif
2676     /****************************************************/
2677 
2678     /* map frame no.to tick from modTimeRef */
2679     /*frameTick = (frameNum[i]*vol[i]->timeIncrementResolution) ;
2680     frameTick = (UInt)((frameTick + (encParams->LayerFrameRate[i]/2))/encParams->LayerFrameRate[i]);*/
2681     /*  11/16/01, change frameTick to be the closest tick from the actual modTime */
2682     /*  12/12/02, add (double) to prevent large number wrap-around */
2683     frameTick = (Int)(((double)(modTime - modTimeRef) * vol[i]->timeIncrementResolution + 500) / 1000);
2684 
2685     /* find timeIncrement to be put in the bitstream */
2686     /* refTick is second boundary reference. */
2687     vol[i]->timeIncrement = frameTick - video->refTick[i];
2688 
2689 
2690     vol[i]->moduloTimeBase = 0;
2691     while (vol[i]->timeIncrement >= vol[i]->timeIncrementResolution)
2692     {
2693         vol[i]->timeIncrement -= vol[i]->timeIncrementResolution;
2694         vol[i]->moduloTimeBase++;
2695         /* do not update refTick and modTimeRef yet, do it after encoding!! */
2696     }
2697 
2698     if (video->relLayerCodeTime[i] <= 0)    /* no skipping */
2699     {
2700         encodeVop = 1;
2701         video->currLayer = *nLayer = i;
2702         video->relLayerCodeTime[i] += 1000;
2703 
2704         /* takes care of more dropped frame than expected */
2705         extra_skip = -1;
2706         frameInc = (frameNum[i] - video->prevFrameNum[i]);
2707         extra_skip += frameInc;
2708 
2709         if (extra_skip > 0)
2710         {   /* update rc->Nr, rc->B, (rc->Rr)*/
2711             video->nextEncIVop -= extra_skip;
2712             video->numVopsInGOP += extra_skip;
2713             if (encParams->RC_Type != CONSTANT_Q)
2714             {
2715                 RC_UpdateBuffer(video, i, extra_skip);
2716             }
2717         }
2718 
2719     }
2720     /* update frame no. */
2721     video->prevFrameNum[i] = frameNum[i];
2722 
2723     /* go through all lower layer */
2724     for (i = (numLayers - 2); i >= 0; i--)
2725     {
2726 
2727         video->relLayerCodeTime[i] -= 1000;
2728 
2729         /* find timeIncrement to be put in the bitstream */
2730         vol[i]->timeIncrement = frameTick - video->refTick[i];
2731 
2732         if (video->relLayerCodeTime[i] <= 0) /* time to encode base */
2733         {
2734             /* 12/27/00 */
2735             encodeVop = 1;
2736             video->currLayer = *nLayer = i;
2737             video->relLayerCodeTime[i] +=
2738                 (Int)((1000.0 * encParams->LayerFrameRate[numLayers-1]) / encParams->LayerFrameRate[i]);
2739 
2740             vol[i]->moduloTimeBase = 0;
2741             while (vol[i]->timeIncrement >= vol[i]->timeIncrementResolution)
2742             {
2743                 vol[i]->timeIncrement -= vol[i]->timeIncrementResolution;
2744                 vol[i]->moduloTimeBase++;
2745                 /* do not update refTick and modTimeRef yet, do it after encoding!! */
2746             }
2747 
2748             /* takes care of more dropped frame than expected */
2749             frameNum[i] = (UInt)((frameModTime - modTimeRef) * encParams->LayerFrameRate[i] + 500) / 1000;
2750             if (video->volInitialize[i])
2751                 video->prevFrameNum[i] = frameNum[i] - 1;
2752 
2753             extra_skip = -1;
2754             frameInc = (frameNum[i] - video->prevFrameNum[i]);
2755             extra_skip += frameInc;
2756 
2757             if (extra_skip > 0)
2758             {   /* update rc->Nr, rc->B, (rc->Rr)*/
2759                 if (encParams->RC_Type != CONSTANT_Q)
2760                 {
2761                     RC_UpdateBuffer(video, i, extra_skip);
2762                 }
2763             }
2764             /* update frame no. */
2765             video->prevFrameNum[i] = frameNum[i];
2766         }
2767     }
2768 
2769 #ifdef _PRINT_STAT
2770     if (encodeVop)
2771         printf(" TI: %d ", vol[*nLayer]->timeIncrement);
2772 #endif
2773 
2774     return encodeVop;
2775 }
2776 
2777 /* ======================================================================== */
2778 /*  Function : DetermineVopType                                             */
2779 /*  Date     : 06/02/2001                                                   */
2780 /*  Purpose  : The name says it all.                                        */
2781 /*  In/out   :                                                              */
2782 /*  Return   : void .                                                       */
2783 /*  Modified :                                                              */
2784 /*                                                                          */
2785 /* ======================================================================== */
2786 
DetermineVopType(VideoEncData * video,Int currLayer)2787 void DetermineVopType(VideoEncData *video, Int currLayer)
2788 {
2789     VideoEncParams *encParams = video->encParams;
2790 //  Vol *currVol = video->vol[currLayer];
2791 
2792     if (encParams->IntraPeriod == 0) /* I-VOPs only */
2793     {
2794         if (video->currLayer > 0)
2795             video->currVop->predictionType = P_VOP;
2796         else
2797         {
2798             video->currVop->predictionType = I_VOP;
2799             if (video->numVopsInGOP >= 132)
2800                 video->numVopsInGOP = 0;
2801         }
2802     }
2803     else if (encParams->IntraPeriod == -1)  /* IPPPPP... */
2804     {
2805 
2806         /* maintain frame type if previous frame is pre-skipped, 06/02/2001 */
2807         if (encParams->RC_Type == CONSTANT_Q || video->rc[currLayer]->skip_next_frame != -1)
2808             video->currVop->predictionType = P_VOP;
2809 
2810         if (video->currLayer == 0)
2811         {
2812             if (/*video->numVopsInGOP>=132 || */video->volInitialize[currLayer])
2813             {
2814                 video->currVop->predictionType = I_VOP;
2815                 video->numVopsInGOP = 0; /* force INTRA update every 132 base frames*/
2816                 video->nextEncIVop = 1;
2817             }
2818             else if (video->nextEncIVop == 0 || video->currVop->predictionType == I_VOP)
2819             {
2820                 video->numVopsInGOP = 0;
2821                 video->nextEncIVop = 1;
2822             }
2823         }
2824     }
2825     else   /* IntraPeriod>0 : IPPPPPIPPPPPI... */
2826     {
2827 
2828         /* maintain frame type if previous frame is pre-skipped, 06/02/2001 */
2829         if (encParams->RC_Type == CONSTANT_Q || video->rc[currLayer]->skip_next_frame != -1)
2830             video->currVop->predictionType = P_VOP;
2831 
2832         if (currLayer == 0)
2833         {
2834             if (video->nextEncIVop <= 0 || video->currVop->predictionType == I_VOP)
2835             {
2836                 video->nextEncIVop = encParams->IntraPeriod;
2837                 video->currVop->predictionType = I_VOP;
2838                 video->numVopsInGOP = 0;
2839             }
2840         }
2841     }
2842 
2843     return ;
2844 }
2845 
2846 /* ======================================================================== */
2847 /*  Function : UpdateSkipNextFrame                                          */
2848 /*  Date     : 06/02/2001                                                   */
2849 /*  Purpose  : From rate control frame skipping decision, update timing
2850                 related parameters.                                         */
2851 /*  In/out   :                                                              */
2852 /*  Return   : Current coded layer.                                         */
2853 /*  Modified :                                                              */
2854 /*                                                                          */
2855 /* ======================================================================== */
2856 
UpdateSkipNextFrame(VideoEncData * video,ULong * modTime,Int * size,PV_STATUS status)2857 Int UpdateSkipNextFrame(VideoEncData *video, ULong *modTime, Int *size, PV_STATUS status)
2858 {
2859     Int currLayer = video->currLayer;
2860     Int nLayer = currLayer;
2861     VideoEncParams *encParams = video->encParams;
2862     Int numLayers = encParams->nLayers;
2863     Vol *currVol = video->vol[currLayer];
2864     Vol **vol = video->vol;
2865     Int num_skip, extra_skip;
2866     Int i;
2867     UInt newRefTick, deltaModTime;
2868     UInt temp;
2869 
2870     if (encParams->RC_Type != CONSTANT_Q)
2871     {
2872         if (video->volInitialize[0] && currLayer == 0)  /* always encode the first frame */
2873         {
2874             RC_ResetSkipNextFrame(video, currLayer);
2875             //return currLayer;  09/15/05
2876         }
2877         else
2878         {
2879             if (RC_GetSkipNextFrame(video, currLayer) < 0 || status == PV_END_OF_BUF)   /* Skip Current Frame */
2880             {
2881 
2882 #ifdef _PRINT_STAT
2883                 printf("Skip current frame");
2884 #endif
2885                 currVol->moduloTimeBase = currVol->prevModuloTimeBase;
2886 
2887                 /*********************/
2888                 /* prepare to return */
2889                 /*********************/
2890                 *size = 0;  /* Set Bitstream buffer to zero */
2891 
2892                 /* Determine nLayer and modTime for next encode */
2893 
2894                 *modTime = video->nextModTime;
2895                 nLayer = -1;
2896 
2897                 return nLayer; /* return immediately without updating RefTick & modTimeRef */
2898                 /* If I-VOP was attempted, then ensure next base is I-VOP */
2899                 /*if((encParams->IntraPeriod>0) && (video->currVop->predictionType == I_VOP))
2900                 video->nextEncIVop = 0; commented out by 06/05/01 */
2901 
2902             }
2903             else if ((num_skip = RC_GetSkipNextFrame(video, currLayer)) > 0)
2904             {
2905 
2906 #ifdef _PRINT_STAT
2907                 printf("Skip next %d frames", num_skip);
2908 #endif
2909                 /* to keep the Nr of enh layer the same */
2910                 /* adjust relLayerCodeTime only, do not adjust layerCodeTime[numLayers-1] */
2911                 extra_skip = 0;
2912                 for (i = 0; i < currLayer; i++)
2913                 {
2914                     if (video->relLayerCodeTime[i] <= 1000)
2915                     {
2916                         extra_skip = 1;
2917                         break;
2918                     }
2919                 }
2920 
2921                 for (i = currLayer; i < numLayers; i++)
2922                 {
2923                     video->relLayerCodeTime[i] += (num_skip + extra_skip) *
2924                                                   ((Int)((1000.0 * encParams->LayerFrameRate[numLayers-1]) / encParams->LayerFrameRate[i]));
2925                 }
2926             }
2927         }/* first frame */
2928     }
2929     /*****  current frame is encoded, now update refTick ******/
2930 
2931     video->refTick[currLayer] += vol[currLayer]->prevModuloTimeBase * vol[currLayer]->timeIncrementResolution;
2932 
2933     /* Reset layerCodeTime every I-VOP to prevent overflow */
2934     if (currLayer == 0)
2935     {
2936         /*  12/12/02, fix for weird targer frame rate of 9.99 fps or 3.33 fps */
2937         if (((encParams->IntraPeriod != 0) /*&& (video->currVop->predictionType==I_VOP)*/) ||
2938                 ((encParams->IntraPeriod == 0) && (video->numVopsInGOP == 0)))
2939         {
2940             newRefTick = video->refTick[0];
2941 
2942             for (i = 1; i < numLayers; i++)
2943             {
2944                 if (video->refTick[i] < newRefTick)
2945                     newRefTick = video->refTick[i];
2946             }
2947 
2948             /* check to make sure that the update is integer multiple of frame number */
2949             /* how many msec elapsed from last modTimeRef */
2950             deltaModTime = (newRefTick / vol[0]->timeIncrementResolution) * 1000;
2951 
2952             for (i = numLayers - 1; i >= 0; i--)
2953             {
2954                 temp = (UInt)(deltaModTime * encParams->LayerFrameRate[i]); /* 12/12/02 */
2955                 if (temp % 1000)
2956                     newRefTick = 0;
2957 
2958             }
2959             if (newRefTick > 0)
2960             {
2961                 video->modTimeRef += deltaModTime;
2962                 for (i = numLayers - 1; i >= 0; i--)
2963                 {
2964                     video->prevFrameNum[i] -= (UInt)(deltaModTime * encParams->LayerFrameRate[i]) / 1000;
2965                     video->refTick[i] -= newRefTick;
2966                 }
2967             }
2968         }
2969     }
2970 
2971     *modTime =  video->nextModTime;
2972 
2973     return nLayer;
2974 }
2975 
2976 
2977 #ifndef ORIGINAL_VERSION
2978 
2979 /* ======================================================================== */
2980 /*  Function : SetProfile_BufferSize                                        */
2981 /*  Date     : 04/08/2002                                                   */
2982 /*  Purpose  : Set profile and video buffer size, copied from Jim's code    */
2983 /*             in PVInitVideoEncoder(.), since we have different places     */
2984 /*             to reset profile and video buffer size                       */
2985 /*  In/out   :                                                              */
2986 /*  Return   :                                                              */
2987 /*  Modified :                                                              */
2988 /*                                                                          */
2989 /* ======================================================================== */
2990 
SetProfile_BufferSize(VideoEncData * video,float delay,Int bInitialized)2991 Bool SetProfile_BufferSize(VideoEncData *video, float delay, Int bInitialized)
2992 {
2993     Int i, j, start, end;
2994 //  Int BaseMBsPerSec = 0, EnhMBsPerSec = 0;
2995     Int nTotalMB = 0;
2996     Int idx, temp_w, temp_h, max = 0, max_width, max_height;
2997 
2998     Int nLayers = video->encParams->nLayers; /* Number of Layers to be encoded */
2999 
3000     Int total_bitrate = 0, base_bitrate;
3001     Int total_packet_size = 0, base_packet_size;
3002     Int total_MBsPerSec = 0, base_MBsPerSec;
3003     Int total_VBV_size = 0, base_VBV_size, enhance_VBV_size = 0;
3004     float total_framerate, base_framerate;
3005     float upper_bound_ratio;
3006     Int bFound = 0;
3007     Int k = 0, width16, height16, index;
3008     Int lowest_level;
3009 
3010 #define MIN_BUFF    16000 /* 16k minimum buffer size */
3011 #define BUFF_CONST  2.0    /* 2000ms */
3012 #define UPPER_BOUND_RATIO 8.54 /* upper_bound = 1.4*(1.1+bound/10)*bitrate/framerate */
3013 
3014 #define QCIF_WIDTH  176
3015 #define QCIF_HEIGHT 144
3016 
3017     index = video->encParams->profile_table_index;
3018 
3019     /* Calculate "nTotalMB" */
3020     /* Find the maximum width*height for memory allocation of the VOPs */
3021     for (idx = 0; idx < nLayers; idx++)
3022     {
3023         temp_w = video->encParams->LayerWidth[idx];
3024         temp_h = video->encParams->LayerHeight[idx];
3025 
3026         if ((temp_w*temp_h) > max)
3027         {
3028             max = temp_w * temp_h;
3029             max_width = temp_w;
3030             max_height = temp_h;
3031             nTotalMB = ((max_width + 15) >> 4) * ((max_height + 15) >> 4);
3032         }
3033     }
3034     upper_bound_ratio = (video->encParams->RC_Type == CBR_LOWDELAY ? (float)5.0 : (float)UPPER_BOUND_RATIO);
3035 
3036 
3037     /* Get the basic information: bitrate, packet_size, MBs/s and VBV_size */
3038     base_bitrate        = video->encParams->LayerBitRate[0];
3039     if (video->encParams->LayerMaxBitRate[0] != 0) /* video->encParams->LayerMaxBitRate[0] == 0 means it has not been set */
3040     {
3041         base_bitrate    = PV_MAX(base_bitrate, video->encParams->LayerMaxBitRate[0]);
3042     }
3043     else /* if the max is not set, set it to the specified profile/level */
3044     {
3045         video->encParams->LayerMaxBitRate[0] = profile_level_max_bitrate[index];
3046     }
3047 
3048     base_framerate      = video->encParams->LayerFrameRate[0];
3049     if (video->encParams->LayerMaxFrameRate[0] != 0)
3050     {
3051         base_framerate  = PV_MAX(base_framerate, video->encParams->LayerMaxFrameRate[0]);
3052     }
3053     else /* if the max is not set, set it to the specified profile/level */
3054     {
3055         video->encParams->LayerMaxFrameRate[0] = (float)profile_level_max_mbsPerSec[index] / nTotalMB;
3056     }
3057 
3058     base_packet_size    = video->encParams->ResyncPacketsize;
3059     base_MBsPerSec      = (Int)(base_framerate * nTotalMB);
3060     base_VBV_size       = PV_MAX((Int)(base_bitrate * delay),
3061                                  (Int)(upper_bound_ratio * base_bitrate / base_framerate));
3062     base_VBV_size       = PV_MAX(base_VBV_size, MIN_BUFF);
3063 
3064     /* if the buffer is larger than maximum buffer size, we'll clip it */
3065     if (base_VBV_size > profile_level_max_VBV_size[5])
3066         base_VBV_size = profile_level_max_VBV_size[5];
3067 
3068 
3069     /* Check if the buffer exceeds the maximum buffer size given the maximum profile and level */
3070     if (nLayers == 1 && base_VBV_size > profile_level_max_VBV_size[index])
3071         return FALSE;
3072 
3073 
3074     if (nLayers == 2)
3075     {
3076         total_bitrate       = video->encParams->LayerBitRate[1];
3077         if (video->encParams->LayerMaxBitRate[1] != 0)
3078         {
3079             total_bitrate   = PV_MIN(total_bitrate, video->encParams->LayerMaxBitRate[1]);
3080         }
3081         else /* if the max is not set, set it to the specified profile/level */
3082         {
3083             video->encParams->LayerMaxBitRate[1] = scalable_profile_level_max_bitrate[index];
3084         }
3085 
3086         total_framerate     = video->encParams->LayerFrameRate[1];
3087         if (video->encParams->LayerMaxFrameRate[1] != 0)
3088         {
3089             total_framerate     = PV_MIN(total_framerate, video->encParams->LayerMaxFrameRate[1]);
3090         }
3091         else /* if the max is not set, set it to the specified profile/level */
3092         {
3093             video->encParams->LayerMaxFrameRate[1] = (float)scalable_profile_level_max_mbsPerSec[index] / nTotalMB;
3094         }
3095 
3096         total_packet_size   = video->encParams->ResyncPacketsize;
3097         total_MBsPerSec     = (Int)(total_framerate * nTotalMB);
3098 
3099         enhance_VBV_size    = PV_MAX((Int)((total_bitrate - base_bitrate) * delay),
3100                                      (Int)(upper_bound_ratio * (total_bitrate - base_bitrate) / (total_framerate - base_framerate)));
3101         enhance_VBV_size    = PV_MAX(enhance_VBV_size, MIN_BUFF);
3102 
3103         total_VBV_size      = base_VBV_size + enhance_VBV_size;
3104 
3105         /* if the buffer is larger than maximum buffer size, we'll clip it */
3106         if (total_VBV_size > scalable_profile_level_max_VBV_size[6])
3107         {
3108             total_VBV_size = scalable_profile_level_max_VBV_size[6];
3109             enhance_VBV_size = total_VBV_size - base_VBV_size;
3110         }
3111 
3112         /* Check if the buffer exceeds the maximum buffer size given the maximum profile and level */
3113         if (total_VBV_size > scalable_profile_level_max_VBV_size[index])
3114             return FALSE;
3115     }
3116 
3117 
3118     if (!bInitialized) /* Has been initialized --> profile @ level has been figured out! */
3119     {
3120         video->encParams->BufferSize[0] = base_VBV_size;
3121         if (nLayers > 1)
3122             video->encParams->BufferSize[1] = enhance_VBV_size;
3123 
3124         return PV_TRUE;
3125     }
3126 
3127 
3128     /* Profile @ level determination */
3129     if (nLayers == 1)
3130     {
3131         /* BASE ONLY : Simple Profile(SP) Or Core Profile(CP) */
3132         if (base_bitrate     > profile_level_max_bitrate[index]     ||
3133                 base_packet_size > profile_level_max_packet_size[index] ||
3134                 base_MBsPerSec   > profile_level_max_mbsPerSec[index]   ||
3135                 base_VBV_size    > profile_level_max_VBV_size[index])
3136 
3137             return PV_FALSE; /* Beyond the bound of Core Profile @ Level2 */
3138 
3139         /* For H263/Short header, determine k*16384 */
3140         width16  = ((video->encParams->LayerWidth[0] + 15) >> 4) << 4;
3141         height16 = ((video->encParams->LayerHeight[0] + 15) >> 4) << 4;
3142         if (video->encParams->H263_Enabled)
3143         {
3144             k = 4;
3145             if (width16  == 2*QCIF_WIDTH && height16 == 2*QCIF_HEIGHT)  /* CIF */
3146                 k = 16;
3147 
3148             else if (width16  == 4*QCIF_WIDTH && height16 == 4*QCIF_HEIGHT)  /* 4CIF */
3149                 k = 32;
3150 
3151             else if (width16  == 8*QCIF_WIDTH && height16 == 8*QCIF_HEIGHT)  /* 16CIF */
3152                 k = 64;
3153 
3154             video->encParams->maxFrameSize  = k * 16384;
3155 
3156             /* Make sure the buffer size is limited to the top profile and level: the Core profile and level 2 */
3157             if (base_VBV_size > (Int)(k*16384 + 4*(float)profile_level_max_bitrate[5]*1001.0 / 30000.0))
3158                 base_VBV_size = (Int)(k * 16384 + 4 * (float)profile_level_max_bitrate[5] * 1001.0 / 30000.0);
3159 
3160             if (base_VBV_size > (Int)(k*16384 + 4*(float)profile_level_max_bitrate[index]*1001.0 / 30000.0))
3161                 return PV_FALSE;
3162         }
3163 
3164         /* Search the appropriate profile@level index */
3165         if (!video->encParams->H263_Enabled &&
3166                 (video->encParams->IntraDCVlcThr != 0 || video->encParams->SearchRange > 16))
3167         {
3168             lowest_level = 1; /* cannot allow SPL0 */
3169         }
3170         else
3171         {
3172             lowest_level = 0; /* SPL0 */
3173         }
3174 
3175         for (i = lowest_level; i <= index; i++)
3176         {
3177             if (i != 4 && /* skip Core Profile@Level1 because the parameters in it are smaller than those in Simple Profile@Level3 */
3178                     base_bitrate     <= profile_level_max_bitrate[i]     &&
3179                     base_packet_size <= profile_level_max_packet_size[i] &&
3180                     base_MBsPerSec   <= profile_level_max_mbsPerSec[i]   &&
3181                     base_VBV_size    <= (video->encParams->H263_Enabled ? (Int)(k*16384 + 4*(float)profile_level_max_bitrate[i]*1001.0 / 30000.0) :
3182                                          profile_level_max_VBV_size[i]))
3183                 break;
3184         }
3185         if (i > index) return PV_FALSE; /* Nothing found!! */
3186 
3187         /* Found out the actual profile @ level : index "i" */
3188         if (i == 0)
3189         {
3190             /* For Simple Profile @ Level 0, we need to do one more check: image size <= QCIF */
3191             if (width16 > QCIF_WIDTH || height16 > QCIF_HEIGHT)
3192                 i = 1; /* image size > QCIF, then set SP level1 */
3193         }
3194 
3195         video->encParams->ProfileLevel[0] = profile_level_code[i];
3196         video->encParams->BufferSize[0]   = base_VBV_size;
3197 
3198         if (video->encParams->LayerMaxBitRate[0] == 0)
3199             video->encParams->LayerMaxBitRate[0] = profile_level_max_bitrate[i];
3200 
3201         if (video->encParams->LayerMaxFrameRate[0] == 0)
3202             video->encParams->LayerMaxFrameRate[0] = PV_MIN(30, (float)profile_level_max_mbsPerSec[i] / nTotalMB);
3203 
3204         /* For H263/Short header, one special constraint for VBV buffer size */
3205         if (video->encParams->H263_Enabled)
3206             video->encParams->BufferSize[0] = (Int)(k * 16384 + 4 * (float)profile_level_max_bitrate[i] * 1001.0 / 30000.0);
3207 
3208     }
3209     else
3210     {
3211         /* SCALABALE MODE: Simple Scalable Profile(SSP) Or Core Scalable Profile(CSP) */
3212 
3213         if (total_bitrate       > scalable_profile_level_max_bitrate[index]     ||
3214                 total_packet_size   > scalable_profile_level_max_packet_size[index] ||
3215                 total_MBsPerSec     > scalable_profile_level_max_mbsPerSec[index]   ||
3216                 total_VBV_size      > scalable_profile_level_max_VBV_size[index])
3217 
3218             return PV_FALSE; /* Beyond given profile and level */
3219 
3220         /* One-time check: Simple Scalable Profile or Core Scalable Profile */
3221         if (total_bitrate       <= scalable_profile_level_max_bitrate[2]        &&
3222                 total_packet_size   <= scalable_profile_level_max_packet_size[2]    &&
3223                 total_MBsPerSec     <= scalable_profile_level_max_mbsPerSec[2]      &&
3224                 total_VBV_size      <= scalable_profile_level_max_VBV_size[2])
3225 
3226         {
3227             start = 0;
3228             end = index;
3229         }
3230 
3231         else
3232         {
3233             start = 4;
3234             end = index;
3235         }
3236 
3237 
3238         /* Search the scalable profile */
3239         for (i = start; i <= end; i++)
3240         {
3241             if (total_bitrate       <= scalable_profile_level_max_bitrate[i]     &&
3242                     total_packet_size   <= scalable_profile_level_max_packet_size[i] &&
3243                     total_MBsPerSec     <= scalable_profile_level_max_mbsPerSec[i]   &&
3244                     total_VBV_size      <= scalable_profile_level_max_VBV_size[i])
3245 
3246                 break;
3247         }
3248         if (i > end) return PV_FALSE;
3249 
3250         /* Search the base profile */
3251         if (i == 0)
3252         {
3253             j = 0;
3254             bFound = 1;
3255         }
3256         else        bFound = 0;
3257 
3258         for (j = start; !bFound && j <= i; j++)
3259         {
3260             if (base_bitrate        <= profile_level_max_bitrate[j]      &&
3261                     base_packet_size    <= profile_level_max_packet_size[j]  &&
3262                     base_MBsPerSec      <= profile_level_max_mbsPerSec[j]    &&
3263                     base_VBV_size       <= profile_level_max_VBV_size[j])
3264 
3265             {
3266                 bFound = 1;
3267                 break;
3268             }
3269         }
3270 
3271         if (!bFound) // && start == 4)
3272             return PV_FALSE; /* mis-match in the profiles between base layer and enhancement layer */
3273 
3274         /* j for base layer, i for enhancement layer */
3275         video->encParams->ProfileLevel[0] = profile_level_code[j];
3276         video->encParams->ProfileLevel[1] = scalable_profile_level_code[i];
3277         video->encParams->BufferSize[0]   = base_VBV_size;
3278         video->encParams->BufferSize[1]   = enhance_VBV_size;
3279 
3280         if (video->encParams->LayerMaxBitRate[0] == 0)
3281             video->encParams->LayerMaxBitRate[0] = profile_level_max_bitrate[j];
3282 
3283         if (video->encParams->LayerMaxBitRate[1] == 0)
3284             video->encParams->LayerMaxBitRate[1] = scalable_profile_level_max_bitrate[i];
3285 
3286         if (video->encParams->LayerMaxFrameRate[0] == 0)
3287             video->encParams->LayerMaxFrameRate[0] = PV_MIN(30, (float)profile_level_max_mbsPerSec[j] / nTotalMB);
3288 
3289         if (video->encParams->LayerMaxFrameRate[1] == 0)
3290             video->encParams->LayerMaxFrameRate[1] = PV_MIN(30, (float)scalable_profile_level_max_mbsPerSec[i] / nTotalMB);
3291 
3292 
3293     } /* end of: if(nLayers == 1) */
3294 
3295 
3296     if (!video->encParams->H263_Enabled && (video->encParams->ProfileLevel[0] == 0x08)) /* SPL0 restriction*/
3297     {
3298         /* PV only allow frame-based rate control, no QP change from one MB to another
3299         if(video->encParams->ACDCPrediction == TRUE && MB-based rate control)
3300          return PV_FALSE */
3301     }
3302 
3303     return PV_TRUE;
3304 }
3305 
3306 #endif /* #ifndef ORIGINAL_VERSION */
3307