Merge commit 'be209bdabb11c59de17220bdbf0bf9c9f7cc16f5' into release/0.10
authorMichael Niedermayer <michaelni@gmx.at>
Thu, 25 Oct 2012 14:51:26 +0000 (16:51 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Thu, 25 Oct 2012 15:02:46 +0000 (17:02 +0200)
* commit 'be209bdabb11c59de17220bdbf0bf9c9f7cc16f5':
  vf_pad: don't give up its own reference to the output buffer.
  libvorbis: use VBR by default, with default quality of 3
  libvorbis: fix use of minrate/maxrate AVOptions
  h264: fix deadlocks on incomplete reference frame decoding.
  cmdutils: avoid setting data pointers to invalid values in alloc_buffer()
  avidec: return 0, not packet size from read_packet().
  wmapro: prevent division by zero when sample rate is unspecified
  vc1dec: check that coded slice positions and interlacing match.
  alsdec: fix number of decoded samples in first sub-block in BGMC mode.
  alsdec: remove dead assignments
  alsdec: Fix out of ltp_gain_values read.
  alsdec: Check that quantized parcor coeffs are within range.
  alsdec: Check k used for rice decoder.

Conflicts:
avconv.c
libavcodec/h264.c
libavcodec/libvorbis.c
libavformat/avidec.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
ffmpeg.c
libavcodec/alsdec.c
libavcodec/h264.c
libavcodec/libvorbis.c
libavcodec/options.c
libavcodec/vc1dec.c
libavcodec/wmaprodec.c
libavfilter/vf_pad.c
libavformat/avidec.c

diff --cc ffmpeg.c
+++ b/ffmpeg.c
@@@ -284,322 -290,46 +284,322 @@@ typedef struct OutputStream 
      AVFilterGraph *graph;
  #endif
  
 -   int sws_flags;
 -   AVDictionary *opts;
 +    int64_t sws_flags;
 +    AVDictionary *opts;
 +    int is_past_recording_time;
 +    int stream_copy;
 +    const char *attachment_filename;
 +    int copy_initial_nonkeyframes;
  } OutputStream;
  
 -static OutputStream **output_streams_for_file[MAX_FILES] = { NULL };
 -static int nb_output_streams_for_file[MAX_FILES] = { 0 };
  
 -typedef struct InputStream {
 -    int file_index;
 -    AVStream *st;
 -    int discard;             /* true if stream data should be discarded */
 -    int decoding_needed;     /* true if the packets must be decoded in 'raw_fifo' */
 -    AVCodec *dec;
 +#if HAVE_TERMIOS_H
  
 -    int64_t       start;     /* time when read started */
 -    int64_t       next_pts;  /* synthetic pts for cases where pkt.pts
 -                                is not defined */
 -    int64_t       pts;       /* current pts */
 -    PtsCorrectionContext pts_ctx;
 -    double ts_scale;
 -    int is_start;            /* is 1 at the start and after a discontinuity */
 -    int showed_multi_packet_warning;
 -    int is_past_recording_time;
 -    AVDictionary *opts;
 -} InputStream;
 +/* init terminal so that we can grab keys */
 +static struct termios oldtty;
 +static int restore_tty;
 +#endif
  
 -typedef struct InputFile {
 +typedef struct OutputFile {
      AVFormatContext *ctx;
 -    int eof_reached;      /* true if eof reached */
 -    int ist_index;        /* index of first stream in ist_table */
 -    int buffer_size;      /* current total buffer size */
 -    int64_t ts_offset;
 -    int nb_streams;       /* nb streams we are aware of */
 -} InputFile;
 +    AVDictionary *opts;
 +    int ost_index;       /* index of the first stream in output_streams */
 +    int64_t recording_time; /* desired length of the resulting file in microseconds */
 +    int64_t start_time;     /* start time in microseconds */
 +    uint64_t limit_filesize;
 +} OutputFile;
  
 -static InputStream *input_streams = NULL;
 +static InputStream *input_streams   = NULL;
  static int         nb_input_streams = 0;
 -static InputFile   *input_files   = NULL;
 +static InputFile   *input_files     = NULL;
  static int         nb_input_files   = 0;
  
