mp3.c 17.7 KB
Newer Older
1
/*
2
 * MP3 muxer and demuxer
3 4
 * Copyright (c) 2003 Fabrice Bellard.
 *
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 23 24

#include "libavutil/avstring.h"
#include "libavcodec/mpegaudio.h"
#include "libavcodec/mpegaudiodecheader.h"
25 26
#include "avformat.h"

Andreas Öman's avatar
Andreas Öman committed
27 28
#define ID3v2_HEADER_SIZE 10
#define ID3v1_TAG_SIZE 128
29

Andreas Öman's avatar
Andreas Öman committed
30
#define ID3v1_GENRE_MAX 125
31

Andreas Öman's avatar
Andreas Öman committed
32
static const char *id3v1_genre_str[ID3v1_GENRE_MAX + 1] = {
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
    [0] = "Blues",
    [1] = "Classic Rock",
    [2] = "Country",
    [3] = "Dance",
    [4] = "Disco",
    [5] = "Funk",
    [6] = "Grunge",
    [7] = "Hip-Hop",
    [8] = "Jazz",
    [9] = "Metal",
    [10] = "New Age",
    [11] = "Oldies",
    [12] = "Other",
    [13] = "Pop",
    [14] = "R&B",
    [15] = "Rap",
    [16] = "Reggae",
    [17] = "Rock",
    [18] = "Techno",
    [19] = "Industrial",
    [20] = "Alternative",
    [21] = "Ska",
    [22] = "Death Metal",
    [23] = "Pranks",
    [24] = "Soundtrack",
    [25] = "Euro-Techno",
    [26] = "Ambient",
    [27] = "Trip-Hop",
    [28] = "Vocal",
    [29] = "Jazz+Funk",
    [30] = "Fusion",
    [31] = "Trance",
    [32] = "Classical",
    [33] = "Instrumental",
    [34] = "Acid",
    [35] = "House",
    [36] = "Game",
    [37] = "Sound Clip",
    [38] = "Gospel",
    [39] = "Noise",
    [40] = "AlternRock",
    [41] = "Bass",
    [42] = "Soul",
    [43] = "Punk",
    [44] = "Space",
    [45] = "Meditative",
    [46] = "Instrumental Pop",
    [47] = "Instrumental Rock",
    [48] = "Ethnic",
    [49] = "Gothic",
    [50] = "Darkwave",
    [51] = "Techno-Industrial",
    [52] = "Electronic",
    [53] = "Pop-Folk",
    [54] = "Eurodance",
    [55] = "Dream",
    [56] = "Southern Rock",
    [57] = "Comedy",
    [58] = "Cult",
    [59] = "Gangsta",
    [60] = "Top 40",
    [61] = "Christian Rap",
    [62] = "Pop/Funk",
    [63] = "Jungle",
    [64] = "Native American",
    [65] = "Cabaret",
    [66] = "New Wave",
    [67] = "Psychadelic",
    [68] = "Rave",
    [69] = "Showtunes",
    [70] = "Trailer",
    [71] = "Lo-Fi",
    [72] = "Tribal",
    [73] = "Acid Punk",
    [74] = "Acid Jazz",
    [75] = "Polka",
    [76] = "Retro",
    [77] = "Musical",
    [78] = "Rock & Roll",
    [79] = "Hard Rock",
    [80] = "Folk",
    [81] = "Folk-Rock",
    [82] = "National Folk",
    [83] = "Swing",
    [84] = "Fast Fusion",
    [85] = "Bebob",
    [86] = "Latin",
    [87] = "Revival",
    [88] = "Celtic",
    [89] = "Bluegrass",
    [90] = "Avantgarde",
    [91] = "Gothic Rock",
    [92] = "Progressive Rock",
    [93] = "Psychedelic Rock",
    [94] = "Symphonic Rock",
    [95] = "Slow Rock",
    [96] = "Big Band",
    [97] = "Chorus",
    [98] = "Easy Listening",
    [99] = "Acoustic",
    [100] = "Humour",
    [101] = "Speech",
    [102] = "Chanson",
    [103] = "Opera",
    [104] = "Chamber Music",
    [105] = "Sonata",
    [106] = "Symphony",
    [107] = "Booty Bass",
    [108] = "Primus",
    [109] = "Porn Groove",
    [110] = "Satire",
    [111] = "Slow Jam",
    [112] = "Club",
    [113] = "Tango",
    [114] = "Samba",
    [115] = "Folklore",
    [116] = "Ballad",
    [117] = "Power Ballad",
    [118] = "Rhythmic Soul",
    [119] = "Freestyle",
    [120] = "Duet",
    [121] = "Punk Rock",
    [122] = "Drum Solo",
    [123] = "A capella",
    [124] = "Euro-House",
    [125] = "Dance Hall",
};

Andreas Öman's avatar
Andreas Öman committed
161 162
/* buf must be ID3v2_HEADER_SIZE byte long */
static int id3v2_match(const uint8_t *buf)
163
{
164
    return  buf[0] == 'I' &&
165 166 167 168 169 170 171
            buf[1] == 'D' &&
            buf[2] == '3' &&
            buf[3] != 0xff &&
            buf[4] != 0xff &&
            (buf[6] & 0x80) == 0 &&
            (buf[7] & 0x80) == 0 &&
            (buf[8] & 0x80) == 0 &&
172
            (buf[9] & 0x80) == 0;
173 174
}

