Merge commit '3f7fd59d151a2773f0e2e93e56b6b13ec6e5334b'
authorMichael Niedermayer <michaelni@gmx.at>
Sun, 16 Sep 2012 12:14:47 +0000 (14:14 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Sun, 16 Sep 2012 12:24:11 +0000 (14:24 +0200)
* commit '3f7fd59d151a2773f0e2e93e56b6b13ec6e5334b':
  avformat: fix typo in avformat_close_input
  mp3enc: write Xing TOC
  mp3enc: support MPEG-2 and MPEG-2.5 in Xing header.
  mp3enc: downgrade some errors in writing Xing frame to warnings
  lavf: flush the output AVIOContext in av_write_trailer().
  lavf: cosmetics, reformat av_write_trailer().
  avio: flush the internal buffer in avio_close()
  Enhance doc on asyncts audiofilter
  cmdutils: avoid setting data pointers to invalid values in alloc_buffer()
  libavcodec: remove av_destruct_packet_nofree()

Conflicts:
libavcodec/avpacket.c
libavformat/mp3enc.c
libavformat/nutenc.c
libavformat/utils.c
libavformat/version.h
tests/ref/lavf/voc
tests/ref/lavf/voc_s16

Merged-by: Michael Niedermayer <michaelni@gmx.at>
23 files changed:
1  2 
doc/filters.texi
libavcodec/avcodec.h
libavcodec/avpacket.c
libavformat/asfenc.c
libavformat/assenc.c
libavformat/avienc.c
libavformat/crcenc.c
libavformat/ffmenc.c
libavformat/ffmetaenc.c
libavformat/filmstripenc.c
libavformat/gif.c
libavformat/img2enc.c
libavformat/matroskaenc.c
libavformat/movenc.c
libavformat/mp3enc.c
libavformat/mxfenc.c
libavformat/nutenc.c
libavformat/rmenc.c
libavformat/rsoenc.c
libavformat/smjpegenc.c
libavformat/swfenc.c
libavformat/utils.c
libavformat/version.h

Simple merge
Simple merge
  #include "libavutil/avassert.h"
  #include "libavutil/mem.h"
  #include "avcodec.h"
 +#include "bytestream.h"
 +#include "internal.h"
  
- void av_destruct_packet_nofree(AVPacket *pkt)
- {
-     pkt->data            = NULL;
-     pkt->size            = 0;
-     pkt->side_data       = NULL;
-     pkt->side_data_elems = 0;
- }
 -void av_destruct_packet(AVPacket *pkt)
 +void ff_packet_free_side_data(AVPacket *pkt)
  {
      int i;
 +    for (i = 0; i < pkt->side_data_elems; i++)
 +        av_free(pkt->side_data[i].data);
 +    av_freep(&pkt->side_data);
 +    pkt->side_data_elems = 0;
 +}
  
 +void av_destruct_packet(AVPacket *pkt)
 +{
      av_free(pkt->data);
      pkt->data = NULL;
      pkt->size = 0;
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -115,18 -114,15 +119,18 @@@ static int mp3_write_xing(AVFormatConte
  {
      MP3Context       *mp3 = s->priv_data;
      AVCodecContext *codec = s->streams[mp3->audio_stream_idx]->codec;
 -    int32_t        header;
 -    MPADecodeHeader  mpah;
 -    int srate_idx, i, channels;
 -    int bitrate_idx;
 -    int xing_offset;
 -    int ver = 0;
 +    int              bitrate_idx;
 +    int              best_bitrate_idx = -1;
 +    int              best_bitrate_error= INT_MAX;
-     int64_t          xing_offset;
++    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;
  
      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];
      switch (codec->channels) {
      case 1:  channels = MPA_MONO;                                          break;
      case 2:  channels = MPA_STEREO;                                        break;
-     default: av_log(s, AV_LOG_WARNING, "Unsupported number of channels, not writing Xing header.\n"); return -1;
+     default: av_log(s, AV_LOG_WARNING, "Unsupported number of channels, "
+                     "not writing Xing header.\n");
 -             return;
++             return -1;
      }
  
 -    /* 64 kbps frame, should be large enough */
 -    bitrate_idx = (ver == 3) ? 5 : 8;
 -
      /* dummy MPEG audio header */
      header  =  0xff                                  << 24; // sync
      header |= (0x7 << 5 | ver << 3 | 0x1 << 1 | 0x1) << 16; // sync/audio-version/layer 3/no crc*/
 -    header |= (bitrate_idx << 4 | srate_idx << 2)    <<  8;
 +    header |= (srate_idx << 2) <<  8;
      header |= channels << 6;
 -    avio_wb32(s->pb, header);
  
 -    avpriv_mpegaudio_decode_header(&mpah, header);
 +    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;
 +        }
 +    }
 +    av_assert0(best_bitrate_idx >= 0);
 +
 +    for (bitrate_idx= best_bitrate_idx;; bitrate_idx++) {
 +        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
 +               + xing_offset
 +               + 4              // xing tag
 +               + 4              // frames/size/toc flags
 +               + 4              // frames
 +               + 4              // size
-                + VBR_TOC_SIZE   // toc
++               + XING_TOC_SIZE   // toc
 +               + 24
 +               ;
 +
 +        if (needed <= c.frame_size)
 +            break;
 +        header &= ~mask;
 +    }
  
 -    av_assert0(mpah.frame_size >= XING_MAX_SIZE);
 +    avio_wb32(s->pb, header);
 -    xing_offset = xing_offtbl[ver != 3][codec->channels == 1];
      ffio_fill(s->pb, 0, xing_offset);
-     avio_wb32(s->pb, MKBETAG('X', 'i', 'n', 'g'));
-     avio_wb32(s->pb, 0x01 | 0x02 | 0x04);  // frames/size/toc
+     mp3->xing_offset = avio_tell(s->pb);
+     ffio_wfourcc(s->pb, "Xing");
+     avio_wb32(s->pb, 0x01 | 0x02 | 0x04);  // frames / size / TOC
  
-     mp3->frames_offset = avio_tell(s->pb);
 -    mp3->size = mpah.frame_size;
 -    mp3->want = 1;
 +    mp3->size = c.frame_size;
 +    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 < VBR_TOC_SIZE; ++i)
