Mercurial > libavformat.hg
annotate mp3.c @ 6260:5c17c20dd67a libavformat
In ogg muxer, use dyn buffer to compute crc of the page, fix muxing with pipe
when page buffer is bigger than default buffer size. Max page is 65k.
| author | bcoudurier |
|---|---|
| date | Wed, 14 Jul 2010 23:21:18 +0000 |
| parents | f7b036d62ba9 |
| children | 8f1439cf4dd0 |
| 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" |
|
5318
fb4f4b61c8ce
Add '#include "libavutil/intreadwrite.h"', necessary for AV_RB32.
diego
parents:
5266
diff
changeset
|
24 #include "libavutil/intreadwrite.h" |
| 234 | 25 #include "avformat.h" |
|
4221
55f448c99135
Factorise id3v2 header parsing from mp3.c to be shared
superdump
parents:
4206
diff
changeset
|
26 #include "id3v2.h" |
|
5016
eb6dd7717805
Move id3v2 parsing code from mp3.c to id3v2.h and id3v2.c.
diego
parents:
4900
diff
changeset
|
27 #include "id3v1.h" |
| 2097 | 28 |
| 5226 | 29 #if CONFIG_MP3_DEMUXER |
| 30 | |
| 31 #include "libavcodec/mpegaudio.h" | |
| 32 #include "libavcodec/mpegaudiodecheader.h" | |
| 33 | |
| 234 | 34 /* mp3 read */ |
| 1107 | 35 |
| 36 static int mp3_read_probe(AVProbeData *p) | |
| 37 { | |
|
2234
2bc002540a9b
kill uninitialised variable warning in mp3_read_probe()
mru
parents:
2231
diff
changeset
|
38 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
|
39 int fsize, frames, sample_rate; |
|
1308
866d43ed0a67
allow ffmpeg to read mp3s beginning with partial frames
gpoirier
parents:
1169
diff
changeset
|
40 uint32_t header; |
| 4254 | 41 uint8_t *buf, *buf0, *buf2, *end; |
|
1308
866d43ed0a67
allow ffmpeg to read mp3s beginning with partial frames
gpoirier
parents:
1169
diff
changeset
|
42 AVCodecContext avctx; |
| 1107 | 43 |
| 4254 | 44 buf0 = p->buf; |
|
6121
81614e9b541b
Generalize ID3v2 functions to support ID3v2-like ID headers with a
cehoyos
parents:
5965
diff
changeset
|
45 if(ff_id3v2_match(buf0, ID3v2_DEFAULT_MAGIC)) { |
| 4254 | 46 buf0 += ff_id3v2_tag_len(buf0); |
| 47 } | |
|
5727
74142991b333
Many mp3s seem to contain padding after id3 tags that is not considered in the
michael
parents:
5661
diff
changeset
|
48 end = p->buf + p->buf_size - sizeof(uint32_t); |
|
74142991b333
Many mp3s seem to contain padding after id3 tags that is not considered in the
michael
parents:
5661
diff
changeset
|
49 while(buf0 < end && !*buf0) |
|
74142991b333
Many mp3s seem to contain padding after id3 tags that is not considered in the
michael
parents:
5661
diff
changeset
|
50 buf0++; |
| 1107 | 51 |
|
1308
866d43ed0a67
allow ffmpeg to read mp3s beginning with partial frames
gpoirier
parents:
1169
diff
changeset
|
52 max_frames = 0; |
| 4254 | 53 buf = buf0; |
|
1308
866d43ed0a67
allow ffmpeg to read mp3s beginning with partial frames
gpoirier
parents:
1169
diff
changeset
|
54 |
| 2797 | 55 for(; buf < end; buf= buf2+1) { |
|
1308
866d43ed0a67
allow ffmpeg to read mp3s beginning with partial frames
gpoirier
parents:
1169
diff
changeset
|
56 buf2 = buf; |
| 1107 | 57 |
| 1312 | 58 for(frames = 0; buf2 < end; frames++) { |
| 2222 | 59 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
|
60 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
|
61 if(fsize < 0) |
|
866d43ed0a67
allow ffmpeg to read mp3s beginning with partial frames
gpoirier
parents:
1169
diff
changeset
|
62 break; |
|
866d43ed0a67
allow ffmpeg to read mp3s beginning with partial frames
gpoirier
parents:
1169
diff
changeset
|
63 buf2 += fsize; |
|
866d43ed0a67
allow ffmpeg to read mp3s beginning with partial frames
gpoirier
parents:
1169
diff
changeset
|
64 } |
|
866d43ed0a67
allow ffmpeg to read mp3s beginning with partial frames
gpoirier
parents:
1169
diff
changeset
|
65 max_frames = FFMAX(max_frames, frames); |
| 4254 | 66 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
|
67 first_frames= frames; |
|
1308
866d43ed0a67
allow ffmpeg to read mp3s beginning with partial frames
gpoirier
parents:
1169
diff
changeset
|
68 } |
|
5238
c872818a8e1f
Sync AC3 probe values with MP3 probe values, they have to avoid similar issues.
reimar
parents:
5236
diff
changeset
|
69 // 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
|
70 // issues with MPEG-files! |
|
5186
cbaefd9135ac
Slighty tweak mp3 probe threshold to prevent probetest from complaining.
michael
parents:
5045
diff
changeset
|
71 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
|
72 else if(max_frames>500)return AVPROBE_SCORE_MAX/2; |
| 4900 | 73 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
|
74 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
|
75 else if(max_frames>=1) return 1; |
|
1308
866d43ed0a67
allow ffmpeg to read mp3s beginning with partial frames
gpoirier
parents:
1169
diff
changeset
|
76 else return 0; |
| 4900 | 77 //mpegps_mp3_unrecognized_format.mpg has max_frames=3 |
| 1107 | 78 } |
| 79 | |
|
2662
08b1ac852321
add support for reading duration from Xing-tag in mp3 files
andoma
parents:
2622
diff
changeset
|
80 /** |
|
2667
e896ac505ec6
add support for reading duration from VBRI-tag in mp3 files
andoma
parents:
2664
diff
changeset
|
81 * 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
|
82 */ |
|
4148
33f55d10246d
If we find a VBR tag at the beginning of the file don't attempt to
michael
parents:
4126
diff
changeset
|
83 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
|
84 { |
|
2663
be889462edfc
cosmetical change of mp3_parse_xing() to prepare for upcoming VBRI tag support
andoma
parents:
2662
diff
changeset
|
85 uint32_t v, spf; |
|
be889462edfc
cosmetical change of mp3_parse_xing() to prepare for upcoming VBRI tag support
andoma
parents:
2662
diff
changeset
|
86 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
|
87 const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}}; |
| 4274 | 88 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
|
89 int vbrtag_size = 0; |
|
2662
08b1ac852321
add support for reading duration from Xing-tag in mp3 files
andoma
parents:
2622
diff
changeset
|
90 |
|
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
91 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
|
92 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
|
93 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
|
94 |
|
4148
33f55d10246d
If we find a VBR tag at the beginning of the file don't attempt to
michael
parents:
4126
diff
changeset
|
95 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
|
96 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
|
97 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
|
98 return -1; |
|
2662
08b1ac852321
add support for reading duration from Xing-tag in mp3 files
andoma
parents:
2622
diff
changeset
|
99 |
|
2663
be889462edfc
cosmetical change of mp3_parse_xing() to prepare for upcoming VBRI tag support
andoma
parents:
2662
diff
changeset
|
100 /* Check for Xing / Info tag */ |
|
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
101 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
|
102 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
|
103 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
|
104 v = get_be32(s->pb); |
| 2664 | 105 if(v & 0x1) |
|
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
106 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
|
107 } |
|
2662
08b1ac852321
add support for reading duration from Xing-tag in mp3 files
andoma
parents:
2622
diff
changeset
|
108 |
|
2667
e896ac505ec6
add support for reading duration from VBRI-tag in mp3 files
andoma
parents:
2664
diff
changeset
|
109 /* 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
|
110 url_fseek(s->pb, base + 4 + 32, SEEK_SET); |
|
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
111 v = get_be32(s->pb); |
|
2667
e896ac505ec6
add support for reading duration from VBRI-tag in mp3 files
andoma
parents:
2664
diff
changeset
|
112 if(v == MKBETAG('V', 'B', 'R', 'I')) { |
|
e896ac505ec6
add support for reading duration from VBRI-tag in mp3 files
andoma
parents:
2664
diff
changeset
|
113 /* Check tag version */ |
|
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
114 if(get_be16(s->pb) == 1) { |
|
2667
e896ac505ec6
add support for reading duration from VBRI-tag in mp3 files
andoma
parents:
2664
diff
changeset
|
115 /* skip delay, quality and total bytes */ |
|
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
116 url_fseek(s->pb, 8, SEEK_CUR); |
|
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
117 frames = get_be32(s->pb); |
|
2667
e896ac505ec6
add support for reading duration from VBRI-tag in mp3 files
andoma
parents:
2664
diff
changeset
|
118 } |
|
e896ac505ec6
add support for reading duration from VBRI-tag in mp3 files
andoma
parents:
2664
diff
changeset
|
119 } |
|
e896ac505ec6
add support for reading duration from VBRI-tag in mp3 files
andoma
parents:
2664
diff
changeset
|
120 |
|
2663
be889462edfc
cosmetical change of mp3_parse_xing() to prepare for upcoming VBRI tag support
andoma
parents:
2662
diff
changeset
|
121 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
|
122 return -1; |
|
33f55d10246d
If we find a VBR tag at the beginning of the file don't attempt to
michael
parents:
4126
diff
changeset
|
123 |
|
33f55d10246d
If we find a VBR tag at the beginning of the file don't attempt to
michael
parents:
4126
diff
changeset
|
124 /* 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
|
125 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
|
126 |
|
be889462edfc
cosmetical change of mp3_parse_xing() to prepare for upcoming VBRI tag support
andoma
parents:
2662
diff
changeset
|
127 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
|
128 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
|
129 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
|
130 return 0; |
|
2662
08b1ac852321
add support for reading duration from Xing-tag in mp3 files
andoma
parents:
2622
diff
changeset
|
131 } |
|
08b1ac852321
add support for reading duration from Xing-tag in mp3 files
andoma
parents:
2622
diff
changeset
|
132 |
| 234 | 133 static int mp3_read_header(AVFormatContext *s, |
| 134 AVFormatParameters *ap) | |
| 135 { | |
| 136 AVStream *st; | |
|
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3871
diff
changeset
|
137 int64_t off; |
| 234 | 138 |
| 139 st = av_new_stream(s, 0); | |
| 140 if (!st) | |
|
2273
7eb456c4ed8a
Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents:
2234
diff
changeset
|
141 return AVERROR(ENOMEM); |
| 234 | 142 |
|
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5727
diff
changeset
|
143 st->codec->codec_type = AVMEDIA_TYPE_AUDIO; |
|
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
814
diff
changeset
|
144 st->codec->codec_id = CODEC_ID_MP3; |
| 2023 | 145 st->need_parsing = AVSTREAM_PARSE_FULL; |
| 2622 | 146 st->start_time = 0; |
| 885 | 147 |
|
5380
7a06194c23af
set mp3 timebase to the lcm of all mp3 sample rates to fix frame duration
bcoudurier
parents:
5319
diff
changeset
|
148 // lcm of all mp3 sample rates |
|
7a06194c23af
set mp3 timebase to the lcm of all mp3 sample rates to fix frame duration
bcoudurier
parents:
5319
diff
changeset
|
149 av_set_pts_info(st, 64, 1, 14112000); |
|
7a06194c23af
set mp3 timebase to the lcm of all mp3 sample rates to fix frame duration
bcoudurier
parents:
5319
diff
changeset
|
150 |
|
6121
81614e9b541b
Generalize ID3v2 functions to support ID3v2-like ID headers with a
cehoyos
parents:
5965
diff
changeset
|
151 ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC); |
|
5641
980dc98901d9
mp3: ftell() file offset for VBR tags before ID3v1 parser messes it up.
andoma
parents:
5618
diff
changeset
|
152 off = url_ftell(s->pb); |
|
980dc98901d9
mp3: ftell() file offset for VBR tags before ID3v1 parser messes it up.
andoma
parents:
5618
diff
changeset
|
153 |
|
5266
73615b247438
Only read ID3v1 tag if ID3v2 isn't present or is empty.
cehoyos
parents:
5265
diff
changeset
|
154 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
|
155 ff_id3v1_read(s); |
| 234 | 156 |
|
4148
33f55d10246d
If we find a VBR tag at the beginning of the file don't attempt to
michael
parents:
4126
diff
changeset
|
157 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
|
158 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
|
159 |
| 234 | 160 /* the parameters will be extracted from the compressed bitstream */ |
| 161 return 0; | |
| 162 } | |
| 163 | |
| 164 #define MP3_PACKET_SIZE 1024 | |
| 165 | |
| 166 static int mp3_read_packet(AVFormatContext *s, AVPacket *pkt) | |
| 167 { | |
| 168 int ret, size; | |
| 169 // AVStream *st = s->streams[0]; | |
| 885 | 170 |
| 234 | 171 size= MP3_PACKET_SIZE; |
| 172 | |
|
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
173 ret= av_get_packet(s->pb, pkt, size); |
| 234 | 174 |
| 175 pkt->stream_index = 0; | |
| 176 if (ret <= 0) { | |
|
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
177 return AVERROR(EIO); |
| 234 | 178 } |
| 179 /* note: we need to modify the packet size here to handle the last | |
| 180 packet */ | |
| 181 pkt->size = ret; | |
| 182 return ret; | |
| 183 } | |
| 184 | |
| 5226 | 185 AVInputFormat mp3_demuxer = { |
| 186 "mp3", | |
| 187 NULL_IF_CONFIG_SMALL("MPEG audio layer 2/3"), | |
| 188 0, | |
| 189 mp3_read_probe, | |
| 190 mp3_read_header, | |
| 191 mp3_read_packet, | |
| 192 .flags= AVFMT_GENERIC_INDEX, | |
| 193 .extensions = "mp2,mp3,m2a", /* XXX: use probe */ | |
|
5265
79be5a6fd62f
id3v2: Export all text information frames with correct names.
ramiro
parents:
5264
diff
changeset
|
194 .metadata_conv = ff_id3v2_metadata_conv, |
| 5226 | 195 }; |
| 196 #endif | |
| 197 | |
| 4206 | 198 #if CONFIG_MP2_MUXER || CONFIG_MP3_MUXER |
| 4355 | 199 static int id3v1_set_string(AVFormatContext *s, const char *key, |
| 200 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
|
201 { |
| 4355 | 202 AVMetadataTag *tag; |
| 203 if ((tag = av_metadata_get(s->metadata, key, NULL, 0))) | |
| 204 strncpy(buf, tag->value, buf_size); | |
| 205 return !!tag; | |
| 206 } | |
| 207 | |
| 208 static int id3v1_create_tag(AVFormatContext *s, uint8_t *buf) | |
| 209 { | |
| 210 AVMetadataTag *tag; | |
| 211 int i, count = 0; | |
|
3561
bc473761b9e7
Move one function that is only used for muxing below #ifdef CONFIG_MUXERS.
diego
parents:
3540
diff
changeset
|
212 |
|
bc473761b9e7
Move one function that is only used for muxing below #ifdef CONFIG_MUXERS.
diego
parents:
3540
diff
changeset
|
213 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
|
214 buf[0] = 'T'; |
|
bc473761b9e7
Move one function that is only used for muxing below #ifdef CONFIG_MUXERS.
diego
parents:
3540
diff
changeset
|
215 buf[1] = 'A'; |
|
bc473761b9e7
Move one function that is only used for muxing below #ifdef CONFIG_MUXERS.
diego
parents:
3540
diff
changeset
|
216 buf[2] = 'G'; |
| 6250 | 217 count += id3v1_set_string(s, "TIT2", buf + 3, 30); //title |
| 218 count += id3v1_set_string(s, "TPE1", buf + 33, 30); //author|artist | |
| 219 count += id3v1_set_string(s, "TALB", buf + 63, 30); //album | |
| 220 count += id3v1_set_string(s, "TDRL", buf + 93, 4); //date | |
| 4355 | 221 count += id3v1_set_string(s, "comment", buf + 97, 30); |
| 6250 | 222 if ((tag = av_metadata_get(s->metadata, "TRCK", NULL, 0))) { //track |
| 4355 | 223 buf[125] = 0; |
| 224 buf[126] = atoi(tag->value); | |
| 225 count++; | |
|
3561
bc473761b9e7
Move one function that is only used for muxing below #ifdef CONFIG_MUXERS.
diego
parents:
3540
diff
changeset
|
226 } |
|
5198
7838e959a646
10l: set genre default immediately before reading genre tag
jbr
parents:
5197
diff
changeset
|
227 buf[127] = 0xFF; /* default to unknown genre */ |
| 6250 | 228 if ((tag = av_metadata_get(s->metadata, "TCON", NULL, 0))) { //genre |
| 4356 | 229 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
|
230 if (!strcasecmp(tag->value, ff_id3v1_genre_str[i])) { |
| 4356 | 231 buf[127] = i; |
| 232 count++; | |
| 233 break; | |
| 234 } | |
|
3561
bc473761b9e7
Move one function that is only used for muxing below #ifdef CONFIG_MUXERS.
diego
parents:
3540
diff
changeset
|
235 } |
|
bc473761b9e7
Move one function that is only used for muxing below #ifdef CONFIG_MUXERS.
diego
parents:
3540
diff
changeset
|
236 } |
| 4355 | 237 return count; |
|
3561
bc473761b9e7
Move one function that is only used for muxing below #ifdef CONFIG_MUXERS.
diego
parents:
3540
diff
changeset
|
238 } |
|
bc473761b9e7
Move one function that is only used for muxing below #ifdef CONFIG_MUXERS.
diego
parents:
3540
diff
changeset
|
239 |
| 234 | 240 /* simple formats */ |
| 2098 | 241 |
| 242 static void id3v2_put_size(AVFormatContext *s, int size) | |
| 243 { | |
|
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
244 put_byte(s->pb, size >> 21 & 0x7f); |
|
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
245 put_byte(s->pb, size >> 14 & 0x7f); |
|
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
246 put_byte(s->pb, size >> 7 & 0x7f); |
|
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
247 put_byte(s->pb, size & 0x7f); |
| 2098 | 248 } |
| 249 | |
| 5264 | 250 static void id3v2_put_ttag(AVFormatContext *s, const char *buf, int len, |
| 251 uint32_t tag) | |
| 2098 | 252 { |
|
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
253 put_be32(s->pb, tag); |
| 2098 | 254 id3v2_put_size(s, len + 1); |
|
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
255 put_be16(s->pb, 0); |
|
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
256 put_byte(s->pb, 3); /* UTF-8 */ |
| 5264 | 257 put_buffer(s->pb, buf, len); |
| 2098 | 258 } |
| 259 | |
| 260 | |
|
5319
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
261 static int mp3_write_packet(struct AVFormatContext *s, AVPacket *pkt) |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
262 { |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
263 put_buffer(s->pb, pkt->data, pkt->size); |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
264 put_flush_packet(s->pb); |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
265 return 0; |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
266 } |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
267 |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
268 static int mp3_write_trailer(struct AVFormatContext *s) |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
269 { |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
270 uint8_t buf[ID3v1_TAG_SIZE]; |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
271 |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
272 /* write the id3v1 tag */ |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
273 if (id3v1_create_tag(s, buf) > 0) { |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
274 put_buffer(s->pb, buf, ID3v1_TAG_SIZE); |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
275 put_flush_packet(s->pb); |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
276 } |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
277 return 0; |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
278 } |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
279 #endif /* CONFIG_MP2_MUXER || CONFIG_MP3_MUXER */ |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
280 |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
281 #if CONFIG_MP2_MUXER |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
282 AVOutputFormat mp2_muxer = { |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
283 "mp2", |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
284 NULL_IF_CONFIG_SMALL("MPEG audio layer 2"), |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
285 "audio/x-mpeg", |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
286 "mp2,m2a", |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
287 0, |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
288 CODEC_ID_MP2, |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
289 CODEC_ID_NONE, |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
290 NULL, |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
291 mp3_write_packet, |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
292 mp3_write_trailer, |
| 6250 | 293 .metadata_conv = ff_id3v2_metadata_conv, |
|
5319
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
294 }; |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
295 #endif |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
296 |
|
86c32a27f69a
Move function that is only used by the MP3 muxer below the corresponding #if.
diego
parents:
5318
diff
changeset
|
297 #if CONFIG_MP3_MUXER |
| 2098 | 298 /** |
| 299 * Write an ID3v2.4 header at beginning of stream | |
| 300 */ | |
| 301 | |
| 234 | 302 static int mp3_write_header(struct AVFormatContext *s) |
| 303 { | |
| 5264 | 304 AVMetadataTag *t = NULL; |
| 2098 | 305 int totlen = 0; |
| 5264 | 306 int64_t size_pos, cur_pos; |
| 2098 | 307 |
|
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
308 put_be32(s->pb, MKBETAG('I', 'D', '3', 0x04)); /* ID3v2.4 */ |
|
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
309 put_byte(s->pb, 0); |
|
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2746
diff
changeset
|
310 put_byte(s->pb, 0); /* flags */ |
| 2098 | 311 |
| 5264 | 312 /* reserve space for size */ |
| 313 size_pos = url_ftell(s->pb); | |
| 314 put_be32(s->pb, 0); | |
| 315 | |
| 316 while ((t = av_metadata_get(s->metadata, "", t, AV_METADATA_IGNORE_SUFFIX))) { | |
| 317 uint32_t tag = 0; | |
| 318 | |
|
5661
6d530eb42996
Set lavf identification string globally in av_write_header(), rather
rbultje
parents:
5641
diff
changeset
|
319 if (t->key[0] == 'T' && strlen(t->key) == 4) { |
| 5264 | 320 int i; |
| 321 for (i = 0; *ff_id3v2_tags[i]; i++) | |
| 322 if (AV_RB32(t->key) == AV_RB32(ff_id3v2_tags[i])) { | |
| 323 int len = strlen(t->value); | |
| 324 tag = AV_RB32(t->key); | |
| 325 totlen += len + ID3v2_HEADER_SIZE + 2; | |
| 326 id3v2_put_ttag(s, t->value, len + 1, tag); | |
| 327 break; | |
| 328 } | |
| 329 } | |
| 2098 | 330 |
| 5264 | 331 if (!tag) { /* unknown tag, write as TXXX frame */ |
| 332 int len = strlen(t->key), len1 = strlen(t->value); | |
| 333 char *buf = av_malloc(len + len1 + 2); | |
| 334 if (!buf) | |
| 335 return AVERROR(ENOMEM); | |
| 336 tag = MKBETAG('T', 'X', 'X', 'X'); | |
| 337 strcpy(buf, t->key); | |
| 338 strcpy(buf + len + 1, t->value); | |
| 339 id3v2_put_ttag(s, buf, len + len1 + 2, tag); | |
| 340 totlen += len + len1 + ID3v2_HEADER_SIZE + 3; | |
| 341 av_free(buf); | |
| 342 } | |
| 343 } | |
| 344 | |
| 345 cur_pos = url_ftell(s->pb); | |
| 346 url_fseek(s->pb, size_pos, SEEK_SET); | |
| 347 id3v2_put_size(s, totlen); | |
| 348 url_fseek(s->pb, cur_pos, SEEK_SET); | |
| 349 | |
| 234 | 350 return 0; |
| 351 } | |
| 352 | |
| 1167 | 353 AVOutputFormat mp3_muxer = { |
| 234 | 354 "mp3", |
|
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3289
diff
changeset
|
355 NULL_IF_CONFIG_SMALL("MPEG audio layer 3"), |
| 234 | 356 "audio/x-mpeg", |
| 357 "mp3", | |
| 358 0, | |
| 359 CODEC_ID_MP3, | |
| 3289 | 360 CODEC_ID_NONE, |
| 234 | 361 mp3_write_header, |
| 362 mp3_write_packet, | |
| 363 mp3_write_trailer, | |
| 5965 | 364 AVFMT_NOTIMESTAMPS, |
|
5236
1403c88b1ce7
Add id3v2 metadata conversion table and use it in mp3 muxer.
cehoyos
parents:
5226
diff
changeset
|
365 .metadata_conv = ff_id3v2_metadata_conv, |
| 234 | 366 }; |
| 367 #endif |
