/src/ffmpeg/libavformat/mp3dec.c
Line | Count | Source |
1 | | /* |
2 | | * MP3 demuxer |
3 | | * Copyright (c) 2003 Fabrice Bellard |
4 | | * |
5 | | * This file is part of FFmpeg. |
6 | | * |
7 | | * FFmpeg is free software; you can redistribute it and/or |
8 | | * modify it under the terms of the GNU Lesser General Public |
9 | | * License as published by the Free Software Foundation; either |
10 | | * version 2.1 of the License, or (at your option) any later version. |
11 | | * |
12 | | * FFmpeg is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | | * Lesser General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU Lesser General Public |
18 | | * License along with FFmpeg; if not, write to the Free Software |
19 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 | | */ |
21 | | |
22 | | #include "libavutil/opt.h" |
23 | | #include "libavutil/intreadwrite.h" |
24 | | #include "libavutil/dict.h" |
25 | | #include "libavutil/mathematics.h" |
26 | | #include "avformat.h" |
27 | | #include "internal.h" |
28 | | #include "avio_internal.h" |
29 | | #include "demux.h" |
30 | | #include "id3v2.h" |
31 | | #include "id3v1.h" |
32 | | #include "replaygain.h" |
33 | | |
34 | | #include "libavcodec/codec_id.h" |
35 | | #include "libavcodec/mpegaudio.h" |
36 | | #include "libavcodec/mpegaudiodecheader.h" |
37 | | |
38 | 952 | #define XING_FLAG_FRAMES 0x01 |
39 | 952 | #define XING_FLAG_SIZE 0x02 |
40 | 952 | #define XING_FLAG_TOC 0x04 |
41 | 952 | #define XING_FLAC_QSCALE 0x08 |
42 | | |
43 | 32.3k | #define XING_TOC_COUNT 100 |
44 | | |
45 | | |
46 | | typedef struct { |
47 | | AVClass *class; |
48 | | int64_t filesize; |
49 | | int xing_toc; |
50 | | int start_pad; |
51 | | int end_pad; |
52 | | int usetoc; |
53 | | unsigned frames; /* Total number of frames in file */ |
54 | | unsigned header_filesize; /* Total number of bytes in the stream */ |
55 | | unsigned frame_duration; /* Frame duration in st->time_base */ |
56 | | int is_cbr; |
57 | | } MP3DecContext; |
58 | | |
59 | | enum CheckRet { |
60 | | CHECK_WRONG_HEADER = -1, |
61 | | CHECK_SEEK_FAILED = -2, |
62 | | }; |
63 | | |
64 | | static int check(AVIOContext *pb, int64_t pos, uint32_t *header); |
65 | | |
66 | | /* mp3 read */ |
67 | | |
68 | | static int mp3_read_probe(const AVProbeData *p) |
69 | 964k | { |
70 | 964k | int max_frames, first_frames = 0; |
71 | 964k | int whole_used = 0; |
72 | 964k | int frames, ret; |
73 | 964k | int framesizes, max_framesizes; |
74 | 964k | uint32_t header; |
75 | 964k | const uint8_t *buf, *buf0, *buf2, *buf3, *end; |
76 | | |
77 | 964k | buf0 = p->buf; |
78 | 964k | end = p->buf + p->buf_size - sizeof(uint32_t); |
79 | 2.57M | while (buf0 < end && !*buf0) |
80 | 1.60M | buf0++; |
81 | | |
82 | 964k | max_frames = 0; |
83 | 964k | max_framesizes = 0; |
84 | 964k | buf = buf0; |
85 | | |
86 | 2.29G | for (; buf < end; buf = buf2+1) { |
87 | 2.29G | buf2 = buf; |
88 | 2.30G | for (framesizes = frames = 0; buf2 < end; frames++) { |
89 | 2.30G | MPADecodeHeader h; |
90 | 2.30G | int header_emu = 0; |
91 | 2.30G | int available; |
92 | | |
93 | 2.30G | header = AV_RB32(buf2); |
94 | 2.30G | ret = avpriv_mpegaudio_decode_header(&h, header); |
95 | 2.30G | if (ret != 0) |
96 | 2.29G | break; |
97 | | |
98 | 8.25M | available = FFMIN(h.frame_size, end - buf2); |
99 | 1.73G | for (buf3 = buf2 + 4; buf3 < buf2 + available; buf3++) { |
100 | 1.72G | uint32_t next_sync = AV_RB32(buf3); |
101 | 1.72G | header_emu += (next_sync & MP3_MASK) == (header & MP3_MASK); |
102 | 1.72G | } |
103 | 8.25M | if (header_emu > 2) |
104 | 1.43M | break; |
105 | 6.82M | framesizes += h.frame_size; |
106 | 6.82M | if (available < h.frame_size) { |
107 | 664k | frames++; |
108 | 664k | break; |
109 | 664k | } |
110 | 6.15M | buf2 += h.frame_size; |
111 | 6.15M | } |
112 | 2.29G | max_frames = FFMAX(max_frames, frames); |
113 | 2.29G | max_framesizes = FFMAX(max_framesizes, framesizes); |
114 | 2.29G | if (buf == buf0) { |
115 | 904k | first_frames= frames; |
116 | 904k | if (buf2 == end + sizeof(uint32_t)) |
117 | 0 | whole_used = 1; |
118 | 904k | } |
119 | 2.29G | } |
120 | | // keep this in sync with ac3 probe, both need to avoid |
121 | | // issues with MPEG-files! |
122 | 964k | if (first_frames>=7) return AVPROBE_SCORE_EXTENSION + 1; |
123 | 964k | else if (max_frames>200 && p->buf_size < 2*max_framesizes)return AVPROBE_SCORE_EXTENSION; |
124 | 964k | else if (max_frames>=4 && p->buf_size < 2*max_framesizes) return AVPROBE_SCORE_EXTENSION / 2; |
125 | 963k | else if (ff_id3v2_match(buf0, ID3v2_DEFAULT_MAGIC) && 2*ff_id3v2_tag_len(buf0) >= p->buf_size) |
126 | 17.7k | return p->buf_size < PROBE_BUF_MAX ? AVPROBE_SCORE_EXTENSION / 4 : AVPROBE_SCORE_EXTENSION - 2; |
127 | 945k | else if (first_frames > 1 && whole_used) return 5; |
128 | 945k | else if (max_frames>=1 && p->buf_size < 10*max_framesizes) return 1; |
129 | 511k | else return 0; |
130 | | //mpegps_mp3_unrecognized_format.mpg has max_frames=3 |
131 | 964k | } |
132 | | |
133 | | static void read_xing_toc(AVFormatContext *s, int64_t filesize, int64_t duration) |
134 | 320 | { |
135 | 320 | int i; |
136 | 320 | MP3DecContext *mp3 = s->priv_data; |
137 | 320 | int fast_seek = s->flags & AVFMT_FLAG_FAST_SEEK; |
138 | 320 | int fill_index = (mp3->usetoc || fast_seek) && duration > 0; |
139 | | |
140 | 320 | if (!filesize && |
141 | 174 | (filesize = avio_size(s->pb)) <= 0) { |
142 | 132 | av_log(s, AV_LOG_WARNING, "Cannot determine file size, skipping TOC table.\n"); |
143 | 132 | fill_index = 0; |
144 | 132 | filesize = 0; |
145 | 132 | } |
146 | | |
147 | 32.3k | for (i = 0; i < XING_TOC_COUNT; i++) { |
148 | 32.0k | uint8_t b = avio_r8(s->pb); |
149 | 32.0k | if (fill_index) |
150 | 0 | av_add_index_entry(s->streams[0], |
151 | 0 | av_rescale(b, filesize, 256), |
152 | 0 | av_rescale(i, duration, XING_TOC_COUNT), |
153 | 0 | 0, 0, AVINDEX_KEYFRAME); |
154 | 32.0k | } |
155 | 320 | if (fill_index) |
156 | 0 | mp3->xing_toc = 1; |
157 | 320 | } |
158 | | |
159 | | static void mp3_parse_info_tag(AVFormatContext *s, AVStream *st, |
160 | | MPADecodeHeader *c, uint32_t spf) |
161 | 1.97k | { |
162 | 2.02k | #define LAST_BITS(k, n) ((k) & ((1 << (n)) - 1)) |
163 | 2.02k | #define MIDDLE_BITS(k, m, n) LAST_BITS((k) >> (m), ((n) - (m) + 1)) |
164 | | |
165 | 1.97k | FFStream *const sti = ffstream(st); |
166 | 1.97k | uint16_t crc; |
167 | 1.97k | uint32_t v; |
168 | | |
169 | 1.97k | char version[10]; |
170 | | |
171 | 1.97k | uint32_t peak = 0; |
172 | 1.97k | int32_t r_gain = INT32_MIN, a_gain = INT32_MIN; |
173 | | |
174 | 1.97k | MP3DecContext *mp3 = s->priv_data; |
175 | 1.97k | static const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}}; |
176 | 1.97k | uint64_t fsize = avio_size(s->pb); |
177 | 1.97k | int64_t pos = avio_tell(s->pb); |
178 | 1.97k | fsize = fsize >= pos ? fsize - pos : 0; |
179 | | |
180 | | /* Check for Xing / Info tag */ |
181 | 1.97k | avio_skip(s->pb, xing_offtbl[c->lsf == 1][c->nb_channels == 1]); |
182 | 1.97k | v = avio_rb32(s->pb); |
183 | 1.97k | mp3->is_cbr = v == MKBETAG('I', 'n', 'f', 'o'); |
184 | 1.97k | if (v != MKBETAG('X', 'i', 'n', 'g') && !mp3->is_cbr) |
185 | 1.02k | return; |
186 | | |
187 | 952 | v = avio_rb32(s->pb); |
188 | 952 | if (v & XING_FLAG_FRAMES) |
189 | 696 | mp3->frames = avio_rb32(s->pb); |
190 | 952 | if (v & XING_FLAG_SIZE) |
191 | 286 | mp3->header_filesize = avio_rb32(s->pb); |
192 | 952 | if (fsize && mp3->header_filesize) { |
193 | 211 | uint64_t min, delta; |
194 | 211 | min = FFMIN(fsize, mp3->header_filesize); |
195 | 211 | delta = FFMAX(fsize, mp3->header_filesize) - min; |
196 | 211 | if (fsize > mp3->header_filesize && delta > min >> 4) { |
197 | 152 | mp3->frames = 0; |
198 | 152 | av_log(s, AV_LOG_WARNING, |
199 | 152 | "invalid concatenated file detected - using bitrate for duration\n"); |
200 | 152 | } else if (delta > min >> 4) { |
201 | 52 | av_log(s, AV_LOG_WARNING, |
202 | 52 | "filesize and duration do not match (growing file?)\n"); |
203 | 52 | } |
204 | 211 | } |
205 | 952 | if (v & XING_FLAG_TOC) |
206 | 320 | read_xing_toc(s, mp3->header_filesize, av_rescale_q(mp3->frames, |
207 | 320 | (AVRational){spf, c->sample_rate}, |
208 | 320 | st->time_base)); |
209 | | /* VBR quality */ |
210 | 952 | if (v & XING_FLAC_QSCALE) |
211 | 358 | avio_rb32(s->pb); |
212 | | |
213 | | /* Encoder short version string */ |
214 | 952 | memset(version, 0, sizeof(version)); |
215 | 952 | avio_read(s->pb, version, 9); |
216 | | |
217 | | /* Info Tag revision + VBR method */ |
218 | 952 | avio_r8(s->pb); |
219 | | |
220 | | /* Lowpass filter value */ |
221 | 952 | avio_r8(s->pb); |
222 | | |
223 | | /* ReplayGain peak */ |
224 | 952 | v = avio_rb32(s->pb); |
225 | 952 | peak = av_rescale(v, 100000, 1 << 23); |
226 | | |
227 | | /* Radio ReplayGain */ |
228 | 952 | v = avio_rb16(s->pb); |
229 | | |
230 | 952 | if (MIDDLE_BITS(v, 13, 15) == 1) { |
231 | 42 | r_gain = MIDDLE_BITS(v, 0, 8) * 10000; |
232 | | |
233 | 42 | if (v & (1 << 9)) |
234 | 27 | r_gain *= -1; |
235 | 42 | } |
236 | | |
237 | | /* Audiophile ReplayGain */ |
238 | 952 | v = avio_rb16(s->pb); |
239 | | |
240 | 952 | if (MIDDLE_BITS(v, 13, 15) == 2) { |
241 | 75 | a_gain = MIDDLE_BITS(v, 0, 8) * 10000; |
242 | | |
243 | 75 | if (v & (1 << 9)) |
244 | 41 | a_gain *= -1; |
245 | 75 | } |
246 | | |
247 | | /* Encoding flags + ATH Type */ |
248 | 952 | avio_r8(s->pb); |
249 | | |
250 | | /* if ABR {specified bitrate} else {minimal bitrate} */ |
251 | 952 | avio_r8(s->pb); |
252 | | |
253 | | /* Encoder delays */ |
254 | 952 | v = avio_rb24(s->pb); |
255 | 952 | if (AV_RB32(version) == MKBETAG('L', 'A', 'M', 'E') |
256 | 682 | || AV_RB32(version) == MKBETAG('L', 'a', 'v', 'f') |
257 | 590 | || AV_RB32(version) == MKBETAG('L', 'a', 'v', 'c') |
258 | 952 | ) { |
259 | | |
260 | 366 | mp3->start_pad = v>>12; |
261 | 366 | mp3-> end_pad = v&4095; |
262 | 366 | sti->start_skip_samples = mp3->start_pad + 528 + 1; |
263 | 366 | if (mp3->frames) { |
264 | 356 | sti->first_discard_sample = -mp3->end_pad + 528 + 1 + mp3->frames * (int64_t)spf; |
265 | 356 | sti->last_discard_sample = mp3->frames * (int64_t)spf; |
266 | 356 | } |
267 | 366 | if (!st->start_time) |
268 | 366 | st->start_time = av_rescale_q(sti->start_skip_samples, |
269 | 366 | (AVRational){1, c->sample_rate}, |
270 | 366 | st->time_base); |
271 | 366 | av_log(s, AV_LOG_DEBUG, "pad %d %d\n", mp3->start_pad, mp3-> end_pad); |
272 | 366 | } |
273 | | |
274 | | /* Misc */ |
275 | 952 | avio_r8(s->pb); |
276 | | |
277 | | /* MP3 gain */ |
278 | 952 | avio_r8(s->pb); |
279 | | |
280 | | /* Preset and surround info */ |
281 | 952 | avio_rb16(s->pb); |
282 | | |
283 | | /* Music length */ |
284 | 952 | avio_rb32(s->pb); |
285 | | |
286 | | /* Music CRC */ |
287 | 952 | avio_rb16(s->pb); |
288 | | |
289 | | /* Info Tag CRC */ |
290 | 952 | crc = ffio_get_checksum(s->pb); |
291 | 952 | v = avio_rb16(s->pb); |
292 | | |
293 | 952 | if (v == crc) { |
294 | 15 | ff_replaygain_export_raw(st, r_gain, peak, a_gain, 0); |
295 | 15 | av_dict_set(&st->metadata, "encoder", version, 0); |
296 | 15 | } |
297 | 952 | } |
298 | | |
299 | | static void mp3_parse_vbri_tag(AVFormatContext *s, AVStream *st, int64_t base) |
300 | 1.97k | { |
301 | 1.97k | uint32_t v; |
302 | 1.97k | MP3DecContext *mp3 = s->priv_data; |
303 | | |
304 | | /* Check for VBRI tag (always 32 bytes after end of mpegaudio header) */ |
305 | 1.97k | avio_seek(s->pb, base + 4 + 32, SEEK_SET); |
306 | 1.97k | v = avio_rb32(s->pb); |
307 | 1.97k | if (v == MKBETAG('V', 'B', 'R', 'I')) { |
308 | | /* Check tag version */ |
309 | 132 | if (avio_rb16(s->pb) == 1) { |
310 | | /* skip delay and quality */ |
311 | 128 | avio_skip(s->pb, 4); |
312 | 128 | mp3->header_filesize = avio_rb32(s->pb); |
313 | 128 | mp3->frames = avio_rb32(s->pb); |
314 | 128 | } |
315 | 132 | } |
316 | 1.97k | } |
317 | | |
318 | | /** |
319 | | * Try to find Xing/Info/VBRI tags and compute duration from info therein |
320 | | */ |
321 | | static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) |
322 | 14.1k | { |
323 | 14.1k | uint32_t v, spf; |
324 | 14.1k | MPADecodeHeader c; |
325 | 14.1k | int vbrtag_size = 0; |
326 | 14.1k | MP3DecContext *mp3 = s->priv_data; |
327 | 14.1k | int ret; |
328 | | |
329 | 14.1k | ffio_init_checksum(s->pb, ff_crcA001_update, 0); |
330 | | |
331 | 14.1k | v = avio_rb32(s->pb); |
332 | | |
333 | 14.1k | ret = avpriv_mpegaudio_decode_header(&c, v); |
334 | 14.1k | if (ret < 0) |
335 | 11.9k | return ret; |
336 | 2.16k | else if (ret == 0) |
337 | 1.10k | vbrtag_size = c.frame_size; |
338 | 2.16k | if (c.layer != 3) |
339 | 186 | return -1; |
340 | | |
341 | 1.97k | spf = c.lsf ? 576 : 1152; /* Samples per frame, layer 3 */ |
342 | | |
343 | 1.97k | mp3->frames = 0; |
344 | 1.97k | mp3->header_filesize = 0; |
345 | 1.97k | mp3->frame_duration = av_rescale_q(spf, (AVRational){1, c.sample_rate}, st->time_base); |
346 | | |
347 | 1.97k | mp3_parse_info_tag(s, st, &c, spf); |
348 | 1.97k | mp3_parse_vbri_tag(s, st, base); |
349 | | |
350 | 1.97k | if (!mp3->frames && !mp3->header_filesize) |
351 | 1.05k | return -1; |
352 | | |
353 | | /* Skip the vbr tag frame */ |
354 | 924 | avio_seek(s->pb, base + vbrtag_size, SEEK_SET); |
355 | | |
356 | 924 | if (mp3->frames) { |
357 | 763 | int64_t full_duration_samples; |
358 | | |
359 | 763 | full_duration_samples = mp3->frames * (int64_t)spf; |
360 | 763 | st->duration = av_rescale_q(full_duration_samples - mp3->start_pad - mp3->end_pad, |
361 | 763 | (AVRational){1, c.sample_rate}, |
362 | 763 | st->time_base); |
363 | | |
364 | 763 | if (mp3->header_filesize && !mp3->is_cbr) |
365 | 145 | st->codecpar->bit_rate = av_rescale(mp3->header_filesize, 8 * c.sample_rate, |
366 | 145 | full_duration_samples); |
367 | 763 | } |
368 | | |
369 | 924 | return 0; |
370 | 1.97k | } |
371 | | |
372 | | static int mp3_read_header(AVFormatContext *s) |
373 | 14.1k | { |
374 | 14.1k | FFFormatContext *const si = ffformatcontext(s); |
375 | 14.1k | MP3DecContext *mp3 = s->priv_data; |
376 | 14.1k | AVStream *st; |
377 | 14.1k | FFStream *sti; |
378 | 14.1k | int64_t off; |
379 | 14.1k | int ret; |
380 | 14.1k | int i; |
381 | | |
382 | 14.1k | s->metadata = si->id3v2_meta; |
383 | 14.1k | si->id3v2_meta = NULL; |
384 | | |
385 | 14.1k | st = avformat_new_stream(s, NULL); |
386 | 14.1k | if (!st) |
387 | 0 | return AVERROR(ENOMEM); |
388 | 14.1k | sti = ffstream(st); |
389 | | |
390 | 14.1k | st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; |
391 | 14.1k | st->codecpar->codec_id = AV_CODEC_ID_MP3; |
392 | 14.1k | sti->need_parsing = AVSTREAM_PARSE_FULL_RAW; |
393 | 14.1k | st->start_time = 0; |
394 | | |
395 | | // lcm of all mp3 sample rates |
396 | 14.1k | avpriv_set_pts_info(st, 64, 1, 14112000); |
397 | | |
398 | 14.1k | ffiocontext(s->pb)->maxsize = -1; |
399 | 14.1k | off = avio_tell(s->pb); |
400 | | |
401 | 14.1k | if (!av_dict_count(s->metadata)) |
402 | 11.9k | ff_id3v1_read(s); |
403 | | |
404 | 14.1k | if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) |
405 | 4.33k | mp3->filesize = avio_size(s->pb); |
406 | | |
407 | 14.1k | if (mp3_parse_vbr_tags(s, st, off) < 0) |
408 | 13.2k | avio_seek(s->pb, off, SEEK_SET); |
409 | | |
410 | 14.1k | ret = ff_replaygain_export(st, s->metadata); |
411 | 14.1k | if (ret < 0) |
412 | 0 | return ret; |
413 | | |
414 | 14.1k | ret = ffio_ensure_seekback(s->pb, 64 * 1024 + MPA_MAX_CODED_FRAME_SIZE + 4); |
415 | 14.1k | if (ret < 0) |
416 | 0 | return ret; |
417 | | |
418 | 14.1k | off = avio_tell(s->pb); |
419 | 8.60M | for (i = 0; i < 64 * 1024; i++) { |
420 | 8.60M | uint32_t header, header2; |
421 | 8.60M | int frame_size; |
422 | 8.60M | frame_size = check(s->pb, off + i, &header); |
423 | 8.60M | if (frame_size > 0) { |
424 | 45.2k | ret = check(s->pb, off + i + frame_size, &header2); |
425 | 45.2k | if (ret >= 0 && (header & MP3_MASK) == (header2 & MP3_MASK)) |
426 | 2.18k | break; |
427 | 8.56M | } else if (frame_size == CHECK_SEEK_FAILED) { |
428 | 11.8k | av_log(s, AV_LOG_ERROR, "Failed to find two consecutive MPEG audio frames.\n"); |
429 | 11.8k | return AVERROR_INVALIDDATA; |
430 | 11.8k | } |
431 | 8.60M | } |
432 | 2.25k | if (i == 64 * 1024) { |
433 | 68 | off = avio_seek(s->pb, off, SEEK_SET); |
434 | 2.18k | } else { |
435 | 2.18k | av_log(s, i > 0 ? AV_LOG_INFO : AV_LOG_VERBOSE, "Skipping %d bytes of junk at %"PRId64".\n", i, off); |
436 | 2.18k | off = avio_seek(s->pb, off + i, SEEK_SET); |
437 | 2.18k | } |
438 | 2.25k | if (off < 0) |
439 | 3 | return off; |
440 | | |
441 | | // the seek index is relative to the end of the xing vbr headers |
442 | 2.25k | for (int i = 0; i < sti->nb_index_entries; i++) |
443 | 0 | sti->index_entries[i].pos += off; |
444 | | |
445 | | /* the parameters will be extracted from the compressed bitstream */ |
446 | 2.25k | return 0; |
447 | 2.25k | } |
448 | | |
449 | 43.3k | #define MP3_PACKET_SIZE 1024 |
450 | | |
451 | | static int mp3_read_packet(AVFormatContext *s, AVPacket *pkt) |
452 | 43.3k | { |
453 | 43.3k | MP3DecContext *mp3 = s->priv_data; |
454 | 43.3k | int ret, size; |
455 | 43.3k | int64_t pos; |
456 | | |
457 | 43.3k | size = MP3_PACKET_SIZE; |
458 | 43.3k | pos = avio_tell(s->pb); |
459 | 43.3k | if (mp3->filesize > ID3v1_TAG_SIZE && pos < mp3->filesize) |
460 | 10.0k | size= FFMIN(size, mp3->filesize - pos); |
461 | | |
462 | 43.3k | ret = av_get_packet(s->pb, pkt, size); |
463 | 43.3k | if (ret <= 0) { |
464 | 6.28k | if(ret<0) |
465 | 6.28k | return ret; |
466 | 0 | return AVERROR_EOF; |
467 | 6.28k | } |
468 | | |
469 | 37.0k | pkt->flags &= ~AV_PKT_FLAG_CORRUPT; |
470 | 37.0k | pkt->stream_index = 0; |
471 | | |
472 | 37.0k | return ret; |
473 | 43.3k | } |
474 | | |
475 | 0 | #define SEEK_WINDOW 4096 |
476 | | |
477 | | static int check(AVIOContext *pb, int64_t pos, uint32_t *ret_header) |
478 | 8.65M | { |
479 | 8.65M | int64_t ret = avio_seek(pb, pos, SEEK_SET); |
480 | 8.65M | uint8_t header_buf[4]; |
481 | 8.65M | unsigned header; |
482 | 8.65M | MPADecodeHeader sd; |
483 | 8.65M | if (ret < 0) |
484 | 6.45k | return CHECK_SEEK_FAILED; |
485 | | |
486 | 8.64M | ret = avio_read(pb, &header_buf[0], 4); |
487 | | /* We should always find four bytes for a valid mpa header. */ |
488 | 8.64M | if (ret < 4) |
489 | 12.0k | return CHECK_SEEK_FAILED; |
490 | | |
491 | 8.63M | header = AV_RB32(&header_buf[0]); |
492 | 8.63M | if (ff_mpa_check_header(header) < 0) |
493 | 8.55M | return CHECK_WRONG_HEADER; |
494 | 76.3k | if (avpriv_mpegaudio_decode_header(&sd, header) == 1) |
495 | 27.7k | return CHECK_WRONG_HEADER; |
496 | | |
497 | 48.6k | if (ret_header) |
498 | 48.6k | *ret_header = header; |
499 | 48.6k | return sd.frame_size; |
500 | 76.3k | } |
501 | | |
502 | | static int64_t mp3_sync(AVFormatContext *s, int64_t target_pos, int flags) |
503 | 0 | { |
504 | 0 | int dir = (flags&AVSEEK_FLAG_BACKWARD) ? -1 : 1; |
505 | 0 | int64_t best_pos; |
506 | 0 | int best_score, i, j; |
507 | 0 | int64_t ret; |
508 | |
|
509 | 0 | avio_seek(s->pb, FFMAX(target_pos - SEEK_WINDOW, 0), SEEK_SET); |
510 | 0 | ret = avio_seek(s->pb, target_pos, SEEK_SET); |
511 | 0 | if (ret < 0) |
512 | 0 | return ret; |
513 | | |
514 | 0 | #define MIN_VALID 3 |
515 | 0 | best_pos = target_pos; |
516 | 0 | best_score = 999; |
517 | 0 | for (i = 0; i < SEEK_WINDOW; i++) { |
518 | 0 | int64_t pos = target_pos + (dir > 0 ? i - SEEK_WINDOW/4 : -i); |
519 | 0 | int64_t candidate = -1; |
520 | 0 | int score = 999; |
521 | |
|
522 | 0 | if (pos < 0) |
523 | 0 | continue; |
524 | | |
525 | 0 | for (j = 0; j < MIN_VALID; j++) { |
526 | 0 | ret = check(s->pb, pos, NULL); |
527 | 0 | if (ret < 0) { |
528 | 0 | if (ret == CHECK_WRONG_HEADER) { |
529 | 0 | break; |
530 | 0 | } else if (ret == CHECK_SEEK_FAILED) { |
531 | 0 | av_log(s, AV_LOG_ERROR, "Could not seek to %"PRId64".\n", pos); |
532 | 0 | return AVERROR(EINVAL); |
533 | 0 | } |
534 | 0 | } |
535 | 0 | if ((target_pos - pos)*dir <= 0 && FFABS(MIN_VALID/2-j) < score) { |
536 | 0 | candidate = pos; |
537 | 0 | score = FFABS(MIN_VALID/2-j); |
538 | 0 | } |
539 | 0 | pos += ret; |
540 | 0 | } |
541 | 0 | if (best_score > score && j == MIN_VALID) { |
542 | 0 | best_pos = candidate; |
543 | 0 | best_score = score; |
544 | 0 | if(score == 0) |
545 | 0 | break; |
546 | 0 | } |
547 | 0 | } |
548 | | |
549 | 0 | return avio_seek(s->pb, best_pos, SEEK_SET); |
550 | 0 | } |
551 | | |
552 | | static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp, |
553 | | int flags) |
554 | 0 | { |
555 | 0 | FFFormatContext *const si = ffformatcontext(s); |
556 | 0 | MP3DecContext *mp3 = s->priv_data; |
557 | 0 | AVIndexEntry *ie, ie1; |
558 | 0 | AVStream *st = s->streams[0]; |
559 | 0 | FFStream *const sti = ffstream(st); |
560 | 0 | int64_t best_pos; |
561 | 0 | int fast_seek = s->flags & AVFMT_FLAG_FAST_SEEK; |
562 | 0 | int64_t filesize = mp3->header_filesize; |
563 | |
|
564 | 0 | if (filesize <= 0) { |
565 | 0 | int64_t size = avio_size(s->pb); |
566 | 0 | if (size > 0 && size > si->data_offset) |
567 | 0 | filesize = size - si->data_offset; |
568 | 0 | } |
569 | |
|
570 | 0 | if (mp3->xing_toc && (mp3->usetoc || (fast_seek && !mp3->is_cbr))) { |
571 | 0 | int64_t ret = av_index_search_timestamp(st, timestamp, flags); |
572 | | |
573 | | // NOTE: The MP3 TOC is not a precise lookup table. Accuracy is worse |
574 | | // for bigger files. |
575 | 0 | av_log(s, AV_LOG_WARNING, "Using MP3 TOC to seek; may be imprecise.\n"); |
576 | |
|
577 | 0 | if (ret < 0) |
578 | 0 | return ret; |
579 | | |
580 | 0 | ie = &sti->index_entries[ret]; |
581 | 0 | } else if (fast_seek && st->duration > 0 && filesize > 0) { |
582 | 0 | if (!mp3->is_cbr) |
583 | 0 | av_log(s, AV_LOG_WARNING, "Using scaling to seek VBR MP3; may be imprecise.\n"); |
584 | |
|
585 | 0 | ie = &ie1; |
586 | 0 | timestamp = av_clip64(timestamp, 0, st->duration); |
587 | 0 | ie->timestamp = timestamp; |
588 | 0 | ie->pos = av_rescale(timestamp, filesize, st->duration) + si->data_offset; |
589 | 0 | } else { |
590 | 0 | return -1; // generic index code |
591 | 0 | } |
592 | | |
593 | 0 | best_pos = mp3_sync(s, ie->pos, flags); |
594 | 0 | if (best_pos < 0) |
595 | 0 | return best_pos; |
596 | | |
597 | 0 | if (mp3->is_cbr && ie == &ie1 && mp3->frames && mp3->header_filesize > 0) { |
598 | 0 | ie1.timestamp = mp3->frame_duration * av_rescale(best_pos - si->data_offset, mp3->frames, mp3->header_filesize); |
599 | 0 | } |
600 | |
|
601 | 0 | avpriv_update_cur_dts(s, st, ie->timestamp); |
602 | 0 | return 0; |
603 | 0 | } |
604 | | |
605 | | static const AVOption options[] = { |
606 | | { "usetoc", "use table of contents", offsetof(MP3DecContext, usetoc), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM}, |
607 | | { NULL }, |
608 | | }; |
609 | | |
610 | | static const AVClass demuxer_class = { |
611 | | .class_name = "mp3", |
612 | | .item_name = av_default_item_name, |
613 | | .option = options, |
614 | | .version = LIBAVUTIL_VERSION_INT, |
615 | | .category = AV_CLASS_CATEGORY_DEMUXER, |
616 | | }; |
617 | | |
618 | | const FFInputFormat ff_mp3_demuxer = { |
619 | | .p.name = "mp3", |
620 | | .p.long_name = NULL_IF_CONFIG_SMALL("MP2/3 (MPEG audio layer 2/3)"), |
621 | | .p.flags = AVFMT_GENERIC_INDEX, |
622 | | .p.extensions = "mp2,mp3,m2a,mpa", /* XXX: use probe */ |
623 | | .p.priv_class = &demuxer_class, |
624 | | .p.mime_type = "audio/mpeg", |
625 | | .flags_internal = FF_INFMT_FLAG_ID3V2_AUTO, |
626 | | .read_probe = mp3_read_probe, |
627 | | .read_header = mp3_read_header, |
628 | | .read_packet = mp3_read_packet, |
629 | | .read_seek = mp3_seek, |
630 | | .priv_data_size = sizeof(MP3DecContext), |
631 | | }; |