• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavformat/mp3.c

Go to the documentation of this file.
00001 /*
00002  * MP3 muxer and demuxer
00003  * Copyright (c) 2003 Fabrice Bellard
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00022 #include <strings.h>
00023 #include "libavutil/avstring.h"
00024 #include "libavutil/intreadwrite.h"
00025 #include "avformat.h"
00026 #include "id3v2.h"
00027 #include "id3v1.h"
00028 
00029 #if CONFIG_MP3_DEMUXER
00030 
00031 #include "libavcodec/mpegaudio.h"
00032 #include "libavcodec/mpegaudiodecheader.h"
00033 
00034 /* mp3 read */
00035 
00036 static int mp3_read_probe(AVProbeData *p)
00037 {
00038     int max_frames, first_frames = 0;
00039     int fsize, frames, sample_rate;
00040     uint32_t header;
00041     uint8_t *buf, *buf0, *buf2, *end;
00042     AVCodecContext avctx;
00043 
00044     buf0 = p->buf;
00045     if(ff_id3v2_match(buf0)) {
00046         buf0 += ff_id3v2_tag_len(buf0);
00047     }
00048     end = p->buf + p->buf_size - sizeof(uint32_t);
00049     while(buf0 < end && !*buf0)
00050         buf0++;
00051 
00052     max_frames = 0;
00053     buf = buf0;
00054 
00055     for(; buf < end; buf= buf2+1) {
00056         buf2 = buf;
00057 
00058         for(frames = 0; buf2 < end; frames++) {
00059             header = AV_RB32(buf2);
00060             fsize = ff_mpa_decode_header(&avctx, header, &sample_rate, &sample_rate, &sample_rate, &sample_rate);
00061             if(fsize < 0)
00062                 break;
00063             buf2 += fsize;
00064         }
00065         max_frames = FFMAX(max_frames, frames);
00066         if(buf == buf0)
00067             first_frames= frames;
00068     }
00069     // keep this in sync with ac3 probe, both need to avoid
00070     // issues with MPEG-files!
00071     if   (first_frames>=4) return AVPROBE_SCORE_MAX/2+1;
00072     else if(max_frames>500)return AVPROBE_SCORE_MAX/2;
00073     else if(max_frames>=4) return AVPROBE_SCORE_MAX/4;
00074     else if(buf0!=p->buf)  return AVPROBE_SCORE_MAX/4-1;
00075     else if(max_frames>=1) return 1;
00076     else                   return 0;
00077 //mpegps_mp3_unrecognized_format.mpg has max_frames=3
00078 }
00079 
00083 static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base)
00084 {
00085     uint32_t v, spf;
00086     int frames = -1; /* Total number of frames in file */
00087     const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}};
00088     MPADecodeHeader c;
00089     int vbrtag_size = 0;
00090 
00091     v = get_be32(s->pb);
00092     if(ff_mpa_check_header(v) < 0)
00093       return -1;
00094 
00095     if (ff_mpegaudio_decode_header(&c, v) == 0)
00096         vbrtag_size = c.frame_size;
00097     if(c.layer != 3)
00098         return -1;
00099 
00100     /* Check for Xing / Info tag */
00101     url_fseek(s->pb, xing_offtbl[c.lsf == 1][c.nb_channels == 1], SEEK_CUR);
00102     v = get_be32(s->pb);
00103     if(v == MKBETAG('X', 'i', 'n', 'g') || v == MKBETAG('I', 'n', 'f', 'o')) {
00104         v = get_be32(s->pb);
00105         if(v & 0x1)
00106             frames = get_be32(s->pb);
00107     }
00108 
00109     /* Check for VBRI tag (always 32 bytes after end of mpegaudio header) */
00110     url_fseek(s->pb, base + 4 + 32, SEEK_SET);
00111     v = get_be32(s->pb);
00112     if(v == MKBETAG('V', 'B', 'R', 'I')) {
00113         /* Check tag version */
00114         if(get_be16(s->pb) == 1) {
00115             /* skip delay, quality and total bytes */
00116             url_fseek(s->pb, 8, SEEK_CUR);
00117             frames = get_be32(s->pb);
00118         }
00119     }
00120 
00121     if(frames < 0)
00122         return -1;
00123 
00124     /* Skip the vbr tag frame */
00125     url_fseek(s->pb, base + vbrtag_size, SEEK_SET);
00126 
00127     spf = c.lsf ? 576 : 1152; /* Samples per frame, layer 3 */
00128     st->duration = av_rescale_q(frames, (AVRational){spf, c.sample_rate},
00129                                 st->time_base);
00130     return 0;
00131 }
00132 
00133 static int mp3_read_header(AVFormatContext *s,
00134                            AVFormatParameters *ap)
00135 {
00136     AVStream *st;
00137     int64_t off;
00138 
00139     st = av_new_stream(s, 0);
00140     if (!st)
00141         return AVERROR(ENOMEM);
00142 
00143     st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00144     st->codec->codec_id = CODEC_ID_MP3;
00145     st->need_parsing = AVSTREAM_PARSE_FULL;
00146     st->start_time = 0;
00147 
00148     // lcm of all mp3 sample rates
00149     av_set_pts_info(st, 64, 1, 14112000);
00150 
00151     ff_id3v2_read(s);
00152     off = url_ftell(s->pb);
00153 
00154     if (!av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX))
00155         ff_id3v1_read(s);
00156 
00157     if (mp3_parse_vbr_tags(s, st, off) < 0)
00158         url_fseek(s->pb, off, SEEK_SET);
00159 
00160     /* the parameters will be extracted from the compressed bitstream */
00161     return 0;
00162 }
00163 
00164 #define MP3_PACKET_SIZE 1024
00165 
00166 static int mp3_read_packet(AVFormatContext *s, AVPacket *pkt)
00167 {
00168     int ret, size;
00169     //    AVStream *st = s->streams[0];
00170 
00171     size= MP3_PACKET_SIZE;
00172 
00173     ret= av_get_packet(s->pb, pkt, size);
00174 
00175     pkt->stream_index = 0;
00176     if (ret <= 0) {
00177         return AVERROR(EIO);
00178     }
00179     /* note: we need to modify the packet size here to handle the last
00180        packet */
00181     pkt->size = ret;
00182     return ret;
00183 }
00184 
00185 AVInputFormat mp3_demuxer = {
00186     "mp3",
00187     NULL_IF_CONFIG_SMALL("MPEG audio layer 2/3"),
00188     0,
00189     mp3_read_probe,
00190     mp3_read_header,
00191     mp3_read_packet,
00192     .flags= AVFMT_GENERIC_INDEX,
00193     .extensions = "mp2,mp3,m2a", /* XXX: use probe */
00194     .metadata_conv = ff_id3v2_metadata_conv,
00195 };
00196 #endif
00197 
00198 #if CONFIG_MP2_MUXER || CONFIG_MP3_MUXER
00199 static int id3v1_set_string(AVFormatContext *s, const char *key,
00200                             uint8_t *buf, int buf_size)
00201 {
00202     AVMetadataTag *tag;
00203     if ((tag = av_metadata_get(s->metadata, key, NULL, 0)))
00204         strncpy(buf, tag->value, buf_size);
00205     return !!tag;
00206 }
00207 
00208 static int id3v1_create_tag(AVFormatContext *s, uint8_t *buf)
00209 {
00210     AVMetadataTag *tag;
00211     int i, count = 0;
00212 
00213     memset(buf, 0, ID3v1_TAG_SIZE); /* fail safe */
00214     buf[0] = 'T';
00215     buf[1] = 'A';
00216     buf[2] = 'G';
00217     count += id3v1_set_string(s, "title",   buf +  3, 30);
00218     count += id3v1_set_string(s, "author",  buf + 33, 30);
00219     count += id3v1_set_string(s, "album",   buf + 63, 30);
00220     count += id3v1_set_string(s, "date",    buf + 93,  4);
00221     count += id3v1_set_string(s, "comment", buf + 97, 30);
00222     if ((tag = av_metadata_get(s->metadata, "track", NULL, 0))) {
00223         buf[125] = 0;
00224         buf[126] = atoi(tag->value);
00225         count++;
00226     }
00227     buf[127] = 0xFF; /* default to unknown genre */
00228     if ((tag = av_metadata_get(s->metadata, "genre", NULL, 0))) {
00229         for(i = 0; i <= ID3v1_GENRE_MAX; i++) {
00230             if (!strcasecmp(tag->value, ff_id3v1_genre_str[i])) {
00231                 buf[127] = i;
00232                 count++;
00233                 break;
00234             }
00235         }
00236     }
00237     return count;
00238 }
00239 
00240 /* simple formats */
00241 
00242 static void id3v2_put_size(AVFormatContext *s, int size)
00243 {
00244     put_byte(s->pb, size >> 21 & 0x7f);
00245     put_byte(s->pb, size >> 14 & 0x7f);
00246     put_byte(s->pb, size >> 7  & 0x7f);
00247     put_byte(s->pb, size       & 0x7f);
00248 }
00249 
00250 static void id3v2_put_ttag(AVFormatContext *s, const char *buf, int len,
00251                            uint32_t tag)
00252 {
00253     put_be32(s->pb, tag);
00254     id3v2_put_size(s, len + 1);
00255     put_be16(s->pb, 0);
00256     put_byte(s->pb, 3); /* UTF-8 */
00257     put_buffer(s->pb, buf, len);
00258 }
00259 
00260 
00261 static int mp3_write_packet(struct AVFormatContext *s, AVPacket *pkt)
00262 {
00263     put_buffer(s->pb, pkt->data, pkt->size);
00264     put_flush_packet(s->pb);
00265     return 0;
00266 }
00267 
00268 static int mp3_write_trailer(struct AVFormatContext *s)
00269 {
00270     uint8_t buf[ID3v1_TAG_SIZE];
00271 
00272     /* write the id3v1 tag */
00273     if (id3v1_create_tag(s, buf) > 0) {
00274         put_buffer(s->pb, buf, ID3v1_TAG_SIZE);
00275         put_flush_packet(s->pb);
00276     }
00277     return 0;
00278 }
00279 #endif /* CONFIG_MP2_MUXER || CONFIG_MP3_MUXER */
00280 
00281 #if CONFIG_MP2_MUXER
00282 AVOutputFormat mp2_muxer = {
00283     "mp2",
00284     NULL_IF_CONFIG_SMALL("MPEG audio layer 2"),
00285     "audio/x-mpeg",
00286     "mp2,m2a",
00287     0,
00288     CODEC_ID_MP2,
00289     CODEC_ID_NONE,
00290     NULL,
00291     mp3_write_packet,
00292     mp3_write_trailer,
00293 };
00294 #endif
00295 
00296 #if CONFIG_MP3_MUXER
00297 
00301 static int mp3_write_header(struct AVFormatContext *s)
00302 {
00303     AVMetadataTag *t = NULL;
00304     int totlen = 0;
00305     int64_t size_pos, cur_pos;
00306 
00307     put_be32(s->pb, MKBETAG('I', 'D', '3', 0x04)); /* ID3v2.4 */
00308     put_byte(s->pb, 0);
00309     put_byte(s->pb, 0); /* flags */
00310 
00311     /* reserve space for size */
00312     size_pos = url_ftell(s->pb);
00313     put_be32(s->pb, 0);
00314 
00315     while ((t = av_metadata_get(s->metadata, "", t, AV_METADATA_IGNORE_SUFFIX))) {
00316         uint32_t tag = 0;
00317 
00318         if (t->key[0] == 'T' && strlen(t->key) == 4) {
00319             int i;
00320             for (i = 0; *ff_id3v2_tags[i]; i++)
00321                 if (AV_RB32(t->key) == AV_RB32(ff_id3v2_tags[i])) {
00322                     int len = strlen(t->value);
00323                     tag = AV_RB32(t->key);
00324                     totlen += len + ID3v2_HEADER_SIZE + 2;
00325                     id3v2_put_ttag(s, t->value, len + 1, tag);
00326                     break;
00327                 }
00328         }
00329 
00330         if (!tag) { /* unknown tag, write as TXXX frame */
00331             int   len = strlen(t->key), len1 = strlen(t->value);
00332             char *buf = av_malloc(len + len1 + 2);
00333             if (!buf)
00334                 return AVERROR(ENOMEM);
00335             tag = MKBETAG('T', 'X', 'X', 'X');
00336             strcpy(buf,           t->key);
00337             strcpy(buf + len + 1, t->value);
00338             id3v2_put_ttag(s, buf, len + len1 + 2, tag);
00339             totlen += len + len1 + ID3v2_HEADER_SIZE + 3;
00340             av_free(buf);
00341         }
00342     }
00343 
00344     cur_pos = url_ftell(s->pb);
00345     url_fseek(s->pb, size_pos, SEEK_SET);
00346     id3v2_put_size(s, totlen);
00347     url_fseek(s->pb, cur_pos, SEEK_SET);
00348 
00349     return 0;
00350 }
00351 
00352 AVOutputFormat mp3_muxer = {
00353     "mp3",
00354     NULL_IF_CONFIG_SMALL("MPEG audio layer 3"),
00355     "audio/x-mpeg",
00356     "mp3",
00357     0,
00358     CODEC_ID_MP3,
00359     CODEC_ID_NONE,
00360     mp3_write_header,
00361     mp3_write_packet,
00362     mp3_write_trailer,
00363     AVFMT_NOTIMESTAMPS,
00364     .metadata_conv = ff_id3v2_metadata_conv,
00365 };
00366 #endif

Generated on Fri Sep 16 2011 17:17:49 for FFmpeg by  doxygen 1.7.1