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:
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

index e6d2aac..9f68bc8 100644 (file)
@@ -79,6 +79,126 @@ The format option may be needed for raw input files.
 
 @c man end DESCRIPTION
 
+@chapter Detailed description
+@c man begin DETAILED DESCRIPTION
+
+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
+
+@command{ffmpeg} calls the libavformat library (containing demuxers) to read
+input files and get packets containing encoded data from them. When there are
+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
+Before encoding, @command{ffmpeg} can process raw audio and video frames using
+filters from the libavfilter library. Several chained filters form a filter
+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
 
index 4d36bc4..a897c9e 100644 (file)
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -2027,7 +2027,7 @@ static int poll_filters(void)
             OutputFile    *of = output_files[ost->file_index];
             int ret = 0;
 
-            if (!ost->filter || ost->is_past_recording_time)
+            if (!ost->filter)
                 continue;
 
             if (!ost->filtered_frame && !(ost->filtered_frame = avcodec_alloc_frame())) {
@@ -2036,7 +2036,7 @@ static int poll_filters(void)
                 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,
@@ -3307,6 +3307,57 @@ static int transcode_init(void)
     return 0;
 }
 
+/**
+ * @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;
+        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,12 +3386,10 @@ 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;
@@ -3433,41 +3482,13 @@ static int transcode(void)
         }
 
         /* 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 8d2312e..da5015c 100644 (file)
@@ -102,7 +102,15 @@ void avfilter_graph_set_auto_convert(AVFilterGraph *graph, unsigned flags)
     graph->disable_auto_convert = flags;
 }
 
-int ff_avfilter_graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
+/**
+ * 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;
@@ -132,7 +140,12 @@ int ff_avfilter_graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
     return 0;
 }
 
-int ff_avfilter_graph_config_links(AVFilterGraph *graph, AVClass *log_ctx)
+/**
+ * Configure all the links of graphctx.
+ *
+ * @return 0 in case of success, a negative value otherwise
+ */
+static int graph_config_links(AVFilterGraph *graph, AVClass *log_ctx)
 {
     AVFilterContext *filt;
     int i, ret;
@@ -688,7 +701,10 @@ static int pick_formats(AVFilterGraph *graph)
     return 0;
 }
 
