Merge commit '3938b6762132d3d7ef1b5782e7dc8bf73ac8145d' into release/1.1
authorMichael Niedermayer <michaelni@gmx.at>
Sun, 4 May 2014 20:49:00 +0000 (22:49 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Sun, 4 May 2014 20:49:00 +0000 (22:49 +0200)
* commit '3938b6762132d3d7ef1b5782e7dc8bf73ac8145d':
  mp3enc: Properly write bitrate value in XING header

Conflicts:
libavformat/mp3enc.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavformat/mp3enc.c

@@@ -119,18 -114,18 +119,19 @@@ static int mp3_write_xing(AVFormatConte
  {
      MP3Context       *mp3 = s->priv_data;
      AVCodecContext *codec = s->streams[mp3->audio_stream_idx]->codec;
-     int              bitrate_idx;
-     int              best_bitrate_idx = -1;
-     int              best_bitrate_error= INT_MAX;
-     int              xing_offset;
-     int32_t          header, mask;
-     MPADecodeHeader  c;
-     int              srate_idx, ver = 0, i, channels;
-     int              needed;
-     const char      *vendor = (codec->flags & CODEC_FLAG_BITEXACT) ? "Lavf" : LIBAVFORMAT_IDENT;
 -    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, lsf;
++    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];
      }
  
      /* 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 |= (srate_idx << 2) << 8;
      header |= channels << 6;
  
-     for (bitrate_idx=1; bitrate_idx<15; bitrate_idx++) {
-         int error;
-         avpriv_mpegaudio_decode_header(&c, header | (bitrate_idx << (4+8)));
-         error= FFABS(c.bit_rate - codec->bit_rate);
-         if(error < best_bitrate_error){
-             best_bitrate_error= error;
-             best_bitrate_idx  = bitrate_idx;
 -    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 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++) {
 -    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;
-         mask = bitrate_idx << (4+8);
          header |= mask;
-         avpriv_mpegaudio_decode_header(&c, header);
-         xing_offset=xing_offtbl[c.lsf == 1][c.nb_channels == 1];
-         needed = 4              // header
+         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 (needed <= c.frame_size)
+         if (bytes_needed <= mpah.frame_size)
              break;
          header &= ~mask;
      }
  
      ffio_wfourcc(s->pb, "Xing");
      avio_wb32(s->pb, 0x01 | 0x02 | 0x04);  // frames / size / TOC
  
-     mp3->size = c.frame_size;
+     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, c.frame_size - needed);
+     ffio_fill(s->pb, 0, mpah.frame_size - bytes_needed);
 +
 +    return 0;
  }
  
  /*
@@@ -259,43 -249,17 +262,43 @@@ static int mp3_write_audio_packet(AVFor
  {
      MP3Context  *mp3 = s->priv_data;
  
 -    if (mp3->xing_offset && pkt->size >= 4) {
 -        MPADecodeHeader c;
 +    if (pkt->data && pkt->size >= 4) {
-         MPADecodeHeader c;
++        MPADecodeHeader mpah;
 +        int av_unused base;
 +        uint32_t head = AV_RB32(pkt->data);
  
 -        avpriv_mpegaudio_decode_header(&c, AV_RB32(pkt->data));
 +        if (ff_mpa_check_header(head) < 0) {
 +            av_log(s, AV_LOG_WARNING, "Audio packet of size %d (starting with %08X...) "
 +                   "is invalid, writing it anyway.\n", pkt->size, head);
 +            return ff_raw_write_packet(s, pkt);
 +        }
-         avpriv_mpegaudio_decode_header(&c, head);
++        avpriv_mpegaudio_decode_header(&mpah, head);
  
          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;
  
 -        mp3_xing_add_frame(mp3, pkt);
 +#ifdef FILTER_VBR_HEADERS
 +        /* filter out XING and INFO headers. */
-         base = 4 + xing_offtbl[c.lsf == 1][c.nb_channels == 1];
++        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;
 +        }
 +
 +        /* 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);