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