package com.twilight.h264.decoder; // This class is implemented using #ifdef ALT_BITSTREAM_READER and #ifdef ALT_BITSTREAM_READER_LE public class GetBitContext { public static final int MIN_CACHE_BITS = 25; public static final int INIT_VLC_LE = 2; public static final int INIT_VLC_USE_NEW_STATIC = 4; public static final int[] av_reverse ={ 0x000,0x080,0x040,0x0C0,0x020,0x0A0,0x060,0x0E0,0x010,0x090,0x050,0x0D0,0x030,0x0B0,0x070,0x0F0, 0x008,0x088,0x048,0x0C8,0x028,0x0A8,0x068,0x0E8,0x018,0x098,0x058,0x0D8,0x038,0x0B8,0x078,0x0F8, 0x004,0x084,0x044,0x0C4,0x024,0x0A4,0x064,0x0E4,0x014,0x094,0x054,0x0D4,0x034,0x0B4,0x074,0x0F4, 0x00C,0x08C,0x04C,0x0CC,0x02C,0x0AC,0x06C,0x0EC,0x01C,0x09C,0x05C,0x0DC,0x03C,0x0BC,0x07C,0x0FC, 0x002,0x082,0x042,0x0C2,0x022,0x0A2,0x062,0x0E2,0x012,0x092,0x052,0x0D2,0x032,0x0B2,0x072,0x0F2, 0x00A,0x08A,0x04A,0x0CA,0x02A,0x0AA,0x06A,0x0EA,0x01A,0x09A,0x05A,0x0DA,0x03A,0x0BA,0x07A,0x0FA, 0x006,0x086,0x046,0x0C6,0x026,0x0A6,0x066,0x0E6,0x016,0x096,0x056,0x0D6,0x036,0x0B6,0x076,0x0F6, 0x00E,0x08E,0x04E,0x0CE,0x02E,0x0AE,0x06E,0x0EE,0x01E,0x09E,0x05E,0x0DE,0x03E,0x0BE,0x07E,0x0FE, 0x001,0x081,0x041,0x0C1,0x021,0x0A1,0x061,0x0E1,0x011,0x091,0x051,0x0D1,0x031,0x0B1,0x071,0x0F1, 0x009,0x089,0x049,0x0C9,0x029,0x0A9,0x069,0x0E9,0x019,0x099,0x059,0x0D9,0x039,0x0B9,0x079,0x0F9, 0x005,0x085,0x045,0x0C5,0x025,0x0A5,0x065,0x0E5,0x015,0x095,0x055,0x0D5,0x035,0x0B5,0x075,0x0F5, 0x00D,0x08D,0x04D,0x0CD,0x02D,0x0AD,0x06D,0x0ED,0x01D,0x09D,0x05D,0x0DD,0x03D,0x0BD,0x07D,0x0FD, 0x003,0x083,0x043,0x0C3,0x023,0x0A3,0x063,0x0E3,0x013,0x093,0x053,0x0D3,0x033,0x0B3,0x073,0x0F3, 0x00B,0x08B,0x04B,0x0CB,0x02B,0x0AB,0x06B,0x0EB,0x01B,0x09B,0x05B,0x0DB,0x03B,0x0BB,0x07B,0x0FB, 0x007,0x087,0x047,0x0C7,0x027,0x0A7,0x067,0x0E7,0x017,0x097,0x057,0x0D7,0x037,0x0B7,0x077,0x0F7, 0x00F,0x08F,0x04F,0x0CF,0x02F,0x0AF,0x06F,0x0EF,0x01F,0x09F,0x05F,0x0DF,0x03F,0x0BF,0x07F,0x0FF, }; public static final int[] ff_golomb_vlc_len = { 19,17,15,15,13,13,13,13,11,11,11,11,11,11,11,11,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }; public static final int[] ff_ue_golomb_vlc_code = { 32,32,32,32,32,32,32,32,31,32,32,32,32,32,32,32,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,10,10,10,11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; public static final int[] ff_se_golomb_vlc_code = { 17, 17, 17, 17, 17, 17, 17, 17, 16, 17, 17, 17, 17, 17, 17, 17, 8, -8, 9, -9, 10,-10, 11,-11, 12,-12, 13,-13, 14,-14, 15,-15, 4, 4, 4, 4, -4, -4, -4, -4, 5, 5, 5, 5, -5, -5, -5, -5, 6, 6, 6, 6, -6, -6, -6, -6, 7, 7, 7, 7, -7, -7, -7, -7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; public static final int[] ff_ue_golomb_len = { 1, 3, 3, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,13, 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,15, 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,17, }; public int[] buffer; // const uint8_t *buffer, *buffer_end; public int buffer_offset; public int buffer_end; public int index; //public int buffer_ptr; public long cache; //public int bit_count; public long cache0; public long cache1; public int size_in_bits; public static final long bitswap_32(long x) { return av_reverse[(int)(x&0x0FF)]<<24 | av_reverse[(int)((x>>>8)&0x0FF)]<<16 | av_reverse[(int)((x>>>16)&0x0FF)]<<8 | av_reverse[(int)(x>>>24)]; } // Copy ctor?? public GetBitContext makeCopy() { GetBitContext ret = new GetBitContext(); ret.buffer = buffer; ret.buffer_offset = buffer_offset; ret.buffer_end = buffer_end; ret.index = index; //ret.buffer_ptr = buffer_ptr; ret.cache = cache; //ret.bit_count = bit_count; ret.cache0 = cache0; ret.cache1 = cache1; ret.size_in_bits = size_in_bits; return ret; } public /*inline*/ int get_bits_count(){ return this.index; } public /*inline*/ void skip_bits_long(int n){ this.index += n; } /** * read mpeg1 dc style vlc (sign bit + mantisse with no MSB). * if MSB not set it is negative * @param n length in bits * @author BERO */ public /*inline*/ int get_xbits(int n){ int sign; long cache; //OPEN_READER(re, s) int re_index= this.index; long re_cache= 0; //UPDATE_CACHE(re, s) //re_cache= AV_RL32( ((const uint8_t *)(gb)->buffer)+(name##_index>>3) ) >> (name##_index&0x07); int pos = buffer_offset + (re_index>>3); //re_cache = ((buffer[pos+3]<<24)|(buffer[pos+2]<<16)|(buffer[pos+1]<<8)|(buffer[pos])) >> (re_index&0x07); re_cache = buffer[pos+0]; re_cache = (re_cache << 8) | buffer[pos+1]; re_cache = (re_cache << 8) | buffer[pos+2]; re_cache = (re_cache << 8) | buffer[pos+3]; re_cache = (re_cache << (re_index & 0x07)); re_cache = re_cache & 0xffffffffl; // Prevent 32-Bit over flow. //cache = GET_CACHE(re,s); cache = (re_cache); //sign=(~cache)>>31; // we use long sign=(int)((~cache)>>63); //LAST_SKIP_BITS(re, s, n) re_index += (n); //CLOSE_READER(re, s) this.index= re_index; //return (NEG_USR32(sign ^ cache, n) ^ sign) - sign; //System.out.println("get_xbit: "+ (( (((int)(sign ^ cache))>>(32-(n))) ^ sign) - sign) ); return ( (((int)(sign ^ cache))>>(32-(n))) ^ sign) - sign; } public /*inline*/ int get_sbits(int n){ int tmp; //OPEN_READER(re, s) int re_index= this.index; long re_cache= 0; //UPDATE_CACHE(re, s) int pos = buffer_offset + (re_index>>3); //re_cache = ((buffer[pos+3]<<24)|(buffer[pos+2]<<16)|(buffer[pos+1]<<8)|(buffer[pos])) >> (re_index&0x07); re_cache = buffer[pos+0]; re_cache = (re_cache << 8) | buffer[pos+1]; re_cache = (re_cache << 8) | buffer[pos+2]; re_cache = (re_cache << 8) | buffer[pos+3]; re_cache = (re_cache << (re_index & 0x07)); re_cache = re_cache & 0xffffffffl; // Prevent 32-Bit over flow. //tmp= SHOW_SBITS(re, s, n); ////tmp = ((( int32_t)(re_cache))>>(32-(n))) tmp = ((( int)(re_cache))>>(32-(n))); //LAST_SKIP_BITS(re, s, n) re_index += (n); //CLOSE_READER(re, s) this.index= re_index; //System.out.println("get_sbits: "+ (tmp) ); return tmp; } /** * reads 1-17 bits. * Note, the alt bitstream reader can read up to 25 bits, but the libmpeg2 reader can't */ public /*inline*/ long get_bits(int n, String message){ long tmp; //OPEN_READER(re, s) int re_index= this.index; long re_cache= 0; //UPDATE_CACHE(re, s) int pos = buffer_offset + (re_index>>3); // DebugTool.printDebugString("--------- Reading 4 bytes from pos: "+pos+"\n"); //re_cache = ((buffer[pos+3]<<24)|(buffer[pos+2]<<16)|(buffer[pos+1]<<8)|(buffer[pos])) >> (re_index&0x07); re_cache = buffer[pos+0]; re_cache = (re_cache << 8) | buffer[pos+1]; re_cache = (re_cache << 8) | buffer[pos+2]; re_cache = (re_cache << 8) | buffer[pos+3]; re_cache = (re_cache << (re_index & 0x07)); re_cache = re_cache & 0xffffffffl; // Prevent 32-Bit over flow. //tmp= SHOW_UBITS(re, s, n); ////tmp = NEG_USR32(re_cache, n) tmp = (((re_cache))>>(32-(n))); //LAST_SKIP_BITS(re, s, n) re_index += (n); //CLOSE_READER(re, s) this.index= re_index; //System.out.println("get_bits(,"+n+","+message+"): "+ (tmp) ); return tmp; } /** * shows 1-17 bits. * Note, the alt bitstream reader can read up to 25 bits, but the libmpeg2 reader can't */ public /*inline*/ long show_bits(int n){ long tmp; //OPEN_READER(re, s) int re_index= this.index; long re_cache= 0; //UPDATE_CACHE(re, s) int pos = buffer_offset + (re_index>>3); //re_cache = ((buffer[pos+3]<<24)|(buffer[pos+2]<<16)|(buffer[pos+1]<<8)|(buffer[pos])) >> (re_index&0x07); re_cache = buffer[pos+0]; re_cache = (re_cache << 8) | buffer[pos+1]; re_cache = (re_cache << 8) | buffer[pos+2]; re_cache = (re_cache << 8) | buffer[pos+3]; re_cache = (re_cache << (re_index & 0x07)); re_cache = re_cache & 0xffffffffl; // Prevent 32-Bit over flow. //tmp= SHOW_UBITS(re, s, n); ////tmp = NEG_USR32(re_cache, n) tmp = (((re_cache))>>(32-(n))); return tmp; } public /*inline*/ void skip_bits(int n){ //Note gcc seems to optimize this to s->index+=n for the ALT_READER :)) //OPEN_READER(re, s) int re_index= this.index; long re_cache= 0; //UPDATE_CACHE(re, s) int pos = buffer_offset + (re_index>>3); //re_cache = ((buffer[pos+3]<<24)|(buffer[pos+2]<<16)|(buffer[pos+1]<<8)|(buffer[pos])) >> (re_index&0x07); re_cache = buffer[pos+0]; re_cache = (re_cache << 8) | buffer[pos+1]; re_cache = (re_cache << 8) | buffer[pos+2]; re_cache = (re_cache << 8) | buffer[pos+3]; re_cache = (re_cache << (re_index & 0x07)); re_cache = re_cache & 0xffffffffl; // Prevent 32-Bit over flow. //LAST_SKIP_BITS(re, s, n) re_index += (n); //CLOSE_READER(re, s) this.index= re_index; } public /*inline*/ long get_bits1(String message){ //#ifdef ALT_BITSTREAM_READER int index= this.index; int result= this.buffer[ this.buffer_offset + (index>>3) ]; //#ifdef ALT_BITSTREAM_READER_LE // result>>= (index&0x07); // result&= 1; //#else //result<<= (index&0x07); //result>>= (8 - 1); // we use int! result<<= ((index&0x07) + 24); result>>= (32 - 1); //#endif index++; this.index= index; //System.out.println("get_bits1("+message+"): "+ ((result!=0)?1:0) ); return (result!=0)?1:0; //#else // return get_bits(s, 1); //#endif } public /*inline*/ long show_bits1(){ return show_bits(1); } public /*inline*/ void skip_bits1(){ skip_bits(1); } /** * reads 0-32 bits. */ public /*inline*/ long get_bits_long(int n, String message){ if(n<=MIN_CACHE_BITS) return get_bits(n, message); else{ // #ifdef ALT_BITSTREAM_READER_LE // long ret= get_bits(16); // return ret | (get_bits(n-16) << 16); // #else long ret = get_bits(16, message) << (n-16); long ret2 = get_bits(n-16, message); ////System.out.println("get_bits_long(,"+n+","+message+"): "+ (ret | get_bits(n-16, message)) ); return (ret | ret2); // #endif } } /** * reads 0-32 bits as a signed integer. */ public /*inline*/ int get_sbits_long(int n, String message) { //return sign_extend(get_bits_long(n), n); return (((int)get_bits_long(n, message)) << ((8 * 4) - n)) >> ((8 * 4) - n); } /** * shows 0-32 bits. */ public /*inline*/ long show_bits_long(int n){ if(n<=MIN_CACHE_BITS) return show_bits(n); else{ GetBitContext gb= makeCopy(); return gb.get_bits_long(n, ""); } } public /*inline*/ long check_marker(String msg) { long bit= get_bits1(msg); if(bit == 0) System.err.println("Marker bit missing: " + msg); return bit; } /** * init GetBitContext. * @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes larger then the actual read bits * because some optimized bitstream readers read 32 or 64 bit at once and could read over the end * @param bit_size the size of the buffer in bits * * While GetBitContext stores the buffer size, for performance reasons you are * responsible for checking for the buffer end yourself (take advantage of the padding)! */ public /*inline*/ void init_get_bits( /*const uint8_t **/ int[] buffer, int buffer_offset, int bit_size) { int buffer_size= (bit_size+7)>>3; if(buffer_size < 0 || bit_size < 0) { buffer_size = bit_size = 0; buffer = null; } this.buffer= buffer; this.buffer_offset = buffer_offset; this.size_in_bits= bit_size; this.buffer_end= buffer_offset + buffer_size; //#ifdef ALT_BITSTREAM_READER this.index=0; //#elif defined LIBMPEG2_BITSTREAM_READER // s->buffer_ptr = (uint8_t*)((intptr_t)buffer&(~1)); // s->bit_count = 16 + 8*((intptr_t)buffer&1); // skip_bits_long(s, 0); //#elif defined A32_BITSTREAM_READER // s->buffer_ptr = (uint32_t*)((intptr_t)buffer&(~3)); // s->bit_count = 32 + 8*((intptr_t)buffer&3); // skip_bits_long(s, 0); //#endif } public /*inline*/ void align_get_bits() { int n= (-get_bits_count()) & 7; if(n != 0) skip_bits(n); } public /*inline*/ long decode012(){ long n; n = get_bits1(""); if (n == 0) return 0; else return get_bits1("") + 1; } public /*inline*/ long decode210(){ if (get_bits1("")!=0) return 0; else return 2 - get_bits1(""); } public /*inline*/ int get_bits_left() { return size_in_bits - get_bits_count(); } public static int alloc_table(VLC vlc, int size, int use_static) { int index; index = vlc.table_size; vlc.table_size += size; if (vlc.table_size > vlc.table_allocated) { if(use_static !=0 ) { //abort(); //cant do anything, init_vlc() is used with too little memory return 0; } vlc.table_allocated += (1 << vlc.bits); short[][/*2*/] newTab = new short[2 * vlc.table_allocated][2]; for(int i=0;i<vlc.table_base.length;i++) { newTab[i][0] = vlc.table_base[i][0]; newTab[i][1] = vlc.table_base[i][1]; } // for i vlc.table_base = newTab; //vlc.table = av_realloc(vlc->table, // sizeof(VLC_TYPE) * 2 * vlc->table_allocated); if (null == vlc.table_base) return -1; } return index; } /** * Build VLC decoding tables suitable for use with get_vlc(). * * @param vlc the context to be initted * * @param table_nb_bits max length of vlc codes to store directly in this table * (Longer codes are delegated to subtables.) * * @param nb_codes number of elements in codes[] * * @param codes descriptions of the vlc codes * These must be ordered such that codes going into the same subtable are contiguous. * Sorting by VLCcode.code is sufficient, though not necessary. */ public static int build_table(VLC vlc, int table_nb_bits, int nb_codes, VLCcode[] codes_base, int codes_offset, int flags) { int table_size, table_index, index, code_prefix, symbol, subtable_bits; int i, k, n, nb, inc; long j; //uint32_t code; long code; //VLC_TYPE (*table)[2]; short[][] table_base; int table_offset; table_size = 1 << table_nb_bits; table_index = alloc_table(vlc, table_size, flags & INIT_VLC_USE_NEW_STATIC); /* #ifdef DEBUG_VLC av_log(NULL,AV_LOG_DEBUG,"new table index=%d size=%d\n", table_index, table_size); #endif */ if (table_index < 0) return -1; table_base = vlc.table_base; table_offset = vlc.table_offset + table_index; for (i = 0; i < table_size; i++) { table_base[table_offset + i][1] = 0; //bits table_base[table_offset + i][0] = -1; //codes } /* first pass: map codes and compute auxillary table sizes */ for (i = 0; i < nb_codes; i++) { n = codes_base[codes_offset + i].bits; code = codes_base[codes_offset + i].code; symbol = codes_base[codes_offset + i].symbol; //System.out.println("i="+i+" n="+n+" code="+code); if (n <= table_nb_bits) { /* no need to add another table */ //!!! Prevent 32-Bit value in negative interval long tmp = code & 0xffffffffL; j = (int)(tmp >> (32 - table_nb_bits)); nb = 1 << (table_nb_bits - n); inc = 1; if ((flags & INIT_VLC_LE)!=0) { j = bitswap_32(code); inc = 1 << n; } for (k = 0; k < nb; k++) { //System.out.println("["+j+"]: code="+i+" n="+n); if (table_base[(int)(table_offset + j)][1] /*bits*/ != 0) { //System.out.println("incorrect codes."); return -1; } table_base[(int)(table_offset + j)][1] = (short)n; //bits table_base[(int)(table_offset + j)][0] = (short)symbol; j += inc; } } else { /* fill auxiliary table recursively */ n -= table_nb_bits; long tmp = code & 0xffffffffL; code_prefix = (int)(tmp >> (32 - table_nb_bits)); subtable_bits = n; codes_base[codes_offset + i].bits = n; codes_base[codes_offset + i].code = code << table_nb_bits; for (k = i+1; k < nb_codes; k++) { n = codes_base[codes_offset + k].bits - table_nb_bits; if (n <= 0) break; code = codes_base[codes_offset + k].code; if (code >> (32 - table_nb_bits) != code_prefix) break; codes_base[codes_offset + k].bits = n; codes_base[codes_offset + k].code = code << table_nb_bits; subtable_bits = Math.max(subtable_bits, n); } subtable_bits = Math.min(subtable_bits, table_nb_bits); j = ((flags & INIT_VLC_LE)!=0) ? (bitswap_32(code_prefix) >> (32 - table_nb_bits)) : code_prefix; table_base[(int)(table_offset + j)][1] = (short)-subtable_bits; //System.out.println("["+j+"]: n="+codes_base[codes_offset + i].bits + table_nb_bits+"(subtable)"); index = build_table(vlc, subtable_bits, k-i, codes_base, codes_offset+i, flags); if (index < 0) return -1; /* note: realloc has been done, so reload tables */ table_base = vlc.table_base; table_offset = vlc.table_offset + table_index; table_base[(int)(table_offset + j)][0] = (short)index; //code i = k-1; } } return table_index; } /** * parses a vlc code, faster then get_vlc() * @param bits is the number of bits which will be read at once, must be * identical to nb_bits in init_vlc() * @param max_depth is the number of times bits bits must be read to completely * read the longest vlc code * = (max_vlc_length + bits - 1) / bits */ public int get_vlc2(short[][/*2*/] table_base, int table_offset, int bits, int max_depth, String message) { int code; //OPEN_READER(re, s) int re_index= this.index; long re_cache= 0; //UPDATE_CACHE(re, s) int pos = buffer_offset + (re_index>>3); //re_cache = ((buffer[pos+3]<<24)|(buffer[pos+2]<<16)|(buffer[pos+1]<<8)|(buffer[pos])) >> (re_index&0x07); re_cache = buffer[pos+0]; re_cache = (re_cache << 8) | buffer[pos+1]; re_cache = (re_cache << 8) | buffer[pos+2]; re_cache = (re_cache << 8) | buffer[pos+3]; re_cache = (re_cache << (re_index & 0x07)); re_cache = re_cache & 0xffffffffl; // Prevent 32-Bit over flow. //GET_VLC(code, re, s, table, bits, max_depth) /** * * If the vlc code is invalid and max_depth=1, then no bits will be removed. * If the vlc code is invalid and max_depth>1, then the number of bits removed * is undefined. */ //#define GET_VLC(code, name, gb, table, bits, max_depth) { int n, nb_bits; /*unsigned*/ int index; //index= SHOW_UBITS(name, gb, bits); ////index = NEG_USR32(re_cache, bits) index = (int)((((re_cache))>>(32-(bits)))); code = table_base[table_offset + index][0]; n = table_base[table_offset + index][1]; //if(// DebugTool.logCount == 8635) { // DebugTool.printDebugString(" get_vlc2(LEVEL0)=> index="+index+", code="+code+", n="+n+", bits="+bits+"\n"); //} // if if(max_depth > 1 && n < 0){ //LAST_SKIP_BITS(name, gb, bits) re_index += (bits); //UPDATE_CACHE(name, gb) pos = buffer_offset + (re_index>>3); //re_cache = ((buffer[pos+3]<<24)|(buffer[pos+2]<<16)|(buffer[pos+1]<<8)|(buffer[pos])) >> (re_index&0x07); re_cache = buffer[pos+0]; re_cache = (re_cache << 8) | buffer[pos+1]; re_cache = (re_cache << 8) | buffer[pos+2]; re_cache = (re_cache << 8) | buffer[pos+3]; re_cache = (re_cache << (re_index & 0x07)); re_cache = re_cache & 0xffffffffl; // Prevent 32-Bit over flow. nb_bits = -n; //index= SHOW_UBITS(name, gb, nb_bits) + code; ////index = NEG_USR32(re_cache, nb_bits) + code index = (int)((((re_cache))>>(32-(nb_bits)))) + code; code = table_base[table_offset + index][0]; n = table_base[table_offset + index][1]; // if(// DebugTool.logCount == 8635) { // DebugTool.printDebugString(" get_vlc2(LEVEL1)=> index="+index+", code="+code+", n="+n+"\n"); // } // if if(max_depth > 2 && n < 0){ //LAST_SKIP_BITS(name, gb, nb_bits) re_index += (nb_bits); //UPDATE_CACHE(name, gb) pos = buffer_offset + (re_index>>3); //re_cache = ((buffer[pos+3]<<24)|(buffer[pos+2]<<16)|(buffer[pos+1]<<8)|(buffer[pos])) >> (re_index&0x07); re_cache = buffer[pos+0]; re_cache = (re_cache << 8) | buffer[pos+1]; re_cache = (re_cache << 8) | buffer[pos+2]; re_cache = (re_cache << 8) | buffer[pos+3]; re_cache = (re_cache << (re_index & 0x07)); re_cache = re_cache & 0xffffffffl; // Prevent 32-Bit over flow. nb_bits = -n; //index= SHOW_UBITS(name, gb, nb_bits) + code; ////index = NEG_USR32(re_cache, nb_bits) + code index = (int)((((re_cache))>>(32-(nb_bits)))) + code; code = table_base[table_offset + index][0]; n = table_base[table_offset + index][1]; // if(// DebugTool.logCount == 8635) { // DebugTool.printDebugString(" get_vlc2(LEVEL2)=> index="+index+", code="+code+", n="+n+"\n"); // } // if } } //SKIP_BITS(name, gb, n) re_cache >>= (n); re_index += (n); // //System.out.println("get_vlc2(,"+n+","+message+"): "+ code); } //CLOSE_READER(re, s) // DebugTool.printDebugString(" stream => update re_index = "+ re_index+"\n"); this.index= re_index; return code; } /** * read unsigned exp golomb code. */ public int get_ue_golomb(String message){ /*unsigned */long buf; int log; // OPEN_READER(re, gb); int re_index= this.index; long re_cache= 0; // UPDATE_CACHE(re, gb); int pos = buffer_offset + (re_index>>3); //re_cache = ((buffer[pos+3]<<24)|(buffer[pos+2]<<16)|(buffer[pos+1]<<8)|(buffer[pos])) >> (re_index&0x07); re_cache = buffer[pos+0]; re_cache = (re_cache << 8) | buffer[pos+1]; re_cache = (re_cache << 8) | buffer[pos+2]; re_cache = (re_cache << 8) | buffer[pos+3]; re_cache = (re_cache << (re_index & 0x07)); re_cache = (re_cache & 0xffffffffl); // Prevent 32-Bit over flow. // buf=GET_CACHE(re, gb); buf = (re_cache); if(buf >= (1l<<27)){ buf >>= 32 - 9; // LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]); re_index += (ff_golomb_vlc_len[(int)buf]); // CLOSE_READER(re, gb); this.index= re_index; //System.out.println("get_ue_golomb(,"+ff_golomb_vlc_len[(int)buf]+","+message+"): "+ (ff_ue_golomb_vlc_code[(int)buf]) ); return ff_ue_golomb_vlc_code[(int)buf]; }else{ log= 2*CAVLCContext.av_log2(buf) - 31; buf>>= log; buf--; // LAST_SKIP_BITS(re, gb, 32 - log); re_index += (32 - log); // CLOSE_READER(re, gb); this.index= re_index; //System.out.println("get_ue_golomb(,"+(32 - log)+","+message+"): "+ ((int)buf) ); return (int)buf; } } /** * read unsigned exp golomb code, constraint to a max of 31. * the return value is undefined if the stored value exceeds 31. */ public int get_ue_golomb_31(String message){ /*unsigned */long buf; // OPEN_READER(re, gb); int re_index= this.index; long re_cache= 0; // UPDATE_CACHE(re, gb); int pos = buffer_offset + (re_index>>3); //re_cache = ((long)(((buffer[pos+3]<<24)|(buffer[pos+2]<<16)|(buffer[pos+1]<<8)|(buffer[pos]<<0)) & 0xffffffff)) >> (re_index&0x07); re_cache = buffer[pos+0]; re_cache = (re_cache << 8) | buffer[pos+1]; re_cache = (re_cache << 8) | buffer[pos+2]; re_cache = (re_cache << 8) | buffer[pos+3]; re_cache = (re_cache << (re_index & 0x07)); re_cache = re_cache & 0xffffffffl; // Prevent 32-Bit over flow. // buf=GET_CACHE(re, gb); //buf = (int)(re_cache >> (32-9)); buf = re_cache >> (32-9); //buf >>= 32 - 9; // LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]); re_index += (ff_golomb_vlc_len[(int)buf]); // CLOSE_READER(re, gb); this.index= re_index; //System.out.println("get_ue_golomb_31(,"+(ff_golomb_vlc_len[(int)buf])+","+message+"): "+ (ff_ue_golomb_vlc_code[(int)buf]) ); return ff_ue_golomb_vlc_code[(int)buf]; } /** * read signed exp golomb code. */ public int get_se_golomb(String message){ /*unsigned */long buf; int log; // OPEN_READER(re, gb); int re_index= this.index; long re_cache= 0; // UPDATE_CACHE(re, gb); int pos = buffer_offset + (re_index>>3); //re_cache = ((buffer[pos+3]<<24)|(buffer[pos+2]<<16)|(buffer[pos+1]<<8)|(buffer[pos])) >> (re_index&0x07); re_cache = buffer[pos+0]; re_cache = (re_cache << 8) | buffer[pos+1]; re_cache = (re_cache << 8) | buffer[pos+2]; re_cache = (re_cache << 8) | buffer[pos+3]; re_cache = (re_cache << (re_index & 0x07)); re_cache = re_cache & 0xffffffffl; // Prevent 32-Bit over flow. // buf=GET_CACHE(re, gb); buf = (re_cache); if(buf >= (1<<27)){ buf >>= 32 - 9; // LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]); re_index += (ff_golomb_vlc_len[(int)buf]); // CLOSE_READER(re, gb); this.index= re_index; //System.out.println("get_se_golomb(,"+(ff_golomb_vlc_len[(int)buf])+","+message+"): "+ (ff_se_golomb_vlc_code[(int)buf]) ); return ff_se_golomb_vlc_code[(int)buf]; }else{ log= 2*CAVLCContext.av_log2(buf) - 31; buf>>= log; // LAST_SKIP_BITS(re, gb, 32 - log); re_index += (32 - log); // CLOSE_READER(re, gb); this.index= re_index; if((buf&1)!=0) buf= -(buf>>1); else buf= (buf>>1); //System.out.println("get_se_golomb(,"+(32 - log)+","+message+"): "+ ((int)buf) ); return (int)buf; } } }