Merge commit '489c180451b1cde469f6aeea44f8bdb11cd941d0' into release/1.1
[ffmpeg.git] / libavformat / mp3enc.c
index 631705c..245b507 100644 (file)
@@ -2,20 +2,20 @@
  * MP3 muxer
  * Copyright (c) 2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * 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
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "libavcodec/mpegaudiodecheader.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/opt.h"
+#include "libavcodec/mpegaudio.h"
+#include "libavcodec/mpegaudiodata.h"
+#include "libavcodec/mpegaudiodecheader.h"
+#include "libavformat/avio_internal.h"
 #include "libavutil/dict.h"
 #include "libavutil/avassert.h"
 
@@ -51,11 +55,12 @@ static int id3v1_create_tag(AVFormatContext *s, uint8_t *buf)
     buf[0] = 'T';
     buf[1] = 'A';
     buf[2] = 'G';
-    count += id3v1_set_string(s, "TIT2",    buf +  3, 30);       //title
-    count += id3v1_set_string(s, "TPE1",    buf + 33, 30);       //author|artist
-    count += id3v1_set_string(s, "TALB",    buf + 63, 30);       //album
-    count += id3v1_set_string(s, "TDRL",    buf + 93,  4);       //date
-    count += id3v1_set_string(s, "comment", buf + 97, 30);
+    /* we knowingly overspecify each tag length by one byte to compensate for the mandatory null byte added by av_strlcpy */
+    count += id3v1_set_string(s, "TIT2",    buf +  3, 30 + 1);       //title
+    count += id3v1_set_string(s, "TPE1",    buf + 33, 30 + 1);       //author|artist
+    count += id3v1_set_string(s, "TALB",    buf + 63, 30 + 1);       //album
+    count += id3v1_set_string(s, "TDRL",    buf + 93,  4 + 1);       //date
+    count += id3v1_set_string(s, "comment", buf + 97, 30 + 1);
     if ((tag = av_dict_get(s->metadata, "TRCK", NULL, 0))) { //track
         buf[125] = 0;
         buf[126] = atoi(tag->value);
@@ -110,22 +115,23 @@ static const uint8_t xing_offtbl[2][2] = {{32, 17}, {17, 9}};
 /*
  * Write an empty XING header and initialize respective data.
  */
-static void mp3_write_xing(AVFormatContext *s)
+static int mp3_write_xing(AVFormatContext *s)
 {
     MP3Context       *mp3 = s->priv_data;
     AVCodecContext *codec = s->streams[mp3->audio_stream_idx]->codec;
-    int32_t        header;
+    int32_t          header;
     MPADecodeHeader  mpah;
     int srate_idx, i, channels;
     int bitrate_idx;
-    int best_bitrate_idx;
+    int best_bitrate_idx = -1;
     int best_bitrate_error = INT_MAX;
     int xing_offset;
     int ver = 0;
-    int lsf, bytes_needed;
+    int bytes_needed;
+    const char *vendor = (codec->flags & CODEC_FLAG_BITEXACT) ? "Lavf" : LIBAVFORMAT_IDENT;
 
     if (!s->pb->seekable)
-        return;
+        return 0;
 
     for (i = 0; i < FF_ARRAY_ELEMS(avpriv_mpa_freq_tab); i++) {
         const uint16_t base_freq = avpriv_mpa_freq_tab[i];
@@ -139,9 +145,8 @@ static void mp3_write_xing(AVFormatContext *s)
         break;
     }
     if (i == FF_ARRAY_ELEMS(avpriv_mpa_freq_tab)) {
-        av_log(s, AV_LOG_WARNING, "Unsupported sample rate, not writing Xing "
-               "header.\n");
-        return;
+        av_log(s, AV_LOG_WARNING, "Unsupported sample rate, not writing Xing header.\n");
+        return -1;
     }
 
     switch (codec->channels) {
@@ -149,41 +154,43 @@ static void mp3_write_xing(AVFormatContext *s)
     case 2:  channels = MPA_STEREO;                                        break;
     default: av_log(s, AV_LOG_WARNING, "Unsupported number of channels, "
                     "not writing Xing header.\n");
-             return;
+             return -1;
     }
 
     /* dummy MPEG audio header */
-    header  =  0xff                                  << 24; // sync
+    header  =  0xffU                                 << 24; // sync
     header |= (0x7 << 5 | ver << 3 | 0x1 << 1 | 0x1) << 16; // sync/audio-version/layer 3/no crc*/
     header |= (srate_idx << 2) << 8;
     header |= channels << 6;
 
-    lsf = !((header & (1 << 20) && header & (1 << 19)));
-
-    xing_offset  = xing_offtbl[ver != 3][channels == 1];
-    bytes_needed = 4              // header
-                 + xing_offset
-                 + 4              // xing tag
-                 + 4              // frames/size/toc flags
-                 + 4              // frames
-                 + 4              // size
-                 + XING_TOC_SIZE; // toc
-
     for (bitrate_idx = 1; bitrate_idx < 15; bitrate_idx++) {
-        int bit_rate = 1000 * avpriv_mpa_bitrate_tab[lsf][3 - 1][bitrate_idx];
+        int bit_rate = 1000 * avpriv_mpa_bitrate_tab[ver != 3][3 - 1][bitrate_idx];
         int error    = FFABS(bit_rate - codec->bit_rate);
 
-        if (error < best_bitrate_error){
+        if (error < best_bitrate_error) {
             best_bitrate_error = error;
             best_bitrate_idx   = bitrate_idx;
         }
     }
+    av_assert0(best_bitrate_idx >= 0);
 
-    for (bitrate_idx = best_bitrate_idx; bitrate_idx < 15; bitrate_idx++) {
+    for (bitrate_idx = best_bitrate_idx; ; bitrate_idx++) {
         int32_t mask = bitrate_idx << (4 + 8);
+        if (15 == bitrate_idx)
+            return -1;
         header |= mask;
 
         avpriv_mpegaudio_decode_header(&mpah, header);
+        xing_offset=xing_offtbl[mpah.lsf == 1][mpah.nb_channels == 1];
+        bytes_needed = 4              // header
+               + xing_offset
+               + 4              // xing tag
+               + 4              // frames/size/toc flags
+               + 4              // frames
+               + 4              // size
+               + XING_TOC_SIZE   // toc
+               + 24
+               ;
 
         if (bytes_needed <= mpah.frame_size)
             break;
@@ -193,26 +200,32 @@ static void mp3_write_xing(AVFormatContext *s)
 
     avio_wb32(s->pb, header);
 
-    avpriv_mpegaudio_decode_header(&mpah, header);
-
-    av_assert0(mpah.frame_size >= XING_MAX_SIZE);
-
     ffio_fill(s->pb, 0, xing_offset);
     mp3->xing_offset = avio_tell(s->pb);
     ffio_wfourcc(s->pb, "Xing");
     avio_wb32(s->pb, 0x01 | 0x02 | 0x04);  // frames / size / TOC
 
     mp3->size = mpah.frame_size;
-    mp3->want = 1;
+    mp3->want=1;
+    mp3->seen=0;
+    mp3->pos=0;
 
     avio_wb32(s->pb, 0);  // frames
     avio_wb32(s->pb, 0);  // size
 
-    // TOC
-    for (i = 0; i < XING_TOC_SIZE; i++)
-        avio_w8(s->pb, 255 * i / XING_TOC_SIZE);
+    // toc
+    for (i = 0; i < XING_TOC_SIZE; ++i)
+        avio_w8(s->pb, (uint8_t)(255 * i / XING_TOC_SIZE));
+
+    for (i = 0; i < strlen(vendor); ++i)
+        avio_w8(s->pb, vendor[i]);
+    for (; i < 21; ++i)
+        avio_w8(s->pb, 0);
+    avio_wb24(s->pb, FFMAX(codec->delay - 528 - 1, 0)<<12);
 
     ffio_fill(s->pb, 0, mpah.frame_size - bytes_needed);
+
+    return 0;
 }
 
 /*
@@ -233,7 +246,7 @@ static void mp3_xing_add_frame(MP3Context *mp3, AVPacket *pkt)
         if (XING_NUM_BAGS == ++mp3->pos) {
             /* shrink table to half size by throwing away each second bag. */
             for (i = 1; i < XING_NUM_BAGS; i += 2)
-                mp3->bag[i / 2] = mp3->bag[i];
+                mp3->bag[i >> 1] = mp3->bag[i];
 
             /* double wanted amount per bag. */
             mp3->want *= 2;
@@ -249,20 +262,43 @@ static int mp3_write_audio_packet(AVFormatContext *s, AVPacket *pkt)
 {
     MP3Context  *mp3 = s->priv_data;
 
-    if (mp3->xing_offset && pkt->size >= 4) {
-        MPADecodeHeader c;
+    if (pkt->data && pkt->size >= 4) {
+        MPADecodeHeader mpah;
+        int av_unused base;
         uint32_t h;
 
         h = AV_RB32(pkt->data);
         if (ff_mpa_check_header(h) == 0) {
-            avpriv_mpegaudio_decode_header(&c, h);
+            avpriv_mpegaudio_decode_header(&mpah, h);
             if (!mp3->initial_bitrate)
-                mp3->initial_bitrate = c.bit_rate;
-            if ((c.bit_rate == 0) || (mp3->initial_bitrate != c.bit_rate))
+                mp3->initial_bitrate = mpah.bit_rate;
+            if ((mpah.bit_rate == 0) || (mp3->initial_bitrate != mpah.bit_rate))
                 mp3->has_variable_bitrate = 1;
+        } else {
+            av_log(s, AV_LOG_WARNING, "Audio packet of size %d (starting with %08X...) "
+                   "is invalid, writing it anyway.\n", pkt->size, h);
+        }
+
+#ifdef FILTER_VBR_HEADERS
+        /* filter out XING and INFO headers. */
+        base = 4 + xing_offtbl[mpah.lsf == 1][mpah.nb_channels == 1];
+
+        if (base + 4 <= pkt->size) {
+            uint32_t v = AV_RB32(pkt->data + base);
+
+            if (MKBETAG('X','i','n','g') == v || MKBETAG('I','n','f','o') == v)
+                return 0;
         }
 
-        mp3_xing_add_frame(mp3, pkt);
+        /* filter out VBRI headers. */
+        base = 4 + 32;
+
+        if (base + 4 <= pkt->size && MKBETAG('V','B','R','I') == AV_RB32(pkt->data + base))
+            return 0;
+#endif
+
+        if (mp3->xing_offset)
+            mp3_xing_add_frame(mp3, pkt);
     }
 
     return ff_raw_write_packet(s, pkt);
@@ -336,6 +372,17 @@ static int mp3_write_trailer(struct AVFormatContext *s)
     return 0;
 }
 
+static int query_codec(enum AVCodecID id, int std_compliance)
+{
+    const CodecMime *cm= ff_id3v2_mime_tags;
+    while(cm->id != AV_CODEC_ID_NONE) {
+        if(id == cm->id)
+            return MKTAG('A', 'P', 'I', 'C');
+        cm++;
+    }
+    return -1;
+}
+
 #if CONFIG_MP2_MUXER
 AVOutputFormat ff_mp2_muxer = {
     .name              = "mp2",
@@ -467,6 +514,7 @@ AVOutputFormat ff_mp3_muxer = {
     .write_header      = mp3_write_header,
     .write_packet      = mp3_write_packet,
     .write_trailer     = mp3_write_trailer,
+    .query_codec       = query_codec,
     .flags             = AVFMT_NOTIMESTAMPS,
     .priv_class        = &mp3_muxer_class,
 };