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