-int ff_avfilter_graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx)
+/**
+ * Configure the formats of all the links in the graph.
+ */
+static int graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx)
 {
     int ret;
 
@@ -759,11 +775,11 @@ int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)
 {
     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;
index bb45274..595fdae 100644 (file)
@@ -45,28 +45,6 @@ typedef struct AVFilterCommand {
 } AVFilterCommand;
 
 /**
- * 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);
-
-/**
  * Update the position of a link in the age heap.
  */
 void ff_avfilter_graph_update_heap(AVFilterGraph *graph, AVFilterLink *link);
index 24aacd0..fea0694 100644 (file)
@@ -40,8 +40,8 @@ typedef struct AVIStream {
     int remaining;
     int packet_size;
 
-    int scale;
-    int rate;
+    uint32_t scale;
+    uint32_t rate;
     int sample_size; /* size of one sample (or packet) (in the rate/scale sense) in bytes */
 
     int64_t cum_len; /* temporary storage (used during seek) */
index 54deef4..fce6bfc 100644 (file)
@@ -422,7 +422,6 @@ static int mov_write_wave_tag(AVIOContext *pb, MOVTrack *track)
     } else if (track->enc->codec_id == CODEC_ID_AMR_NB) {
         mov_write_amr_tag(pb, track);
     } else if (track->enc->codec_id == CODEC_ID_AC3) {
-        mov_write_chan_tag(pb, track);
         mov_write_ac3_tag(pb, track);
     } else if (track->enc->codec_id == CODEC_ID_ALAC) {
         mov_write_extradata_tag(pb, track);
@@ -695,6 +694,9 @@ static int mov_write_audio_tag(AVIOContext *pb, MOVTrack *track)
     else if (track->vos_len > 0)
         mov_write_glbl_tag(pb, track);
 
+    if (track->mode == MODE_MOV && track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
+        mov_write_chan_tag(pb, track);
+
     return update_size(pb, pos);
 }
 
index 1df8044..9e95718 100644 (file)
@@ -232,10 +232,6 @@ typedef struct MpegTSWriteStream {
     int64_t payload_dts;
     int payload_flags;
     uint8_t *payload;
-
-    uint8_t *adata;
-    int adata_pos;
-    int adata_size;
     AVFormatContext *amux;
 } MpegTSWriteStream;
 
@@ -503,19 +499,6 @@ static void section_write_packet(MpegTSSection *s, const uint8_t *packet)
     avio_write(ctx->pb, packet, TS_PACKET_SIZE);
 }
 
-/* Write callback for audio packetizer */
-static int mpegts_audio_write(void *opaque, uint8_t *buf, int size)
-{
-    MpegTSWriteStream *ts_st = (MpegTSWriteStream *)opaque;
-    if (ts_st->adata_pos + (int64_t)size > ts_st->adata_size)
-        return AVERROR(EIO);
-
-    memcpy(ts_st->adata + ts_st->adata_pos, buf, size);
-    ts_st->adata_pos += size;
-
-    return 0;
-}
-
 static int mpegts_write_header(AVFormatContext *s)
 {
     MpegTSWrite *ts = s->priv_data;
@@ -616,25 +599,11 @@ static int mpegts_write_header(AVFormatContext *s)
             st->codec->extradata_size > 0)
         {
             AVStream *ast;
-            uint8_t *buffer;
-            int buffer_size = 32768;
             ts_st->amux = avformat_alloc_context();
             if (!ts_st->amux) {
                 ret = AVERROR(ENOMEM);
                 goto fail;
             }
-            buffer = av_malloc(buffer_size);
-            if (!buffer) {
-                ret = AVERROR(ENOMEM);
-                goto fail;
-            }
-            ts_st->amux->pb = avio_alloc_context(buffer, buffer_size, AVIO_FLAG_WRITE,
-                                                 ts_st, NULL, mpegts_audio_write, NULL);
-            if (!ts_st->amux->pb) {
-                av_free(buffer);
-                ret = AVERROR(ENOMEM);
-                goto fail;
-            }
             ts_st->amux->oformat = av_guess_format((ts->flags & MPEGTS_FLAG_AAC_LATM) ? "latm" : "adts", NULL, NULL);
             if (!ts_st->amux->oformat) {
                 ret = AVERROR(EINVAL);
@@ -723,8 +692,6 @@ static int mpegts_write_header(AVFormatContext *s)
         if (ts_st) {
             av_freep(&ts_st->payload);
             if (ts_st->amux) {
-                av_freep(&ts_st->amux->pb->buffer);
-                av_freep(&ts_st->amux->pb);
                 avformat_free_context(ts_st->amux);
                 ts_st->amux = NULL;
             }
@@ -1130,24 +1097,20 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
             av_init_packet(&pkt2);
             pkt2.data = pkt->data;
             pkt2.size = pkt->size;
-            ts_st->adata_size = 1024 + pkt->size;
-            ts_st->adata = data = av_malloc(ts_st->adata_size);
-            ts_st->adata_pos = 0;
-            if (!data)
+            ret = avio_open_dyn_buf(&ts_st->amux->pb);
+            if (ret < 0)
                 return AVERROR(ENOMEM);
 
             ret = av_write_frame(ts_st->amux, &pkt2);
             if (ret < 0) {
+                avio_close_dyn_buf(ts_st->amux->pb, &data);
+                ts_st->amux->pb = NULL;
                 av_free(data);
                 return ret;
             }
-            avio_flush(ts_st->amux->pb);
-            if (ts_st->amux->pb->error < 0) {
-                av_free(data);
-                return ts_st->amux->pb->error;
-            }
-            buf = ts_st->adata;
-            size = ts_st->adata_pos;
+            size = avio_close_dyn_buf(ts_st->amux->pb, &data);
+            ts_st->amux->pb = NULL;
+            buf = data;
         }
     }
 
@@ -1236,8 +1199,6 @@ static int mpegts_write_end(AVFormatContext *s)
         MpegTSWriteStream *ts_st = st->priv_data;
         av_freep(&ts_st->payload);
         if (ts_st->amux) {
-            av_freep(&ts_st->amux->pb->buffer);
-            av_freep(&ts_st->amux->pb);
             avformat_free_context(ts_st->amux);
             ts_st->amux = NULL;
         }
index 6f52d8b..d923719 100644 (file)
@@ -1,4 +1,4 @@
-1e5266b204b33ab4608e368d309716cb *tests/data/fate/acodec-alac.mov
-388994 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 00285b8..1cf04ed 100644 (file)
@@ -1,4 +1,4 @@
-a874f5c08b8d104a6bbf41b21454180d *tests/data/fate/acodec-pcm-s16be.mov
-1059045 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 894844a..d0376a6 100644 (file)
@@ -1,4 +1,4 @@
-833d4afd907139af7106a5642a9c23d3 *tests/data/fate/acodec-pcm-s24be.mov
-1588245 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 5360fc1..656a6b2 100644 (file)
@@ -1,4 +1,4 @@
-c02c96e37b321f2c978968e3a102c669 *tests/data/fate/acodec-pcm-s32be.mov
-2117449 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 e7c09f4..cabf004 100644 (file)
@@ -1,4 +1,4 @@
-111d465266385298fde83005402ac171 *tests/data/fate/acodec-pcm-s8.mov
-529829 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 7487ff2..b9b020c 100644 (file)
@@ -1,12 +1,12 @@
-83754d7142a7770ac374f75b729a9319 *./tests/data/lavf/lavf.mov
-367322 ./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