mp3.c 10.1 KB
Newer Older
1
/*
2
 * MP3 muxer and demuxer
3
 * Copyright (c) 2003 Fabrice Bellard
4
 *
5 6 7
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
8 9
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13 14 15 16 17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21

22
#include <strings.h>
23
#include "libavutil/avstring.h"
24
#include "libavutil/intreadwrite.h"
25
#include "avformat.h"
26
#include "id3v2.h"
27
#include "id3v1.h"
Andreas Öman's avatar
Andreas Öman committed
28

29 30 31 32 33
#if CONFIG_MP3_DEMUXER

#include "libavcodec/mpegaudio.h"
#include "libavcodec/mpegaudiodecheader.h"

34
/* mp3 read */
Måns Rullgård's avatar
Måns Rullgård committed
35 36 37

static int mp3_read_probe(AVProbeData *p)
{
38
    int max_frames, first_frames = 0;
39
    int fsize, frames, sample_rate;
40
    uint32_t header;
41
    uint8_t *buf, *buf0, *buf2, *end;
42
    AVCodecContext avctx;
Måns Rullgård's avatar
Måns Rullgård committed
43

44 45 46 47
    buf0 = p->buf;
    if(ff_id3v2_match(buf0)) {
        buf0 += ff_id3v2_tag_len(buf0);
    }
Måns Rullgård's avatar
Måns Rullgård committed
48

49
    max_frames = 0;
50
    buf = buf0;
51
    end = p->buf + p->buf_size - sizeof(uint32_t);
Måns Rullgård's avatar
Måns Rullgård committed
52

53
    for(; buf < end; buf= buf2+1) {
54
        buf2 = buf;
Måns Rullgård's avatar
Måns Rullgård committed
55

Michael Niedermayer's avatar
Michael Niedermayer committed
56
        for(frames = 0; buf2 < end; frames++) {
57
            header = AV_RB32(buf2);
58
            fsize = ff_mpa_decode_header(&avctx, header, &sample_rate, &sample_rate, &sample_rate, &sample_rate);
59 60 61 62 63
            if(fsize < 0)
                break;
            buf2 += fsize;
        }
        max_frames = FFMAX(max_frames, frames);
64
        if(buf == buf0)
65
            first_frames= frames;
66
    }
67 68
    // keep this in sync with ac3 probe, both need to avoid
    // issues with MPEG-files!
69
    if   (first_frames>=4) return AVPROBE_SCORE_MAX/2+1;
70
    else if(max_frames>500)return AVPROBE_SCORE_MAX/2;
71
    else if(max_frames>=4) return AVPROBE_SCORE_MAX/4;
72
    else if(buf0!=p->buf)  return AVPROBE_SCORE_MAX/4-1;
73
    else if(max_frames>=1) return 1;
74
    else                   return 0;
75
//mpegps_mp3_unrecognized_format.mpg has max_frames=3
Måns Rullgård's avatar
Måns Rullgård committed
76 77
}

78
/**
79
 * Try to find Xing/Info/VBRI tags and compute duration from info therein
80
 */
81
static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base)
82
{
83 84
    uint32_t v, spf;
    int frames = -1; /* Total number of frames in file */
85
    const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}};
86
    MPADecodeHeader c;
87
    int vbrtag_size = 0;
88

89
    v = get_be32(s->pb);
90
    if(ff_mpa_check_header(v) < 0)
91
      return -1;
92

93 94
    if (ff_mpegaudio_decode_header(&c, v) == 0)
        vbrtag_size = c.frame_size;
95
    if(c.layer != 3)
96
        return -1;
97

98
    /* Check for Xing / Info tag */
99 100
    url_fseek(s->pb, xing_offtbl[c.lsf == 1][c.nb_channels == 1], SEEK_CUR);
    v = get_be32(s->pb);
101
    if(v == MKBETAG('X', 'i', 'n', 'g') || v == MKBETAG('I', 'n', 'f', 'o')) {
102
        v = get_be32(s->pb);
Andreas Öman's avatar
Andreas Öman committed
103
        if(v & 0x1)
104
            frames = get_be32(s->pb);
105
    }
106

107
    /* Check for VBRI tag (always 32 bytes after end of mpegaudio header) */
108 109
    url_fseek(s->pb, base + 4 + 32, SEEK_SET);
    v = get_be32(s->pb);
110 111
    if(v == MKBETAG('V', 'B', 'R', 'I')) {
        /* Check tag version */
112
        if(get_be16(s->pb) == 1) {
113
            /* skip delay, quality and total bytes */
114 115
            url_fseek(s->pb, 8, SEEK_CUR);
            frames = get_be32(s->pb);
116 117 118
        }
    }

119
    if(frames < 0)
120 121 122 123
        return -1;

    /* Skip the vbr tag frame */
    url_fseek(s->pb, base + vbrtag_size, SEEK_SET);
