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#ifndef H263_ONLY
1959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
2059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "mp4def.h"
2159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "mp4lib_int.h"
2259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "bitstream_io.h"
2359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "mp4enc_lib.h"
2459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "m4venc_oscl.h"
2559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
2659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
2759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : EncodeFrameDataPartMode()                                    */
2859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 09/6/2000                                                    */
2959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  History  :                                                              */
3059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Encode a frame of MPEG4 bitstream in datapartitioning mode.  */
3159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
3259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   :  PV_SUCCESS if successful else PV_FAIL                       */
3359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
3459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
3559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
3659f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS EncodeFrameDataPartMode(VideoEncData *video)
3759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
3859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    PV_STATUS status = PV_SUCCESS;
3959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vol *currVol = video->vol[video->currLayer];
4059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vop *currVop = video->currVop;
4159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncParams *encParams = video->encParams;
4259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int width = currVop->width; /* has to be Vop, for multiple of 16 */
4359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int lx = currVop->pitch; /*  with padding */
4459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int offset = 0;
4559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int ind_x, ind_y;
4659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int start_packet_header = 0;
4759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar *QPMB = video->QPMB;
4859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int QP;
4959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int mbnum = 0, slice_counter = 0;
5059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int num_bits, packet_size = encParams->ResyncPacketsize;
5159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    BitstreamEncVideo *bs1 = video->bitstream1;
5259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    BitstreamEncVideo *bs2 = video->bitstream2;
5359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    BitstreamEncVideo *bs3 = video->bitstream3;
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    video->QP_prev = currVop->quantizer;
6259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
6359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    numHeaderBits = BitstreamGetPos(bs1); /* Number of bits in VOP Header */
6459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
6559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* determine type of quantization   */
6659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef NO_MPEG_QUANT
6759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (currVol->quantType == 0)
6859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        CodeMB = &CodeMB_H263;
6959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
7059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        CodeMB = &CodeMB_MPEG;
7159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#else
7259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    CodeMB = &CodeMB_H263;
7359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
7459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
7559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* determine which functions to be used, in MB-level */
7659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (currVop->predictionType == P_VOP)
7759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        MBVlcEncode = &MBVlcEncodeDataPar_P_VOP;
7859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else if (currVop->predictionType == I_VOP)
7959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        MBVlcEncode = &MBVlcEncodeDataPar_I_VOP;
8059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else /* B_VOP not implemented yet */
8159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FAIL;
8259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
8359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* determine which VLC table to be used */
8459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (currVol->shortVideoHeader)
8559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockCodeCoeff = &BlockCodeCoeff_ShortHeader;
8659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef NO_RVLC
8759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else if (currVol->useReverseVLC)
8859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockCodeCoeff = &BlockCodeCoeff_RVLC;
8959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
9059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
9159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockCodeCoeff = &BlockCodeCoeff_Normal;
9259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
9359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->usePrevQP = 0;
9459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
9559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (ind_y = 0; ind_y < currVol->nMBPerCol; ind_y++)    /* Col MB Loop */
9659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
9759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
9859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->outputMB->mb_y = ind_y; /*  5/28/01 */
9959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
10059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        for (ind_x = 0; ind_x < currVol->nMBPerRow; ind_x++)  /* Row MB Loop */
10159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
10259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->outputMB->mb_x = ind_x; /*  5/28/01 */
10359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->mbnum = mbnum;
10459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->sliceNo[mbnum] = slice_counter;      /* Update MB slice number */
10559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            QP = QPMB[mbnum];   /* always read new QP */
10659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
10759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /****************************************************************************************/
10859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* MB Prediction:Put into MC macroblock, substract from currVop, put in predMB */
10959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /****************************************************************************************/
11059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
11159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            getMotionCompensatedMB(video, ind_x, ind_y, offset);
11259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
11359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (start_packet_header)
11459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
11559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                slice_counter++;                        /* Increment slice counter */
11659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->sliceNo[mbnum] = slice_counter;  /* Update MB slice number*/
11759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->header_bits -= BitstreamGetPos(bs1); /* Header Bits */
11859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->QP_prev = currVop->quantizer;                        /* store QP */
11959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = EncodeVideoPacketHeader(video, mbnum, video->QP_prev, 0);
12059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->header_bits += BitstreamGetPos(bs1); /* Header Bits */
12159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                numHeaderBits = BitstreamGetPos(bs1);
12259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                start_packet_header = 0;
12359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->usePrevQP = 0;
12459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
12559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
12659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /***********************************************/
12759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* Code_MB:  DCT, Q, Q^(-1), IDCT, Motion Comp */
12859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /***********************************************/
12959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
13059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            status = (*CodeMB)(video, &fastDCTfunction, (offset << 5) + QP, ncoefblck);
13159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
13259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /************************************/
13359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* MB VLC Encode: VLC Encode MB     */
13459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /************************************/
13559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
13659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            MBVlcEncode(video, ncoefblck, (void*)BlockCodeCoeff);
13759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
13859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /*************************************************************/
13959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* Assemble Packets:  Assemble the MB VLC codes into Packets */
14059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /*************************************************************/
14159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
14259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* INCLUDE VOP HEADER IN COUNT */
14359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
14459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            num_bits = BitstreamGetPos(bs1) + BitstreamGetPos(bs2) +
14559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                       BitstreamGetPos(bs3) - numHeaderBits;
14659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
14759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* Assemble_Packet(video) */
14859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
14959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (num_bits > packet_size)
15059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
15159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (video->currVop->predictionType == I_VOP)
15259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    BitstreamPutGT16Bits(bs1, 19, DC_MARKER);   /* Add dc_marker */
15359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                else
15459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    BitstreamPutGT16Bits(bs1, 17, MOTION_MARKER_COMB); /*Add motion_marker*/
15559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                BitstreamAppendEnc(bs1, bs2);   /* Combine bs1 and bs2 */
15659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                BitstreamAppendEnc(bs1, bs3);   /* Combine bs1 and bs3 */
15759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->header_bits += BitstreamMpeg4ByteAlignStuffing(bs1); /* Byte align Packet */
15859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
15959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = BitstreamAppendPacket(currVol->stream, bs1); /* Put Packet to Buffer */
16059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /* continue even if status == PV_END_OF_BUF, to get the stats */
16159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
16259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                BitstreamEncReset(bs1); /* Initialize to 0 */
16359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                BitstreamEncReset(bs2);
16459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                BitstreamEncReset(bs3);
16559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                start_packet_header = 1;
16659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
16759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            mbnum++;
16859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            offset += 16;
16959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        } /* End of For ind_x */
17059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
17159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        offset += (lx << 4) - width;
17259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    } /* End of For ind_y */
17359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
17459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (!start_packet_header)
17559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
17659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->currVop->predictionType == I_VOP)
17759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
17859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            BitstreamPutGT16Bits(bs1, 19, DC_MARKER);   /* Add dc_marker */
17959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->header_bits += 19;
18059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
18159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else
18259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
18359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            BitstreamPutGT16Bits(bs1, 17, MOTION_MARKER_COMB); /* Add motion_marker */
18459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->header_bits += 17;
18559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
18659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BitstreamAppendEnc(bs1, bs2);
18759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BitstreamAppendEnc(bs1, bs3);
18859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->header_bits += BitstreamMpeg4ByteAlignStuffing(bs1); /* Byte align Packet */
18959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        status = BitstreamAppendPacket(currVol->stream, bs1); /* Put Packet to Buffer */
19059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* continue even if status == PV_END_OF_BUF, to get the stats */
19159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BitstreamEncReset(bs1); /* Initialize to 0 */
19259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BitstreamEncReset(bs2);
19359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BitstreamEncReset(bs3);
19459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
19559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
19659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return status; /* if status == PV_END_OF_BUF, this frame will be pre-skipped */
19759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
19859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
19959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef  NO_SLICE_ENCODE
20059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
20159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : EncodeSliceDataPartMode()                                    */
20259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 04/19/2002                                                   */
20359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  History  :                                                              */
20459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Encode a slice of MPEG4 bitstream in DataPar mode and save   */
20559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*              the current MB to continue next time it is called.          */
20659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   :                                                              */
20759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   :  PV_SUCCESS if successful else PV_FAIL                       */
20859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
20959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
21059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
21159f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS EncodeSliceDataPartMode(VideoEncData *video)
21259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
21359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    PV_STATUS status = PV_SUCCESS;
21459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vol *currVol = video->vol[video->currLayer];
21559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vop *currVop = video->currVop;
21659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar mode, *Mode = video->headerInfo.Mode;
21759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncParams *encParams = video->encParams;
21859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int nTotalMB = currVol->nTotalMB;
21959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int width = currVop->width; /* has to be Vop, for multiple of 16 */
22059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int lx = currVop->pitch; /* , with pading */
22159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar *QPMB = video->QPMB;
22259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int QP;
22359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int ind_x = video->outputMB->mb_x, ind_y = video->outputMB->mb_y;
22459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int offset = video->offset;                 /* get current MB location */
22559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int mbnum = video->mbnum, slice_counter = video->sliceNo[mbnum]; /* get current MB location */
22659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int firstMB = mbnum;
22759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int start_packet_header = (mbnum != 0);
22859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int num_bits = 0;
22959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int packet_size = encParams->ResyncPacketsize - 1 - (currVop->predictionType == I_VOP ? 19 : 17);
23059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    BitstreamEncVideo *bs1 = video->bitstream1;
23159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    BitstreamEncVideo *bs2 = video->bitstream2;
23259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    BitstreamEncVideo *bs3 = video->bitstream3;
23359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int bitCount1 = 0, bitCount2 = 0, bitCount3 = 0, byteCount1 = 0, byteCount2 = 0, byteCount3 = 0;
23459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int numHeaderBits = 0;
23559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    approxDCT fastDCTfunction;
23659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int ncoefblck[6] = {64, 64, 64, 64, 64, 64}; /* for FastCodeMB,  5/18/2001 */
23759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar CBP;
23859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Short outputMB[6][64];
23959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    PV_STATUS(*CodeMB)(VideoEncData *, approxDCT *, Int, Int[]);
24059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void (*MBVlcEncode)(VideoEncData*, Int[], void *);
24159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void (*BlockCodeCoeff)(RunLevelBlock*, BitstreamEncVideo*, Int, Int, UChar);
24259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int k;
24359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
24459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->QP_prev = 31;
24559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
24659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->end_of_buf) /* left-over from previous run */
24759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
24859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        status = BitstreamAppendPacketNoOffset(currVol->stream, bs1);
24959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (status != PV_END_OF_BUF)
25059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
25159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            BitstreamEncReset(bs1);
25259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->end_of_buf = 0;
25359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
25459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return status;
25559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
25659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
25759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (mbnum == 0) /* only do this at the start of a frame */
25859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
25959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        QPMB[0] = video->QP_prev = QP = currVop->quantizer;
26059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->usePrevQP = 0;
26159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
26259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        numHeaderBits = BitstreamGetPos(bs1); /* Number of bits in VOP Header */
26359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
26459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
26559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
26659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
26759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Re-assign fast functions on every slice, don't have to put it in the memory */
26859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    QP = QPMB[mbnum];
26959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (mbnum > 0)   video->QP_prev = QPMB[mbnum-1];
27059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
27159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* determine type of quantization   */
27259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef NO_MPEG_QUANT
27359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (currVol->quantType == 0)
27459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        CodeMB = &CodeMB_H263;
27559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
27659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        CodeMB = &CodeMB_MPEG;
27759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#else
27859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    CodeMB = &CodeMB_H263;
27959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
28059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
28159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* determine which functions to be used, in MB-level */
28259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (currVop->predictionType == P_VOP)
28359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        MBVlcEncode = &MBVlcEncodeDataPar_P_VOP;
28459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else if (currVop->predictionType == I_VOP)
28559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        MBVlcEncode = &MBVlcEncodeDataPar_I_VOP;
28659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else /* B_VOP not implemented yet */
28759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return PV_FAIL;
28859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
28959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* determine which VLC table to be used */
29059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef NO_RVLC
29159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (currVol->useReverseVLC)
29259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockCodeCoeff = &BlockCodeCoeff_RVLC;
29359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
29459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
29559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockCodeCoeff = &BlockCodeCoeff_Normal;
29659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
29759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (mbnum != 0)
29859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
29959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        goto JUMP_IN;
30059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
30159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
30259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (ind_y = 0; ind_y < currVol->nMBPerCol; ind_y++)    /* Col MB Loop */
30359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
30459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
30559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->outputMB->mb_y = ind_y; /*  5/28/01 */
30659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
30759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        for (ind_x = 0; ind_x < currVol->nMBPerRow; ind_x++)  /* Row MB Loop */
30859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
30959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
31059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->outputMB->mb_x = ind_x; /*  5/28/01 */
31159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->mbnum = mbnum;
31259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->sliceNo[mbnum] = slice_counter;      /* Update MB slice number */
31359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
31459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /****************************************************************************************/
31559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* MB Prediction:Put into MC macroblock, substract from currVop, put in predMB */
31659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /****************************************************************************************/
31759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            getMotionCompensatedMB(video, ind_x, ind_y, offset);
31859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
31959f566c4ec3dfc097ad8163523e522280b27e5c3James DongJUMP_IN:
32059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
32159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            QP = QPMB[mbnum];   /* always read new QP */
32259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
32359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (start_packet_header)
32459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
32559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                slice_counter++;                        /* Increment slice counter */
32659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->sliceNo[mbnum] = slice_counter;  /* Update MB slice number*/
32759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->QP_prev = currVop->quantizer;                        /* store QP */
32859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                num_bits = BitstreamGetPos(bs1);
32959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = EncodeVideoPacketHeader(video, mbnum, video->QP_prev, 0);
33059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                numHeaderBits = BitstreamGetPos(bs1) - num_bits;
33159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->header_bits += numHeaderBits; /* Header Bits */
33259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                start_packet_header = 0;
33359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->usePrevQP = 0;
33459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
33559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else  /* don't encode the first MB in packet again */
33659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
33759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /***********************************************/
33859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /* Code_MB:  DCT, Q, Q^(-1), IDCT, Motion Comp */
33959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /***********************************************/
34059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
34159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = (*CodeMB)(video, &fastDCTfunction, (offset << 5) + QP, ncoefblck);
34259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                for (k = 0; k < 6; k++)
34359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
34459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    M4VENC_MEMCPY(outputMB[k], video->outputMB->block[k], sizeof(Short) << 6);
34559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
34659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
34759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
34859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /************************************/
34959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* MB VLC Encode: VLC Encode MB     */
35059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /************************************/
35159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
35259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* save the state before VLC encoding */
35359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            bitCount1 = BitstreamGetPos(bs1);
35459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            bitCount2 = BitstreamGetPos(bs2);
35559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            bitCount3 = BitstreamGetPos(bs3);
35659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            byteCount1 = bitCount1 >> 3;
35759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            byteCount2 = bitCount2 >> 3;
35859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            byteCount3 = bitCount3 >> 3;
35959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            bitCount1 &= 0x7;
36059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            bitCount2 &= 0x7;
36159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            bitCount3 &= 0x7;
36259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            mode = Mode[mbnum];
36359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            CBP = video->headerInfo.CBP[mbnum];
36459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
36559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /*************************************/
36659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
36759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            MBVlcEncode(video, ncoefblck, (void*)BlockCodeCoeff);
36859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
36959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /*************************************************************/
37059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* Assemble Packets:  Assemble the MB VLC codes into Packets */
37159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /*************************************************************/
37259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
37359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            num_bits = BitstreamGetPos(bs1) + BitstreamGetPos(bs2) +
37459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                       BitstreamGetPos(bs3);// - numHeaderBits; //include header bits
37559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
37659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* Assemble_Packet(video) */
37759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (num_bits > packet_size && mbnum != firstMB)  /* encoding at least one more MB*/
37859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
37959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
38059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                BitstreamRepos(bs1, byteCount1, bitCount1); /* rewind one MB */
38159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                BitstreamRepos(bs2, byteCount2, bitCount2); /* rewind one MB */
38259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                BitstreamRepos(bs3, byteCount3, bitCount3); /* rewind one MB */
38359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
38459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (video->currVop->predictionType == I_VOP)
38559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
38659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    BitstreamPutGT16Bits(bs1, 19, DC_MARKER);   /* Add dc_marker */
38759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    video->header_bits += 19;
38859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
38959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                else
39059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
39159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    BitstreamPutGT16Bits(bs1, 17, MOTION_MARKER_COMB); /*Add motion_marker*/
39259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    video->header_bits += 17;
39359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
39459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
39559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = BitstreamAppendEnc(bs1, bs2);  /* Combine with bs2 */
39659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = BitstreamAppendEnc(bs1, bs3);  /* Combine with bs3 */
39759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
39859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->header_bits += BitstreamMpeg4ByteAlignStuffing(bs1); /* Byte align Packet */
39959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                status = BitstreamAppendPacketNoOffset(currVol->stream, bs1);
40059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
40159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                BitstreamEncReset(bs2);
40259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                BitstreamEncReset(bs3);
40359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
40459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (status == PV_END_OF_BUF) /* if cannot fit a buffer */
40559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
40659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    video->end_of_buf = 1;
40759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
40859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                else
40959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
41059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    BitstreamEncReset(bs1);
41159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
41259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
41359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                start_packet_header = 1;
41459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
41559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (mbnum < nTotalMB || video->end_of_buf) /* return here */
41659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
41759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    video->mbnum = mbnum;
41859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    video->sliceNo[mbnum] = slice_counter;
41959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    video->offset = offset;
42059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    Mode[mbnum] = mode;
42159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    video->headerInfo.CBP[mbnum] = CBP;
42259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
42359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    for (k = 0; k < 6; k++)
42459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    {
42559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        M4VENC_MEMCPY(video->outputMB->block[k], outputMB[k], sizeof(Short) << 6);
42659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    }
42759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
42859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    return status;
42959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
43059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
43159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
43259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            offset += 16;
43359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            mbnum++; /* has to increment before SCD, to preserve Mode[mbnum] */
43459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        } /* End of For ind_x */
43559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
43659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        offset += (lx << 4) - width;
43759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
43859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    } /* End of For ind_y */
43959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
44059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (!start_packet_header)
44159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
44259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->currVop->predictionType == I_VOP)
44359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
44459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            BitstreamPutGT16Bits(bs1, 19, DC_MARKER);   /* Add dc_marker */
44559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->header_bits += 19;
44659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
44759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else
44859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
44959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            BitstreamPutGT16Bits(bs1, 17, MOTION_MARKER_COMB); /*Add motion_marker*/
45059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->header_bits += 17;
45159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
45259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
45359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        status = BitstreamAppendEnc(bs1, bs2);  /* Combine with bs2 */
45459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        status = BitstreamAppendEnc(bs1, bs3);  /* Combine with bs3 */
45559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
45659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->header_bits += BitstreamMpeg4ByteAlignStuffing(bs1); /* Byte align Packet */
45759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        status = BitstreamAppendPacketNoOffset(currVol->stream, bs1);
45859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
45959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BitstreamEncReset(bs2);
46059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BitstreamEncReset(bs3);
46159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
46259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (status == PV_END_OF_BUF)
46359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
46459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            video->end_of_buf = 1;
46559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
46659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else
46759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
46859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            BitstreamEncReset(bs1);
46959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
47059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
47159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
47259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->mbnum = mbnum;
47359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (mbnum < nTotalMB)
47459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->sliceNo[mbnum] = slice_counter;
47559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->offset = offset;
47659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
47759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return status;
47859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
47959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif /* NO_SLICE_ENCODE */
48059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif /* H263_ONLY */
48159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
48259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
483