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