Andreas Öman's avatar
Andreas Öman committed
175 176 177 178 179 180 181 182 183 184 185 186 187
static unsigned int id3v2_get_size(ByteIOContext *s, int len)
{
    int v=0;
    while(len--)
        v= (v<<7) + (get_byte(s)&0x7F);
    return v;
}

static void id3v2_read_ttag(AVFormatContext *s, int taglen, char *dst, int dstlen)
{
    char *q;
    int len;

188 189
    if(dstlen > 0)
        dst[0]= 0;
Andreas Öman's avatar
Andreas Öman committed
190 191 192 193 194 195
    if(taglen < 1)
        return;

    taglen--; /* account for encoding type byte */
    dstlen--; /* Leave space for zero terminator */

196
    switch(get_byte(s->pb)) { /* encoding type */
Andreas Öman's avatar
Andreas Öman committed
197 198 199 200 201

    case 0:  /* ISO-8859-1 (0 - 255 maps directly into unicode) */
        q = dst;
        while(taglen--) {
            uint8_t tmp;
202
            PUT_UTF8(get_byte(s->pb), tmp, if (q - dst < dstlen - 1) *q++ = tmp;)
Andreas Öman's avatar
Andreas Öman committed
203 204 205 206 207 208
        }
        *q = '\0';
        break;

    case 3:  /* UTF-8 */
        len = FFMIN(taglen, dstlen);
209
        get_buffer(s->pb, dst, len);
Andreas Öman's avatar
Andreas Öman committed
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
        dst[len] = 0;
        break;
    }
}

/**
 * ID3v2 parser
 *
 * Handles ID3v2.2, 2.3 and 2.4.
 *
 */

