142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/* ------------------------------------------------------------------
242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong * Copyright (C) 1998-2009 PacketVideo
342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong *
442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong * Licensed under the Apache License, Version 2.0 (the "License");
542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong * you may not use this file except in compliance with the License.
642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong * You may obtain a copy of the License at
742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong *
842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong *      http://www.apache.org/licenses/LICENSE-2.0
942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong *
1042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong * Unless required by applicable law or agreed to in writing, software
1142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong * distributed under the License is distributed on an "AS IS" BASIS,
1242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
1342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong * express or implied.
1442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong * See the License for the specific language governing permissions
1542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong * and limitations under the License.
1642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong * -------------------------------------------------------------------
1742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong */
1842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifndef H263_ONLY
1942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
2042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#include "mp4def.h"
2142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#include "mp4lib_int.h"
2242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#include "bitstream_io.h"
2342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#include "mp4enc_lib.h"
2442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#include "m4venc_oscl.h"
2542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
2642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/* ======================================================================== */
2742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*  Function : EncodeFrameDataPartMode()                                    */
2842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*  Date     : 09/6/2000                                                    */
2942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*  History  :                                                              */
3042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*  Purpose  : Encode a frame of MPEG4 bitstream in datapartitioning mode.  */
3142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*  In/out   :                                                              */
3242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*  Return   :  PV_SUCCESS if successful else PV_FAIL                       */
3342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*  Modified :                                                              */
3442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*                                                                          */
3542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/* ======================================================================== */
3642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames DongPV_STATUS EncodeFrameDataPartMode(VideoEncData *video)
3742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong{
3842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    PV_STATUS status = PV_SUCCESS;
3942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Vol *currVol = video->vol[video->currLayer];
4042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Vop *currVop = video->currVop;
4142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    VideoEncParams *encParams = video->encParams;
4242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int width = currVop->width; /* has to be Vop, for multiple of 16 */
4342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int lx = currVop->pitch; /*  with padding */
4442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int offset = 0;
4542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int ind_x, ind_y;
4642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int start_packet_header = 0;
4742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    UChar *QPMB = video->QPMB;
4842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int QP;
4942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int mbnum = 0, slice_counter = 0;
5042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int num_bits, packet_size = encParams->ResyncPacketsize;
5142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    BitstreamEncVideo *bs1 = video->bitstream1;
5242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    BitstreamEncVideo *bs2 = video->bitstream2;
5342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    BitstreamEncVideo *bs3 = video->bitstream3;
5442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int numHeaderBits;
5542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    approxDCT fastDCTfunction;
5642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int ncoefblck[6] = {64, 64, 64, 64, 64, 64}; /* for FastCodeMB,  5/18/2001 */
5742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    PV_STATUS(*CodeMB)(VideoEncData *, approxDCT *, Int, Int[]);
5842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    void (*MBVlcEncode)(VideoEncData*, Int[], void *);
5942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    void (*BlockCodeCoeff)(RunLevelBlock*, BitstreamEncVideo*, Int, Int, UChar);
6042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
6142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    video->QP_prev = currVop->quantizer;
6242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
6342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    numHeaderBits = BitstreamGetPos(bs1); /* Number of bits in VOP Header */
6442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
6542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /* determine type of quantization   */
6642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifndef NO_MPEG_QUANT
6742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (currVol->quantType == 0)
6842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        CodeMB = &CodeMB_H263;
6942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    else
7042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        CodeMB = &CodeMB_MPEG;
7142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#else
7242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    CodeMB = &CodeMB_H263;
7342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
7442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
7542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /* determine which functions to be used, in MB-level */
7642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (currVop->predictionType == P_VOP)
7742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        MBVlcEncode = &MBVlcEncodeDataPar_P_VOP;
7842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    else if (currVop->predictionType == I_VOP)
7942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        MBVlcEncode = &MBVlcEncodeDataPar_I_VOP;
8042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    else /* B_VOP not implemented yet */
8142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        return PV_FAIL;
8242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
8342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /* determine which VLC table to be used */
8442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (currVol->shortVideoHeader)
8542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        BlockCodeCoeff = &BlockCodeCoeff_ShortHeader;
8642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifndef NO_RVLC
8742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    else if (currVol->useReverseVLC)
8842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        BlockCodeCoeff = &BlockCodeCoeff_RVLC;
8942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
9042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    else
9142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        BlockCodeCoeff = &BlockCodeCoeff_Normal;
9242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
9342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    video->usePrevQP = 0;
9442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
9542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    for (ind_y = 0; ind_y < currVol->nMBPerCol; ind_y++)    /* Col MB Loop */
9642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
9742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
9842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        video->outputMB->mb_y = ind_y; /*  5/28/01 */
9942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
10042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        for (ind_x = 0; ind_x < currVol->nMBPerRow; ind_x++)  /* Row MB Loop */
10142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
10242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            video->outputMB->mb_x = ind_x; /*  5/28/01 */
10342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            video->mbnum = mbnum;
10442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            video->sliceNo[mbnum] = slice_counter;      /* Update MB slice number */
10542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            QP = QPMB[mbnum];   /* always read new QP */
10642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
10742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /****************************************************************************************/
10842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /* MB Prediction:Put into MC macroblock, substract from currVop, put in predMB */
10942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /****************************************************************************************/
11042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
11142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            getMotionCompensatedMB(video, ind_x, ind_y, offset);
11242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
11342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (start_packet_header)
11442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
11542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                slice_counter++;                        /* Increment slice counter */
11642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                video->sliceNo[mbnum] = slice_counter;  /* Update MB slice number*/
11742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                video->header_bits -= BitstreamGetPos(bs1); /* Header Bits */
11842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                video->QP_prev = currVop->quantizer;                        /* store QP */
11942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                status = EncodeVideoPacketHeader(video, mbnum, video->QP_prev, 0);
12042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                video->header_bits += BitstreamGetPos(bs1); /* Header Bits */
12142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                numHeaderBits = BitstreamGetPos(bs1);
12242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                start_packet_header = 0;
12342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                video->usePrevQP = 0;
12442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
12542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
12642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /***********************************************/
12742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /* Code_MB:  DCT, Q, Q^(-1), IDCT, Motion Comp */
12842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /***********************************************/
12942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
13042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            status = (*CodeMB)(video, &fastDCTfunction, (offset << 5) + QP, ncoefblck);
13142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
13242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /************************************/
13342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /* MB VLC Encode: VLC Encode MB     */
13442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /************************************/
13542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
13642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            MBVlcEncode(video, ncoefblck, (void*)BlockCodeCoeff);
13742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
13842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /*************************************************************/
13942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /* Assemble Packets:  Assemble the MB VLC codes into Packets */
14042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /*************************************************************/
14142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
14242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /* INCLUDE VOP HEADER IN COUNT */
14342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
14442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            num_bits = BitstreamGetPos(bs1) + BitstreamGetPos(bs2) +
14542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                       BitstreamGetPos(bs3) - numHeaderBits;
14642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
14742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /* Assemble_Packet(video) */
14842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
14942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (num_bits > packet_size)
15042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
15142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                if (video->currVop->predictionType == I_VOP)
15242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    BitstreamPutGT16Bits(bs1, 19, DC_MARKER);   /* Add dc_marker */
15342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                else
15442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    BitstreamPutGT16Bits(bs1, 17, MOTION_MARKER_COMB); /*Add motion_marker*/
15542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                BitstreamAppendEnc(bs1, bs2);   /* Combine bs1 and bs2 */
15642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                BitstreamAppendEnc(bs1, bs3);   /* Combine bs1 and bs3 */
15742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                video->header_bits += BitstreamMpeg4ByteAlignStuffing(bs1); /* Byte align Packet */
15842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
15942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                status = BitstreamAppendPacket(currVol->stream, bs1); /* Put Packet to Buffer */
16042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                /* continue even if status == PV_END_OF_BUF, to get the stats */
16142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
16242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                BitstreamEncReset(bs1); /* Initialize to 0 */
16342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                BitstreamEncReset(bs2);
16442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                BitstreamEncReset(bs3);
16542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                start_packet_header = 1;
16642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
16742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            mbnum++;
16842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            offset += 16;
16942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        } /* End of For ind_x */
17042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
17142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        offset += (lx << 4) - width;
17242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    } /* End of For ind_y */
17342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
17442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (!start_packet_header)
17542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
17642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        if (video->currVop->predictionType == I_VOP)
17742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
17842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            BitstreamPutGT16Bits(bs1, 19, DC_MARKER);   /* Add dc_marker */
17942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            video->header_bits += 19;
18042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        }
18142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        else
18242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
18342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            BitstreamPutGT16Bits(bs1, 17, MOTION_MARKER_COMB); /* Add motion_marker */
18442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            video->header_bits += 17;
18542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        }
18642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        BitstreamAppendEnc(bs1, bs2);
18742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        BitstreamAppendEnc(bs1, bs3);
18842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        video->header_bits += BitstreamMpeg4ByteAlignStuffing(bs1); /* Byte align Packet */
18942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        status = BitstreamAppendPacket(currVol->stream, bs1); /* Put Packet to Buffer */
19042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        /* continue even if status == PV_END_OF_BUF, to get the stats */
19142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        BitstreamEncReset(bs1); /* Initialize to 0 */
19242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        BitstreamEncReset(bs2);
19342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        BitstreamEncReset(bs3);
19442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
19542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
19642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    return status; /* if status == PV_END_OF_BUF, this frame will be pre-skipped */
19742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong}
19842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
19942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifndef  NO_SLICE_ENCODE
20042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/* ======================================================================== */
20142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*  Function : EncodeSliceDataPartMode()                                    */
20242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*  Date     : 04/19/2002                                                   */
20342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*  History  :                                                              */
20442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*  Purpose  : Encode a slice of MPEG4 bitstream in DataPar mode and save   */
20542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*              the current MB to continue next time it is called.          */
20642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*  In/out   :                                                              */
20742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*  Return   :  PV_SUCCESS if successful else PV_FAIL                       */
20842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*  Modified :                                                              */
20942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*                                                                          */
21042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/* ======================================================================== */
21142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames DongPV_STATUS EncodeSliceDataPartMode(VideoEncData *video)
21242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong{
21342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    PV_STATUS status = PV_SUCCESS;
21442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Vol *currVol = video->vol[video->currLayer];
21542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Vop *currVop = video->currVop;
21642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    UChar mode, *Mode = video->headerInfo.Mode;
21742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    VideoEncParams *encParams = video->encParams;
21842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int nTotalMB = currVol->nTotalMB;
21942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int width = currVop->width; /* has to be Vop, for multiple of 16 */
22042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int lx = currVop->pitch; /* , with pading */
22142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    UChar *QPMB = video->QPMB;
22242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int QP;
22342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int ind_x = video->outputMB->mb_x, ind_y = video->outputMB->mb_y;
22442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int offset = video->offset;                 /* get current MB location */
22542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int mbnum = video->mbnum, slice_counter = video->sliceNo[mbnum]; /* get current MB location */
22642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int firstMB = mbnum;
22742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int start_packet_header = (mbnum != 0);
22842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int num_bits = 0;
22942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int packet_size = encParams->ResyncPacketsize - 1 - (currVop->predictionType == I_VOP ? 19 : 17);
23042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    BitstreamEncVideo *bs1 = video->bitstream1;
23142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    BitstreamEncVideo *bs2 = video->bitstream2;
23242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    BitstreamEncVideo *bs3 = video->bitstream3;
23342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int bitCount1 = 0, bitCount2 = 0, bitCount3 = 0, byteCount1 = 0, byteCount2 = 0, byteCount3 = 0;
23442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int numHeaderBits = 0;
23542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    approxDCT fastDCTfunction;
23642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int ncoefblck[6] = {64, 64, 64, 64, 64, 64}; /* for FastCodeMB,  5/18/2001 */
23742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    UChar CBP;
23842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Short outputMB[6][64];
23942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    PV_STATUS(*CodeMB)(VideoEncData *, approxDCT *, Int, Int[]);
24042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    void (*MBVlcEncode)(VideoEncData*, Int[], void *);
24142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    void (*BlockCodeCoeff)(RunLevelBlock*, BitstreamEncVideo*, Int, Int, UChar);
24242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int k;
24342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
24442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    video->QP_prev = 31;
24542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
24642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (video->end_of_buf) /* left-over from previous run */
24742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
24842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        status = BitstreamAppendPacketNoOffset(currVol->stream, bs1);
24942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        if (status != PV_END_OF_BUF)
25042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
25142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            BitstreamEncReset(bs1);
25242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            video->end_of_buf = 0;
25342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        }
25442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        return status;
25542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
25642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
25742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (mbnum == 0) /* only do this at the start of a frame */
25842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
25942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        QPMB[0] = video->QP_prev = QP = currVop->quantizer;
26042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        video->usePrevQP = 0;
26142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
26242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        numHeaderBits = BitstreamGetPos(bs1); /* Number of bits in VOP Header */
26342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
26442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
26542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
26642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
26742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /* Re-assign fast functions on every slice, don't have to put it in the memory */
26842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    QP = QPMB[mbnum];
26942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (mbnum > 0)   video->QP_prev = QPMB[mbnum-1];
27042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
27142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /* determine type of quantization   */
27242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifndef NO_MPEG_QUANT
27342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (currVol->quantType == 0)
27442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        CodeMB = &CodeMB_H263;
27542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    else
27642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        CodeMB = &CodeMB_MPEG;
27742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#else
27842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    CodeMB = &CodeMB_H263;
27942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
28042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
28142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /* determine which functions to be used, in MB-level */
28242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (currVop->predictionType == P_VOP)
28342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        MBVlcEncode = &MBVlcEncodeDataPar_P_VOP;
28442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    else if (currVop->predictionType == I_VOP)
28542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        MBVlcEncode = &MBVlcEncodeDataPar_I_VOP;
28642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    else /* B_VOP not implemented yet */
28742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        return PV_FAIL;
28842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
28942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /* determine which VLC table to be used */
29042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifndef NO_RVLC
29142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (currVol->useReverseVLC)
29242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        BlockCodeCoeff = &BlockCodeCoeff_RVLC;
29342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    else
29442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
29542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        BlockCodeCoeff = &BlockCodeCoeff_Normal;
29642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
29742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (mbnum != 0)
29842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
29942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        goto JUMP_IN;
30042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
30142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
30242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    for (ind_y = 0; ind_y < currVol->nMBPerCol; ind_y++)    /* Col MB Loop */
30342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
30442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
30542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        video->outputMB->mb_y = ind_y; /*  5/28/01 */
30642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
30742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        for (ind_x = 0; ind_x < currVol->nMBPerRow; ind_x++)  /* Row MB Loop */
30842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
30942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
31042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            video->outputMB->mb_x = ind_x; /*  5/28/01 */
31142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            video->mbnum = mbnum;
31242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            video->sliceNo[mbnum] = slice_counter;      /* Update MB slice number */
31342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
31442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /****************************************************************************************/
31542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /* MB Prediction:Put into MC macroblock, substract from currVop, put in predMB */
31642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /****************************************************************************************/
31742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            getMotionCompensatedMB(video, ind_x, ind_y, offset);
31842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
31942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames DongJUMP_IN:
32042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
32142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            QP = QPMB[mbnum];   /* always read new QP */
32242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
32342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (start_packet_header)
32442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
32542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                slice_counter++;                        /* Increment slice counter */
32642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                video->sliceNo[mbnum] = slice_counter;  /* Update MB slice number*/
32742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                video->QP_prev = currVop->quantizer;                        /* store QP */
32842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                num_bits = BitstreamGetPos(bs1);
32942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                status = EncodeVideoPacketHeader(video, mbnum, video->QP_prev, 0);
33042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                numHeaderBits = BitstreamGetPos(bs1) - num_bits;
33142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                video->header_bits += numHeaderBits; /* Header Bits */
33242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                start_packet_header = 0;
33342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                video->usePrevQP = 0;
33442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
33542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            else  /* don't encode the first MB in packet again */
33642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
33742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                /***********************************************/
33842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                /* Code_MB:  DCT, Q, Q^(-1), IDCT, Motion Comp */
33942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                /***********************************************/
34042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
34142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                status = (*CodeMB)(video, &fastDCTfunction, (offset << 5) + QP, ncoefblck);
34242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                for (k = 0; k < 6; k++)
34342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                {
34442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    M4VENC_MEMCPY(outputMB[k], video->outputMB->block[k], sizeof(Short) << 6);
34542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                }
34642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
34742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
34842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /************************************/
34942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /* MB VLC Encode: VLC Encode MB     */
35042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /************************************/
35142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
35242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /* save the state before VLC encoding */
35342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            bitCount1 = BitstreamGetPos(bs1);
35442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            bitCount2 = BitstreamGetPos(bs2);
35542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            bitCount3 = BitstreamGetPos(bs3);
35642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            byteCount1 = bitCount1 >> 3;
35742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            byteCount2 = bitCount2 >> 3;
35842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            byteCount3 = bitCount3 >> 3;
35942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            bitCount1 &= 0x7;
36042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            bitCount2 &= 0x7;
36142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            bitCount3 &= 0x7;
36242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            mode = Mode[mbnum];
36342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            CBP = video->headerInfo.CBP[mbnum];
36442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
36542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /*************************************/
36642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
36742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            MBVlcEncode(video, ncoefblck, (void*)BlockCodeCoeff);
36842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
36942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /*************************************************************/
37042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /* Assemble Packets:  Assemble the MB VLC codes into Packets */
37142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /*************************************************************/
37242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
37342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            num_bits = BitstreamGetPos(bs1) + BitstreamGetPos(bs2) +
37442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                       BitstreamGetPos(bs3);// - numHeaderBits; //include header bits
37542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
37642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /* Assemble_Packet(video) */
37742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (num_bits > packet_size && mbnum != firstMB)  /* encoding at least one more MB*/
37842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
37942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
38042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                BitstreamRepos(bs1, byteCount1, bitCount1); /* rewind one MB */
38142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                BitstreamRepos(bs2, byteCount2, bitCount2); /* rewind one MB */
38242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                BitstreamRepos(bs3, byteCount3, bitCount3); /* rewind one MB */
38342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
38442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                if (video->currVop->predictionType == I_VOP)
38542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                {
38642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    BitstreamPutGT16Bits(bs1, 19, DC_MARKER);   /* Add dc_marker */
38742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    video->header_bits += 19;
38842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                }
38942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                else
39042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                {
39142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    BitstreamPutGT16Bits(bs1, 17, MOTION_MARKER_COMB); /*Add motion_marker*/
39242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    video->header_bits += 17;
39342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                }
39442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
39542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                status = BitstreamAppendEnc(bs1, bs2);  /* Combine with bs2 */
39642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                status = BitstreamAppendEnc(bs1, bs3);  /* Combine with bs3 */
39742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
39842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                video->header_bits += BitstreamMpeg4ByteAlignStuffing(bs1); /* Byte align Packet */
39942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                status = BitstreamAppendPacketNoOffset(currVol->stream, bs1);
40042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
40142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                BitstreamEncReset(bs2);
40242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                BitstreamEncReset(bs3);
40342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
40442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                if (status == PV_END_OF_BUF) /* if cannot fit a buffer */
40542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                {
40642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    video->end_of_buf = 1;
40742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                }
40842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                else
40942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                {
41042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    BitstreamEncReset(bs1);
41142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                }
41242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
41342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                start_packet_header = 1;
41442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
41542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                if (mbnum < nTotalMB || video->end_of_buf) /* return here */
41642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                {
41742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    video->mbnum = mbnum;
41842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    video->sliceNo[mbnum] = slice_counter;
41942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    video->offset = offset;
42042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    Mode[mbnum] = mode;
42142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    video->headerInfo.CBP[mbnum] = CBP;
42242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
42342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    for (k = 0; k < 6; k++)
42442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    {
42542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        M4VENC_MEMCPY(video->outputMB->block[k], outputMB[k], sizeof(Short) << 6);
42642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    }
42742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
42842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    return status;
42942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                }
43042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
43142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
43242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            offset += 16;
43342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            mbnum++; /* has to increment before SCD, to preserve Mode[mbnum] */
43442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        } /* End of For ind_x */
43542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
43642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        offset += (lx << 4) - width;
43742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
43842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    } /* End of For ind_y */
43942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
44042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (!start_packet_header)
44142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
44242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        if (video->currVop->predictionType == I_VOP)
44342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
44442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            BitstreamPutGT16Bits(bs1, 19, DC_MARKER);   /* Add dc_marker */
44542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            video->header_bits += 19;
44642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        }
44742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        else
44842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
44942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            BitstreamPutGT16Bits(bs1, 17, MOTION_MARKER_COMB); /*Add motion_marker*/
45042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            video->header_bits += 17;
45142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        }
45242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
45342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        status = BitstreamAppendEnc(bs1, bs2);  /* Combine with bs2 */
45442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        status = BitstreamAppendEnc(bs1, bs3);  /* Combine with bs3 */
45542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
45642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        video->header_bits += BitstreamMpeg4ByteAlignStuffing(bs1); /* Byte align Packet */
45742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        status = BitstreamAppendPacketNoOffset(currVol->stream, bs1);
45842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
45942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        BitstreamEncReset(bs2);
46042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        BitstreamEncReset(bs3);
46142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
46242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        if (status == PV_END_OF_BUF)
46342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
46442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            video->end_of_buf = 1;
46542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        }
46642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        else
46742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
46842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            BitstreamEncReset(bs1);
46942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        }
47042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
47142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
47242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    video->mbnum = mbnum;
47342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (mbnum < nTotalMB)
47442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        video->sliceNo[mbnum] = slice_counter;
47542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    video->offset = offset;
47642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
47742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    return status;
47842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong}
47942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif /* NO_SLICE_ENCODE */
48042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif /* H263_ONLY */
48142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
48242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
483