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