History

mp3dec: move XING/Info and VBRI parsing into their own functions

Alessandro Ghedini committed 12 years ago

Commit fbd8e041 parent ae43c101 file · +58 −35Browse files

Unified · Split

libavformat/mp3dec.c+58−35
@@ -39,6 +39,9 @@ · 38 unmodified lines
3939
4040 typedef struct MP3DecContext {
4141 int xing_toc;
42+ unsigned frames; /* Total number of frames in file */
43+ unsigned size; /* Total number of bytes in the stream */
44+ int is_cbr;
4245 } MP3DecContext;
4346
4447 /* mp3 read */
@@ -125,18 +128,60 @@ static void read_xing_toc(AVFormatContext *s, int64_t filesize, int64_t duration · 80 unmodified lines
125128 mp3->xing_toc = 1;
126129 }
127130
131+
132+static void mp3_parse_info_tag(AVFormatContext *s, AVStream *st,
133+ MPADecodeHeader *c, uint32_t spf)
134+{
135+ uint32_t v;
136+ MP3DecContext *mp3 = s->priv_data;
137+ const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}};
138+
139+ /* Check for Xing / Info tag */
140+ avio_skip(s->pb, xing_offtbl[c->lsf == 1][c->nb_channels == 1]);
141+ v = avio_rb32(s->pb);
142+ mp3->is_cbr = v == MKBETAG('I', 'n', 'f', 'o');
143+ if (v == MKBETAG('X', 'i', 'n', 'g') || mp3->is_cbr) {
144+ v = avio_rb32(s->pb);
145+ if (v & XING_FLAG_FRAMES)
146+ mp3->frames = avio_rb32(s->pb);
147+ if (v & XING_FLAG_SIZE)
148+ mp3->size = avio_rb32(s->pb);
149+ if (v & XING_FLAG_TOC && mp3->frames)
150+ read_xing_toc(s, mp3->size,
151+ av_rescale_q(mp3->frames,
152+ (AVRational){spf, c->sample_rate},
153+ st->time_base));
154+ }
155+}
156+
157+static void mp3_parse_vbri_tag(AVFormatContext *s, AVStream *st, int64_t base)
158+{
159+ uint32_t v;
160+ MP3DecContext *mp3 = s->priv_data;
161+
162+ /* Check for VBRI tag (always 32 bytes after end of mpegaudio header) */
163+ avio_seek(s->pb, base + 4 + 32, SEEK_SET);
164+ v = avio_rb32(s->pb);
165+ if (v == MKBETAG('V', 'B', 'R', 'I')) {
166+ /* Check tag version */
167+ if (avio_rb16(s->pb) == 1) {
168+ /* skip delay and quality */
169+ avio_skip(s->pb, 4);
170+ mp3->size = avio_rb32(s->pb);
171+ mp3->frames = avio_rb32(s->pb);
172+ }
173+ }
174+}
175+
128176 /**
129177 * Try to find Xing/Info/VBRI tags and compute duration from info therein
130178 */
131179 static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base)
132180 {
133181 uint32_t v, spf;
134− unsigned frames = 0; /* Total number of frames in file */
135− unsigned size = 0; /* Total number of bytes in the stream */
136− const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}};
137182 MPADecodeHeader c;
138183 int vbrtag_size = 0;
139− int is_cbr;
184+ MP3DecContext *mp3 = s->priv_data;
140185
141186 v = avio_rb32(s->pb);
142187 if(ff_mpa_check_header(v) < 0)
@@ -149,45 +194,23 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) · 6 unmodified lines
149194
150195 spf = c.lsf ? 576 : 1152; /* Samples per frame, layer 3 */
151196
152− /* Check for Xing / Info tag */
153− avio_skip(s->pb, xing_offtbl[c.lsf == 1][c.nb_channels == 1]);
154− v = avio_rb32(s->pb);
155− is_cbr = v == MKBETAG('I', 'n', 'f', 'o');
156− if (v == MKBETAG('X', 'i', 'n', 'g') || is_cbr) {
157− v = avio_rb32(s->pb);
158− if(v & XING_FLAG_FRAMES)
159− frames = avio_rb32(s->pb);
160− if(v & XING_FLAG_SIZE)
161− size = avio_rb32(s->pb);
162− if (v & XING_FLAG_TOC && frames)
163− read_xing_toc(s, size, av_rescale_q(frames, (AVRational){spf, c.sample_rate},
164− st->time_base));
165− }
197+ mp3->frames = 0;
198+ mp3->size = 0;
166199
167− /* Check for VBRI tag (always 32 bytes after end of mpegaudio header) */
168− avio_seek(s->pb, base + 4 + 32, SEEK_SET);
169− v = avio_rb32(s->pb);
170− if(v == MKBETAG('V', 'B', 'R', 'I')) {
171− /* Check tag version */
172− if(avio_rb16(s->pb) == 1) {
173− /* skip delay and quality */
174− avio_skip(s->pb, 4);
175− size = avio_rb32(s->pb);
176− frames = avio_rb32(s->pb);
177− }
178− }
200+ mp3_parse_info_tag(s, st, &c, spf);
201+ mp3_parse_vbri_tag(s, st, base);
179202
180− if(!frames && !size)
203+ if (!mp3->frames && !mp3->size)
181204 return -1;
182205
183206 /* Skip the vbr tag frame */
184207 avio_seek(s->pb, base + vbrtag_size, SEEK_SET);
185208
186− if(frames)
187− st->duration = av_rescale_q(frames, (AVRational){spf, c.sample_rate},
209+ if (mp3->frames)
210+ st->duration = av_rescale_q(mp3->frames, (AVRational){spf, c.sample_rate},
188211 st->time_base);
189− if (size && frames && !is_cbr)
190− st->codec->bit_rate = av_rescale(size, 8 * c.sample_rate, frames * (int64_t)spf);
212+ if (mp3->size && mp3->frames && !mp3->is_cbr)
213+ st->codec->bit_rate = av_rescale(mp3->size, 8 * c.sample_rate, mp3->frames * (int64_t)spf);
191214
192215 return 0;
193216 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t