static void id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t flags)
{
    int isv34, tlen;
    uint32_t tag;
    offset_t next;
    char tmp[16];
    int taghdrlen;
    const char *reason;

    switch(version) {
    case 2:
        if(flags & 0x40) {
            reason = "compression";
            goto error;
        }
        isv34 = 0;
        taghdrlen = 6;
        break;

241 242
    case 3:
    case 4:
Andreas Öman's avatar
Andreas Öman committed
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
        isv34 = 1;
        taghdrlen = 10;
        break;

    default:
        reason = "version";
        goto error;
    }

    if(flags & 0x80) {
        reason = "unsynchronization";
        goto error;
    }

    if(isv34 && flags & 0x40) /* Extended header present, just skip over it */
258
        url_fskip(s->pb, id3v2_get_size(s->pb, 4));
Andreas Öman's avatar
Andreas Öman committed
259 260 261

    while(len >= taghdrlen) {
        if(isv34) {
262 263 264
            tag  = get_be32(s->pb);
            tlen = id3v2_get_size(s->pb, 4);
            get_be16(s->pb); /* flags */
Andreas Öman's avatar
Andreas Öman committed
265
        } else {
266 267
            tag  = get_be24(s->pb);
            tlen = id3v2_get_size(s->pb, 3);
Andreas Öman's avatar
Andreas Öman committed
268 269 270 271 272 273
        }
        len -= taghdrlen + tlen;

        if(len < 0)
            break;

274
        next = url_ftell(s->pb) + tlen;
Andreas Öman's avatar
Andreas Öman committed
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303

        switch(tag) {
        case MKBETAG('T', 'I', 'T', '2'):
        case MKBETAG(0,   'T', 'T', '2'):
            id3v2_read_ttag(s, tlen, s->title, sizeof(s->title));
            break;
        case MKBETAG('T', 'P', 'E', '1'):
        case MKBETAG(0,   'T', 'P', '1'):
            id3v2_read_ttag(s, tlen, s->author, sizeof(s->author));
            break;
        case MKBETAG('T', 'A', 'L', 'B'):
        case MKBETAG(0,   'T', 'A', 'L'):
            id3v2_read_ttag(s, tlen, s->album, sizeof(s->album));
            break;
        case MKBETAG('T', 'C', 'O', 'N'):
        case MKBETAG(0,   'T', 'C', 'O'):
            id3v2_read_ttag(s, tlen, s->genre, sizeof(s->genre));
            break;
        case MKBETAG('T', 'C', 'O', 'P'):
        case MKBETAG(0,   'T', 'C', 'R'):
            id3v2_read_ttag(s, tlen, s->copyright, sizeof(s->copyright));
            break;
        case MKBETAG('T', 'R', 'C', 'K'):
        case MKBETAG(0,   'T', 'R', 'K'):
            id3v2_read_ttag(s, tlen, tmp, sizeof(tmp));
            s->track = atoi(tmp);
            break;
        case 0:
            /* padding, skip to end */
304
            url_fskip(s->pb, len);
Andreas Öman's avatar
Andreas Öman committed
305 306 307 308
            len = 0;
            continue;
        }
        /* Skip to end of tag */
309
        url_fseek(s->pb, next, SEEK_SET);
Andreas Öman's avatar
Andreas Öman committed
310 311 312
    }

    if(version == 4 && flags & 0x10) /* Footer preset, always 10 bytes, skip over it */
313
        url_fskip(s->pb, 10);
Andreas Öman's avatar
Andreas Öman committed
314 315 316 317
    return;

  error:
    av_log(s, AV_LOG_INFO, "ID3v2.%d tag skipped, cannot handle %s\n", version, reason);
318
    url_fskip(s->pb, len);
Andreas Öman's avatar
Andreas Öman committed
319 320
}

Andreas Öman's avatar
Andreas Öman committed
321 322
static void id3v1_get_string(char *str, int str_size,
                             const uint8_t *buf, int buf_size)
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338
{
    int i, c;
    char *q;

    q = str;
    for(i = 0; i < buf_size; i++) {
        c = buf[i];
        if (c == '\0')
            break;
        if ((q - str) >= str_size - 1)
            break;
        *q++ = c;
    }
    *q = '\0';
}

