Mercurial > libavformat.hg
annotate mp3.c @ 5266:73615b247438 libavformat
Only read ID3v1 tag if ID3v2 isn't present or is empty.
This prevents the demuxer from exporting multiple semantically identical but
differently named tags.
Patch by Anton Khirnov, wyskas gmail
author | cehoyos |
---|---|
date | Mon, 05 Oct 2009 21:36:56 +0000 |
parents | 79be5a6fd62f |
children | fb4f4b61c8ce |
rev | line source |
---|---|
885 | 1 /* |
1415
3b00fb8ef8e4
replace coder/decoder file description in libavformat by muxer/demuxer
aurel
parents:
1358
diff
changeset
|
2 * MP3 muxer and demuxer |
4251
77e0c7511d41
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
4221
diff
changeset
|
3 * Copyright (c) 2003 Fabrice Bellard |
234 | 4 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1321
diff
changeset
|
5 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1321
diff
changeset
|
6 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1321
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
234 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1321
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
234 | 11 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1321
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
234 | 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 | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1321
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
896
edbe5c3717f9
Update licensing information: The FSF changed postal address.
diego
parents:
885
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
234 | 20 */ |
3286 | 21 |
3714 | 22 #include <strings.h> |
3286 | 23 #include "libavutil/avstring.h" |
234 | 24 #include "avformat.h" |
4221
55f448c99135
Factorise id3v2 header parsing from mp3.c to be shared
superdump
parents:
4206
diff
changeset
|
25 #include "id3v2.h" |
5016
eb6dd7717805
Move id3v2 parsing code from mp3.c to id3v2.h and id3v2.c.
diego
parents:
4900
diff
changeset
|
26 #include "id3v1.h" |
2097 | 27 |
5226 | 28 #if CONFIG_MP3_DEMUXER |
29 | |
30 #include "libavcodec/mpegaudio.h" | |
31 #include "libavcodec/mpegaudiodecheader.h" | |
32 | |
234 | 33 /* mp3 read */ |
1107 | 34 |
35 static int mp3_read_probe(AVProbeData *p) | |
36 { | |
2234
2bc002540a9b
kill uninitialised variable warning in mp3_read_probe()
mru
parents:
2231
diff
changeset
|
37 int max_frames, first_frames = 0; |
1433
dababce8f69e
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:
1415
diff
changeset
|
38 int fsize, frames, sample_rate; |
1308
866d43ed0a67
allow ffmpeg to read mp3s beginning with partial frames
gpoirier
parents:
1169
diff
changeset
|
39 uint32_t header; |
4254 | 40 uint8_t *buf, *buf0, *buf2, *end; |
1308
866d43ed0a67
allow ffmpeg to read mp3s beginning with partial frames
gpoirier
parents:
1169
diff
changeset
|
41 AVCodecContext avctx; |
1107 | 42 |
4254 | 43 buf0 = p->buf; |
44 if(ff_id3v2_match(buf0)) { | |
45 buf0 += ff_id3v2_tag_len(buf0); | |
46 } | |
1107 | 47 |
1308
866d43ed0a67
allow ffmpeg to read mp3s beginning with partial frames
gpoirier
parents:
1169
diff
changeset
|
48 max_frames = 0; |
4254 | 49 buf = buf0; |
4258
35c8abd32d93
Fix a read past end of buffer crash in the mp3 probe
alexc
parents:
4254
diff
changeset
|
50 end = p->buf + p->buf_size - sizeof(uint32_t); |
1308
866d43ed0a67
allow ffmpeg to read mp3s beginning with partial frames
gpoirier
parents:
1169
diff
changeset
|
51 |
2797 | 52 for(; buf < end; buf= buf2+1) { |
1308
866d43ed0a67
allow ffmpeg to read mp3s beginning with partial frames
gpoirier
parents:
1169
diff
changeset
|
53 buf2 = buf; |
1107 | 54 |
1312 | 55 for(frames = 0; buf2 < end; frames++) { |
2222 | 56 header = AV_RB32(buf2); |
4126
bfc790ab375f
Change mpeg audio parser so it only sets frame_size, channels and bit_rate
michael
parents:
3973
diff
changeset
|
57 fsize = ff_mpa_decode_header(&avctx, header, &sample_rate, &sample_rate, &sample_rate, &sample_rate); |
1308
866d43ed0a67
allow ffmpeg to read mp3s beginning with partial frames
gpoirier
parents:
1169
diff
changeset
|
58 if(fsize < 0) |
866d43ed0a67
allow ffmpeg to read mp3s beginning with partial frames
gpoirier
parents:
1169
diff
changeset
|
59 break; |
866d43ed0a67
allow ffmpeg to read mp3s beginning with partial frames
gpoirier
parents:
1169
diff
changeset
|
60 buf2 += fsize; |
866d43ed0a67
allow ffmpeg to read mp3s beginning with partial frames
gpoirier
parents:
1169
diff
changeset
|
61 } |
866d43ed0a67
allow ffmpeg to read mp3s beginning with partial frames
gpoirier
parents:
1169
diff
changeset
|
62 max_frames = FFMAX(max_frames, frames); |
4254 | 63 if(buf == buf0) |
1321
9eeb01383e30
reduce scores if the mp3 frames dont start from the begin of the file (fixes flv deteted as mp3 issues)
michael
parents:
1312
diff
changeset
|
64 first_frames= frames; |
1308
866d43ed0a67
allow ffmpeg to read mp3s beginning with partial frames
gpoirier
parents:
1169
diff
changeset
|
65 } |
5238
c872818a8e1f
Sync AC3 probe values with MP3 probe values, they have to avoid similar issues.
reimar
parents:
5236
diff
changeset
|
66 // keep this in sync with ac3 probe, both need to avoid |
c872818a8e1f
Sync AC3 probe values with MP3 probe values, they have to avoid similar issues.
reimar
parents:
5236
diff
changeset
|
67 // issues with MPEG-files! |
5186
cbaefd9135ac
Slighty tweak mp3 probe threshold to prevent probetest from complaining.
michael
parents:
5045
diff
changeset
|
68 if (first_frames>=4) return AVPROBE_SCORE_MAX/2+1; |
2798
51e0a502392f
return a slightly larger score if we find more than 500 valid mp3 frames in a row
michael
parents:
2797
diff
changeset
|
69 else if(max_frames>500)return AVPROBE_SCORE_MAX/2; |
4900 | 70 else if(max_frames>=4) return AVPROBE_SCORE_MAX/4; |
4383
0b688ff86d2f
Make the MP3 probe weakly claim all files with ID3v2 tags to fix regressions on
alexc
parents:
4358
diff
changeset
|
71 else if(buf0!=p->buf) return AVPROBE_SCORE_MAX/4-1; |
1321
9eeb01383e30
reduce scores if the mp3 frames dont start from the begin of the file (fixes flv deteted as mp3 issues)
michael
parents:
1312
diff
changeset
|
72 else if(max_frames>=1) return 1; |
1308
866d43ed0a67
allow ffmpeg to read mp3s beginning with partial frames
gpoirier
parents:
1169
diff
changeset
|
73 else return 0; |
4900 | 74 //mpegps_mp3_unrecognized_format.mpg has max_frames=3 |
1107 | 75 } |
76 | |
2662
08b1ac852321
add support for reading duration from Xing-tag in mp3 files
andoma
parents:
2622
diff
changeset
|
77 /** |
2667
e896ac505ec6
add support for reading duration from VBRI-tag in mp3 files
andoma
parents:
2664
diff
changeset
|
78 * Try to find Xing/Info/VBRI tags and compute duration from info therein |
2662
08b1ac852321
add support for reading duration from Xing-tag in mp3 files
andoma
parents:
2622
diff
changeset
|
79 */ |
4148
33f55d10246d
If we find a VBR tag at the beginning of the file don't attempt to
michael
parents:
4126
diff
changeset
|
80 static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) |
2662
08b1ac852321
add support for reading duration from Xing-tag in mp3 files
andoma
parents:
2622
diff
changeset
|
81 { |
2663
be889462edfc
cosmetical change of mp3_parse_xing() to prepare for upcoming VBRI tag support
andoma
parents:
2662
diff
changeset
|
82 uint32_t v, spf; |
be889462edfc
cosmetical change of mp3_parse_xing() to prepare for upcoming VBRI tag support
andoma
parents:
2662
diff
changeset
|
83 int frames = -1; /* Total number of frames in file */ |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3871
diff
changeset
|
84 const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}}; |
4274 | 85 MPADecodeHeader c; |
4148
33f55d10246d
If we find a VBR tag at the beginning of the file don't attempt to
michael
parents:
4126
diff
changeset
|
86 int vbrtag_size = 0; |
2662
08b1ac852321
add support for reading duration from Xing-tag in mp3 files
andoma
parents:
2622
diff
changeset
|
87 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
88 v = get_be32(s->pb); |
2703
2c2da3011d6e
make sure the mpeg audio header is valid before passing it to ff_mpegaudio_decode_header()
andoma
parents:
2667
diff
changeset
|
89 if(ff_mpa_check_header(v) < 0) |
4148
33f55d10246d
If we find a VBR tag at the beginning of the file don't attempt to
michael
parents:
4126
diff
changeset
|
90 return -1; |
2703
2c2da3011d6e
make sure the mpeg audio header is valid before passing it to ff_mpegaudio_decode_header()
andoma
parents:
2667
diff
changeset
|
91 |
4148
33f55d10246d
If we find a VBR tag at the beginning of the file don't attempt to
michael
parents:
4126
diff
changeset
|
92 if (ff_mpegaudio_decode_header(&c, v) == 0) |
33f55d10246d
If we find a VBR tag at the beginning of the file don't attempt to
michael
parents:
4126
diff
changeset
|
93 vbrtag_size = c.frame_size; |
2663
be889462edfc
cosmetical change of mp3_parse_xing() to prepare for upcoming VBRI tag support
andoma
parents:
2662
diff
changeset
|
94 if(c.layer != 3) |
4148
33f55d10246d
If we find a VBR tag at the beginning of the file don't attempt to
michael
parents:
4126
diff
changeset
|
95 return -1; |
2662
08b1ac852321
add support for reading duration from Xing-tag in mp3 files
andoma
parents:
2622
diff
changeset
|
96 |
2663
be889462edfc
cosmetical change of mp3_parse_xing() to prepare for upcoming VBRI tag support
andoma
parents:
2662
diff
changeset
|
97 /* Check for Xing / Info tag */ |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
98 url_fseek(s->pb, xing_offtbl[c.lsf == 1][c.nb_channels == 1], SEEK_CUR); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
99 v = get_be32(s->pb); |
2663
be889462edfc
cosmetical change of mp3_parse_xing() to prepare for upcoming VBRI tag support
andoma
parents:
2662
diff
changeset
|
100 if(v == MKBETAG('X', 'i', 'n', 'g') || v == MKBETAG('I', 'n', 'f', 'o')) { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
101 v = get_be32(s->pb); |
2664 | 102 if(v & 0x1) |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
103 frames = get_be32(s->pb); |
2663
be889462edfc
cosmetical change of mp3_parse_xing() to prepare for upcoming VBRI tag support
andoma
parents:
2662
diff
changeset
|
104 } |
2662
08b1ac852321
add support for reading duration from Xing-tag in mp3 files
andoma
parents:
2622
diff
changeset
|
105 |
2667
e896ac505ec6
add support for reading duration from VBRI-tag in mp3 files
andoma
parents:
2664
diff
changeset
|
106 /* Check for VBRI tag (always 32 bytes after end of mpegaudio header) */ |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
107 url_fseek(s->pb, base + 4 + 32, SEEK_SET); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
108 v = get_be32(s->pb); |
2667
e896ac505ec6
add support for reading duration from VBRI-tag in mp3 files
andoma
parents:
2664
diff
changeset
|
109 if(v == MKBETAG('V', 'B', 'R', 'I')) { |
e896ac505ec6
add support for reading duration from VBRI-tag in mp3 files
andoma
parents:
2664
diff
changeset
|
110 /* Check tag version */ |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
111 if(get_be16(s->pb) == 1) { |
2667
e896ac505ec6
add support for reading duration from VBRI-tag in mp3 files
andoma
parents:
2664
diff
changeset
|
112 /* skip delay, quality and total bytes */ |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
113 url_fseek(s->pb, 8, SEEK_CUR); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
114 frames = get_be32(s->pb); |
2667
e896ac505ec6
add support for reading duration from VBRI-tag in mp3 files
andoma
parents:
2664
diff
changeset
|
115 } |
e896ac505ec6
add support for reading duration from VBRI-tag in mp3 files
andoma
parents:
2664
diff
changeset
|
116 } |
e896ac505ec6
add support for reading duration from VBRI-tag in mp3 files
andoma
parents:
2664
diff
changeset
|
117 |
2663
be889462edfc
cosmetical change of mp3_parse_xing() to prepare for upcoming VBRI tag support
andoma
parents:
2662
diff
changeset
|
118 if(frames < 0) |
4148
33f55d10246d
If we find a VBR tag at the beginning of the file don't attempt to
michael
parents:
4126
diff
changeset
|
119 return -1; |
33f55d10246d
If we find a VBR tag at the beginning of the file don't attempt to
michael
parents:
4126
diff
changeset
|
120 |
33f55d10246d
If we find a VBR tag at the beginning of the file don't attempt to
michael
parents:
4126
diff
changeset
|
121 /* Skip the vbr tag frame */ |
33f55d10246d
If we find a VBR tag at the beginning of the file don't attempt to
michael
parents:
4126
diff
changeset
|
122 url_fseek(s->pb, base + vbrtag_size, SEEK_SET); |
2663
be889462edfc
cosmetical change of mp3_parse_xing() to prepare for upcoming VBRI tag support
andoma
parents:
2662
diff
changeset
|
123 |
be889462edfc
cosmetical change of mp3_parse_xing() to prepare for upcoming VBRI tag support
andoma
parents:
2662
diff
changeset
|
124 spf = c.lsf ? 576 : 1152; /* Samples per frame, layer 3 */ |
be889462edfc
cosmetical change of mp3_parse_xing() to prepare for upcoming VBRI tag support
andoma
parents:
2662
diff
changeset
|
125 st->duration = av_rescale_q(frames, (AVRational){spf, c.sample_rate}, |
be889462edfc
cosmetical change of mp3_parse_xing() to prepare for upcoming VBRI tag support
andoma
parents:
2662
diff
changeset
|
126 st->time_base); |
4148
33f55d10246d
If we find a VBR tag at the beginning of the file don't attempt to
michael
parents:
4126
diff
changeset
|
127 return 0; |
2662
08b1ac852321
add support for reading duration from Xing-tag in mp3 files
andoma
parents:
2622
diff
changeset
|
128 } |
08b1ac852321
add support for reading duration from Xing-tag in mp3 files
andoma
parents:
2622
diff
changeset
|
129 |
234 | 130 static int mp3_read_header(AVFormatContext *s, |
131 AVFormatParameters *ap) | |
132 { | |
133 AVStream *st; | |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3871
diff
changeset
|
134 int64_t off; |
234 | 135 |
136 st = av_new_stream(s, 0); | |
137 if (!st) | |
2273
7eb456c4ed8a
Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents:
2234
diff
changeset
|
138 return AVERROR(ENOMEM); |
234 | 139 |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
814
diff
changeset
|
140 st->codec->codec_type = CODEC_TYPE_AUDIO; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
814
diff
changeset
|
141 st->codec->codec_id = CODEC_ID_MP3; |
2023 | 142 st->need_parsing = AVSTREAM_PARSE_FULL; |
2622 | 143 st->start_time = 0; |
885 | 144 |
5045
9ed3c88ed9ba
Move id3v1/id3v2 handling code from mp3.c to id3v[12].c.
diego
parents:
5016
diff
changeset
|
145 ff_id3v2_read(s); |
5266
73615b247438
Only read ID3v1 tag if ID3v2 isn't present or is empty.
cehoyos
parents:
5265
diff
changeset
|
146 if (!av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX)) |
73615b247438
Only read ID3v1 tag if ID3v2 isn't present or is empty.
cehoyos
parents:
5265
diff
changeset
|
147 ff_id3v1_read(s); |
234 | 148 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
149 off = url_ftell(s->pb); |
4148
33f55d10246d
If we find a VBR tag at the beginning of the file don't attempt to
michael
parents:
4126
diff
changeset
|
150 if (mp3_parse_vbr_tags(s, st, off) < 0) |
33f55d10246d
If we find a VBR tag at the beginning of the file don't attempt to
michael
parents:
4126
diff
changeset
|
151 url_fseek(s->pb, off, SEEK_SET); |
2662
08b1ac852321
add support for reading duration from Xing-tag in mp3 files
andoma
parents:
2622
diff
changeset
|
152 |
234 | 153 /* the parameters will be extracted from the compressed bitstream */ |
154 return 0; | |
155 } | |
156 | |
157 #define MP3_PACKET_SIZE 1024 | |
158 | |
159 static int mp3_read_packet(AVFormatContext *s, AVPacket *pkt) | |
160 { | |
161 int ret, size; | |
162 // AVStream *st = s->streams[0]; | |
885 | 163 |
234 | 164 size= MP3_PACKET_SIZE; |
165 | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
166 ret= av_get_packet(s->pb, pkt, size); |
234 | 167 |
168 pkt->stream_index = 0; | |
169 if (ret <= 0) { | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
170 return AVERROR(EIO); |
234 | 171 } |
172 /* note: we need to modify the packet size here to handle the last | |
173 packet */ | |
174 pkt->size = ret; | |
175 return ret; | |
176 } | |
177 | |
5226 | 178 AVInputFormat mp3_demuxer = { |
179 "mp3", | |
180 NULL_IF_CONFIG_SMALL("MPEG audio layer 2/3"), | |
181 0, | |
182 mp3_read_probe, | |
183 mp3_read_header, | |
184 mp3_read_packet, | |
185 .flags= AVFMT_GENERIC_INDEX, | |
186 .extensions = "mp2,mp3,m2a", /* XXX: use probe */ | |
5265
79be5a6fd62f
id3v2: Export all text information frames with correct names.
ramiro
parents:
5264
diff
changeset
|
187 .metadata_conv = ff_id3v2_metadata_conv, |
5226 | 188 }; |
189 #endif | |
190 | |
4206 | 191 #if CONFIG_MP2_MUXER || CONFIG_MP3_MUXER |
4355 | 192 static int id3v1_set_string(AVFormatContext *s, const char *key, |
193 uint8_t *buf, int buf_size) | |
3561
bc473761b9e7
Move one function that is only used for muxing below #ifdef CONFIG_MUXERS.
diego
parents:
3540
diff
changeset
|
194 { |
4355 | 195 AVMetadataTag *tag; |
196 if ((tag = av_metadata_get(s->metadata, key, NULL, 0))) | |
197 strncpy(buf, tag->value, buf_size); | |
198 return !!tag; | |
199 } | |
200 | |
201 static int id3v1_create_tag(AVFormatContext *s, uint8_t *buf) | |
202 { | |
203 AVMetadataTag *tag; | |
204 int i, count = 0; | |
3561
bc473761b9e7
Move one function that is only used for muxing below #ifdef CONFIG_MUXERS.
diego
parents:
3540
diff
changeset
|
205 |
bc473761b9e7
Move one function that is only used for muxing below #ifdef CONFIG_MUXERS.
diego
parents:
3540
diff
changeset
|
206 memset(buf, 0, ID3v1_TAG_SIZE); /* fail safe */ |
bc473761b9e7
Move one function that is only used for muxing below #ifdef CONFIG_MUXERS.
diego
parents:
3540
diff
changeset
|
207 buf[0] = 'T'; |
bc473761b9e7
Move one function that is only used for muxing below #ifdef CONFIG_MUXERS.
diego
parents:
3540
diff
changeset
|
208 buf[1] = 'A'; |
bc473761b9e7
Move one function that is only used for muxing below #ifdef CONFIG_MUXERS.
diego
parents:
3540
diff
changeset
|
209 buf[2] = 'G'; |
4355 | 210 count += id3v1_set_string(s, "title", buf + 3, 30); |
211 count += id3v1_set_string(s, "author", buf + 33, 30); | |
212 count += id3v1_set_string(s, "album", buf + 63, 30); | |
213 count += id3v1_set_string(s, "year", buf + 93, 4); | |
214 count += id3v1_set_string(s, "comment", buf + 97, 30); | |
215 if ((tag = av_metadata_get(s->metadata, "track", NULL, 0))) { | |
216 buf[125] = 0; | |
217 buf[126] = atoi(tag->value); | |
218 count++; | |
3561
bc473761b9e7
Move one function that is only used for muxing below #ifdef CONFIG_MUXERS.
diego
parents:
3540
diff
changeset
|
219 } |
5198
7838e959a646
10l: set genre default immediately before reading genre tag
jbr
parents:
5197
diff
changeset
|
220 buf[127] = 0xFF; /* default to unknown genre */ |
4355 | 221 if ((tag = av_metadata_get(s->metadata, "genre", NULL, 0))) { |
4356 | 222 for(i = 0; i <= ID3v1_GENRE_MAX; i++) { |
5016
eb6dd7717805
Move id3v2 parsing code from mp3.c to id3v2.h and id3v2.c.
diego
parents:
4900
diff
changeset
|
223 if (!strcasecmp(tag->value, ff_id3v1_genre_str[i])) { |
4356 | 224 buf[127] = i; |
225 count++; | |
226 break; | |
227 } | |
3561
bc473761b9e7
Move one function that is only used for muxing below #ifdef CONFIG_MUXERS.
diego
parents:
3540
diff
changeset
|
228 } |
bc473761b9e7
Move one function that is only used for muxing below #ifdef CONFIG_MUXERS.
diego
parents:
3540
diff
changeset
|
229 } |
4355 | 230 return count; |
3561
bc473761b9e7
Move one function that is only used for muxing below #ifdef CONFIG_MUXERS.
diego
parents:
3540
diff
changeset
|
231 } |
bc473761b9e7
Move one function that is only used for muxing below #ifdef CONFIG_MUXERS.
diego
parents:
3540
diff
changeset
|
232 |
234 | 233 /* simple formats */ |
2098 | 234 |
235 static void id3v2_put_size(AVFormatContext *s, int size) | |
236 { | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
237 put_byte(s->pb, size >> 21 & 0x7f); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
238 put_byte(s->pb, size >> 14 & 0x7f); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
239 put_byte(s->pb, size >> 7 & 0x7f); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
240 put_byte(s->pb, size & 0x7f); |
2098 | 241 } |
242 | |
5264 | 243 static void id3v2_put_ttag(AVFormatContext *s, const char *buf, int len, |
244 uint32_t tag) | |
2098 | 245 { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
246 put_be32(s->pb, tag); |
2098 | 247 id3v2_put_size(s, len + 1); |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
248 put_be16(s->pb, 0); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
249 put_byte(s->pb, 3); /* UTF-8 */ |
5264 | 250 put_buffer(s->pb, buf, len); |
2098 | 251 } |
252 | |
253 | |
254 /** | |
255 * Write an ID3v2.4 header at beginning of stream | |
256 */ | |
257 | |
234 | 258 static int mp3_write_header(struct AVFormatContext *s) |
259 { | |
5264 | 260 AVMetadataTag *t = NULL; |
2098 | 261 int totlen = 0; |
5264 | 262 int64_t size_pos, cur_pos; |
2098 | 263 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
264 put_be32(s->pb, MKBETAG('I', 'D', '3', 0x04)); /* ID3v2.4 */ |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
265 put_byte(s->pb, 0); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
266 put_byte(s->pb, 0); /* flags */ |
2098 | 267 |
5264 | 268 /* reserve space for size */ |
269 size_pos = url_ftell(s->pb); | |
270 put_be32(s->pb, 0); | |
271 | |
272 while ((t = av_metadata_get(s->metadata, "", t, AV_METADATA_IGNORE_SUFFIX))) { | |
273 uint32_t tag = 0; | |
274 | |
275 if (t->key[0] == 'T' && strcmp(t->key, "TSSE")) { | |
276 int i; | |
277 for (i = 0; *ff_id3v2_tags[i]; i++) | |
278 if (AV_RB32(t->key) == AV_RB32(ff_id3v2_tags[i])) { | |
279 int len = strlen(t->value); | |
280 tag = AV_RB32(t->key); | |
281 totlen += len + ID3v2_HEADER_SIZE + 2; | |
282 id3v2_put_ttag(s, t->value, len + 1, tag); | |
283 break; | |
284 } | |
285 } | |
2098 | 286 |
5264 | 287 if (!tag) { /* unknown tag, write as TXXX frame */ |
288 int len = strlen(t->key), len1 = strlen(t->value); | |
289 char *buf = av_malloc(len + len1 + 2); | |
290 if (!buf) | |
291 return AVERROR(ENOMEM); | |
292 tag = MKBETAG('T', 'X', 'X', 'X'); | |
293 strcpy(buf, t->key); | |
294 strcpy(buf + len + 1, t->value); | |
295 id3v2_put_ttag(s, buf, len + len1 + 2, tag); | |
296 totlen += len + len1 + ID3v2_HEADER_SIZE + 3; | |
297 av_free(buf); | |
298 } | |
299 } | |
300 if(!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) { | |
301 totlen += strlen(LIBAVFORMAT_IDENT) + ID3v2_HEADER_SIZE + 2; | |
302 id3v2_put_ttag(s, LIBAVFORMAT_IDENT, strlen(LIBAVFORMAT_IDENT) + 1, | |
303 MKBETAG('T', 'S', 'S', 'E')); | |
304 } | |
305 | |
306 cur_pos = url_ftell(s->pb); | |
307 url_fseek(s->pb, size_pos, SEEK_SET); | |
308 id3v2_put_size(s, totlen); | |
309 url_fseek(s->pb, cur_pos, SEEK_SET); | |
310 | |
234 | 311 return 0; |
312 } | |
313 | |
468 | 314 static int mp3_write_packet(struct AVFormatContext *s, AVPacket *pkt) |
234 | 315 { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
316 put_buffer(s->pb, pkt->data, pkt->size); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
317 put_flush_packet(s->pb); |
234 | 318 return 0; |
319 } | |
320 | |
321 static int mp3_write_trailer(struct AVFormatContext *s) | |
322 { | |
2096 | 323 uint8_t buf[ID3v1_TAG_SIZE]; |
234 | 324 |
2096 | 325 /* write the id3v1 tag */ |
4355 | 326 if (id3v1_create_tag(s, buf) > 0) { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
327 put_buffer(s->pb, buf, ID3v1_TAG_SIZE); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
328 put_flush_packet(s->pb); |
234 | 329 } |
330 return 0; | |
331 } | |
4206 | 332 #endif /* CONFIG_MP2_MUXER || CONFIG_MP3_MUXER */ |
234 | 333 |
4206 | 334 #if CONFIG_MP2_MUXER |
1167 | 335 AVOutputFormat mp2_muxer = { |
234 | 336 "mp2", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3289
diff
changeset
|
337 NULL_IF_CONFIG_SMALL("MPEG audio layer 2"), |
234 | 338 "audio/x-mpeg", |
814 | 339 "mp2,m2a", |
234 | 340 0, |
341 CODEC_ID_MP2, | |
3289 | 342 CODEC_ID_NONE, |
2306
d045cbcf37a3
do not write id3v2 header when writing .mp2 files
bcoudurier
parents:
2274
diff
changeset
|
343 NULL, |
234 | 344 mp3_write_packet, |
345 mp3_write_trailer, | |
346 }; | |
1169 | 347 #endif |
4206 | 348 #if CONFIG_MP3_MUXER |
1167 | 349 AVOutputFormat mp3_muxer = { |
234 | 350 "mp3", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3289
diff
changeset
|
351 NULL_IF_CONFIG_SMALL("MPEG audio layer 3"), |
234 | 352 "audio/x-mpeg", |
353 "mp3", | |
354 0, | |
355 CODEC_ID_MP3, | |
3289 | 356 CODEC_ID_NONE, |
234 | 357 mp3_write_header, |
358 mp3_write_packet, | |
359 mp3_write_trailer, | |
5236
1403c88b1ce7
Add id3v2 metadata conversion table and use it in mp3 muxer.
cehoyos
parents:
5226
diff
changeset
|
360 .metadata_conv = ff_id3v2_metadata_conv, |
234 | 361 }; |
362 #endif |