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