annotate src/wma/libffwma/common.c @ 2150:04421592e6a3

Fixed an unexpected cddb error messaje when no cddb info is available
author Calin Crisan ccrisan@gmail.com
date Sat, 03 Nov 2007 01:23:56 +0200
parents aa044d71838f
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
878
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
1 /*
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
2 * Common bit i/o utils
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
3 * Copyright (c) 2000, 2001 Fabrice Bellard.
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
4 * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
5 * Copyright (c) 2004 Roman Bogorodskiy (bmp-wma specific stuff)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
6 *
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
7 * This library is free software; you can redistribute it and/or
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
10 * version 2 of the License, or (at your option) any later version.
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
11 *
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
12 * This library is distributed in the hope that it will be useful,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
15 * Lesser General Public License for more details.
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
16 *
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
18 * License along with this library; if not, write to the Free Software
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
20 *
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
21 * alternative bitstream reader & writer by Michael Niedermayer <michaelni@gmx.at>
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
22 */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
23
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
24 /**
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
25 * @file common.c
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
26 * common internal api.
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
27 */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
28
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
29 #include "avcodec.h"
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
30
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
31 const uint8_t ff_sqrt_tab[128]={
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
32 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
33 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
34 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
35 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
36 };
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
37
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
38 const uint8_t ff_log2_tab[256]={
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
39 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
40 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,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
41 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
42 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
43 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,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
44 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,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
45 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,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
46 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
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
47 };
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
48
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
49 void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
50 {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
51 s->buf = buffer;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
52 s->buf_end = s->buf + buffer_size;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
53 s->buf_ptr = s->buf;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
54 s->bit_left=32;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
55 s->bit_buf=0;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
56 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
57
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
58 /**
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
59 * init GetBitContext.
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
60 * @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes larger then the actual read bits
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
61 * because some optimized bitstream readers read 32 or 64 bit at once and could read over the end
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
62 * @param bit_size the size of the buffer in bits
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
63 */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
64 void init_get_bits(GetBitContext *s,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
65 const uint8_t *buffer, int bit_size)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
66 {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
67 const int buffer_size= (bit_size+7)>>3;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
68
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
69 s->buffer= buffer;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
70 s->size_in_bits= bit_size;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
71 s->buffer_end= buffer + buffer_size;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
72 #ifdef ALT_BITSTREAM_READER
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
73 s->index=0;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
74 #elif defined LIBMPEG2_BITSTREAM_READER
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
75 #ifdef LIBMPEG2_BITSTREAM_READER_HACK
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
76 if ((int)buffer&1) {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
77 /* word alignment */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
78 s->cache = (*buffer++)<<24;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
79 s->buffer_ptr = buffer;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
80 s->bit_count = 16-8;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
81 } else
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
82 #endif
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
83 {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
84 s->buffer_ptr = buffer;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
85 s->bit_count = 16;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
86 s->cache = 0;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
87 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
88 #elif defined A32_BITSTREAM_READER
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
89 s->buffer_ptr = (uint32_t*)buffer;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
90 s->bit_count = 32;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
91 s->cache0 = 0;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
92 s->cache1 = 0;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
93 #endif
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
94 {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
95 OPEN_READER(re, s)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
96 UPDATE_CACHE(re, s)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
97 UPDATE_CACHE(re, s)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
98 CLOSE_READER(re, s)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
99 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
100 #ifdef A32_BITSTREAM_READER
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
101 s->cache1 = 0;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
102 #endif
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
103 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
104
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
105 /**
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
106 * reads 0-32 bits.
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
107 */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
108 unsigned int get_bits_long(GetBitContext *s, int n){
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
109 if(n<=17) return get_bits(s, n);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
110 else{
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
111 int ret= get_bits(s, 16) << (n-16);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
112 return ret | get_bits(s, n-16);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
113 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
114 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
115
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
116 /**
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
117 * shows 0-32 bits.
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
118 */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
119 unsigned int show_bits_long(GetBitContext *s, int n){
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
120 if(n<=17) return show_bits(s, n);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
121 else{
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
122 GetBitContext gb= *s;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
123 int ret= get_bits_long(s, n);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
124 *s= gb;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
125 return ret;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
126 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
127 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
128
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
129 void align_get_bits(GetBitContext *s)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
130 {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
131 int n= (-get_bits_count(s)) & 7;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
132 if(n) skip_bits(s, n);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
133 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
134
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
135 int check_marker(GetBitContext *s, const char *msg)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
136 {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
137 int bit= get_bits1(s);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
138 if(!bit)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
139 av_log(NULL, AV_LOG_INFO, "Marker bit missing %s\n", msg);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
140
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
141 return bit;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
142 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
143
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
144 /* VLC decoding */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
145
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
146 //#define DEBUG_VLC
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
147
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
148 #define GET_DATA(v, table, i, wrap, size) \
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
149 {\
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
150 const uint8_t *ptr = (const uint8_t *)table + i * wrap;\
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
151 switch(size) {\
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
152 case 1:\
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
153 v = *(const uint8_t *)ptr;\
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
154 break;\
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
155 case 2:\
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
156 v = *(const uint16_t *)ptr;\
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
157 break;\
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
158 default:\
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
159 v = *(const uint32_t *)ptr;\
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
160 break;\
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
161 }\
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
162 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
163
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
164
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
165 static int alloc_table(VLC *vlc, int size)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
166 {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
167 int index;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
168 index = vlc->table_size;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
169 vlc->table_size += size;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
170 if (vlc->table_size > vlc->table_allocated) {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
171 vlc->table_allocated += (1 << vlc->bits);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
172 vlc->table = realloc(vlc->table,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
173 sizeof(VLC_TYPE) * 2 * vlc->table_allocated);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
174 if (!vlc->table)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
175 return -1;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
176 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
177 return index;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
178 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
179
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
180 static int build_table(VLC *vlc, int table_nb_bits,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
181 int nb_codes,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
182 const void *bits, int bits_wrap, int bits_size,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
183 const void *codes, int codes_wrap, int codes_size,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
184 uint32_t code_prefix, int n_prefix)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
185 {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
186 int i, j, k, n, table_size, table_index, nb, n1, index;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
187 uint32_t code;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
188 VLC_TYPE (*table)[2];
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
189
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
190 table_size = 1 << table_nb_bits;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
191 table_index = alloc_table(vlc, table_size);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
192
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
193 if (table_index < 0)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
194 return -1;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
195 table = &vlc->table[table_index];
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
196
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
197 for(i=0;i<table_size;i++) {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
198 table[i][1] = 0; //bits
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
199 table[i][0] = -1; //codes
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
200 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
201
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
202 /* first pass: map codes and compute auxillary table sizes */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
203 for(i=0;i<nb_codes;i++) {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
204 GET_DATA(n, bits, i, bits_wrap, bits_size);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
205 GET_DATA(code, codes, i, codes_wrap, codes_size);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
206 /* we accept tables with holes */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
207 if (n <= 0)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
208 continue;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
209 /* if code matches the prefix, it is in the table */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
210 n -= n_prefix;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
211 if (n > 0 && (code >> n) == code_prefix) {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
212 if (n <= table_nb_bits) {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
213 /* no need to add another table */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
214 j = (code << (table_nb_bits - n)) & (table_size - 1);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
215 nb = 1 << (table_nb_bits - n);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
216 for(k=0;k<nb;k++) {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
217 if (table[j][1] /*bits*/ != 0) {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
218 av_log(NULL, AV_LOG_ERROR, "incorrect codes\n");
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
219 av_abort();
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
220 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
221 table[j][1] = n; //bits
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
222 table[j][0] = i; //code
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
223 j++;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
224 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
225 } else {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
226 n -= table_nb_bits;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
227 j = (code >> n) & ((1 << table_nb_bits) - 1);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
228 /* compute table size */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
229 n1 = -table[j][1]; //bits
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
230 if (n > n1)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
231 n1 = n;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
232 table[j][1] = -n1; //bits
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
233 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
234 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
235 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
236
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
237 /* second pass : fill auxillary tables recursively */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
238 for(i=0;i<table_size;i++) {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
239 n = table[i][1]; //bits
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
240 if (n < 0) {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
241 n = -n;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
242 if (n > table_nb_bits) {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
243 n = table_nb_bits;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
244 table[i][1] = -n; //bits
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
245 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
246 index = build_table(vlc, n, nb_codes,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
247 bits, bits_wrap, bits_size,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
248 codes, codes_wrap, codes_size,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
249 (code_prefix << table_nb_bits) | i,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
250 n_prefix + table_nb_bits);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
251 if (index < 0)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
252 return -1;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
253 /* note: realloc has been done, so reload tables */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
254 table = &vlc->table[table_index];
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
255 table[i][0] = index; //code
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
256 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
257 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
258 return table_index;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
259 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
260
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
261
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
262 /* Build VLC decoding tables suitable for use with get_vlc().
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
263
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
264 'nb_bits' set thee decoding table size (2^nb_bits) entries. The
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
265 bigger it is, the faster is the decoding. But it should not be too
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
266 big to save memory and L1 cache. '9' is a good compromise.
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
267
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
268 'nb_codes' : number of vlcs codes
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
269
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
270 'bits' : table which gives the size (in bits) of each vlc code.
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
271
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
272 'codes' : table which gives the bit pattern of of each vlc code.
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
273
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
274 'xxx_wrap' : give the number of bytes between each entry of the
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
275 'bits' or 'codes' tables.
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
276
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
277 'xxx_size' : gives the number of bytes of each entry of the 'bits'
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
278 or 'codes' tables.
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
279
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
280 'wrap' and 'size' allows to use any memory configuration and types
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
281 (byte/word/long) to store the 'bits' and 'codes' tables.
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
282 */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
283 int init_vlc(VLC *vlc, int nb_bits, int nb_codes,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
284 const void *bits, int bits_wrap, int bits_size,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
285 const void *codes, int codes_wrap, int codes_size)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
286 {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
287 vlc->bits = nb_bits;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
288 vlc->table = NULL;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
289 vlc->table_allocated = 0;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
290 vlc->table_size = 0;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
291
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
292 if (build_table(vlc, nb_bits, nb_codes,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
293 bits, bits_wrap, bits_size,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
294 codes, codes_wrap, codes_size,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
295 0, 0) < 0) {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
296 free(vlc->table);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
297 return -1;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
298 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
299 return 0;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
300 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
301
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
302
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
303 void free_vlc(VLC *vlc)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
304 {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
305 free(vlc->table);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
306 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
307
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
308 int64_t ff_gcd(int64_t a, int64_t b){
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
309 if(b) return ff_gcd(b, a%b);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
310 else return a;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
311 }