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