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->allChan = 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->allChan = 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->allChan = 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->allChan = 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->allChan)
   1200             {
   1201                 M4VENC_FREE(video->currVop->allChan);
   1202             }
   1203             M4VENC_FREE(video->currVop);
   1204         }
   1205 
   1206         if (video->nextBaseVop)
   1207         {
   1208             if (video->nextBaseVop->allChan)
   1209             {
   1210                 M4VENC_FREE(video->nextBaseVop->allChan);
   1211             }
   1212             M4VENC_FREE(video->nextBaseVop);
   1213         }
   1214 
   1215         if (video->prevBaseVop)
   1216         {
   1217             if (video->prevBaseVop->allChan)
   1218             {
   1219                 M4VENC_FREE(video->prevBaseVop->allChan);
   1220             }
   1221             M4VENC_FREE(video->prevBaseVop);
   1222         }
   1223         if (video->prevEnhanceVop)
   1224         {
   1225             if (video->prevEnhanceVop->allChan)
   1226             {
   1227                 M4VENC_FREE(video->prevEnhanceVop->allChan);
   1228             }
   1229             M4VENC_FREE(video->prevEnhanceVop);
   1230         }
   1231 
   1232         /* 04/09/01, for Vops in the use multipass processing */
   1233         for (idx = 0; idx < video->encParams->nLayers; idx++)
   1234         {
   1235             if (video->pMP[idx])
   1236             {
   1237                 if (video->pMP[idx]->pRDSamples)
   1238                 {
   1239                     for (i = 0; i < 30; i++)
   1240                     {
   1241                         if (video->pMP[idx]->pRDSamples[i])
   1242                             M4VENC_FREE(video->pMP[idx]->pRDSamples[i]);
   1243                     }
   1244                     M4VENC_FREE(video->pMP[idx]->pRDSamples);
   1245                 }
   1246 
   1247                 M4VENC_MEMSET(video->pMP[idx], 0, sizeof(MultiPass));
   1248                 M4VENC_FREE(video->pMP[idx]);
   1249             }
   1250         }
   1251         /* //  End /////////////////////////////////////// */
   1252 
   1253         if (video->vol)
   1254         {
   1255             for (idx = 0; idx < video->encParams->nLayers; idx++)
   1256             {
   1257                 if (video->vol[idx])
   1258                 {
   1259                     if (video->vol[idx]->stream)
   1260                         M4VENC_FREE(video->vol[idx]->stream);
   1261                     M4VENC_FREE(video->vol[idx]);
   1262                 }
   1263             }
   1264             M4VENC_FREE(video->vol);
   1265         }
   1266 
   1267         /***************************************************/
   1268         /* stop rate control parameters */
   1269         /***************************************************/
   1270 
   1271         /* ANNEX L RATE CONTROL */
   1272         if (video->encParams->RC_Type != CONSTANT_Q)
   1273         {
   1274             RC_Cleanup(video->rc, video->encParams->nLayers);
   1275 
   1276             for (idx = 0; idx < video->encParams->nLayers; idx++)
   1277             {
   1278                 if (video->rc[idx])
   1279                     M4VENC_FREE(video->rc[idx]);
   1280             }
   1281         }
   1282 
   1283         if (video->functionPointer) M4VENC_FREE(video->functionPointer);
   1284 
   1285         /* If application has called PVCleanUpVideoEncoder then we deallocate */
   1286         /* If PVInitVideoEncoder class it, then we DO NOT deallocate */
   1287         if (video->encParams)
   1288         {
   1289             M4VENC_FREE(video->encParams);
   1290         }
   1291 
   1292         M4VENC_FREE(video);
   1293         encoderControl->videoEncoderData = NULL; /* video */
   1294     }
   1295 
   1296     encoderControl->videoEncoderInit = 0;
   1297 
   1298     return PV_TRUE;
   1299 }
   1300 
   1301 /* ======================================================================== */
   1302 /*  Function : PVGetVolHeader()                                             */
   1303 /*  Date     : 7/17/2001,                                                   */
   1304 /*  Purpose  :                                                              */
   1305 /*  In/out   :                                                              */
   1306 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
   1307 /*  Modified :                                                              */
   1308 /*                                                                          */
   1309 /* ======================================================================== */
   1310 
   1311 OSCL_EXPORT_REF Bool PVGetVolHeader(VideoEncControls *encCtrl, UChar *volHeader, Int *size, Int layer)
   1312 {
   1313     VideoEncData    *encData;
   1314     PV_STATUS   EncodeVOS_Start(VideoEncControls *encCtrl);
   1315     encData = (VideoEncData *)encCtrl->videoEncoderData;
   1316 
   1317 
   1318     if (encData == NULL)
   1319         return PV_FALSE;
   1320     if (encData->encParams == NULL)
   1321         return PV_FALSE;
   1322 
   1323 
   1324     encData->currLayer = layer; /* Set Layer */
   1325     /*pv_status = */
   1326     EncodeVOS_Start(encCtrl); /* Encode VOL Header */
   1327 
   1328     encData->encParams->GetVolHeader[layer] = 1; /* Set usage flag: Needed to support old method*/
   1329 
   1330     /* Copy bitstream to buffer and set the size */
   1331 
   1332     if (*size > encData->bitstream1->byteCount)
   1333     {
   1334         *size = encData->bitstream1->byteCount;
   1335         M4VENC_MEMCPY(volHeader, encData->bitstream1->bitstreamBuffer, *size);
   1336     }
   1337     else
   1338         return PV_FALSE;
   1339 
   1340     /* Reset bitstream1 buffer parameters */
   1341     BitstreamEncReset(encData->bitstream1);
   1342 
   1343     return PV_TRUE;
   1344 }
   1345 
   1346 /* ======================================================================== */
   1347 /*  Function : PVGetOverrunBuffer()                                         */
   1348 /*  Purpose  : Get the overrun buffer `                                     */
   1349 /*  In/out   :                                                              */
   1350 /*  Return   : Pointer to overrun buffer.                                   */
   1351 /*  Modified :                                                              */
   1352 /* ======================================================================== */
   1353 
   1354 OSCL_EXPORT_REF UChar* PVGetOverrunBuffer(VideoEncControls *encCtrl)
   1355 {
   1356     VideoEncData *video = (VideoEncData *)encCtrl->videoEncoderData;
   1357     Int currLayer = video->currLayer;
   1358     Vol *currVol = video->vol[currLayer];
   1359 
   1360     if (currVol->stream->bitstreamBuffer != video->overrunBuffer) // not used
   1361     {
   1362         return NULL;
   1363     }
   1364 
   1365     return video->overrunBuffer;
   1366 }
   1367 
   1368 
   1369 
   1370 
   1371 /* ======================================================================== */
   1372 /*  Function : EncodeVideoFrame()                                           */
   1373 /*  Date     : 08/22/2000                                                   */
   1374 /*  Purpose  : Encode video frame and return bitstream                      */
   1375 /*  In/out   :                                                              */
   1376 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
   1377 /*  Modified :                                                              */
   1378 /*  02.14.2001                                      */
   1379 /*              Finishing new timestamp 32-bit input                        */
   1380 /*              Applications need to take care of wrap-around               */
   1381 /* ======================================================================== */
   1382 OSCL_EXPORT_REF Bool PVEncodeVideoFrame(VideoEncControls *encCtrl, VideoEncFrameIO *vid_in, VideoEncFrameIO *vid_out,
   1383                                         ULong *nextModTime, UChar *bstream, Int *size, Int *nLayer)
   1384 {
   1385     Bool status = PV_TRUE;
   1386     PV_STATUS pv_status;
   1387     VideoEncData *video = (VideoEncData *)encCtrl->videoEncoderData;
   1388     VideoEncParams *encParams = video->encParams;
   1389     Vol *currVol;
   1390     Vop *tempForwRefVop = NULL;
   1391     Int tempRefSelCode = 0;
   1392     PV_STATUS   EncodeVOS_Start(VideoEncControls *encCtrl);
   1393     Int width_16, height_16;
   1394     Int width, height;
   1395     Vop *temp;
   1396     Int encodeVop = 0;
   1397     void  PaddingEdge(Vop *padVop);
   1398     Int currLayer = -1;
   1399     //Int nLayers = encParams->nLayers;
   1400 
   1401     ULong modTime = vid_in->timestamp;
   1402 
   1403 #ifdef RANDOM_REFSELCODE   /* add random selection of reference Vop */
   1404     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};
   1405     static Int rand_idx = 0;
   1406 #endif
   1407 
   1408     /*******************************************************/
   1409     /* Determine Next Vop to encode, if any, and nLayer    */
   1410     /*******************************************************/
   1411     //i = nLayers-1;
   1412 
   1413     if (video->volInitialize[0]) /* first vol to code */
   1414     {
   1415         video->nextModTime = video->modTimeRef = ((modTime) - ((modTime) % 1000));
   1416     }
   1417 
   1418     encodeVop = DetermineCodingLayer(video, nLayer, modTime);
   1419     currLayer = *nLayer;
   1420     if ((currLayer < 0) || (currLayer > encParams->nLayers - 1))
   1421         return PV_FALSE;
   1422 
   1423     /******************************************/
   1424     /* If post-skipping still effective --- return */
   1425     /******************************************/
   1426 
   1427     if (!encodeVop) /* skip enh layer, no base layer coded --- return */
   1428     {
   1429 #ifdef _PRINT_STAT
   1430         printf("No frame coded. Continue to next frame.");
   1431 #endif
   1432         /* expected next code time, convert back to millisec */
   1433         *nextModTime = video->nextModTime;
   1434 
   1435 #ifdef ALLOW_VOP_NOT_CODED
   1436         if (video->vol[0]->shortVideoHeader) /* Short Video Header = 1 */
   1437         {
   1438             *size = 0;
   1439             *nLayer = -1;
   1440         }
   1441         else
   1442         {
   1443             *nLayer = 0;
   1444             EncodeVopNotCoded(video, bstream, size, modTime);
   1445             *size = video->vol[0]->stream->byteCount;
   1446         }
   1447 #else
   1448         *size = 0;
   1449         *nLayer = -1;
   1450 #endif
   1451         return status;
   1452     }
   1453 
   1454 
   1455 //ENCODE_VOP_AGAIN:  /* 12/30/00 */
   1456 
   1457     /**************************************************************/
   1458     /* Initialize Vol stream structure with application bitstream */
   1459     /**************************************************************/
   1460 
   1461     currVol = video->vol[currLayer];
   1462     currVol->stream->bitstreamBuffer = bstream;
   1463     currVol->stream->bufferSize = *size;
   1464     BitstreamEncReset(currVol->stream);
   1465     BitstreamSetOverrunBuffer(currVol->stream, video->overrunBuffer, video->oBSize, video);
   1466 
   1467     /***********************************************************/
   1468     /* Encode VOS and VOL Headers on first call for each layer */
   1469     /***********************************************************/
   1470 
   1471     if (video->volInitialize[currLayer])
   1472     {
   1473         video->currVop->timeInc = 0;
   1474         video->prevBaseVop->timeInc = 0;
   1475         if (!video->encParams->GetVolHeader[currLayer])
   1476             pv_status = EncodeVOS_Start(encCtrl);
   1477     }
   1478 
   1479     /***************************************************/
   1480     /* Copy Input Video Frame to Internal Video Buffer */
   1481     /***************************************************/
   1482     /* Determine Width and Height of Vop Layer */
   1483 
   1484     width = encParams->LayerWidth[currLayer];   /* Get input width */
   1485     height = encParams->LayerHeight[currLayer]; /* Get input height */
   1486     /* Round Up to nearest multiple of 16 : MPEG-4 Standard */
   1487 
   1488     width_16 = ((width + 15) / 16) * 16;            /* Round up to nearest multiple of 16 */
   1489     height_16 = ((height + 15) / 16) * 16;          /* Round up to nearest multiple of 16 */
   1490 
   1491     video->input = vid_in;  /* point to the frame input */
   1492 
   1493     /*//  End ////////////////////////////// */
   1494 
   1495 
   1496     /**************************************/
   1497     /* Determine VOP Type                 */
   1498     /* 6/2/2001, separate function      */
   1499     /**************************************/
   1500     DetermineVopType(video, currLayer);
   1501 
   1502     /****************************/
   1503     /*    Initialize VOP        */
   1504     /****************************/
   1505     video->currVop->volID = currVol->volID;
   1506     video->currVop->width = width_16;
   1507     video->currVop->height = height_16;
   1508     if (video->encParams->H263_Enabled) /*  11/28/05 */
   1509     {
   1510         video->currVop->pitch = width_16;
   1511     }
   1512     else
   1513     {
   1514         video->currVop->pitch = width_16 + 32;
   1515     }
   1516     video->currVop->timeInc = currVol->timeIncrement;
   1517     video->currVop->vopCoded = 1;
   1518     video->currVop->roundingType = 0;
   1519     video->currVop->intraDCVlcThr = encParams->IntraDCVlcThr;
   1520 
   1521     if (currLayer == 0
   1522 #ifdef RANDOM_REFSELCODE   /* add random selection of reference Vop */
   1523             || random_val[rand_idx] || video->volInitialize[currLayer]
   1524 #endif
   1525        )
   1526     {
   1527         tempForwRefVop = video->forwardRefVop; /* keep initial state */
   1528         if (tempForwRefVop != NULL) tempRefSelCode = tempForwRefVop->refSelectCode;
   1529 
   1530         video->forwardRefVop = video->prevBaseVop;
   1531         video->forwardRefVop->refSelectCode = 1;
   1532     }
   1533 #ifdef RANDOM_REFSELCODE
   1534     else
   1535     {
   1536         tempForwRefVop = video->forwardRefVop; /* keep initial state */
   1537         if (tempForwRefVop != NULL) tempRefSelCode = tempForwRefVop->refSelectCode;
   1538 
   1539         video->forwardRefVop = video->prevEnhanceVop;
   1540         video->forwardRefVop->refSelectCode = 0;
   1541     }
   1542     rand_idx++;
   1543     rand_idx %= 30;
   1544 #endif
   1545 
   1546     video->currVop->refSelectCode = video->forwardRefVop->refSelectCode;
   1547     video->currVop->gobNumber = 0;
   1548     video->currVop->gobFrameID = video->currVop->predictionType;
   1549     video->currVop->temporalRef = (modTime * 30 / 1001) % 256;
   1550 
   1551     video->currVop->temporalInterval = 0;
   1552 
   1553     if (video->currVop->predictionType == I_VOP)
   1554         video->currVop->quantizer = encParams->InitQuantIvop[currLayer];
   1555     else
   1556         video->currVop->quantizer = encParams->InitQuantPvop[currLayer];
   1557 
   1558 
   1559     /****************/
   1560     /* Encode Vop */
   1561     /****************/
   1562     video->slice_coding = 0;
   1563 
   1564     pv_status = EncodeVop(video);
   1565 #ifdef _PRINT_STAT
   1566     if (video->currVop->predictionType == I_VOP)
   1567         printf(" I-VOP ");
   1568     else
   1569         printf(" P-VOP (ref.%d)", video->forwardRefVop->refSelectCode);
   1570 #endif
   1571 
   1572     /************************************/
   1573     /* Update Skip Next Frame           */
   1574     /************************************/
   1575     *nLayer = UpdateSkipNextFrame(video, nextModTime, size, pv_status);
   1576     if (*nLayer == -1) /* skip current frame */
   1577     {
   1578         /* make sure that pointers are restored to the previous state */
   1579         if (currLayer == 0)
   1580         {
   1581             video->forwardRefVop = tempForwRefVop; /* For P-Vop base only */
   1582             video->forwardRefVop->refSelectCode = tempRefSelCode;
   1583         }
   1584 
   1585         return status;
   1586     }
   1587 
   1588     /* If I-VOP was encoded, reset IntraPeriod */
   1589     if ((currLayer == 0) && (encParams->IntraPeriod > 0) && (video->currVop->predictionType == I_VOP))
   1590         video->nextEncIVop = encParams->IntraPeriod;
   1591 
   1592     /* Set HintTrack Information */
   1593     if (currLayer != -1)
   1594     {
   1595         if (currVol->prevModuloTimeBase)
   1596             video->hintTrackInfo.MTB = 1;
   1597         else
   1598             video->hintTrackInfo.MTB = 0;
   1599         video->hintTrackInfo.LayerID = (UChar)currVol->volID;
   1600         video->hintTrackInfo.CodeType = (UChar)video->currVop->predictionType;
   1601         video->hintTrackInfo.RefSelCode = (UChar)video->currVop->refSelectCode;
   1602     }
   1603 
   1604     /************************************************/
   1605     /* Determine nLayer and timeInc for next encode */
   1606     /* 12/27/00 always go by the highest layer*/
   1607     /************************************************/
   1608 
   1609     /**********************************************************/
   1610     /* Copy Reconstructed Buffer to Output Video Frame Buffer */
   1611     /**********************************************************/
   1612     vid_out->yChan = video->currVop->yChan;
   1613     vid_out->uChan = video->currVop->uChan;
   1614     vid_out->vChan = video->currVop->vChan;
   1615     if (video->encParams->H263_Enabled)
   1616     {
   1617         vid_out->height = video->currVop->height; /* padded height */
   1618         vid_out->pitch = video->currVop->width; /* padded width */
   1619     }
   1620     else
   1621     {
   1622         vid_out->height = video->currVop->height + 32; /* padded height */
   1623         vid_out->pitch = video->currVop->width + 32; /* padded width */
   1624     }
   1625     //video_out->timestamp = video->modTime;
   1626     vid_out->timestamp = (ULong)(((video->prevFrameNum[currLayer] * 1000) / encParams->LayerFrameRate[currLayer]) + video->modTimeRef + 0.5);
   1627 
   1628     /*// End /////////////////////// */
   1629 
   1630     /***********************************/
   1631     /* Update Ouput bstream byte count */
   1632     /***********************************/
   1633 
   1634     *size = currVol->stream->byteCount;
   1635 
   1636     /****************************************/
   1637     /* Swap Vop Pointers for Base Layer     */
   1638     /****************************************/
   1639     if (currLayer == 0)
   1640     {
   1641         temp = video->prevBaseVop;
   1642         video->prevBaseVop = video->currVop;
   1643         video->prevBaseVop->padded = 0; /* not padded */
   1644         video->currVop  = temp;
   1645         video->forwardRefVop = video->prevBaseVop; /* For P-Vop base only */
   1646         video->forwardRefVop->refSelectCode = 1;
   1647     }
   1648     else
   1649     {
   1650         temp = video->prevEnhanceVop;
   1651         video->prevEnhanceVop = video->currVop;
   1652         video->prevEnhanceVop->padded = 0; /* not padded */
   1653         video->currVop = temp;
   1654         video->forwardRefVop = video->prevEnhanceVop;
   1655         video->forwardRefVop->refSelectCode = 0;
   1656     }
   1657 
   1658     /****************************************/
   1659     /* Modify the intialize flag at the end.*/
   1660     /****************************************/
   1661     if (video->volInitialize[currLayer])
   1662         video->volInitialize[currLayer] = 0;
   1663 
   1664     return status;
   1665 }
   1666 
   1667 #ifndef NO_SLICE_ENCODE
   1668 /* ======================================================================== */
   1669 /*  Function : PVEncodeFrameSet()                                           */
   1670 /*  Date     : 04/18/2000                                                   */
   1671 /*  Purpose  : Enter a video frame and perform front-end time check plus ME */
   1672 /*  In/out   :                                                              */
   1673 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
   1674 /*  Modified :                                                              */
   1675 /*                                                                          */
   1676 /* ======================================================================== */
   1677 OSCL_EXPORT_REF Bool PVEncodeFrameSet(VideoEncControls *encCtrl, VideoEncFrameIO *vid_in, ULong *nextModTime, Int *nLayer)
   1678 {
   1679     Bool status = PV_TRUE;
   1680     VideoEncData *video = (VideoEncData *)encCtrl->videoEncoderData;
   1681     VideoEncParams *encParams = video->encParams;
   1682     Vol *currVol;
   1683     PV_STATUS   EncodeVOS_Start(VideoEncControls *encCtrl);
   1684     Int width_16, height_16;
   1685     Int width, height;
   1686     Int encodeVop = 0;
   1687     void  PaddingEdge(Vop *padVop);
   1688     Int currLayer = -1;
   1689     //Int nLayers = encParams->nLayers;
   1690 
   1691     ULong   modTime = vid_in->timestamp;
   1692 
   1693 #ifdef RANDOM_REFSELCODE   /* add random selection of reference Vop */
   1694     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};
   1695     static Int rand_idx = 0;
   1696 #endif
   1697     /*******************************************************/
   1698     /* Determine Next Vop to encode, if any, and nLayer    */
   1699     /*******************************************************/
   1700 
   1701     video->modTime = modTime;
   1702 
   1703     //i = nLayers-1;
   1704 
   1705     if (video->volInitialize[0]) /* first vol to code */
   1706     {
   1707         video->nextModTime = video->modTimeRef = ((modTime) - ((modTime) % 1000));
   1708     }
   1709 
   1710 
   1711     encodeVop = DetermineCodingLayer(video, nLayer, modTime);
   1712 
   1713     currLayer = *nLayer;
   1714 
   1715     /******************************************/
   1716     /* If post-skipping still effective --- return */
   1717     /******************************************/
   1718 
   1719     if (!encodeVop) /* skip enh layer, no base layer coded --- return */
   1720     {
   1721 #ifdef _PRINT_STAT
   1722         printf("No frame coded. Continue to next frame.");
   1723 #endif
   1724         *nLayer = -1;
   1725 
   1726         /* expected next code time, convert back to millisec */
   1727         *nextModTime = video->nextModTime;;
   1728         return status;
   1729     }
   1730 
   1731     /**************************************************************/
   1732     /* Initialize Vol stream structure with application bitstream */
   1733     /**************************************************************/
   1734 
   1735     currVol = video->vol[currLayer];
   1736     currVol->stream->bufferSize = 0;
   1737     BitstreamEncReset(currVol->stream);
   1738 
   1739     /***********************************************************/
   1740     /* Encode VOS and VOL Headers on first call for each layer */
   1741     /***********************************************************/
   1742 
   1743     if (video->volInitialize[currLayer])
   1744     {
   1745         video->currVop->timeInc = 0;
   1746         video->prevBaseVop->timeInc = 0;
   1747     }
   1748 
   1749     /***************************************************/
   1750     /* Copy Input Video Frame to Internal Video Buffer */
   1751     /***************************************************/
   1752     /* Determine Width and Height of Vop Layer */
   1753 
   1754     width = encParams->LayerWidth[currLayer];   /* Get input width */
   1755     height = encParams->LayerHeight[currLayer]; /* Get input height */
   1756     /* Round Up to nearest multiple of 16 : MPEG-4 Standard */
   1757 
   1758     width_16 = ((width + 15) / 16) * 16;            /* Round up to nearest multiple of 16 */
   1759     height_16 = ((height + 15) / 16) * 16;          /* Round up to nearest multiple of 16 */
   1760 
   1761     video->input = vid_in;  /* point to the frame input */
   1762 
   1763     /*//  End ////////////////////////////// */
   1764 
   1765 
   1766     /**************************************/
   1767     /* Determine VOP Type                 */
   1768     /* 6/2/2001, separate function      */
   1769     /**************************************/
   1770     DetermineVopType(video, currLayer);
   1771 
   1772     /****************************/
   1773     /*    Initialize VOP        */
   1774     /****************************/
   1775     video->currVop->volID = currVol->volID;
   1776     video->currVop->width = width_16;
   1777     video->currVop->height = height_16;
   1778     if (video->encParams->H263_Enabled) /*  11/28/05 */
   1779     {
   1780         video->currVop->pitch = width_16;
   1781     }
   1782     else
   1783     {
   1784         video->currVop->pitch = width_16 + 32;
   1785     }
   1786     video->currVop->timeInc = currVol->timeIncrement;
   1787     video->currVop->vopCoded = 1;
   1788     video->currVop->roundingType = 0;
   1789     video->currVop->intraDCVlcThr = encParams->IntraDCVlcThr;
   1790 
   1791     if (currLayer == 0
   1792 #ifdef RANDOM_REFSELCODE   /* add random selection of reference Vop */
   1793             || random_val[rand_idx] || video->volInitialize[currLayer]
   1794 #endif
   1795        )
   1796     {
   1797         video->tempForwRefVop = video->forwardRefVop; /* keep initial state */
   1798         if (video->tempForwRefVop != NULL) video->tempRefSelCode = video->tempForwRefVop->refSelectCode;
   1799 
   1800         video->forwardRefVop = video->prevBaseVop;
   1801         video->forwardRefVop->refSelectCode = 1;
   1802     }
   1803 #ifdef RANDOM_REFSELCODE
   1804     else
   1805     {
   1806         video->tempForwRefVop = video->forwardRefVop; /* keep initial state */
   1807         if (video->tempForwRefVop != NULL) video->tempRefSelCode = video->tempForwRefVop->refSelectCode;
   1808 
   1809         video->forwardRefVop = video->prevEnhanceVop;
   1810         video->forwardRefVop->refSelectCode = 0;
   1811     }
   1812     rand_idx++;
   1813     rand_idx %= 30;
   1814 #endif
   1815 
   1816     video->currVop->refSelectCode = video->forwardRefVop->refSelectCode;
   1817     video->currVop->gobNumber = 0;
   1818     video->currVop->gobFrameID = video->currVop->predictionType;
   1819     video->currVop->temporalRef = ((modTime) * 30 / 1001) % 256;
   1820 
   1821     video->currVop->temporalInterval = 0;
   1822 
   1823     if (video->currVop->predictionType == I_VOP)
   1824         video->currVop->quantizer = encParams->InitQuantIvop[currLayer];
   1825     else
   1826         video->currVop->quantizer = encParams->InitQuantPvop[currLayer];
   1827 
   1828     /****************/
   1829     /* Encode Vop   */
   1830     /****************/
   1831     video->slice_coding = 1;
   1832 
   1833     /*pv_status =*/
   1834     EncodeVop(video);
   1835 
   1836 #ifdef _PRINT_STAT
   1837     if (video->currVop->predictionType == I_VOP)
   1838         printf(" I-VOP ");
   1839     else
   1840         printf(" P-VOP (ref.%d)", video->forwardRefVop->refSelectCode);
   1841 #endif
   1842 
   1843     /* Set HintTrack Information */
   1844     if (currVol->prevModuloTimeBase)
   1845         video->hintTrackInfo.MTB = 1;
   1846     else
   1847         video->hintTrackInfo.MTB = 0;
   1848 
   1849     video->hintTrackInfo.LayerID = (UChar)currVol->volID;
   1850     video->hintTrackInfo.CodeType = (UChar)video->currVop->predictionType;
   1851     video->hintTrackInfo.RefSelCode = (UChar)video->currVop->refSelectCode;
   1852 
   1853     return status;
   1854 }
   1855 #endif /* NO_SLICE_ENCODE */
   1856 
   1857 #ifndef NO_SLICE_ENCODE
   1858 /* ======================================================================== */
   1859 /*  Function : PVEncodePacket()                                             */
   1860 /*  Date     : 04/18/2002                                                   */
   1861 /*  Purpose  : Encode one packet and return bitstream                       */
   1862 /*  In/out   :                                                              */
   1863 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
   1864 /*  Modified :                                                              */
   1865 /*                                                                          */
   1866 /* ======================================================================== */
   1867 OSCL_EXPORT_REF Bool PVEncodeSlice(VideoEncControls *encCtrl, UChar *bstream, Int *size,
   1868                                    Int *endofFrame, VideoEncFrameIO *vid_out, ULong *nextModTime)
   1869 {
   1870     PV_STATUS pv_status;
   1871     VideoEncData *video = (VideoEncData *)encCtrl->videoEncoderData;
   1872     VideoEncParams *encParams = video->encParams;
   1873     Vol *currVol;
   1874     PV_STATUS   EncodeVOS_Start(VideoEncControls *encCtrl);
   1875     Vop *temp;
   1876     void  PaddingEdge(Vop *padVop);
   1877     Int currLayer = video->currLayer;
   1878     Int pre_skip;
   1879     Int pre_size;
   1880     /**************************************************************/
   1881     /* Initialize Vol stream structure with application bitstream */
   1882     /**************************************************************/
   1883 
   1884     currVol = video->vol[currLayer];
   1885     currVol->stream->bitstreamBuffer = bstream;
   1886     pre_size = currVol->stream->byteCount;
   1887     currVol->stream->bufferSize = pre_size + (*size);
   1888 
   1889     /***********************************************************/
   1890     /* Encode VOS and VOL Headers on first call for each layer */
   1891     /***********************************************************/
   1892 
   1893     if (video->volInitialize[currLayer])
   1894     {
   1895         if (!video->encParams->GetVolHeader[currLayer])
   1896             pv_status = EncodeVOS_Start(encCtrl);
   1897     }
   1898 
   1899     /****************/
   1900     /* Encode Slice */
   1901     /****************/
   1902     pv_status = EncodeSlice(video);
   1903 
   1904     *endofFrame = 0;
   1905 
   1906     if (video->mbnum >= currVol->nTotalMB && !video->end_of_buf)
   1907     {
   1908         *endofFrame = 1;
   1909 
   1910         /************************************/
   1911         /* Update Skip Next Frame           */
   1912         /************************************/
   1913         pre_skip = UpdateSkipNextFrame(video, nextModTime, size, pv_status); /* modified such that no pre-skipped */
   1914 
   1915         if (pre_skip == -1) /* error */
   1916         {
   1917             *endofFrame = -1;
   1918             /* make sure that pointers are restored to the previous state */
   1919             if (currLayer == 0)
   1920             {
   1921                 video->forwardRefVop = video->tempForwRefVop; /* For P-Vop base only */
   1922                 video->forwardRefVop->refSelectCode = video->tempRefSelCode;
   1923             }
   1924 
   1925             return pv_status;
   1926         }
   1927 
   1928         /* If I-VOP was encoded, reset IntraPeriod */
   1929         if ((currLayer == 0) && (encParams->IntraPeriod > 0) && (video->currVop->predictionType == I_VOP))
   1930             video->nextEncIVop = encParams->IntraPeriod;
   1931 
   1932         /**********************************************************/
   1933         /* Copy Reconstructed Buffer to Output Video Frame Buffer */
   1934         /**********************************************************/
   1935         vid_out->yChan = video->currVop->yChan;
   1936         vid_out->uChan = video->currVop->uChan;
   1937         vid_out->vChan = video->currVop->vChan;
   1938         if (video->encParams->H263_Enabled)
   1939         {
   1940             vid_out->height = video->currVop->height; /* padded height */
   1941             vid_out->pitch = video->currVop->width; /* padded width */
   1942         }
   1943         else
   1944         {
   1945             vid_out->height = video->currVop->height + 32; /* padded height */
   1946             vid_out->pitch = video->currVop->width + 32; /* padded width */
   1947         }
   1948         //vid_out->timestamp = video->modTime;
   1949         vid_out->timestamp = (ULong)(((video->prevFrameNum[currLayer] * 1000) / encParams->LayerFrameRate[currLayer]) + video->modTimeRef + 0.5);
   1950 
   1951         /*// End /////////////////////// */
   1952 
   1953         /****************************************/
   1954         /* Swap Vop Pointers for Base Layer     */
   1955         /****************************************/
   1956 
   1957         if (currLayer == 0)
   1958         {
   1959             temp = video->prevBaseVop;
   1960             video->prevBaseVop = video->currVop;
   1961             video->prevBaseVop->padded = 0; /* not padded */
   1962             video->currVop = temp;
   1963             video->forwardRefVop = video->prevBaseVop; /* For P-Vop base only */
   1964             video->forwardRefVop->refSelectCode = 1;
   1965         }
   1966         else
   1967         {
   1968             temp = video->prevEnhanceVop;
   1969             video->prevEnhanceVop = video->currVop;
   1970             video->prevEnhanceVop->padded = 0; /* not padded */
   1971             video->currVop = temp;
   1972             video->forwardRefVop = video->prevEnhanceVop;
   1973             video->forwardRefVop->refSelectCode = 0;
   1974         }
   1975     }
   1976 
   1977     /***********************************/
   1978     /* Update Ouput bstream byte count */
   1979     /***********************************/
   1980 
   1981     *size = currVol->stream->byteCount - pre_size;
   1982 
   1983     /****************************************/
   1984     /* Modify the intialize flag at the end.*/
   1985     /****************************************/
   1986     if (video->volInitialize[currLayer])
   1987         video->volInitialize[currLayer] = 0;
   1988 
   1989     return pv_status;
   1990 }
   1991 #endif /* NO_SLICE_ENCODE */
   1992 
   1993 
   1994 /* ======================================================================== */
   1995 /*  Function : PVGetH263ProfileLevelID()                                    */
   1996 /*  Date     : 02/05/2003                                                   */
   1997 /*  Purpose  : Get H.263 Profile ID and level ID for profile 0              */
   1998 /*  In/out   : Profile ID=0, levelID is what we want                        */
   1999 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
   2000 /*  Modified :                                                              */
   2001 /*  Note     : h263Level[8], rBR_bound[8], max_h263_framerate[2]            */
   2002 /*             max_h263_width[2], max_h263_height[2] are global             */
   2003 /*                                                                          */
   2004 /* ======================================================================== */
   2005 OSCL_EXPORT_REF Bool PVGetH263ProfileLevelID(VideoEncControls *encCtrl, Int *profileID, Int *levelID)
   2006 {
   2007     VideoEncData *encData;
   2008     Int width, height;
   2009     float bitrate_r, framerate;
   2010 
   2011 
   2012     /* For this version, we only support H.263 profile 0 */
   2013     *profileID = 0;
   2014 
   2015     *levelID = 0;
   2016     encData = (VideoEncData *)encCtrl->videoEncoderData;
   2017 
   2018     if (encData == NULL)
   2019         return PV_FALSE;
   2020     if (encData->encParams == NULL)
   2021         return PV_FALSE;
   2022 
   2023     if (!encData->encParams->H263_Enabled) return PV_FALSE;
   2024 
   2025 
   2026     /* get image width, height, bitrate and framerate */
   2027     width     = encData->encParams->LayerWidth[0];
   2028     height    = encData->encParams->LayerHeight[0];
   2029     bitrate_r = (float)(encData->encParams->LayerBitRate[0]) / (float)64000.0;
   2030     framerate = encData->encParams->LayerFrameRate[0];
   2031     if (!width || !height || !(bitrate_r > 0 && framerate > 0)) return PV_FALSE;
   2032 
   2033     /* This is the most frequent case : level 10 */
   2034     if (bitrate_r <= rBR_bound[1] && framerate <= max_h263_framerate[0] &&
   2035             (width <= max_h263_width[0] && height <= max_h263_height[0]))
   2036     {
   2037         *levelID = h263Level[1];
   2038         return PV_TRUE;
   2039     }
   2040     else if (bitrate_r > rBR_bound[4] ||
   2041              (width > max_h263_width[1] || height > max_h263_height[1]) ||
   2042              framerate > max_h263_framerate[1])    /* check the highest level 70 */
   2043     {
   2044         *levelID = h263Level[7];
   2045         return PV_TRUE;
   2046     }
   2047     else   /* search level 20, 30, 40 */
   2048     {
   2049 
   2050         /* pick out level 20 */
   2051         if (bitrate_r <= rBR_bound[2] &&
   2052                 ((width <= max_h263_width[0] && height <= max_h263_height[0] && framerate <= max_h263_framerate[1]) ||
   2053                  (width <= max_h263_width[1] && height <= max_h263_height[1] && framerate <= max_h263_framerate[0])))
   2054         {
   2055             *levelID = h263Level[2];
   2056             return PV_TRUE;
   2057         }
   2058         else   /* width, height and framerate are ok, now choose level 30 or 40 */
   2059         {
   2060             *levelID = (bitrate_r <= rBR_bound[3] ? h263Level[3] : h263Level[4]);
   2061             return PV_TRUE;
   2062         }
   2063     }
   2064 }
   2065 
   2066 /* ======================================================================== */
   2067 /*  Function : PVGetMPEG4ProfileLevelID()                                   */
   2068 /*  Date     : 26/06/2008                                                   */
   2069 /*  Purpose  : Get MPEG4 Level after initialized                            */
   2070 /*  In/out   : profile_level according to interface                         */
   2071 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
   2072 /*  Modified :                                                              */
   2073 /*                                                                          */
   2074 /* ======================================================================== */
   2075 OSCL_EXPORT_REF Bool PVGetMPEG4ProfileLevelID(VideoEncControls *encCtrl, Int *profile_level, Int nLayer)
   2076 {
   2077     VideoEncData* video;
   2078     Int i;
   2079 
   2080     video = (VideoEncData *)encCtrl->videoEncoderData;
   2081 
   2082     if (nLayer == 0)
   2083     {
   2084         for (i = 0; i < 8; i++)
   2085         {
   2086             if (video->encParams->ProfileLevel[0] == profile_level_code[i])
   2087             {
   2088                 break;
   2089             }
   2090         }
   2091         *profile_level = i;
   2092     }
   2093     else
   2094     {
   2095         for (i = 0; i < 8; i++)
   2096         {
   2097             if (video->encParams->ProfileLevel[0] == scalable_profile_level_code[i])
   2098             {
   2099                 break;
   2100             }
   2101         }
   2102         *profile_level = i + SIMPLE_SCALABLE_PROFILE_LEVEL0;
   2103     }
   2104 
   2105     return true;
   2106 }
   2107 
   2108 #ifndef LIMITED_API
   2109 /* ======================================================================== */
   2110 /*  Function : PVUpdateEncFrameRate                                         */
   2111 /*  Date     : 04/08/2002                                                   */
   2112 /*  Purpose  : Update target frame rates of the encoded base and enhance    */
   2113 /*             layer(if any) while encoding operation is ongoing            */
   2114 /*  In/out   :                                                              */
   2115 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
   2116 /*  Modified :                                                              */
   2117 /*                                                                          */
   2118 /* ======================================================================== */
   2119 
   2120 OSCL_EXPORT_REF Bool PVUpdateEncFrameRate(VideoEncControls *encCtrl, float *frameRate)
   2121 {
   2122     VideoEncData    *encData;
   2123     Int i;// nTotalMB, mbPerSec;
   2124 
   2125     encData = (VideoEncData *)encCtrl->videoEncoderData;
   2126 
   2127     if (encData == NULL)
   2128         return PV_FALSE;
   2129     if (encData->encParams == NULL)
   2130         return PV_FALSE;
   2131 
   2132     /* Update the framerates for all the layers */
   2133     for (i = 0; i < encData->encParams->nLayers; i++)
   2134     {
   2135 
   2136         /* New check: encoding framerate should be consistent with the given profile and level */
   2137         //nTotalMB = (((encData->encParams->LayerWidth[i]+15)/16)*16)*(((encData->encParams->LayerHeight[i]+15)/16)*16)/(16*16);
   2138         //mbPerSec = (Int)(nTotalMB * frameRate[i]);
   2139         //if(mbPerSec > encData->encParams->LayerMaxMbsPerSec[i]) return PV_FALSE;
   2140         if (frameRate[i] > encData->encParams->LayerMaxFrameRate[i]) return PV_FALSE; /* set by users or profile */
   2141 
   2142         encData->encParams->LayerFrameRate[i] = frameRate[i];
   2143     }
   2144 
   2145     return RC_UpdateBXRCParams((void*) encData);
   2146 
   2147 }
   2148 #endif
   2149 #ifndef LIMITED_API
   2150 /* ======================================================================== */
   2151 /*  Function : PVUpdateBitRate                                              */
   2152 /*  Date     : 04/08/2002                                                   */
   2153 /*  Purpose  : Update target bit rates of the encoded base and enhance      */
   2154 /*             layer(if any) while encoding operation is ongoing            */
   2155 /*  In/out   :                                                              */
   2156 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
   2157 /*  Modified :                                                              */
   2158 /*                                                                          */
   2159 /* ======================================================================== */
   2160 
   2161 OSCL_EXPORT_REF Bool PVUpdateBitRate(VideoEncControls *encCtrl, Int *bitRate)
   2162 {
   2163     VideoEncData    *encData;
   2164     Int i;
   2165 
   2166     encData = (VideoEncData *)encCtrl->videoEncoderData;
   2167 
   2168     if (encData == NULL)
   2169         return PV_FALSE;
   2170     if (encData->encParams == NULL)
   2171         return PV_FALSE;
   2172 
   2173     /* Update the bitrates for all the layers */
   2174     for (i = 0; i < encData->encParams->nLayers; i++)
   2175     {
   2176         if (bitRate[i] > encData->encParams->LayerMaxBitRate[i]) /* set by users or profile */
   2177         {
   2178             return PV_FALSE;
   2179         }
   2180         encData->encParams->LayerBitRate[i] = bitRate[i];
   2181     }
   2182 
   2183     return RC_UpdateBXRCParams((void*) encData);
   2184 
   2185 }
   2186 #endif
   2187 #ifndef LIMITED_API
   2188 /* ============================================================================ */
   2189 /*  Function : PVUpdateVBVDelay()                                                   */
   2190 /*  Date     : 4/23/2004                                                        */
   2191 /*  Purpose  : Update VBV buffer size(in delay)                                 */
   2192 /*  In/out   :                                                                  */
   2193 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                        */
   2194 /*  Modified :                                                                  */
   2195 /*                                                                              */
   2196 /* ============================================================================ */
   2197 
   2198 Bool PVUpdateVBVDelay(VideoEncControls *encCtrl, float delay)
   2199 {
   2200 
   2201     VideoEncData    *encData;
   2202     Int total_bitrate, max_buffer_size;
   2203     int index;
   2204 
   2205     encData = (VideoEncData *)encCtrl->videoEncoderData;
   2206 
   2207     if (encData == NULL)
   2208         return PV_FALSE;
   2209     if (encData->encParams == NULL)
   2210         return PV_FALSE;
   2211 
   2212     /* Check whether the input delay is valid based on the given profile */
   2213     total_bitrate   = (encData->encParams->nLayers == 1 ? encData->encParams->LayerBitRate[0] :
   2214                        encData->encParams->LayerBitRate[1]);
   2215     index = encData->encParams->profile_table_index;
   2216     max_buffer_size = (encData->encParams->nLayers == 1 ? profile_level_max_VBV_size[index] :
   2217                        scalable_profile_level_max_VBV_size[index]);
   2218 
   2219     if (total_bitrate*delay > (float)max_buffer_size)
   2220         return PV_FALSE;
   2221 
   2222     encData->encParams->VBV_delay = delay;
   2223     return PV_TRUE;
   2224 
   2225 }
   2226 #endif
   2227 #ifndef LIMITED_API
   2228 /* ======================================================================== */
   2229 /*  Function : PVUpdateIFrameInterval()                                         */
   2230 /*  Date     : 04/10/2002                                                   */
   2231 /*  Purpose  : updates the INTRA frame refresh interval while encoding      */
   2232 /*             is ongoing                                                   */
   2233 /*  In/out   :                                                              */
   2234 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
   2235 /*  Modified :                                                              */
   2236 /*                                                                          */
   2237 /* ======================================================================== */
   2238 
   2239 OSCL_EXPORT_REF Bool PVUpdateIFrameInterval(VideoEncControls *encCtrl, Int aIFramePeriod)
   2240 {
   2241     VideoEncData    *encData;
   2242 
   2243     encData = (VideoEncData *)encCtrl->videoEncoderData;
   2244 
   2245     if (encData == NULL)
   2246         return PV_FALSE;
   2247     if (encData->encParams == NULL)
   2248         return PV_FALSE;
   2249 
   2250     encData->encParams->IntraPeriod = aIFramePeriod;
   2251     return PV_TRUE;
   2252 }
   2253 #endif
   2254 #ifndef LIMITED_API
   2255 /* ======================================================================== */
   2256 /*  Function : PVSetNumIntraMBRefresh()                                     */
   2257 /*  Date     : 08/05/2003                                                   */
   2258 /*  Purpose  :                                                              */
   2259 /*  In/out   :                                                              */
   2260 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
   2261 /*  Modified :                                                              */
   2262 /*                                                                          */
   2263 /* ======================================================================== */
   2264 OSCL_EXPORT_REF Bool    PVUpdateNumIntraMBRefresh(VideoEncControls *encCtrl, Int numMB)
   2265 {
   2266     VideoEncData    *encData;
   2267 
   2268     encData = (VideoEncData *)encCtrl->videoEncoderData;
   2269 
   2270     if (encData == NULL)
   2271         return PV_FALSE;
   2272 
   2273     encData->encParams->Refresh = numMB;
   2274 
   2275     return PV_TRUE;
   2276 }
   2277 #endif
   2278 #ifndef LIMITED_API
   2279 /* ======================================================================== */
   2280 /*  Function : PVIFrameRequest()                                            */
   2281 /*  Date     : 04/10/2002                                                   */
   2282 /*  Purpose  : encodes the next base frame as an I-Vop                      */
   2283 /*  In/out   :                                                              */
   2284 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
   2285 /*  Modified :                                                              */
   2286 /*                                                                          */
   2287 /* ======================================================================== */
   2288 
   2289 OSCL_EXPORT_REF Bool PVIFrameRequest(VideoEncControls *encCtrl)
   2290 {
   2291     VideoEncData    *encData;
   2292 
   2293     encData = (VideoEncData *)encCtrl->videoEncoderData;
   2294 
   2295     if (encData == NULL)
   2296         return PV_FALSE;
   2297     if (encData->encParams == NULL)
   2298         return PV_FALSE;
   2299 
   2300     encData->nextEncIVop = 1;
   2301     return PV_TRUE;
   2302 }
   2303 #endif
   2304 #ifndef LIMITED_API
   2305 /* ======================================================================== */
   2306 /*  Function : PVGetEncMemoryUsage()                                        */
   2307 /*  Date     : 10/17/2000                                                   */
   2308 /*  Purpose  :                                                              */
   2309 /*  In/out   :                                                              */
   2310 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
   2311 /*  Modified :                                                              */
   2312 /*                                                                          */
   2313 /* ======================================================================== */
   2314 
   2315 OSCL_EXPORT_REF Int PVGetEncMemoryUsage(VideoEncControls *encCtrl)
   2316 {
   2317     VideoEncData    *encData;
   2318 
   2319     encData = (VideoEncData *)encCtrl->videoEncoderData;
   2320 
   2321     if (encData == NULL)
   2322         return PV_FALSE;
   2323     if (encData->encParams == NULL)
   2324         return PV_FALSE;
   2325     return encData->encParams->MemoryUsage;
   2326 }
   2327 #endif
   2328 
   2329 /* ======================================================================== */
   2330 /*  Function : PVGetHintTrack()                                             */
   2331 /*  Date     : 1/17/2001,                                                   */
   2332 /*  Purpose  :                                                              */
   2333 /*  In/out   :                                                              */
   2334 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
   2335 /*  Modified :                                                              */
   2336 /*                                                                          */
   2337 /* ======================================================================== */
   2338 
   2339 OSCL_EXPORT_REF Bool PVGetHintTrack(VideoEncControls *encCtrl, MP4HintTrack *info)
   2340 {
   2341     VideoEncData    *encData;
   2342 
   2343     encData = (VideoEncData *)encCtrl->videoEncoderData;
   2344 
   2345     if (encData == NULL)
   2346         return PV_FALSE;
   2347     if (encData->encParams == NULL)
   2348         return PV_FALSE;
   2349     info->MTB = encData->hintTrackInfo.MTB;
   2350     info->LayerID = encData->hintTrackInfo.LayerID;
   2351     info->CodeType = encData->hintTrackInfo.CodeType;
   2352     info->RefSelCode = encData->hintTrackInfo.RefSelCode;
   2353 
   2354     return PV_TRUE;
   2355 }
   2356 
   2357 /* ======================================================================== */
   2358 /*  Function : PVGetMaxVideoFrameSize()                                     */
   2359 /*  Date     : 7/17/2001,                                                   */
   2360 /*  Purpose  : Function merely returns the maximum buffer size              */
   2361 /*  In/out   :                                                              */
   2362 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
   2363 /*  Modified :                                                              */
   2364 /*                                                                          */
   2365 /* ======================================================================== */
   2366 
   2367 OSCL_EXPORT_REF Bool PVGetMaxVideoFrameSize(VideoEncControls *encCtrl, Int *maxVideoFrameSize)
   2368 {
   2369     VideoEncData    *encData;
   2370 
   2371     encData = (VideoEncData *)encCtrl->videoEncoderData;
   2372 
   2373     if (encData == NULL)
   2374         return PV_FALSE;
   2375     if (encData->encParams == NULL)
   2376         return PV_FALSE;
   2377 
   2378 
   2379 
   2380     *maxVideoFrameSize = encData->encParams->BufferSize[0];
   2381 
   2382     if (encData->encParams->nLayers == 2)
   2383         if (*maxVideoFrameSize < encData->encParams->BufferSize[1])
   2384             *maxVideoFrameSize = encData->encParams->BufferSize[1];
   2385     *maxVideoFrameSize >>= 3;   /* Convert to Bytes */
   2386 
   2387     if (*maxVideoFrameSize <= 4000)
   2388         *maxVideoFrameSize = 4000;
   2389 
   2390     return PV_TRUE;
   2391 }
   2392 #ifndef LIMITED_API
   2393 /* ======================================================================== */
   2394 /*  Function : PVGetVBVSize()                                               */
   2395 /*  Date     : 4/15/2002                                                    */
   2396 /*  Purpose  : Function merely returns the maximum buffer size              */
   2397 /*  In/out   :                                                              */
   2398 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
   2399 /*  Modified :                                                              */
   2400 /*                                                                          */
   2401 /* ======================================================================== */
   2402 
   2403 OSCL_EXPORT_REF Bool PVGetVBVSize(VideoEncControls *encCtrl, Int *VBVSize)
   2404 {
   2405     VideoEncData    *encData;
   2406 
   2407     encData = (VideoEncData *)encCtrl->videoEncoderData;
   2408 
   2409     if (encData == NULL)
   2410         return PV_FALSE;
   2411     if (encData->encParams == NULL)
   2412         return PV_FALSE;
   2413 
   2414     *VBVSize = encData->encParams->BufferSize[0];
   2415     if (encData->encParams->nLayers == 2)
   2416         *VBVSize += encData->encParams->BufferSize[1];
   2417 
   2418     return PV_TRUE;
   2419 
   2420 }
   2421 #endif
   2422 /* ======================================================================== */
   2423 /*  Function : EncodeVOS_Start()                                            */
   2424 /*  Date     : 08/22/2000                                                   */
   2425 /*  Purpose  : Encodes the VOS,VO, and VOL or Short Headers                 */
   2426 /*  In/out   :                                                              */
   2427 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
   2428 /*  Modified :                                                              */
   2429 /*                                                                          */
   2430 /* ======================================================================== */
   2431 PV_STATUS EncodeVOS_Start(VideoEncControls *encoderControl)
   2432 {
   2433 
   2434     VideoEncData *video = (VideoEncData *)encoderControl->videoEncoderData;
   2435     Vol         *currVol = video->vol[video->currLayer];
   2436     PV_STATUS status = PV_SUCCESS;
   2437     //int profile_level=0x01;
   2438     BitstreamEncVideo *stream = video->bitstream1;
   2439     int i, j;
   2440 
   2441     /********************************/
   2442     /* Check for short_video_header */
   2443     /********************************/
   2444     if (currVol->shortVideoHeader == 1)
   2445         return status;
   2446     else
   2447     {
   2448         /* Short Video Header or M4V */
   2449 
   2450         /**************************/
   2451         /* VisualObjectSequence ()*/
   2452         /**************************/
   2453         status = BitstreamPutGT16Bits(stream, 32, SESSION_START_CODE);
   2454         /*  Determine profile_level */
   2455         status = BitstreamPutBits(stream, 8, video->encParams->ProfileLevel[video->currLayer]);
   2456 
   2457         /******************/
   2458         /* VisualObject() */
   2459         /******************/
   2460 
   2461         status = BitstreamPutGT16Bits(stream, 32, VISUAL_OBJECT_START_CODE);
   2462         status = BitstreamPut1Bits(stream, 0x00); /* visual object identifier */
   2463         status = BitstreamPutBits(stream, 4, 0x01); /* visual object Type == "video ID" */
   2464         status = BitstreamPut1Bits(stream, 0x00); /* no video signal type */
   2465 
   2466         /*temp   = */
   2467         BitstreamMpeg4ByteAlignStuffing(stream);
   2468 
   2469 
   2470         status = BitstreamPutGT16Bits(stream, 27, VO_START_CODE);/* byte align: should be 2 bits */
   2471         status = BitstreamPutBits(stream, 5, 0x00);/*  Video ID = 0  */
   2472 
   2473 
   2474 
   2475         /**********************/
   2476         /* VideoObjectLayer() */
   2477         /**********************/
   2478         if (currVol->shortVideoHeader == 0)
   2479         { /* M4V  else Short Video Header */
   2480             status = BitstreamPutGT16Bits(stream, VOL_START_CODE_LENGTH, VOL_START_CODE);
   2481             status = BitstreamPutBits(stream, 4, currVol->volID);/*  video_object_layer_id */
   2482             status = BitstreamPut1Bits(stream, 0x00);/*  Random Access = 0  */
   2483 
   2484             if (video->currLayer == 0)
   2485                 status = BitstreamPutBits(stream, 8, 0x01);/* Video Object Type Indication = 1  ... Simple Object Type */
   2486             else
   2487                 status = BitstreamPutBits(stream, 8, 0x02);/* Video Object Type Indication = 2  ... Simple Scalable Object Type */
   2488 
   2489             status = BitstreamPut1Bits(stream, 0x00);/*  is_object_layer_identifer = 0 */
   2490 
   2491 
   2492             status = BitstreamPutBits(stream, 4, 0x01); /* aspect_ratio_info = 1 ... 1:1(Square) */
   2493             status = BitstreamPut1Bits(stream, 0x00);/* vol_control_parameters = 0 */
   2494             status = BitstreamPutBits(stream, 2, 0x00);/* video_object_layer_shape = 00 ... rectangular */
   2495             status = BitstreamPut1Bits(stream, 0x01);/* marker bit */
   2496             status = BitstreamPutGT8Bits(stream, 16, currVol->timeIncrementResolution);/* vop_time_increment_resolution */
   2497             status = BitstreamPut1Bits(stream, 0x01);/* marker bit */
   2498             status = BitstreamPut1Bits(stream, currVol->fixedVopRate);/* fixed_vop_rate = 0 */
   2499 
   2500             /* For Rectangular VO layer shape */
   2501             status = BitstreamPut1Bits(stream, 0x01);/* marker bit */
   2502             status = BitstreamPutGT8Bits(stream, 13, currVol->width);/* video_object_layer_width */
   2503             status = BitstreamPut1Bits(stream, 0x01);/* marker bit */
   2504             status = BitstreamPutGT8Bits(stream, 13, currVol->height);/* video_object_layer_height */
   2505             status = BitstreamPut1Bits(stream, 0x01);/*marker bit */
   2506 
   2507             status = BitstreamPut1Bits(stream, 0x00);/*interlaced = 0 */
   2508             status = BitstreamPut1Bits(stream, 0x01);/* obmc_disable = 1 */
   2509             status = BitstreamPut1Bits(stream, 0x00);/* sprite_enable = 0 */
   2510             status = BitstreamPut1Bits(stream, 0x00);/* not_8_bit = 0 */
   2511             status = BitstreamPut1Bits(stream, currVol->quantType);/*   quant_type */
   2512 
   2513             if (currVol->quantType)
   2514             {
   2515                 status = BitstreamPut1Bits(stream, currVol->loadIntraQuantMat); /* Intra quant matrix */
   2516                 if (currVol->loadIntraQuantMat)
   2517                 {
   2518                     for (j = 63; j >= 1; j--)
   2519                         if (currVol->iqmat[*(zigzag_i+j)] != currVol->iqmat[*(zigzag_i+j-1)])
   2520                             break;
   2521                     if ((j == 1) && (currVol->iqmat[*(zigzag_i+j)] == currVol->iqmat[*(zigzag_i+j-1)]))
   2522                         j = 0;
   2523                     for (i = 0; i < j + 1; i++)
   2524                         BitstreamPutBits(stream, 8, currVol->iqmat[*(zigzag_i+i)]);
   2525                     if (j < 63)
   2526                         BitstreamPutBits(stream, 8, 0);
   2527                 }
   2528                 else
   2529                 {
   2530                     for (j = 0; j < 64; j++)
   2531                         currVol->iqmat[j] = mpeg_iqmat_def[j];
   2532 
   2533                 }
   2534                 status = BitstreamPut1Bits(stream, currVol->loadNonIntraQuantMat); /* Non-Intra quant matrix */
   2535                 if (currVol->loadNonIntraQuantMat)
   2536                 {
   2537                     for (j = 63; j >= 1; j--)
   2538                         if (currVol->niqmat[*(zigzag_i+j)] != currVol->niqmat[*(zigzag_i+j-1)])
   2539                             break;
   2540                     if ((j == 1) && (currVol->niqmat[*(zigzag_i+j)] == currVol->niqmat[*(zigzag_i+j-1)]))
   2541                         j = 0;
   2542                     for (i = 0; i < j + 1; i++)
   2543                         BitstreamPutBits(stream, 8, currVol->niqmat[*(zigzag_i+i)]);
   2544                     if (j < 63)
   2545                         BitstreamPutBits(stream, 8, 0);
   2546                 }
   2547                 else
   2548                 {
   2549                     for (j = 0; j < 64; j++)
   2550                         currVol->niqmat[j] = mpeg_nqmat_def[j];
   2551                 }
   2552             }
   2553 
   2554             status = BitstreamPut1Bits(stream, 0x01);   /* complexity_estimation_disable = 1 */
   2555             status = BitstreamPut1Bits(stream, currVol->ResyncMarkerDisable);/* Resync_marker_disable */
   2556             status = BitstreamPut1Bits(stream, currVol->dataPartitioning);/* Data partitioned */
   2557 
   2558             if (currVol->dataPartitioning)
   2559                 status = BitstreamPut1Bits(stream, currVol->useReverseVLC); /* Reversible_vlc */
   2560 
   2561 
   2562             if (currVol->scalability) /* Scalability*/
   2563             {
   2564 
   2565                 status = BitstreamPut1Bits(stream, currVol->scalability);/* Scalability = 1 */
   2566                 status = BitstreamPut1Bits(stream, currVol->scalType);/* hierarchy _type ... Spatial= 0 and Temporal = 1 */
   2567                 status = BitstreamPutBits(stream, 4, currVol->refVolID);/* ref_layer_id  */
   2568                 status = BitstreamPut1Bits(stream, currVol->refSampDir);/* ref_layer_sampling_direc*/
   2569                 status = BitstreamPutBits(stream, 5, currVol->horSamp_n);/*hor_sampling_factor_n*/
   2570                 status = BitstreamPutBits(stream, 5, currVol->horSamp_m);/*hor_sampling_factor_m*/
   2571                 status = BitstreamPutBits(stream, 5, currVol->verSamp_n);/*vert_sampling_factor_n*/
   2572                 status = BitstreamPutBits(stream, 5, currVol->verSamp_m);/*vert_sampling_factor_m*/
   2573                 status = BitstreamPut1Bits(stream, currVol->enhancementType);/* enhancement_type*/
   2574             }
   2575             else /* No Scalability */
   2576                 status = BitstreamPut1Bits(stream, currVol->scalability);/* Scalability = 0 */
   2577 
   2578             /*temp = */
   2579             BitstreamMpeg4ByteAlignStuffing(stream); /* Byte align Headers for VOP */
   2580         }
   2581     }
   2582 
   2583     return status;
   2584 }
   2585 
   2586 /* ======================================================================== */
   2587 /*  Function : VOS_End()                                                    */
   2588 /*  Date     : 08/22/2000                                                   */
   2589 /*  Purpose  : Visual Object Sequence End                                   */
   2590 /*  In/out   :                                                              */
   2591 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
   2592 /*  Modified :                                                              */
   2593 /*                                                                          */
   2594 /* ======================================================================== */
   2595 
   2596 PV_STATUS VOS_End(VideoEncControls *encoderControl)
   2597 {
   2598     PV_STATUS status = PV_SUCCESS;
   2599     VideoEncData *video = (VideoEncData *)encoderControl->videoEncoderData;
   2600     Vol         *currVol = video->vol[video->currLayer];
   2601     BitstreamEncVideo *stream = currVol->stream;
   2602 
   2603 
   2604     status = BitstreamPutBits(stream, SESSION_END_CODE, 32);
   2605 
   2606     return status;
   2607 }
   2608 
   2609 /* ======================================================================== */
   2610 /*  Function : DetermineCodingLayer                                         */
   2611 /*  Date     : 06/02/2001                                                   */
   2612 /*  Purpose  : Find layer to code based on current mod time, assuming that
   2613                it's time to encode enhanced layer.                          */
   2614 /*  In/out   :                                                              */
   2615 /*  Return   : Number of layer to code.                                     */
   2616 /*  Modified :                                                              */
   2617 /*                                                                          */
   2618 /* ======================================================================== */
   2619 
   2620 Int DetermineCodingLayer(VideoEncData *video, Int *nLayer, ULong modTime)
   2621 {
   2622     Vol **vol = video->vol;
   2623     VideoEncParams *encParams = video->encParams;
   2624     Int numLayers = encParams->nLayers;
   2625     UInt modTimeRef = video->modTimeRef;
   2626     float *LayerFrameRate = encParams->LayerFrameRate;
   2627     UInt frameNum[4], frameTick;
   2628     ULong frameModTime, nextFrmModTime;
   2629 #ifdef REDUCE_FRAME_VARIANCE    /* To limit how close 2 frames can be */
   2630     float frameInterval;
   2631 #endif
   2632     float srcFrameInterval;
   2633     Int frameInc;
   2634     Int i, extra_skip;
   2635     Int encodeVop = 0;
   2636 
   2637     i = numLayers - 1;
   2638 
   2639     if (modTime - video->nextModTime > ((ULong)(-1)) >> 1) /* next time wrapped around */
   2640         return 0; /* not time to code it yet */
   2641 
   2642     video->relLayerCodeTime[i] -= 1000;
   2643     video->nextEncIVop--;  /* number of Vops in highest layer resolution. */
   2644     video->numVopsInGOP++;
   2645 
   2646     /* from this point frameModTime and nextFrmModTime are internal */
   2647 
   2648     frameNum[i] = (UInt)((modTime - modTimeRef) * LayerFrameRate[i] + 500) / 1000;
   2649     if (video->volInitialize[i])
   2650     {
   2651         video->prevFrameNum[i] = frameNum[i] - 1;
   2652     }
   2653     else if (frameNum[i] <= video->prevFrameNum[i])
   2654     {
   2655         return 0; /* do not encode this frame */
   2656     }
   2657 
   2658     /**** this part computes expected next frame *******/
   2659     frameModTime = (ULong)(((frameNum[i] * 1000) / LayerFrameRate[i]) + modTimeRef + 0.5); /* rec. time */
   2660     nextFrmModTime = (ULong)((((frameNum[i] + 1) * 1000) / LayerFrameRate[i]) + modTimeRef + 0.5); /* rec. time */
   2661 
   2662     srcFrameInterval = 1000 / video->FrameRate;
   2663 
   2664     video->nextModTime = nextFrmModTime - (ULong)(srcFrameInterval / 2.) - 1; /* between current and next frame */
   2665 
   2666 #ifdef REDUCE_FRAME_VARIANCE    /* To limit how close 2 frames can be */
   2667     frameInterval = 1000 / LayerFrameRate[i]; /* next rec. time */
   2668     delta = (Int)(frameInterval / 4); /* empirical number */
   2669     if (video->nextModTime - modTime  < (ULong)delta) /* need to move nextModTime further. */
   2670     {
   2671         video->nextModTime += ((delta - video->nextModTime + modTime)); /* empirical formula  */
   2672     }
   2673 #endif
   2674     /****************************************************/
   2675 
   2676     /* map frame no.to tick from modTimeRef */
   2677     /*frameTick = (frameNum[i]*vol[i]->timeIncrementResolution) ;
   2678     frameTick = (UInt)((frameTick + (encParams->LayerFrameRate[i]/2))/encParams->LayerFrameRate[i]);*/
   2679     /*  11/16/01, change frameTick to be the closest tick from the actual modTime */
   2680     /*  12/12/02, add (double) to prevent large number wrap-around */
   2681     frameTick = (Int)(((double)(modTime - modTimeRef) * vol[i]->timeIncrementResolution + 500) / 1000);
   2682 
   2683     /* find timeIncrement to be put in the bitstream */
   2684     /* refTick is second boundary reference. */
   2685     vol[i]->timeIncrement = frameTick - video->refTick[i];
   2686 
   2687 
   2688     vol[i]->moduloTimeBase = 0;
   2689     while (vol[i]->timeIncrement >= vol[i]->timeIncrementResolution)
   2690     {
   2691         vol[i]->timeIncrement -= vol[i]->timeIncrementResolution;
   2692         vol[i]->moduloTimeBase++;
   2693         /* do not update refTick and modTimeRef yet, do it after encoding!! */
   2694     }
   2695 
   2696     if (video->relLayerCodeTime[i] <= 0)    /* no skipping */
   2697     {
   2698         encodeVop = 1;
   2699         video->currLayer = *nLayer = i;
   2700         video->relLayerCodeTime[i] += 1000;
   2701 
   2702         /* takes care of more dropped frame than expected */
   2703         extra_skip = -1;
   2704         frameInc = (frameNum[i] - video->prevFrameNum[i]);
   2705         extra_skip += frameInc;
   2706 
   2707         if (extra_skip > 0)
   2708         {   /* update rc->Nr, rc->B, (rc->Rr)*/
   2709             video->nextEncIVop -= extra_skip;
   2710             video->numVopsInGOP += extra_skip;
   2711             if (encParams->RC_Type != CONSTANT_Q)
   2712             {
   2713                 RC_UpdateBuffer(video, i, extra_skip);
   2714             }
   2715         }
   2716 
   2717     }
   2718     /* update frame no. */
   2719     video->prevFrameNum[i] = frameNum[i];
   2720 
   2721     /* go through all lower layer */
   2722     for (i = (numLayers - 2); i >= 0; i--)
   2723     {
   2724 
   2725         video->relLayerCodeTime[i] -= 1000;
   2726 
   2727         /* find timeIncrement to be put in the bitstream */
   2728         vol[i]->timeIncrement = frameTick - video->refTick[i];
   2729 
   2730         if (video->relLayerCodeTime[i] <= 0) /* time to encode base */
   2731         {
   2732             /* 12/27/00 */
   2733             encodeVop = 1;
   2734             video->currLayer = *nLayer = i;
   2735             video->relLayerCodeTime[i] +=
   2736                 (Int)((1000.0 * encParams->LayerFrameRate[numLayers-1]) / encParams->LayerFrameRate[i]);
   2737 
   2738             vol[i]->moduloTimeBase = 0;
   2739             while (vol[i]->timeIncrement >= vol[i]->timeIncrementResolution)
   2740             {
   2741                 vol[i]->timeIncrement -= vol[i]->timeIncrementResolution;
   2742                 vol[i]->moduloTimeBase++;
   2743                 /* do not update refTick and modTimeRef yet, do it after encoding!! */
   2744             }
   2745 
   2746             /* takes care of more dropped frame than expected */
   2747             frameNum[i] = (UInt)((frameModTime - modTimeRef) * encParams->LayerFrameRate[i] + 500) / 1000;
   2748             if (video->volInitialize[i])
   2749                 video->prevFrameNum[i] = frameNum[i] - 1;
   2750 
   2751             extra_skip = -1;
   2752             frameInc = (frameNum[i] - video->prevFrameNum[i]);
   2753             extra_skip += frameInc;
   2754 
   2755             if (extra_skip > 0)
   2756             {   /* update rc->Nr, rc->B, (rc->Rr)*/
   2757                 if (encParams->RC_Type != CONSTANT_Q)
   2758                 {
   2759                     RC_UpdateBuffer(video, i, extra_skip);
   2760                 }
   2761             }
   2762             /* update frame no. */
   2763             video->prevFrameNum[i] = frameNum[i];
   2764         }
   2765     }
   2766 
   2767 #ifdef _PRINT_STAT
   2768     if (encodeVop)
   2769         printf(" TI: %d ", vol[*nLayer]->timeIncrement);
   2770 #endif
   2771 
   2772     return encodeVop;
   2773 }
   2774 
   2775 /* ======================================================================== */
   2776 /*  Function : DetermineVopType                                             */
   2777 /*  Date     : 06/02/2001                                                   */
   2778 /*  Purpose  : The name says it all.                                        */
   2779 /*  In/out   :                                                              */
   2780 /*  Return   : void .                                                       */
   2781 /*  Modified :                                                              */
   2782 /*                                                                          */
   2783 /* ======================================================================== */
   2784 
   2785 void DetermineVopType(VideoEncData *video, Int currLayer)
   2786 {
   2787     VideoEncParams *encParams = video->encParams;
   2788 //  Vol *currVol = video->vol[currLayer];
   2789 
   2790     if (encParams->IntraPeriod == 0) /* I-VOPs only */
   2791     {
   2792         if (video->currLayer > 0)
   2793             video->currVop->predictionType = P_VOP;
   2794         else
   2795         {
   2796             video->currVop->predictionType = I_VOP;
   2797             if (video->numVopsInGOP >= 132)
   2798                 video->numVopsInGOP = 0;
   2799         }
   2800     }
   2801     else if (encParams->IntraPeriod == -1)  /* IPPPPP... */
   2802     {
   2803 
   2804         /* maintain frame type if previous frame is pre-skipped, 06/02/2001 */
   2805         if (encParams->RC_Type == CONSTANT_Q || video->rc[currLayer]->skip_next_frame != -1)
   2806             video->currVop->predictionType = P_VOP;
   2807 
   2808         if (video->currLayer == 0)
   2809         {
   2810             if (/*video->numVopsInGOP>=132 || */video->volInitialize[currLayer])
   2811             {
   2812                 video->currVop->predictionType = I_VOP;
   2813                 video->numVopsInGOP = 0; /* force INTRA update every 132 base frames*/
   2814                 video->nextEncIVop = 1;
   2815             }
   2816             else if (video->nextEncIVop == 0 || video->currVop->predictionType == I_VOP)
   2817             {
   2818                 video->numVopsInGOP = 0;
   2819                 video->nextEncIVop = 1;
   2820             }
   2821         }
   2822     }
   2823     else   /* IntraPeriod>0 : IPPPPPIPPPPPI... */
   2824     {
   2825 
   2826         /* maintain frame type if previous frame is pre-skipped, 06/02/2001 */
   2827         if (encParams->RC_Type == CONSTANT_Q || video->rc[currLayer]->skip_next_frame != -1)
   2828             video->currVop->predictionType = P_VOP;
   2829 
   2830         if (currLayer == 0)
   2831         {
   2832             if (video->nextEncIVop <= 0 || video->currVop->predictionType == I_VOP)
   2833             {
   2834                 video->nextEncIVop = encParams->IntraPeriod;
   2835                 video->currVop->predictionType = I_VOP;
   2836                 video->numVopsInGOP = 0;
   2837             }
   2838         }
   2839     }
   2840 
   2841     return ;
   2842 }
   2843 
   2844 /* ======================================================================== */
   2845 /*  Function : UpdateSkipNextFrame                                          */
   2846 /*  Date     : 06/02/2001                                                   */
   2847 /*  Purpose  : From rate control frame skipping decision, update timing
   2848                 related parameters.                                         */
   2849 /*  In/out   :                                                              */
   2850 /*  Return   : Current coded layer.                                         */
   2851 /*  Modified :                                                              */
   2852 /*                                                                          */
   2853 /* ======================================================================== */
   2854 
   2855 Int UpdateSkipNextFrame(VideoEncData *video, ULong *modTime, Int *size, PV_STATUS status)
   2856 {
   2857     Int currLayer = video->currLayer;
   2858     Int nLayer = currLayer;
   2859     VideoEncParams *encParams = video->encParams;
   2860     Int numLayers = encParams->nLayers;
   2861     Vol *currVol = video->vol[currLayer];
   2862     Vol **vol = video->vol;
   2863     Int num_skip, extra_skip;
   2864     Int i;
   2865     UInt newRefTick, deltaModTime;
   2866     UInt temp;
   2867 
   2868     if (encParams->RC_Type != CONSTANT_Q)
   2869     {
   2870         if (video->volInitialize[0] && currLayer == 0)  /* always encode the first frame */
   2871         {
   2872             RC_ResetSkipNextFrame(video, currLayer);
   2873             //return currLayer;  09/15/05
   2874         }
   2875         else
   2876         {
   2877             if (RC_GetSkipNextFrame(video, currLayer) < 0 || status == PV_END_OF_BUF)   /* Skip Current Frame */
   2878             {
   2879 
   2880 #ifdef _PRINT_STAT
   2881                 printf("Skip current frame");
   2882 #endif
   2883                 currVol->moduloTimeBase = currVol->prevModuloTimeBase;
   2884 
   2885                 /*********************/
   2886                 /* prepare to return */
   2887                 /*********************/
   2888                 *size = 0;  /* Set Bitstream buffer to zero */
   2889 
   2890                 /* Determine nLayer and modTime for next encode */
   2891 
   2892                 *modTime = video->nextModTime;
   2893                 nLayer = -1;
   2894 
   2895                 return nLayer; /* return immediately without updating RefTick & modTimeRef */
   2896                 /* If I-VOP was attempted, then ensure next base is I-VOP */
   2897                 /*if((encParams->IntraPeriod>0) && (video->currVop->predictionType == I_VOP))
   2898                 video->nextEncIVop = 0; commented out by 06/05/01 */
   2899 
   2900             }
   2901             else if ((num_skip = RC_GetSkipNextFrame(video, currLayer)) > 0)
   2902             {
   2903 
   2904 #ifdef _PRINT_STAT
   2905                 printf("Skip next %d frames", num_skip);
   2906 #endif
   2907                 /* to keep the Nr of enh layer the same */
   2908                 /* adjust relLayerCodeTime only, do not adjust layerCodeTime[numLayers-1] */
   2909                 extra_skip = 0;
   2910                 for (i = 0; i < currLayer; i++)
   2911                 {
   2912                     if (video->relLayerCodeTime[i] <= 1000)
   2913                     {
   2914                         extra_skip = 1;
   2915                         break;
   2916                     }
   2917                 }
   2918 
   2919                 for (i = currLayer; i < numLayers; i++)
   2920                 {
   2921                     video->relLayerCodeTime[i] += (num_skip + extra_skip) *
   2922                                                   ((Int)((1000.0 * encParams->LayerFrameRate[numLayers-1]) / encParams->LayerFrameRate[i]));
   2923                 }
   2924             }
   2925         }/* first frame */
   2926     }
   2927     /*****  current frame is encoded, now update refTick ******/
   2928 
   2929     video->refTick[currLayer] += vol[currLayer]->prevModuloTimeBase * vol[currLayer]->timeIncrementResolution;
   2930 
   2931     /* Reset layerCodeTime every I-VOP to prevent overflow */
   2932     if (currLayer == 0)
   2933     {
   2934         /*  12/12/02, fix for weird targer frame rate of 9.99 fps or 3.33 fps */
   2935         if (((encParams->IntraPeriod != 0) /*&& (video->currVop->predictionType==I_VOP)*/) ||
   2936                 ((encParams->IntraPeriod == 0) && (video->numVopsInGOP == 0)))
   2937         {
   2938             newRefTick = video->refTick[0];
   2939 
   2940             for (i = 1; i < numLayers; i++)
   2941             {
   2942                 if (video->refTick[i] < newRefTick)
   2943                     newRefTick = video->refTick[i];
   2944             }
   2945 
   2946             /* check to make sure that the update is integer multiple of frame number */
   2947             /* how many msec elapsed from last modTimeRef */
   2948             deltaModTime = (newRefTick / vol[0]->timeIncrementResolution) * 1000;
   2949 
   2950             for (i = numLayers - 1; i >= 0; i--)
   2951             {
   2952                 temp = (UInt)(deltaModTime * encParams->LayerFrameRate[i]); /* 12/12/02 */
   2953                 if (temp % 1000)
   2954                     newRefTick = 0;
   2955 
   2956             }
   2957             if (newRefTick > 0)
   2958             {
   2959                 video->modTimeRef += deltaModTime;
   2960                 for (i = numLayers - 1; i >= 0; i--)
   2961                 {
   2962                     video->prevFrameNum[i] -= (UInt)(deltaModTime * encParams->LayerFrameRate[i]) / 1000;
   2963                     video->refTick[i] -= newRefTick;
   2964                 }
   2965             }
   2966         }
   2967     }
   2968 
   2969     *modTime =  video->nextModTime;
   2970 
   2971     return nLayer;
   2972 }
   2973 
   2974 
   2975 #ifndef ORIGINAL_VERSION
   2976 
   2977 /* ======================================================================== */
   2978 /*  Function : SetProfile_BufferSize                                        */
   2979 /*  Date     : 04/08/2002                                                   */
   2980 /*  Purpose  : Set profile and video buffer size, copied from Jim's code    */
   2981 /*             in PVInitVideoEncoder(.), since we have different places     */
   2982 /*             to reset profile and video buffer size                       */
   2983 /*  In/out   :                                                              */
   2984 /*  Return   :                                                              */
   2985 /*  Modified :                                                              */
   2986 /*                                                                          */
   2987 /* ======================================================================== */
   2988 
   2989 Bool SetProfile_BufferSize(VideoEncData *video, float delay, Int bInitialized)
   2990 {
   2991     Int i, j, start, end;
   2992 //  Int BaseMBsPerSec = 0, EnhMBsPerSec = 0;
   2993     Int nTotalMB = 0;
   2994     Int idx, temp_w, temp_h, max = 0, max_width, max_height;
   2995 
   2996     Int nLayers = video->encParams->nLayers; /* Number of Layers to be encoded */
   2997 
   2998     Int total_bitrate = 0, base_bitrate;
   2999     Int total_packet_size = 0, base_packet_size;
   3000     Int total_MBsPerSec = 0, base_MBsPerSec;
   3001     Int total_VBV_size = 0, base_VBV_size, enhance_VBV_size = 0;
   3002     float total_framerate, base_framerate;
   3003     float upper_bound_ratio;
   3004     Int bFound = 0;
   3005     Int k = 0, width16, height16, index;
   3006     Int lowest_level;
   3007 
   3008 #define MIN_BUFF    16000 /* 16k minimum buffer size */
   3009 #define BUFF_CONST  2.0    /* 2000ms */
   3010 #define UPPER_BOUND_RATIO 8.54 /* upper_bound = 1.4*(1.1+bound/10)*bitrate/framerate */
   3011 
   3012 #define QCIF_WIDTH  176
   3013 #define QCIF_HEIGHT 144
   3014 
   3015     index = video->encParams->profile_table_index;
   3016 
   3017     /* Calculate "nTotalMB" */
   3018     /* Find the maximum width*height for memory allocation of the VOPs */
   3019     for (idx = 0; idx < nLayers; idx++)
   3020     {
   3021         temp_w = video->encParams->LayerWidth[idx];
   3022         temp_h = video->encParams->LayerHeight[idx];
   3023 
   3024         if ((temp_w*temp_h) > max)
   3025         {
   3026             max = temp_w * temp_h;
   3027             max_width = temp_w;
   3028             max_height = temp_h;
   3029             nTotalMB = ((max_width + 15) >> 4) * ((max_height + 15) >> 4);
   3030         }
   3031     }
   3032     upper_bound_ratio = (video->encParams->RC_Type == CBR_LOWDELAY ? (float)5.0 : (float)UPPER_BOUND_RATIO);
   3033 
   3034 
   3035     /* Get the basic information: bitrate, packet_size, MBs/s and VBV_size */
   3036     base_bitrate        = video->encParams->LayerBitRate[0];
   3037     if (video->encParams->LayerMaxBitRate[0] != 0) /* video->encParams->LayerMaxBitRate[0] == 0 means it has not been set */
   3038     {
   3039         base_bitrate    = PV_MAX(base_bitrate, video->encParams->LayerMaxBitRate[0]);
   3040     }
   3041     else /* if the max is not set, set it to the specified profile/level */
   3042     {
   3043         video->encParams->LayerMaxBitRate[0] = profile_level_max_bitrate[index];
   3044     }
   3045 
   3046     base_framerate      = video->encParams->LayerFrameRate[0];
   3047     if (video->encParams->LayerMaxFrameRate[0] != 0)
   3048     {
   3049         base_framerate  = PV_MAX(base_framerate, video->encParams->LayerMaxFrameRate[0]);
   3050     }
   3051     else /* if the max is not set, set it to the specified profile/level */
   3052     {
   3053         video->encParams->LayerMaxFrameRate[0] = (float)profile_level_max_mbsPerSec[index] / nTotalMB;
   3054     }
   3055 
   3056     base_packet_size    = video->encParams->ResyncPacketsize;
   3057     base_MBsPerSec      = (Int)(base_framerate * nTotalMB);
   3058     base_VBV_size       = PV_MAX((Int)(base_bitrate * delay),
   3059                                  (Int)(upper_bound_ratio * base_bitrate / base_framerate));
   3060     base_VBV_size       = PV_MAX(base_VBV_size, MIN_BUFF);
   3061 
   3062     /* if the buffer is larger than maximum buffer size, we'll clip it */
   3063     if (base_VBV_size > profile_level_max_VBV_size[5])
   3064         base_VBV_size = profile_level_max_VBV_size[5];
   3065 
   3066 
   3067     /* Check if the buffer exceeds the maximum buffer size given the maximum profile and level */
   3068     if (nLayers == 1 && base_VBV_size > profile_level_max_VBV_size[index])
   3069         return FALSE;
   3070 
   3071 
   3072     if (nLayers == 2)
   3073     {
   3074         total_bitrate       = video->encParams->LayerBitRate[1];
   3075         if (video->encParams->LayerMaxBitRate[1] != 0)
   3076         {
   3077             total_bitrate   = PV_MIN(total_bitrate, video->encParams->LayerMaxBitRate[1]);
   3078         }
   3079         else /* if the max is not set, set it to the specified profile/level */
   3080         {
   3081             video->encParams->LayerMaxBitRate[1] = scalable_profile_level_max_bitrate[index];
   3082         }
   3083 
   3084         total_framerate     = video->encParams->LayerFrameRate[1];
   3085         if (video->encParams->LayerMaxFrameRate[1] != 0)
   3086         {
   3087             total_framerate     = PV_MIN(total_framerate, video->encParams->LayerMaxFrameRate[1]);
   3088         }
   3089         else /* if the max is not set, set it to the specified profile/level */
   3090         {
   3091             video->encParams->LayerMaxFrameRate[1] = (float)scalable_profile_level_max_mbsPerSec[index] / nTotalMB;
   3092         }
   3093 
   3094         total_packet_size   = video->encParams->ResyncPacketsize;
   3095         total_MBsPerSec     = (Int)(total_framerate * nTotalMB);
   3096 
   3097         enhance_VBV_size    = PV_MAX((Int)((total_bitrate - base_bitrate) * delay),
   3098                                      (Int)(upper_bound_ratio * (total_bitrate - base_bitrate) / (total_framerate - base_framerate)));
   3099         enhance_VBV_size    = PV_MAX(enhance_VBV_size, MIN_BUFF);
   3100 
   3101         total_VBV_size      = base_VBV_size + enhance_VBV_size;
   3102 
   3103         /* if the buffer is larger than maximum buffer size, we'll clip it */
   3104         if (total_VBV_size > scalable_profile_level_max_VBV_size[6])
   3105         {
   3106             total_VBV_size = scalable_profile_level_max_VBV_size[6];
   3107             enhance_VBV_size = total_VBV_size - base_VBV_size;
   3108         }
   3109 
   3110         /* Check if the buffer exceeds the maximum buffer size given the maximum profile and level */
   3111         if (total_VBV_size > scalable_profile_level_max_VBV_size[index])
   3112             return FALSE;
   3113     }
   3114 
   3115 
   3116     if (!bInitialized) /* Has been initialized --> profile @ level has been figured out! */
   3117     {
   3118         video->encParams->BufferSize[0] = base_VBV_size;
   3119         if (nLayers > 1)
   3120             video->encParams->BufferSize[1] = enhance_VBV_size;
   3121 
   3122         return PV_TRUE;
   3123     }
   3124 
   3125 
   3126     /* Profile @ level determination */
   3127     if (nLayers == 1)
   3128     {
   3129         /* BASE ONLY : Simple Profile(SP) Or Core Profile(CP) */
   3130         if (base_bitrate     > profile_level_max_bitrate[index]     ||
   3131                 base_packet_size > profile_level_max_packet_size[index] ||
   3132                 base_MBsPerSec   > profile_level_max_mbsPerSec[index]   ||
   3133                 base_VBV_size    > profile_level_max_VBV_size[index])
   3134 
   3135             return PV_FALSE; /* Beyond the bound of Core Profile @ Level2 */
   3136 
   3137         /* For H263/Short header, determine k*16384 */
   3138         width16  = ((video->encParams->LayerWidth[0] + 15) >> 4) << 4;
   3139         height16 = ((video->encParams->LayerHeight[0] + 15) >> 4) << 4;
   3140         if (video->encParams->H263_Enabled)
   3141         {
   3142             k = 4;
   3143             if (width16  == 2*QCIF_WIDTH && height16 == 2*QCIF_HEIGHT)  /* CIF */
   3144                 k = 16;
   3145 
   3146             else if (width16  == 4*QCIF_WIDTH && height16 == 4*QCIF_HEIGHT)  /* 4CIF */
   3147                 k = 32;
   3148 
   3149             else if (width16  == 8*QCIF_WIDTH && height16 == 8*QCIF_HEIGHT)  /* 16CIF */
   3150                 k = 64;
   3151 
   3152             video->encParams->maxFrameSize  = k * 16384;
   3153 
   3154             /* Make sure the buffer size is limited to the top profile and level: the Core profile and level 2 */
   3155             if (base_VBV_size > (Int)(k*16384 + 4*(float)profile_level_max_bitrate[5]*1001.0 / 30000.0))
   3156                 base_VBV_size = (Int)(k * 16384 + 4 * (float)profile_level_max_bitrate[5] * 1001.0 / 30000.0);
   3157 
   3158             if (base_VBV_size > (Int)(k*16384 + 4*(float)profile_level_max_bitrate[index]*1001.0 / 30000.0))
   3159                 return PV_FALSE;
   3160         }
   3161 
   3162         /* Search the appropriate profile@level index */
   3163         if (!video->encParams->H263_Enabled &&
   3164                 (video->encParams->IntraDCVlcThr != 0 || video->encParams->SearchRange > 16))
   3165         {
   3166             lowest_level = 1; /* cannot allow SPL0 */
   3167         }
   3168         else
   3169         {
   3170             lowest_level = 0; /* SPL0 */
   3171         }
   3172 
   3173         for (i = lowest_level; i <= index; i++)
   3174         {
   3175             if (i != 4 && /* skip Core Profile@Level1 because the parameters in it are smaller than those in Simple Profile@Level3 */
   3176                     base_bitrate     <= profile_level_max_bitrate[i]     &&
   3177                     base_packet_size <= profile_level_max_packet_size[i] &&
   3178                     base_MBsPerSec   <= profile_level_max_mbsPerSec[i]   &&
   3179                     base_VBV_size    <= (video->encParams->H263_Enabled ? (Int)(k*16384 + 4*(float)profile_level_max_bitrate[i]*1001.0 / 30000.0) :
   3180                                          profile_level_max_VBV_size[i]))
   3181                 break;
   3182         }
   3183         if (i > index) return PV_FALSE; /* Nothing found!! */
   3184 
   3185         /* Found out the actual profile @ level : index "i" */
   3186         if (i == 0)
   3187         {
   3188             /* For Simple Profile @ Level 0, we need to do one more check: image size <= QCIF */
   3189             if (width16 > QCIF_WIDTH || height16 > QCIF_HEIGHT)
   3190                 i = 1; /* image size > QCIF, then set SP level1 */
   3191         }
   3192 
   3193         video->encParams->ProfileLevel[0] = profile_level_code[i];
   3194         video->encParams->BufferSize[0]   = base_VBV_size;
   3195 
   3196         if (video->encParams->LayerMaxBitRate[0] == 0)
   3197             video->encParams->LayerMaxBitRate[0] = profile_level_max_bitrate[i];
   3198 
   3199         if (video->encParams->LayerMaxFrameRate[0] == 0)
   3200             video->encParams->LayerMaxFrameRate[0] = PV_MIN(30, (float)profile_level_max_mbsPerSec[i] / nTotalMB);
   3201 
   3202         /* For H263/Short header, one special constraint for VBV buffer size */
   3203         if (video->encParams->H263_Enabled)
   3204             video->encParams->BufferSize[0] = (Int)(k * 16384 + 4 * (float)profile_level_max_bitrate[i] * 1001.0 / 30000.0);
   3205 
   3206     }
   3207     else
   3208     {
   3209         /* SCALABALE MODE: Simple Scalable Profile(SSP) Or Core Scalable Profile(CSP) */
   3210 
   3211         if (total_bitrate       > scalable_profile_level_max_bitrate[index]     ||
   3212                 total_packet_size   > scalable_profile_level_max_packet_size[index] ||
   3213                 total_MBsPerSec     > scalable_profile_level_max_mbsPerSec[index]   ||
   3214                 total_VBV_size      > scalable_profile_level_max_VBV_size[index])
   3215 
   3216             return PV_FALSE; /* Beyond given profile and level */
   3217 
   3218         /* One-time check: Simple Scalable Profile or Core Scalable Profile */
   3219         if (total_bitrate       <= scalable_profile_level_max_bitrate[2]        &&
   3220                 total_packet_size   <= scalable_profile_level_max_packet_size[2]    &&
   3221                 total_MBsPerSec     <= scalable_profile_level_max_mbsPerSec[2]      &&
   3222                 total_VBV_size      <= scalable_profile_level_max_VBV_size[2])
   3223 
   3224         {
   3225             start = 0;
   3226             end = index;
   3227         }
   3228 
   3229         else
   3230         {
   3231             start = 4;
   3232             end = index;
   3233         }
   3234 
   3235 
   3236         /* Search the scalable profile */
   3237         for (i = start; i <= end; i++)
   3238         {
   3239             if (total_bitrate       <= scalable_profile_level_max_bitrate[i]     &&
   3240                     total_packet_size   <= scalable_profile_level_max_packet_size[i] &&
   3241                     total_MBsPerSec     <= scalable_profile_level_max_mbsPerSec[i]   &&
   3242                     total_VBV_size      <= scalable_profile_level_max_VBV_size[i])
   3243 
   3244                 break;
   3245         }
   3246         if (i > end) return PV_FALSE;
   3247 
   3248         /* Search the base profile */
   3249         if (i == 0)
   3250         {
   3251             j = 0;
   3252             bFound = 1;
   3253         }
   3254         else        bFound = 0;
   3255 
   3256         for (j = start; !bFound && j <= i; j++)
   3257         {
   3258             if (base_bitrate        <= profile_level_max_bitrate[j]      &&
   3259                     base_packet_size    <= profile_level_max_packet_size[j]  &&
   3260                     base_MBsPerSec      <= profile_level_max_mbsPerSec[j]    &&
   3261                     base_VBV_size       <= profile_level_max_VBV_size[j])
   3262 
   3263             {
   3264                 bFound = 1;
   3265                 break;
   3266             }
   3267         }
   3268 
   3269         if (!bFound) // && start == 4)
   3270             return PV_FALSE; /* mis-match in the profiles between base layer and enhancement layer */
   3271 
   3272         /* j for base layer, i for enhancement layer */
   3273         video->encParams->ProfileLevel[0] = profile_level_code[j];
   3274         video->encParams->ProfileLevel[1] = scalable_profile_level_code[i];
   3275         video->encParams->BufferSize[0]   = base_VBV_size;
   3276         video->encParams->BufferSize[1]   = enhance_VBV_size;
   3277 
   3278         if (video->encParams->LayerMaxBitRate[0] == 0)
   3279             video->encParams->LayerMaxBitRate[0] = profile_level_max_bitrate[j];
   3280 
   3281         if (video->encParams->LayerMaxBitRate[1] == 0)
   3282             video->encParams->LayerMaxBitRate[1] = scalable_profile_level_max_bitrate[i];
   3283 
   3284         if (video->encParams->LayerMaxFrameRate[0] == 0)
   3285             video->encParams->LayerMaxFrameRate[0] = PV_MIN(30, (float)profile_level_max_mbsPerSec[j] / nTotalMB);
   3286 
   3287         if (video->encParams->LayerMaxFrameRate[1] == 0)
   3288             video->encParams->LayerMaxFrameRate[1] = PV_MIN(30, (float)scalable_profile_level_max_mbsPerSec[i] / nTotalMB);
   3289 
   3290 
   3291     } /* end of: if(nLayers == 1) */
   3292 
   3293 
   3294     if (!video->encParams->H263_Enabled && (video->encParams->ProfileLevel[0] == 0x08)) /* SPL0 restriction*/
   3295     {
   3296         /* PV only allow frame-based rate control, no QP change from one MB to another
   3297         if(video->encParams->ACDCPrediction == TRUE && MB-based rate control)
   3298          return PV_FALSE */
   3299     }
   3300 
   3301     return PV_TRUE;
   3302 }
   3303 
   3304 #endif /* #ifndef ORIGINAL_VERSION */
   3305 
   3306 
   3307 
   3308