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#include "mp4def.h"
1959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "mp4enc_lib.h"
2059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "mp4lib_int.h"
2159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "bitstream_io.h"
2259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "vlc_encode.h"
2359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "m4venc_oscl.h"
2459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
2559f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS EncodeGOBHeader(VideoEncData *video, Int GOB_number, Int quant_scale, Int bs1stream);
2659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
2759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
2859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : EncodeFrameCombinedMode()                                    */
2959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 09/01/2000                                                   */
3059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  History  :                                                              */
3159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Encode a frame of MPEG4 bitstream in Combined mode.          */
3259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
3359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   :  PV_SUCCESS if successful else PV_FAIL                       */
3459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
3559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
3659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
3759f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS EncodeFrameCombinedMode(VideoEncData *video)
3859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
3959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    PV_STATUS status = PV_SUCCESS;
4059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vol *currVol = video->vol[video->currLayer];
4159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vop *currVop = video->currVop;
4259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncParams *encParams = video->encParams;
4359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int width = currVop->width; /* has to be Vop, for multiple of 16 */
4459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int lx = currVop->pitch; /* with padding */
4559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int offset = 0;
4659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int ind_x, ind_y;
4759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int start_packet_header = 0;
4859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar *QPMB = video->QPMB;
4959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int QP;
5059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int mbnum = 0, slice_counter = 0, curr_slice_counter = 0;
5159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int num_bits, packet_size = encParams->ResyncPacketsize;
5259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int GOB_Header_Interval = encParams->GOB_Header_Interval;
5359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    BitstreamEncVideo *bs1 = video->bitstream1;
5459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int numHeaderBits;
5559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    approxDCT fastDCTfunction;
5659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int ncoefblck[6] = {64, 64, 64, 64, 64, 64}; /* for FastCodeMB,  5/18/2001 */
5759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    PV_STATUS(*CodeMB)(VideoEncData *, approxDCT *, Int, Int[]);
5859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void (*MBVlcEncode)(VideoEncData*, Int[], void *);
5959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void (*BlockCodeCoeff)(RunLevelBlock*, BitstreamEncVideo*, Int, Int, UChar);
6059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
6159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* for H263 GOB changes */
6259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//MP4RateControlType rc_type = encParams->RC_Type;
6359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
6459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->QP_prev = currVop->quantizer;
6559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
6659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    numHeaderBits = BitstreamGetPos(bs1);
6759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
6859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* determine type of quantization   */
6959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef NO_MPEG_QUANT
7059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (currVol->quantType == 0)
7159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        CodeMB = &CodeMB_H263;
7259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
7359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        CodeMB = &CodeMB_MPEG;
7459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#else
7559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    CodeMB = &CodeMB_H263;
7659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
7759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
7859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* determine which functions to be used, in MB-level */
7959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (currVop->predictionType == P_VOP)
8059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        MBVlcEncode = &MBVlcEncodeCombined_P_VOP;
8159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else if (currVop->predictionType == I_VOP)
8259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        MBVlcEncode = &MBVlcEncodeCombined_I_VOP;
8359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else /* B_VOP not implemented yet */
8459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FAIL;
8559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
8659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* determine which VLC table to be used */
8759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef H263_ONLY
8859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (currVol->shortVideoHeader)
8959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockCodeCoeff = &BlockCodeCoeff_ShortHeader;
9059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef NO_RVLC
9159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else if (currVol->useReverseVLC)
9259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockCodeCoeff = &BlockCodeCoeff_RVLC;
9359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
9459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
9559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockCodeCoeff = &BlockCodeCoeff_Normal;
9659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#else
9759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    BlockCodeCoeff = &BlockCodeCoeff_ShortHeader;
9859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
9959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
10059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* gob_frame_id is the same for different vop types - the reason should be SCD */
10159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (currVol->shortVideoHeader && currVop->gobFrameID != currVop->predictionType)
10259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        currVop->gobFrameID = currVop->predictionType;
10359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
10459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
10559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->usePrevQP = 0;
10659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
10759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (ind_y = 0; ind_y < currVol->nMBPerCol; ind_y++)    /* Col MB Loop */
10859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
10959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
11059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->outputMB->mb_y = ind_y; /*  5/28/01 */
11159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
11259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (currVol->shortVideoHeader)  /* ShortVideoHeader Mode */
11359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
11459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
11559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (slice_counter && GOB_Header_Interval && (ind_y % GOB_Header_Interval == 0))     /* Encode GOB Header */
11659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
11759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                QP = QPMB[mbnum];    /* Get quant_scale */
11859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->header_bits -= BitstreamGetPos(currVol->stream); /* Header Bits */
11959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = EncodeGOBHeader(video, slice_counter, QP, 0);  //ind_y     /* Encode GOB Header */
12059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->header_bits += BitstreamGetPos(currVol->stream); /* Header Bits */
12159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                curr_slice_counter = slice_counter;
12259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
12359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
12459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
12559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        for (ind_x = 0; ind_x < currVol->nMBPerRow; ind_x++)  /* Row MB Loop */
12659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
12759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->outputMB->mb_x = ind_x; /*  5/28/01 */
12859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->mbnum = mbnum;
12959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            QP = QPMB[mbnum];   /* always read new QP */
13059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
13159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (GOB_Header_Interval)
13259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->sliceNo[mbnum] = curr_slice_counter; /* Update MB slice number */
13359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else
13459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->sliceNo[mbnum] = slice_counter;
13559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
13659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /****************************************************************************************/
13759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* MB Prediction:Put into MC macroblock, substract from currVop, put in predMB */
13859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /****************************************************************************************/
13959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            getMotionCompensatedMB(video, ind_x, ind_y, offset);
14059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
14159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef H263_ONLY
14259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (start_packet_header)
14359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
14459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                slice_counter++;                        /* Increment slice counter */
14559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->sliceNo[mbnum] = slice_counter;  /* Update MB slice number*/
14659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->header_bits -= BitstreamGetPos(bs1); /* Header Bits */
14759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->QP_prev = currVop->quantizer;
14859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = EncodeVideoPacketHeader(video, mbnum, video->QP_prev, 0);
14959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->header_bits += BitstreamGetPos(bs1); /* Header Bits */
15059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                numHeaderBits = BitstreamGetPos(bs1);
15159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                start_packet_header = 0;
15259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->usePrevQP = 0;
15359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
15459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
15559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /***********************************************/
15659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* Code_MB:  DCT, Q, Q^(-1), IDCT, Motion Comp */
15759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /***********************************************/
15859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
15959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = (*CodeMB)(video, &fastDCTfunction, (offset << 5) + QP, ncoefblck);
16059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
16159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /************************************/
16259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* MB VLC Encode: VLC Encode MB     */
16359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /************************************/
16459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
16559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            (*MBVlcEncode)(video, ncoefblck, (void*)BlockCodeCoeff);
16659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
16759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /*************************************************************/
16859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* Assemble Packets:  Assemble the MB VLC codes into Packets */
16959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /*************************************************************/
17059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
17159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* Assemble_Packet(video) */
17259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef H263_ONLY
17359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (!currVol->shortVideoHeader) /* Not in ShortVideoHeader mode */
17459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
17559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (!currVol->ResyncMarkerDisable) /* RESYNC MARKER MODE */
17659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
17759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    num_bits = BitstreamGetPos(bs1) - numHeaderBits;
17859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if (num_bits > packet_size)
17959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    {
18059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        video->header_bits += BitstreamMpeg4ByteAlignStuffing(bs1); /* Byte align Packet */
18159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
18259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        status = BitstreamAppendPacket(currVol->stream, bs1); /* Put Packet to Buffer */
18359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        /* continue even if status == PV_END_OF_BUF, to get the stats */
18459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
18559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        BitstreamEncReset(bs1);
18659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
18759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        start_packet_header = 1;
18859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    }
18959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
19059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                else   /* NO RESYNC MARKER MODE */
19159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
19259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    status = BitstreamAppendEnc(currVol->stream, bs1); /* Initialize to 0 */
19359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    /* continue even if status == PV_END_OF_BUF, to get the stats */
19459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
19559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    BitstreamEncReset(bs1);
19659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
19759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
19859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else
19959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif /* H263_ONLY */
20059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {   /* ShortVideoHeader Mode */
20159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = BitstreamAppendEnc(currVol->stream, bs1);  /* Initialize to 0 */
20259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /* continue even if status == PV_END_OF_BUF, to get the stats */
20359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
20459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                BitstreamEncReset(bs1);
20559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
20659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            mbnum++;
20759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            offset += 16;
20859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        } /* End of For ind_x */
20959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
21059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        offset += (lx << 4) - width;
21159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (currVol->shortVideoHeader)  /* ShortVideoHeader = 1 */
21259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
21359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
21459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (GOB_Header_Interval)  slice_counter++;
21559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
21659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
21759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    } /* End of For ind_y */
21859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
21959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (currVol->shortVideoHeader) /* ShortVideoHeader = 1 */
22059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
22159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
22259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->header_bits += BitstreamShortHeaderByteAlignStuffing(currVol->stream); /* Byte Align */
22359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
22459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef H263_ONLY
22559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else   /* Combined Mode*/
22659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
22759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (!currVol->ResyncMarkerDisable) /* Resync Markers */
22859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
22959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
23059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (!start_packet_header)
23159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
23259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->header_bits += BitstreamMpeg4ByteAlignStuffing(bs1);/* Byte Align  */
23359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
23459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = BitstreamAppendPacket(currVol->stream, bs1);   /* Put Packet to Buffer */
23559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /* continue even if status == PV_END_OF_BUF, to get the stats */
23659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
23759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                BitstreamEncReset(bs1);
23859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
23959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
24059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else   /* No Resync Markers */
24159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
24259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->header_bits += BitstreamMpeg4ByteAlignStuffing(currVol->stream); /* Byte Align */
24359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
24459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
24559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif /* H263_ONLY */
24659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
24759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return status; /* if status == PV_END_OF_BUF, this frame will be pre-skipped */
24859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
24959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
25059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef NO_SLICE_ENCODE
25159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
25259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : EncodeSliceCombinedMode()                                    */
25359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 04/19/2002                                                   */
25459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  History  :                                                              */
25559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Encode a slice of MPEG4 bitstream in Combined mode and save  */
25659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*              the current MB to continue next time it is called.          */
25759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
25859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   :  PV_SUCCESS if successful else PV_FAIL                       */
25959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
26059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
26159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
26259f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS EncodeSliceCombinedMode(VideoEncData *video)
26359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
26459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    PV_STATUS status = PV_SUCCESS;
26559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vol *currVol = video->vol[video->currLayer];
26659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vop *currVop = video->currVop;
26759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar mode = MODE_INTRA;
26859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar *Mode = video->headerInfo.Mode;
26959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncParams *encParams = video->encParams;
27059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int nTotalMB = currVol->nTotalMB;
27159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int width = currVop->width; /* has to be Vop, for multiple of 16 */
27259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int lx = currVop->pitch; /* , with padding */
27359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//  rateControl *rc = encParams->rc[video->currLayer];
27459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar *QPMB = video->QPMB;
27559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int QP;
27659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int ind_x = video->outputMB->mb_x, ind_y = video->outputMB->mb_y;
27759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int offset = video->offset;                 /* get current MB location */
27859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int mbnum = video->mbnum, slice_counter = video->sliceNo[mbnum]; /* get current MB location */
27959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int firstMB = mbnum;
28059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int start_packet_header = 0;
28159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int num_bits = 0;
28259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int packet_size = encParams->ResyncPacketsize - 1;
28359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int resync_marker = ((!currVol->shortVideoHeader) && (!currVol->ResyncMarkerDisable));
28459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    BitstreamEncVideo *bs1 = video->bitstream1;
28559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int byteCount = 0, byteCount1 = 0, bitCount = 0;
28659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int numHeaderBits = 0;
28759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    approxDCT fastDCTfunction;
28859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int ncoefblck[6] = {64, 64, 64, 64, 64, 64}; /* for FastCodeMB,  5/18/2001 */
28959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar CBP = 0;
29059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Short outputMB[6][64];
29159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int k;
29259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    PV_STATUS(*CodeMB)(VideoEncData *, approxDCT *, Int, Int[]);
29359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void (*MBVlcEncode)(VideoEncData*, Int[], void *);
29459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void (*BlockCodeCoeff)(RunLevelBlock*, BitstreamEncVideo*, Int, Int, UChar);
29559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
29659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->QP_prev = 31;
29759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
29859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#define H263_GOB_CHANGES
29959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
30059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
30159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->end_of_buf) /* left-over from previous run */
30259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
30359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        status = BitstreamAppendPacketNoOffset(currVol->stream, bs1);
30459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (status != PV_END_OF_BUF)
30559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
30659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            BitstreamEncReset(bs1);
30759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->end_of_buf = 0;
30859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
30959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return status;
31059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
31159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
31259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
31359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (mbnum == 0) /* only do this at the start of a frame */
31459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
31559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        QPMB[0] = video->QP_prev = QP = currVop->quantizer;
31659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->usePrevQP = 0;
31759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
31859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        numHeaderBits = BitstreamGetPos(bs1);
31959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
32059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
32159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Re-assign fast functions on every slice, don't have to put it in the memory */
32259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    QP = QPMB[mbnum];
32359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (mbnum > 0)   video->QP_prev = QPMB[mbnum-1];
32459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
32559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* determine type of quantization   */
32659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef NO_MPEG_QUANT
32759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (currVol->quantType == 0)
32859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        CodeMB = &CodeMB_H263;
32959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
33059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        CodeMB = &CodeMB_MPEG;
33159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#else
33259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    CodeMB = &CodeMB_H263;
33359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
33459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
33559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* determine which functions to be used, in MB-level */
33659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (currVop->predictionType == P_VOP)
33759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        MBVlcEncode = &MBVlcEncodeCombined_P_VOP;
33859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else if (currVop->predictionType == I_VOP)
33959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        MBVlcEncode = &MBVlcEncodeCombined_I_VOP;
34059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else /* B_VOP not implemented yet */
34159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FAIL;
34259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
34359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* determine which VLC table to be used */
34459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef H263_ONLY
34559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (currVol->shortVideoHeader)
34659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockCodeCoeff = &BlockCodeCoeff_ShortHeader;
34759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef NO_RVLC
34859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else if (currVol->useReverseVLC)
34959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockCodeCoeff = &BlockCodeCoeff_RVLC;
35059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
35159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
35259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockCodeCoeff = &BlockCodeCoeff_Normal;
35359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#else
35459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    BlockCodeCoeff = &BlockCodeCoeff_ShortHeader;
35559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
35659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
35759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*  (gob_frame_id is the same for different vop types) The reason should be SCD */
35859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (currVol->shortVideoHeader && currVop->gobFrameID != currVop->predictionType)
35959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        currVop->gobFrameID = currVop->predictionType;
36059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
36159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
36259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (mbnum != 0)
36359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
36459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (currVol->shortVideoHeader)
36559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
36659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* Encode GOB Header */
36759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            bitCount = BitstreamGetPos(bs1);
36859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            byteCount1 = byteCount = bitCount >> 3; /* save the position before GOB header */
36959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            bitCount = bitCount & 0x7;
37059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
37159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef H263_GOB_CHANGES
37259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->header_bits -= BitstreamGetPos(bs1); /* Header Bits */
37359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = EncodeGOBHeader(video, slice_counter, QP, 1);  //ind_y    /* Encode GOB Header */
37459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->header_bits += BitstreamGetPos(bs1); /* Header Bits */
37559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
37659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            goto JUMP_IN_SH;
37759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
37859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else if (currVol->ResyncMarkerDisable)
37959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
38059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            goto JUMP_IN_SH;
38159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
38259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else
38359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
38459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            start_packet_header = 1;
38559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            goto JUMP_IN;
38659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
38759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
38859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
38959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (ind_y = 0; ind_y < currVol->nMBPerCol; ind_y++)    /* Col MB Loop */
39059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
39159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
39259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->outputMB->mb_y = ind_y; /*  5/28/01, do not remove */
39359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
39459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        for (ind_x = 0; ind_x < currVol->nMBPerRow; ind_x++)  /* Row MB Loop */
39559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
39659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
39759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->outputMB->mb_x = ind_x; /*  5/28/01, do not remove */
39859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->mbnum = mbnum;
39959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->sliceNo[mbnum] = slice_counter;      /* Update MB slice number */
40059f566c4ec3dfc097ad8163523e522280b27e5c3James DongJUMP_IN_SH:
40159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /****************************************************************************************/
40259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* MB Prediction:Put into MC macroblock, substract from currVop, put in predMB */
40359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /****************************************************************************************/
40459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            getMotionCompensatedMB(video, ind_x, ind_y, offset);
40559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
40659f566c4ec3dfc097ad8163523e522280b27e5c3James DongJUMP_IN:
40759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            QP = QPMB[mbnum];   /* always read new QP */
40859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef H263_ONLY
40959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (start_packet_header)
41059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
41159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                slice_counter++;                        /* Increment slice counter */
41259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->sliceNo[mbnum] = slice_counter;  /* Update MB slice number*/
41359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->QP_prev = currVop->quantizer;                        /* store QP */
41459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                num_bits = BitstreamGetPos(bs1);
41559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = EncodeVideoPacketHeader(video, mbnum, video->QP_prev, 1);
41659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                numHeaderBits = BitstreamGetPos(bs1) - num_bits;
41759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->header_bits += numHeaderBits; /* Header Bits */
41859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                start_packet_header = 0;
41959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->usePrevQP = 0;
42059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
42159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else  /* don't encode the first MB in packet again */
42259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif /* H263_ONLY */
42359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
42459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /***********************************************/
42559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /* Code_MB:  DCT, Q, Q^(-1), IDCT, Motion Comp */
42659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /***********************************************/
42759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = (*CodeMB)(video, &fastDCTfunction, (offset << 5) + QP, ncoefblck);
42859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
42959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
43059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /************************************/
43159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* MB VLC Encode: VLC Encode MB     */
43259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /************************************/
43359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
43459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* save the state before VLC encoding */
43559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (resync_marker)
43659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
43759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                bitCount = BitstreamGetPos(bs1);
43859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                byteCount = bitCount >> 3; /* save the state before encoding */
43959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                bitCount = bitCount & 0x7;
44059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mode = Mode[mbnum];
44159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                CBP = video->headerInfo.CBP[mbnum];
44259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                for (k = 0; k < 6; k++)
44359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
44459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    M4VENC_MEMCPY(outputMB[k], video->outputMB->block[k], sizeof(Short) << 6);
44559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
44659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
44759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /*************************************/
44859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
44959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            (*MBVlcEncode)(video, ncoefblck, (void*)BlockCodeCoeff);
45059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
45159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /*************************************************************/
45259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* Assemble Packets:  Assemble the MB VLC codes into Packets */
45359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /*************************************************************/
45459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
45559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* Assemble_Packet(video) */
45659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef H263_ONLY
45759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (!currVol->shortVideoHeader)
45859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
45959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (!currVol->ResyncMarkerDisable)
46059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
46159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    /* Not in ShortVideoHeader mode and RESYNC MARKER MODE */
46259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
46359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    num_bits = BitstreamGetPos(bs1) ;//- numHeaderBits; // include header
46459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
46559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    /* Assemble packet and return when size reached */
46659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if (num_bits > packet_size && mbnum != firstMB)
46759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    {
46859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
46959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        BitstreamRepos(bs1, byteCount, bitCount); /* rewind one MB */
47059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
47159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        video->header_bits += BitstreamMpeg4ByteAlignStuffing(bs1); /* Byte align Packet */
47259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
47359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        status = BitstreamAppendPacketNoOffset(currVol->stream, bs1); /* Put Packet to Buffer */
47459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
47559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        if (status == PV_END_OF_BUF)
47659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        {
47759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            video->end_of_buf = 1;
47859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        }
47959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        else
48059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        {
48159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            BitstreamEncReset(bs1);
48259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        }
48359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
48459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        start_packet_header = 1;
48559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
48659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        if (mbnum < nTotalMB || video->end_of_buf) /* return here */
48759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        {
48859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            video->mbnum = mbnum;
48959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            video->sliceNo[mbnum] = slice_counter;
49059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            video->offset = offset;
49159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            Mode[mbnum] = mode;
49259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            video->headerInfo.CBP[mbnum] = CBP;
49359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
49459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            for (k = 0; k < 6; k++)
49559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            {
49659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                M4VENC_MEMCPY(video->outputMB->block[k], outputMB[k], sizeof(Short) << 6);
49759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            }
49859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
49959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            return status;
50059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        }
50159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    }
50259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
50359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                else  /* NO RESYNC MARKER , return when buffer is full*/
50459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
50559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
50659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if (mbnum < nTotalMB - 1 && currVol->stream->byteCount + bs1->byteCount + 1 >= currVol->stream->bufferSize)
50759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    {
50859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        /* find maximum bytes to fit in the buffer */
50959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        byteCount = currVol->stream->bufferSize - currVol->stream->byteCount - 1;
51059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
51159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        num_bits = BitstreamGetPos(bs1) - (byteCount << 3);
51259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        BitstreamRepos(bs1, byteCount, 0);
51359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        status = BitstreamAppendPacketNoOffset(currVol->stream, bs1);
51459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        BitstreamFlushBits(bs1, num_bits);
51559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
51659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        /* move on to next MB */
51759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        mbnum++ ;
51859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        offset += 16;
51959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        video->outputMB->mb_x++;
52059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        if (video->outputMB->mb_x >= currVol->nMBPerRow)
52159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        {
52259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            video->outputMB->mb_x = 0;
52359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            video->outputMB->mb_y++;
52459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            offset += (lx << 4) - width;
52559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        }
52659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        video->mbnum = mbnum;
52759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        video->offset = offset;
52859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        video->sliceNo[mbnum] = slice_counter;
52959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        return status;
53059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    }
53159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
53259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
53359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif /* H263_ONLY */
53459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            offset += 16;
53559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            mbnum++; /* has to increment before SCD, to preserve Mode[mbnum] */
53659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
53759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        } /* End of For ind_x */
53859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
53959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        offset += (lx << 4) - width;
54059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
54159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (currVol->shortVideoHeader)  /* ShortVideoHeader = 1 */
54259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
54359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef H263_GOB_CHANGES
54459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            slice_counter++;
54559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->header_bits += BitstreamShortHeaderByteAlignStuffing(bs1);
54659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
54759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            //video->header_bits+=BitstreamShortHeaderByteAlignStuffing(bs1);
54859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
54959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* check if time to packetize */
55059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (currVol->stream->byteCount + bs1->byteCount > currVol->stream->bufferSize)
55159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
55259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (byteCount == byteCount1) /* a single GOB bigger than packet size */
55359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
55459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    status = BitstreamAppendPacketNoOffset(currVol->stream, bs1);
55559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    status = PV_END_OF_BUF;
55659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    video->end_of_buf = 1;
55759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    start_packet_header = 1;
55859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
55959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                else    /* for short_header scooch back to previous GOB */
56059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
56159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    num_bits = ((bs1->byteCount - byteCount) << 3);
56259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    //num_bits = ((bs1->byteCount<<3) + bs1->bitCount) - ((byteCount<<3) + bitCount);
56359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    BitstreamRepos(bs1, byteCount, 0);
56459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    //BitstreamRepos(bs1,byteCount,bitCount);
56559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//                  k = currVol->stream->byteCount; /* save state before appending */
56659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    status = BitstreamAppendPacketNoOffset(currVol->stream, bs1);
56759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    BitstreamFlushBits(bs1, num_bits);
56859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//                  if(mbnum == nTotalMB || k + bs1->byteCount >= currVol->stream->bufferSize){
56959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    /* last GOB or current one with larger size will be returned next run */
57059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//                      status = PV_END_OF_BUF;
57159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//                      video->end_of_buf = 1;
57259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//                  }
57359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    start_packet_header = 1;
57459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if (mbnum == nTotalMB) /* there's one more GOB to packetize for the next round */
57559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    {
57659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        status = PV_END_OF_BUF;
57759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        video->end_of_buf = 1;
57859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    }
57959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
58059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
58159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (mbnum < nTotalMB) /* return here */
58259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
58359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    /* move on to next MB */
58459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    video->outputMB->mb_x = 0;
58559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    video->outputMB->mb_y++;
58659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    video->mbnum = mbnum;
58759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    video->offset = offset;
58859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    video->sliceNo[mbnum] = slice_counter;
58959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    return status;
59059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
59159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
59259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else if (mbnum < nTotalMB) /* do not write GOB header if end of vop */
59359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
59459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                bitCount = BitstreamGetPos(bs1);
59559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                byteCount = bitCount >> 3;  /* save the position before GOB header */
59659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                bitCount = bitCount & 0x7;
59759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef H263_GOB_CHANGES
59859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->header_bits -= BitstreamGetPos(bs1); /* Header Bits */
59959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = EncodeGOBHeader(video, slice_counter, QP, 1);         /* Encode GOB Header */
60059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->header_bits += BitstreamGetPos(bs1); /* Header Bits */
60159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
60259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
60359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
60459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
60559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    } /* End of For ind_y */
60659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef H263_ONLY
60759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (!currVol->shortVideoHeader) /* Combined Mode*/
60859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
60959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (!currVol->ResyncMarkerDisable) /* Resync Markers */
61059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
61159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
61259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (!start_packet_header)
61359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
61459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
61559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->header_bits += BitstreamMpeg4ByteAlignStuffing(bs1);/* Byte Align  */
61659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
61759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = BitstreamAppendPacketNoOffset(currVol->stream, bs1);   /* Put Packet to Buffer */
61859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (status == PV_END_OF_BUF)
61959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
62059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    video->end_of_buf = 1;
62159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
62259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                else
62359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
62459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    BitstreamEncReset(bs1);
62559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
62659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
62759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
62859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else   /* No Resync Markers */
62959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
63059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->header_bits += BitstreamMpeg4ByteAlignStuffing(bs1); /* Byte Align */
63159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = BitstreamAppendPacketNoOffset(currVol->stream, bs1); /* Initialize to 0 */
63259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (status == PV_END_OF_BUF)
63359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
63459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->end_of_buf = 1;
63559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
63659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else
63759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
63859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                BitstreamEncReset(bs1);
63959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
64059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
64159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
64259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
64359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif /* H263_ONLY */
64459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
64559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (!start_packet_header) /* not yet packetized */
64659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
64759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->header_bits += BitstreamShortHeaderByteAlignStuffing(bs1);
64859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = BitstreamAppendPacketNoOffset(currVol->stream, bs1);
64959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (status == PV_END_OF_BUF)
65059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
65159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->end_of_buf = 1;
65259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
65359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else
65459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
65559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                BitstreamEncReset(bs1);
65659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->end_of_buf = 0;
65759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
65859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
65959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
66059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
66159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->mbnum = mbnum;
66259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (mbnum < nTotalMB)
66359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->sliceNo[mbnum] = slice_counter;
66459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->offset = offset;
66559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
66659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return status;
66759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
66859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif  /* NO_SLICE_ENCODE */
66959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
67059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
67159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : EncodeGOBHeader()                                            */
67259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 09/05/2000                                                   */
67359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  History  :                                                              */
67459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Encode a frame of MPEG4 bitstream in Combined mode.          */
67559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
67659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   :  PV_SUCCESS if successful else PV_FAIL                       */
67759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
67859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
67959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
68059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
68159f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS EncodeGOBHeader(VideoEncData *video, Int GOB_number, Int quant_scale, Int bs1stream)
68259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
68359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    PV_STATUS status = PV_SUCCESS;
68459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    BitstreamEncVideo *stream = (bs1stream ? video->bitstream1 : video->vol[video->currLayer]->stream);
68559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
68659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    status = BitstreamPutGT16Bits(stream, 17, GOB_RESYNC_MARKER); /* gob_resync_marker */
68759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    status = BitstreamPutBits(stream, 5, GOB_number);           /* Current gob_number */
68859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    status = BitstreamPutBits(stream, 2, video->currVop->gobFrameID); /* gob_frame_id */
68959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    status = BitstreamPutBits(stream, 5, quant_scale);              /* quant_scale */
69059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return status;
69159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
69259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
69359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
694