-         else
 +static OutputStream *output_streams = NULL;
 +static int        nb_output_streams = 0;
 +static OutputFile   *output_files   = NULL;
 +static int        nb_output_files   = 0;
 +
 +typedef struct OptionsContext {
 +    /* input/output options */
 +    int64_t start_time;
 +    const char *format;
 +
 +    SpecifierOpt *codec_names;
 +    int        nb_codec_names;
 +    SpecifierOpt *audio_channels;
 +    int        nb_audio_channels;
 +    SpecifierOpt *audio_sample_rate;
 +    int        nb_audio_sample_rate;
 +    SpecifierOpt *rematrix_volume;
 +    int        nb_rematrix_volume;
 +    SpecifierOpt *frame_rates;
 +    int        nb_frame_rates;
 +    SpecifierOpt *frame_sizes;
 +    int        nb_frame_sizes;
 +    SpecifierOpt *frame_pix_fmts;
 +    int        nb_frame_pix_fmts;
 +
 +    /* input options */
 +    int64_t input_ts_offset;
 +    int rate_emu;
 +
 +    SpecifierOpt *ts_scale;
 +    int        nb_ts_scale;
 +    SpecifierOpt *dump_attachment;
 +    int        nb_dump_attachment;
 +
 +    /* output options */
 +    StreamMap *stream_maps;
 +    int     nb_stream_maps;
 +    AudioChannelMap *audio_channel_maps; ///< one info entry per -map_channel
 +    int           nb_audio_channel_maps; ///< number of (valid) -map_channel settings
 +    /* first item specifies output metadata, second is input */
 +    MetadataMap (*meta_data_maps)[2];
 +    int nb_meta_data_maps;
 +    int metadata_global_manual;
 +    int metadata_streams_manual;
 +    int metadata_chapters_manual;
 +    const char **attachments;
 +    int       nb_attachments;
 +
 +    int chapters_input_file;
 +
 +    int64_t recording_time;
 +    uint64_t limit_filesize;
 +    float mux_preload;
 +    float mux_max_delay;
 +
 +    int video_disable;
 +    int audio_disable;
 +    int subtitle_disable;
 +    int data_disable;
 +
 +    /* indexed by output file stream index */
 +    int   *streamid_map;
 +    int nb_streamid_map;
 +
 +    SpecifierOpt *metadata;
 +    int        nb_metadata;
 +    SpecifierOpt *max_frames;
 +    int        nb_max_frames;
 +    SpecifierOpt *bitstream_filters;
 +    int        nb_bitstream_filters;
 +    SpecifierOpt *codec_tags;
 +    int        nb_codec_tags;
 +    SpecifierOpt *sample_fmts;
 +    int        nb_sample_fmts;
 +    SpecifierOpt *qscale;
 +    int        nb_qscale;
 +    SpecifierOpt *forced_key_frames;
 +    int        nb_forced_key_frames;
 +    SpecifierOpt *force_fps;
 +    int        nb_force_fps;
 +    SpecifierOpt *frame_aspect_ratios;
 +    int        nb_frame_aspect_ratios;
 +    SpecifierOpt *rc_overrides;
 +    int        nb_rc_overrides;
 +    SpecifierOpt *intra_matrices;
 +    int        nb_intra_matrices;
 +    SpecifierOpt *inter_matrices;
 +    int        nb_inter_matrices;
 +    SpecifierOpt *top_field_first;
 +    int        nb_top_field_first;
 +    SpecifierOpt *metadata_map;
 +    int        nb_metadata_map;
 +    SpecifierOpt *presets;
 +    int        nb_presets;
 +    SpecifierOpt *copy_initial_nonkeyframes;
 +    int        nb_copy_initial_nonkeyframes;
 +#if CONFIG_AVFILTER
 +    SpecifierOpt *filters;
 +    int        nb_filters;
 +#endif
 +} OptionsContext;
 +
 +#define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\
 +{\
 +    int i, ret;\
 +    for (i = 0; i < o->nb_ ## name; i++) {\
 +        char *spec = o->name[i].specifier;\
 +        if ((ret = check_stream_specifier(fmtctx, st, spec)) > 0)\
 +            outvar = o->name[i].u.type;\
 +        else if (ret < 0)\
 +            exit_program(1);\
 +    }\
 +}
 +
 +static void reset_options(OptionsContext *o, int is_input)
 +{
 +    const OptionDef *po = options;
 +    OptionsContext bak= *o;
 +
 +    /* all OPT_SPEC and OPT_STRING can be freed in generic way */
 +    while (po->name) {
 +        void *dst = (uint8_t*)o + po->u.off;
 +
 +        if (po->flags & OPT_SPEC) {
 +            SpecifierOpt **so = dst;
 +            int i, *count = (int*)(so + 1);
 +            for (i = 0; i < *count; i++) {
 +                av_freep(&(*so)[i].specifier);
 +                if (po->flags & OPT_STRING)
 +                    av_freep(&(*so)[i].u.str);
 +            }
 +            av_freep(so);
 +            *count = 0;
 +        } else if (po->flags & OPT_OFFSET && po->flags & OPT_STRING)
 +            av_freep(dst);
 +        po++;
 +    }
 +
 +    av_freep(&o->stream_maps);
 +    av_freep(&o->audio_channel_maps);
 +    av_freep(&o->meta_data_maps);
 +    av_freep(&o->streamid_map);
 +
 +    memset(o, 0, sizeof(*o));
 +
 +    if(is_input) o->recording_time = bak.recording_time;
 +    else         o->recording_time = INT64_MAX;
 +    o->mux_max_delay  = 0.7;
 +    o->limit_filesize = UINT64_MAX;
 +    o->chapters_input_file = INT_MAX;
 +
 +    uninit_opts();
 +    init_opts();
 +}
 +
 +static int alloc_buffer(AVCodecContext *s, InputStream *ist, FrameBuffer **pbuf)
 +{
 +    FrameBuffer  *buf = av_mallocz(sizeof(*buf));
 +    int ret, i;
 +    const int pixel_size = av_pix_fmt_descriptors[s->pix_fmt].comp[0].step_minus1+1;
 +    int h_chroma_shift, v_chroma_shift;
 +    int edge = 32; // XXX should be avcodec_get_edge_width(), but that fails on svq1
 +    int w = s->width, h = s->height;
 +
 +    if (!buf)
 +        return AVERROR(ENOMEM);
 +
 +    if (!(s->flags & CODEC_FLAG_EMU_EDGE)) {
 +        w += 2*edge;
 +        h += 2*edge;
 +    }
 +
 +    avcodec_align_dimensions(s, &w, &h);
 +    if ((ret = av_image_alloc(buf->base, buf->linesize, w, h,
 +                              s->pix_fmt, 32)) < 0) {
 +        av_freep(&buf);
 +        return ret;
 +    }
 +    /* XXX this shouldn't be needed, but some tests break without this line
 +     * those decoders are buggy and need to be fixed.
 +     * the following tests fail:
 +     * bethsoft-vid, cdgraphics, ansi, aasc, fraps-v1, qtrle-1bit
 +     */
 +    memset(buf->base[0], 128, ret);
 +
 +    avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift);
 +    for (i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) {
 +        const int h_shift = i==0 ? 0 : h_chroma_shift;
 +        const int v_shift = i==0 ? 0 : v_chroma_shift;
 +        if (s->flags & CODEC_FLAG_EMU_EDGE)
 +            buf->data[i] = buf->base[i];
++        else if (buf->base[i])
 +            buf->data[i] = buf->base[i] +
 +                           FFALIGN((buf->linesize[i]*edge >> v_shift) +
 +                                   (pixel_size*edge >> h_shift), 32);
 +    }
 +    buf->w       = s->width;
 +    buf->h       = s->height;
 +    buf->pix_fmt = s->pix_fmt;
 +    buf->ist     = ist;
 +
 +    *pbuf = buf;
 +    return 0;
 +}
 +
 +static void free_buffer_pool(InputStream *ist)
 +{
 +    FrameBuffer *buf = ist->buffer_pool;
 +    while (buf) {
 +        ist->buffer_pool = buf->next;
 +        av_freep(&buf->base[0]);
 +        av_free(buf);
 +        buf = ist->buffer_pool;
 +    }
 +}
 +
 +static void unref_buffer(InputStream *ist, FrameBuffer *buf)
 +{
 +    av_assert0(buf->refcount);
 +    buf->refcount--;
 +    if (!buf->refcount) {
 +        buf->next = ist->buffer_pool;
 +        ist->buffer_pool = buf;
 +    }
 +}
 +
 +static int codec_get_buffer(AVCodecContext *s, AVFrame *frame)
 +{
 +    InputStream *ist = s->opaque;
 +    FrameBuffer *buf;
 +    int ret, i;
 +
 +    if(av_image_check_size(s->width, s->height, 0, s))
 +        return -1;
 +
 +    if (!ist->buffer_pool && (ret = alloc_buffer(s, ist, &ist->buffer_pool)) < 0)
 +        return ret;
 +
 +    buf              = ist->buffer_pool;
 +    ist->buffer_pool = buf->next;
 +    buf->next        = NULL;
 +    if (buf->w != s->width || buf->h != s->height || buf->pix_fmt != s->pix_fmt) {
 +        av_freep(&buf->base[0]);
 +        av_free(buf);
 +        ist->dr1 = 0;
 +        if ((ret = alloc_buffer(s, ist, &buf)) < 0)
 +            return ret;
 +    }
 +    buf->refcount++;
 +
 +    frame->opaque        = buf;
 +    frame->type          = FF_BUFFER_TYPE_USER;
 +    frame->extended_data = frame->data;
 +    frame->pkt_pts       = s->pkt ? s->pkt->pts : AV_NOPTS_VALUE;
 +
 +    for (i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) {
 +        frame->base[i]     = buf->base[i];  // XXX h264.c uses base though it shouldn't
 +        frame->data[i]     = buf->data[i];
 +        frame->linesize[i] = buf->linesize[i];
 +    }
 +
 +    return 0;
 +}
 +
 +static void codec_release_buffer(AVCodecContext *s, AVFrame *frame)
 +{
 +    InputStream *ist = s->opaque;
 +    FrameBuffer *buf = frame->opaque;
 +    int i;
 +
 +    if(frame->type!=FF_BUFFER_TYPE_USER)
 +        return avcodec_default_release_buffer(s, frame);
 +
 +    for (i = 0; i < FF_ARRAY_ELEMS(frame->data); i++)
 +        frame->data[i] = NULL;
 +
 +    unref_buffer(ist, buf);
 +}
 +
 +static void filter_release_buffer(AVFilterBuffer *fb)
 +{
 +    FrameBuffer *buf = fb->priv;
 +    av_free(fb);
 +    unref_buffer(buf->ist, buf);
 +}
 +
  #if CONFIG_AVFILTER
  
  static int configure_video_filters(InputStream *ist, OutputStream *ost)
