annotate mpegaudiodec.c @ 0:986e461dc072 libavcodec

Initial revision
author glantau
date Sun, 22 Jul 2001 14:18:56 +0000
parents
children 46ee548e47e4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
1 /*
986e461dc072 Initial revision
glantau
parents:
diff changeset
2 * MPEG Audio decoder
986e461dc072 Initial revision
glantau
parents:
diff changeset
3 * Copyright (c) 2001 Gerard Lantau.
986e461dc072 Initial revision
glantau
parents:
diff changeset
4 *
986e461dc072 Initial revision
glantau
parents:
diff changeset
5 * This program is free software; you can redistribute it and/or modify
986e461dc072 Initial revision
glantau
parents:
diff changeset
6 * it under the terms of the GNU General Public License as published by
986e461dc072 Initial revision
glantau
parents:
diff changeset
7 * the Free Software Foundation; either version 2 of the License, or
986e461dc072 Initial revision
glantau
parents:
diff changeset
8 * (at your option) any later version.
986e461dc072 Initial revision
glantau
parents:
diff changeset
9 *
986e461dc072 Initial revision
glantau
parents:
diff changeset
10 * This program is distributed in the hope that it will be useful,
986e461dc072 Initial revision
glantau
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
986e461dc072 Initial revision
glantau
parents:
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
986e461dc072 Initial revision
glantau
parents:
diff changeset
13 * GNU General Public License for more details.
986e461dc072 Initial revision
glantau
parents:
diff changeset
14 *
986e461dc072 Initial revision
glantau
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License
986e461dc072 Initial revision
glantau
parents:
diff changeset
16 * along with this program; if not, write to the Free Software
986e461dc072 Initial revision
glantau
parents:
diff changeset
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
986e461dc072 Initial revision
glantau
parents:
diff changeset
18 */
986e461dc072 Initial revision
glantau
parents:
diff changeset
19 #include <stdlib.h>
986e461dc072 Initial revision
glantau
parents:
diff changeset
20 #include <stdio.h>
986e461dc072 Initial revision
glantau
parents:
diff changeset
21 #include <string.h>
986e461dc072 Initial revision
glantau
parents:
diff changeset
22 #include "avcodec.h"
986e461dc072 Initial revision
glantau
parents:
diff changeset
23 #include "mpglib/mpg123.h"
986e461dc072 Initial revision
glantau
parents:
diff changeset
24
986e461dc072 Initial revision
glantau
parents:
diff changeset
25 /*
986e461dc072 Initial revision
glantau
parents:
diff changeset
26 * TODO:
986e461dc072 Initial revision
glantau
parents:
diff changeset
27 * - add free format
986e461dc072 Initial revision
glantau
parents:
diff changeset
28 * - do not rely anymore on mpglib (first step: implement dct64 and decoding filter)
986e461dc072 Initial revision
glantau
parents:
diff changeset
29 */
986e461dc072 Initial revision
glantau
parents:
diff changeset
30
986e461dc072 Initial revision
glantau
parents:
diff changeset
31 #define HEADER_SIZE 4
986e461dc072 Initial revision
glantau
parents:
diff changeset
32 #define BACKSTEP_SIZE 512
986e461dc072 Initial revision
glantau
parents:
diff changeset
33
986e461dc072 Initial revision
glantau
parents:
diff changeset
34 typedef struct MPADecodeContext {
986e461dc072 Initial revision
glantau
parents:
diff changeset
35 struct mpstr mpstr;
986e461dc072 Initial revision
glantau
parents:
diff changeset
36 UINT8 inbuf1[2][MAXFRAMESIZE + BACKSTEP_SIZE]; /* input buffer */
986e461dc072 Initial revision
glantau
parents:
diff changeset
37 int inbuf_index;
986e461dc072 Initial revision
glantau
parents:
diff changeset
38 UINT8 *inbuf_ptr, *inbuf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
39 int frame_size;
986e461dc072 Initial revision
glantau
parents:
diff changeset
40 int error_protection;
986e461dc072 Initial revision
glantau
parents:
diff changeset
41 int layer;
986e461dc072 Initial revision
glantau
parents:
diff changeset
42 int sample_rate;
986e461dc072 Initial revision
glantau
parents:
diff changeset
43 int bit_rate;
986e461dc072 Initial revision
glantau
parents:
diff changeset
44 int old_frame_size;
986e461dc072 Initial revision
glantau
parents:
diff changeset
45 GetBitContext gb;
986e461dc072 Initial revision
glantau
parents:
diff changeset
46 } MPADecodeContext;
986e461dc072 Initial revision
glantau
parents:
diff changeset
47
986e461dc072 Initial revision
glantau
parents:
diff changeset
48 /* XXX: suppress that mess */
986e461dc072 Initial revision
glantau
parents:
diff changeset
49 struct mpstr *gmp;
986e461dc072 Initial revision
glantau
parents:
diff changeset
50 GetBitContext *gmp_gb;
986e461dc072 Initial revision
glantau
parents:
diff changeset
51 static MPADecodeContext *gmp_s;
986e461dc072 Initial revision
glantau
parents:
diff changeset
52
986e461dc072 Initial revision
glantau
parents:
diff changeset
53 /* XXX: merge constants with encoder */
986e461dc072 Initial revision
glantau
parents:
diff changeset
54 static const unsigned short mp_bitrate_tab[2][3][15] = {
986e461dc072 Initial revision
glantau
parents:
diff changeset
55 { {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 },
986e461dc072 Initial revision
glantau
parents:
diff changeset
56 {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 },
986e461dc072 Initial revision
glantau
parents:
diff changeset
57 {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 } },
986e461dc072 Initial revision
glantau
parents:
diff changeset
58 { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256},
986e461dc072 Initial revision
glantau
parents:
diff changeset
59 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160},
986e461dc072 Initial revision
glantau
parents:
diff changeset
60 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}
986e461dc072 Initial revision
glantau
parents:
diff changeset
61 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
62 };
986e461dc072 Initial revision
glantau
parents:
diff changeset
63
986e461dc072 Initial revision
glantau
parents:
diff changeset
64 static unsigned short mp_freq_tab[3] = { 44100, 48000, 32000 };
986e461dc072 Initial revision
glantau
parents:
diff changeset
65
986e461dc072 Initial revision
glantau
parents:
diff changeset
66 static int decode_init(AVCodecContext * avctx)
986e461dc072 Initial revision
glantau
parents:
diff changeset
67 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
68 MPADecodeContext *s = avctx->priv_data;
986e461dc072 Initial revision
glantau
parents:
diff changeset
69 struct mpstr *mp = &s->mpstr;
986e461dc072 Initial revision
glantau
parents:
diff changeset
70 static int init;
986e461dc072 Initial revision
glantau
parents:
diff changeset
71
986e461dc072 Initial revision
glantau
parents:
diff changeset
72 mp->fr.single = -1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
73 mp->synth_bo = 1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
74
986e461dc072 Initial revision
glantau
parents:
diff changeset
75 if(!init) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
76 init = 1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
77 make_decode_tables(32767);
986e461dc072 Initial revision
glantau
parents:
diff changeset
78 init_layer2();
986e461dc072 Initial revision
glantau
parents:
diff changeset
79 init_layer3(SBLIMIT);
986e461dc072 Initial revision
glantau
parents:
diff changeset
80 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
81
986e461dc072 Initial revision
glantau
parents:
diff changeset
82 s->inbuf_index = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
83 s->inbuf = &s->inbuf1[s->inbuf_index][BACKSTEP_SIZE];
986e461dc072 Initial revision
glantau
parents:
diff changeset
84 s->inbuf_ptr = s->inbuf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
85
986e461dc072 Initial revision
glantau
parents:
diff changeset
86 return 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
87 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
88
986e461dc072 Initial revision
glantau
parents:
diff changeset
89 /* fast header check for resync */
986e461dc072 Initial revision
glantau
parents:
diff changeset
90 static int check_header(UINT32 header)
986e461dc072 Initial revision
glantau
parents:
diff changeset
91 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
92 /* header */
986e461dc072 Initial revision
glantau
parents:
diff changeset
93 if ((header & 0xffe00000) != 0xffe00000)
986e461dc072 Initial revision
glantau
parents:
diff changeset
94 return -1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
95 /* layer check */
986e461dc072 Initial revision
glantau
parents:
diff changeset
96 if (((header >> 17) & 3) == 0)
986e461dc072 Initial revision
glantau
parents:
diff changeset
97 return -1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
98 /* bit rate : currently no free format supported */
986e461dc072 Initial revision
glantau
parents:
diff changeset
99 if (((header >> 12) & 0xf) == 0xf ||
986e461dc072 Initial revision
glantau
parents:
diff changeset
100 ((header >> 12) & 0xf) == 0x0)
986e461dc072 Initial revision
glantau
parents:
diff changeset
101 return -1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
102 /* frequency */
986e461dc072 Initial revision
glantau
parents:
diff changeset
103 if (((header >> 10) & 3) == 3)
986e461dc072 Initial revision
glantau
parents:
diff changeset
104 return -1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
105 return 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
106 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
107
986e461dc072 Initial revision
glantau
parents:
diff changeset
108 /* header decoding. MUST check the header before because no
986e461dc072 Initial revision
glantau
parents:
diff changeset
109 consistency check is done there */
986e461dc072 Initial revision
glantau
parents:
diff changeset
110 static void decode_header(MPADecodeContext *s, UINT32 header)
986e461dc072 Initial revision
glantau
parents:
diff changeset
111 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
112 struct frame *fr = &s->mpstr.fr;
986e461dc072 Initial revision
glantau
parents:
diff changeset
113 int sample_rate, frame_size;
986e461dc072 Initial revision
glantau
parents:
diff changeset
114
986e461dc072 Initial revision
glantau
parents:
diff changeset
115 if (header & (1<<20)) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
116 fr->lsf = (header & (1<<19)) ? 0 : 1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
117 fr->mpeg25 = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
118 } else {
986e461dc072 Initial revision
glantau
parents:
diff changeset
119 fr->lsf = 1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
120 fr->mpeg25 = 1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
121 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
122
986e461dc072 Initial revision
glantau
parents:
diff changeset
123 s->layer = 4 - ((header >> 17) & 3);
986e461dc072 Initial revision
glantau
parents:
diff changeset
124 /* extract frequency */
986e461dc072 Initial revision
glantau
parents:
diff changeset
125 fr->sampling_frequency = ((header >> 10) & 3);
986e461dc072 Initial revision
glantau
parents:
diff changeset
126 sample_rate = mp_freq_tab[fr->sampling_frequency] >> (fr->lsf + fr->mpeg25);
986e461dc072 Initial revision
glantau
parents:
diff changeset
127 fr->sampling_frequency += 3 * (fr->lsf + fr->mpeg25);
986e461dc072 Initial revision
glantau
parents:
diff changeset
128
986e461dc072 Initial revision
glantau
parents:
diff changeset
129 s->error_protection = ((header>>16) & 1) ^ 1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
130
986e461dc072 Initial revision
glantau
parents:
diff changeset
131 fr->bitrate_index = ((header>>12)&0xf);
986e461dc072 Initial revision
glantau
parents:
diff changeset
132 fr->padding = ((header>>9)&0x1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
133 fr->extension = ((header>>8)&0x1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
134 fr->mode = ((header>>6)&0x3);
986e461dc072 Initial revision
glantau
parents:
diff changeset
135 fr->mode_ext = ((header>>4)&0x3);
986e461dc072 Initial revision
glantau
parents:
diff changeset
136 fr->copyright = ((header>>3)&0x1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
137 fr->original = ((header>>2)&0x1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
138 fr->emphasis = header & 0x3;
986e461dc072 Initial revision
glantau
parents:
diff changeset
139
986e461dc072 Initial revision
glantau
parents:
diff changeset
140 fr->stereo = (fr->mode == MPG_MD_MONO) ? 1 : 2;
986e461dc072 Initial revision
glantau
parents:
diff changeset
141
986e461dc072 Initial revision
glantau
parents:
diff changeset
142
986e461dc072 Initial revision
glantau
parents:
diff changeset
143 frame_size = mp_bitrate_tab[fr->lsf][s->layer - 1][fr->bitrate_index];
986e461dc072 Initial revision
glantau
parents:
diff changeset
144 s->bit_rate = frame_size * 1000;
986e461dc072 Initial revision
glantau
parents:
diff changeset
145 switch(s->layer) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
146 case 1:
986e461dc072 Initial revision
glantau
parents:
diff changeset
147 frame_size = (frame_size * 12000) / sample_rate;
986e461dc072 Initial revision
glantau
parents:
diff changeset
148 frame_size = ((frame_size + fr->padding) << 2);
986e461dc072 Initial revision
glantau
parents:
diff changeset
149 break;
986e461dc072 Initial revision
glantau
parents:
diff changeset
150 case 2:
986e461dc072 Initial revision
glantau
parents:
diff changeset
151 frame_size = (frame_size * 144000) / sample_rate;
986e461dc072 Initial revision
glantau
parents:
diff changeset
152 frame_size += fr->padding;
986e461dc072 Initial revision
glantau
parents:
diff changeset
153 break;
986e461dc072 Initial revision
glantau
parents:
diff changeset
154 case 3:
986e461dc072 Initial revision
glantau
parents:
diff changeset
155 frame_size = (frame_size * 144000) / (sample_rate << fr->lsf);
986e461dc072 Initial revision
glantau
parents:
diff changeset
156 frame_size += fr->padding;
986e461dc072 Initial revision
glantau
parents:
diff changeset
157 break;
986e461dc072 Initial revision
glantau
parents:
diff changeset
158 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
159 s->frame_size = frame_size;
986e461dc072 Initial revision
glantau
parents:
diff changeset
160 s->sample_rate = sample_rate;
986e461dc072 Initial revision
glantau
parents:
diff changeset
161
986e461dc072 Initial revision
glantau
parents:
diff changeset
162 #if 0
986e461dc072 Initial revision
glantau
parents:
diff changeset
163 printf("layer%d, %d Hz, %d kbits/s, %s\n",
986e461dc072 Initial revision
glantau
parents:
diff changeset
164 s->layer, s->sample_rate, s->bit_rate, fr->stereo ? "stereo" : "mono");
986e461dc072 Initial revision
glantau
parents:
diff changeset
165 #endif
986e461dc072 Initial revision
glantau
parents:
diff changeset
166 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
167
986e461dc072 Initial revision
glantau
parents:
diff changeset
168 static int mp_decode_frame(MPADecodeContext *s,
986e461dc072 Initial revision
glantau
parents:
diff changeset
169 short *samples)
986e461dc072 Initial revision
glantau
parents:
diff changeset
170 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
171 int nb_bytes;
986e461dc072 Initial revision
glantau
parents:
diff changeset
172
986e461dc072 Initial revision
glantau
parents:
diff changeset
173 init_get_bits(&s->gb, s->inbuf + HEADER_SIZE, s->inbuf_ptr - s->inbuf - HEADER_SIZE);
986e461dc072 Initial revision
glantau
parents:
diff changeset
174
986e461dc072 Initial revision
glantau
parents:
diff changeset
175 /* skip error protection field */
986e461dc072 Initial revision
glantau
parents:
diff changeset
176 if (s->error_protection)
986e461dc072 Initial revision
glantau
parents:
diff changeset
177 get_bits(&s->gb, 16);
986e461dc072 Initial revision
glantau
parents:
diff changeset
178
986e461dc072 Initial revision
glantau
parents:
diff changeset
179 /* XXX: horrible: global! */
986e461dc072 Initial revision
glantau
parents:
diff changeset
180 gmp = &s->mpstr;
986e461dc072 Initial revision
glantau
parents:
diff changeset
181 gmp_s = s;
986e461dc072 Initial revision
glantau
parents:
diff changeset
182 gmp_gb = &s->gb;
986e461dc072 Initial revision
glantau
parents:
diff changeset
183
986e461dc072 Initial revision
glantau
parents:
diff changeset
184 nb_bytes = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
185 switch(s->layer) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
186 case 1:
986e461dc072 Initial revision
glantau
parents:
diff changeset
187 do_layer1(&s->mpstr.fr,(unsigned char *)samples, &nb_bytes);
986e461dc072 Initial revision
glantau
parents:
diff changeset
188 break;
986e461dc072 Initial revision
glantau
parents:
diff changeset
189 case 2:
986e461dc072 Initial revision
glantau
parents:
diff changeset
190 do_layer2(&s->mpstr.fr,(unsigned char *)samples, &nb_bytes);
986e461dc072 Initial revision
glantau
parents:
diff changeset
191 break;
986e461dc072 Initial revision
glantau
parents:
diff changeset
192 case 3:
986e461dc072 Initial revision
glantau
parents:
diff changeset
193 do_layer3(&s->mpstr.fr,(unsigned char *)samples, &nb_bytes);
986e461dc072 Initial revision
glantau
parents:
diff changeset
194 s->inbuf_index ^= 1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
195 s->inbuf = &s->inbuf1[s->inbuf_index][BACKSTEP_SIZE];
986e461dc072 Initial revision
glantau
parents:
diff changeset
196 s->old_frame_size = s->frame_size;
986e461dc072 Initial revision
glantau
parents:
diff changeset
197 break;
986e461dc072 Initial revision
glantau
parents:
diff changeset
198 default:
986e461dc072 Initial revision
glantau
parents:
diff changeset
199 break;
986e461dc072 Initial revision
glantau
parents:
diff changeset
200 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
201 return nb_bytes;
986e461dc072 Initial revision
glantau
parents:
diff changeset
202 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
203
986e461dc072 Initial revision
glantau
parents:
diff changeset
204 /*
986e461dc072 Initial revision
glantau
parents:
diff changeset
205 * seek back in the stream for backstep bytes (at most 511 bytes, and
986e461dc072 Initial revision
glantau
parents:
diff changeset
206 * at most in last frame). Note that this is slightly incorrect (data
986e461dc072 Initial revision
glantau
parents:
diff changeset
207 * can span more than one block!)
986e461dc072 Initial revision
glantau
parents:
diff changeset
208 */
986e461dc072 Initial revision
glantau
parents:
diff changeset
209 int set_pointer(long backstep)
986e461dc072 Initial revision
glantau
parents:
diff changeset
210 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
211 UINT8 *ptr;
986e461dc072 Initial revision
glantau
parents:
diff changeset
212
986e461dc072 Initial revision
glantau
parents:
diff changeset
213 /* compute current position in stream */
986e461dc072 Initial revision
glantau
parents:
diff changeset
214 ptr = gmp_gb->buf_ptr - (gmp_gb->bit_cnt >> 3);
986e461dc072 Initial revision
glantau
parents:
diff changeset
215 /* copy old data before current one */
986e461dc072 Initial revision
glantau
parents:
diff changeset
216 ptr -= backstep;
986e461dc072 Initial revision
glantau
parents:
diff changeset
217 memcpy(ptr, gmp_s->inbuf1[gmp_s->inbuf_index ^ 1] +
986e461dc072 Initial revision
glantau
parents:
diff changeset
218 BACKSTEP_SIZE + gmp_s->old_frame_size - backstep, backstep);
986e461dc072 Initial revision
glantau
parents:
diff changeset
219 /* init get bits again */
986e461dc072 Initial revision
glantau
parents:
diff changeset
220 init_get_bits(gmp_gb, ptr, gmp_s->frame_size + backstep);
986e461dc072 Initial revision
glantau
parents:
diff changeset
221
986e461dc072 Initial revision
glantau
parents:
diff changeset
222 return 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
223 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
224
986e461dc072 Initial revision
glantau
parents:
diff changeset
225 static int decode_frame(AVCodecContext * avctx,
986e461dc072 Initial revision
glantau
parents:
diff changeset
226 void *data, int *data_size,
986e461dc072 Initial revision
glantau
parents:
diff changeset
227 UINT8 * buf, int buf_size)
986e461dc072 Initial revision
glantau
parents:
diff changeset
228 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
229 MPADecodeContext *s = avctx->priv_data;
986e461dc072 Initial revision
glantau
parents:
diff changeset
230 UINT32 header;
986e461dc072 Initial revision
glantau
parents:
diff changeset
231 UINT8 *buf_ptr;
986e461dc072 Initial revision
glantau
parents:
diff changeset
232 int len, out_size;
986e461dc072 Initial revision
glantau
parents:
diff changeset
233 short *out_samples = data;
986e461dc072 Initial revision
glantau
parents:
diff changeset
234
986e461dc072 Initial revision
glantau
parents:
diff changeset
235 *data_size = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
236 buf_ptr = buf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
237 while (buf_size > 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
238 len = s->inbuf_ptr - s->inbuf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
239 if (s->frame_size == 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
240 /* no header seen : find one. We need at least 7 bytes to parse it */
986e461dc072 Initial revision
glantau
parents:
diff changeset
241 len = HEADER_SIZE - len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
242 if (len > buf_size)
986e461dc072 Initial revision
glantau
parents:
diff changeset
243 len = buf_size;
986e461dc072 Initial revision
glantau
parents:
diff changeset
244 memcpy(s->inbuf_ptr, buf_ptr, len);
986e461dc072 Initial revision
glantau
parents:
diff changeset
245 buf_ptr += len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
246 s->inbuf_ptr += len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
247 buf_size -= len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
248 if ((s->inbuf_ptr - s->inbuf) == HEADER_SIZE) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
249 header = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) |
986e461dc072 Initial revision
glantau
parents:
diff changeset
250 (s->inbuf[2] << 8) | s->inbuf[3];
986e461dc072 Initial revision
glantau
parents:
diff changeset
251 if (check_header(header) < 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
252 /* no sync found : move by one byte (inefficient, but simple!) */
986e461dc072 Initial revision
glantau
parents:
diff changeset
253 memcpy(s->inbuf, s->inbuf + 1, HEADER_SIZE - 1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
254 s->inbuf_ptr--;
986e461dc072 Initial revision
glantau
parents:
diff changeset
255 } else {
986e461dc072 Initial revision
glantau
parents:
diff changeset
256 decode_header(s, header);
986e461dc072 Initial revision
glantau
parents:
diff changeset
257 /* update codec info */
986e461dc072 Initial revision
glantau
parents:
diff changeset
258 avctx->sample_rate = s->sample_rate;
986e461dc072 Initial revision
glantau
parents:
diff changeset
259 avctx->channels = s->mpstr.fr.stereo ? 2 : 1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
260 avctx->bit_rate = s->bit_rate;
986e461dc072 Initial revision
glantau
parents:
diff changeset
261 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
262 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
263 } else if (len < s->frame_size) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
264 len = s->frame_size - len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
265 if (len > buf_size)
986e461dc072 Initial revision
glantau
parents:
diff changeset
266 len = buf_size;
986e461dc072 Initial revision
glantau
parents:
diff changeset
267
986e461dc072 Initial revision
glantau
parents:
diff changeset
268 memcpy(s->inbuf_ptr, buf_ptr, len);
986e461dc072 Initial revision
glantau
parents:
diff changeset
269 buf_ptr += len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
270 s->inbuf_ptr += len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
271 buf_size -= len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
272 } else {
986e461dc072 Initial revision
glantau
parents:
diff changeset
273 out_size = mp_decode_frame(s, out_samples);
986e461dc072 Initial revision
glantau
parents:
diff changeset
274 s->inbuf_ptr = s->inbuf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
275 s->frame_size = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
276 *data_size = out_size;
986e461dc072 Initial revision
glantau
parents:
diff changeset
277 break;
986e461dc072 Initial revision
glantau
parents:
diff changeset
278 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
279 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
280 return buf_ptr - buf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
281 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
282
986e461dc072 Initial revision
glantau
parents:
diff changeset
283 AVCodec mp3_decoder =
986e461dc072 Initial revision
glantau
parents:
diff changeset
284 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
285 "mpegaudio",
986e461dc072 Initial revision
glantau
parents:
diff changeset
286 CODEC_TYPE_AUDIO,
986e461dc072 Initial revision
glantau
parents:
diff changeset
287 CODEC_ID_MP2,
986e461dc072 Initial revision
glantau
parents:
diff changeset
288 sizeof(MPADecodeContext),
986e461dc072 Initial revision
glantau
parents:
diff changeset
289 decode_init,
986e461dc072 Initial revision
glantau
parents:
diff changeset
290 NULL,
986e461dc072 Initial revision
glantau
parents:
diff changeset
291 NULL,
986e461dc072 Initial revision
glantau
parents:
diff changeset
292 decode_frame,
986e461dc072 Initial revision
glantau
parents:
diff changeset
293 };