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