124 125 126 127

    spf = c.lsf ? 576 : 1152; /* Samples per frame, layer 3 */
    st->duration = av_rescale_q(frames, (AVRational){spf, c.sample_rate},
                                st->time_base);
128
    return 0;
129 130
}

131 132 133 134
static int mp3_read_header(AVFormatContext *s,
                           AVFormatParameters *ap)
{
    AVStream *st;
135
    int64_t off;
136 137 138

    st = av_new_stream(s, 0);
    if (!st)
139
        return AVERROR(ENOMEM);
140

141 142
    st->codec->codec_type = CODEC_TYPE_AUDIO;
    st->codec->codec_id = CODEC_ID_MP3;
143
    st->need_parsing = AVSTREAM_PARSE_FULL;
144
    st->start_time = 0;
145

146 147 148
    // lcm of all mp3 sample rates
    av_set_pts_info(st, 64, 1, 14112000);

149
    ff_id3v2_read(s);
150 151
    if (!av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX))
        ff_id3v1_read(s);
152

153
    off = url_ftell(s->pb);
154 155
    if (mp3_parse_vbr_tags(s, st, off) < 0)
        url_fseek(s->pb, off, SEEK_SET);
156

157 158 159 160 161 162 163 164 165 166
    /* the parameters will be extracted from the compressed bitstream */
    return 0;
}

#define MP3_PACKET_SIZE 1024

static int mp3_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    int ret, size;
    //    AVStream *st = s->streams[0];
167

168 169
    size= MP3_PACKET_SIZE;

170
    ret= av_get_packet(s->pb, pkt, size);
171 172 173

    pkt->stream_index = 0;
    if (ret <= 0) {
174
        return AVERROR(EIO);
175 176 177 178 179 180 181
    }
    /* note: we need to modify the packet size here to handle the last
       packet */
    pkt->size = ret;
    return ret;
}

182 183 184 185 186 187 188 189 190
AVInputFormat mp3_demuxer = {
    "mp3",
    NULL_IF_CONFIG_SMALL("MPEG audio layer 2/3"),
    0,
    mp3_read_probe,
    mp3_read_header,
    mp3_read_packet,
    .flags= AVFMT_GENERIC_INDEX,
    .extensions = "mp2,mp3,m2a", /* XXX: use probe */
191
    .metadata_conv = ff_id3v2_metadata_conv,
192 193 194
};
#endif

195
#if CONFIG_MP2_MUXER || CONFIG_MP3_MUXER
196 197
static int id3v1_set_string(AVFormatContext *s, const char *key,
                            uint8_t *buf, int buf_size)
198
{
199 200 201 202 203 204 205 206 207 208
    AVMetadataTag *tag;
    if ((tag = av_metadata_get(s->metadata, key, NULL, 0)))
        strncpy(buf, tag->value, buf_size);
    return !!tag;
}

static int id3v1_create_tag(AVFormatContext *s, uint8_t *buf)
{
    AVMetadataTag *tag;
    int i, count = 0;
209 210 211 212 213

    memset(buf, 0, ID3v1_TAG_SIZE); /* fail safe */
    buf[0] = 'T';
    buf[1] = 'A';
    buf[2] = 'G';
214 215 216 217 218 219
    count += id3v1_set_string(s, "title",   buf +  3, 30);
    count += id3v1_set_string(s, "author",  buf + 33, 30);
    count += id3v1_set_string(s, "album",   buf + 63, 30);
    count += id3v1_set_string(s, "year",    buf + 93,  4);
    count += id3v1_set_string(s, "comment", buf + 97, 30);
    if ((tag = av_metadata_get(s->metadata, "track", NULL, 0))) {
220
        buf[125] = 0;
221 222
        buf[126] = atoi(tag->value);
        count++;
223
    }
224
    buf[127] = 0xFF; /* default to unknown genre */
225
    if ((tag = av_metadata_get(s->metadata, "genre", NULL, 0))) {
Aurelien Jacobs's avatar
Aurelien Jacobs committed
226
        for(i = 0; i <= ID3v1_GENRE_MAX; i++) {
227
            if (!strcasecmp(tag->value, ff_id3v1_genre_str[i])) {
Aurelien Jacobs's avatar
Aurelien Jacobs committed
228 229 230 231
                buf[127] = i;
                count++;
                break;
            }
232 233
        }
    }
234
    return count;
235 236
}

237
/* simple formats */
Andreas Öman's avatar
Andreas Öman committed
238 239 240

static void id3v2_put_size(AVFormatContext *s, int size)
{
241 242 243 244
    put_byte(s->pb, size >> 21 & 0x7f);
    put_byte(s->pb, size >> 14 & 0x7f);
    put_byte(s->pb, size >> 7  & 0x7f);
    put_byte(s->pb, size       & 0x7f);
Andreas Öman's avatar
Andreas Öman committed
245 246
}

247 248
static void id3v2_put_ttag(AVFormatContext *s, const char *buf, int len,
                           uint32_t tag)