-         avio_w8(s->pb, (uint8_t)(255 * i / VBR_TOC_SIZE));
++    for (i = 0; i < XING_TOC_SIZE; ++i)
++        avio_w8(s->pb, (uint8_t)(255 * i / XING_TOC_SIZE));
  
 -    mpah.frame_size -= 4 + xing_offset + 4 + 4 + 4 + 4 + XING_TOC_SIZE;
 -    ffio_fill(s->pb, 0, mpah.frame_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);
-     avio_flush(s->pb);
 +
 +    return 0;
  }
  
  /*
   * Add a frame to XING data.
   * Following lame's "VbrTag.c".
   */
- static void mp3_xing_add_frame(AVFormatContext *s, AVPacket *pkt)
+ static void mp3_xing_add_frame(MP3Context *mp3, AVPacket *pkt)
  {
-     MP3Context  *mp3 = s->priv_data;
      int i;
  
-     ++mp3->frames;
+     mp3->frames++;
+     mp3->seen++;
      mp3->size += pkt->size;
  
-     if (mp3->want == ++mp3->seen) {
+     if (mp3->want == mp3->seen) {
          mp3->bag[mp3->pos] = mp3->size;
  
-         if (VBR_NUM_BAGS == ++mp3->pos) {
+         if (XING_NUM_BAGS == ++mp3->pos) {
              /* shrink table to half size by throwing away each second bag. */
-             for (i = 1; i < VBR_NUM_BAGS; i += 2)
+             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 <<= 1;
+             mp3->want *= 2;
              /* adjust current position to half of table size. */
-             mp3->pos >>= 1;
+             mp3->pos = XING_NUM_BAGS / 2;
          }
  
          mp3->seen = 0;
      }
  }
  
- static void mp3_fix_xing(AVFormatContext *s)
++static void mp3_update_xing(AVFormatContext *s)
 +{
 +    MP3Context  *mp3 = s->priv_data;
 +    int i;
 +
-     avio_flush(s->pb);
 +    /* replace "Xing" identification string with "Info" for CBR files. */
 +    if (!mp3->has_variable_bitrate) {
-         int64_t tag_offset = mp3->frames_offset
-             - 4   // frames/size/toc flags
-             - 4;  // xing tag
-         avio_seek(s->pb, tag_offset, SEEK_SET);
-         avio_wb32(s->pb, MKBETAG('I', 'n', 'f', 'o'));
++        avio_seek(s->pb, mp3->xing_offset, SEEK_SET);
++        ffio_wfourcc(s->pb, "Info");
 +    }
 +
-     avio_seek(s->pb, mp3->frames_offset, SEEK_SET);
++    avio_seek(s->pb, mp3->xing_offset + 8, SEEK_SET);
 +    avio_wb32(s->pb, mp3->frames);
 +    avio_wb32(s->pb, mp3->size);
 +
 +    avio_w8(s->pb, 0);  // first toc entry has to be zero.
 +
-     for (i = 1; i < VBR_TOC_SIZE; ++i) {
-         int j = i * mp3->pos / VBR_TOC_SIZE;
++    for (i = 1; i < XING_TOC_SIZE; ++i) {
++        int j = i * mp3->pos / XING_TOC_SIZE;
 +        int seek_point = 256LL * mp3->bag[j] / mp3->size;
 +        avio_w8(s->pb, FFMIN(seek_point, 255));
 +    }
 +
-     avio_flush(s->pb);
 +    avio_seek(s->pb, 0, SEEK_END);
 +}
 +
- static int mp3_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
+ static int mp3_write_audio_packet(AVFormatContext *s, AVPacket *pkt)
  {
-     if (! pkt || ! pkt->data || pkt->size < 4)
-         return ff_raw_write_packet(s, pkt);
-     else {
-         MP3Context  *mp3 = s->priv_data;
+     MP3Context  *mp3 = s->priv_data;
 -    if (mp3->xing_offset && pkt->size >= 4) {
++    if (pkt && pkt->data && pkt->size >= 4) {
          MPADecodeHeader c;
 +        int av_unused base;
  
          avpriv_mpegaudio_decode_header(&c, AV_RB32(pkt->data));
  
          if (!mp3->initial_bitrate)
              mp3->initial_bitrate = c.bit_rate;
-         if (!mp3->has_variable_bitrate) {
-             if ((c.bit_rate == 0) || (mp3->initial_bitrate != c.bit_rate))
-                 mp3->has_variable_bitrate = 1;
-         }
+         if ((c.bit_rate == 0) || (mp3->initial_bitrate != c.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];
 +
 +        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->frames_offset)
-             mp3_xing_add_frame(s, pkt);
-         return ff_raw_write_packet(s, pkt);
++        if (mp3->xing_offset)
++            mp3_xing_add_frame(mp3, pkt);
      }
+     return ff_raw_write_packet(s, pkt);
  }
  
  static int mp3_queue_flush(AVFormatContext *s)
@@@ -358,15 -295,9 +357,13 @@@ static int mp2_write_trailer(struct AVF
          avio_write(s->pb, buf, ID3v1_TAG_SIZE);
      }
  
 -    if (mp3->xing_offset)
 -        mp3_update_xing(s);
 +    /* write number of frames */
-     if (mp3 && mp3->frames_offset) {
-         avio_seek(s->pb, mp3->frames_offset, SEEK_SET);
++    if (mp3->xing_offset) {
++        avio_seek(s->pb, mp3->xing_offset+8, SEEK_SET);
 +        avio_wb32(s->pb, s->streams[mp3->audio_stream_idx]->nb_frames);
 +        avio_seek(s->pb, 0, SEEK_END);
 +    }
  
-     avio_flush(s->pb);
      return 0;
  }
  
@@@ -502,20 -421,6 +498,20 @@@ static int mp3_write_header(struct AVFo
      return 0;
  }
  
-     if (mp3->frames_offset)
-         mp3_fix_xing(s);
 +static int mp3_write_trailer(AVFormatContext *s)
 +{
 +    MP3Context  *mp3 = s->priv_data;
 +    int ret=mp2_write_trailer(s);
 +
 +    if (ret < 0)
 +        return ret;
 +
++    if (mp3->xing_offset)
++        mp3_update_xing(s);
 +
 +    return 0;
 +}
 +
  AVOutputFormat ff_mp3_muxer = {
      .name              = "mp3",
      .long_name         = NULL_IF_CONFIG_SMALL("MP3 (MPEG audio layer 3)"),
Simple merge
@@@ -924,17 -852,7 +924,16 @@@ static int nut_write_trailer(AVFormatCo
      while(nut->header_count<3)
          write_headers(s, bc);
  
-     avio_flush(bc);
 +    ret = avio_open_dyn_buf(&dyn_bc);
 +    if(ret >= 0) {
 +        write_index(nut, dyn_bc);
 +        put_packet(nut, bc, dyn_bc, 1, INDEX_STARTCODE);
 +    }
 +
      ff_nut_free_sp(nut);
 +    for(i=0; i<s->nb_streams; i++)
 +        av_freep(&nut->stream[i].keyframe_pts);
 +
      av_freep(&nut->stream);
      av_freep(&nut->chapter);
      av_freep(&nut->time_base);
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -3775,20 -3264,18 +3778,24 @@@ int av_write_trailer(AVFormatContext *s
  
          av_free_packet(&pkt);
  
-         if(ret<0)
+         if (ret < 0)
              goto fail;
 +        if(s->pb && s->pb->error)
 +            goto fail;
      }
  
-     if(s->oformat->write_trailer)
+     if (s->oformat->write_trailer)
          ret = s->oformat->write_trailer(s);
+     if (!(s->oformat->flags & AVFMT_NOFILE))
+         avio_flush(s->pb);
  fail:
-     if(ret == 0)
 +    if (s->pb)
 +       avio_flush(s->pb);
-     for(i=0;i<s->nb_streams;i++) {
++    if (ret == 0)
 +       ret = s->pb ? s->pb->error : 0;
+     for (i = 0; i < s->nb_streams; i++) {
          av_freep(&s->streams[i]->priv_data);
          av_freep(&s->streams[i]->index_entries);
      }
@@@ -30,8 -30,8 +30,8 @@@
  #include "libavutil/avutil.h"
  
  #define LIBAVFORMAT_VERSION_MAJOR 54
 -#define LIBAVFORMAT_VERSION_MINOR 16
 -#define LIBAVFORMAT_VERSION_MICRO  1
 +#define LIBAVFORMAT_VERSION_MINOR 27
- #define LIBAVFORMAT_VERSION_MICRO 100
++#define LIBAVFORMAT_VERSION_MICRO 101
  
  #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
                                                 LIBAVFORMAT_VERSION_MINOR, \