| /* ------------------------------------------------------------------ |
| * Copyright (C) 2008 PacketVideo |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either |
| * express or implied. |
| * See the License for the specific language governing permissions |
| * and limitations under the License. |
| * ------------------------------------------------------------------- |
| */ |
| #include "avcdec_bitstream.h" |
| |
| /* Swapping may not be needed anymore since we read one byte at a time and perform |
| EBSP to RBSP conversion in bitstream. */ |
| #ifdef LITTLE_ENDIAN |
| #if (WORD_SIZE==32) /* this can be replaced with assembly instructions */ |
| #define SWAP_BYTES(x) ((((x)&0xFF)<<24) | (((x)&0xFF00)<<8) | (((x)&0xFF0000)>>8) | (((x)&0xFF000000)>>24)) |
| #else /* for 16-bit */ |
| #define SWAP_BYTES(x) ((((x)&0xFF)<<8) | (((x)&0xFF00)>>8)) |
| #endif |
| #else |
| #define SWAP_BYTES(x) (x) |
| #endif |
| |
| |
| /* array for trailing bit pattern as function of number of bits */ |
| /* the first one is unused. */ |
| const static uint8 trailing_bits[9] = {0, 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80}; |
| |
| /* ======================================================================== */ |
| /* Function : BitstreamInit() */ |
| /* Date : 11/4/2003 */ |
| /* Purpose : Populate bitstream structure with bitstream buffer and size */ |
| /* it also initializes internal data */ |
| /* In/out : */ |
| /* Return : AVCDEC_SUCCESS if successed, AVCDEC_FAIL if failed. */ |
| /* Modified : */ |
| /* ======================================================================== */ |
| /* |--------|--------|----~~~~~-----|---------|---------|---------| |
| ^ ^read_pos ^data_end_pos |
| bitstreamBuffer <---------> |
| current_word |
| |
| |xxxxxxxxxxxxx----| = current_word 32 or 16 bits |
| <------------> |
| bit_left |
| ======================================================================== */ |
| |
| |
| /* ======================================================================== */ |
| /* Function : BitstreamNextWord() */ |
| /* Date : 12/4/2003 */ |
| /* Purpose : Read up to machine word. */ |
| /* In/out : */ |
| /* Return : Next word with emulation prevention code removed. Everything |
| in the bitstream structure got modified except current_word */ |
| /* Modified : */ |
| /* ======================================================================== */ |
| |
| AVCDec_Status BitstreamInit(AVCDecBitstream *stream, uint8 *buffer, int size) |
| { |
| EBSPtoRBSP(buffer, &size); |
| |
| stream->incnt = 0; |
| stream->incnt_next = 0; |
| stream->bitcnt = 0; |
| stream->curr_word = stream->next_word = 0; |
| stream->read_pos = 0; |
| |
| stream->bitstreamBuffer = buffer; |
| |
| stream->data_end_pos = size; |
| |
| stream->nal_size = size; |
| |
| return AVCDEC_SUCCESS; |
| } |
| /* ======================================================================== */ |
| /* Function : AVC_BitstreamFillCache() */ |
| /* Date : 1/1/2005 */ |
| /* Purpose : Read up to machine word. */ |
| /* In/out : */ |
| /* Return : Read in 4 bytes of input data */ |
| /* Modified : */ |
| /* ======================================================================== */ |
| |
| AVCDec_Status AVC_BitstreamFillCache(AVCDecBitstream *stream) |
| { |
| uint8 *bitstreamBuffer = stream->bitstreamBuffer; |
| uint8 *v; |
| int num_bits, i; |
| |
| stream->curr_word |= (stream->next_word >> stream->incnt); // stream->incnt cannot be 32 |
| stream->next_word <<= (31 - stream->incnt); |
| stream->next_word <<= 1; |
| num_bits = stream->incnt_next + stream->incnt; |
| if (num_bits >= 32) |
| { |
| stream->incnt_next -= (32 - stream->incnt); |
| stream->incnt = 32; |
| return AVCDEC_SUCCESS; |
| } |
| /* this check can be removed if there is additional extra 4 bytes at the end of the bitstream */ |
| v = bitstreamBuffer + stream->read_pos; |
| |
| if (stream->read_pos > stream->data_end_pos - 4) |
| { |
| if (stream->data_end_pos <= stream->read_pos) |
| { |
| stream->incnt = num_bits; |
| stream->incnt_next = 0; |
| return AVCDEC_SUCCESS; |
| } |
| |
| stream->next_word = 0; |
| |
| for (i = 0; i < stream->data_end_pos - stream->read_pos;i++) |
| { |
| stream->next_word |= (v[i] << ((3 - i) << 3)); |
| } |
| |
| stream->read_pos = stream->data_end_pos; |
| stream->curr_word |= (stream->next_word >> num_bits); // this is safe |
| |
| stream->next_word <<= (31 - num_bits); |
| stream->next_word <<= 1; |
| num_bits = i << 3; |
| stream->incnt += stream->incnt_next; |
| stream->incnt_next = num_bits - (32 - stream->incnt); |
| if (stream->incnt_next < 0) |
| { |
| stream->incnt += num_bits; |
| stream->incnt_next = 0; |
| } |
| else |
| { |
| stream->incnt = 32; |
| } |
| return AVCDEC_SUCCESS; |
| } |
| |
| stream->next_word = ((uint32)v[0] << 24) | (v[1] << 16) | (v[2] << 8) | v[3]; |
| stream->read_pos += 4; |
| |
| stream->curr_word |= (stream->next_word >> num_bits); // this is safe |
| stream->next_word <<= (31 - num_bits); |
| stream->next_word <<= 1; |
| stream->incnt_next += stream->incnt; |
| stream->incnt = 32; |
| return AVCDEC_SUCCESS; |
| |
| } |
| /* ======================================================================== */ |
| /* Function : BitstreamReadBits() */ |
| /* Date : 11/4/2003 */ |
| /* Purpose : Read up to machine word. */ |
| /* In/out : */ |
| /* Return : AVCDEC_SUCCESS if successed, AVCDEC_FAIL if number of bits */ |
| /* is greater than the word-size, AVCDEC_PACKET_LOSS or */ |
| /* AVCDEC_NO_DATA if callback to get data fails. */ |
| /* Modified : */ |
| /* ======================================================================== */ |
| AVCDec_Status BitstreamReadBits(AVCDecBitstream *stream, int nBits, uint *code) |
| { |
| if (stream->incnt < nBits) |
| { |
| /* frame-based decoding */ |
| AVC_BitstreamFillCache(stream); |
| } |
| *code = stream->curr_word >> (32 - nBits); |
| BitstreamFlushBits(stream, nBits); |
| return AVCDEC_SUCCESS; |
| } |
| |
| |
| |
| /* ======================================================================== */ |
| /* Function : BitstreamShowBits() */ |
| /* Date : 11/4/2003 */ |
| /* Purpose : Show up to machine word without advancing the pointer. */ |
| /* In/out : */ |
| /* Return : AVCDEC_SUCCESS if successed, AVCDEC_FAIL if number of bits */ |
| /* is greater than the word-size, AVCDEC_NO_DATA if it needs */ |
| /* to callback to get data. */ |
| /* Modified : */ |
| /* ======================================================================== */ |
| AVCDec_Status BitstreamShowBits(AVCDecBitstream *stream, int nBits, uint *code) |
| { |
| if (stream->incnt < nBits) |
| { |
| /* frame-based decoding */ |
| AVC_BitstreamFillCache(stream); |
| } |
| |
| *code = stream->curr_word >> (32 - nBits); |
| |
| return AVCDEC_SUCCESS; |
| } |
| |
| /* ======================================================================== */ |
| /* Function : BitstreamRead1Bit() */ |
| /* Date : 11/4/2003 */ |
| /* Purpose : Read 1 bit from the bitstream. */ |
| /* In/out : */ |
| /* Return : AVCDEC_SUCCESS if successed, AVCDEC_FAIL if number of bits */ |
| /* is greater than the word-size, AVCDEC_PACKET_LOSS or */ |
| /* AVCDEC_NO_DATA if callback to get data fails. */ |
| /* Modified : */ |
| /* ======================================================================== */ |
| |
| AVCDec_Status BitstreamRead1Bit(AVCDecBitstream *stream, uint *code) |
| { |
| if (stream->incnt < 1) |
| { |
| /* frame-based decoding */ |
| AVC_BitstreamFillCache(stream); |
| } |
| *code = stream->curr_word >> 31; |
| BitstreamFlushBits(stream, 1); |
| return AVCDEC_SUCCESS; |
| } |
| |
| |
| |
| AVCDec_Status BitstreamByteAlign(AVCDecBitstream *stream) |
| { |
| uint n_stuffed; |
| |
| n_stuffed = (8 - (stream->bitcnt & 0x7)) & 0x7; /* 07/05/01 */ |
| |
| stream->bitcnt += n_stuffed; |
| stream->incnt -= n_stuffed; |
| |
| if (stream->incnt < 0) |
| { |
| stream->bitcnt += stream->incnt; |
| stream->incnt = 0; |
| } |
| stream->curr_word <<= n_stuffed; |
| return AVCDEC_SUCCESS; |
| } |
| |
| /* check whether there are more RBSP data. */ |
| /* ignore the emulation prevention code, assume it has been taken out. */ |
| bool more_rbsp_data(AVCDecBitstream *stream) |
| { |
| int total_bit_left; |
| uint code; |
| |
| if (stream->read_pos >= stream->nal_size) |
| { |
| total_bit_left = stream->incnt_next + stream->incnt; |
| if (total_bit_left <= 0) |
| { |
| return FALSE; |
| } |
| else if (total_bit_left <= 8) |
| { |
| BitstreamShowBits(stream, total_bit_left, &code); |
| if (code == trailing_bits[total_bit_left]) |
| { |
| return FALSE; |
| } |
| } |
| } |
| |
| return TRUE; |
| } |
| |