Andreas Öman's avatar
Andreas Öman committed
249
{
250
    put_be32(s->pb, tag);
Andreas Öman's avatar
Andreas Öman committed
251
    id3v2_put_size(s, len + 1);
252 253
    put_be16(s->pb, 0);
    put_byte(s->pb, 3); /* UTF-8 */
254
    put_buffer(s->pb, buf, len);
Andreas Öman's avatar
Andreas Öman committed
255 256 257
}


258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
static int mp3_write_packet(struct AVFormatContext *s, AVPacket *pkt)
{
    put_buffer(s->pb, pkt->data, pkt->size);
    put_flush_packet(s->pb);
    return 0;
}

static int mp3_write_trailer(struct AVFormatContext *s)
{
    uint8_t buf[ID3v1_TAG_SIZE];

    /* write the id3v1 tag */
    if (id3v1_create_tag(s, buf) > 0) {
        put_buffer(s->pb, buf, ID3v1_TAG_SIZE);
        put_flush_packet(s->pb);
    }
    return 0;
}
#endif /* CONFIG_MP2_MUXER || CONFIG_MP3_MUXER */

#if CONFIG_MP2_MUXER
AVOutputFormat mp2_muxer = {
    "mp2",
    NULL_IF_CONFIG_SMALL("MPEG audio layer 2"),
    "audio/x-mpeg",
    "mp2,m2a",
    0,
    CODEC_ID_MP2,
    CODEC_ID_NONE,
    NULL,
    mp3_write_packet,
    mp3_write_trailer,
};
#endif

#if CONFIG_MP3_MUXER
Andreas Öman's avatar
Andreas Öman committed
294 295 296 297
/**
 * Write an ID3v2.4 header at beginning of stream
 */

298 299
static int mp3_write_header(struct AVFormatContext *s)
{
300
    AVMetadataTag *t = NULL;
Andreas Öman's avatar
Andreas Öman committed
301
    int totlen = 0;
302
    int64_t size_pos, cur_pos;
Andreas Öman's avatar
Andreas Öman committed
303

304 305 306
    put_be32(s->pb, MKBETAG('I', 'D', '3', 0x04)); /* ID3v2.4 */
    put_byte(s->pb, 0);
    put_byte(s->pb, 0); /* flags */
Andreas Öman's avatar
Andreas Öman committed
307

308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
    /* reserve space for size */
    size_pos = url_ftell(s->pb);
    put_be32(s->pb, 0);

    while ((t = av_metadata_get(s->metadata, "", t, AV_METADATA_IGNORE_SUFFIX))) {
        uint32_t tag = 0;

        if (t->key[0] == 'T' && strcmp(t->key, "TSSE")) {
            int i;
            for (i = 0; *ff_id3v2_tags[i]; i++)
                if (AV_RB32(t->key) == AV_RB32(ff_id3v2_tags[i])) {
                    int len = strlen(t->value);
                    tag = AV_RB32(t->key);
                    totlen += len + ID3v2_HEADER_SIZE + 2;
                    id3v2_put_ttag(s, t->value, len + 1, tag);
                    break;
                }
        }

        if (!tag) { /* unknown tag, write as TXXX frame */
            int   len = strlen(t->key), len1 = strlen(t->value);
            char *buf = av_malloc(len + len1 + 2);
            if (!buf)
                return AVERROR(ENOMEM);
            tag = MKBETAG('T', 'X', 'X', 'X');
            strcpy(buf,           t->key);
            strcpy(buf + len + 1, t->value);
            id3v2_put_ttag(s, buf, len + len1 + 2, tag);
            totlen += len + len1 + ID3v2_HEADER_SIZE + 3;
            av_free(buf);
        }
    }
    if(!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) {
        totlen += strlen(LIBAVFORMAT_IDENT) + ID3v2_HEADER_SIZE + 2;
        id3v2_put_ttag(s, LIBAVFORMAT_IDENT, strlen(LIBAVFORMAT_IDENT) + 1,
                       MKBETAG('T', 'S', 'S', 'E'));
    }

    cur_pos = url_ftell(s->pb);
    url_fseek(s->pb, size_pos, SEEK_SET);
Andreas Öman's avatar
Andreas Öman committed
348
    id3v2_put_size(s, totlen);
349
    url_fseek(s->pb, cur_pos, SEEK_SET);
Andreas Öman's avatar
Andreas Öman committed
350

351 352 353
    return 0;
}

354
AVOutputFormat mp3_muxer = {
355
    "mp3",
356
    NULL_IF_CONFIG_SMALL("MPEG audio layer 3"),
357 358 359 360
    "audio/x-mpeg",
    "mp3",
    0,
    CODEC_ID_MP3,
361
    CODEC_ID_NONE,
362 363 364
    mp3_write_header,
    mp3_write_packet,
    mp3_write_trailer,
365
    .metadata_conv = ff_id3v2_metadata_conv,
366 367
};
#endif