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