[FFmpeg-devel] [PATCH 4/5] ffplay: add support for MOV edit lists

Clément Bœsch u at pkh.me
Tue Jan 6 18:10:00 CET 2015


From: Clément Bœsch <clement at stupeflix.com>

---
 doc/ffplay.texi |  3 +++
 ffplay.c        | 25 ++++++++++++++++++++++---
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/doc/ffplay.texi b/doc/ffplay.texi
index 45731a2..126c19b 100644
--- a/doc/ffplay.texi
+++ b/doc/ffplay.texi
@@ -174,6 +174,9 @@ input as soon as possible. Enabled by default for realtime streams, where data
 may be dropped if not read in time. Use this option to enable infinite buffers
 for all inputs, use @option{-noinfbuf} to disable it.
 
+ at item -honor_timeline
+Enable support for format timelines such as MOV/MP4 edit lists. Enabled by
+default, use @option{-nohonor_timeline} to disable it.
 @end table
 
 @section While playing
diff --git a/ffplay.c b/ffplay.c
index 72ec35d..0e70f25 100644
--- a/ffplay.c
+++ b/ffplay.c
@@ -342,6 +342,7 @@ static int nb_vfilters = 0;
 static char *afilters = NULL;
 #endif
 static int autorotate = 1;
+static int honor_timeline = 1;
 
 /* current context */
 static int is_full_screen;
@@ -2022,6 +2023,10 @@ static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c
         }
     }
 
+    if (honor_timeline &&
+        (ret = insert_timeline_graph(is->video_st, &last_filter, 0, 1)) < 0)
+        goto fail;
+
     if ((ret = configure_filtergraph(graph, vfilters, filt_src, last_filter)) < 0)
         goto fail;
 
@@ -2038,7 +2043,7 @@ static int configure_audio_filters(VideoState *is, const char *afilters, int for
     int sample_rates[2] = { 0, -1 };
     int64_t channel_layouts[2] = { 0, -1 };
     int channels[2] = { 0, -1 };
-    AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
+    AVFilterContext *filt_asrc = NULL, *filt_asink = NULL, *last_filter = NULL;
     char aresample_swr_opts[512] = "";
     AVDictionaryEntry *e = NULL;
     char asrc_args[256];
@@ -2095,8 +2100,14 @@ static int configure_audio_filters(VideoState *is, const char *afilters, int for
             goto end;
     }
 
+    last_filter = filt_asink;
 
-    if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, filt_asink)) < 0)
+    // XXX: audio stream can be NULL here, why?
+    if (honor_timeline && is->audio_st &&
+        (ret = insert_timeline_graph(is->audio_st, &last_filter, 0, 1)) < 0)
+        goto end;
+
+    if ((ret = configure_filtergraph(is->agraph, afilters, filt_asrc, last_filter)) < 0)
         goto end;
 
     is->in_audio_filter  = filt_asrc;
@@ -2880,7 +2891,7 @@ static int read_thread(void *arg)
     AVDictionary **opts;
     int orig_nb_streams;
     SDL_mutex *wait_mutex = SDL_CreateMutex();
-    int scan_all_pmts_set = 0;
+    int scan_all_pmts_set = 0, ignore_editlist_set = 0;
 
     memset(st_index, -1, sizeof(st_index));
     is->last_video_stream = is->video_stream = -1;
@@ -2894,6 +2905,11 @@ static int read_thread(void *arg)
         av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
         scan_all_pmts_set = 1;
     }
+    if (CONFIG_AVFILTER && honor_timeline &&
+        !av_dict_get(format_opts, "ignore_editlist", NULL, AV_DICT_MATCH_CASE)) {
+        av_dict_set(&format_opts, "ignore_editlist", "export", AV_DICT_DONT_OVERWRITE);
+        ignore_editlist_set = 1;
+    }
     err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
     if (err < 0) {
         print_error(is->filename, err);
@@ -2902,6 +2918,8 @@ static int read_thread(void *arg)
     }
     if (scan_all_pmts_set)
         av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
+    if (ignore_editlist_set)
+        av_dict_set(&format_opts, "ignore_editlist", NULL, AV_DICT_MATCH_CASE);
 
     if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
         av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
@@ -3713,6 +3731,7 @@ static const OptionDef options[] = {
     { "scodec", HAS_ARG | OPT_STRING | OPT_EXPERT, { &subtitle_codec_name }, "force subtitle decoder", "decoder_name" },
     { "vcodec", HAS_ARG | OPT_STRING | OPT_EXPERT, {    &video_codec_name }, "force video decoder",    "decoder_name" },
     { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" },
+    { "honor_timeline", OPT_BOOL | OPT_EXPERT, { &honor_timeline }, "honor timelines", "" },
     { NULL, },
 };
 
-- 
2.2.1



More information about the ffmpeg-devel mailing list