Merge remote-tracking branch 'qatar/master'
authorMichael Niedermayer <michaelni@gmx.at>
Mon, 4 Jun 2012 20:54:15 +0000 (22:54 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Mon, 4 Jun 2012 20:59:32 +0000 (22:59 +0200)
* qatar/master:
  movenc: Write chan atom for all audio tracks in mov mode movies.
  mpegtsenc: use avio_open_dyn_buf(), zero pointers after freeing
  doc/avconv: add some details about the transcoding process.
  avidec: make scale and rate unsigned.
  avconv: check output stream recording time before each frame returned from filters
  avconv: split selecting input file out of transcode().
  avconv: split checking for active outputs out of transcode().
  avfiltergraph: make some functions static.

Conflicts:
ffmpeg.c
libavfilter/avfiltergraph.c
libavfilter/internal.h
libavformat/mpegtsenc.c
tests/ref/fate/acodec-alac
tests/ref/fate/acodec-pcm-s16be
tests/ref/fate/acodec-pcm-s24be
tests/ref/fate/acodec-pcm-s32be
tests/ref/fate/acodec-pcm-s8
tests/ref/lavf/mov

Merged-by: Michael Niedermayer <michaelni@gmx.at>
13 files changed:
1  2 
doc/ffmpeg.texi
ffmpeg.c
libavfilter/avfiltergraph.c
libavfilter/internal.h
libavformat/avidec.c
libavformat/movenc.c
libavformat/mpegtsenc.c
tests/ref/fate/acodec-alac
tests/ref/fate/acodec-pcm-s16be
tests/ref/fate/acodec-pcm-s24be
tests/ref/fate/acodec-pcm-s32be
tests/ref/fate/acodec-pcm-s8
tests/ref/lavf/mov

diff --cc doc/ffmpeg.texi
index e6d2aac24488703d308eea3db5393ce271110572,776a3263696084248f0c665ac1f5baaa9e6612a2..9f68bc8b90e82c464335c76efaded812c905de9a
@@@ -79,6 -79,126 +79,126 @@@ The format option may be needed for ra
  
  @c man end DESCRIPTION
  
 -The transcoding process in @command{avconv} for each output can be described by
+ @chapter Detailed description
+ @c man begin DETAILED DESCRIPTION
 -@command{avconv} calls the libavformat library (containing demuxers) to read
++The transcoding process in @command{ffmpeg} for each output can be described by
+ the following diagram:
+ @example
+  _______              ______________               _________              ______________            ________
+ |       |            |              |             |         |            |              |          |        |
+ | input |  demuxer   | encoded data |   decoder   | decoded |  encoder   | encoded data |  muxer   | output |
+ | file  | ---------> | packets      |  ---------> | frames  | ---------> | packets      | -------> | file   |
+ |_______|            |______________|             |_________|            |______________|          |________|
+ @end example
 -multiple input files, @command{avconv} tries to keep them synchronized by
++@command{ffmpeg} calls the libavformat library (containing demuxers) to read
+ input files and get packets containing encoded data from them. When there are
 -Before encoding, @command{avconv} can process raw audio and video frames using
++multiple input files, @command{ffmpeg} tries to keep them synchronized by
+ tracking lowest timestamp on any active input stream.
+ Encoded packets are then passed to the decoder (unless streamcopy is selected
+ for the stream, see further for a description). The decoder produces
+ uncompressed frames (raw video/PCM audio/...) which can be processed further by
+ filtering (see next section). After filtering the frames are passed to the
+ encoder, which encodes them and outputs encoded packets again. Finally those are
+ passed to the muxer, which writes the encoded packets to the output file.
+ @section Filtering
 -graph.  @command{avconv} distinguishes between two types of filtergraphs -
++Before encoding, @command{ffmpeg} can process raw audio and video frames using
+ filters from the libavfilter library. Several chained filters form a filter
 -@option{-codec} option. It makes @command{avconv} omit the decoding and encoding
++graph.  @command{ffmpeg} distinguishes between two types of filtergraphs -
+ simple and complex.
+ @subsection Simple filtergraphs
+ Simple filtergraphs are those that have exactly one input and output, both of
+ the same type. In the above diagram they can be represented by simply inserting
+ an additional step between decoding and encoding:
+ @example
+  _________                        __________              ______________
+ |         |                      |          |            |              |
+ | decoded |  simple filtergraph  | filtered |  encoder   | encoded data |
+ | frames  | -------------------> | frames   | ---------> | packets      |
+ |_________|                      |__________|            |______________|
+ @end example
+ Simple filtergraphs are configured with the per-stream @option{-filter} option
+ (with @option{-vf} and @option{-af} aliases for video and audio respectively).
+ A simple filtergraph for video can look for example like this:
+ @example
+  _______        _____________        _______        _____        ________
+ |       |      |             |      |       |      |     |      |        |
+ | input | ---> | deinterlace | ---> | scale | ---> | fps | ---> | output |
+ |_______|      |_____________|      |_______|      |_____|      |________|
+ @end example
+ Note that some filters change frame properties but not frame contents. E.g. the
+ @code{fps} filter in the example above changes number of frames, but does not
+ touch the frame contents. Another example is the @code{setpts} filter, which
+ only sets timestamps and otherwise passes the frames unchanged.
+ @subsection Complex filtergraphs
+ Complex filtergraphs are those which cannot be described as simply a linear
+ processing chain applied to one stream. This is the case e.g. when the graph has
+ more than one input and/or output, or when output stream type is different from
+ input. They can be represented with the following diagram:
+ @example
+  _________
+ |         |
+ | input 0 |\                    __________
+ |_________| \                  |          |
+              \   _________    /| output 0 |
+               \ |         |  / |__________|
+  _________     \| complex | /
+ |         |     |         |/
+ | input 1 |---->| filter  |\
+ |_________|     |         | \   __________
+                /| graph   |  \ |          |
+               / |         |   \| output 1 |
+  _________   /  |_________|    |__________|
+ |         | /
+ | input 2 |/
+ |_________|
+ @end example
+ Complex filtergraphs are configured with the @option{-filter_complex} option.
+ Note that this option is global, since a complex filtergraph by its nature
+ cannot be unambiguously associated with a single stream or file.
+ A trivial example of a complex filtergraph is the @code{overlay} filter, which
+ has two video inputs and one video output, containing one video overlaid on top
+ of the other. Its audio counterpart is the @code{amix} filter.
+ @section Stream copy
+ Stream copy is a mode selected by supplying the @code{copy} parameter to the
++@option{-codec} option. It makes @command{ffmpeg} omit the decoding and encoding
+ step for the specified stream, so it does only demuxing and muxing. It is useful
+ for changing the container format or modifying container-level metadata. The
+ diagram above will in this case simplify to this:
+ @example
+  _______              ______________            ________
+ |       |            |              |          |        |
+ | input |  demuxer   | encoded data |  muxer   | output |
+ | file  | ---------> | packets      | -------> | file   |
+ |_______|            |______________|          |________|
+ @end example
+ Since there is no decoding or encoding, it is very fast and there is no quality
+ loss. However it might not work in some cases because of many factors. Applying
+ filters is obviously also impossible, since filters work on uncompressed data.
+ @c man end DETAILED DESCRIPTION
  @chapter Stream selection
  @c man begin STREAM SELECTION
  
diff --cc ffmpeg.c
index 4d36bc443c30c326c4d66ae287c18c27d7597a5d,3cbdfab1430382ad34224545dff8e9f3ff8ec38d..a897c9e917aca8c9043d27868b3aa391b1619fca
+++ b/ffmpeg.c
@@@ -2016,113 -1661,73 +2016,113 @@@ static int poll_filters(void
  {
      AVFilterBufferRef *picref;
      AVFrame *filtered_frame = NULL;
 -    int i, frame_size;
 +    int i, ret, ret_all;
 +    unsigned nb_success, nb_eof;
 +    int64_t frame_pts;
  
 -    for (i = 0; i < nb_output_streams; i++) {
 -        OutputStream *ost = output_streams[i];
 -        OutputFile    *of = output_files[ost->file_index];
 -        int ret = 0;
 +    while (1) {
 +        /* Reap all buffers present in the buffer sinks */
 +        for (i = 0; i < nb_output_streams; i++) {
 +            OutputStream *ost = output_streams[i];
 +            OutputFile    *of = output_files[ost->file_index];
 +            int ret = 0;
  
-             if (!ost->filter || ost->is_past_recording_time)
 -        if (!ost->filter)
 -            continue;
++            if (!ost->filter)
 +                continue;
  
 -        if (!ost->filtered_frame && !(ost->filtered_frame = avcodec_alloc_frame())) {
 -            return AVERROR(ENOMEM);
 -        } else
 -            avcodec_get_frame_defaults(ost->filtered_frame);
 -        filtered_frame = ost->filtered_frame;
 -
 -        while (ret >= 0 && !ost->is_past_recording_time) {
 -            if (ost->enc->type == AVMEDIA_TYPE_AUDIO &&
 -                !(ost->enc->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE))
 -                ret = av_buffersink_read_samples(ost->filter->filter, &picref,
 -                                                 ost->st->codec->frame_size);
 -            else
 -                ret = av_buffersink_read(ost->filter->filter, &picref);
 +            if (!ost->filtered_frame && !(ost->filtered_frame = avcodec_alloc_frame())) {
 +                return AVERROR(ENOMEM);
 +            } else
 +                avcodec_get_frame_defaults(ost->filtered_frame);
 +            filtered_frame = ost->filtered_frame;
 +
-             while (1) {
++            while (!ost->is_past_recording_time) {
 +                if (ost->enc->type == AVMEDIA_TYPE_AUDIO &&
 +                    !(ost->enc->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE))
 +                    ret = av_buffersink_read_samples(ost->filter->filter, &picref,
 +                                                    ost->st->codec->frame_size);
 +                else
 +#ifdef SINKA
 +                    ret = av_buffersink_read(ost->filter->filter, &picref);
 +#else
 +                    ret = av_buffersink_get_buffer_ref(ost->filter->filter, &picref,
 +                                                       AV_BUFFERSINK_FLAG_NO_REQUEST);
 +#endif
 +                if (ret < 0) {
 +                    if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) {
 +                        char buf[256];
 +                        av_strerror(ret, buf, sizeof(buf));
 +                        av_log(NULL, AV_LOG_WARNING,
 +                               "Error in av_buffersink_get_buffer_ref(): %s\n", buf);
 +                    }
 +                    break;
 +                }
 +                frame_pts = AV_NOPTS_VALUE;
 +                if (picref->pts != AV_NOPTS_VALUE) {
 +                    filtered_frame->pts = frame_pts = av_rescale_q(picref->pts,
 +                                                    ost->filter->filter->inputs[0]->time_base,
 +                                                    ost->st->codec->time_base) -
 +                                        av_rescale_q(of->start_time,
 +                                                    AV_TIME_BASE_Q,
 +                                                    ost->st->codec->time_base);
 +
 +                    if (of->start_time && filtered_frame->pts < 0) {
 +                        avfilter_unref_buffer(picref);
 +                        continue;
 +                    }
 +                }
 +                //if (ost->source_index >= 0)
 +                //    *filtered_frame= *input_streams[ost->source_index]->decoded_frame; //for me_threshold
  
 -            if (ret < 0)
 -                break;
  
 -            avfilter_copy_buf_props(filtered_frame, picref);
 -            if (picref->pts != AV_NOPTS_VALUE)
 -                filtered_frame->pts = av_rescale_q(picref->pts,
 -                                                   ost->filter->filter->inputs[0]->time_base,
 -                                                   ost->st->codec->time_base) -
 -                                      av_rescale_q(of->start_time,
 -                                                   AV_TIME_BASE_Q,
 -                                                   ost->st->codec->time_base);
 +                switch (ost->filter->filter->inputs[0]->type) {
 +                case AVMEDIA_TYPE_VIDEO:
 +                    avfilter_fill_frame_from_video_buffer_ref(filtered_frame, picref);
 +                    filtered_frame->pts = frame_pts;
 +                    if (!ost->frame_aspect_ratio)
 +                        ost->st->codec->sample_aspect_ratio = picref->video->sample_aspect_ratio;
 +
 +                    do_video_out(of->ctx, ost, filtered_frame,
 +                                 same_quant ? ost->last_quality :
 +                                              ost->st->codec->global_quality);
 +                    break;
 +                case AVMEDIA_TYPE_AUDIO:
 +                    avfilter_copy_buf_props(filtered_frame, picref);
 +                    filtered_frame->pts = frame_pts;
 +                    do_audio_out(of->ctx, ost, filtered_frame);
 +                    break;
 +                default:
 +                    // TODO support subtitle filters
 +                    av_assert0(0);
 +                }
  
 -            if (of->start_time && filtered_frame->pts < of->start_time) {
                  avfilter_unref_buffer(picref);
 -                continue;
              }
 -
 -            switch (ost->filter->filter->inputs[0]->type) {
 -            case AVMEDIA_TYPE_VIDEO:
 -                if (!ost->frame_aspect_ratio)
 -                    ost->st->codec->sample_aspect_ratio = picref->video->pixel_aspect;
 -
 -                do_video_out(of->ctx, ost, filtered_frame, &frame_size,
 -                             same_quant ? ost->last_quality :
 -                                          ost->st->codec->global_quality);
 -                if (vstats_filename && frame_size)
 -                    do_video_stats(of->ctx, ost, frame_size);
 -                break;
 -            case AVMEDIA_TYPE_AUDIO:
 -                do_audio_out(of->ctx, ost, filtered_frame);
 -                break;
 -            default:
 -                // TODO support subtitle filters
 -                av_assert0(0);
 +        }
 +        /* Request frames through all the graphs */
 +        ret_all = nb_success = nb_eof = 0;
 +        for (i = 0; i < nb_filtergraphs; i++) {
 +            ret = avfilter_graph_request_oldest(filtergraphs[i]->graph);
 +            if (!ret) {
 +                nb_success++;
 +            } else if (ret == AVERROR_EOF) {
 +                nb_eof++;
 +            } else if (ret != AVERROR(EAGAIN)) {
 +                char buf[256];
 +                av_strerror(ret, buf, sizeof(buf));
 +                av_log(NULL, AV_LOG_WARNING,
 +                       "Error in request_frame(): %s\n", buf);
 +                ret_all = ret;
              }
 -
 -            avfilter_unref_buffer(picref);
          }
 +        if (!nb_success)
 +            break;
 +        /* Try again if anything succeeded */
      }
 -    return 0;
 +    return nb_eof == nb_filtergraphs ? AVERROR_EOF : ret_all;
  }
  
 -static void print_report(int is_last_report, int64_t timer_start)
 +static void print_report(int is_last_report, int64_t timer_start, int64_t cur_time)
  {
      char buf[1024];
      OutputStream *ost;
@@@ -3307,6 -2855,57 +3307,57 @@@ static int transcode_init(void
      return 0;
  }
  
 -        if (ost->frame_number > ost->max_frames) {
+ /**
+  * @return 1 if there are still streams where more output is wanted,
+  *         0 otherwise
+  */
+ static int need_output(void)
+ {
+     int i;
+     for (i = 0; i < nb_output_streams; i++) {
+         OutputStream *ost    = output_streams[i];
+         OutputFile *of       = output_files[ost->file_index];
+         AVFormatContext *os  = output_files[ost->file_index]->ctx;
+         if (ost->is_past_recording_time ||
+             (os->pb && avio_tell(os->pb) >= of->limit_filesize))
+             continue;
 -        int64_t ipts     = ist->last_dts;
++        if (ost->frame_number >= ost->max_frames) {
+             int j;
+             for (j = 0; j < of->ctx->nb_streams; j++)
+                 output_streams[of->ost_index + j]->is_past_recording_time = 1;
+             continue;
+         }
+         return 1;
+     }
+     return 0;
+ }
+ static int select_input_file(uint8_t *no_packet)
+ {
+     int64_t ipts_min = INT64_MAX;
+     int i, file_index = -1;
+     for (i = 0; i < nb_input_streams; i++) {
+         InputStream *ist = input_streams[i];
++        int64_t ipts     = ist->pts;
+         if (ist->discard || no_packet[ist->file_index])
+             continue;
+         if (!input_files[ist->file_index]->eof_reached) {
+             if (ipts < ipts_min) {
+                 ipts_min = ipts;
+                 file_index = ist->file_index;
+             }
+         }
+     }
+     return file_index;
+ }
  /*
   * The following code is the main loop of the file converter
   */
@@@ -3335,139 -2932,17 +3386,109 @@@ static int transcode(void
      timer_start = av_gettime();
  
      for (; received_sigterm == 0;) {
-         int file_index, ist_index, past_recording_time = 1;
+         int file_index, ist_index;
          AVPacket pkt;
-         int64_t ipts_min;
 +        int64_t cur_time= av_gettime();
 +
-         ipts_min = INT64_MAX;
 +        /* if 'q' pressed, exits */
 +        if (!using_stdin) {
 +            static int64_t last_time;
 +            if (received_nb_signals)
 +                break;
 +            /* read_key() returns 0 on EOF */
 +            if(cur_time - last_time >= 100000 && !run_as_daemon){
 +                key =  read_key();
 +                last_time = cur_time;
 +            }else
 +                key = -1;
 +            if (key == 'q')
 +                break;
 +            if (key == '+') av_log_set_level(av_log_get_level()+10);
 +            if (key == '-') av_log_set_level(av_log_get_level()-10);
 +            if (key == 's') qp_hist     ^= 1;
 +            if (key == 'h'){
 +                if (do_hex_dump){
 +                    do_hex_dump = do_pkt_dump = 0;
 +                } else if(do_pkt_dump){
 +                    do_hex_dump = 1;
 +                } else
 +                    do_pkt_dump = 1;
 +                av_log_set_level(AV_LOG_DEBUG);
 +            }
 +            if (key == 'c' || key == 'C'){
 +                char buf[4096], target[64], command[256], arg[256] = {0};
 +                double time;
 +                int k, n = 0;
 +                fprintf(stderr, "\nEnter command: <target> <time> <command>[ <argument>]\n");
 +                i = 0;
 +                while ((k = read_key()) != '\n' && k != '\r' && i < sizeof(buf)-1)
 +                    if (k > 0)
 +                        buf[i++] = k;
 +                buf[i] = 0;
 +                if (k > 0 &&
 +                    (n = sscanf(buf, "%63[^ ] %lf %255[^ ] %255[^\n]", target, &time, command, arg)) >= 3) {
 +                    av_log(NULL, AV_LOG_DEBUG, "Processing command target:%s time:%f command:%s arg:%s",
 +                           target, time, command, arg);
 +                    for (i = 0; i < nb_filtergraphs; i++) {
 +                        FilterGraph *fg = filtergraphs[i];
 +                        if (fg->graph) {
 +                            if (time < 0) {
 +                                ret = avfilter_graph_send_command(fg->graph, target, command, arg, buf, sizeof(buf),
 +                                                                  key == 'c' ? AVFILTER_CMD_FLAG_ONE : 0);
 +                                fprintf(stderr, "Command reply for stream %d: ret:%d res:%s\n", i, ret, buf);
 +                            } else {
 +                                ret = avfilter_graph_queue_command(fg->graph, target, command, arg, 0, time);
 +                            }
 +                        }
 +                    }
 +                } else {
 +                    av_log(NULL, AV_LOG_ERROR,
 +                           "Parse error, at least 3 arguments were expected, "
 +                           "only %d given in string '%s'\n", n, buf);
 +                }
 +            }
 +            if (key == 'd' || key == 'D'){
 +                int debug=0;
 +                if(key == 'D') {
 +                    debug = input_streams[0]->st->codec->debug<<1;
 +                    if(!debug) debug = 1;
 +                    while(debug & (FF_DEBUG_DCT_COEFF|FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE)) //unsupported, would just crash
 +                        debug += debug;
 +                }else
 +                    if(scanf("%d", &debug)!=1)
 +                        fprintf(stderr,"error parsing debug value\n");
 +                for(i=0;i<nb_input_streams;i++) {
 +                    input_streams[i]->st->codec->debug = debug;
 +                }
 +                for(i=0;i<nb_output_streams;i++) {
 +                    ost = output_streams[i];
 +                    ost->st->codec->debug = debug;
 +                }
 +                if(debug) av_log_set_level(AV_LOG_DEBUG);
 +                fprintf(stderr,"debug=%d\n", debug);
 +            }
 +            if (key == '?'){
 +                fprintf(stderr, "key    function\n"
 +                                "?      show this help\n"
 +                                "+      increase verbosity\n"
 +                                "-      decrease verbosity\n"
 +                                "c      Send command to filtergraph\n"
 +                                "D      cycle through available debug modes\n"
 +                                "h      dump packets/hex press to cycle through the 3 states\n"
 +                                "q      quit\n"
 +                                "s      Show QP histogram\n"
 +                );
 +            }
 +        }
  
          /* check if there's any stream where output is still needed */
-         for (i = 0; i < nb_output_streams; i++) {
-             OutputFile *of;
-             ost = output_streams[i];
-             of  = output_files[ost->file_index];
-             os  = output_files[ost->file_index]->ctx;
-             if (ost->is_past_recording_time ||
-                 (os->pb && avio_tell(os->pb) >= of->limit_filesize))
-                 continue;
-             if (ost->frame_number >= ost->max_frames) {
-                 int j;
-                 for (j = 0; j < of->ctx->nb_streams; j++)
-                     output_streams[of->ost_index + j]->is_past_recording_time = 1;
-                 continue;
-             }
-             past_recording_time = 0;
-         }
-         if (past_recording_time)
+         if (!need_output()) {
+             av_log(NULL, AV_LOG_VERBOSE, "No more output streams to write to, finishing.\n");
              break;
-         /* select the stream that we must read now by looking at the
-            smallest output pts */
-         file_index = -1;
-         for (i = 0; i < nb_input_streams; i++) {
-             int64_t ipts;
-             ist = input_streams[i];
-             ipts = ist->pts;
-             if (ist->discard || no_packet[ist->file_index])
-                 continue;
-             if (!input_files[ist->file_index]->eof_reached) {
-                 if (ipts < ipts_min) {
-                     ipts_min = ipts;
-                     file_index = ist->file_index;
-                 }
-             }
          }
+         /* select the stream that we must read now */
+         file_index = select_input_file(no_packet);
          /* if none, if is finished */
          if (file_index < 0) {
              if (no_packet_count) {
index 8d2312e05d5dbf40cc6d6122ef2b39bc70e4cade,bc275142d269d9c47ee39cec3d012269b126f16d..da5015ca88b2270d107613c602343584c397cf5e
@@@ -97,12 -93,15 +97,20 @@@ fail
      return ret;
  }
  
- int ff_avfilter_graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
 +void avfilter_graph_set_auto_convert(AVFilterGraph *graph, unsigned flags)
 +{
 +    graph->disable_auto_convert = flags;
 +}
 +
+ /**
+  * Check for the validity of graph.
+  *
+  * A graph is considered valid if all its input and output pads are
+  * connected.
+  *
+  * @return 0 in case of success, a negative value otherwise
+  */
+ static int graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
  {
      AVFilterContext *filt;
      int i, j;
@@@ -759,14 -591,12 +775,14 @@@ int avfilter_graph_config(AVFilterGrap
  {
      int ret;
  
-     if ((ret = ff_avfilter_graph_check_validity(graphctx, log_ctx)))
+     if ((ret = graph_check_validity(graphctx, log_ctx)))
          return ret;
-     if ((ret = ff_avfilter_graph_config_formats(graphctx, log_ctx)))
+     if ((ret = graph_config_formats(graphctx, log_ctx)))
          return ret;
-     if ((ret = ff_avfilter_graph_config_links(graphctx, log_ctx)))
+     if ((ret = graph_config_links(graphctx, log_ctx)))
          return ret;
 +    if ((ret = ff_avfilter_graph_config_pointers(graphctx, log_ctx)))
 +        return ret;
  
      return 0;
  }
index bb45274e27590c709da077d4576c999153ccf683,4eb65305f9b994166b72579e4eebd57eef509803..595fdaeb12a1843fcd3997b561567cf526329fdb
   */
  
  #include "avfilter.h"
- /**
-  * Check for the validity of graph.
-  *
-  * A graph is considered valid if all its input and output pads are
-  * connected.
-  *
-  * @return 0 in case of success, a negative value otherwise
-  */
- int ff_avfilter_graph_check_validity(AVFilterGraph *graphctx, AVClass *log_ctx);
- /**
-  * Configure all the links of graphctx.
-  *
-  * @return 0 in case of success, a negative value otherwise
-  */
- int ff_avfilter_graph_config_links(AVFilterGraph *graphctx, AVClass *log_ctx);
- /**
-  * Configure the formats of all the links in the graph.
-  */
- int ff_avfilter_graph_config_formats(AVFilterGraph *graphctx, AVClass *log_ctx);
 +#include "avfiltergraph.h"
 +#include "formats.h"
 +
 +#define POOL_SIZE 32
 +typedef struct AVFilterPool {
 +    AVFilterBufferRef *pic[POOL_SIZE];
 +    int count;
 +    int refcount;
 +    int draining;
 +} AVFilterPool;
 +
 +typedef struct AVFilterCommand {
 +    double time;                ///< time expressed in seconds
 +    char *command;              ///< command
 +    char *arg;                  ///< optional argument for the command
 +    int flags;
 +    struct AVFilterCommand *next;
 +} AVFilterCommand;
 +
 +/**
 + * Update the position of a link in the age heap.
 + */
 +void ff_avfilter_graph_update_heap(AVFilterGraph *graph, AVFilterLink *link);
  
  /** default handler for freeing audio/video buffer when there are no references left */
  void ff_avfilter_default_free_buffer(AVFilterBuffer *buf);
Simple merge
Simple merge
Simple merge
index 6f52d8b0840d4b21d412126f247163ac9eced602,bb7a20242d99c666d23ac809de69ba9fbcc0e6cb..d923719ed83dc2fa86cf6fa26e3fc3c25a593708
@@@ -1,4 -1,4 +1,4 @@@
- 1e5266b204b33ab4608e368d309716cb *tests/data/fate/acodec-alac.mov
- 388994 tests/data/fate/acodec-alac.mov
 -8ad790d3a0bbda81cd23c15ab8ba760d *tests/data/fate/acodec-alac.mov
 -389258 tests/data/fate/acodec-alac.mov
++f01f453dd13c4e88266409cddf2a7177 *tests/data/fate/acodec-alac.mov
++389018 tests/data/fate/acodec-alac.mov
  64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-alac.out.wav
  stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  1058400/  1058400
index 00285b8bfd10ded23aa966ee6c212737750c1855,06614e1067c7d91b67987429ddfa7325ef3f06f3..1cf04ed45e559b848de4b1506cb2810404c76776
@@@ -1,4 -1,4 +1,4 @@@
- a874f5c08b8d104a6bbf41b21454180d *tests/data/fate/acodec-pcm-s16be.mov
- 1059045 tests/data/fate/acodec-pcm-s16be.mov
 -b023c4792bd206fa96f64a8a012b6eb8 *tests/data/fate/acodec-pcm-s16be.mov
 -1060097 tests/data/fate/acodec-pcm-s16be.mov
++8bffa66afe9e17366af11e77882518a0 *tests/data/fate/acodec-pcm-s16be.mov
++1059069 tests/data/fate/acodec-pcm-s16be.mov
  64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-pcm-s16be.out.wav
  stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  1058400/  1058400
index 894844a1c280e251d4eff81ff9f5b0c584876f1f,c6a58891341aff377485039c1799491713cd9dba..d0376a6eafeae9484ac69748facfe853c5c86326
@@@ -1,4 -1,4 +1,4 @@@
- 833d4afd907139af7106a5642a9c23d3 *tests/data/fate/acodec-pcm-s24be.mov
- 1588245 tests/data/fate/acodec-pcm-s24be.mov
 -3607f8c7029a0c2ca2c8bf2c929518b3 *tests/data/fate/acodec-pcm-s24be.mov
 -1589297 tests/data/fate/acodec-pcm-s24be.mov
++e3013cfce9b792acb9d572268012160d *tests/data/fate/acodec-pcm-s24be.mov
++1588269 tests/data/fate/acodec-pcm-s24be.mov
  64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-pcm-s24be.out.wav
  stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  1058400/  1058400
index 5360fc10384370b975a7d8bc79bcd3f94b70821a,8d77642b6b3007f8d49267d9d690c379af1a48e4..656a6b2a61eebe4b79b8be29dd33735fd42c02e2
@@@ -1,4 -1,4 +1,4 @@@
- c02c96e37b321f2c978968e3a102c669 *tests/data/fate/acodec-pcm-s32be.mov
- 2117449 tests/data/fate/acodec-pcm-s32be.mov
 -2a47292543cb0c25583a49397504e6d1 *tests/data/fate/acodec-pcm-s32be.mov
 -2118497 tests/data/fate/acodec-pcm-s32be.mov
++f3ef00480e89c5c791e87b8af1cc167c *tests/data/fate/acodec-pcm-s32be.mov
++2117473 tests/data/fate/acodec-pcm-s32be.mov
  64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-pcm-s32be.out.wav
  stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  1058400/  1058400
index e7c09f44303e61d5d9ef7948aa619231bc747668,2689bf286a79166a2201d6ffa5d5e1114c601284..cabf004983ff7d87052ffbe5c0653fafc5a57909
@@@ -1,4 -1,4 +1,4 @@@
- 111d465266385298fde83005402ac171 *tests/data/fate/acodec-pcm-s8.mov
- 529829 tests/data/fate/acodec-pcm-s8.mov
 -953eb563c7ea81c1ec73c5a806975e34 *tests/data/fate/acodec-pcm-s8.mov
 -530897 tests/data/fate/acodec-pcm-s8.mov
++2c504a4e48c19ea1b0e1705893b771bf *tests/data/fate/acodec-pcm-s8.mov
++529853 tests/data/fate/acodec-pcm-s8.mov
  651d4eb8d98dfcdda96ae6c43d8f156b *tests/data/fate/acodec-pcm-s8.out.wav
  stddev:  147.89 PSNR: 52.93 MAXDIFF:  255 bytes:  1058400/  1058400
index 7487ff2f847519c926091fb11a5b7c9e797f120c,2db01d4aebe80caf99b069956e881de542feaaa2..b9b020cd80ff7de9ccd435147ffa34b4e45b21b5
@@@ -1,12 -1,3 +1,12 @@@
- 83754d7142a7770ac374f75b729a9319 *./tests/data/lavf/lavf.mov
- 367322 ./tests/data/lavf/lavf.mov
 -a5c982910b1a1547db68ffa35cc2a05a *./tests/data/lavf/lavf.mov
 -357741 ./tests/data/lavf/lavf.mov
++484aeef3be3eb4deef05c83bdc2dd484 *./tests/data/lavf/lavf.mov
++367346 ./tests/data/lavf/lavf.mov
 +./tests/data/lavf/lavf.mov CRC=0x2f6a9b26
- 9a0b239ff596da58debcf210dece3985 *./tests/data/lavf/lavf.mov
- 357821 ./tests/data/lavf/lavf.mov
++305a68397e3cdb505704841fedcdc352 *./tests/data/lavf/lavf.mov
++357845 ./tests/data/lavf/lavf.mov
 +./tests/data/lavf/lavf.mov CRC=0x2f6a9b26
- cea874222a6d40b1761d75ea11ebe681 *./tests/data/lavf/lavf.mov
- 367251 ./tests/data/lavf/lavf.mov
++6e047bce400f2c4a840f783dee1ae030 *./tests/data/lavf/lavf.mov
++367275 ./tests/data/lavf/lavf.mov
 +./tests/data/lavf/lavf.mov CRC=0xab307eb9
- 9a0b239ff596da58debcf210dece3985 *./tests/data/lavf/lavf.mov
- 357821 ./tests/data/lavf/lavf.mov
++305a68397e3cdb505704841fedcdc352 *./tests/data/lavf/lavf.mov
++357845 ./tests/data/lavf/lavf.mov
  ./tests/data/lavf/lavf.mov CRC=0x2f6a9b26