[FFmpeg-devel] [PATCH] ffprobe: add -ss option

Stefano Sabatini stefasab at gmail.com
Mon Oct 22 16:02:16 CEST 2012


This is useful to test seeking on an input file.

TODO: add Changelog entry
---
 doc/ffprobe.texi |    4 ++++
 ffprobe.c        |   26 ++++++++++++++++++++++++++
 2 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/doc/ffprobe.texi b/doc/ffprobe.texi
index 6295eb3..c2adcc4 100644
--- a/doc/ffprobe.texi
+++ b/doc/ffprobe.texi
@@ -162,6 +162,10 @@ corresponding stream section.
 Count the number of packets per stream and report it in the
 corresponding stream section.
 
+ at item -ss @var{seek_point}
+Seek input to position specified by @var{seek_point}.
+ at var{seek_point} must be a duration specification.
+
 @item -show_private_data, -private
 Show private data, that is data depending on the format of the
 particular shown element.
diff --git a/ffprobe.c b/ffprobe.c
index 1cf6c42..27f8638 100644
--- a/ffprobe.c
+++ b/ffprobe.c
@@ -70,6 +70,7 @@ static int show_private_data            = 1;
 
 static char *print_format;
 static char *stream_specifier;
+static int64_t seek_point = -INT64_MAX;
 
 /* section structure definition */
 
@@ -1863,6 +1864,24 @@ static int open_input_file(AVFormatContext **fmt_ctx_ptr, const char *filename)
 
     av_dump_format(fmt_ctx, 0, filename, 0);
 
+    if (seek_point > -INT64_MAX) {
+        // add the stream start time, should it exist
+        if (fmt_ctx->start_time != AV_NOPTS_VALUE) {
+            if (seek_point > INT64_MAX - fmt_ctx->start_time) {
+                av_log(NULL, AV_LOG_ERROR,
+                       "Seek point value %"PRId64" overflow with start time value:%"PRId64"\n",
+                       seek_point, fmt_ctx->start_time);
+                return AVERROR(EINVAL);
+            }
+            seek_point += fmt_ctx->start_time;
+        }
+        if ((err = av_seek_frame(fmt_ctx, -1, seek_point, AVSEEK_FLAG_BACKWARD)) < 0) {
+            av_log(NULL, AV_LOG_ERROR, "Could not seek to position %"PRId64"\n",
+                   seek_point);
+            return err;
+        }
+    }
+
     /* bind a decoder to each input stream */
     for (i = 0; i < fmt_ctx->nb_streams; i++) {
         AVStream *stream = fmt_ctx->streams[i];
@@ -2056,6 +2075,12 @@ void show_help_default(const char *opt, const char *arg)
     show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
 }
 
+static int opt_seek_point(void *optctx, const char *opt, const char *arg)
+{
+    seek_point = parse_time_or_die(opt, arg, 1);
+    return 0;
+}
+
 static int opt_pretty(void *optctx, const char *opt, const char *arg)
 {
     show_value_unit              = 1;
@@ -2103,6 +2128,7 @@ static const OptionDef real_options[] = {
     { "show_private_data", OPT_BOOL, {(void*)&show_private_data}, "show private data" },
     { "private",           OPT_BOOL, {(void*)&show_private_data}, "same as show_private_data" },
     { "bitexact", OPT_BOOL, {&do_bitexact}, "force bitexact output" },
+    { "ss", HAS_ARG, {.func_arg = opt_seek_point}, "seek input to the specified seek point", "seek_point" },
     { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {.func_arg = opt_default}, "generic catch all option", "" },
     { "i", HAS_ARG, {.func_arg = opt_input_file_i}, "read specified file", "input_file"},
     { NULL, },
-- 
1.7.5.4



More information about the ffmpeg-devel mailing list