[go: nahoru, domu]

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