Mercurial > libavcodec.hg
annotate mpegaudio_parser.c @ 5062:2dd00b1cc94b libavcodec
Remove mdct.o and fft.o from fft-test prerequisites list.
Both objects were added to the link command, resulting in multiple definitions
of symbols. Now linking works in the general case when mdct.o and fft.o are
compiled into libavcodec.a.
author | diego |
---|---|
date | Tue, 22 May 2007 07:08:38 +0000 |
parents | b908c67063c8 |
children | bff60ecc02f9 |
rev | line source |
---|---|
1613 | 1 /* |
4913 | 2 * MPEG Audio parser |
1613 | 3 * Copyright (c) 2003 Fabrice Bellard. |
4 * Copyright (c) 2003 Michael Niedermayer. | |
5 * | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
6 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
7 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
8 * FFmpeg is free software; you can redistribute it and/or |
1613 | 9 * modify it under the terms of the GNU Lesser General Public |
10 * License as published by the Free Software Foundation; either | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
11 * version 2.1 of the License, or (at your option) any later version. |
1613 | 12 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
13 * FFmpeg is distributed in the hope that it will be useful, |
1613 | 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 * Lesser General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU Lesser General Public | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
19 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2979
diff
changeset
|
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1613 | 21 */ |
2967 | 22 |
4913 | 23 #include "parser.h" |
24 #include "mpegaudio.h" | |
5050 | 25 #include "mpegaudiodecheader.h" |
2386 | 26 |
27 | |
1613 | 28 typedef struct MpegAudioParseContext { |
2979 | 29 uint8_t inbuf[MPA_MAX_CODED_FRAME_SIZE]; /* input buffer */ |
1613 | 30 uint8_t *inbuf_ptr; |
31 int frame_size; | |
32 int free_format_frame_size; | |
33 int free_format_next_header; | |
2470
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
34 uint32_t header; |
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
35 int header_count; |
1613 | 36 } MpegAudioParseContext; |
37 | |
38 #define MPA_HEADER_SIZE 4 | |
39 | |
40 /* header + layer + bitrate + freq + lsf/mpeg25 */ | |
2522
e25782262d7d
kill warnings patch by (Mns Rullgrd <mru inprovide com>)
michael
parents:
2486
diff
changeset
|
41 #undef SAME_HEADER_MASK /* mpegaudio.h defines different version */ |
1613 | 42 #define SAME_HEADER_MASK \ |
2480 | 43 (0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19)) |
1613 | 44 |
5050 | 45 /* useful helper to get mpeg audio stream infos. Return -1 if error in |
46 header, otherwise the coded frame size in bytes */ | |
5051 | 47 int ff_mpa_decode_header(AVCodecContext *avctx, uint32_t head, int *sample_rate) |
5050 | 48 { |
49 MPADecodeContext s1, *s = &s1; | |
50 s1.avctx = avctx; | |
51 | |
52 if (ff_mpa_check_header(head) != 0) | |
53 return -1; | |
54 | |
5051 | 55 if (ff_mpegaudio_decode_header(s, head) != 0) { |
5050 | 56 return -1; |
57 } | |
58 | |
59 switch(s->layer) { | |
60 case 1: | |
61 avctx->frame_size = 384; | |
62 break; | |
63 case 2: | |
64 avctx->frame_size = 1152; | |
65 break; | |
66 default: | |
67 case 3: | |
68 if (s->lsf) | |
69 avctx->frame_size = 576; | |
70 else | |
71 avctx->frame_size = 1152; | |
72 break; | |
73 } | |
74 | |
75 *sample_rate = s->sample_rate; | |
76 avctx->channels = s->nb_channels; | |
77 avctx->bit_rate = s->bit_rate; | |
78 avctx->sub_id = s->layer; | |
79 return s->frame_size; | |
80 } | |
81 | |
1613 | 82 static int mpegaudio_parse_init(AVCodecParserContext *s1) |
83 { | |
84 MpegAudioParseContext *s = s1->priv_data; | |
85 s->inbuf_ptr = s->inbuf; | |
86 return 0; | |
87 } | |
88 | |
89 static int mpegaudio_parse(AVCodecParserContext *s1, | |
90 AVCodecContext *avctx, | |
4931
0d1cc37d9430
make some parser parameters const to avoid casting const to non-const
aurel
parents:
4914
diff
changeset
|
91 const uint8_t **poutbuf, int *poutbuf_size, |
1613 | 92 const uint8_t *buf, int buf_size) |
93 { | |
94 MpegAudioParseContext *s = s1->priv_data; | |
2470
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
95 int len, ret, sr; |
1613 | 96 uint32_t header; |
97 const uint8_t *buf_ptr; | |
98 | |
99 *poutbuf = NULL; | |
100 *poutbuf_size = 0; | |
101 buf_ptr = buf; | |
102 while (buf_size > 0) { | |
2979 | 103 len = s->inbuf_ptr - s->inbuf; |
104 if (s->frame_size == 0) { | |
1613 | 105 /* special case for next header for first frame in free |
106 format case (XXX: find a simpler method) */ | |
107 if (s->free_format_next_header != 0) { | |
108 s->inbuf[0] = s->free_format_next_header >> 24; | |
109 s->inbuf[1] = s->free_format_next_header >> 16; | |
110 s->inbuf[2] = s->free_format_next_header >> 8; | |
111 s->inbuf[3] = s->free_format_next_header; | |
112 s->inbuf_ptr = s->inbuf + 4; | |
113 s->free_format_next_header = 0; | |
114 goto got_header; | |
115 } | |
2979 | 116 /* no header seen : find one. We need at least MPA_HEADER_SIZE |
1613 | 117 bytes to parse it */ |
3639
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
118 len = FFMIN(MPA_HEADER_SIZE - len, buf_size); |
2979 | 119 if (len > 0) { |
120 memcpy(s->inbuf_ptr, buf_ptr, len); | |
121 buf_ptr += len; | |
122 buf_size -= len; | |
123 s->inbuf_ptr += len; | |
124 } | |
125 if ((s->inbuf_ptr - s->inbuf) >= MPA_HEADER_SIZE) { | |
1613 | 126 got_header: |
2979 | 127 header = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) | |
128 (s->inbuf[2] << 8) | s->inbuf[3]; | |
1613 | 129 |
5051 | 130 ret = ff_mpa_decode_header(avctx, header, &sr); |
1613 | 131 if (ret < 0) { |
2470
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
132 s->header_count= -2; |
2979 | 133 /* no sync found : move by one byte (inefficient, but simple!) */ |
134 memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1); | |
135 s->inbuf_ptr--; | |
4652 | 136 dprintf(avctx, "skip %x\n", header); |
1613 | 137 /* reset free format frame size to give a chance |
138 to get a new bitrate */ | |
139 s->free_format_frame_size = 0; | |
2979 | 140 } else { |
2470
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
141 if((header&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header) |
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
142 s->header_count= -3; |
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
143 s->header= header; |
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
144 s->header_count++; |
1613 | 145 s->frame_size = ret; |
2967 | 146 |
1613 | 147 #if 0 |
148 /* free format: prepare to compute frame size */ | |
5051 | 149 if (ff_mpegaudio_decode_header(s, header) == 1) { |
2979 | 150 s->frame_size = -1; |
1613 | 151 } |
152 #endif | |
2979 | 153 } |
4104
04ff8026d9c0
dont set the sampling rate just because 1 mp3 packet header says so (fixes playback speed on some old mencoder generated avis which where then dumped to mp3)
michael
parents:
3989
diff
changeset
|
154 if(s->header_count > 1) |
04ff8026d9c0
dont set the sampling rate just because 1 mp3 packet header says so (fixes playback speed on some old mencoder generated avis which where then dumped to mp3)
michael
parents:
3989
diff
changeset
|
155 avctx->sample_rate= sr; |
2979 | 156 } |
2967 | 157 } else |
1613 | 158 #if 0 |
159 if (s->frame_size == -1) { | |
160 /* free format : find next sync to compute frame size */ | |
2979 | 161 len = MPA_MAX_CODED_FRAME_SIZE - len; |
162 if (len > buf_size) | |
163 len = buf_size; | |
1613 | 164 if (len == 0) { |
2979 | 165 /* frame too long: resync */ |
1613 | 166 s->frame_size = 0; |
2979 | 167 memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1); |
168 s->inbuf_ptr--; | |
1613 | 169 } else { |
170 uint8_t *p, *pend; | |
171 uint32_t header1; | |
172 int padding; | |
173 | |
174 memcpy(s->inbuf_ptr, buf_ptr, len); | |
175 /* check for header */ | |
176 p = s->inbuf_ptr - 3; | |
177 pend = s->inbuf_ptr + len - 4; | |
178 while (p <= pend) { | |
179 header = (p[0] << 24) | (p[1] << 16) | | |
180 (p[2] << 8) | p[3]; | |
181 header1 = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) | | |
182 (s->inbuf[2] << 8) | s->inbuf[3]; | |
183 /* check with high probability that we have a | |
184 valid header */ | |
185 if ((header & SAME_HEADER_MASK) == | |
186 (header1 & SAME_HEADER_MASK)) { | |
187 /* header found: update pointers */ | |
188 len = (p + 4) - s->inbuf_ptr; | |
189 buf_ptr += len; | |
190 buf_size -= len; | |
191 s->inbuf_ptr = p; | |
192 /* compute frame size */ | |
193 s->free_format_next_header = header; | |
194 s->free_format_frame_size = s->inbuf_ptr - s->inbuf; | |
195 padding = (header1 >> 9) & 1; | |
196 if (s->layer == 1) | |
197 s->free_format_frame_size -= padding * 4; | |
198 else | |
199 s->free_format_frame_size -= padding; | |
4652 | 200 dprintf(avctx, "free frame size=%d padding=%d\n", |
1613 | 201 s->free_format_frame_size, padding); |
5051 | 202 ff_mpegaudio_decode_header(s, header1); |
1613 | 203 goto next_data; |
204 } | |
205 p++; | |
206 } | |
207 /* not found: simply increase pointers */ | |
208 buf_ptr += len; | |
209 s->inbuf_ptr += len; | |
210 buf_size -= len; | |
211 } | |
2979 | 212 } else |
1613 | 213 #endif |
214 if (len < s->frame_size) { | |
215 if (s->frame_size > MPA_MAX_CODED_FRAME_SIZE) | |
216 s->frame_size = MPA_MAX_CODED_FRAME_SIZE; | |
3639
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
217 len = FFMIN(s->frame_size - len, buf_size); |
2979 | 218 memcpy(s->inbuf_ptr, buf_ptr, len); |
219 buf_ptr += len; | |
220 s->inbuf_ptr += len; | |
221 buf_size -= len; | |
222 } | |
3639
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
223 |
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
224 if(s->frame_size > 0 && buf_ptr - buf == s->inbuf_ptr - s->inbuf |
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
225 && buf_size + buf_ptr - buf >= s->frame_size){ |
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
226 if(s->header_count > 0){ |
4931
0d1cc37d9430
make some parser parameters const to avoid casting const to non-const
aurel
parents:
4914
diff
changeset
|
227 *poutbuf = buf; |
3639
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
228 *poutbuf_size = s->frame_size; |
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
229 } |
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
230 buf_ptr = buf + s->frame_size; |
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
231 s->inbuf_ptr = s->inbuf; |
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
232 s->frame_size = 0; |
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
233 break; |
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
234 } |
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
235 |
1613 | 236 // next_data: |
2967 | 237 if (s->frame_size > 0 && |
1613 | 238 (s->inbuf_ptr - s->inbuf) >= s->frame_size) { |
2470
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
239 if(s->header_count > 0){ |
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
240 *poutbuf = s->inbuf; |
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
241 *poutbuf_size = s->inbuf_ptr - s->inbuf; |
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
242 } |
2979 | 243 s->inbuf_ptr = s->inbuf; |
244 s->frame_size = 0; | |
245 break; | |
246 } | |
1613 | 247 } |
248 return buf_ptr - buf; | |
249 } | |
4397
acb9faabab8d
Allows the AC3 parser to read the frame size and codec parameters from E-AC3 streams,
gpoirier
parents:
4310
diff
changeset
|
250 |
acb9faabab8d
Allows the AC3 parser to read the frame size and codec parameters from E-AC3 streams,
gpoirier
parents:
4310
diff
changeset
|
251 |
1613 | 252 AVCodecParser mpegaudio_parser = { |
253 { CODEC_ID_MP2, CODEC_ID_MP3 }, | |
254 sizeof(MpegAudioParseContext), | |
255 mpegaudio_parse_init, | |
256 mpegaudio_parse, | |
257 NULL, | |
258 }; |