Andreas Öman's avatar
Andreas Öman committed
339 340
/* 'buf' must be ID3v1_TAG_SIZE byte long */
static int id3v1_parse_tag(AVFormatContext *s, const uint8_t *buf)
341 342 343
{
    char str[5];
    int genre;
344

345 346 347 348
    if (!(buf[0] == 'T' &&
          buf[1] == 'A' &&
          buf[2] == 'G'))
        return -1;
Andreas Öman's avatar
Andreas Öman committed
349 350 351 352
    id3v1_get_string(s->title, sizeof(s->title), buf + 3, 30);
    id3v1_get_string(s->author, sizeof(s->author), buf + 33, 30);
    id3v1_get_string(s->album, sizeof(s->album), buf + 63, 30);
    id3v1_get_string(str, sizeof(str), buf + 93, 4);
353
    s->year = atoi(str);
Andreas Öman's avatar
Andreas Öman committed
354
    id3v1_get_string(s->comment, sizeof(s->comment), buf + 97, 30);
355 356 357
    if (buf[125] == 0 && buf[126] != 0)
        s->track = buf[126];
    genre = buf[127];
Andreas Öman's avatar
Andreas Öman committed
358
    if (genre <= ID3v1_GENRE_MAX)
Måns Rullgård's avatar
Måns Rullgård committed
359
        av_strlcpy(s->genre, id3v1_genre_str[genre], sizeof(s->genre));
360 361 362
    return 0;
}

Andreas Öman's avatar
Andreas Öman committed
363
static void id3v1_create_tag(AVFormatContext *s, uint8_t *buf)
364 365 366
{
    int v, i;

Andreas Öman's avatar
Andreas Öman committed
367
    memset(buf, 0, ID3v1_TAG_SIZE); /* fail safe */
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
    buf[0] = 'T';
    buf[1] = 'A';
    buf[2] = 'G';
    strncpy(buf + 3, s->title, 30);
    strncpy(buf + 33, s->author, 30);
    strncpy(buf + 63, s->album, 30);
    v = s->year;
    if (v > 0) {
        for(i = 0;i < 4; i++) {
            buf[96 - i] = '0' + (v % 10);
            v = v / 10;
        }
    }
    strncpy(buf + 97, s->comment, 30);
    if (s->track != 0) {
        buf[125] = 0;
        buf[126] = s->track;
    }
Andreas Öman's avatar
Andreas Öman committed
386 387
    for(i = 0; i <= ID3v1_GENRE_MAX; i++) {
        if (!strcasecmp(s->genre, id3v1_genre_str[i])) {
388 389 390 391 392 393 394
            buf[127] = i;
            break;
        }
    }
}

/* mp3 read */
Måns Rullgård's avatar
Måns Rullgård committed
395 396 397

static int mp3_read_probe(AVProbeData *p)
{
398
    int max_frames, first_frames = 0;
399
    int fsize, frames, sample_rate;
400 401 402
    uint32_t header;
    uint8_t *buf, *buf2, *end;
    AVCodecContext avctx;
Måns Rullgård's avatar
Måns Rullgård committed
403

Andreas Öman's avatar
Andreas Öman committed
404 405
    if(id3v2_match(p->buf))
        return AVPROBE_SCORE_MAX/2+1; // this must be less than mpeg-ps because some retards put id3v2 tags before mpeg-ps files
Måns Rullgård's avatar
Måns Rullgård committed
406

407 408
    max_frames = 0;
    buf = p->buf;
409
    end = buf + p->buf_size - sizeof(uint32_t);
Måns Rullgård's avatar
Måns Rullgård committed
410

411
    for(; buf < end; buf= buf2+1) {
412
        buf2 = buf;
Måns Rullgård's avatar
Måns Rullgård committed
413

Michael Niedermayer's avatar
Michael Niedermayer committed
414
        for(frames = 0; buf2 < end; frames++) {
415
            header = AV_RB32(buf2);
416
            fsize = ff_mpa_decode_header(&avctx, header, &sample_rate);
417 418 419 420 421
            if(fsize < 0)
                break;
            buf2 += fsize;
        }
        max_frames = FFMAX(max_frames, frames);
422 423
        if(buf == p->buf)
            first_frames= frames;
424
    }
425
    if   (first_frames>=3) return AVPROBE_SCORE_MAX/2+1;
426
    else if(max_frames>500)return AVPROBE_SCORE_MAX/2;
427 428
    else if(max_frames>=3) return AVPROBE_SCORE_MAX/4;
    else if(max_frames>=1) return 1;
429
    else                   return 0;
Måns Rullgård's avatar
Måns Rullgård committed
430 431
}

