mp3.c 9.88 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);
    }
48 49 50
    end = p->buf + p->buf_size - sizeof(uint32_t);
    while(buf0 < end && !*buf0)
        buf0++;
Måns Rullgård's avatar
Måns Rullgård committed
51

52
    max_frames = 0;
53
    buf = buf0;
Måns Rullgård's avatar
Måns Rullgård committed
54

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

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

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

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

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

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

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

121
    if(frames < 0)
122 123 124 125
        return -1;

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

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

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

    st = av_new_stream(s, 0);
    if (!st)
141
        return AVERROR(ENOMEM);
142

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

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

151
    ff_id3v2_read(s);
152 153
    off = url_ftell(s->pb);

154 155
    if (!av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX))
        ff_id3v1_read(s);
156

157 158
    if (mp3_parse_vbr_tags(s, st, off) < 0)
        url_fseek(s->pb, off, SEEK_SET);
159

160 161 162 163 164 165 166 167 168 169
    /* 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];
170

171 172
    size= MP3_PACKET_SIZE;

173
    ret= av_get_packet(s->pb, pkt, size);
174 175 176

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

185 186 187 188 189 190 191 192 193
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 */
194
    .metadata_conv = ff_id3v2_metadata_conv,
195 196 197
};
#endif

198
#if CONFIG_MP2_MUXER || CONFIG_MP3_MUXER
199 200
static int id3v1_set_string(AVFormatContext *s, const char *key,
                            uint8_t *buf, int buf_size)
201
{
202 203 204 205 206 207 208 209 210 211
    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;
212 213 214 215 216

    memset(buf, 0, ID3v1_TAG_SIZE); /* fail safe */
    buf[0] = 'T';
    buf[1] = 'A';
    buf[2] = 'G';
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);
220
    count += id3v1_set_string(s, "date",    buf + 93,  4);
221 222
    count += id3v1_set_string(s, "comment", buf + 97, 30);
    if ((tag = av_metadata_get(s->metadata, "track", NULL, 0))) {
223
        buf[125] = 0;
224 225
        buf[126] = atoi(tag->value);
        count++;
226
    }
227
    buf[127] = 0xFF; /* default to unknown genre */
228
    if ((tag = av_metadata_get(s->metadata, "genre", NULL, 0))) {
Aurelien Jacobs's avatar
Aurelien Jacobs committed
229
        for(i = 0; i <= ID3v1_GENRE_MAX; i++) {
230
            if (!strcasecmp(tag->value, ff_id3v1_genre_str[i])) {
Aurelien Jacobs's avatar
Aurelien Jacobs committed
231 232 233 234
                buf[127] = i;
                count++;
                break;
            }
235 236
        }
    }
237
    return count;
238 239
}

240
/* simple formats */
Andreas Öman's avatar
Andreas Öman committed
241 242 243

static void id3v2_put_size(AVFormatContext *s, int size)
{
244 245 246 247
    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
248 249
}

250 251
static void id3v2_put_ttag(AVFormatContext *s, const char *buf, int len,
                           uint32_t tag)
Andreas Öman's avatar
Andreas Öman committed
252
{
253
    put_be32(s->pb, tag);
Andreas Öman's avatar
Andreas Öman committed
254
    id3v2_put_size(s, len + 1);
255 256
    put_be16(s->pb, 0);
    put_byte(s->pb, 3); /* UTF-8 */
257
    put_buffer(s->pb, buf, len);
Andreas Öman's avatar
Andreas Öman committed
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 294 295 296
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
297 298 299 300
/**
 * Write an ID3v2.4 header at beginning of stream
 */

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

307 308 309
    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
310

311 312 313 314 315 316 317
    /* 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;

318
        if (t->key[0] == 'T' && strlen(t->key) == 4) {
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
            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);
        }
    }

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

349 350 351
    return 0;
}

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