blob: 021cba4d5ccde8fbbc5bc34d372e3d27b7eb4599
1 | /* |
2 | * MPEG Audio parser |
3 | * Copyright (c) 2003 Fabrice Bellard |
4 | * Copyright (c) 2003 Michael Niedermayer |
5 | * |
6 | * This file is part of FFmpeg. |
7 | * |
8 | * FFmpeg is free software; you can redistribute it and/or |
9 | * modify it under the terms of the GNU Lesser General Public |
10 | * License as published by the Free Software Foundation; either |
11 | * version 2.1 of the License, or (at your option) any later version. |
12 | * |
13 | * FFmpeg is distributed in the hope that it will be useful, |
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 |
19 | * License along with FFmpeg; if not, write to the Free Software |
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
21 | */ |
22 | |
23 | #include "parser.h" |
24 | #include "mpegaudiodecheader.h" |
25 | #include "libavutil/common.h" |
26 | #include "libavformat/id3v1.h" // for ID3v1_TAG_SIZE |
27 | |
28 | typedef struct MpegAudioParseContext { |
29 | ParseContext pc; |
30 | int frame_size; |
31 | uint32_t header; |
32 | int header_count; |
33 | int no_bitrate; |
34 | } MpegAudioParseContext; |
35 | |
36 | #define MPA_HEADER_SIZE 4 |
37 | |
38 | /* header + layer + freq + lsf/mpeg25 */ |
39 | #define SAME_HEADER_MASK \ |
40 | (0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19)) |
41 | |
42 | static int mpegaudio_parse(AVCodecParserContext *s1, |
43 | AVCodecContext *avctx, |
44 | const uint8_t **poutbuf, int *poutbuf_size, |
45 | const uint8_t *buf, int buf_size) |
46 | { |
47 | MpegAudioParseContext *s = s1->priv_data; |
48 | ParseContext *pc = &s->pc; |
49 | uint32_t state= pc->state; |
50 | int i; |
51 | int next= END_NOT_FOUND; |
52 | int flush = !buf_size; |
53 | |
54 | for(i=0; i<buf_size; ){ |
55 | if(s->frame_size){ |
56 | int inc= FFMIN(buf_size - i, s->frame_size); |
57 | i += inc; |
58 | s->frame_size -= inc; |
59 | state = 0; |
60 | |
61 | if(!s->frame_size){ |
62 | next= i; |
63 | break; |
64 | } |
65 | }else{ |
66 | while(i<buf_size){ |
67 | int ret, sr, channels, bit_rate, frame_size; |
68 | enum AVCodecID codec_id = avctx->codec_id; |
69 | |
70 | state= (state<<8) + buf[i++]; |
71 | |
72 | ret = ff_mpa_decode_header(state, &sr, &channels, &frame_size, &bit_rate, &codec_id); |
73 | if (ret < 4) { |
74 | if (i > 4) |
75 | s->header_count = -2; |
76 | } else { |
77 | int header_threshold = avctx->codec_id != AV_CODEC_ID_NONE && avctx->codec_id != codec_id; |
78 | if((state&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header) |
79 | s->header_count= -3; |
80 | s->header= state; |
81 | s->header_count++; |
82 | s->frame_size = ret-4; |
83 | |
84 | if (s->header_count > header_threshold) { |
85 | avctx->sample_rate= sr; |
86 | avctx->channels = channels; |
87 | s1->duration = frame_size; |
88 | avctx->codec_id = codec_id; |
89 | if (s->no_bitrate || !avctx->bit_rate) { |
90 | s->no_bitrate = 1; |
91 | avctx->bit_rate += (bit_rate - avctx->bit_rate) / (s->header_count - header_threshold); |
92 | } |
93 | } |
94 | if (avctx->codec_id == AV_CODEC_ID_MP3 && codec_id == AV_CODEC_ID_MP2) { |
95 | avctx->codec_id = AV_CODEC_ID_MP2; |
96 | } |
97 | |
98 | if (s1->flags & PARSER_FLAG_COMPLETE_FRAMES) { |
99 | s->frame_size = 0; |
100 | next = buf_size; |
101 | } else if (codec_id == AV_CODEC_ID_MP3ADU) { |
102 | avpriv_report_missing_feature(avctx, |
103 | "MP3ADU full parser"); |
104 | return 0; /* parsers must not return error codes */ |
105 | } |
106 | |
107 | break; |
108 | } |
109 | } |
110 | } |
111 | } |
112 | |
113 | pc->state= state; |
114 | if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { |
115 | *poutbuf = NULL; |
116 | *poutbuf_size = 0; |
117 | return buf_size; |
118 | } |
119 | |
120 | if (flush && buf_size >= ID3v1_TAG_SIZE && memcmp(buf, "TAG", 3) == 0) { |
121 | *poutbuf = NULL; |
122 | *poutbuf_size = 0; |
123 | return next; |
124 | } |
125 | |
126 | *poutbuf = buf; |
127 | *poutbuf_size = buf_size; |
128 | return next; |
129 | } |
130 | |
131 | |
132 | AVCodecParser ff_mpegaudio_parser = { |
133 | .codec_ids = { AV_CODEC_ID_MP1, AV_CODEC_ID_MP2, AV_CODEC_ID_MP3, AV_CODEC_ID_MP3ADU }, |
134 | .priv_data_size = sizeof(MpegAudioParseContext), |
135 | .parser_parse = mpegaudio_parse, |
136 | .parser_close = ff_parse_close, |
137 | }; |
138 |