PageRenderTime 27ms CodeModel.GetById 13ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/Avc/avc_bitstream.cpp

http://github.com/mbebenita/Broadway
C++ | 276 lines | 145 code | 39 blank | 92 comment | 15 complexity | 430cd17351d8cf78566def824824b68b MD5 | raw file
  1/* ------------------------------------------------------------------
  2 * Copyright (C) 1998-2009 PacketVideo
  3 *
  4 * Licensed under the Apache License, Version 2.0 (the "License");
  5 * you may not use this file except in compliance with the License.
  6 * You may obtain a copy of the License at
  7 *
  8 *      http://www.apache.org/licenses/LICENSE-2.0
  9 *
 10 * Unless required by applicable law or agreed to in writing, software
 11 * distributed under the License is distributed on an "AS IS" BASIS,
 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 13 * express or implied.
 14 * See the License for the specific language governing permissions
 15 * and limitations under the License.
 16 * -------------------------------------------------------------------
 17 */
 18#include "avcdec_bitstream.h"
 19
 20/* Swapping may not be needed anymore since we read one byte at a time and perform
 21EBSP to RBSP conversion in bitstream. */
 22#ifdef LITTLE_ENDIAN
 23#if (WORD_SIZE==32)  /* this can be replaced with assembly instructions */
 24#define SWAP_BYTES(x) ((((x)&0xFF)<<24) | (((x)&0xFF00)<<8) | (((x)&0xFF0000)>>8) | (((x)&0xFF000000)>>24))
 25#else  /* for 16-bit */
 26#define SWAP_BYTES(x) ((((x)&0xFF)<<8) | (((x)&0xFF00)>>8))
 27#endif
 28#else
 29#define SWAP_BYTES(x) (x)
 30#endif
 31
 32
 33/* array for trailing bit pattern as function of number of bits */
 34/* the first one is unused. */
 35const static uint8 trailing_bits[9] = {0, 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80};
 36
 37/* ======================================================================== */
 38/*  Function : BitstreamInit()                                              */
 39/*  Date     : 11/4/2003                                                    */
 40/*  Purpose  : Populate bitstream structure with bitstream buffer and size  */
 41/*             it also initializes internal data                            */
 42/*  In/out   :                                                              */
 43/*  Return   : AVCDEC_SUCCESS if successed, AVCDEC_FAIL if failed.              */
 44/*  Modified :                                                              */
 45/* ======================================================================== */
 46/* |--------|--------|----~~~~~-----|---------|---------|---------|
 47   ^                                          ^read_pos           ^data_end_pos
 48   bitstreamBuffer                  <--------->
 49                                    current_word
 50
 51   |xxxxxxxxxxxxx----|  = current_word 32 or 16 bits
 52    <------------>
 53     bit_left
 54 ======================================================================== */
 55
 56
 57/* ======================================================================== */
 58/*  Function : BitstreamNextWord()                                          */
 59/*  Date     : 12/4/2003                                                    */
 60/*  Purpose  : Read up to machine word.                                     */
 61/*  In/out   :                                                              */
 62/*  Return   : Next word with emulation prevention code removed. Everything
 63    in the bitstream structure got modified except current_word             */
 64/*  Modified :                                                              */
 65/* ======================================================================== */
 66
 67AVCDec_Status BitstreamInit(AVCDecBitstream *stream, uint8 *buffer, int size)
 68{
 69    EBSPtoRBSP(buffer, &size);
 70
 71    stream->incnt = 0;
 72    stream->incnt_next = 0;
 73    stream->bitcnt = 0;
 74    stream->curr_word = stream->next_word = 0;
 75    stream->read_pos = 0;
 76
 77    stream->bitstreamBuffer = buffer;
 78
 79    stream->data_end_pos = size;
 80
 81    stream->nal_size = size;
 82
 83    return AVCDEC_SUCCESS;
 84}
 85/* ======================================================================== */
 86/*  Function : AVC_BitstreamFillCache()                                         */
 87/*  Date     : 1/1/2005                                                     */
 88/*  Purpose  : Read up to machine word.                                     */
 89/*  In/out   :                                                              */
 90/*  Return   : Read in 4 bytes of input data                                */
 91/*  Modified :                                                              */
 92/* ======================================================================== */
 93
 94AVCDec_Status AVC_BitstreamFillCache(AVCDecBitstream *stream)
 95{
 96    uint8 *bitstreamBuffer = stream->bitstreamBuffer;
 97    uint8 *v;
 98    int num_bits, i;
 99
100    stream->curr_word |= (stream->next_word >> stream->incnt);   // stream->incnt cannot be 32
101    stream->next_word <<= (31 - stream->incnt);
102    stream->next_word <<= 1;
103    num_bits = stream->incnt_next + stream->incnt;
104    if (num_bits >= 32)
105    {
106        stream->incnt_next -= (32 - stream->incnt);
107        stream->incnt = 32;
108        return AVCDEC_SUCCESS;
109    }
110    /* this check can be removed if there is additional extra 4 bytes at the end of the bitstream */
111    v = bitstreamBuffer + stream->read_pos;
112
113    if (stream->read_pos > stream->data_end_pos - 4)
114    {
115        if (stream->data_end_pos <= stream->read_pos)
116        {
117            stream->incnt = num_bits;
118            stream->incnt_next = 0;
119            return AVCDEC_SUCCESS;
120        }
121
122        stream->next_word = 0;
123
124        for (i = 0; i < stream->data_end_pos - stream->read_pos; i++)
125        {
126            stream->next_word |= (v[i] << ((3 - i) << 3));
127        }
128
129        stream->read_pos = stream->data_end_pos;
130        stream->curr_word |= (stream->next_word >> num_bits); // this is safe
131
132        stream->next_word <<= (31 - num_bits);
133        stream->next_word <<= 1;
134        num_bits = i << 3;
135        stream->incnt += stream->incnt_next;
136        stream->incnt_next = num_bits - (32 - stream->incnt);
137        if (stream->incnt_next < 0)
138        {
139            stream->incnt +=  num_bits;
140            stream->incnt_next = 0;
141        }
142        else
143        {
144            stream->incnt = 32;
145        }
146        return AVCDEC_SUCCESS;
147    }
148
149    stream->next_word = ((uint32)v[0] << 24) | (v[1] << 16) | (v[2] << 8) | v[3];
150    stream->read_pos += 4;
151
152    stream->curr_word |= (stream->next_word >> num_bits); // this is safe
153    stream->next_word <<= (31 - num_bits);
154    stream->next_word <<= 1;
155    stream->incnt_next += stream->incnt;
156    stream->incnt = 32;
157    return AVCDEC_SUCCESS;
158
159}
160/* ======================================================================== */
161/*  Function : BitstreamReadBits()                                          */
162/*  Date     : 11/4/2003                                                    */
163/*  Purpose  : Read up to machine word.                                     */
164/*  In/out   :                                                              */
165/*  Return   : AVCDEC_SUCCESS if successed, AVCDEC_FAIL if number of bits   */
166/*              is greater than the word-size, AVCDEC_PACKET_LOSS or        */
167/*              AVCDEC_NO_DATA if callback to get data fails.               */
168/*  Modified :                                                              */
169/* ======================================================================== */
170AVCDec_Status BitstreamReadBits(AVCDecBitstream *stream, int nBits, uint *code)
171{
172    if (stream->incnt < nBits)
173    {
174        /* frame-based decoding */
175        AVC_BitstreamFillCache(stream);
176    }
177    *code = stream->curr_word >> (32 - nBits);
178    BitstreamFlushBits(stream, nBits);
179    return AVCDEC_SUCCESS;
180}
181
182
183
184/* ======================================================================== */
185/*  Function : BitstreamShowBits()                                          */
186/*  Date     : 11/4/2003                                                    */
187/*  Purpose  : Show up to machine word without advancing the pointer.       */
188/*  In/out   :                                                              */
189/*  Return   : AVCDEC_SUCCESS if successed, AVCDEC_FAIL if number of bits   */
190/*              is greater than the word-size, AVCDEC_NO_DATA if it needs   */
191/*              to callback to get data.                                    */
192/*  Modified :                                                              */
193/* ======================================================================== */
194AVCDec_Status BitstreamShowBits(AVCDecBitstream *stream, int nBits, uint *code)
195{
196    if (stream->incnt < nBits)
197    {
198        /* frame-based decoding */
199        AVC_BitstreamFillCache(stream);
200    }
201
202    *code = stream->curr_word >> (32 - nBits);
203
204    return AVCDEC_SUCCESS;
205}
206
207/* ======================================================================== */
208/*  Function : BitstreamRead1Bit()                                          */
209/*  Date     : 11/4/2003                                                    */
210/*  Purpose  : Read 1 bit from the bitstream.                               */
211/*  In/out   :                                                              */
212/*  Return   : AVCDEC_SUCCESS if successed, AVCDEC_FAIL if number of bits   */
213/*              is greater than the word-size, AVCDEC_PACKET_LOSS or        */
214/*              AVCDEC_NO_DATA if callback to get data fails.               */
215/*  Modified :                                                              */
216/* ======================================================================== */
217
218AVCDec_Status BitstreamRead1Bit(AVCDecBitstream *stream, uint *code)
219{
220    if (stream->incnt < 1)
221    {
222        /* frame-based decoding */
223        AVC_BitstreamFillCache(stream);
224    }
225    *code = stream->curr_word >> 31;
226    BitstreamFlushBits(stream, 1);
227    return AVCDEC_SUCCESS;
228}
229
230
231
232AVCDec_Status BitstreamByteAlign(AVCDecBitstream  *stream)
233{
234    uint n_stuffed;
235
236    n_stuffed = (8 - (stream->bitcnt & 0x7)) & 0x7; /*  07/05/01 */
237
238    stream->bitcnt += n_stuffed;
239    stream->incnt -= n_stuffed;
240
241    if (stream->incnt < 0)
242    {
243        stream->bitcnt += stream->incnt;
244        stream->incnt = 0;
245    }
246    stream->curr_word <<= n_stuffed;
247    return AVCDEC_SUCCESS;
248}
249
250/* check whether there are more RBSP data. */
251/* ignore the emulation prevention code, assume it has been taken out. */
252bool more_rbsp_data(AVCDecBitstream *stream)
253{
254    int total_bit_left;
255    uint code;
256
257    if (stream->read_pos >= stream->nal_size)
258    {
259        total_bit_left = stream->incnt_next + stream->incnt;
260        if (total_bit_left <= 0)
261        {
262            return FALSE;
263        }
264        else if (total_bit_left <= 8)
265        {
266            BitstreamShowBits(stream, total_bit_left, &code);
267            if (code == trailing_bits[total_bit_left])
268            {
269                return FALSE;
270            }
271        }
272    }
273
274    return TRUE;
275}
276