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/* Date: 8/02/04 */ 1959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Description: */ 2059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Change the bitstream parsing algorithm. Use temporary word of 2 or 4 bytes */ 2159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* before writing it to the bitstream buffer. */ 2259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Note byteCount doesn't have to be multiple of 2 or 4 */ 2359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*********************************************************************************/ 2459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 2559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "bitstream_io.h" 2659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "m4venc_oscl.h" 2759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include <stdlib.h> 2859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 2959f566c4ec3dfc097ad8163523e522280b27e5c3James Dongstatic const UChar Mask[ ] = 3059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 3159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF 3259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}; 3359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 3459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#define WORD_SIZE 4 /* for 32-bit machine */ 3559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 3659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*Note: 3759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 1. There is a problem when output the last bits(which can not form a byte yet 3859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong so when you output, you need to stuff to make sure it is a byte 3959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 2. I now hard coded byte to be 8 bits*/ 4059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 4159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 4259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 4359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : BitStreamCreateEnc(Int bufferSize ) */ 4459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 08/29/2000 */ 4559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : Create a bitstream to hold one encoded video packet or frame */ 4659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : */ 4759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* bufferSize : size of the bitstream buffer in bytes */ 4859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : Pointer to the BitstreamEncVideo */ 4959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 5059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 5159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 5259f566c4ec3dfc097ad8163523e522280b27e5c3James DongBitstreamEncVideo *BitStreamCreateEnc(Int bufferSize) 5359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 5459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BitstreamEncVideo *stream; 5559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream = (BitstreamEncVideo *) M4VENC_MALLOC(sizeof(BitstreamEncVideo)); 5659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (stream == NULL) 5759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 5859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return NULL; 5959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 6059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->bufferSize = bufferSize; 6159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->bitstreamBuffer = (UChar *) M4VENC_MALLOC(stream->bufferSize * sizeof(UChar)); 6259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (stream->bitstreamBuffer == NULL) 6359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 6459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong M4VENC_FREE(stream); 6559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream = NULL; 6659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return NULL; 6759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 6859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong M4VENC_MEMSET(stream->bitstreamBuffer, 0, stream->bufferSize*sizeof(UChar)); 6959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->word = 0; 7059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#if WORD_SIZE==4 7159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->bitLeft = 32; 7259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#else 7359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->bitLeft = 16; 7459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif 7559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->byteCount = 0; 7659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 7759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->overrunBuffer = NULL; 7859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->oBSize = 0; 7959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 8059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return stream; 8159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 8259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 8359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 8459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : BitstreamCloseEnc( ) */ 8559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 08/29/2000 */ 8659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : close a bitstream */ 8759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : 8859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream : the bitstream to be closed */ 8959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : */ 9059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 9159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 9259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 9359f566c4ec3dfc097ad8163523e522280b27e5c3James DongVoid BitstreamCloseEnc(BitstreamEncVideo *stream) 9459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 9559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (stream) 9659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 9759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (stream->bitstreamBuffer) 9859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 9959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong M4VENC_FREE(stream->bitstreamBuffer); 10059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 10159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 10259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong M4VENC_FREE(stream); 10359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 10459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 10559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 10659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 10759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 10859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : BitstreamPutBits(BitstreamEncVideo *stream, Int Length, 10959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int Value) */ 11059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 08/29/2000 */ 11159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : put Length (1-16) number of bits to the stream */ 11259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* for 32-bit machine this function can do upto 32 bit input */ 11359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : */ 11459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* stream the bitstream where the bits are put in */ 11559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Length bits length (should belong to 1 to 16) */ 11659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Value those bits value */ 11759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : PV_STATUS */ 11859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 11959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 12059f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS BitstreamPutBits(BitstreamEncVideo *stream, Int Length, UInt Value) 12159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 12259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong PV_STATUS status; 12359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 12459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (stream->bitLeft > Length) 12559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 12659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->word <<= Length; 12759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->word |= Value; /* assuming Value is not larger than Length */ 12859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->bitLeft -= Length; 12959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_SUCCESS; 13059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 13159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 13259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 13359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 13459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->word <<= stream->bitLeft; 13559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Length -= stream->bitLeft; 13659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->word |= ((UInt)Value >> Length); 13759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 13859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong status = BitstreamSaveWord(stream); 13959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (status != PV_SUCCESS) 14059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 14159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return status; 14259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 14359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 14459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* we got new Length and Value */ 14559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* note that Value is not "clean" because of msb are not masked out */ 14659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->word = Value; 14759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->bitLeft -= Length; 14859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* assuming that Length is no more than 16 bits */ 14959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* stream->bitLeft should be greater than zero at this point */ 15059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong //if(stream->bitLeft<=0) 15159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong // exit(-1); 15259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_SUCCESS; 15359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 15459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 15559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 15659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 15759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : BitstreamPutGT16Bits(BitstreamEncVideo *stream, Int Length, UInt32 Value) */ 15859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 08/29/2000 */ 15959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : Use this function to put Length (17-32) number of bits to */ 16059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* for 16-bit machine the stream. */ 16159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : */ 16259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* stream the bitstream where the bits are put in */ 16359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Length bits length (should belong to 17 to 32) */ 16459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Value those bits value */ 16559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : PV_STATUS */ 16659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 16759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 16859f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS BitstreamPutGT16Bits(BitstreamEncVideo *stream, Int Length, ULong Value) 16959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 17059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong PV_STATUS status; 17159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UInt topValue; 17259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int topLength; 17359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 17459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong topValue = (Value >> 16); 17559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong topLength = Length - 16; 17659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 17759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (topLength > 0) 17859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 17959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong status = BitstreamPutBits(stream, topLength, topValue); 18059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 18159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (status != PV_SUCCESS) 18259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 18359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return status; 18459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 18559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 18659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong status = BitstreamPutBits(stream, 16, (UInt)(Value & 0xFFFF)); 18759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 18859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return status; 18959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 19059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 19159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 19259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong status = BitstreamPutBits(stream, Length, (UInt)Value); 19359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return status; 19459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 19559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 19659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 19759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 19859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : BitstreamSaveWord */ 19959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 08/03/2004 */ 20059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : save written word into the bitstream buffer. */ 20159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : */ 20259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* stream the bitstream where the bits are put in */ 20359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : PV_STATUS */ 20459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 20559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 20659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 20759f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS BitstreamSaveWord(BitstreamEncVideo *stream) 20859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 20959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UChar *ptr; 21059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UInt word; 21159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 21259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* assume that stream->bitLeft is always zero when this function is called */ 21359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (stream->byteCount + WORD_SIZE > stream->bufferSize) 21459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 21559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (PV_SUCCESS != BitstreamUseOverrunBuffer(stream, WORD_SIZE)) 21659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 21759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->byteCount += WORD_SIZE; 21859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_FAIL; 21959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 22059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 22159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 22259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ptr = stream->bitstreamBuffer + stream->byteCount; 22359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong word = stream->word; 22459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->word = 0; /* important to reset to zero */ 22559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 22659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* NOTE: byteCount does not have to be multiple of 2 or 4 */ 22759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#if (WORD_SIZE == 4) 22859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong *ptr++ = word >> 24; 22959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong *ptr++ = 0xFF & (word >> 16); 23059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif 23159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 23259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong *ptr++ = 0xFF & (word >> 8); 23359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong *ptr = 0xFF & word; 23459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 23559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#if (WORD_SIZE == 4) 23659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->byteCount += 4; 23759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->bitLeft = 32; 23859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#else 23959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->byteCount += 2; 24059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->bitLeft = 16; 24159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif 24259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 24359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_SUCCESS; 24459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 24559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 24659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 24759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 24859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : BitstreamSavePartial */ 24959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 08/03/2004 */ 25059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : save unfinished written word into the bitstream buffer. */ 25159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : */ 25259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* stream the bitstream where the bits are put in */ 25359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : PV_STATUS */ 25459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 25559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 25659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 25759f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS BitstreamSavePartial(BitstreamEncVideo *stream, Int *fraction) 25859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 25959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UChar *ptr; 26059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UInt word, shift; 26159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int numbyte, bitleft, bitused; 26259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 26359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitleft = stream->bitLeft; 26459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitused = (WORD_SIZE << 3) - bitleft; /* number of bits used */ 26559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong numbyte = bitused >> 3; /* number of byte fully used */ 26659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 26759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (stream->byteCount + numbyte > stream->bufferSize) 26859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 26959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (PV_SUCCESS != BitstreamUseOverrunBuffer(stream, numbyte)) 27059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 27159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->byteCount += numbyte; 27259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_FAIL; 27359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 27459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 27559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 27659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ptr = stream->bitstreamBuffer + stream->byteCount; 27759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong word = stream->word; 27859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong word <<= bitleft; /* word is not all consumed */ 27959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitleft = bitused - (numbyte << 3); /* number of bits used (fraction) */ 28059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->byteCount += numbyte; 28159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (bitleft) 28259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 28359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong *fraction = 1; 28459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 28559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 28659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 28759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong *fraction = 0; 28859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 28959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitleft = (WORD_SIZE << 3) - bitleft; 29059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* save new value */ 29159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->bitLeft = bitleft; 29259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 29359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong shift = ((WORD_SIZE - 1) << 3); 29459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong while (numbyte) 29559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 29659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong *ptr++ = (UChar)((word >> shift) & 0xFF); 29759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong word <<= 8; 29859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong numbyte--; 29959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 30059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 30159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (*fraction) 30259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong {// this could lead to buffer overrun when ptr is already out of bound. 30359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong // *ptr = (UChar)((word>>shift)&0xFF); /* need to do it for the last fractional byte */ 30459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 30559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 30659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* save new values */ 30759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->word = word >> bitleft; 30859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 30959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* note we don't update byteCount, bitLeft and word */ 31059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* so that encoder can continue PutBits if they don't */ 31159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 31259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_SUCCESS; 31359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 31459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 31559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 31659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 31759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : BitstreamShortHeaderByteAlignStuffing( */ 31859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* BitstreamEncVideo *stream) */ 31959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 08/29/2000 */ 32059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : bit stuffing for next start code in short video header */ 32159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : */ 32259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : number of bits to be stuffed */ 32359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 32459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 32559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 32659f566c4ec3dfc097ad8163523e522280b27e5c3James DongInt BitstreamShortHeaderByteAlignStuffing(BitstreamEncVideo *stream) 32759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 32859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UInt restBits; 32959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int fraction; 33059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 33159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong restBits = (stream->bitLeft & 0x7); /* modulo 8 */ 33259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 33359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (restBits) /*short_video_header[0] is 1 in h263 baseline*/ 33459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 33559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* H.263 style stuffing */ 33659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BitstreamPutBits(stream, restBits, 0); 33759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 33859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 33959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (stream->bitLeft != (WORD_SIZE << 3)) 34059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 34159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BitstreamSavePartial(stream, &fraction); 34259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 34359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 34459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return restBits; 34559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 34659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 34759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 34859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : BitstreamMpeg4ByteAlignStuffing(BitstreamEncVideo *stream) */ 34959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 08/29/2000 */ 35059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : bit stuffing for next start code in MPEG-4 */ 35159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : */ 35259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : number of bits to be stuffed */ 35359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 35459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 35559f566c4ec3dfc097ad8163523e522280b27e5c3James DongInt BitstreamMpeg4ByteAlignStuffing(BitstreamEncVideo *stream) 35659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 35759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 35859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UInt restBits; 35959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int fraction; 36059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* Question: in MPEG-4 , short_video_header[0]==0 => even already byte aligned, will still stuff 8 bits 36159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong need to check with */ 36259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /*if (!(getPointerENC(index1, index2)%8) && short_video_header[0]) return 0;*/ 36359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 36459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* need stuffing bits, */ 36559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BitstreamPutBits(stream, 1, 0); 36659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 36759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong restBits = (stream->bitLeft & 0x7); /* modulo 8 */ 36859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 36959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (restBits) /*short_video_header[0] is 1 in h263 baseline*/ 37059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 37159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* need stuffing bits, */ 37259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BitstreamPutBits(stream, restBits, Mask[restBits]); 37359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 37459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 37559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (stream->bitLeft != (WORD_SIZE << 3)) 37659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 37759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BitstreamSavePartial(stream, &fraction); 37859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 37959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 38059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return (restBits); 38159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 38259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 38359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*does bit stuffing for next resync marker*/ 38459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* does bit stuffing for next resync marker 38559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * "0" 38659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * "01" 38759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * "011" 38859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * "0111" 38959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * "01111" 39059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * "011111" 39159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * "0111111" 39259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * "01111111" (8-bit codeword) 39359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong */ 39459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 39559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*Int BitstreamNextResyncMarkerEnc(BitstreamEncVideo *stream) 39659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 39759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int count; 39859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BitstreamPut1Bits(stream,0); 39959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong count=8-stream->totalBits & 8; 40059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BitstreamPutBits(stream,count,Mask[count]); 40159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return count; 40259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}*/ 40359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 40459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 40559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : BitstreamAppendEnc( BitstreamEncVideo *bitstream1, */ 40659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* BitstreamEncVideo *bitstream2 ) */ 40759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 08/29/2000 */ 40859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : Append the intermediate bitstream (bitstream2) to the end of */ 40959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* output bitstream(bitstream1) */ 41059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : */ 41159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : */ 41259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 41359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 41459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 41559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 41659f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS BitstreamAppendEnc(BitstreamEncVideo *bitstream1, BitstreamEncVideo *bitstream2) 41759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 41859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong PV_STATUS status; 41959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UChar *ptrBS2, *ptrBS1; 42059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UChar byteBS2, byteBS1; 42159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int numbyte2; 42259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int bitused, bitleft, offset, fraction; 42359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 42459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong status = BitstreamSavePartial(bitstream1, &fraction); 42559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (status != PV_SUCCESS) 42659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 42759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return status; 42859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 42959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 43059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong offset = fraction; 43159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong status = BitstreamSavePartial(bitstream2, &fraction); 43259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (status != PV_SUCCESS) 43359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 43459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return status; 43559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 43659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 43759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (!offset) /* bitstream1 is byte-aligned */ 43859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 43959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return BitstreamAppendPacket(bitstream1, bitstream2); 44059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 44159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 44259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong offset += fraction; 44359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 44459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* since bitstream1 doesn't have to be byte-aligned, we have to process byte by byte */ 44559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* we read one byte from bitstream2 and use BitstreamPutBits to do the job */ 44659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (bitstream1->byteCount + bitstream2->byteCount + offset > bitstream1->bufferSize) 44759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 44859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (PV_SUCCESS != BitstreamUseOverrunBuffer(bitstream1, bitstream2->byteCount + offset)) 44959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 45059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitstream1->byteCount += (bitstream2->byteCount + offset); 45159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_FAIL; 45259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 45359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 45459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 45559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ptrBS1 = bitstream1->bitstreamBuffer + bitstream1->byteCount; /* move ptr bs1*/ 45659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ptrBS2 = bitstream2->bitstreamBuffer; 45759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 45859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitused = (WORD_SIZE << 3) - bitstream1->bitLeft; /* this must be between 1-7 */ 45959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitleft = 8 - bitused; 46059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 46159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong numbyte2 = bitstream2->byteCount; /* number of byte to copy from bs2 */ 46259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitstream1->byteCount += numbyte2; /* new byteCount */ 46359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 46459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong byteBS1 = ((UChar) bitstream1->word) << bitleft; /* fraction byte from bs1 */ 46559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 46659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong while (numbyte2) 46759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 46859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong byteBS2 = *ptrBS2++; 46959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong byteBS1 |= (byteBS2 >> bitused); 47059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong *ptrBS1++ = byteBS1; 47159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong byteBS1 = byteBS2 << bitleft; 47259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong numbyte2--; 47359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 47459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 47559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitstream1->word = byteBS1 >> bitleft; /* bitstream->bitLeft remains the same */ 47659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 47759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* now save bs2->word in bs1 */ 47859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong status = BitstreamPutBits(bitstream1, (WORD_SIZE << 3) - bitstream2->bitLeft, bitstream2->word); 47959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 48059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return status; 48159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 48259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 48359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 48459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : BitstreamAppendPacket( BitstreamEncVideo *bitstream1, */ 48559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* BitstreamEncVideo *bitstream2 ) */ 48659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 05/31/2001 */ 48759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : Append the intermediate bitstream (bitstream2) to the end of */ 48859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* output bitstream(bitstream1) knowing that bitstream1 is byte-aligned*/ 48959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : */ 49059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : */ 49159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 49259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 49359f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS BitstreamAppendPacket(BitstreamEncVideo *bitstream1, BitstreamEncVideo *bitstream2) 49459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 49559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UChar *ptrBS2, *ptrBS1; 49659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int numbyte2; 49759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 49859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (bitstream1->byteCount + bitstream2->byteCount > bitstream1->bufferSize) 49959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 50059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (PV_SUCCESS != BitstreamUseOverrunBuffer(bitstream1, bitstream2->byteCount)) 50159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 50259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitstream1->byteCount += bitstream2->byteCount; /* legacy, to keep track of total bytes */ 50359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_FAIL; 50459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 50559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 50659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 50759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ptrBS1 = bitstream1->bitstreamBuffer + bitstream1->byteCount; /* move ptr bs1*/ 50859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ptrBS2 = bitstream2->bitstreamBuffer; 50959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 51059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong numbyte2 = bitstream2->byteCount; 51159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitstream1->byteCount += numbyte2; /* new byteCount */ 51259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 51359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /*copy all the bytes in bitstream2*/ 51459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong M4VENC_MEMCPY(ptrBS1, ptrBS2, sizeof(UChar)*numbyte2); 51559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 51659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitstream1->word = bitstream2->word; /* bitstream1->bitLeft is the same */ 51759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitstream1->bitLeft = bitstream2->bitLeft; 51859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 51959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_SUCCESS; 52059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 52159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 52259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 52359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : BitstreamAppendPacketNoOffset( BitstreamEncVideo *bitstream1,*/ 52459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* BitstreamEncVideo *bitstream2 ) */ 52559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 04/23/2002 */ 52659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : Append the intermediate bitstream (bitstream2) to the end of */ 52759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* output bitstream(bitstream1) , for slice-based coding only */ 52859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : */ 52959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : */ 53059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 53159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 53259f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS BitstreamAppendPacketNoOffset(BitstreamEncVideo *bitstream1, BitstreamEncVideo *bitstream2) 53359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 53459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong PV_STATUS status = PV_SUCCESS; 53559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UChar *ptrBS2, *ptrBS1; 53659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int numbyte2; 53759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int byteleft; 53859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 53959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong numbyte2 = bitstream2->byteCount; 54059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 54159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (bitstream1->byteCount + bitstream2->byteCount > bitstream1->bufferSize) 54259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 54359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong numbyte2 = bitstream1->bufferSize - bitstream1->byteCount; 54459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong status = PV_END_OF_BUF; /* signal end of buffer */ 54559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 54659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 54759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ptrBS1 = bitstream1->bitstreamBuffer; /* move ptr bs1*/ 54859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ptrBS2 = bitstream2->bitstreamBuffer; 54959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 55059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitstream1->byteCount += numbyte2; /* should be equal to bufferSize */ 55159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 55259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /*copy all the bytes in bitstream2*/ 55359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong M4VENC_MEMCPY(ptrBS1, ptrBS2, sizeof(UChar)*numbyte2); 55459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitstream1->word = 0; 55559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitstream1->bitLeft = (WORD_SIZE << 3); 55659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 55759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (status == PV_END_OF_BUF) /* re-position bitstream2 */ 55859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 55959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong byteleft = bitstream2->byteCount - numbyte2; 56059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 56159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong M4VENC_MEMCPY(ptrBS2, ptrBS2 + numbyte2, sizeof(UChar)*byteleft); 56259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 56359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitstream2->byteCount = byteleft; 56459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* bitstream2->word and bitstream->bitLeft are unchanged. 56559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong they should be 0 and (WORD_SIZE<<3) */ 56659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 56759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 56859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return status; 56959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 57059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 57159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef NO_SLICE_ENCODE 57259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 57359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : BitstreamRepos( BitstreamEncVideo *bitstream, */ 57459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Int byteCount, Int bitCount) */ 57559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 04/28/2002 */ 57659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : Reposition the size of the buffer content (curtail) */ 57759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : */ 57859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : */ 57959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 58059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 58159f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS BitstreamRepos(BitstreamEncVideo *bitstream, Int byteCount, Int bitCount) 58259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 58359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UChar *ptr, byte; 58459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UInt word; 58559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int fraction; 58659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 58759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BitstreamSavePartial(bitstream, &fraction); 58859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 58959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitstream->byteCount = byteCount; 59059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ptr = bitstream->bitstreamBuffer + byteCount; /* get fraction of the byte */ 59159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (bitCount) 59259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 59359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitstream->bitLeft = (WORD_SIZE << 3) - bitCount; /* bitCount should be 0-31 */ 59459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong word = *ptr++; 59559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong byte = *ptr++; 59659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong word = byte | (word << 8); 59759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#if (WORD_SIZE == 4) 59859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong byte = *ptr++; 59959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong word = byte | (word << 8); 60059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong byte = *ptr++; 60159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong word = byte | (word << 8); 60259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif 60359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitstream->word = word >> (bitstream->bitLeft); 60459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 60559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 60659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 60759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitstream->word = 0; 60859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitstream->bitLeft = (WORD_SIZE << 3); 60959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 61059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 61159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_SUCCESS; 61259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 61359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 61459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 61559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : BitstreamFlushBits(BitstreamEncVideo *bitstream1, */ 61659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Int num_bit_left) */ 61759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 04/24/2002 */ 61859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : Flush buffer except the last num_bit_left bits. */ 61959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : */ 62059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : */ 62159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 62259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 62359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 62459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 62559f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS BitstreamFlushBits(BitstreamEncVideo *bitstream1, Int num_bit_left) 62659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 62759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int i; 62859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UChar *ptrDst, *ptrSrc; 62959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int leftover, bitused; 63059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int new_byte = (num_bit_left >> 3); 63159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int new_bit = num_bit_left - (new_byte << 3); /* between 0-7 */ 63259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 63359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ptrSrc = bitstream1->bitstreamBuffer + bitstream1->byteCount; 63459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ptrDst = bitstream1->bitstreamBuffer; 63559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 63659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitused = (WORD_SIZE << 3) - bitstream1->bitLeft; 63759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 63859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong leftover = 8 - bitused; /* bitused should be between 0-7 */ 63959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 64059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitstream1->byteCount = new_byte; 64159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitstream1->bitLeft = (WORD_SIZE << 3) - new_bit; 64259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 64359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (!bitused) /* byte aligned */ 64459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 64559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong M4VENC_MEMCPY(ptrDst, ptrSrc, new_byte + 1); 64659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 64759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 64859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 64959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /*copy all the bytes in bitstream2*/ 65059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong for (i = 0; i < new_byte; i++) 65159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 65259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong *ptrDst++ = (ptrSrc[0] << bitused) | (ptrSrc[1] >> leftover); 65359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ptrSrc++; 65459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 65559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* copy for the last byte of ptrSrc, copy extra bits doesn't hurt */ 65659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (new_bit) 65759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 65859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong *ptrDst++ = (ptrSrc[0] << bitused) | (ptrSrc[1] >> leftover); 65959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ptrSrc++; 66059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 66159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 66259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (new_bit) 66359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 66459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ptrSrc = bitstream1->bitstreamBuffer + new_byte; 66559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitstream1->word = (*ptrSrc) >> (8 - new_bit); 66659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 66759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 66859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_SUCCESS; 66959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 67059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 67159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 67259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : BitstreamPrependPacket( BitstreamEncVideo *bitstream1, */ 67359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* BitstreamEncVideo *bitstream2 ) */ 67459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 04/26/2002 */ 67559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : Prepend the intermediate bitstream (bitstream2) to the beginning of */ 67659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* output bitstream(bitstream1) */ 67759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : */ 67859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : */ 67959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 68059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 68159f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS BitstreamPrependPacket(BitstreamEncVideo *bitstream1, BitstreamEncVideo *bitstream2) 68259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 68359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UChar *pSrc, *pDst, byte; 68459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int movebyte, bitused, leftover, i, fraction; 68559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 68659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BitstreamSavePartial(bitstream2, &fraction); /* make sure only fraction of byte left */ 68759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BitstreamSavePartial(bitstream1, &fraction); 68859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 68959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (bitstream1->byteCount + bitstream2->byteCount >= bitstream1->bufferSize) 69059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 69159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitstream1->byteCount += bitstream2->byteCount; 69259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_END_OF_BUF; 69359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 69459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 69559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong movebyte = bitstream1->byteCount; 69659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (movebyte < bitstream2->byteCount) 69759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong movebyte = bitstream2->byteCount; 69859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong movebyte++; 69959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 70059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* shift bitstream1 to the right by movebyte */ 70159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pSrc = bitstream1->bitstreamBuffer; 70259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pDst = pSrc + movebyte; 70359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 70459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong M4VENC_MEMCPY(pDst, pSrc, bitstream1->byteCount + 1); 70559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 70659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* copy bitstream2 to the beginning of bitstream1 */ 70759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong M4VENC_MEMCPY(pSrc, bitstream2->bitstreamBuffer, bitstream2->byteCount + 1); 70859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 70959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* now shift back previous bitstream1 buffer to the end */ 71059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pSrc = pDst; 71159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pDst = bitstream1->bitstreamBuffer + bitstream2->byteCount; 71259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 71359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitused = (WORD_SIZE << 3) - bitstream2->bitLeft; 71459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong leftover = 8 - bitused; /* bitused should be 0-7 */ 71559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 71659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong byte = (bitstream2->word) << leftover; 71759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 71859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong *pDst++ = byte | (pSrc[0] >> bitused); 71959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 72059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong for (i = 0; i < bitstream1->byteCount + 1; i++) 72159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 72259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong *pDst++ = ((pSrc[0] << leftover) | (pSrc[1] >> bitused)); 72359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pSrc++; 72459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 72559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 72659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitstream1->byteCount += bitstream2->byteCount; 72759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong //bitstream1->bitCount += bitstream2->bitCount; 72859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitused = (WORD_SIZE << 4) - (bitstream1->bitLeft + bitstream2->bitLeft); 72959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 73059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (bitused >= 8) 73159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 73259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitused -= 8; 73359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitstream1->byteCount++; 73459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 73559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 73659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitstream1->bitLeft = (WORD_SIZE << 3) - bitused; 73759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 73859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitstream2->byteCount = bitstream2->word = 0; 73959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitstream2->bitLeft = (WORD_SIZE << 3); 74059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 74159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pSrc = bitstream1->bitstreamBuffer + bitstream1->byteCount; 74259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong leftover = 8 - bitused; 74359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong //*pSrc = (pSrc[0]>>leftover)<<leftover; /* make sure the rest of bits are zeros */ 74459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 74559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitstream1->word = (UInt)((pSrc[0]) >> leftover); 74659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 74759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_SUCCESS; 74859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 74959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif /* NO_SLICE_ENCODE */ 75059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 75159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 75259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 75359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : BitstreamGetPos( BitstreamEncVideo *stream */ 75459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 08/05/2004 */ 75559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : Get the bit position. */ 75659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : */ 75759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : */ 75859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 75959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 76059f566c4ec3dfc097ad8163523e522280b27e5c3James DongInt BitstreamGetPos(BitstreamEncVideo *stream) 76159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 76259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 76359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return stream->byteCount*8 + (WORD_SIZE << 3) - stream->bitLeft; 76459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 76559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 76659f566c4ec3dfc097ad8163523e522280b27e5c3James Dongvoid BitstreamEncReset(BitstreamEncVideo *stream) 76759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 76859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->bitLeft = (WORD_SIZE << 3); 76959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->word = 0; 77059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->byteCount = 0; 77159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return ; 77259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 77359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 77459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* This function set the overrun buffer, and VideoEncData context for callback to reallocate 77559f566c4ec3dfc097ad8163523e522280b27e5c3James Dongoverrun buffer. */ 77659f566c4ec3dfc097ad8163523e522280b27e5c3James DongVoid BitstreamSetOverrunBuffer(BitstreamEncVideo* stream, UChar* overrunBuffer, Int oBSize, VideoEncData *video) 77759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 77859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->overrunBuffer = overrunBuffer; 77959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->oBSize = oBSize; 78059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->video = video; 78159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 78259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return ; 78359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 78459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 78559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 78659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* determine whether overrun buffer can be used or not */ 78759f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS BitstreamUseOverrunBuffer(BitstreamEncVideo* stream, Int numExtraBytes) 78859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 78959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong VideoEncData *video = stream->video; 79059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 79159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (stream->overrunBuffer != NULL) // overrunBuffer is set 79259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 79359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (stream->bitstreamBuffer != stream->overrunBuffer) // not already used 79459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 79559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (stream->byteCount + numExtraBytes >= stream->oBSize) 79659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 79759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->oBSize = stream->byteCount + numExtraBytes + 100; 79859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->oBSize &= (~0x3); // make it multiple of 4 79959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 80059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong // allocate new overrun Buffer 80159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (video->overrunBuffer) 80259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 80359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong M4VENC_FREE(video->overrunBuffer); 80459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 80559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong video->oBSize = stream->oBSize; 80659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong video->overrunBuffer = (UChar*) M4VENC_MALLOC(sizeof(UChar) * stream->oBSize); 80759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->overrunBuffer = video->overrunBuffer; 80859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (stream->overrunBuffer == NULL) 80959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 81059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_FAIL; 81159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 81259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 81359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 81459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong // copy everything to overrun buffer and start using it. 81559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong memcpy(stream->overrunBuffer, stream->bitstreamBuffer, stream->byteCount); 81659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->bitstreamBuffer = stream->overrunBuffer; 81759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->bufferSize = stream->oBSize; 81859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 81959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else // overrun buffer is already used 82059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 82159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (stream->byteCount + numExtraBytes >= stream->oBSize) 82259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 82359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->oBSize = stream->byteCount + numExtraBytes + 100; 82459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 82559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 82659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong // allocate new overrun buffer 82759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->oBSize &= (~0x3); // make it multiple of 4 82859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong video->oBSize = stream->oBSize; 82959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong video->overrunBuffer = (UChar*) M4VENC_MALLOC(sizeof(UChar) * stream->oBSize); 83059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (video->overrunBuffer == NULL) 83159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 83259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_FAIL; 83359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 83459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 83559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong // copy from the old buffer to new buffer 83659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong memcpy(video->overrunBuffer, stream->overrunBuffer, stream->byteCount); 83759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong // free old buffer 83859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong M4VENC_FREE(stream->overrunBuffer); 83959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong // assign pointer to new buffer 84059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->overrunBuffer = video->overrunBuffer; 84159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->bitstreamBuffer = stream->overrunBuffer; 84259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong stream->bufferSize = stream->oBSize; 84359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 84459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 84559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_SUCCESS; 84659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 84759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else // overrunBuffer is not enable. 84859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 84959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_FAIL; 85059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 85159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 85259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 85359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 85459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 85559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 85659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 85759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 85859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 85959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 860