Simple merge
@@@ -2880,10 -2880,22 +2886,22 @@@ static int decode_slice_header(H264Cont
      }
      h->mb_field_decoding_flag= s->picture_structure != PICT_FRAME;
  
-     if(h0->current_slice == 0){
-         // Shorten frame num gaps so we don't have to allocate reference frames just to throw them away
-         if(h->frame_num != h->prev_frame_num && h->prev_frame_num >= 0) {
-             int unwrap_prev_frame_num = h->prev_frame_num, max_frame_num = 1<<h->sps.log2_max_frame_num;
+     if (h0->current_slice != 0) {
+         if (last_pic_structure != s->picture_structure ||
+             last_pic_dropable  != s->dropable) {
+             av_log(h->s.avctx, AV_LOG_ERROR,
+                    "Changing field mode (%d -> %d) between slices is not allowed\n",
+                    last_pic_structure, s->picture_structure);
+             s->picture_structure = last_pic_structure;
+             s->dropable          = last_pic_dropable;
+             return AVERROR_INVALIDDATA;
+         }
+     } else {
+         /* Shorten frame num gaps so we don't have to allocate reference
+          * frames just to throw them away */
 -        if (h->frame_num != h->prev_frame_num) {
++        if (h->frame_num != h->prev_frame_num && h->prev_frame_num >= 0) {
+             int unwrap_prev_frame_num = h->prev_frame_num;
+             int max_frame_num         = 1 << h->sps.log2_max_frame_num;
  
              if (unwrap_prev_frame_num > h->frame_num) unwrap_prev_frame_num -= max_frame_num;
  
              }
          }
  
-         while(h->frame_num !=  h->prev_frame_num && h->prev_frame_num >= 0 &&
-               h->frame_num != (h->prev_frame_num+1)%(1<<h->sps.log2_max_frame_num)){
+         /* See if we have a decoded first field looking for a pair...
+          * Here, we're using that to see if we should mark previously
+          * decode frames as "finished".
+          * We have to do that before the "dummy" in-between frame allocation,
+          * since that can modify s->current_picture_ptr. */
+         if (s0->first_field) {
+             assert(s0->current_picture_ptr);
+             assert(s0->current_picture_ptr->f.data[0]);
+             assert(s0->current_picture_ptr->f.reference != DELAYED_PIC_REF);
+             /* Mark old field/frame as completed */
+             if (!last_pic_dropable && s0->current_picture_ptr->owner2 == s0) {
+                 ff_thread_report_progress(&s0->current_picture_ptr->f, INT_MAX,
+                                           last_pic_structure == PICT_BOTTOM_FIELD);
+             }
+             /* figure out if we have a complementary field pair */
+             if (!FIELD_PICTURE || s->picture_structure == last_pic_structure) {
+                 /* Previous field is unmatched. Don't display it, but let it
+                  * remain for reference if marked as such. */
+                 if (!last_pic_dropable && last_pic_structure != PICT_FRAME) {
+                     ff_thread_report_progress(&s0->current_picture_ptr->f, INT_MAX,
+                                               last_pic_structure == PICT_TOP_FIELD);
+                 }
+             } else {
+                 if (s0->current_picture_ptr->frame_num != h->frame_num) {
+                     /* This and previous field were reference, but had
+                      * different frame_nums. Consider this field first in
+                      * pair. Throw away previous field except for reference
+                      * purposes. */
+                     if (!last_pic_dropable && last_pic_structure != PICT_FRAME) {
+                         ff_thread_report_progress(&s0->current_picture_ptr->f, INT_MAX,
+                                                   last_pic_structure == PICT_TOP_FIELD);
+                     }
+                 } else {
+                     /* Second field in complementary pair */
+                     if (!((last_pic_structure   == PICT_TOP_FIELD &&
+                            s->picture_structure == PICT_BOTTOM_FIELD) ||
+                           (last_pic_structure   == PICT_BOTTOM_FIELD &&
+                            s->picture_structure == PICT_TOP_FIELD))) {
+                         av_log(s->avctx, AV_LOG_ERROR,
+                                "Invalid field mode combination %d/%d\n",
+                                last_pic_structure, s->picture_structure);
+                         s->picture_structure = last_pic_structure;
+                         s->dropable          = last_pic_dropable;
+                         return AVERROR_INVALIDDATA;
+                     } else if (last_pic_dropable != s->dropable) {
+                         av_log(s->avctx, AV_LOG_ERROR,
+                                "Cannot combine reference and non-reference fields in the same frame\n");
+                         av_log_ask_for_sample(s->avctx, NULL);
+                         s->picture_structure = last_pic_structure;
+                         s->dropable          = last_pic_dropable;
+                         return AVERROR_INVALIDDATA;
+                     }
+                     /* Take ownership of this buffer. Note that if another thread owned
+                      * the first field of this buffer, we're not operating on that pointer,
+                      * so the original thread is still responsible for reporting progress
+                      * on that first field (or if that was us, we just did that above).
+                      * By taking ownership, we assign responsibility to ourselves to
+                      * report progress on the second field. */
+                     s0->current_picture_ptr->owner2 = s0;
+                 }
+             }
+         }
 -        while (h->frame_num != h->prev_frame_num &&
++        while (h->frame_num != h->prev_frame_num && h->prev_frame_num >= 0 &&
+                h->frame_num != (h->prev_frame_num + 1) % (1 << h->sps.log2_max_frame_num)) {
              Picture *prev = h->short_ref_count ? h->short_ref[0] : NULL;
              av_log(h->s.avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n", h->frame_num, h->prev_frame_num);
              if (ff_h264_frame_start(h) < 0)
@@@ -3872,8 -3937,9 +3956,9 @@@ static int decode_nal_units(H264Contex
          switch(hx->nal_unit_type){
          case NAL_IDR_SLICE:
              if (h->nal_unit_type != NAL_IDR_SLICE) {
 -                av_log(h->s.avctx, AV_LOG_ERROR, "Invalid mix of idr and non-idr slices");
 +                av_log(h->s.avctx, AV_LOG_ERROR, "Invalid mix of idr and non-idr slices\n");
-                 return -1;
+                 buf_index = -1;
+                 goto end;
              }
              idr(h); // FIXME ensure we don't lose some frames if there is reordering
          case NAL_SLICE:
@@@ -59,18 -60,14 +60,24 @@@ static const AVOption options[] = 
      { "iblock", "Sets the impulse block bias", offsetof(OggVorbisContext, iblock), AV_OPT_TYPE_DOUBLE, { .dbl = 0 }, -15, 0, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
      { NULL }
  };
+ static const AVCodecDefault defaults[] = {
+     { "b",  "0" },
+     { NULL },
+ };
  static const AVClass class = { "libvorbis", av_default_item_name, options, LIBAVUTIL_VERSION_INT };
  
 +static const char * error(int oggerr, int *averr)
 +{
 +    switch (oggerr) {
 +        case OV_EFAULT: *averr = AVERROR(EFAULT); return "internal error";
 +        case OV_EIMPL:  *averr = AVERROR(EINVAL); return "not supported";
 +        case OV_EINVAL: *averr = AVERROR(EINVAL); return "invalid request";
 +        default:        *averr = AVERROR(EINVAL); return "unknown error";
 +    }
 +}
 +
  static av_cold int oggvorbis_init_encoder(vorbis_info *vi, AVCodecContext *avccontext)
  {
      OggVorbisContext *context = avccontext->priv_data;
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -1205,23 -1122,7 +1205,23 @@@ resync
              ast->packet_size= 0;
          }
  
-         return size;
 +        if(!avi->non_interleaved && pkt->pos >= 0 && ast->seek_pos > pkt->pos){
 +            av_free_packet(pkt);
 +            goto resync;
 +        }
 +        ast->seek_pos= 0;
 +
 +        if(!avi->non_interleaved && st->nb_index_entries>1 && avi->index_loaded>1){
 +            int64_t dts= av_rescale_q(pkt->dts, st->time_base, AV_TIME_BASE_Q);
 +
 +            if(avi->dts_max - dts > 2*AV_TIME_BASE){
 +                avi->non_interleaved= 1;
 +                av_log(s, AV_LOG_INFO, "Switching to NI mode, due to poor interleaving\n");
 +            }else if(avi->dts_max < dts)
 +                avi->dts_max = dts;
 +        }
 +
+         return 0;
      }
  
      if ((err = avi_sync(s, 0)) < 0)