159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ------------------------------------------------------------------
259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * Copyright (C) 1998-2009 PacketVideo
359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong *
459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * Licensed under the Apache License, Version 2.0 (the "License");
559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * you may not use this file except in compliance with the License.
659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * You may obtain a copy of the License at
759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong *
859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong *      http://www.apache.org/licenses/LICENSE-2.0
959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong *
1059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * Unless required by applicable law or agreed to in writing, software
1159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
1359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * express or implied.
1459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * See the License for the specific language governing permissions
1559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * and limitations under the License.
1659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * -------------------------------------------------------------------
1759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong */
1859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
1959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "mp4enc_lib.h"
2059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "bitstream_io.h"
2159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "rate_control.h"
2259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "m4venc_oscl.h"
2359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
2459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
2559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Inverse normal zigzag */
2659f566c4ec3dfc097ad8163523e522280b27e5c3James Dongconst static Int zigzag_i[NCOEFF_BLOCK] =
2759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
2859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    0, 1, 8, 16, 9, 2, 3, 10,
2959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    17, 24, 32, 25, 18, 11, 4, 5,
3059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    12, 19, 26, 33, 40, 48, 41, 34,
3159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    27, 20, 13, 6, 7, 14, 21, 28,
3259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    35, 42, 49, 56, 57, 50, 43, 36,
3359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    29, 22, 15, 23, 30, 37, 44, 51,
3459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    58, 59, 52, 45, 38, 31, 39, 46,
3559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    53, 60, 61, 54, 47, 55, 62, 63
3659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong};
3759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
3859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* INTRA */
3959f566c4ec3dfc097ad8163523e522280b27e5c3James Dongconst static Int mpeg_iqmat_def[NCOEFF_BLOCK] =
4059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {  8, 17, 18, 19, 21, 23, 25, 27,
4159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong       17, 18, 19, 21, 23, 25, 27, 28,
4259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong       20, 21, 22, 23, 24, 26, 28, 30,
4359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong       21, 22, 23, 24, 26, 28, 30, 32,
4459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong       22, 23, 24, 26, 28, 30, 32, 35,
4559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong       23, 24, 26, 28, 30, 32, 35, 38,
4659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong       25, 26, 28, 30, 32, 35, 38, 41,
4759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong       27, 28, 30, 32, 35, 38, 41, 45
4859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    };
4959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
5059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* INTER */
5159f566c4ec3dfc097ad8163523e522280b27e5c3James Dongconst static Int mpeg_nqmat_def[64]  =
5259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    { 16, 17, 18, 19, 20, 21, 22, 23,
5359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong      17, 18, 19, 20, 21, 22, 23, 24,
5459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong      18, 19, 20, 21, 22, 23, 24, 25,
5559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong      19, 20, 21, 22, 23, 24, 26, 27,
5659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong      20, 21, 22, 23, 25, 26, 27, 28,
5759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong      21, 22, 23, 24, 26, 27, 28, 30,
5859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong      22, 23, 24, 26, 27, 28, 30, 31,
5959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong      23, 24, 25, 27, 28, 30, 31, 33
6059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    };
6159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
6259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Profiles and levels */
6359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Simple profile(level 0-3) and Core profile (level 1-2) */
6459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* {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 */
6559f566c4ec3dfc097ad8163523e522280b27e5c3James Dongconst static Int profile_level_code[8] =
6659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
6759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    0x08, 0x01, 0x02, 0x03, 0x21, 0x22, 0x22, 0x22
6859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong};
6959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
7059f566c4ec3dfc097ad8163523e522280b27e5c3James Dongconst static Int profile_level_max_bitrate[8] =
7159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
7259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    64000, 64000, 128000, 384000, 384000, 2000000, 2000000, 2000000
7359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong};
7459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
7559f566c4ec3dfc097ad8163523e522280b27e5c3James Dongconst static Int profile_level_max_packet_size[8] =
7659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
7759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    2048, 2048, 4096, 8192, 4096, 8192, 8192, 8192
7859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong};
7959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
8059f566c4ec3dfc097ad8163523e522280b27e5c3James Dongconst static Int profile_level_max_mbsPerSec[8] =
8159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
8259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    1485, 1485, 5940, 11880, 5940, 23760, 23760, 23760
8359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong};
8459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
8559f566c4ec3dfc097ad8163523e522280b27e5c3James Dongconst static Int profile_level_max_VBV_size[8] =
8659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
8759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    163840, 163840, 655360, 655360, 262144, 1310720, 1310720, 1310720
8859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong};
8959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
9059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
9159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Simple scalable profile (level 0-2) and Core scalable profile (level 1-3) */
9259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* {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 */
9359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
9459f566c4ec3dfc097ad8163523e522280b27e5c3James Dongconst static Int scalable_profile_level_code[8] =
9559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
9659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    0x10, 0x11, 0x12, 0x12, 0xA1, 0xA2, 0xA3, 0xA3
9759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong};
9859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
9959f566c4ec3dfc097ad8163523e522280b27e5c3James Dongconst static Int scalable_profile_level_max_bitrate[8] =
10059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
10159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    128000, 128000, 256000, 256000, 768000, 1500000, 4000000, 4000000
10259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong};
10359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
10459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* in bits */
10559f566c4ec3dfc097ad8163523e522280b27e5c3James Dongconst static Int scalable_profile_level_max_packet_size[8] =
10659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
10759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    2048, 2048, 4096, 4096, 4096, 4096, 16384, 16384
10859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong};
10959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
11059f566c4ec3dfc097ad8163523e522280b27e5c3James Dongconst static Int scalable_profile_level_max_mbsPerSec[8] =
11159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
11259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    1485, 7425, 23760, 23760, 14850, 29700, 120960, 120960
11359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong};
11459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
11559f566c4ec3dfc097ad8163523e522280b27e5c3James Dongconst static Int scalable_profile_level_max_VBV_size[8] =
11659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
11759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    163840, 655360, 655360, 655360, 1048576, 1310720, 1310720, 1310720
11859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong};
11959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
12059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
12159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* H263 profile 0 @ level 10-70 */
12259f566c4ec3dfc097ad8163523e522280b27e5c3James Dongconst static Int   h263Level[8] = {0, 10, 20, 30, 40, 50, 60, 70};
12359f566c4ec3dfc097ad8163523e522280b27e5c3James Dongconst static float rBR_bound[8] = {0, 1, 2, 6, 32, 64, 128, 256};
12459f566c4ec3dfc097ad8163523e522280b27e5c3James Dongconst static float max_h263_framerate[2] = {(float)30000 / (float)2002,
12559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        (float)30000 / (float)1001
12659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                           };
12759f566c4ec3dfc097ad8163523e522280b27e5c3James Dongconst static Int   max_h263_width[2]  = {176, 352};
12859f566c4ec3dfc097ad8163523e522280b27e5c3James Dongconst static Int   max_h263_height[2] = {144, 288};
12959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
13059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* 6/2/2001, newly added functions to make PVEncodeVop more readable. */
13159f566c4ec3dfc097ad8163523e522280b27e5c3James DongInt DetermineCodingLayer(VideoEncData *video, Int *nLayer, ULong modTime);
13259f566c4ec3dfc097ad8163523e522280b27e5c3James Dongvoid DetermineVopType(VideoEncData *video, Int currLayer);
13359f566c4ec3dfc097ad8163523e522280b27e5c3James DongInt UpdateSkipNextFrame(VideoEncData *video, ULong *modTime, Int *size, PV_STATUS status);
13459f566c4ec3dfc097ad8163523e522280b27e5c3James DongBool SetProfile_BufferSize(VideoEncData *video, float delay, Int bInitialized);
13559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
13659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef PRINT_RC_INFO
13759f566c4ec3dfc097ad8163523e522280b27e5c3James Dongextern FILE *facct;
13859f566c4ec3dfc097ad8163523e522280b27e5c3James Dongextern int tiTotalNumBitsGenerated;
13959f566c4ec3dfc097ad8163523e522280b27e5c3James Dongextern int iStuffBits;
14059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
14159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
14259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef PRINT_EC
14359f566c4ec3dfc097ad8163523e522280b27e5c3James Dongextern FILE *fec;
14459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
14559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
14659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
14759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
14859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : PVGetDefaultEncOption()                                      */
14959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 12/12/2005                                                   */
15059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  :                                                              */
15159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
15259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
15359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
15459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
15559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
15659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
15759f566c4ec3dfc097ad8163523e522280b27e5c3James DongOSCL_EXPORT_REF Bool PVGetDefaultEncOption(VideoEncOptions *encOption, Int encUseCase)
15859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
15959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncOptions defaultUseCase = {H263_MODE, profile_level_max_packet_size[SIMPLE_PROFILE_LEVEL0] >> 3,
16059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                      SIMPLE_PROFILE_LEVEL0, PV_OFF, 0, 1, 1000, 33, {144, 144}, {176, 176}, {15, 30}, {64000, 128000},
16159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                      {10, 10}, {12, 12}, {0, 0}, CBR_1, 0.0, PV_OFF, -1, 0, PV_OFF, 16, PV_OFF, 0, PV_ON
16259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                     };
16359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
16459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    OSCL_UNUSED_ARG(encUseCase); // unused for now. Later we can add more defaults setting and use this
16559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    // argument to select the right one.
16659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* in the future we can create more meaningful use-cases */
16759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encOption == NULL)
16859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
16959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
17059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
17159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
17259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    M4VENC_MEMCPY(encOption, &defaultUseCase, sizeof(VideoEncOptions));
17359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
17459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return PV_TRUE;
17559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
17659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
17759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
17859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : PVInitVideoEncoder()                                         */
17959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 08/22/2000                                                   */
18059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Initialization of MP4 Encoder and VO bitstream               */
18159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
18259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
18359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :  5/21/01, allocate only yChan and assign uChan & vChan   */
18459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*              12/12/05, add encoding option as input argument         */
18559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
18659f566c4ec3dfc097ad8163523e522280b27e5c3James DongOSCL_EXPORT_REF Bool    PVInitVideoEncoder(VideoEncControls *encoderControl, VideoEncOptions *encOption)
18759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
18859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
18959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Bool        status = PV_TRUE;
19059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int         nLayers, idx, i, j;
19159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int         max = 0, max_width = 0, max_height = 0, pitch, offset;
19259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int         size = 0, nTotalMB = 0;
19359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncData *video;
19459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vol         *pVol;
19559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncParams  *pEncParams;
19659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int         temp_w, temp_h, mbsPerSec;
19759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
19859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /******************************************/
19959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*      this part use to be PVSetEncode() */
20059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int profile_table_index, *profile_level_table;
20159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int profile_level = encOption->profile_level;
20259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int PacketSize = encOption->packetSize << 3;
20359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int timeInc, timeIncRes;
20459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    float profile_max_framerate;
20559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncParams *encParams;
20659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
20759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encoderControl->videoEncoderData) /* this has been called */
20859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
20959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (encoderControl->videoEncoderInit) /* check if PVInitVideoEncoder() has been called  */
21059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
21159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            PVCleanUpVideoEncoder(encoderControl);
21259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encoderControl->videoEncoderInit = 0;
21359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
21459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
21559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        M4VENC_FREE(encoderControl->videoEncoderData);
21659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        encoderControl->videoEncoderData = NULL;
21759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
21859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encoderControl->videoEncoderInit = 0;   /* reset this value */
21959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
22059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video = (VideoEncData *)M4VENC_MALLOC(sizeof(VideoEncData)); /* allocate memory for encData */
22159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
22259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video == NULL)
22359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
22459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
22559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    M4VENC_MEMSET(video, 0, sizeof(VideoEncData));
22659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
22759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encoderControl->videoEncoderData = (void *) video;         /* set up pointer in VideoEncData structure */
22859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
22959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->encParams = (VideoEncParams *)M4VENC_MALLOC(sizeof(VideoEncParams));
23059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->encParams == NULL)
23159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        goto CLEAN_UP;
23259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
23359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    M4VENC_MEMSET(video->encParams, 0, sizeof(VideoEncParams));
23459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
23559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams = video->encParams;
23659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->nLayers = encOption->numLayers;
23759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
23859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Check whether the input packetsize is valid (Note: put code here (before any memory allocation) in order to avoid memory leak */
23959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if ((Int)profile_level < (Int)(SIMPLE_SCALABLE_PROFILE_LEVEL0))  /* non-scalable profile */
24059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
24159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        profile_level_table = (Int *)profile_level_max_packet_size;
24259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        profile_table_index = (Int)profile_level;
24359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (encParams->nLayers != 1)
24459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
24559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            goto CLEAN_UP;
24659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
24759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
24859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        encParams->LayerMaxMbsPerSec[0] = profile_level_max_mbsPerSec[profile_table_index];
24959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
25059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
25159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else   /* scalable profile */
25259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
25359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        profile_level_table = (Int *)scalable_profile_level_max_packet_size;
25459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        profile_table_index = (Int)profile_level - (Int)(SIMPLE_SCALABLE_PROFILE_LEVEL0);
25559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (encParams->nLayers < 2)
25659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
25759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            goto CLEAN_UP;
25859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
25959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        for (i = 0; i < encParams->nLayers; i++)
26059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
26159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->LayerMaxMbsPerSec[i] = scalable_profile_level_max_mbsPerSec[profile_table_index];
26259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
26359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
26459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
26559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
26659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* cannot have zero size packet with these modes */
26759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (PacketSize == 0)
26859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
26959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (encOption->encMode == DATA_PARTITIONING_MODE)
27059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
27159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            goto CLEAN_UP;
27259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
27359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (encOption->encMode == COMBINE_MODE_WITH_ERR_RES)
27459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
27559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encOption->encMode = COMBINE_MODE_NO_ERR_RES;
27659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
27759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
27859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
27959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encOption->gobHeaderInterval == 0)
28059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
28159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (encOption->encMode == H263_MODE_WITH_ERR_RES)
28259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
28359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encOption->encMode = H263_MODE;
28459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
28559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
28659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (encOption->encMode == SHORT_HEADER_WITH_ERR_RES)
28759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
28859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encOption->encMode = SHORT_HEADER;
28959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
29059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
29159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
29259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (PacketSize > profile_level_table[profile_table_index])
29359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        goto CLEAN_UP;
29459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
29559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Initial Defaults for all Modes */
29659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
29759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->SequenceStartCode = 1;
29859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->GOV_Enabled = 0;
29959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->RoundingType = 0;
30059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->IntraDCVlcThr = PV_MAX(PV_MIN(encOption->intraDCVlcTh, 7), 0);
30159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->ACDCPrediction = ((encOption->useACPred == PV_ON) ? TRUE : FALSE);
30259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->RC_Type = encOption->rcType;
30359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->Refresh = encOption->numIntraMB;
30459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->ResyncMarkerDisable = 0; /* Enable Resync Marker */
30559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
30659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (i = 0; i < encOption->numLayers; i++)
30759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
30859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef NO_MPEG_QUANT
30959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        encParams->QuantType[i] = 0;
31059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#else
31159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        encParams->QuantType[i] = encOption->quantType[i];      /* H263 */
31259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
31359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (encOption->pQuant[i] >= 1 && encOption->pQuant[i] <= 31)
31459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
31559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->InitQuantPvop[i] = encOption->pQuant[i];
31659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
31759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else
31859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
31959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            goto CLEAN_UP;
32059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
32159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (encOption->iQuant[i] >= 1 && encOption->iQuant[i] <= 31)
32259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
32359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->InitQuantIvop[i] = encOption->iQuant[i];
32459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
32559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else
32659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
32759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            goto CLEAN_UP;
32859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
32959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
33059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
33159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->HalfPel_Enabled = 1;
33259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->SearchRange = encOption->searchRange; /* 4/16/2001 */
33359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->FullSearch_Enabled = 0;
33459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef NO_INTER4V
33559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->MV8x8_Enabled = 0;
33659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#else
33759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->MV8x8_Enabled = 0;// comment out for now!! encOption->mv8x8Enable;
33859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
33959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->H263_Enabled = 0;
34059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->GOB_Header_Interval = 0; // need to be reset to 0
34159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->IntraPeriod = encOption->intraPeriod;    /* Intra update period update default*/
34259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->SceneChange_Det = encOption->sceneDetect;
34359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->FineFrameSkip_Enabled = 0;
34459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->NoFrameSkip_Enabled = encOption->noFrameSkipped;
34559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->NoPreSkip_Enabled = encOption->noFrameSkipped;
34659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->GetVolHeader[0] = 0;
34759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->GetVolHeader[1] = 0;
34859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->ResyncPacketsize = encOption->packetSize << 3;
34959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->LayerMaxBitRate[0] = 0;
35059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->LayerMaxBitRate[1] = 0;
35159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->LayerMaxFrameRate[0] = (float)0.0;
35259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->LayerMaxFrameRate[1] = (float)0.0;
35359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->VBV_delay = encOption->vbvDelay;  /* 2sec VBV buffer size */
35459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
35559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    switch (encOption->encMode)
35659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
35759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
35859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        case SHORT_HEADER:
35959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        case SHORT_HEADER_WITH_ERR_RES:
36059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
36159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* From Table 6-26 */
36259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->nLayers = 1;
36359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->QuantType[0] = 0;    /*H263 */
36459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->ResyncMarkerDisable = 1; /* Disable Resync Marker */
36559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->DataPartitioning = 0; /* Combined Mode */
36659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->ReversibleVLC = 0;   /* Disable RVLC */
36759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->RoundingType = 0;
36859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->IntraDCVlcThr = 7;   /* use_intra_dc_vlc = 0 */
36959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->MV8x8_Enabled = 0;
37059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
37159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->GOB_Header_Interval = encOption->gobHeaderInterval;
37259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->H263_Enabled = 2;
37359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->GOV_Enabled = 0;
37459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->TimeIncrementRes = 30000;        /* timeIncrementRes for H263 */
37559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            break;
37659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
37759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        case H263_MODE:
37859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        case H263_MODE_WITH_ERR_RES:
37959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
38059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* From Table 6-26 */
38159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->nLayers = 1;
38259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->QuantType[0] = 0;    /*H263 */
38359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->ResyncMarkerDisable = 1; /* Disable Resync Marker */
38459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->DataPartitioning = 0; /* Combined Mode */
38559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->ReversibleVLC = 0;   /* Disable RVLC */
38659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->RoundingType = 0;
38759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->IntraDCVlcThr = 7;   /* use_intra_dc_vlc = 0 */
38859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->MV8x8_Enabled = 0;
38959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
39059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->H263_Enabled = 1;
39159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->GOV_Enabled = 0;
39259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->TimeIncrementRes = 30000;        /* timeIncrementRes for H263 */
39359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
39459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            break;
39559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef H263_ONLY
39659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        case DATA_PARTITIONING_MODE:
39759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
39859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->DataPartitioning = 1;        /* Base Layer Data Partitioning */
39959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->ResyncMarkerDisable = 0; /* Resync Marker */
40059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef NO_RVLC
40159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->ReversibleVLC = 0;
40259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#else
40359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->ReversibleVLC = (encOption->rvlcEnable == PV_ON); /* RVLC when Data Partitioning */
40459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
40559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->ResyncPacketsize = PacketSize;
40659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            break;
40759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
40859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        case COMBINE_MODE_WITH_ERR_RES:
40959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
41059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->DataPartitioning = 0;        /* Combined Mode */
41159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->ResyncMarkerDisable = 0; /* Resync Marker */
41259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->ReversibleVLC = 0;           /* No RVLC */
41359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->ResyncPacketsize = PacketSize;
41459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            break;
41559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
41659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        case COMBINE_MODE_NO_ERR_RES:
41759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
41859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->DataPartitioning = 0;        /* Combined Mode */
41959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->ResyncMarkerDisable = 1; /* Disable Resync Marker */
42059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->ReversibleVLC = 0;           /* No RVLC */
42159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            break;
42259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
42359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        default:
42459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            goto CLEAN_UP;
42559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
42659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Set the constraints (maximum values) according to the input profile and level */
42759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Note that profile_table_index is already figured out above */
42859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
42959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* base layer */
43059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->profile_table_index    = profile_table_index; /* Used to limit the profile and level in SetProfile_BufferSize() */
43159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
43259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* check timeIncRes */
43359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    timeIncRes = encOption->timeIncRes;
43459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    timeInc = encOption->tickPerSrc;
43559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
43659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if ((timeIncRes >= 1) && (timeIncRes <= 65536) && (timeInc < timeIncRes) && (timeInc != 0))
43759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
43859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (!encParams->H263_Enabled)
43959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
44059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->TimeIncrementRes = timeIncRes;
44159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
44259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else
44359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
44459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encParams->TimeIncrementRes = 30000;
44559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//          video->FrameRate = 30000/(float)1001; /* fix it to 29.97 fps */
44659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
44759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->FrameRate = timeIncRes / ((float)timeInc);
44859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
44959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
45059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
45159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        goto CLEAN_UP;
45259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
45359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
45459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* check frame dimension */
45559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encParams->H263_Enabled)
45659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
45759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        switch (encOption->encWidth[0])
45859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
45959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            case 128:
46059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (encOption->encHeight[0] != 96) /* source_format = 1 */
46159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    goto CLEAN_UP;
46259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                break;
46359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            case 176:
46459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (encOption->encHeight[0] != 144) /* source_format = 2 */
46559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    goto CLEAN_UP;
46659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                break;
46759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            case 352:
46859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (encOption->encHeight[0] != 288) /* source_format = 2 */
46959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    goto CLEAN_UP;
47059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                break;
47159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
47259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            case 704:
47359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (encOption->encHeight[0] != 576) /* source_format = 2 */
47459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    goto CLEAN_UP;
47559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                break;
47659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            case 1408:
47759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (encOption->encHeight[0] != 1152) /* source_format = 2 */
47859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    goto CLEAN_UP;
47959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                break;
48059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
48159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            default:
48259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                goto CLEAN_UP;
48359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
48459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
48559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (i = 0; i < encParams->nLayers; i++)
48659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
48759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        encParams->LayerHeight[i] = encOption->encHeight[i];
48859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        encParams->LayerWidth[i] = encOption->encWidth[i];
48959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
49059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
49159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* check frame rate */
49259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (i = 0; i < encParams->nLayers; i++)
49359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
49459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        encParams->LayerFrameRate[i] = encOption->encFrameRate[i];
49559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
49659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
49759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encParams->nLayers > 1)
49859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
49959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (encOption->encFrameRate[0] == encOption->encFrameRate[1] ||
50059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                encOption->encFrameRate[0] == 0. || encOption->encFrameRate[1] == 0.) /* 7/31/03 */
50159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            goto CLEAN_UP;
50259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
50359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* set max frame rate */
50459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (i = 0; i < encParams->nLayers; i++)
50559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
50659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
50759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* Make sure the maximum framerate is consistent with the given profile and level */
50859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        nTotalMB = ((encParams->LayerWidth[i] + 15) / 16) * ((encParams->LayerHeight[i] + 15) / 16);
50959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
51059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (nTotalMB > 0)
51159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            profile_max_framerate = (float)encParams->LayerMaxMbsPerSec[i] / (float)nTotalMB;
51259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
51359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else
51459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            profile_max_framerate = (float)30.0;
51559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
51659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        encParams->LayerMaxFrameRate[i] = PV_MIN(profile_max_framerate, encParams->LayerFrameRate[i]);
51759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
51859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
51959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* check bit rate */
52059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* set max bit rate */
52159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (i = 0; i < encParams->nLayers; i++)
52259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
52359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        encParams->LayerBitRate[i] = encOption->bitRate[i];
52459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        encParams->LayerMaxBitRate[i] = encOption->bitRate[i];
52559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
52659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encParams->nLayers > 1)
52759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
52859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (encOption->bitRate[0] == encOption->bitRate[1] ||
52959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                encOption->bitRate[0] == 0 || encOption->bitRate[1] == 0) /* 7/31/03 */
53059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            goto CLEAN_UP;
53159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
53259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* check rate control and vbv delay*/
53359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encParams->RC_Type = encOption->rcType;
53459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
53559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encOption->vbvDelay == 0.0) /* set to default */
53659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
53759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        switch (encOption->rcType)
53859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
53959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            case CBR_1:
54059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            case CBR_2:
54159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                encParams->VBV_delay = (float)2.0; /* default 2sec VBV buffer size */
54259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                break;
54359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
54459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            case CBR_LOWDELAY:
54559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                encParams->VBV_delay = (float)0.5; /* default 0.5sec VBV buffer size */
54659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                break;
54759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
54859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            case VBR_1:
54959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            case VBR_2:
55059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                encParams->VBV_delay = (float)10.0; /* default 10sec VBV buffer size */
55159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                break;
55259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            default:
55359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                break;
55459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
55559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
55659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else /* force this value */
55759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
55859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        encParams->VBV_delay = encOption->vbvDelay;
55959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
56059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
56159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* check search range */
56259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encParams->H263_Enabled && encOption->searchRange > 16)
56359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
56459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        encParams->SearchRange = 16; /* 4/16/2001 */
56559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
56659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
56759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*****************************************/
56859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* checking for conflict between options */
56959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*****************************************/
57059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
57159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->encParams->RC_Type == CBR_1 || video->encParams->RC_Type == CBR_2 || video->encParams->RC_Type == CBR_LOWDELAY)  /* if CBR */
57259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
57359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef _PRINT_STAT
57459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->encParams->NoFrameSkip_Enabled == PV_ON ||
57559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->encParams->NoPreSkip_Enabled == PV_ON) /* don't allow frame skip*/
57659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            printf("WARNING!!!! CBR with NoFrameSkip\n");
57759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
57859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
57959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else if (video->encParams->RC_Type == CONSTANT_Q)   /* constant_Q */
58059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
58159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->encParams->NoFrameSkip_Enabled = PV_ON;  /* no frame skip */
58259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->encParams->NoPreSkip_Enabled = PV_ON;    /* no frame skip */
58359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef _PRINT_STAT
58459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        printf("Turn on NoFrameSkip\n");
58559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
58659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
58759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
58859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->encParams->NoFrameSkip_Enabled == PV_ON) /* if no frame skip */
58959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
59059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->encParams->FineFrameSkip_Enabled = PV_OFF;
59159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef _PRINT_STAT
59259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        printf("NoFrameSkip !!! may violate VBV_BUFFER constraint.\n");
59359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        printf("Turn off FineFrameSkip\n");
59459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
59559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
59659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
59759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /******************************************/
59859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /******************************************/
59959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
60059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    nLayers = video->encParams->nLayers; /* Number of Layers to be encoded */
60159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
60259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Find the maximum width*height for memory allocation of the VOPs */
60359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (idx = 0; idx < nLayers; idx++)
60459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
60559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        temp_w = video->encParams->LayerWidth[idx];
60659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        temp_h = video->encParams->LayerHeight[idx];
60759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
60859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if ((temp_w*temp_h) > max)
60959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
61059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            max = temp_w * temp_h;
61159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            max_width = ((temp_w + 15) >> 4) << 4;
61259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            max_height = ((temp_h + 15) >> 4) << 4;
61359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            nTotalMB = ((max_width * max_height) >> 8);
61459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
61559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
61659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* Check if the video size and framerate(MBsPerSec) are vald */
61759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        mbsPerSec = (Int)(nTotalMB * video->encParams->LayerFrameRate[idx]);
61859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (mbsPerSec > video->encParams->LayerMaxMbsPerSec[idx]) status = PV_FALSE;
61959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
62059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
62159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /****************************************************/
62259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Set Profile and Video Buffer Size for each layer */
62359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /****************************************************/
62459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->encParams->RC_Type == CBR_LOWDELAY) video->encParams->VBV_delay = 0.5; /* For CBR_LOWDELAY, we set 0.5sec buffer */
62559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    status = SetProfile_BufferSize(video, video->encParams->VBV_delay, 1);
62659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (status != PV_TRUE)
62759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        goto CLEAN_UP;
62859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
62959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /****************************************/
63059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* memory allocation and initialization */
63159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /****************************************/
63259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
63359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video == NULL) goto CLEAN_UP;
63459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
63559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* cyclic reference for passing through both structures */
63659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->videoEncControls = encoderControl;
63759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
63859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    //video->currLayer = 0; /* Set current Layer to 0 */
63959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    //video->currFrameNo = 0; /* Set current frame Number to 0 */
64059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->nextModTime = 0;
64159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->nextEncIVop = 0; /* Sets up very first frame to be I-VOP! */
64259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->numVopsInGOP = 0; /* counter for Vops in Gop, 2/8/01 */
64359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
64459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    //video->frameRate = video->encParams->LayerFrameRate[0]; /* Set current layer frame rate */
64559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
64659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->QPMB = (UChar *) M4VENC_MALLOC(nTotalMB * sizeof(UChar)); /* Memory for MB quantizers */
64759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->QPMB == NULL) goto CLEAN_UP;
64859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
64959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
65059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->headerInfo.Mode = (UChar *) M4VENC_MALLOC(sizeof(UChar) * nTotalMB); /* Memory for MB Modes */
65159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->headerInfo.Mode == NULL) goto CLEAN_UP;
65259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->headerInfo.CBP = (UChar *) M4VENC_MALLOC(sizeof(UChar) * nTotalMB);   /* Memory for CBP (Y and C) of each MB */
65359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->headerInfo.CBP == NULL) goto CLEAN_UP;
65459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
65559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Allocating motion vector space and interpolation memory*/
65659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
65759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->mot = (MOT **)M4VENC_MALLOC(sizeof(MOT *) * nTotalMB);
65859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->mot == NULL) goto CLEAN_UP;
65959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
66059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (idx = 0; idx < nTotalMB; idx++)
66159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
66259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->mot[idx] = (MOT *)M4VENC_MALLOC(sizeof(MOT) * 8);
66359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->mot[idx] == NULL)
66459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
66559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            goto CLEAN_UP;
66659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
66759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
66859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
66959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->intraArray = (UChar *)M4VENC_MALLOC(sizeof(UChar) * nTotalMB);
67059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->intraArray == NULL) goto CLEAN_UP;
67159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
67259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->sliceNo = (UChar *) M4VENC_MALLOC(nTotalMB); /* Memory for Slice Numbers */
67359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->sliceNo == NULL) goto CLEAN_UP;
67459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Allocating space for predDCAC[][8][16], Not that I intentionally  */
67559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*    increase the dimension of predDCAC from [][6][15] to [][8][16] */
67659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*    so that compilers can generate faster code to indexing the     */
67759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*    data inside (by using << instead of *).         04/14/2000. */
67859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* 5/29/01, use  decoder lib ACDC prediction memory scheme.  */
67959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->predDC = (typeDCStore *) M4VENC_MALLOC(nTotalMB * sizeof(typeDCStore));
68059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->predDC == NULL) goto CLEAN_UP;
68159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
68259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (!video->encParams->H263_Enabled)
68359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
68459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->predDCAC_col = (typeDCACStore *) M4VENC_MALLOC(((max_width >> 4) + 1) * sizeof(typeDCACStore));
68559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->predDCAC_col == NULL) goto CLEAN_UP;
68659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
68759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* element zero will be used for storing vertical (col) AC coefficients */
68859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /*  the rest will be used for storing horizontal (row) AC coefficients  */
68959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->predDCAC_row = video->predDCAC_col + 1;        /*  ACDC */
69059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
69159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->acPredFlag = (Int *) M4VENC_MALLOC(nTotalMB * sizeof(Int)); /* Memory for acPredFlag */
69259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->acPredFlag == NULL) goto CLEAN_UP;
69359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
69459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
69559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->outputMB = (MacroBlock *) M4VENC_MALLOC(sizeof(MacroBlock)); /* Allocating macroblock space */
69659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->outputMB == NULL) goto CLEAN_UP;
69759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    M4VENC_MEMSET(video->outputMB->block[0], 0, (sizeof(Short) << 6)*6);
69859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
69959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    M4VENC_MEMSET(video->dataBlock, 0, sizeof(Short) << 7);
70059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Allocate (2*packetsize) working bitstreams */
70159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
70259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->bitstream1 = BitStreamCreateEnc(2 * 4096); /*allocate working stream 1*/
70359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->bitstream1 == NULL) goto CLEAN_UP;
70459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->bitstream2 = BitStreamCreateEnc(2 * 4096); /*allocate working stream 2*/
70559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->bitstream2 == NULL) goto CLEAN_UP;
70659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->bitstream3 = BitStreamCreateEnc(2 * 4096); /*allocate working stream 3*/
70759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->bitstream3 == NULL) goto CLEAN_UP;
70859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
70959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* allocate overrun buffer */
71059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    // this buffer is used when user's buffer is too small to hold one frame.
71159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    // It is not needed for slice-based encoding.
71259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (nLayers == 1)
71359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
71459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->oBSize = encParams->BufferSize[0] >> 3;
71559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
71659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
71759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
71859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->oBSize = PV_MAX((encParams->BufferSize[0] >> 3), (encParams->BufferSize[1] >> 3));
71959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
72059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
72159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->oBSize > DEFAULT_OVERRUN_BUFFER_SIZE || encParams->RC_Type == CONSTANT_Q) // set limit
72259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
72359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->oBSize = DEFAULT_OVERRUN_BUFFER_SIZE;
72459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
72559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->overrunBuffer = (UChar*) M4VENC_MALLOC(sizeof(UChar) * video->oBSize);
72659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->overrunBuffer == NULL) goto CLEAN_UP;
72759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
72859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
72959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop = (Vop *) M4VENC_MALLOC(sizeof(Vop)); /* Memory for Current VOP */
73059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->currVop == NULL) goto CLEAN_UP;
73159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
73259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* add padding, 09/19/05 */
73359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->encParams->H263_Enabled) /* make it conditional  11/28/05 */
73459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
73559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pitch = max_width;
73659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        offset = 0;
73759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
73859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
73959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
74059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pitch = max_width + 32;
74159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        offset = (pitch << 4) + 16;
74259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        max_height += 32;
74359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
74459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    size = pitch * max_height;
74559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
74659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->yChan = (PIXEL *)M4VENC_MALLOC(sizeof(PIXEL) * (size + (size >> 1))); /* Memory for currVop Y */
74759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->currVop->yChan == NULL) goto CLEAN_UP;
74859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->uChan = video->currVop->yChan + size;/* Memory for currVop U */
74959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->vChan = video->currVop->uChan + (size >> 2);/* Memory for currVop V */
75059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
75159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* shift for the offset */
75259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (offset)
75359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
75459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->currVop->yChan += offset; /* offset to the origin.*/
75559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->currVop->uChan += (offset >> 2) + 4;
75659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->currVop->vChan += (offset >> 2) + 4;
75759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
75859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
75959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->forwardRefVop = video->currVop;      /*  Initialize forwardRefVop */
76059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->backwardRefVop = video->currVop;     /*  Initialize backwardRefVop */
76159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
76259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->prevBaseVop = (Vop *) M4VENC_MALLOC(sizeof(Vop));         /* Memory for Previous Base Vop */
76359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->prevBaseVop == NULL) goto CLEAN_UP;
76459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->prevBaseVop->yChan = (PIXEL *) M4VENC_MALLOC(sizeof(PIXEL) * (size + (size >> 1))); /* Memory for prevBaseVop Y */
76559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->prevBaseVop->yChan == NULL) goto CLEAN_UP;
76659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->prevBaseVop->uChan = video->prevBaseVop->yChan + size; /* Memory for prevBaseVop U */
76759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->prevBaseVop->vChan = video->prevBaseVop->uChan + (size >> 2); /* Memory for prevBaseVop V */
76859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
76959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (offset)
77059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
77159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->prevBaseVop->yChan += offset; /* offset to the origin.*/
77259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->prevBaseVop->uChan += (offset >> 2) + 4;
77359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->prevBaseVop->vChan += (offset >> 2) + 4;
77459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
77559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
77659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
77759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (0) /* If B Frames */
77859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
77959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->nextBaseVop = (Vop *) M4VENC_MALLOC(sizeof(Vop));         /* Memory for Next Base Vop */
78059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->nextBaseVop == NULL) goto CLEAN_UP;
78159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->nextBaseVop->yChan = (PIXEL *) M4VENC_MALLOC(sizeof(PIXEL) * (size + (size >> 1))); /* Memory for nextBaseVop Y */
78259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->nextBaseVop->yChan == NULL) goto CLEAN_UP;
78359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->nextBaseVop->uChan = video->nextBaseVop->yChan + size; /* Memory for nextBaseVop U */
78459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->nextBaseVop->vChan = video->nextBaseVop->uChan + (size >> 2); /* Memory for nextBaseVop V */
78559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
78659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (offset)
78759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
78859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->nextBaseVop->yChan += offset; /* offset to the origin.*/
78959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->nextBaseVop->uChan += (offset >> 2) + 4;
79059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->nextBaseVop->vChan += (offset >> 2) + 4;
79159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
79259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
79359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
79459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (nLayers > 1)   /* If enhancement layers */
79559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
79659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->prevEnhanceVop = (Vop *) M4VENC_MALLOC(sizeof(Vop));      /* Memory for Previous Enhancement Vop */
79759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->prevEnhanceVop == NULL) goto CLEAN_UP;
79859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->prevEnhanceVop->yChan = (PIXEL *) M4VENC_MALLOC(sizeof(PIXEL) * (size + (size >> 1))); /* Memory for Previous Ehancement Y */
79959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->prevEnhanceVop->yChan == NULL) goto CLEAN_UP;
80059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->prevEnhanceVop->uChan = video->prevEnhanceVop->yChan + size; /* Memory for Previous Enhancement U */
80159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->prevEnhanceVop->vChan = video->prevEnhanceVop->uChan + (size >> 2); /* Memory for Previous Enhancement V */
80259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
80359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (offset)
80459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
80559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->prevEnhanceVop->yChan += offset; /* offset to the origin.*/
80659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->prevEnhanceVop->uChan += (offset >> 2) + 4;
80759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->prevEnhanceVop->vChan += (offset >> 2) + 4;
80859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
80959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
81059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
81159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->numberOfLayers = nLayers; /* Number of Layers */
81259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->sumMAD = 0;
81359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
81459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
81559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* 04/09/01, for Vops in the use multipass processing */
81659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (idx = 0; idx < nLayers; idx++)
81759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
81859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->pMP[idx] = (MultiPass *)M4VENC_MALLOC(sizeof(MultiPass));
81959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->pMP[idx] == NULL)    goto CLEAN_UP;
82059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        M4VENC_MEMSET(video->pMP[idx], 0, sizeof(MultiPass));
82159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
82259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->pMP[idx]->encoded_frames = -1; /* forget about the very first I frame */
82359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
82459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
82559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* RDInfo **pRDSamples */
82659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->pMP[idx]->pRDSamples = (RDInfo **)M4VENC_MALLOC(30 * sizeof(RDInfo *));
82759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->pMP[idx]->pRDSamples == NULL)    goto CLEAN_UP;
82859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        for (i = 0; i < 30; i++)
82959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
83059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->pMP[idx]->pRDSamples[i] = (RDInfo *)M4VENC_MALLOC(32 * sizeof(RDInfo));
83159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (video->pMP[idx]->pRDSamples[i] == NULL) goto CLEAN_UP;
83259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            for (j = 0; j < 32; j++)    M4VENC_MEMSET(&(video->pMP[idx]->pRDSamples[i][j]), 0, sizeof(RDInfo));
83359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
83459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->pMP[idx]->frameRange = (Int)(video->encParams->LayerFrameRate[idx] * 1.0); /* 1.0s time frame*/
83559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->pMP[idx]->frameRange = PV_MAX(video->pMP[idx]->frameRange, 5);
83659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->pMP[idx]->frameRange = PV_MIN(video->pMP[idx]->frameRange, 30);
83759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
83859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->pMP[idx]->framePos = -1;
83959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
84059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
84159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* /// End /////////////////////////////////////// */
84259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
84359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
84459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->vol = (Vol **)M4VENC_MALLOC(nLayers * sizeof(Vol *)); /* Memory for VOL pointers */
84559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
84659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Memory allocation and Initialization of Vols and writing of headers */
84759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->vol == NULL) goto CLEAN_UP;
84859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
84959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (idx = 0; idx < nLayers; idx++)
85059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
85159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->volInitialize[idx] = 1;
85259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->refTick[idx] = 0;
85359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->relLayerCodeTime[idx] = 1000;
85459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->vol[idx] = (Vol *)M4VENC_MALLOC(sizeof(Vol));
85559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->vol[idx] == NULL)  goto CLEAN_UP;
85659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
85759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol = video->vol[idx];
85859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pEncParams = video->encParams;
85959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
86059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        M4VENC_MEMSET(video->vol[idx], 0, sizeof(Vol));
86159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* Initialize some VOL parameters */
86259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->volID = idx;  /* Set VOL ID */
86359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->shortVideoHeader = pEncParams->H263_Enabled; /*Short Header */
86459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->GOVStart = pEncParams->GOV_Enabled; /* GOV Header */
86559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->timeIncrementResolution = video->encParams->TimeIncrementRes;
86659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->nbitsTimeIncRes = 1;
86759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        while (pVol->timeIncrementResolution > (1 << pVol->nbitsTimeIncRes))
86859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
86959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pVol->nbitsTimeIncRes++;
87059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
87159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
87259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* timing stuff */
87359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->timeIncrement = 0;
87459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->moduloTimeBase = 0;
87559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->fixedVopRate = 0; /* No fixed VOP rate */
87659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->stream = (BitstreamEncVideo *)M4VENC_MALLOC(sizeof(BitstreamEncVideo)); /* allocate BitstreamEncVideo Instance */
87759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (pVol->stream == NULL)  goto CLEAN_UP;
87859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
87959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->width = pEncParams->LayerWidth[idx];      /* Layer Width */
88059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->height = pEncParams->LayerHeight[idx];    /* Layer Height */
88159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        //  pVol->intra_acdcPredDisable = pEncParams->ACDCPrediction; /* ACDC Prediction */
88259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->ResyncMarkerDisable = pEncParams->ResyncMarkerDisable; /* Resync Marker Mode */
88359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->dataPartitioning = pEncParams->DataPartitioning; /* Data Partitioning */
88459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->useReverseVLC = pEncParams->ReversibleVLC; /* RVLC */
88559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (idx > 0) /* Scalability layers */
88659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
88759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pVol->ResyncMarkerDisable = 1;
88859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pVol->dataPartitioning = 0;
88959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pVol->useReverseVLC = 0; /*  No RVLC */
89059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
89159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->quantType = pEncParams->QuantType[idx];           /* Quantizer Type */
89259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
89359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* no need to init Quant Matrices */
89459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
89559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->scalability = 0;  /* Vol Scalability */
89659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (idx > 0)
89759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pVol->scalability = 1; /* Multiple layers => Scalability */
89859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
89959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* Initialize Vol to Temporal scalability.  It can change during encoding */
90059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->scalType = 1;
90159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* Initialize reference Vol ID to the base layer = 0 */
90259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->refVolID = 0;
90359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* Initialize layer resolution to same as the reference */
90459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->refSampDir = 0;
90559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->horSamp_m = 1;
90659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->horSamp_n = 1;
90759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->verSamp_m = 1;
90859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->verSamp_n = 1;
90959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->enhancementType = 0; /* We always enhance the entire region */
91059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
91159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->nMBPerRow = (pVol->width + 15) / 16;
91259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->nMBPerCol = (pVol->height + 15) / 16;
91359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pVol->nTotalMB = pVol->nMBPerRow * pVol->nMBPerCol;
91459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
91559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (pVol->nTotalMB >= 1)
91659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pVol->nBitsForMBID = 1;
91759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (pVol->nTotalMB >= 3)
91859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pVol->nBitsForMBID = 2;
91959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (pVol->nTotalMB >= 5)
92059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pVol->nBitsForMBID = 3;
92159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (pVol->nTotalMB >= 9)
92259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pVol->nBitsForMBID = 4;
92359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (pVol->nTotalMB >= 17)
92459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pVol->nBitsForMBID = 5;
92559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (pVol->nTotalMB >= 33)
92659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pVol->nBitsForMBID = 6;
92759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (pVol->nTotalMB >= 65)
92859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pVol->nBitsForMBID = 7;
92959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (pVol->nTotalMB >= 129)
93059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pVol->nBitsForMBID = 8;
93159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (pVol->nTotalMB >= 257)
93259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pVol->nBitsForMBID = 9;
93359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (pVol->nTotalMB >= 513)
93459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pVol->nBitsForMBID = 10;
93559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (pVol->nTotalMB >= 1025)
93659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pVol->nBitsForMBID = 11;
93759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (pVol->nTotalMB >= 2049)
93859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pVol->nBitsForMBID = 12;
93959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (pVol->nTotalMB >= 4097)
94059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pVol->nBitsForMBID = 13;
94159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (pVol->nTotalMB >= 8193)
94259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pVol->nBitsForMBID = 14;
94359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (pVol->nTotalMB >= 16385)
94459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pVol->nBitsForMBID = 15;
94559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (pVol->nTotalMB >= 32769)
94659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pVol->nBitsForMBID = 16;
94759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (pVol->nTotalMB >= 65537)
94859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pVol->nBitsForMBID = 17;
94959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (pVol->nTotalMB >= 131073)
95059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pVol->nBitsForMBID = 18;
95159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
95259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (pVol->shortVideoHeader)
95359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
95459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            switch (pVol->width)
95559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
95659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                case 128:
95759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if (pVol->height == 96)  /* source_format = 1 */
95859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    {
95959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        pVol->nGOBinVop = 6;
96059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        pVol->nMBinGOB = 8;
96159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    }
96259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    else
96359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        status = PV_FALSE;
96459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    break;
96559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
96659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                case 176:
96759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if (pVol->height == 144)  /* source_format = 2 */
96859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    {
96959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        pVol->nGOBinVop = 9;
97059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        pVol->nMBinGOB = 11;
97159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    }
97259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    else
97359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        status = PV_FALSE;
97459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    break;
97559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                case 352:
97659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if (pVol->height == 288)  /* source_format = 2 */
97759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    {
97859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        pVol->nGOBinVop = 18;
97959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        pVol->nMBinGOB = 22;
98059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    }
98159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    else
98259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        status = PV_FALSE;
98359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    break;
98459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
98559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                case 704:
98659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if (pVol->height == 576)  /* source_format = 2 */
98759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    {
98859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        pVol->nGOBinVop = 18;
98959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        pVol->nMBinGOB = 88;
99059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    }
99159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    else
99259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        status = PV_FALSE;
99359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    break;
99459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                case 1408:
99559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if (pVol->height == 1152)  /* source_format = 2 */
99659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    {
99759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        pVol->nGOBinVop = 18;
99859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        pVol->nMBinGOB = 352;
99959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    }
100059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    else
100159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        status = PV_FALSE;
100259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    break;
100359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
100459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                default:
100559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    status = PV_FALSE;
100659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    break;
100759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
100859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
100959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
101059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
101159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /***************************************************/
101259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* allocate and initialize rate control parameters */
101359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /***************************************************/
101459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
101559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* BEGIN INITIALIZATION OF ANNEX L RATE CONTROL */
101659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->encParams->RC_Type != CONSTANT_Q)
101759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
101859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        for (idx = 0; idx < nLayers; idx++) /* 12/25/00 */
101959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
102059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->rc[idx] =
102159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                (rateControl *)M4VENC_MALLOC(sizeof(rateControl));
102259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
102359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (video->rc[idx] == NULL) goto CLEAN_UP;
102459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
102559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            M4VENC_MEMSET(video->rc[idx], 0, sizeof(rateControl));
102659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
102759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (PV_SUCCESS != RC_Initialize(video))
102859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
102959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            goto CLEAN_UP;
103059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
103159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* initialization for 2-pass rate control */
103259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
103359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* END INITIALIZATION OF ANNEX L RATE CONTROL */
103459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
103559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /********** assign platform dependent functions ***********************/
103659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* 1/23/01 */
103759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* This must be done at run-time not a compile time */
103859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->functionPointer = (FuncPtr*) M4VENC_MALLOC(sizeof(FuncPtr));
103959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->functionPointer == NULL) goto CLEAN_UP;
104059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
104159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->functionPointer->ComputeMBSum = &ComputeMBSum_C;
104259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->functionPointer->SAD_MB_HalfPel[0] = NULL;
104359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->functionPointer->SAD_MB_HalfPel[1] = &SAD_MB_HalfPel_Cxh;
104459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->functionPointer->SAD_MB_HalfPel[2] = &SAD_MB_HalfPel_Cyh;
104559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->functionPointer->SAD_MB_HalfPel[3] = &SAD_MB_HalfPel_Cxhyh;
104659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
104759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef NO_INTER4V
104859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->functionPointer->SAD_Blk_HalfPel = &SAD_Blk_HalfPel_C;
104959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->functionPointer->SAD_Block = &SAD_Block_C;
105059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
105159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->functionPointer->SAD_Macroblock = &SAD_Macroblock_C;
105259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->functionPointer->ChooseMode = &ChooseMode_C;
105359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->functionPointer->GetHalfPelMBRegion = &GetHalfPelMBRegion_C;
105459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//  video->functionPointer->SAD_MB_PADDING = &SAD_MB_PADDING; /* 4/21/01 */
105559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
105659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
105759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encoderControl->videoEncoderInit = 1;  /* init done! */
105859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
105959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return PV_TRUE;
106059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
106159f566c4ec3dfc097ad8163523e522280b27e5c3James DongCLEAN_UP:
106259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    PVCleanUpVideoEncoder(encoderControl);
106359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
106459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return PV_FALSE;
106559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
106659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
106759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
106859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
106959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : PVCleanUpVideoEncoder()                                      */
107059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 08/22/2000                                                   */
107159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Deallocates allocated memory from InitVideoEncoder()         */
107259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
107359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
107459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified : 5/21/01, free only yChan in Vop                          */
107559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
107659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
107759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
107859f566c4ec3dfc097ad8163523e522280b27e5c3James DongOSCL_EXPORT_REF Bool    PVCleanUpVideoEncoder(VideoEncControls *encoderControl)
107959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
108059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int idx, i;
108159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncData *video = (VideoEncData *)encoderControl->videoEncoderData;
108259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    int nTotalMB;
108359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    int max_width, offset;
108459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
108559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef PRINT_RC_INFO
108659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (facct != NULL)
108759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
108859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
108959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        fprintf(facct, "TOTAL NUM BITS GENERATED %d\n", tiTotalNumBitsGenerated);
109059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
109159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        fprintf(facct, "TOTAL NUMBER OF FRAMES CODED %d\n",
109259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->encParams->rc[0]->totalFrameNumber);
109359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
109459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        fprintf(facct, "Average BitRate %d\n",
109559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                (tiTotalNumBitsGenerated / (90 / 30)));
109659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
109759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        fprintf(facct, "TOTAL NUMBER OF STUFF BITS %d\n", (iStuffBits + 10740));
109859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
109959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        fprintf(facct, "TOTAL NUMBER OF BITS TO NETWORK %d\n", (35800*90 / 30));;
110059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
110159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        fprintf(facct, "SUM OF STUFF BITS AND GENERATED BITS %d\n",
110259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                (tiTotalNumBitsGenerated + iStuffBits + 10740));
110359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
110459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        fprintf(facct, "UNACCOUNTED DIFFERENCE %d\n",
110559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                ((35800*90 / 30) - (tiTotalNumBitsGenerated + iStuffBits + 10740)));
110659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
110759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        fclose(facct);
110859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
110959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
111059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
111159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef PRINT_EC
111259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    fclose(fec);
111359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
111459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
111559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video != NULL)
111659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
111759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
111859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->QPMB) M4VENC_FREE(video->QPMB);
111959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->headerInfo.Mode)M4VENC_FREE(video->headerInfo.Mode);
112059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->headerInfo.CBP)M4VENC_FREE(video->headerInfo.CBP);
112159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
112259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
112359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->mot)
112459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
112559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            nTotalMB = video->vol[0]->nTotalMB;
112659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            for (idx = 1; idx < video->currLayer; idx++)
112759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (video->vol[idx]->nTotalMB > nTotalMB)
112859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    nTotalMB = video->vol[idx]->nTotalMB;
112959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            for (idx = 0; idx < nTotalMB; idx++)
113059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
113159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (video->mot[idx])
113259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    M4VENC_FREE(video->mot[idx]);
113359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
113459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            M4VENC_FREE(video->mot);
113559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
113659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
113759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->intraArray) M4VENC_FREE(video->intraArray);
113859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
113959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->sliceNo)M4VENC_FREE(video->sliceNo);
114059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->acPredFlag)M4VENC_FREE(video->acPredFlag);
114159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//      if(video->predDCAC)M4VENC_FREE(video->predDCAC);
114259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->predDC) M4VENC_FREE(video->predDC);
114359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->predDCAC_row = NULL;
114459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->predDCAC_col) M4VENC_FREE(video->predDCAC_col);
114559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->outputMB)M4VENC_FREE(video->outputMB);
114659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
114759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->bitstream1)BitstreamCloseEnc(video->bitstream1);
114859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->bitstream2)BitstreamCloseEnc(video->bitstream2);
114959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->bitstream3)BitstreamCloseEnc(video->bitstream3);
115059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
115159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->overrunBuffer) M4VENC_FREE(video->overrunBuffer);
115259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
115359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        max_width = video->encParams->LayerWidth[0];
115459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        max_width = (((max_width + 15) >> 4) << 4); /* 09/19/05 */
115559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->encParams->H263_Enabled)
115659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
115759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            offset = 0;
115859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
115959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else
116059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
116159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            offset = ((max_width + 32) << 4) + 16;
116259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
116359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
116459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->currVop)
116559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
116659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (video->currVop->yChan)
116759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
116859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->currVop->yChan -= offset;
116959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                M4VENC_FREE(video->currVop->yChan);
117059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
117159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            M4VENC_FREE(video->currVop);
117259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
117359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
117459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->nextBaseVop)
117559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
117659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (video->nextBaseVop->yChan)
117759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
117859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->nextBaseVop->yChan -= offset;
117959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                M4VENC_FREE(video->nextBaseVop->yChan);
118059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
118159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            M4VENC_FREE(video->nextBaseVop);
118259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
118359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
118459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->prevBaseVop)
118559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
118659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (video->prevBaseVop->yChan)
118759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
118859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->prevBaseVop->yChan -= offset;
118959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                M4VENC_FREE(video->prevBaseVop->yChan);
119059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
119159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            M4VENC_FREE(video->prevBaseVop);
119259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
119359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->prevEnhanceVop)
119459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
119559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (video->prevEnhanceVop->yChan)
119659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
119759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->prevEnhanceVop->yChan -= offset;
119859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                M4VENC_FREE(video->prevEnhanceVop->yChan);
119959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
120059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            M4VENC_FREE(video->prevEnhanceVop);
120159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
120259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
120359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* 04/09/01, for Vops in the use multipass processing */
120459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        for (idx = 0; idx < video->encParams->nLayers; idx++)
120559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
120659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (video->pMP[idx])
120759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
120859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (video->pMP[idx]->pRDSamples)
120959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
121059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    for (i = 0; i < 30; i++)
121159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    {
121259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        if (video->pMP[idx]->pRDSamples[i])
121359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            M4VENC_FREE(video->pMP[idx]->pRDSamples[i]);
121459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    }
121559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    M4VENC_FREE(video->pMP[idx]->pRDSamples);
121659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
121759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
121859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                M4VENC_MEMSET(video->pMP[idx], 0, sizeof(MultiPass));
121959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                M4VENC_FREE(video->pMP[idx]);
122059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
122159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
122259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* //  End /////////////////////////////////////// */
122359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
122459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->vol)
122559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
122659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            for (idx = 0; idx < video->encParams->nLayers; idx++)
122759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
122859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (video->vol[idx])
122959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
123059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if (video->vol[idx]->stream)
123159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        M4VENC_FREE(video->vol[idx]->stream);
123259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    M4VENC_FREE(video->vol[idx]);
123359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
123459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
123559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            M4VENC_FREE(video->vol);
123659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
123759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
123859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /***************************************************/
123959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* stop rate control parameters */
124059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /***************************************************/
124159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
124259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* ANNEX L RATE CONTROL */
124359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->encParams->RC_Type != CONSTANT_Q)
124459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
124559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            RC_Cleanup(video->rc, video->encParams->nLayers);
124659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
124759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            for (idx = 0; idx < video->encParams->nLayers; idx++)
124859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
124959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (video->rc[idx])
125059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    M4VENC_FREE(video->rc[idx]);
125159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
125259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
125359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
125459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->functionPointer) M4VENC_FREE(video->functionPointer);
125559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
125659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* If application has called PVCleanUpVideoEncoder then we deallocate */
125759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* If PVInitVideoEncoder class it, then we DO NOT deallocate */
125859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->encParams)
125959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
126059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            M4VENC_FREE(video->encParams);
126159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
126259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
126359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        M4VENC_FREE(video);
126459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        encoderControl->videoEncoderData = NULL; /* video */
126559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
126659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
126759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encoderControl->videoEncoderInit = 0;
126859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
126959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return PV_TRUE;
127059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
127159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
127259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
127359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : PVGetVolHeader()                                             */
127459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 7/17/2001,                                                   */
127559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  :                                                              */
127659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
127759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
127859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
127959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
128059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
128159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
128259f566c4ec3dfc097ad8163523e522280b27e5c3James DongOSCL_EXPORT_REF Bool PVGetVolHeader(VideoEncControls *encCtrl, UChar *volHeader, Int *size, Int layer)
128359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
128459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncData    *encData;
128559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    PV_STATUS   EncodeVOS_Start(VideoEncControls *encCtrl);
128659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encData = (VideoEncData *)encCtrl->videoEncoderData;
128759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
128859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
128959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encData == NULL)
129059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
129159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encData->encParams == NULL)
129259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
129359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
129459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
129559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encData->currLayer = layer; /* Set Layer */
129659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*pv_status = */
129759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    EncodeVOS_Start(encCtrl); /* Encode VOL Header */
129859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
129959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encData->encParams->GetVolHeader[layer] = 1; /* Set usage flag: Needed to support old method*/
130059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
130159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Copy bitstream to buffer and set the size */
130259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
130359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (*size > encData->bitstream1->byteCount)
130459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
130559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        *size = encData->bitstream1->byteCount;
130659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        M4VENC_MEMCPY(volHeader, encData->bitstream1->bitstreamBuffer, *size);
130759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
130859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
130959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
131059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
131159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Reset bitstream1 buffer parameters */
131259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    BitstreamEncReset(encData->bitstream1);
131359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
131459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return PV_TRUE;
131559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
131659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
131759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
131859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : PVGetOverrunBuffer()                                         */
131959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Get the overrun buffer `                                     */
132059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
132159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   : Pointer to overrun buffer.                                   */
132259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
132359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
132459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
132559f566c4ec3dfc097ad8163523e522280b27e5c3James DongOSCL_EXPORT_REF UChar* PVGetOverrunBuffer(VideoEncControls *encCtrl)
132659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
132759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncData *video = (VideoEncData *)encCtrl->videoEncoderData;
132859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int currLayer = video->currLayer;
132959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vol *currVol = video->vol[currLayer];
133059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
133159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (currVol->stream->bitstreamBuffer != video->overrunBuffer) // not used
133259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
133359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return NULL;
133459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
133559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
133659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return video->overrunBuffer;
133759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
133859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
133959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
134059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
134159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
134259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
134359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : EncodeVideoFrame()                                           */
134459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 08/22/2000                                                   */
134559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Encode video frame and return bitstream                      */
134659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
134759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
134859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
134959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  02.14.2001                                      */
135059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*              Finishing new timestamp 32-bit input                        */
135159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*              Applications need to take care of wrap-around               */
135259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
135359f566c4ec3dfc097ad8163523e522280b27e5c3James DongOSCL_EXPORT_REF Bool PVEncodeVideoFrame(VideoEncControls *encCtrl, VideoEncFrameIO *vid_in, VideoEncFrameIO *vid_out,
135459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                        ULong *nextModTime, UChar *bstream, Int *size, Int *nLayer)
135559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
135659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Bool status = PV_TRUE;
135759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    PV_STATUS pv_status;
135859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncData *video = (VideoEncData *)encCtrl->videoEncoderData;
135959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncParams *encParams = video->encParams;
136059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vol *currVol;
136159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vop *tempForwRefVop = NULL;
136259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int tempRefSelCode = 0;
136359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    PV_STATUS   EncodeVOS_Start(VideoEncControls *encCtrl);
136459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int width_16, height_16;
136559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int width, height;
136659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vop *temp;
136759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int encodeVop = 0;
136859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void  PaddingEdge(Vop *padVop);
136959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int currLayer = -1;
137059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    //Int nLayers = encParams->nLayers;
137159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
137259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    ULong modTime = vid_in->timestamp;
137359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
137459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef RANDOM_REFSELCODE   /* add random selection of reference Vop */
137559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    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};
137659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    static Int rand_idx = 0;
137759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
137859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
137959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*******************************************************/
138059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Determine Next Vop to encode, if any, and nLayer    */
138159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*******************************************************/
138259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    //i = nLayers-1;
138359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
138459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->volInitialize[0]) /* first vol to code */
138559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
138659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->nextModTime = video->modTimeRef = ((modTime) - ((modTime) % 1000));
138759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
138859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
138959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encodeVop = DetermineCodingLayer(video, nLayer, modTime);
139059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    currLayer = *nLayer;
139159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if ((currLayer < 0) || (currLayer > encParams->nLayers - 1))
139259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
139359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
139459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /******************************************/
139559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* If post-skipping still effective --- return */
139659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /******************************************/
139759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
139859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (!encodeVop) /* skip enh layer, no base layer coded --- return */
139959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
140059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef _PRINT_STAT
140159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        printf("No frame coded. Continue to next frame.");
140259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
140359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* expected next code time, convert back to millisec */
140459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        *nextModTime = video->nextModTime;
140559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
140659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef ALLOW_VOP_NOT_CODED
140759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->vol[0]->shortVideoHeader) /* Short Video Header = 1 */
140859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
140959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            *size = 0;
141059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            *nLayer = -1;
141159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
141259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else
141359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
141459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            *nLayer = 0;
141559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            EncodeVopNotCoded(video, bstream, size, modTime);
141659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            *size = video->vol[0]->stream->byteCount;
141759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
141859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#else
141959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        *size = 0;
142059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        *nLayer = -1;
142159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
142259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return status;
142359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
142459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
142559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
142659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//ENCODE_VOP_AGAIN:  /* 12/30/00 */
142759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
142859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /**************************************************************/
142959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Initialize Vol stream structure with application bitstream */
143059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /**************************************************************/
143159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
143259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    currVol = video->vol[currLayer];
143359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    currVol->stream->bitstreamBuffer = bstream;
143459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    currVol->stream->bufferSize = *size;
143559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    BitstreamEncReset(currVol->stream);
143659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    BitstreamSetOverrunBuffer(currVol->stream, video->overrunBuffer, video->oBSize, video);
143759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
143859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /***********************************************************/
143959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Encode VOS and VOL Headers on first call for each layer */
144059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /***********************************************************/
144159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
144259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->volInitialize[currLayer])
144359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
144459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->currVop->timeInc = 0;
144559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->prevBaseVop->timeInc = 0;
144659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (!video->encParams->GetVolHeader[currLayer])
144759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pv_status = EncodeVOS_Start(encCtrl);
144859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
144959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
145059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /***************************************************/
145159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Copy Input Video Frame to Internal Video Buffer */
145259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /***************************************************/
145359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Determine Width and Height of Vop Layer */
145459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
145559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    width = encParams->LayerWidth[currLayer];   /* Get input width */
145659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    height = encParams->LayerHeight[currLayer]; /* Get input height */
145759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Round Up to nearest multiple of 16 : MPEG-4 Standard */
145859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
145959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    width_16 = ((width + 15) / 16) * 16;            /* Round up to nearest multiple of 16 */
146059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    height_16 = ((height + 15) / 16) * 16;          /* Round up to nearest multiple of 16 */
146159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
146259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->input = vid_in;  /* point to the frame input */
146359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
146459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*//  End ////////////////////////////// */
146559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
146659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
146759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /**************************************/
146859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Determine VOP Type                 */
146959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* 6/2/2001, separate function      */
147059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /**************************************/
147159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    DetermineVopType(video, currLayer);
147259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
147359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /****************************/
147459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*    Initialize VOP        */
147559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /****************************/
147659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->volID = currVol->volID;
147759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->width = width_16;
147859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->height = height_16;
147959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->encParams->H263_Enabled) /*  11/28/05 */
148059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
148159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->currVop->pitch = width_16;
148259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
148359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
148459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
148559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->currVop->pitch = width_16 + 32;
148659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
148759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->timeInc = currVol->timeIncrement;
148859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->vopCoded = 1;
148959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->roundingType = 0;
149059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->intraDCVlcThr = encParams->IntraDCVlcThr;
149159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
149259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (currLayer == 0
149359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef RANDOM_REFSELCODE   /* add random selection of reference Vop */
149459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            || random_val[rand_idx] || video->volInitialize[currLayer]
149559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
149659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong       )
149759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
149859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        tempForwRefVop = video->forwardRefVop; /* keep initial state */
149959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (tempForwRefVop != NULL) tempRefSelCode = tempForwRefVop->refSelectCode;
150059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
150159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->forwardRefVop = video->prevBaseVop;
150259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->forwardRefVop->refSelectCode = 1;
150359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
150459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef RANDOM_REFSELCODE
150559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
150659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
150759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        tempForwRefVop = video->forwardRefVop; /* keep initial state */
150859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (tempForwRefVop != NULL) tempRefSelCode = tempForwRefVop->refSelectCode;
150959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
151059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->forwardRefVop = video->prevEnhanceVop;
151159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->forwardRefVop->refSelectCode = 0;
151259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
151359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    rand_idx++;
151459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    rand_idx %= 30;
151559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
151659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
151759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->refSelectCode = video->forwardRefVop->refSelectCode;
151859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->gobNumber = 0;
151959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->gobFrameID = video->currVop->predictionType;
152059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->temporalRef = (modTime * 30 / 1001) % 256;
152159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
152259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->temporalInterval = 0;
152359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
152459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->currVop->predictionType == I_VOP)
152559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->currVop->quantizer = encParams->InitQuantIvop[currLayer];
152659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
152759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->currVop->quantizer = encParams->InitQuantPvop[currLayer];
152859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
152959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
153059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /****************/
153159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Encode Vop */
153259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /****************/
153359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->slice_coding = 0;
153459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
153559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    pv_status = EncodeVop(video);
153659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef _PRINT_STAT
153759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->currVop->predictionType == I_VOP)
153859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        printf(" I-VOP ");
153959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
154059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        printf(" P-VOP (ref.%d)", video->forwardRefVop->refSelectCode);
154159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
154259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
154359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /************************************/
154459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Update Skip Next Frame           */
154559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /************************************/
154659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    *nLayer = UpdateSkipNextFrame(video, nextModTime, size, pv_status);
154759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (*nLayer == -1) /* skip current frame */
154859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
154959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* make sure that pointers are restored to the previous state */
155059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (currLayer == 0)
155159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
155259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->forwardRefVop = tempForwRefVop; /* For P-Vop base only */
155359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->forwardRefVop->refSelectCode = tempRefSelCode;
155459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
155559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
155659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return status;
155759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
155859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
155959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* If I-VOP was encoded, reset IntraPeriod */
156059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if ((currLayer == 0) && (encParams->IntraPeriod > 0) && (video->currVop->predictionType == I_VOP))
156159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->nextEncIVop = encParams->IntraPeriod;
156259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
156359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Set HintTrack Information */
156459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (currLayer != -1)
156559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
156659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (currVol->prevModuloTimeBase)
156759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->hintTrackInfo.MTB = 1;
156859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else
156959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->hintTrackInfo.MTB = 0;
157059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->hintTrackInfo.LayerID = (UChar)currVol->volID;
157159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->hintTrackInfo.CodeType = (UChar)video->currVop->predictionType;
157259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->hintTrackInfo.RefSelCode = (UChar)video->currVop->refSelectCode;
157359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
157459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
157559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /************************************************/
157659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Determine nLayer and timeInc for next encode */
157759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* 12/27/00 always go by the highest layer*/
157859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /************************************************/
157959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
158059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /**********************************************************/
158159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Copy Reconstructed Buffer to Output Video Frame Buffer */
158259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /**********************************************************/
158359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    vid_out->yChan = video->currVop->yChan;
158459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    vid_out->uChan = video->currVop->uChan;
158559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    vid_out->vChan = video->currVop->vChan;
158659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->encParams->H263_Enabled)
158759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
158859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        vid_out->height = video->currVop->height; /* padded height */
158959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        vid_out->pitch = video->currVop->width; /* padded width */
159059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
159159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
159259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
159359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        vid_out->height = video->currVop->height + 32; /* padded height */
159459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        vid_out->pitch = video->currVop->width + 32; /* padded width */
159559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
159659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    //video_out->timestamp = video->modTime;
159759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    vid_out->timestamp = (ULong)(((video->prevFrameNum[currLayer] * 1000) / encParams->LayerFrameRate[currLayer]) + video->modTimeRef + 0.5);
159859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
159959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*// End /////////////////////// */
160059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
160159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /***********************************/
160259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Update Ouput bstream byte count */
160359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /***********************************/
160459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
160559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    *size = currVol->stream->byteCount;
160659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
160759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /****************************************/
160859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Swap Vop Pointers for Base Layer     */
160959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /****************************************/
161059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (currLayer == 0)
161159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
161259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        temp = video->prevBaseVop;
161359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->prevBaseVop = video->currVop;
161459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->prevBaseVop->padded = 0; /* not padded */
161559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->currVop  = temp;
161659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->forwardRefVop = video->prevBaseVop; /* For P-Vop base only */
161759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->forwardRefVop->refSelectCode = 1;
161859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
161959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
162059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
162159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        temp = video->prevEnhanceVop;
162259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->prevEnhanceVop = video->currVop;
162359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->prevEnhanceVop->padded = 0; /* not padded */
162459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->currVop = temp;
162559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->forwardRefVop = video->prevEnhanceVop;
162659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->forwardRefVop->refSelectCode = 0;
162759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
162859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
162959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /****************************************/
163059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Modify the intialize flag at the end.*/
163159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /****************************************/
163259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->volInitialize[currLayer])
163359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->volInitialize[currLayer] = 0;
163459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
163559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return status;
163659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
163759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
163859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef NO_SLICE_ENCODE
163959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
164059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : PVEncodeFrameSet()                                           */
164159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 04/18/2000                                                   */
164259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Enter a video frame and perform front-end time check plus ME */
164359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
164459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
164559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
164659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
164759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
164859f566c4ec3dfc097ad8163523e522280b27e5c3James DongOSCL_EXPORT_REF Bool PVEncodeFrameSet(VideoEncControls *encCtrl, VideoEncFrameIO *vid_in, ULong *nextModTime, Int *nLayer)
164959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
165059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Bool status = PV_TRUE;
165159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncData *video = (VideoEncData *)encCtrl->videoEncoderData;
165259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncParams *encParams = video->encParams;
165359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vol *currVol;
165459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    PV_STATUS   EncodeVOS_Start(VideoEncControls *encCtrl);
165559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int width_16, height_16;
165659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int width, height;
165759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int encodeVop = 0;
165859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void  PaddingEdge(Vop *padVop);
165959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int currLayer = -1;
166059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    //Int nLayers = encParams->nLayers;
166159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
166259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    ULong   modTime = vid_in->timestamp;
166359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
166459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef RANDOM_REFSELCODE   /* add random selection of reference Vop */
166559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    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};
166659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    static Int rand_idx = 0;
166759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
166859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*******************************************************/
166959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Determine Next Vop to encode, if any, and nLayer    */
167059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*******************************************************/
167159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
167259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->modTime = modTime;
167359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
167459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    //i = nLayers-1;
167559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
167659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->volInitialize[0]) /* first vol to code */
167759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
167859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->nextModTime = video->modTimeRef = ((modTime) - ((modTime) % 1000));
167959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
168059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
168159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
168259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encodeVop = DetermineCodingLayer(video, nLayer, modTime);
168359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
168459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    currLayer = *nLayer;
168559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
168659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /******************************************/
168759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* If post-skipping still effective --- return */
168859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /******************************************/
168959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
169059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (!encodeVop) /* skip enh layer, no base layer coded --- return */
169159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
169259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef _PRINT_STAT
169359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        printf("No frame coded. Continue to next frame.");
169459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
169559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        *nLayer = -1;
169659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
169759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* expected next code time, convert back to millisec */
169859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        *nextModTime = video->nextModTime;;
169959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return status;
170059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
170159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
170259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /**************************************************************/
170359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Initialize Vol stream structure with application bitstream */
170459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /**************************************************************/
170559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
170659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    currVol = video->vol[currLayer];
170759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    currVol->stream->bufferSize = 0;
170859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    BitstreamEncReset(currVol->stream);
170959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
171059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /***********************************************************/
171159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Encode VOS and VOL Headers on first call for each layer */
171259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /***********************************************************/
171359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
171459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->volInitialize[currLayer])
171559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
171659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->currVop->timeInc = 0;
171759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->prevBaseVop->timeInc = 0;
171859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
171959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
172059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /***************************************************/
172159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Copy Input Video Frame to Internal Video Buffer */
172259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /***************************************************/
172359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Determine Width and Height of Vop Layer */
172459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
172559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    width = encParams->LayerWidth[currLayer];   /* Get input width */
172659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    height = encParams->LayerHeight[currLayer]; /* Get input height */
172759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Round Up to nearest multiple of 16 : MPEG-4 Standard */
172859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
172959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    width_16 = ((width + 15) / 16) * 16;            /* Round up to nearest multiple of 16 */
173059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    height_16 = ((height + 15) / 16) * 16;          /* Round up to nearest multiple of 16 */
173159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
173259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->input = vid_in;  /* point to the frame input */
173359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
173459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*//  End ////////////////////////////// */
173559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
173659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
173759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /**************************************/
173859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Determine VOP Type                 */
173959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* 6/2/2001, separate function      */
174059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /**************************************/
174159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    DetermineVopType(video, currLayer);
174259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
174359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /****************************/
174459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*    Initialize VOP        */
174559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /****************************/
174659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->volID = currVol->volID;
174759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->width = width_16;
174859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->height = height_16;
174959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->encParams->H263_Enabled) /*  11/28/05 */
175059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
175159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->currVop->pitch = width_16;
175259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
175359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
175459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
175559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->currVop->pitch = width_16 + 32;
175659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
175759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->timeInc = currVol->timeIncrement;
175859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->vopCoded = 1;
175959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->roundingType = 0;
176059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->intraDCVlcThr = encParams->IntraDCVlcThr;
176159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
176259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (currLayer == 0
176359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef RANDOM_REFSELCODE   /* add random selection of reference Vop */
176459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            || random_val[rand_idx] || video->volInitialize[currLayer]
176559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
176659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong       )
176759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
176859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->tempForwRefVop = video->forwardRefVop; /* keep initial state */
176959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->tempForwRefVop != NULL) video->tempRefSelCode = video->tempForwRefVop->refSelectCode;
177059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
177159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->forwardRefVop = video->prevBaseVop;
177259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->forwardRefVop->refSelectCode = 1;
177359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
177459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef RANDOM_REFSELCODE
177559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
177659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
177759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->tempForwRefVop = video->forwardRefVop; /* keep initial state */
177859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->tempForwRefVop != NULL) video->tempRefSelCode = video->tempForwRefVop->refSelectCode;
177959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
178059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->forwardRefVop = video->prevEnhanceVop;
178159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->forwardRefVop->refSelectCode = 0;
178259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
178359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    rand_idx++;
178459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    rand_idx %= 30;
178559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
178659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
178759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->refSelectCode = video->forwardRefVop->refSelectCode;
178859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->gobNumber = 0;
178959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->gobFrameID = video->currVop->predictionType;
179059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->temporalRef = ((modTime) * 30 / 1001) % 256;
179159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
179259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->currVop->temporalInterval = 0;
179359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
179459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->currVop->predictionType == I_VOP)
179559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->currVop->quantizer = encParams->InitQuantIvop[currLayer];
179659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
179759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->currVop->quantizer = encParams->InitQuantPvop[currLayer];
179859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
179959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /****************/
180059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Encode Vop   */
180159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /****************/
180259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->slice_coding = 1;
180359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
180459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*pv_status =*/
180559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    EncodeVop(video);
180659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
180759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef _PRINT_STAT
180859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->currVop->predictionType == I_VOP)
180959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        printf(" I-VOP ");
181059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
181159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        printf(" P-VOP (ref.%d)", video->forwardRefVop->refSelectCode);
181259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
181359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
181459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Set HintTrack Information */
181559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (currVol->prevModuloTimeBase)
181659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->hintTrackInfo.MTB = 1;
181759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
181859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->hintTrackInfo.MTB = 0;
181959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
182059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->hintTrackInfo.LayerID = (UChar)currVol->volID;
182159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->hintTrackInfo.CodeType = (UChar)video->currVop->predictionType;
182259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->hintTrackInfo.RefSelCode = (UChar)video->currVop->refSelectCode;
182359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
182459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return status;
182559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
182659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif /* NO_SLICE_ENCODE */
182759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
182859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef NO_SLICE_ENCODE
182959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
183059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : PVEncodePacket()                                             */
183159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 04/18/2002                                                   */
183259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Encode one packet and return bitstream                       */
183359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
183459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
183559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
183659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
183759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
183859f566c4ec3dfc097ad8163523e522280b27e5c3James DongOSCL_EXPORT_REF Bool PVEncodeSlice(VideoEncControls *encCtrl, UChar *bstream, Int *size,
183959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                   Int *endofFrame, VideoEncFrameIO *vid_out, ULong *nextModTime)
184059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
184159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    PV_STATUS pv_status;
184259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncData *video = (VideoEncData *)encCtrl->videoEncoderData;
184359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncParams *encParams = video->encParams;
184459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vol *currVol;
184559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    PV_STATUS   EncodeVOS_Start(VideoEncControls *encCtrl);
184659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vop *temp;
184759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void  PaddingEdge(Vop *padVop);
184859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int currLayer = video->currLayer;
184959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int pre_skip;
185059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int pre_size;
185159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /**************************************************************/
185259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Initialize Vol stream structure with application bitstream */
185359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /**************************************************************/
185459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
185559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    currVol = video->vol[currLayer];
185659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    currVol->stream->bitstreamBuffer = bstream;
185759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    pre_size = currVol->stream->byteCount;
185859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    currVol->stream->bufferSize = pre_size + (*size);
185959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
186059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /***********************************************************/
186159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Encode VOS and VOL Headers on first call for each layer */
186259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /***********************************************************/
186359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
186459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->volInitialize[currLayer])
186559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
186659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (!video->encParams->GetVolHeader[currLayer])
186759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pv_status = EncodeVOS_Start(encCtrl);
186859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
186959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
187059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /****************/
187159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Encode Slice */
187259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /****************/
187359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    pv_status = EncodeSlice(video);
187459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
187559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    *endofFrame = 0;
187659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
187759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->mbnum >= currVol->nTotalMB && !video->end_of_buf)
187859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
187959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        *endofFrame = 1;
188059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
188159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /************************************/
188259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* Update Skip Next Frame           */
188359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /************************************/
188459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        pre_skip = UpdateSkipNextFrame(video, nextModTime, size, pv_status); /* modified such that no pre-skipped */
188559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
188659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (pre_skip == -1) /* error */
188759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
188859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            *endofFrame = -1;
188959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* make sure that pointers are restored to the previous state */
189059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (currLayer == 0)
189159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
189259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->forwardRefVop = video->tempForwRefVop; /* For P-Vop base only */
189359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->forwardRefVop->refSelectCode = video->tempRefSelCode;
189459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
189559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
189659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            return pv_status;
189759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
189859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
189959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* If I-VOP was encoded, reset IntraPeriod */
190059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if ((currLayer == 0) && (encParams->IntraPeriod > 0) && (video->currVop->predictionType == I_VOP))
190159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->nextEncIVop = encParams->IntraPeriod;
190259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
190359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /**********************************************************/
190459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* Copy Reconstructed Buffer to Output Video Frame Buffer */
190559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /**********************************************************/
190659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        vid_out->yChan = video->currVop->yChan;
190759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        vid_out->uChan = video->currVop->uChan;
190859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        vid_out->vChan = video->currVop->vChan;
190959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->encParams->H263_Enabled)
191059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
191159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            vid_out->height = video->currVop->height; /* padded height */
191259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            vid_out->pitch = video->currVop->width; /* padded width */
191359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
191459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else
191559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
191659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            vid_out->height = video->currVop->height + 32; /* padded height */
191759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            vid_out->pitch = video->currVop->width + 32; /* padded width */
191859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
191959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        //vid_out->timestamp = video->modTime;
192059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        vid_out->timestamp = (ULong)(((video->prevFrameNum[currLayer] * 1000) / encParams->LayerFrameRate[currLayer]) + video->modTimeRef + 0.5);
192159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
192259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /*// End /////////////////////// */
192359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
192459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /****************************************/
192559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* Swap Vop Pointers for Base Layer     */
192659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /****************************************/
192759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
192859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (currLayer == 0)
192959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
193059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            temp = video->prevBaseVop;
193159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->prevBaseVop = video->currVop;
193259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->prevBaseVop->padded = 0; /* not padded */
193359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->currVop = temp;
193459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->forwardRefVop = video->prevBaseVop; /* For P-Vop base only */
193559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->forwardRefVop->refSelectCode = 1;
193659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
193759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else
193859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
193959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            temp = video->prevEnhanceVop;
194059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->prevEnhanceVop = video->currVop;
194159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->prevEnhanceVop->padded = 0; /* not padded */
194259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->currVop = temp;
194359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->forwardRefVop = video->prevEnhanceVop;
194459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->forwardRefVop->refSelectCode = 0;
194559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
194659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
194759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
194859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /***********************************/
194959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Update Ouput bstream byte count */
195059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /***********************************/
195159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
195259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    *size = currVol->stream->byteCount - pre_size;
195359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
195459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /****************************************/
195559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Modify the intialize flag at the end.*/
195659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /****************************************/
195759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->volInitialize[currLayer])
195859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->volInitialize[currLayer] = 0;
195959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
196059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return pv_status;
196159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
196259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif /* NO_SLICE_ENCODE */
196359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
196459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
196559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
196659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : PVGetH263ProfileLevelID()                                    */
196759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 02/05/2003                                                   */
196859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Get H.263 Profile ID and level ID for profile 0              */
196959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   : Profile ID=0, levelID is what we want                        */
197059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
197159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
197259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Note     : h263Level[8], rBR_bound[8], max_h263_framerate[2]            */
197359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*             max_h263_width[2], max_h263_height[2] are global             */
197459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
197559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
197659f566c4ec3dfc097ad8163523e522280b27e5c3James DongOSCL_EXPORT_REF Bool PVGetH263ProfileLevelID(VideoEncControls *encCtrl, Int *profileID, Int *levelID)
197759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
197859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncData *encData;
197959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int width, height;
198059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    float bitrate_r, framerate;
198159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
198259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
198359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* For this version, we only support H.263 profile 0 */
198459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    *profileID = 0;
198559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
198659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    *levelID = 0;
198759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encData = (VideoEncData *)encCtrl->videoEncoderData;
198859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
198959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encData == NULL)
199059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
199159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encData->encParams == NULL)
199259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
199359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
199459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (!encData->encParams->H263_Enabled) return PV_FALSE;
199559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
199659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
199759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* get image width, height, bitrate and framerate */
199859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    width     = encData->encParams->LayerWidth[0];
199959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    height    = encData->encParams->LayerHeight[0];
200059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    bitrate_r = (float)(encData->encParams->LayerBitRate[0]) / (float)64000.0;
200159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    framerate = encData->encParams->LayerFrameRate[0];
200259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (!width || !height || !(bitrate_r > 0 && framerate > 0)) return PV_FALSE;
200359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
200459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* This is the most frequent case : level 10 */
200559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (bitrate_r <= rBR_bound[1] && framerate <= max_h263_framerate[0] &&
200659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            (width <= max_h263_width[0] && height <= max_h263_height[0]))
200759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
200859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        *levelID = h263Level[1];
200959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_TRUE;
201059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
201159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else if (bitrate_r > rBR_bound[4] ||
201259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong             (width > max_h263_width[1] || height > max_h263_height[1]) ||
201359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong             framerate > max_h263_framerate[1])    /* check the highest level 70 */
201459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
201559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        *levelID = h263Level[7];
201659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_TRUE;
201759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
201859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else   /* search level 20, 30, 40 */
201959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
202059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
202159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* pick out level 20 */
202259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (bitrate_r <= rBR_bound[2] &&
202359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                ((width <= max_h263_width[0] && height <= max_h263_height[0] && framerate <= max_h263_framerate[1]) ||
202459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                 (width <= max_h263_width[1] && height <= max_h263_height[1] && framerate <= max_h263_framerate[0])))
202559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
202659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            *levelID = h263Level[2];
202759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            return PV_TRUE;
202859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
202959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else   /* width, height and framerate are ok, now choose level 30 or 40 */
203059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
203159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            *levelID = (bitrate_r <= rBR_bound[3] ? h263Level[3] : h263Level[4]);
203259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            return PV_TRUE;
203359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
203459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
203559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
203659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
203759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
203859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : PVGetMPEG4ProfileLevelID()                                   */
203959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 26/06/2008                                                   */
204059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Get MPEG4 Level after initialized                            */
204159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   : profile_level according to interface                         */
204259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
204359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
204459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
204559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
204659f566c4ec3dfc097ad8163523e522280b27e5c3James DongOSCL_EXPORT_REF Bool PVGetMPEG4ProfileLevelID(VideoEncControls *encCtrl, Int *profile_level, Int nLayer)
204759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
204859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncData* video;
204959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int i;
205059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
205159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video = (VideoEncData *)encCtrl->videoEncoderData;
205259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
205359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (nLayer == 0)
205459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
205559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        for (i = 0; i < 8; i++)
205659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
205759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (video->encParams->ProfileLevel[0] == profile_level_code[i])
205859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
205959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                break;
206059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
206159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
206259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        *profile_level = i;
206359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
206459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
206559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
206659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        for (i = 0; i < 8; i++)
206759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
206859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (video->encParams->ProfileLevel[0] == scalable_profile_level_code[i])
206959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
207059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                break;
207159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
207259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
207359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        *profile_level = i + SIMPLE_SCALABLE_PROFILE_LEVEL0;
207459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
207559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
207659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return true;
207759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
207859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
207959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef LIMITED_API
208059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
208159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : PVUpdateEncFrameRate                                         */
208259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 04/08/2002                                                   */
208359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Update target frame rates of the encoded base and enhance    */
208459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*             layer(if any) while encoding operation is ongoing            */
208559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
208659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
208759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
208859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
208959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
209059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
209159f566c4ec3dfc097ad8163523e522280b27e5c3James DongOSCL_EXPORT_REF Bool PVUpdateEncFrameRate(VideoEncControls *encCtrl, float *frameRate)
209259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
209359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncData    *encData;
209459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int i;// nTotalMB, mbPerSec;
209559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
209659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encData = (VideoEncData *)encCtrl->videoEncoderData;
209759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
209859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encData == NULL)
209959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
210059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encData->encParams == NULL)
210159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
210259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
210359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Update the framerates for all the layers */
210459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (i = 0; i < encData->encParams->nLayers; i++)
210559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
210659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
210759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* New check: encoding framerate should be consistent with the given profile and level */
210859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        //nTotalMB = (((encData->encParams->LayerWidth[i]+15)/16)*16)*(((encData->encParams->LayerHeight[i]+15)/16)*16)/(16*16);
210959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        //mbPerSec = (Int)(nTotalMB * frameRate[i]);
211059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        //if(mbPerSec > encData->encParams->LayerMaxMbsPerSec[i]) return PV_FALSE;
211159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (frameRate[i] > encData->encParams->LayerMaxFrameRate[i]) return PV_FALSE; /* set by users or profile */
211259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
211359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        encData->encParams->LayerFrameRate[i] = frameRate[i];
211459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
211559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
211659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return RC_UpdateBXRCParams((void*) encData);
211759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
211859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
211959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
212059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef LIMITED_API
212159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
212259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : PVUpdateBitRate                                              */
212359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 04/08/2002                                                   */
212459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Update target bit rates of the encoded base and enhance      */
212559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*             layer(if any) while encoding operation is ongoing            */
212659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
212759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
212859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
212959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
213059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
213159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
213259f566c4ec3dfc097ad8163523e522280b27e5c3James DongOSCL_EXPORT_REF Bool PVUpdateBitRate(VideoEncControls *encCtrl, Int *bitRate)
213359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
213459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncData    *encData;
213559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int i;
213659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
213759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encData = (VideoEncData *)encCtrl->videoEncoderData;
213859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
213959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encData == NULL)
214059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
214159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encData->encParams == NULL)
214259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
214359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
214459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Update the bitrates for all the layers */
214559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (i = 0; i < encData->encParams->nLayers; i++)
214659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
214759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (bitRate[i] > encData->encParams->LayerMaxBitRate[i]) /* set by users or profile */
214859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
214959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            return PV_FALSE;
215059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
215159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        encData->encParams->LayerBitRate[i] = bitRate[i];
215259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
215359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
215459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return RC_UpdateBXRCParams((void*) encData);
215559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
215659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
215759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
215859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef LIMITED_API
215959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ============================================================================ */
216059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : PVUpdateVBVDelay()                                                   */
216159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 4/23/2004                                                        */
216259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Update VBV buffer size(in delay)                                 */
216359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                                  */
216459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   : PV_TRUE if successed, PV_FALSE if failed.                        */
216559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                                  */
216659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                              */
216759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ============================================================================ */
216859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
216959f566c4ec3dfc097ad8163523e522280b27e5c3James DongBool PVUpdateVBVDelay(VideoEncControls *encCtrl, float delay)
217059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
217159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
217259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncData    *encData;
217359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int total_bitrate, max_buffer_size;
217459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    int index;
217559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
217659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encData = (VideoEncData *)encCtrl->videoEncoderData;
217759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
217859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encData == NULL)
217959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
218059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encData->encParams == NULL)
218159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
218259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
218359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Check whether the input delay is valid based on the given profile */
218459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    total_bitrate   = (encData->encParams->nLayers == 1 ? encData->encParams->LayerBitRate[0] :
218559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                       encData->encParams->LayerBitRate[1]);
218659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    index = encData->encParams->profile_table_index;
218759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    max_buffer_size = (encData->encParams->nLayers == 1 ? profile_level_max_VBV_size[index] :
218859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                       scalable_profile_level_max_VBV_size[index]);
218959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
219059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (total_bitrate*delay > (float)max_buffer_size)
219159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
219259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
219359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encData->encParams->VBV_delay = delay;
219459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return PV_TRUE;
219559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
219659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
219759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
219859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef LIMITED_API
219959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
220059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : PVUpdateIFrameInterval()                                         */
220159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 04/10/2002                                                   */
220259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : updates the INTRA frame refresh interval while encoding      */
220359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*             is ongoing                                                   */
220459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
220559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
220659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
220759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
220859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
220959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
221059f566c4ec3dfc097ad8163523e522280b27e5c3James DongOSCL_EXPORT_REF Bool PVUpdateIFrameInterval(VideoEncControls *encCtrl, Int aIFramePeriod)
221159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
221259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncData    *encData;
221359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
221459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encData = (VideoEncData *)encCtrl->videoEncoderData;
221559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
221659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encData == NULL)
221759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
221859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encData->encParams == NULL)
221959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
222059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
222159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encData->encParams->IntraPeriod = aIFramePeriod;
222259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return PV_TRUE;
222359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
222459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
222559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef LIMITED_API
222659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
222759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : PVSetNumIntraMBRefresh()                                     */
222859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 08/05/2003                                                   */
222959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  :                                                              */
223059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
223159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
223259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
223359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
223459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
223559f566c4ec3dfc097ad8163523e522280b27e5c3James DongOSCL_EXPORT_REF Bool    PVUpdateNumIntraMBRefresh(VideoEncControls *encCtrl, Int numMB)
223659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
223759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncData    *encData;
223859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
223959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encData = (VideoEncData *)encCtrl->videoEncoderData;
224059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
224159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encData == NULL)
224259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
224359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
224459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encData->encParams->Refresh = numMB;
224559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
224659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return PV_TRUE;
224759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
224859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
224959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef LIMITED_API
225059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
225159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : PVIFrameRequest()                                            */
225259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 04/10/2002                                                   */
225359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : encodes the next base frame as an I-Vop                      */
225459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
225559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
225659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
225759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
225859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
225959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
226059f566c4ec3dfc097ad8163523e522280b27e5c3James DongOSCL_EXPORT_REF Bool PVIFrameRequest(VideoEncControls *encCtrl)
226159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
226259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncData    *encData;
226359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
226459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encData = (VideoEncData *)encCtrl->videoEncoderData;
226559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
226659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encData == NULL)
226759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
226859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encData->encParams == NULL)
226959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
227059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
227159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encData->nextEncIVop = 1;
227259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return PV_TRUE;
227359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
227459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
227559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef LIMITED_API
227659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
227759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : PVGetEncMemoryUsage()                                        */
227859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 10/17/2000                                                   */
227959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  :                                                              */
228059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
228159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
228259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
228359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
228459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
228559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
228659f566c4ec3dfc097ad8163523e522280b27e5c3James DongOSCL_EXPORT_REF Int PVGetEncMemoryUsage(VideoEncControls *encCtrl)
228759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
228859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncData    *encData;
228959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
229059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encData = (VideoEncData *)encCtrl->videoEncoderData;
229159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
229259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encData == NULL)
229359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
229459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encData->encParams == NULL)
229559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
229659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return encData->encParams->MemoryUsage;
229759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
229859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
229959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
230059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
230159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : PVGetHintTrack()                                             */
230259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 1/17/2001,                                                   */
230359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  :                                                              */
230459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
230559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
230659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
230759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
230859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
230959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
231059f566c4ec3dfc097ad8163523e522280b27e5c3James DongOSCL_EXPORT_REF Bool PVGetHintTrack(VideoEncControls *encCtrl, MP4HintTrack *info)
231159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
231259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncData    *encData;
231359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
231459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encData = (VideoEncData *)encCtrl->videoEncoderData;
231559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
231659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encData == NULL)
231759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
231859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encData->encParams == NULL)
231959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
232059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    info->MTB = encData->hintTrackInfo.MTB;
232159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    info->LayerID = encData->hintTrackInfo.LayerID;
232259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    info->CodeType = encData->hintTrackInfo.CodeType;
232359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    info->RefSelCode = encData->hintTrackInfo.RefSelCode;
232459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
232559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return PV_TRUE;
232659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
232759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
232859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
232959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : PVGetMaxVideoFrameSize()                                     */
233059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 7/17/2001,                                                   */
233159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Function merely returns the maximum buffer size              */
233259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
233359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
233459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
233559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
233659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
233759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
233859f566c4ec3dfc097ad8163523e522280b27e5c3James DongOSCL_EXPORT_REF Bool PVGetMaxVideoFrameSize(VideoEncControls *encCtrl, Int *maxVideoFrameSize)
233959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
234059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncData    *encData;
234159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
234259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encData = (VideoEncData *)encCtrl->videoEncoderData;
234359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
234459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encData == NULL)
234559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
234659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encData->encParams == NULL)
234759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
234859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
234959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
235059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
235159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    *maxVideoFrameSize = encData->encParams->BufferSize[0];
235259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
235359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encData->encParams->nLayers == 2)
235459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (*maxVideoFrameSize < encData->encParams->BufferSize[1])
235559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            *maxVideoFrameSize = encData->encParams->BufferSize[1];
235659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    *maxVideoFrameSize >>= 3;   /* Convert to Bytes */
235759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
235859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (*maxVideoFrameSize <= 4000)
235959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        *maxVideoFrameSize = 4000;
236059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
236159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return PV_TRUE;
236259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
236359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef LIMITED_API
236459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
236559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : PVGetVBVSize()                                               */
236659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 4/15/2002                                                    */
236759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Function merely returns the maximum buffer size              */
236859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
236959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
237059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
237159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
237259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
237359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
237459f566c4ec3dfc097ad8163523e522280b27e5c3James DongOSCL_EXPORT_REF Bool PVGetVBVSize(VideoEncControls *encCtrl, Int *VBVSize)
237559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
237659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncData    *encData;
237759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
237859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    encData = (VideoEncData *)encCtrl->videoEncoderData;
237959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
238059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encData == NULL)
238159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
238259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encData->encParams == NULL)
238359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FALSE;
238459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
238559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    *VBVSize = encData->encParams->BufferSize[0];
238659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encData->encParams->nLayers == 2)
238759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        *VBVSize += encData->encParams->BufferSize[1];
238859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
238959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return PV_TRUE;
239059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
239159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
239259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
239359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
239459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : EncodeVOS_Start()                                            */
239559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 08/22/2000                                                   */
239659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Encodes the VOS,VO, and VOL or Short Headers                 */
239759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
239859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
239959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
240059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
240159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
240259f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS EncodeVOS_Start(VideoEncControls *encoderControl)
240359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
240459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
240559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncData *video = (VideoEncData *)encoderControl->videoEncoderData;
240659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vol         *currVol = video->vol[video->currLayer];
240759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    PV_STATUS status = PV_SUCCESS;
240859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    //int profile_level=0x01;
240959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    BitstreamEncVideo *stream = video->bitstream1;
241059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    int i, j;
241159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
241259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /********************************/
241359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Check for short_video_header */
241459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /********************************/
241559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (currVol->shortVideoHeader == 1)
241659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return status;
241759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
241859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
241959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* Short Video Header or M4V */
242059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
242159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /**************************/
242259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* VisualObjectSequence ()*/
242359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /**************************/
242459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        status = BitstreamPutGT16Bits(stream, 32, SESSION_START_CODE);
242559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /*  Determine profile_level */
242659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        status = BitstreamPutBits(stream, 8, video->encParams->ProfileLevel[video->currLayer]);
242759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
242859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /******************/
242959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* VisualObject() */
243059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /******************/
243159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
243259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        status = BitstreamPutGT16Bits(stream, 32, VISUAL_OBJECT_START_CODE);
243359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        status = BitstreamPut1Bits(stream, 0x00); /* visual object identifier */
243459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        status = BitstreamPutBits(stream, 4, 0x01); /* visual object Type == "video ID" */
243559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        status = BitstreamPut1Bits(stream, 0x00); /* no video signal type */
243659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
243759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /*temp   = */
243859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BitstreamMpeg4ByteAlignStuffing(stream);
243959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
244059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
244159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        status = BitstreamPutGT16Bits(stream, 27, VO_START_CODE);/* byte align: should be 2 bits */
244259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        status = BitstreamPutBits(stream, 5, 0x00);/*  Video ID = 0  */
244359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
244459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
244559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
244659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /**********************/
244759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* VideoObjectLayer() */
244859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /**********************/
244959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (currVol->shortVideoHeader == 0)
245059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        { /* M4V  else Short Video Header */
245159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = BitstreamPutGT16Bits(stream, VOL_START_CODE_LENGTH, VOL_START_CODE);
245259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = BitstreamPutBits(stream, 4, currVol->volID);/*  video_object_layer_id */
245359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = BitstreamPut1Bits(stream, 0x00);/*  Random Access = 0  */
245459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
245559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (video->currLayer == 0)
245659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = BitstreamPutBits(stream, 8, 0x01);/* Video Object Type Indication = 1  ... Simple Object Type */
245759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else
245859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = BitstreamPutBits(stream, 8, 0x02);/* Video Object Type Indication = 2  ... Simple Scalable Object Type */
245959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
246059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = BitstreamPut1Bits(stream, 0x00);/*  is_object_layer_identifer = 0 */
246159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
246259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
246359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = BitstreamPutBits(stream, 4, 0x01); /* aspect_ratio_info = 1 ... 1:1(Square) */
246459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = BitstreamPut1Bits(stream, 0x00);/* vol_control_parameters = 0 */
246559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = BitstreamPutBits(stream, 2, 0x00);/* video_object_layer_shape = 00 ... rectangular */
246659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = BitstreamPut1Bits(stream, 0x01);/* marker bit */
246759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = BitstreamPutGT8Bits(stream, 16, currVol->timeIncrementResolution);/* vop_time_increment_resolution */
246859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = BitstreamPut1Bits(stream, 0x01);/* marker bit */
246959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = BitstreamPut1Bits(stream, currVol->fixedVopRate);/* fixed_vop_rate = 0 */
247059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
247159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* For Rectangular VO layer shape */
247259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = BitstreamPut1Bits(stream, 0x01);/* marker bit */
247359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = BitstreamPutGT8Bits(stream, 13, currVol->width);/* video_object_layer_width */
247459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = BitstreamPut1Bits(stream, 0x01);/* marker bit */
247559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = BitstreamPutGT8Bits(stream, 13, currVol->height);/* video_object_layer_height */
247659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = BitstreamPut1Bits(stream, 0x01);/*marker bit */
247759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
247859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = BitstreamPut1Bits(stream, 0x00);/*interlaced = 0 */
247959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = BitstreamPut1Bits(stream, 0x01);/* obmc_disable = 1 */
248059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = BitstreamPut1Bits(stream, 0x00);/* sprite_enable = 0 */
248159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = BitstreamPut1Bits(stream, 0x00);/* not_8_bit = 0 */
248259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = BitstreamPut1Bits(stream, currVol->quantType);/*   quant_type */
248359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
248459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (currVol->quantType)
248559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
248659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = BitstreamPut1Bits(stream, currVol->loadIntraQuantMat); /* Intra quant matrix */
248759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (currVol->loadIntraQuantMat)
248859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
248959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    for (j = 63; j >= 1; j--)
249059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        if (currVol->iqmat[*(zigzag_i+j)] != currVol->iqmat[*(zigzag_i+j-1)])
249159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            break;
249259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if ((j == 1) && (currVol->iqmat[*(zigzag_i+j)] == currVol->iqmat[*(zigzag_i+j-1)]))
249359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        j = 0;
249459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    for (i = 0; i < j + 1; i++)
249559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        BitstreamPutBits(stream, 8, currVol->iqmat[*(zigzag_i+i)]);
249659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if (j < 63)
249759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        BitstreamPutBits(stream, 8, 0);
249859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
249959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                else
250059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
250159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    for (j = 0; j < 64; j++)
250259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        currVol->iqmat[j] = mpeg_iqmat_def[j];
250359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
250459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
250559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = BitstreamPut1Bits(stream, currVol->loadNonIntraQuantMat); /* Non-Intra quant matrix */
250659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (currVol->loadNonIntraQuantMat)
250759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
250859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    for (j = 63; j >= 1; j--)
250959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        if (currVol->niqmat[*(zigzag_i+j)] != currVol->niqmat[*(zigzag_i+j-1)])
251059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            break;
251159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if ((j == 1) && (currVol->niqmat[*(zigzag_i+j)] == currVol->niqmat[*(zigzag_i+j-1)]))
251259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        j = 0;
251359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    for (i = 0; i < j + 1; i++)
251459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        BitstreamPutBits(stream, 8, currVol->niqmat[*(zigzag_i+i)]);
251559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if (j < 63)
251659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        BitstreamPutBits(stream, 8, 0);
251759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
251859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                else
251959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
252059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    for (j = 0; j < 64; j++)
252159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        currVol->niqmat[j] = mpeg_nqmat_def[j];
252259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
252359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
252459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
252559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = BitstreamPut1Bits(stream, 0x01);   /* complexity_estimation_disable = 1 */
252659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = BitstreamPut1Bits(stream, currVol->ResyncMarkerDisable);/* Resync_marker_disable */
252759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = BitstreamPut1Bits(stream, currVol->dataPartitioning);/* Data partitioned */
252859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
252959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (currVol->dataPartitioning)
253059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = BitstreamPut1Bits(stream, currVol->useReverseVLC); /* Reversible_vlc */
253159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
253259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
253359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (currVol->scalability) /* Scalability*/
253459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
253559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
253659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = BitstreamPut1Bits(stream, currVol->scalability);/* Scalability = 1 */
253759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = BitstreamPut1Bits(stream, currVol->scalType);/* hierarchy _type ... Spatial= 0 and Temporal = 1 */
253859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = BitstreamPutBits(stream, 4, currVol->refVolID);/* ref_layer_id  */
253959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = BitstreamPut1Bits(stream, currVol->refSampDir);/* ref_layer_sampling_direc*/
254059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = BitstreamPutBits(stream, 5, currVol->horSamp_n);/*hor_sampling_factor_n*/
254159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = BitstreamPutBits(stream, 5, currVol->horSamp_m);/*hor_sampling_factor_m*/
254259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = BitstreamPutBits(stream, 5, currVol->verSamp_n);/*vert_sampling_factor_n*/
254359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = BitstreamPutBits(stream, 5, currVol->verSamp_m);/*vert_sampling_factor_m*/
254459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = BitstreamPut1Bits(stream, currVol->enhancementType);/* enhancement_type*/
254559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
254659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else /* No Scalability */
254759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = BitstreamPut1Bits(stream, currVol->scalability);/* Scalability = 0 */
254859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
254959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /*temp = */
255059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            BitstreamMpeg4ByteAlignStuffing(stream); /* Byte align Headers for VOP */
255159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
255259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
255359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
255459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return status;
255559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
255659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
255759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
255859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : VOS_End()                                                    */
255959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 08/22/2000                                                   */
256059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Visual Object Sequence End                                   */
256159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
256259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
256359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
256459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
256559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
256659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
256759f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS VOS_End(VideoEncControls *encoderControl)
256859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
256959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    PV_STATUS status = PV_SUCCESS;
257059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncData *video = (VideoEncData *)encoderControl->videoEncoderData;
257159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vol         *currVol = video->vol[video->currLayer];
257259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    BitstreamEncVideo *stream = currVol->stream;
257359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
257459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
257559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    status = BitstreamPutBits(stream, SESSION_END_CODE, 32);
257659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
257759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return status;
257859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
257959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
258059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
258159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : DetermineCodingLayer                                         */
258259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 06/02/2001                                                   */
258359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Find layer to code based on current mod time, assuming that
258459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong               it's time to encode enhanced layer.                          */
258559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
258659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   : Number of layer to code.                                     */
258759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
258859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
258959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
259059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
259159f566c4ec3dfc097ad8163523e522280b27e5c3James DongInt DetermineCodingLayer(VideoEncData *video, Int *nLayer, ULong modTime)
259259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
259359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vol **vol = video->vol;
259459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncParams *encParams = video->encParams;
259559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int numLayers = encParams->nLayers;
259659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UInt modTimeRef = video->modTimeRef;
259759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    float *LayerFrameRate = encParams->LayerFrameRate;
259859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UInt frameNum[4], frameTick;
259959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    ULong frameModTime, nextFrmModTime;
260059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef REDUCE_FRAME_VARIANCE    /* To limit how close 2 frames can be */
260159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    float frameInterval;
260259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
260359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    float srcFrameInterval;
260459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int frameInc;
260559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int i, extra_skip;
260659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int encodeVop = 0;
260759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
260859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    i = numLayers - 1;
260959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
261059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (modTime - video->nextModTime > ((ULong)(-1)) >> 1) /* next time wrapped around */
261159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return 0; /* not time to code it yet */
261259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
261359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->relLayerCodeTime[i] -= 1000;
261459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->nextEncIVop--;  /* number of Vops in highest layer resolution. */
261559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->numVopsInGOP++;
261659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
261759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* from this point frameModTime and nextFrmModTime are internal */
261859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
261959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    frameNum[i] = (UInt)((modTime - modTimeRef) * LayerFrameRate[i] + 500) / 1000;
262059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->volInitialize[i])
262159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
262259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->prevFrameNum[i] = frameNum[i] - 1;
262359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
262459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else if (frameNum[i] <= video->prevFrameNum[i])
262559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
262659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return 0; /* do not encode this frame */
262759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
262859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
262959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /**** this part computes expected next frame *******/
263059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    frameModTime = (ULong)(((frameNum[i] * 1000) / LayerFrameRate[i]) + modTimeRef + 0.5); /* rec. time */
263159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    nextFrmModTime = (ULong)((((frameNum[i] + 1) * 1000) / LayerFrameRate[i]) + modTimeRef + 0.5); /* rec. time */
263259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
263359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    srcFrameInterval = 1000 / video->FrameRate;
263459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
263559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->nextModTime = nextFrmModTime - (ULong)(srcFrameInterval / 2.) - 1; /* between current and next frame */
263659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
263759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef REDUCE_FRAME_VARIANCE    /* To limit how close 2 frames can be */
263859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    frameInterval = 1000 / LayerFrameRate[i]; /* next rec. time */
263959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    delta = (Int)(frameInterval / 4); /* empirical number */
264059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->nextModTime - modTime  < (ULong)delta) /* need to move nextModTime further. */
264159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
264259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->nextModTime += ((delta - video->nextModTime + modTime)); /* empirical formula  */
264359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
264459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
264559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /****************************************************/
264659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
264759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* map frame no.to tick from modTimeRef */
264859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*frameTick = (frameNum[i]*vol[i]->timeIncrementResolution) ;
264959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    frameTick = (UInt)((frameTick + (encParams->LayerFrameRate[i]/2))/encParams->LayerFrameRate[i]);*/
265059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*  11/16/01, change frameTick to be the closest tick from the actual modTime */
265159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*  12/12/02, add (double) to prevent large number wrap-around */
265259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    frameTick = (Int)(((double)(modTime - modTimeRef) * vol[i]->timeIncrementResolution + 500) / 1000);
265359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
265459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* find timeIncrement to be put in the bitstream */
265559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* refTick is second boundary reference. */
265659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    vol[i]->timeIncrement = frameTick - video->refTick[i];
265759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
265859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
265959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    vol[i]->moduloTimeBase = 0;
266059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    while (vol[i]->timeIncrement >= vol[i]->timeIncrementResolution)
266159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
266259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        vol[i]->timeIncrement -= vol[i]->timeIncrementResolution;
266359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        vol[i]->moduloTimeBase++;
266459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* do not update refTick and modTimeRef yet, do it after encoding!! */
266559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
266659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
266759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->relLayerCodeTime[i] <= 0)    /* no skipping */
266859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
266959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        encodeVop = 1;
267059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->currLayer = *nLayer = i;
267159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->relLayerCodeTime[i] += 1000;
267259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
267359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* takes care of more dropped frame than expected */
267459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        extra_skip = -1;
267559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        frameInc = (frameNum[i] - video->prevFrameNum[i]);
267659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        extra_skip += frameInc;
267759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
267859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (extra_skip > 0)
267959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {   /* update rc->Nr, rc->B, (rc->Rr)*/
268059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->nextEncIVop -= extra_skip;
268159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->numVopsInGOP += extra_skip;
268259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (encParams->RC_Type != CONSTANT_Q)
268359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
268459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                RC_UpdateBuffer(video, i, extra_skip);
268559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
268659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
268759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
268859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
268959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* update frame no. */
269059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->prevFrameNum[i] = frameNum[i];
269159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
269259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* go through all lower layer */
269359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (i = (numLayers - 2); i >= 0; i--)
269459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
269559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
269659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->relLayerCodeTime[i] -= 1000;
269759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
269859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* find timeIncrement to be put in the bitstream */
269959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        vol[i]->timeIncrement = frameTick - video->refTick[i];
270059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
270159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->relLayerCodeTime[i] <= 0) /* time to encode base */
270259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
270359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* 12/27/00 */
270459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            encodeVop = 1;
270559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->currLayer = *nLayer = i;
270659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->relLayerCodeTime[i] +=
270759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                (Int)((1000.0 * encParams->LayerFrameRate[numLayers-1]) / encParams->LayerFrameRate[i]);
270859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
270959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            vol[i]->moduloTimeBase = 0;
271059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            while (vol[i]->timeIncrement >= vol[i]->timeIncrementResolution)
271159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
271259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                vol[i]->timeIncrement -= vol[i]->timeIncrementResolution;
271359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                vol[i]->moduloTimeBase++;
271459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /* do not update refTick and modTimeRef yet, do it after encoding!! */
271559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
271659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
271759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* takes care of more dropped frame than expected */
271859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            frameNum[i] = (UInt)((frameModTime - modTimeRef) * encParams->LayerFrameRate[i] + 500) / 1000;
271959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (video->volInitialize[i])
272059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->prevFrameNum[i] = frameNum[i] - 1;
272159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
272259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            extra_skip = -1;
272359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            frameInc = (frameNum[i] - video->prevFrameNum[i]);
272459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            extra_skip += frameInc;
272559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
272659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (extra_skip > 0)
272759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {   /* update rc->Nr, rc->B, (rc->Rr)*/
272859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (encParams->RC_Type != CONSTANT_Q)
272959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
273059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    RC_UpdateBuffer(video, i, extra_skip);
273159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
273259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
273359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* update frame no. */
273459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->prevFrameNum[i] = frameNum[i];
273559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
273659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
273759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
273859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef _PRINT_STAT
273959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encodeVop)
274059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        printf(" TI: %d ", vol[*nLayer]->timeIncrement);
274159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
274259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
274359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return encodeVop;
274459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
274559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
274659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
274759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : DetermineVopType                                             */
274859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 06/02/2001                                                   */
274959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : The name says it all.                                        */
275059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
275159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   : void .                                                       */
275259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
275359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
275459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
275559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
275659f566c4ec3dfc097ad8163523e522280b27e5c3James Dongvoid DetermineVopType(VideoEncData *video, Int currLayer)
275759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
275859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncParams *encParams = video->encParams;
275959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//  Vol *currVol = video->vol[currLayer];
276059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
276159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encParams->IntraPeriod == 0) /* I-VOPs only */
276259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
276359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->currLayer > 0)
276459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->currVop->predictionType = P_VOP;
276559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else
276659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
276759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->currVop->predictionType = I_VOP;
276859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (video->numVopsInGOP >= 132)
276959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->numVopsInGOP = 0;
277059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
277159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
277259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else if (encParams->IntraPeriod == -1)  /* IPPPPP... */
277359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
277459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
277559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* maintain frame type if previous frame is pre-skipped, 06/02/2001 */
277659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (encParams->RC_Type == CONSTANT_Q || video->rc[currLayer]->skip_next_frame != -1)
277759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->currVop->predictionType = P_VOP;
277859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
277959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->currLayer == 0)
278059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
278159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (/*video->numVopsInGOP>=132 || */video->volInitialize[currLayer])
278259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
278359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->currVop->predictionType = I_VOP;
278459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->numVopsInGOP = 0; /* force INTRA update every 132 base frames*/
278559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->nextEncIVop = 1;
278659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
278759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else if (video->nextEncIVop == 0 || video->currVop->predictionType == I_VOP)
278859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
278959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->numVopsInGOP = 0;
279059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->nextEncIVop = 1;
279159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
279259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
279359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
279459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else   /* IntraPeriod>0 : IPPPPPIPPPPPI... */
279559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
279659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
279759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* maintain frame type if previous frame is pre-skipped, 06/02/2001 */
279859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (encParams->RC_Type == CONSTANT_Q || video->rc[currLayer]->skip_next_frame != -1)
279959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->currVop->predictionType = P_VOP;
280059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
280159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (currLayer == 0)
280259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
280359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (video->nextEncIVop <= 0 || video->currVop->predictionType == I_VOP)
280459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
280559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->nextEncIVop = encParams->IntraPeriod;
280659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->currVop->predictionType = I_VOP;
280759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->numVopsInGOP = 0;
280859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
280959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
281059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
281159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
281259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return ;
281359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
281459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
281559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
281659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : UpdateSkipNextFrame                                          */
281759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 06/02/2001                                                   */
281859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : From rate control frame skipping decision, update timing
281959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                related parameters.                                         */
282059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
282159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   : Current coded layer.                                         */
282259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
282359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
282459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
282559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
282659f566c4ec3dfc097ad8163523e522280b27e5c3James DongInt UpdateSkipNextFrame(VideoEncData *video, ULong *modTime, Int *size, PV_STATUS status)
282759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
282859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int currLayer = video->currLayer;
282959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int nLayer = currLayer;
283059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncParams *encParams = video->encParams;
283159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int numLayers = encParams->nLayers;
283259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vol *currVol = video->vol[currLayer];
283359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vol **vol = video->vol;
283459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int num_skip, extra_skip;
283559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int i;
283659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UInt newRefTick, deltaModTime;
283759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UInt temp;
283859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
283959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (encParams->RC_Type != CONSTANT_Q)
284059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
284159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->volInitialize[0] && currLayer == 0)  /* always encode the first frame */
284259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
284359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            RC_ResetSkipNextFrame(video, currLayer);
284459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            //return currLayer;  09/15/05
284559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
284659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else
284759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
284859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (RC_GetSkipNextFrame(video, currLayer) < 0 || status == PV_END_OF_BUF)   /* Skip Current Frame */
284959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
285059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
285159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef _PRINT_STAT
285259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                printf("Skip current frame");
285359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
285459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                currVol->moduloTimeBase = currVol->prevModuloTimeBase;
285559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
285659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /*********************/
285759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /* prepare to return */
285859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /*********************/
285959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                *size = 0;  /* Set Bitstream buffer to zero */
286059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
286159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /* Determine nLayer and modTime for next encode */
286259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
286359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                *modTime = video->nextModTime;
286459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                nLayer = -1;
286559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
286659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                return nLayer; /* return immediately without updating RefTick & modTimeRef */
286759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /* If I-VOP was attempted, then ensure next base is I-VOP */
286859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /*if((encParams->IntraPeriod>0) && (video->currVop->predictionType == I_VOP))
286959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->nextEncIVop = 0; commented out by 06/05/01 */
287059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
287159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
287259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else if ((num_skip = RC_GetSkipNextFrame(video, currLayer)) > 0)
287359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
287459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
287559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef _PRINT_STAT
287659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                printf("Skip next %d frames", num_skip);
287759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
287859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /* to keep the Nr of enh layer the same */
287959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /* adjust relLayerCodeTime only, do not adjust layerCodeTime[numLayers-1] */
288059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                extra_skip = 0;
288159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                for (i = 0; i < currLayer; i++)
288259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
288359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if (video->relLayerCodeTime[i] <= 1000)
288459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    {
288559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        extra_skip = 1;
288659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        break;
288759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    }
288859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
288959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
289059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                for (i = currLayer; i < numLayers; i++)
289159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
289259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    video->relLayerCodeTime[i] += (num_skip + extra_skip) *
289359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                                  ((Int)((1000.0 * encParams->LayerFrameRate[numLayers-1]) / encParams->LayerFrameRate[i]));
289459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
289559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
289659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }/* first frame */
289759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
289859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*****  current frame is encoded, now update refTick ******/
289959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
290059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->refTick[currLayer] += vol[currLayer]->prevModuloTimeBase * vol[currLayer]->timeIncrementResolution;
290159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
290259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Reset layerCodeTime every I-VOP to prevent overflow */
290359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (currLayer == 0)
290459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
290559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /*  12/12/02, fix for weird targer frame rate of 9.99 fps or 3.33 fps */
290659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (((encParams->IntraPeriod != 0) /*&& (video->currVop->predictionType==I_VOP)*/) ||
290759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                ((encParams->IntraPeriod == 0) && (video->numVopsInGOP == 0)))
290859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
290959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            newRefTick = video->refTick[0];
291059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
291159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            for (i = 1; i < numLayers; i++)
291259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
291359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (video->refTick[i] < newRefTick)
291459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    newRefTick = video->refTick[i];
291559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
291659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
291759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* check to make sure that the update is integer multiple of frame number */
291859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* how many msec elapsed from last modTimeRef */
291959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            deltaModTime = (newRefTick / vol[0]->timeIncrementResolution) * 1000;
292059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
292159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            for (i = numLayers - 1; i >= 0; i--)
292259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
292359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                temp = (UInt)(deltaModTime * encParams->LayerFrameRate[i]); /* 12/12/02 */
292459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (temp % 1000)
292559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    newRefTick = 0;
292659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
292759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
292859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (newRefTick > 0)
292959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
293059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->modTimeRef += deltaModTime;
293159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                for (i = numLayers - 1; i >= 0; i--)
293259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
293359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    video->prevFrameNum[i] -= (UInt)(deltaModTime * encParams->LayerFrameRate[i]) / 1000;
293459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    video->refTick[i] -= newRefTick;
293559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
293659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
293759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
293859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
293959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
294059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    *modTime =  video->nextModTime;
294159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
294259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return nLayer;
294359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
294459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
294559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
294659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef ORIGINAL_VERSION
294759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
294859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
294959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : SetProfile_BufferSize                                        */
295059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 04/08/2002                                                   */
295159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Set profile and video buffer size, copied from Jim's code    */
295259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*             in PVInitVideoEncoder(.), since we have different places     */
295359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*             to reset profile and video buffer size                       */
295459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
295559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   :                                                              */
295659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
295759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
295859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
295959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
296059f566c4ec3dfc097ad8163523e522280b27e5c3James DongBool SetProfile_BufferSize(VideoEncData *video, float delay, Int bInitialized)
296159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
296259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int i, j, start, end;
296359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//  Int BaseMBsPerSec = 0, EnhMBsPerSec = 0;
296459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int nTotalMB = 0;
296559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int idx, temp_w, temp_h, max = 0, max_width, max_height;
296659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
296759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int nLayers = video->encParams->nLayers; /* Number of Layers to be encoded */
296859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
296959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int total_bitrate = 0, base_bitrate;
297059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int total_packet_size = 0, base_packet_size;
297159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int total_MBsPerSec = 0, base_MBsPerSec;
297259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int total_VBV_size = 0, base_VBV_size, enhance_VBV_size = 0;
297359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    float total_framerate, base_framerate;
297459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    float upper_bound_ratio;
297559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int bFound = 0;
297659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int k = 0, width16, height16, index;
297759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int lowest_level;
297859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
297959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#define MIN_BUFF    16000 /* 16k minimum buffer size */
298059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#define BUFF_CONST  2.0    /* 2000ms */
298159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#define UPPER_BOUND_RATIO 8.54 /* upper_bound = 1.4*(1.1+bound/10)*bitrate/framerate */
298259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
298359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#define QCIF_WIDTH  176
298459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#define QCIF_HEIGHT 144
298559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
298659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    index = video->encParams->profile_table_index;
298759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
298859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Calculate "nTotalMB" */
298959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Find the maximum width*height for memory allocation of the VOPs */
299059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (idx = 0; idx < nLayers; idx++)
299159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
299259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        temp_w = video->encParams->LayerWidth[idx];
299359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        temp_h = video->encParams->LayerHeight[idx];
299459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
299559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if ((temp_w*temp_h) > max)
299659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
299759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            max = temp_w * temp_h;
299859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            max_width = temp_w;
299959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            max_height = temp_h;
300059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            nTotalMB = ((max_width + 15) >> 4) * ((max_height + 15) >> 4);
300159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
300259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
300359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    upper_bound_ratio = (video->encParams->RC_Type == CBR_LOWDELAY ? (float)5.0 : (float)UPPER_BOUND_RATIO);
300459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
300559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
300659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Get the basic information: bitrate, packet_size, MBs/s and VBV_size */
300759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    base_bitrate        = video->encParams->LayerBitRate[0];
300859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->encParams->LayerMaxBitRate[0] != 0) /* video->encParams->LayerMaxBitRate[0] == 0 means it has not been set */
300959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
301059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        base_bitrate    = PV_MAX(base_bitrate, video->encParams->LayerMaxBitRate[0]);
301159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
301259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else /* if the max is not set, set it to the specified profile/level */
301359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
301459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->encParams->LayerMaxBitRate[0] = profile_level_max_bitrate[index];
301559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
301659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
301759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    base_framerate      = video->encParams->LayerFrameRate[0];
301859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->encParams->LayerMaxFrameRate[0] != 0)
301959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
302059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        base_framerate  = PV_MAX(base_framerate, video->encParams->LayerMaxFrameRate[0]);
302159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
302259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else /* if the max is not set, set it to the specified profile/level */
302359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
302459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->encParams->LayerMaxFrameRate[0] = (float)profile_level_max_mbsPerSec[index] / nTotalMB;
302559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
302659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
302759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    base_packet_size    = video->encParams->ResyncPacketsize;
302859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    base_MBsPerSec      = (Int)(base_framerate * nTotalMB);
302959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    base_VBV_size       = PV_MAX((Int)(base_bitrate * delay),
303059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                 (Int)(upper_bound_ratio * base_bitrate / base_framerate));
303159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    base_VBV_size       = PV_MAX(base_VBV_size, MIN_BUFF);
303259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
303359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* if the buffer is larger than maximum buffer size, we'll clip it */
303459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (base_VBV_size > profile_level_max_VBV_size[5])
303559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        base_VBV_size = profile_level_max_VBV_size[5];
303659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
303759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
303859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Check if the buffer exceeds the maximum buffer size given the maximum profile and level */
303959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (nLayers == 1 && base_VBV_size > profile_level_max_VBV_size[index])
304059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return FALSE;
304159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
304259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
304359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (nLayers == 2)
304459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
304559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        total_bitrate       = video->encParams->LayerBitRate[1];
304659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->encParams->LayerMaxBitRate[1] != 0)
304759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
304859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            total_bitrate   = PV_MIN(total_bitrate, video->encParams->LayerMaxBitRate[1]);
304959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
305059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else /* if the max is not set, set it to the specified profile/level */
305159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
305259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->encParams->LayerMaxBitRate[1] = scalable_profile_level_max_bitrate[index];
305359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
305459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
305559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        total_framerate     = video->encParams->LayerFrameRate[1];
305659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->encParams->LayerMaxFrameRate[1] != 0)
305759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
305859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            total_framerate     = PV_MIN(total_framerate, video->encParams->LayerMaxFrameRate[1]);
305959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
306059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else /* if the max is not set, set it to the specified profile/level */
306159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
306259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->encParams->LayerMaxFrameRate[1] = (float)scalable_profile_level_max_mbsPerSec[index] / nTotalMB;
306359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
306459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
306559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        total_packet_size   = video->encParams->ResyncPacketsize;
306659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        total_MBsPerSec     = (Int)(total_framerate * nTotalMB);
306759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
306859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        enhance_VBV_size    = PV_MAX((Int)((total_bitrate - base_bitrate) * delay),
306959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                     (Int)(upper_bound_ratio * (total_bitrate - base_bitrate) / (total_framerate - base_framerate)));
307059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        enhance_VBV_size    = PV_MAX(enhance_VBV_size, MIN_BUFF);
307159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
307259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        total_VBV_size      = base_VBV_size + enhance_VBV_size;
307359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
307459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* if the buffer is larger than maximum buffer size, we'll clip it */
307559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (total_VBV_size > scalable_profile_level_max_VBV_size[6])
307659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
307759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            total_VBV_size = scalable_profile_level_max_VBV_size[6];
307859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            enhance_VBV_size = total_VBV_size - base_VBV_size;
307959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
308059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
308159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* Check if the buffer exceeds the maximum buffer size given the maximum profile and level */
308259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (total_VBV_size > scalable_profile_level_max_VBV_size[index])
308359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            return FALSE;
308459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
308559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
308659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
308759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (!bInitialized) /* Has been initialized --> profile @ level has been figured out! */
308859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
308959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->encParams->BufferSize[0] = base_VBV_size;
309059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (nLayers > 1)
309159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->encParams->BufferSize[1] = enhance_VBV_size;
309259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
309359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_TRUE;
309459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
309559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
309659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
309759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Profile @ level determination */
309859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (nLayers == 1)
309959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
310059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* BASE ONLY : Simple Profile(SP) Or Core Profile(CP) */
310159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (base_bitrate     > profile_level_max_bitrate[index]     ||
310259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                base_packet_size > profile_level_max_packet_size[index] ||
310359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                base_MBsPerSec   > profile_level_max_mbsPerSec[index]   ||
310459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                base_VBV_size    > profile_level_max_VBV_size[index])
310559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
310659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            return PV_FALSE; /* Beyond the bound of Core Profile @ Level2 */
310759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
310859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* For H263/Short header, determine k*16384 */
310959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        width16  = ((video->encParams->LayerWidth[0] + 15) >> 4) << 4;
311059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        height16 = ((video->encParams->LayerHeight[0] + 15) >> 4) << 4;
311159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->encParams->H263_Enabled)
311259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
311359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            k = 4;
311459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (width16  == 2*QCIF_WIDTH && height16 == 2*QCIF_HEIGHT)  /* CIF */
311559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                k = 16;
311659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
311759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else if (width16  == 4*QCIF_WIDTH && height16 == 4*QCIF_HEIGHT)  /* 4CIF */
311859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                k = 32;
311959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
312059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else if (width16  == 8*QCIF_WIDTH && height16 == 8*QCIF_HEIGHT)  /* 16CIF */
312159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                k = 64;
312259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
312359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->encParams->maxFrameSize  = k * 16384;
312459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
312559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* Make sure the buffer size is limited to the top profile and level: the Core profile and level 2 */
312659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (base_VBV_size > (Int)(k*16384 + 4*(float)profile_level_max_bitrate[5]*1001.0 / 30000.0))
312759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                base_VBV_size = (Int)(k * 16384 + 4 * (float)profile_level_max_bitrate[5] * 1001.0 / 30000.0);
312859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
312959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (base_VBV_size > (Int)(k*16384 + 4*(float)profile_level_max_bitrate[index]*1001.0 / 30000.0))
313059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                return PV_FALSE;
313159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
313259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
313359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* Search the appropriate profile@level index */
313459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (!video->encParams->H263_Enabled &&
313559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                (video->encParams->IntraDCVlcThr != 0 || video->encParams->SearchRange > 16))
313659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
313759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            lowest_level = 1; /* cannot allow SPL0 */
313859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
313959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else
314059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
314159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            lowest_level = 0; /* SPL0 */
314259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
314359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
314459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        for (i = lowest_level; i <= index; i++)
314559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
314659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (i != 4 && /* skip Core Profile@Level1 because the parameters in it are smaller than those in Simple Profile@Level3 */
314759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    base_bitrate     <= profile_level_max_bitrate[i]     &&
314859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    base_packet_size <= profile_level_max_packet_size[i] &&
314959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    base_MBsPerSec   <= profile_level_max_mbsPerSec[i]   &&
315059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    base_VBV_size    <= (video->encParams->H263_Enabled ? (Int)(k*16384 + 4*(float)profile_level_max_bitrate[i]*1001.0 / 30000.0) :
315159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                         profile_level_max_VBV_size[i]))
315259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                break;
315359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
315459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (i > index) return PV_FALSE; /* Nothing found!! */
315559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
315659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* Found out the actual profile @ level : index "i" */
315759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (i == 0)
315859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
315959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* For Simple Profile @ Level 0, we need to do one more check: image size <= QCIF */
316059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (width16 > QCIF_WIDTH || height16 > QCIF_HEIGHT)
316159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                i = 1; /* image size > QCIF, then set SP level1 */
316259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
316359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
316459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->encParams->ProfileLevel[0] = profile_level_code[i];
316559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->encParams->BufferSize[0]   = base_VBV_size;
316659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
316759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->encParams->LayerMaxBitRate[0] == 0)
316859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->encParams->LayerMaxBitRate[0] = profile_level_max_bitrate[i];
316959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
317059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->encParams->LayerMaxFrameRate[0] == 0)
317159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->encParams->LayerMaxFrameRate[0] = PV_MIN(30, (float)profile_level_max_mbsPerSec[i] / nTotalMB);
317259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
317359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* For H263/Short header, one special constraint for VBV buffer size */
317459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->encParams->H263_Enabled)
317559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->encParams->BufferSize[0] = (Int)(k * 16384 + 4 * (float)profile_level_max_bitrate[i] * 1001.0 / 30000.0);
317659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
317759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
317859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
317959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
318059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* SCALABALE MODE: Simple Scalable Profile(SSP) Or Core Scalable Profile(CSP) */
318159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
318259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (total_bitrate       > scalable_profile_level_max_bitrate[index]     ||
318359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                total_packet_size   > scalable_profile_level_max_packet_size[index] ||
318459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                total_MBsPerSec     > scalable_profile_level_max_mbsPerSec[index]   ||
318559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                total_VBV_size      > scalable_profile_level_max_VBV_size[index])
318659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
318759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            return PV_FALSE; /* Beyond given profile and level */
318859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
318959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* One-time check: Simple Scalable Profile or Core Scalable Profile */
319059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (total_bitrate       <= scalable_profile_level_max_bitrate[2]        &&
319159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                total_packet_size   <= scalable_profile_level_max_packet_size[2]    &&
319259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                total_MBsPerSec     <= scalable_profile_level_max_mbsPerSec[2]      &&
319359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                total_VBV_size      <= scalable_profile_level_max_VBV_size[2])
319459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
319559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
319659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            start = 0;
319759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            end = index;
319859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
319959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
320059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else
320159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
320259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            start = 4;
320359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            end = index;
320459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
320559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
320659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
320759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* Search the scalable profile */
320859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        for (i = start; i <= end; i++)
320959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
321059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (total_bitrate       <= scalable_profile_level_max_bitrate[i]     &&
321159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    total_packet_size   <= scalable_profile_level_max_packet_size[i] &&
321259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    total_MBsPerSec     <= scalable_profile_level_max_mbsPerSec[i]   &&
321359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    total_VBV_size      <= scalable_profile_level_max_VBV_size[i])
321459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
321559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                break;
321659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
321759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (i > end) return PV_FALSE;
321859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
321959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* Search the base profile */
322059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (i == 0)
322159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
322259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            j = 0;
322359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            bFound = 1;
322459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
322559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else        bFound = 0;
322659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
322759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        for (j = start; !bFound && j <= i; j++)
322859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
322959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (base_bitrate        <= profile_level_max_bitrate[j]      &&
323059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    base_packet_size    <= profile_level_max_packet_size[j]  &&
323159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    base_MBsPerSec      <= profile_level_max_mbsPerSec[j]    &&
323259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    base_VBV_size       <= profile_level_max_VBV_size[j])
323359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
323459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
323559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                bFound = 1;
323659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                break;
323759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
323859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
323959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
324059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (!bFound) // && start == 4)
324159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            return PV_FALSE; /* mis-match in the profiles between base layer and enhancement layer */
324259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
324359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* j for base layer, i for enhancement layer */
324459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->encParams->ProfileLevel[0] = profile_level_code[j];
324559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->encParams->ProfileLevel[1] = scalable_profile_level_code[i];
324659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->encParams->BufferSize[0]   = base_VBV_size;
324759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->encParams->BufferSize[1]   = enhance_VBV_size;
324859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
324959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->encParams->LayerMaxBitRate[0] == 0)
325059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->encParams->LayerMaxBitRate[0] = profile_level_max_bitrate[j];
325159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
325259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->encParams->LayerMaxBitRate[1] == 0)
325359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->encParams->LayerMaxBitRate[1] = scalable_profile_level_max_bitrate[i];
325459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
325559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->encParams->LayerMaxFrameRate[0] == 0)
325659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->encParams->LayerMaxFrameRate[0] = PV_MIN(30, (float)profile_level_max_mbsPerSec[j] / nTotalMB);
325759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
325859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->encParams->LayerMaxFrameRate[1] == 0)
325959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->encParams->LayerMaxFrameRate[1] = PV_MIN(30, (float)scalable_profile_level_max_mbsPerSec[i] / nTotalMB);
326059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
326159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
326259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    } /* end of: if(nLayers == 1) */
326359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
326459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
326559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (!video->encParams->H263_Enabled && (video->encParams->ProfileLevel[0] == 0x08)) /* SPL0 restriction*/
326659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
326759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* PV only allow frame-based rate control, no QP change from one MB to another
326859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if(video->encParams->ACDCPrediction == TRUE && MB-based rate control)
326959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong         return PV_FALSE */
327059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
327159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
327259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return PV_TRUE;
327359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
327459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
327559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif /* #ifndef ORIGINAL_VERSION */
327659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
327759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
327859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
3279