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