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