432
/**
433
 * Try to find Xing/Info/VBRI tags and compute duration from info therein
434
 */
435
static void mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, offset_t base)
436
{
437 438 439
    uint32_t v, spf;
    int frames = -1; /* Total number of frames in file */
    const offset_t xing_offtbl[2][2] = {{32, 17}, {17,9}};
440 441
    MPADecodeContext c;

442
    v = get_be32(s->pb);
443 444 445 446
    if(ff_mpa_check_header(v) < 0)
      return;

    ff_mpegaudio_decode_header(&c, v);
447
    if(c.layer != 3)
Andreas Öman's avatar
Andreas Öman committed
448
        return;
449

450
    /* Check for Xing / Info tag */
451 452
    url_fseek(s->pb, xing_offtbl[c.lsf == 1][c.nb_channels == 1], SEEK_CUR);
    v = get_be32(s->pb);
453
    if(v == MKBETAG('X', 'i', 'n', 'g') || v == MKBETAG('I', 'n', 'f', 'o')) {
454
        v = get_be32(s->pb);
Andreas Öman's avatar
Andreas Öman committed
455
        if(v & 0x1)
456
            frames = get_be32(s->pb);
457
    }
458

459
    /* Check for VBRI tag (always 32 bytes after end of mpegaudio header) */
460 461
    url_fseek(s->pb, base + 4 + 32, SEEK_SET);
    v = get_be32(s->pb);
462 463
    if(v == MKBETAG('V', 'B', 'R', 'I')) {
        /* Check tag version */
464
        if(get_be16(s->pb) == 1) {
465
            /* skip delay, quality and total bytes */
466 467
            url_fseek(s->pb, 8, SEEK_CUR);
            frames = get_be32(s->pb);
468 469 470
        }
    }

471
    if(frames < 0)
Andreas Öman's avatar
Andreas Öman committed
472
        return;
473 474 475 476

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

479 480 481 482
static int mp3_read_header(AVFormatContext *s,
                           AVFormatParameters *ap)
{
    AVStream *st;
Andreas Öman's avatar
Andreas Öman committed
483
    uint8_t buf[ID3v1_TAG_SIZE];
484
    int len, ret, filesize;
485
    offset_t off;
486 487 488

    st = av_new_stream(s, 0);
    if (!st)
489
        return AVERROR(ENOMEM);
490

491 492
    st->codec->codec_type = CODEC_TYPE_AUDIO;
    st->codec->codec_id = CODEC_ID_MP3;
Aurelien Jacobs's avatar
Aurelien Jacobs committed
493
    st->need_parsing = AVSTREAM_PARSE_FULL;
494
    st->start_time = 0;
495

496
    /* try to get the TAG */
497
    if (!url_is_streamed(s->pb)) {
498
        /* XXX: change that */
499
        filesize = url_fsize(s->pb);
500
        if (filesize > 128) {
501 502
            url_fseek(s->pb, filesize - 128, SEEK_SET);
            ret = get_buffer(s->pb, buf, ID3v1_TAG_SIZE);
Andreas Öman's avatar
Andreas Öman committed
503 504
            if (ret == ID3v1_TAG_SIZE) {
                id3v1_parse_tag(s, buf);
505
            }
506
            url_fseek(s->pb, 0, SEEK_SET);
507 508 509
        }
    }

Andreas Öman's avatar
Andreas Öman committed
510
    /* if ID3v2 header found, skip it */
511
    ret = get_buffer(s->pb, buf, ID3v2_HEADER_SIZE);
Andreas Öman's avatar
Andreas Öman committed
512
    if (ret != ID3v2_HEADER_SIZE)
513
        return -1;
Andreas Öman's avatar
Andreas Öman committed
514
    if (id3v2_match(buf)) {
Andreas Öman's avatar
Andreas Öman committed
515
        /* parse ID3v2 header */
516 517 518 519
        len = ((buf[6] & 0x7f) << 21) |
            ((buf[7] & 0x7f) << 14) |
            ((buf[8] & 0x7f) << 7) |
            (buf[9] & 0x7f);
Andreas Öman's avatar
Andreas Öman committed
520
        id3v2_parse(s, len, buf[3], buf[5]);
521
    } else {
522
        url_fseek(s->pb, 0, SEEK_SET);
523 524
    }

525
    off = url_ftell(s->pb);
526
    mp3_parse_vbr_tags(s, st, off);
527
    url_fseek(s->pb, off, SEEK_SET);
528

529 530 531 532 533 534 535 536 537 538
    /* 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];
539

540 541
    size= MP3_PACKET_SIZE;

542
    ret= av_get_packet(s->pb, pkt, size);
543 544 545

    pkt->stream_index = 0;
    if (ret <= 0) {
546
        return AVERROR(EIO);
547 548 549 550 551 552 553
    }
    /* note: we need to modify the packet size here to handle the last
       packet */
    pkt->size = ret;
    return ret;
}

554
#ifdef CONFIG_MUXERS
555
/* simple formats */
Andreas Öman's avatar
Andreas Öman committed
556 557 558

static void id3v2_put_size(AVFormatContext *s, int size)
{
559 560 561 562
    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
563 564
}

565
static void id3v2_put_ttag(AVFormatContext *s, const char *string, uint32_t tag)
Andreas Öman's avatar
Andreas Öman committed
566 567
{
    int len = strlen(string);
568
    put_be32(s->pb, tag);
Andreas Öman's avatar
Andreas Öman committed
569
    id3v2_put_size(s, len + 1);
570 571 572
    put_be16(s->pb, 0);
    put_byte(s->pb, 3); /* UTF-8 */
    put_buffer(s->pb, string, len);
Andreas Öman's avatar
Andreas Öman committed
573 574 575 576 577 578 579
}


/**
 * Write an ID3v2.4 header at beginning of stream
 */

580 581
static int mp3_write_header(struct AVFormatContext *s)
{
Andreas Öman's avatar
Andreas Öman committed
582 583
    int totlen = 0;
    char tracktxt[10];
584
    char yeartxt[10];
Andreas Öman's avatar
Andreas Öman committed
585 586

    if(s->track)
Aurelien Jacobs's avatar
Aurelien Jacobs committed
587
        snprintf(tracktxt, sizeof(tracktxt), "%d", s->track);
588
    if(s->year)
Aurelien Jacobs's avatar
Aurelien Jacobs committed
589
        snprintf( yeartxt, sizeof(yeartxt) , "%d", s->year );
Andreas Öman's avatar
Andreas Öman committed
590 591 592 593 594 595 596

    if(s->title[0])     totlen += 11 + strlen(s->title);
    if(s->author[0])    totlen += 11 + strlen(s->author);
    if(s->album[0])     totlen += 11 + strlen(s->album);
    if(s->genre[0])     totlen += 11 + strlen(s->genre);
    if(s->copyright[0]) totlen += 11 + strlen(s->copyright);
    if(s->track)        totlen += 11 + strlen(tracktxt);
597
    if(s->year)         totlen += 11 + strlen(yeartxt);
Andreas Öman's avatar
Andreas Öman committed
598 599 600 601 602 603
    if(!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT))
        totlen += strlen(LIBAVFORMAT_IDENT) + 11;

    if(totlen == 0)
        return 0;

604 605 606
    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
607 608 609 610 611 612 613 614 615

    id3v2_put_size(s, totlen);

    if(s->title[0])     id3v2_put_ttag(s, s->title,     MKBETAG('T', 'I', 'T', '2'));
    if(s->author[0])    id3v2_put_ttag(s, s->author,    MKBETAG('T', 'P', 'E', '1'));
    if(s->album[0])     id3v2_put_ttag(s, s->album,     MKBETAG('T', 'A', 'L', 'B'));
    if(s->genre[0])     id3v2_put_ttag(s, s->genre,     MKBETAG('T', 'C', 'O', 'N'));
    if(s->copyright[0]) id3v2_put_ttag(s, s->copyright, MKBETAG('T', 'C', 'O', 'P'));
    if(s->track)        id3v2_put_ttag(s, tracktxt,     MKBETAG('T', 'R', 'C', 'K'));
616
    if(s->year)         id3v2_put_ttag(s, yeartxt,      MKBETAG('T', 'Y', 'E', 'R'));
Andreas Öman's avatar
Andreas Öman committed
617 618
    if(!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT))
        id3v2_put_ttag(s, LIBAVFORMAT_IDENT,            MKBETAG('T', 'E', 'N', 'C'));
