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