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