619 620 621
    return 0;
}

622
static int mp3_write_packet(struct AVFormatContext *s, AVPacket *pkt)
623
{
624 625
    put_buffer(s->pb, pkt->data, pkt->size);
    put_flush_packet(s->pb);
626 627 628 629 630
    return 0;
}

static int mp3_write_trailer(struct AVFormatContext *s)
{
Andreas Öman's avatar
Andreas Öman committed
631
    uint8_t buf[ID3v1_TAG_SIZE];
632

Andreas Öman's avatar
Andreas Öman committed
633
    /* write the id3v1 tag */
634
    if (s->title[0] != '\0') {
Andreas Öman's avatar
Andreas Öman committed
635
        id3v1_create_tag(s, buf);
636 637
        put_buffer(s->pb, buf, ID3v1_TAG_SIZE);
        put_flush_packet(s->pb);
638 639 640
    }
    return 0;
}
641
#endif //CONFIG_MUXERS
642

643
#ifdef CONFIG_MP3_DEMUXER
644
AVInputFormat mp3_demuxer = {
645
    "mp3",
646
    NULL_IF_CONFIG_SMALL("MPEG audio"),
647
    0,
Måns Rullgård's avatar
Måns Rullgård committed
648
    mp3_read_probe,
649 650
    mp3_read_header,
    mp3_read_packet,
651
    .flags= AVFMT_GENERIC_INDEX,
652
    .extensions = "mp2,mp3,m2a", /* XXX: use probe */
653
};
654 655
#endif
#ifdef CONFIG_MP2_MUXER
656
AVOutputFormat mp2_muxer = {
657
    "mp2",
658
    NULL_IF_CONFIG_SMALL("MPEG audio layer 2"),
659
    "audio/x-mpeg",
660
#ifdef CONFIG_LIBMP3LAME
661
    "mp2,m2a",
662
#else
663
    "mp2,mp3,m2a",
664 665 666
#endif
    0,
    CODEC_ID_MP2,
667
    CODEC_ID_NONE,
668
    NULL,
669 670 671
    mp3_write_packet,
    mp3_write_trailer,
};
672 673
#endif
#ifdef CONFIG_MP3_MUXER
674
AVOutputFormat mp3_muxer = {
675
    "mp3",
676
    NULL_IF_CONFIG_SMALL("MPEG audio layer 3"),
677 678 679 680
    "audio/x-mpeg",
    "mp3",
    0,
    CODEC_ID_MP3,
681
    CODEC_ID_NONE,
682 683 684 685 686
    mp3_write_header,
    mp3_write_packet,
    mp3_write_trailer,
};
#endif