Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH 1/2] avformat: add avformat_query_seekable
@ 2025-04-13 11:15 Gyan Doshi
  2025-04-13 11:15 ` [FFmpeg-devel] [PATCH 2/2] ffprobe: show seekability details in format section Gyan Doshi
                   ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Gyan Doshi @ 2025-04-13 11:15 UTC (permalink / raw)
  To: ffmpeg-devel

Utility function to report seekability features for a given input.

Useful for ffprobe and to extend seek possibilities in fftools.
---
 doc/APIchanges         |  3 +++
 libavformat/avformat.h | 22 ++++++++++++++++++
 libavformat/seek.c     | 53 ++++++++++++++++++++++++++++++++++++++++++
 libavformat/version.h  |  2 +-
 4 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index 65bf5a9419..879f56b572 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -2,6 +2,9 @@ The last version increases of all libraries were on 2025-03-28
 
 API changes, most recent first:
 
+2025-04-xx - xxxxxxxxxx - lavf 62.1.100 - avformat.h
+  Add avformat_query_seekable().
+
 2025-04-07 - 19e9a203b7 - lavu 60.01.100 - dict.h
   Add AV_DICT_DEDUP.
 
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 498c3020a5..e00f1ed0d9 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -2338,6 +2338,28 @@ int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp,
  */
 int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags);
 
+#define AVSEEKABLE_NORMAL     0x01 ///< I/O is seekable like a local file
+#define AVSEEKABLE_PROTOCOL   0x02 ///< I/O seek is through protocol request via avio_seek_time
+#define AVSEEKABLE_DEMUXER    0x04 ///< demuxer has a seek function
+#define AVSEEKABLE_PKTSCAN    0x08 ///< seek is performed by consuming and scanning packet timestamps
+#define AVSEEKABLE_TIME       0x10 ///< seek target can be a timestamp
+#define AVSEEKABLE_BYTE       0x20 ///< seek target can be in bytes
+#define AVSEEKABLE_FRAME      0x40 ///< seek target can be a frame index
+#define AVSEEKABLE_PTS       0x100 ///< seek target timestamp is expected to be PTS
+#define AVSEEKABLE_FAST      0x200 ///< demuxer allows fast but inaccurate seeking
+#define AVSEEKABLE_FWDONLY   0x400 ///< set seek will be equal or forward of specified seek point
+
+/**
+ * Report if and how a seek can be performed in a given input.
+ *
+ * @param s            media file handle
+ *
+ * @return 0 if no seek can be performed on input,
+ *         -1 if the fmt ctx is NULL or is not an input
+ *         else return AVSEEKABLE_ bitflags indicating seekability features.
+ */
+int avformat_query_seekable(AVFormatContext *s);
+
 /**
  * Discard all internally buffered data. This can be useful when dealing with
  * discontinuities in the byte stream. Generally works only with formats that
diff --git a/libavformat/seek.c b/libavformat/seek.c
index c0d94371e6..776a09744a 100644
--- a/libavformat/seek.c
+++ b/libavformat/seek.c
@@ -712,6 +712,59 @@ int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts,
     return ret;
 }
 
+int avformat_query_seekable(AVFormatContext *s)
+{
+    int ret = 0;
+
+    if (!s || !s->iformat)
+        return -1;
+
+    if (!(s->pb && s->pb->seekable) || s->ctx_flags & AVFMTCTX_UNSEEKABLE)
+        return 0;
+
+    if (s->pb->seekable & AVIO_SEEKABLE_NORMAL)
+        ret |= AVSEEKABLE_NORMAL;
+
+    if (s->pb->seekable & AVIO_SEEKABLE_TIME)
+        ret |= AVSEEKABLE_PROTOCOL;
+
+    if (ffifmt(s->iformat)->read_seek || ffifmt(s->iformat)->read_seek2)
+        ret |= AVSEEKABLE_DEMUXER;
+
+    if (ffifmt(s->iformat)->read_timestamp && !(s->iformat->flags & AVFMT_NOBINSEARCH))
+        ret |= AVSEEKABLE_PKTSCAN;
+
+    if (!(s->iformat->flags & AVFMT_NOTIMESTAMPS))
+        ret |= AVSEEKABLE_TIME;
+
+    // TODO: incomplete, a few demuxers don't set flag but error out on byte seek
+    if (!(s->iformat->flags & AVFMT_NO_BYTE_SEEK))
+        ret |= AVSEEKABLE_BYTE;
+
+    // TODO: no flag for frame seeking. Add flag and update this check
+    if (s->iformat->flags & 0)
+        ret |= AVSEEKABLE_FRAME;
+
+    if (s->iformat->flags & AVFMT_SEEK_TO_PTS)
+        ret |= AVSEEKABLE_PTS;
+
+    // TODO: flag exists but not added to the demuxers which support it
+    if (s->iformat->flags & AVFMT_FLAG_FAST_SEEK)
+        ret |= AVSEEKABLE_FAST;
+
+    if (!(ret & AVSEEKABLE_DEMUXER) && ret & AVSEEKABLE_PKTSCAN)
+        ret |= AVSEEKABLE_FWDONLY;
+
+    if ( !(ret & AVSEEKABLE_DEMUXER) &&
+         !(ret & AVSEEKABLE_PKTSCAN) &&
+         !(ret & AVSEEKABLE_BYTE) &&
+         !(ret & AVSEEKABLE_PROTOCOL) &&
+         (s->iformat->flags & AVFMT_NOGENSEARCH) )
+        ret = 0;
+
+    return ret;
+}
+
 /** Flush the frame reader. */
 void ff_read_frame_flush(AVFormatContext *s)
 {
diff --git a/libavformat/version.h b/libavformat/version.h
index 752aac16f7..a7c80dc564 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -31,7 +31,7 @@
 
 #include "version_major.h"
 
-#define LIBAVFORMAT_VERSION_MINOR   0
+#define LIBAVFORMAT_VERSION_MINOR   1
 #define LIBAVFORMAT_VERSION_MICRO 100
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
-- 
2.49.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [FFmpeg-devel] [PATCH 2/2] ffprobe: show seekability details in format section
  2025-04-13 11:15 [FFmpeg-devel] [PATCH 1/2] avformat: add avformat_query_seekable Gyan Doshi
@ 2025-04-13 11:15 ` Gyan Doshi
  2025-04-13 16:18   ` softworkz .
  2025-04-13 16:09 ` [FFmpeg-devel] [PATCH 1/2] avformat: add avformat_query_seekable softworkz .
  2025-04-13 16:42 ` Zhao Zhili
  2 siblings, 1 reply; 15+ messages in thread
From: Gyan Doshi @ 2025-04-13 11:15 UTC (permalink / raw)
  To: ffmpeg-devel

---
 fftools/ffprobe.c                    | 49 +++++++++++++++++++++++++++-
 tests/ref/fate/cavs-demux            |  2 +-
 tests/ref/fate/ffprobe_compact       |  2 +-
 tests/ref/fate/ffprobe_csv           |  2 +-
 tests/ref/fate/ffprobe_default       |  1 +
 tests/ref/fate/ffprobe_flat          |  1 +
 tests/ref/fate/ffprobe_ini           |  1 +
 tests/ref/fate/ffprobe_json          |  1 +
 tests/ref/fate/ffprobe_xml           |  2 +-
 tests/ref/fate/ffprobe_xsd           |  2 +-
 tests/ref/fate/flv-demux             |  2 +-
 tests/ref/fate/gapless-mp3-side-data |  2 +-
 tests/ref/fate/oggopus-demux         |  2 +-
 tests/ref/fate/ts-demux              |  2 +-
 tests/ref/fate/ts-opus-demux         |  2 +-
 tests/ref/fate/ts-small-demux        |  2 +-
 tests/ref/fate/ts-timed-id3-demux    |  2 +-
 17 files changed, 64 insertions(+), 13 deletions(-)

diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c
index e0a7322523..8b09afb8c1 100644
--- a/fftools/ffprobe.c
+++ b/fftools/ffprobe.c
@@ -2260,7 +2260,7 @@ static int show_format(AVTextFormatContext *tfc, InputFile *ifile)
 {
     AVFormatContext *fmt_ctx = ifile->fmt_ctx;
     int64_t size = fmt_ctx->pb ? avio_size(fmt_ctx->pb) : -1;
-    int ret = 0;
+    int seekable, ret = 0;
 
     avtext_print_section_header(tfc, NULL, SECTION_ID_FORMAT);
     print_str_validate("filename", fmt_ctx->url);
@@ -2279,6 +2279,53 @@ static int show_format(AVTextFormatContext *tfc, InputFile *ifile)
     if (fmt_ctx->bit_rate > 0) print_val    ("bit_rate", fmt_ctx->bit_rate, unit_bit_per_second_str);
     else                       print_str_opt("bit_rate", "N/A");
     print_int("probe_score", fmt_ctx->probe_score);
+
+    seekable = avformat_query_seekable(fmt_ctx);
+    if (seekable > 0) {
+        int gen = 1, ante = 0;
+        AVBPrint seek_str;
+        av_bprint_init(&seek_str, 0, AV_BPRINT_SIZE_AUTOMATIC);
+
+        av_bprintf(&seek_str, "yes, by");
+        if (seekable & AVSEEKABLE_TIME) {
+            av_bprintf(&seek_str, " time");
+            if (seekable & AVSEEKABLE_PTS)
+                av_bprintf(&seek_str, "(pts)");
+            else
+                av_bprintf(&seek_str, "(dts)");
+            ante = 1;
+        }
+        if (seekable & AVSEEKABLE_BYTE) {
+            av_bprintf(&seek_str, "%cbyte-offset", ante ? ',':' ');
+            ante = 1;
+        }
+        if (seekable & AVSEEKABLE_FRAME) {
+            av_bprintf(&seek_str, "%cframe-index", ante ? ',':' ');
+        }
+
+        ante = 0;
+        av_bprintf(&seek_str, " via");
+        if (seekable & AVSEEKABLE_DEMUXER) {
+            av_bprintf(&seek_str, " demuxer");
+            gen = 0;
+            ante = 1;
+        }
+        if (seekable & AVSEEKABLE_PKTSCAN) {
+            av_bprintf(&seek_str, "%cpacket-scan", ante ? ',':' ');
+            gen = 0;
+            ante = 0;
+        }
+        if (gen)
+            av_bprintf(&seek_str, " generic seek");
+
+        if (seekable & AVSEEKABLE_FWDONLY)
+            av_bprintf(&seek_str, " (forward only)");
+
+        print_str("seekable",      seek_str.str);
+    }
+    else
+        print_str("seekable",      "no");
+
     if (do_show_format_tags)
         ret = show_tags(tfc, fmt_ctx->metadata, SECTION_ID_FORMAT_TAGS);
 
diff --git a/tests/ref/fate/cavs-demux b/tests/ref/fate/cavs-demux
index b1e2c2fd25..ad3a7a0d4b 100644
--- a/tests/ref/fate/cavs-demux
+++ b/tests/ref/fate/cavs-demux
@@ -59,4 +59,4 @@ packet|codec_type=video|stream_index=0|pts=2320000|pts_time=1.933333|dts=2320000
 packet|codec_type=video|stream_index=0|pts=2360000|pts_time=1.966667|dts=2360000|dts_time=1.966667|duration=40000|duration_time=0.033333|size=83|pos=172252|flags=K__|data_hash=CRC32:a941bdf0
 packet|codec_type=video|stream_index=0|pts=2400000|pts_time=2.000000|dts=2400000|dts_time=2.000000|duration=40000|duration_time=0.033333|size=5417|pos=172335|flags=K__|data_hash=CRC32:9d0d503b
 stream|index=0|codec_name=cavs|profile=unknown|codec_type=video|codec_tag_string=[0][0][0][0]|codec_tag=0x0000|width=1280|height=720|coded_width=1280|coded_height=720|has_b_frames=0|sample_aspect_ratio=N/A|display_aspect_ratio=N/A|pix_fmt=yuv420p|level=-99|color_range=unknown|color_space=unknown|color_transfer=unknown|color_primaries=unknown|chroma_location=unspecified|field_order=unknown|refs=1|id=N/A|r_frame_rate=30/1|avg_frame_rate=25/1|time_base=1/1200000|start_pts=N/A|start_time=N/A|duration_ts=N/A|duration=N/A|bit_rate=N/A|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=N/A|nb_read_packets=60|extradata_size=18|extradata_hash=CRC32:1255d52e|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|disposition:non_diegetic=0|disposition:captions=0|disposition:descriptions=0|disposition:metadata=0|disposition:dependent=0|disposition:still_image=0|disposition:multilayer=0
-format|filename=bunny.mp4|nb_streams=1|nb_programs=0|nb_stream_groups=0|format_name=cavsvideo|start_time=N/A|duration=N/A|size=177752|bit_rate=N/A|probe_score=51
+format|filename=bunny.mp4|nb_streams=1|nb_programs=0|nb_stream_groups=0|format_name=cavsvideo|start_time=N/A|duration=N/A|size=177752|bit_rate=N/A|probe_score=51|seekable=yes, by byte-offset via generic seek
diff --git a/tests/ref/fate/ffprobe_compact b/tests/ref/fate/ffprobe_compact
index 68b9acf599..0659da573c 100644
--- a/tests/ref/fate/ffprobe_compact
+++ b/tests/ref/fate/ffprobe_compact
@@ -29,4 +29,4 @@ frame|media_type=video|stream_index=2|key_frame=1|pts=6144|pts_time=0.120000|pkt
 stream|index=0|codec_name=pcm_s16le|profile=unknown|codec_type=audio|codec_tag_string=PSD[16]|codec_tag=0x10445350|sample_fmt=s16|sample_rate=44100|channels=1|channel_layout=unknown|bits_per_sample=16|initial_padding=0|id=N/A|r_frame_rate=0/0|avg_frame_rate=0/0|time_base=1/44100|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=705600|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=6|nb_read_packets=6|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|disposition:non_diegetic=0|disposition:captions=0|disposition:descriptions=0|disposition:metadata=0|disposition:dependent=0|disposition:still_image=0|disposition:multilayer=0|tag:encoder=Lavc pcm_s16le|tag:E=mc²
 stream|index=1|codec_name=rawvideo|profile=unknown|codec_type=video|codec_tag_string=RGB[24]|codec_tag=0x18424752|width=320|height=240|coded_width=320|coded_height=240|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=4:3|pix_fmt=rgb24|level=-99|color_range=unknown|color_space=unknown|color_transfer=unknown|color_primaries=unknown|chroma_location=unspecified|field_order=unknown|refs=1|id=N/A|r_frame_rate=25/1|avg_frame_rate=25/1|time_base=1/51200|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=N/A|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=4|nb_read_packets=4|disposition:default=1|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|disposition:non_diegetic=0|disposition:captions=0|disposition:descriptions=0|disposition:metadata=0|disposition:dependent=0|disposition:still_image=0|disposition:multilayer=0|tag:encoder=Lavc rawvideo|tag:title=foobar|tag:duration_ts=field-and-tags-conflict-attempt
 stream|index=2|codec_name=rawvideo|profile=unknown|codec_type=video|codec_tag_string=RGB[24]|codec_tag=0x18424752|width=100|height=100|coded_width=100|coded_height=100|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=1:1|pix_fmt=rgb24|level=-99|color_range=unknown|color_space=unknown|color_transfer=unknown|color_primaries=unknown|chroma_location=unspecified|field_order=unknown|refs=1|id=N/A|r_frame_rate=25/1|avg_frame_rate=25/1|time_base=1/51200|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=N/A|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=4|nb_read_packets=4|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|disposition:non_diegetic=0|disposition:captions=0|disposition:descriptions=0|disposition:metadata=0|disposition:dependent=0|disposition:still_image=0|disposition:multilayer=0|tag:encoder=Lavc rawvideo
-format|filename=tests/data/ffprobe-test.nut|nb_streams=3|nb_programs=0|nb_stream_groups=0|format_name=nut|start_time=0.000000|duration=0.120000|size=1053646|bit_rate=70243066|probe_score=100|tag:title=ffprobe test file|tag:comment='A comment with CSV, XML & JSON special chars': <tag value="x">|tag:comment2=I ♥ Üñîçød€
+format|filename=tests/data/ffprobe-test.nut|nb_streams=3|nb_programs=0|nb_stream_groups=0|format_name=nut|start_time=0.000000|duration=0.120000|size=1053646|bit_rate=70243066|probe_score=100|seekable=yes, by time(pts),byte-offset via demuxer|tag:title=ffprobe test file|tag:comment='A comment with CSV, XML & JSON special chars': <tag value="x">|tag:comment2=I ♥ Üñîçød€
diff --git a/tests/ref/fate/ffprobe_csv b/tests/ref/fate/ffprobe_csv
index 37c67bb4e3..65e34df3ad 100644
--- a/tests/ref/fate/ffprobe_csv
+++ b/tests/ref/fate/ffprobe_csv
@@ -29,4 +29,4 @@ frame,video,2,1,6144,0.120000,6144,0.120000,6144,0.120000,2048,0.040000,1023566,
 stream,0,pcm_s16le,unknown,audio,PSD[16],0x10445350,s16,44100,1,unknown,16,0,N/A,0/0,0/0,1/44100,0,0.000000,N/A,N/A,705600,N/A,N/A,N/A,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,Lavc pcm_s16le,mc²
 stream,1,rawvideo,unknown,video,RGB[24],0x18424752,320,240,320,240,0,1:1,4:3,rgb24,-99,unknown,unknown,unknown,unknown,unspecified,unknown,1,N/A,25/1,25/1,1/51200,0,0.000000,N/A,N/A,N/A,N/A,N/A,N/A,4,4,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,Lavc rawvideo,foobar,field-and-tags-conflict-attempt
 stream,2,rawvideo,unknown,video,RGB[24],0x18424752,100,100,100,100,0,1:1,1:1,rgb24,-99,unknown,unknown,unknown,unknown,unspecified,unknown,1,N/A,25/1,25/1,1/51200,0,0.000000,N/A,N/A,N/A,N/A,N/A,N/A,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,Lavc rawvideo
-format,tests/data/ffprobe-test.nut,3,0,0,nut,0.000000,0.120000,1053646,70243066,100,ffprobe test file,"'A comment with CSV, XML & JSON special chars': <tag value=""x"">",I ♥ Üñîçød€
+format,tests/data/ffprobe-test.nut,3,0,0,nut,0.000000,0.120000,1053646,70243066,100,"yes, by time(pts),byte-offset via demuxer",ffprobe test file,"'A comment with CSV, XML & JSON special chars': <tag value=""x"">",I ♥ Üñîçød€
diff --git a/tests/ref/fate/ffprobe_default b/tests/ref/fate/ffprobe_default
index 2d38d4d211..171c60379b 100644
--- a/tests/ref/fate/ffprobe_default
+++ b/tests/ref/fate/ffprobe_default
@@ -736,6 +736,7 @@ duration=0.120000
 size=1053646
 bit_rate=70243066
 probe_score=100
+seekable=yes, by time(pts),byte-offset via demuxer
 TAG:title=ffprobe test file
 TAG:comment='A comment with CSV, XML & JSON special chars': <tag value="x">
 TAG:comment2=I ♥ Üñîçød€
diff --git a/tests/ref/fate/ffprobe_flat b/tests/ref/fate/ffprobe_flat
index b9aac8a007..d6eba6c14c 100644
--- a/tests/ref/fate/ffprobe_flat
+++ b/tests/ref/fate/ffprobe_flat
@@ -673,6 +673,7 @@ format.duration="0.120000"
 format.size="1053646"
 format.bit_rate="70243066"
 format.probe_score=100
+format.seekable="yes, by time(pts),byte-offset via demuxer"
 format.tags.title="ffprobe test file"
 format.tags.comment="'A comment with CSV, XML & JSON special chars': <tag value=\"x\">"
 format.tags.comment2="I ♥ Üñîçød€"
diff --git a/tests/ref/fate/ffprobe_ini b/tests/ref/fate/ffprobe_ini
index d353c09339..ec5cd8be42 100644
--- a/tests/ref/fate/ffprobe_ini
+++ b/tests/ref/fate/ffprobe_ini
@@ -750,6 +750,7 @@ duration=0.120000
 size=1053646
 bit_rate=70243066
 probe_score=100
+seekable=yes, by time(pts),byte-offset via demuxer
 
 [format.tags]
 title=ffprobe test file
diff --git a/tests/ref/fate/ffprobe_json b/tests/ref/fate/ffprobe_json
index ac295181b5..dcc9c55b05 100644
--- a/tests/ref/fate/ffprobe_json
+++ b/tests/ref/fate/ffprobe_json
@@ -699,6 +699,7 @@
         "size": "1053646",
         "bit_rate": "70243066",
         "probe_score": 100,
+        "seekable": "yes, by time(pts),byte-offset via demuxer",
         "tags": {
             "title": "ffprobe test file",
             "comment": "'A comment with CSV, XML & JSON special chars': <tag value=\"x\">",
diff --git a/tests/ref/fate/ffprobe_xml b/tests/ref/fate/ffprobe_xml
index 0917813fa5..d4a228bd51 100644
--- a/tests/ref/fate/ffprobe_xml
+++ b/tests/ref/fate/ffprobe_xml
@@ -55,7 +55,7 @@
         </stream>
     </streams>
 
-    <format filename="tests/data/ffprobe-test.nut" nb_streams="3" nb_programs="0" nb_stream_groups="0" format_name="nut" start_time="0.000000" duration="0.120000" size="1053646" bit_rate="70243066" probe_score="100">
+    <format filename="tests/data/ffprobe-test.nut" nb_streams="3" nb_programs="0" nb_stream_groups="0" format_name="nut" start_time="0.000000" duration="0.120000" size="1053646" bit_rate="70243066" probe_score="100" seekable="yes, by time(pts),byte-offset via demuxer">
         <tags>
             <tag key="title" value="ffprobe test file"/>
             <tag key="comment" value="'A comment with CSV, XML &amp; JSON special chars': &lt;tag value=&quot;x&quot;&gt;"/>
diff --git a/tests/ref/fate/ffprobe_xsd b/tests/ref/fate/ffprobe_xsd
index 743746738d..a714878765 100644
--- a/tests/ref/fate/ffprobe_xsd
+++ b/tests/ref/fate/ffprobe_xsd
@@ -55,7 +55,7 @@
         </stream>
     </streams>
 
-    <format filename="tests/data/ffprobe-test.nut" nb_streams="3" nb_programs="0" nb_stream_groups="0" format_name="nut" start_time="0.000000" duration="0.120000" size="1053646" bit_rate="70243066" probe_score="100">
+    <format filename="tests/data/ffprobe-test.nut" nb_streams="3" nb_programs="0" nb_stream_groups="0" format_name="nut" start_time="0.000000" duration="0.120000" size="1053646" bit_rate="70243066" probe_score="100" seekable="yes, by time(pts),byte-offset via demuxer">
         <tags>
             <tag key="title" value="ffprobe test file"/>
             <tag key="comment" value="'A comment with CSV, XML &amp; JSON special chars': &lt;tag value=&quot;x&quot;&gt;"/>
diff --git a/tests/ref/fate/flv-demux b/tests/ref/fate/flv-demux
index 429cc50874..9feb971e9f 100644
--- a/tests/ref/fate/flv-demux
+++ b/tests/ref/fate/flv-demux
@@ -603,4 +603,4 @@ packet|codec_type=audio|stream_index=1|pts=11656|pts_time=11.656000|dts=11656|dt
 packet|codec_type=video|stream_index=0|pts=11678|pts_time=11.678000|dts=11678|dts_time=11.678000|duration=33|duration_time=0.033000|size=1190|pos=510794|flags=__C|data_hash=CRC32:a0206c90
 stream|index=0|codec_name=h264|profile=77|codec_type=video|codec_tag_string=[0][0][0][0]|codec_tag=0x0000|width=426|height=240|coded_width=426|coded_height=240|has_b_frames=1|sample_aspect_ratio=1:1|display_aspect_ratio=71:40|pix_fmt=yuv420p|level=21|color_range=unknown|color_space=unknown|color_transfer=unknown|color_primaries=unknown|chroma_location=left|field_order=progressive|refs=1|is_avc=true|nal_length_size=4|id=N/A|r_frame_rate=30000/1001|avg_frame_rate=30/1|time_base=1/1000|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=393929|max_bit_rate=N/A|bits_per_raw_sample=8|nb_frames=N/A|nb_read_frames=N/A|nb_read_packets=351|extradata_size=39|extradata_hash=CRC32:07b85ca9|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|disposition:non_diegetic=0|disposition:captions=0|disposition:descriptions=0|disposition:metadata=0|disposition:dependent=0|disposition:still_image=0|disposition:multilayer=0
 stream|index=1|codec_name=aac|profile=1|codec_type=audio|codec_tag_string=[0][0][0][0]|codec_tag=0x0000|sample_fmt=fltp|sample_rate=22050|channels=2|channel_layout=stereo|bits_per_sample=0|initial_padding=0|id=N/A|r_frame_rate=0/0|avg_frame_rate=0/0|time_base=1/1000|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=67874|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=N/A|nb_read_packets=252|extradata_size=2|extradata_hash=CRC32:d039c029|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|disposition:non_diegetic=0|disposition:captions=0|disposition:descriptions=0|disposition:metadata=0|disposition:dependent=0|disposition:still_image=0|disposition:multilayer=0
-format|filename=Enigma_Principles_of_Lust-part.flv|nb_streams=2|nb_programs=0|nb_stream_groups=0|format_name=flv|start_time=0.000000|duration=210.209999|size=512000|bit_rate=19485|probe_score=100|tag:hasKeyframes=true|tag:hasMetadata=true|tag:datasize=11970544|tag:hasVideo=true|tag:canSeekToEnd=false|tag:lasttimestamp=210|tag:lastkeyframetimestamp=210|tag:audiosize=1791332|tag:hasAudio=true|tag:audiodelay=0|tag:videosize=10176110|tag:metadatadate=2011-02-27T11:00:33.125000Z|tag:metadatacreator=inlet media FLVTool2 v1.0.6 - http://www.inlet-media.de/flvtool2|tag:hasCuePoints=false
+format|filename=Enigma_Principles_of_Lust-part.flv|nb_streams=2|nb_programs=0|nb_stream_groups=0|format_name=flv|start_time=0.000000|duration=210.209999|size=512000|bit_rate=19485|probe_score=100|seekable=yes, by time(dts),byte-offset via demuxer|tag:hasKeyframes=true|tag:hasMetadata=true|tag:datasize=11970544|tag:hasVideo=true|tag:canSeekToEnd=false|tag:lasttimestamp=210|tag:lastkeyframetimestamp=210|tag:audiosize=1791332|tag:hasAudio=true|tag:audiodelay=0|tag:videosize=10176110|tag:metadatadate=2011-02-27T11:00:33.125000Z|tag:metadatacreator=inlet media FLVTool2 v1.0.6 - http://www.inlet-media.de/flvtool2|tag:hasCuePoints=false
diff --git a/tests/ref/fate/gapless-mp3-side-data b/tests/ref/fate/gapless-mp3-side-data
index 878425f092..3e1f239646 100644
--- a/tests/ref/fate/gapless-mp3-side-data
+++ b/tests/ref/fate/gapless-mp3-side-data
@@ -594,4 +594,4 @@ packet|codec_type=audio|stream_index=0|pts=218234880|pts_time=15.464490|dts=2182
 packet|codec_type=audio|stream_index=0|pts=218603520|pts_time=15.490612|dts=218603520|dts_time=15.490612|duration=368640|duration_time=0.026122|size=418|pos=249300|flags=K__|data_hash=CRC32:d5fb5f9c|side_datum/skip_samples:side_data_type=Skip Samples|side_datum/skip_samples:skip_samples=0|side_datum/skip_samples:discard_padding=303|side_datum/skip_samples:skip_reason=0|side_datum/skip_samples:discard_reason=0
 packet|codec_type=audio|stream_index=0|pts=218972160|pts_time=15.516735|dts=218972160|dts_time=15.516735|duration=368640|duration_time=0.026122|size=418|pos=249718|flags=K__|data_hash=CRC32:3789f3cf|side_datum/skip_samples:side_data_type=Skip Samples|side_datum/skip_samples:skip_samples=0|side_datum/skip_samples:discard_padding=1152|side_datum/skip_samples:skip_reason=0|side_datum/skip_samples:discard_reason=0
 stream|index=0|codec_name=mp3|profile=unknown|codec_type=audio|codec_tag_string=[0][0][0][0]|codec_tag=0x0000|sample_fmt=fltp|sample_rate=44100|channels=2|channel_layout=stereo|bits_per_sample=0|initial_padding=0|id=N/A|r_frame_rate=0/0|avg_frame_rate=0/0|time_base=1/14112000|start_pts=353600|start_time=0.025057|duration_ts=218521600|duration=15.484807|bit_rate=128000|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=N/A|nb_read_packets=595|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|disposition:non_diegetic=0|disposition:captions=0|disposition:descriptions=0|disposition:metadata=0|disposition:dependent=0|disposition:still_image=0|disposition:multilayer=0|tag:encoder=LAME3.93 
-format|filename=gapless.mp3|nb_streams=1|nb_programs=0|nb_stream_groups=0|format_name=mp3|start_time=0.025057|duration=15.484807|size=250264|bit_rate=129295|probe_score=51|tag:title=test
+format|filename=gapless.mp3|nb_streams=1|nb_programs=0|nb_stream_groups=0|format_name=mp3|start_time=0.025057|duration=15.484807|size=250264|bit_rate=129295|probe_score=51|seekable=yes, by time(dts),byte-offset via demuxer|tag:title=test
diff --git a/tests/ref/fate/oggopus-demux b/tests/ref/fate/oggopus-demux
index 03b7b76cf2..75b59e0f73 100644
--- a/tests/ref/fate/oggopus-demux
+++ b/tests/ref/fate/oggopus-demux
@@ -40,4 +40,4 @@ packet|codec_type=audio|stream_index=0|pts=36124|pts_time=0.752583|dts=36124|dts
 packet|codec_type=audio|stream_index=0|pts=37084|pts_time=0.772583|dts=37084|dts_time=0.772583|duration=960|duration_time=0.020000|size=217|pos=841|flags=K__|data_hash=CRC32:06797ece
 packet|codec_type=audio|stream_index=0|pts=38044|pts_time=0.792583|dts=38044|dts_time=0.792583|duration=356|duration_time=0.007417|size=359|pos=841|flags=K__|data_hash=CRC32:01ca3f8f|side_datum/skip_samples:side_data_type=Skip Samples|side_datum/skip_samples:skip_samples=0|side_datum/skip_samples:discard_padding=604|side_datum/skip_samples:skip_reason=0|side_datum/skip_samples:discard_reason=0
 stream|index=0|codec_name=opus|profile=unknown|codec_type=audio|codec_tag_string=[0][0][0][0]|codec_tag=0x0000|sample_fmt=fltp|sample_rate=48000|channels=2|channel_layout=stereo|bits_per_sample=0|initial_padding=356|id=N/A|r_frame_rate=0/0|avg_frame_rate=0/0|time_base=1/48000|start_pts=0|start_time=0.000000|duration_ts=38756|duration=0.807417|bit_rate=N/A|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=N/A|nb_read_packets=41|extradata_size=19|extradata_hash=CRC32:58ba5ff3|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|disposition:non_diegetic=0|disposition:captions=0|disposition:descriptions=0|disposition:metadata=0|disposition:dependent=0|disposition:still_image=0|disposition:multilayer=0|tag:ENCODER=opusenc from opus-tools 0.1.9|tag:ENCODER_OPTIONS=--discard-comments
-format|filename=intro-partial.opus|nb_streams=1|nb_programs=0|nb_stream_groups=0|format_name=ogg|start_time=0.000000|duration=0.807417|size=10250|bit_rate=101558|probe_score=100
+format|filename=intro-partial.opus|nb_streams=1|nb_programs=0|nb_stream_groups=0|format_name=ogg|start_time=0.000000|duration=0.807417|size=10250|bit_rate=101558|probe_score=100|seekable=yes, by time(dts),byte-offset via demuxer
diff --git a/tests/ref/fate/ts-demux b/tests/ref/fate/ts-demux
index 6a830d0d99..a09e54c7e8 100644
--- a/tests/ref/fate/ts-demux
+++ b/tests/ref/fate/ts-demux
@@ -26,4 +26,4 @@ packet|codec_type=audio|stream_index=2|pts=3912645580|pts_time=43473.839778|dts=
 stream|index=0|codec_name=mpeg2video|profile=4|codec_type=video|codec_tag_string=[2][0][0][0]|codec_tag=0x0002|width=1280|height=720|coded_width=0|coded_height=0|has_b_frames=1|sample_aspect_ratio=1:1|display_aspect_ratio=16:9|pix_fmt=yuv420p|level=4|color_range=tv|color_space=unknown|color_transfer=unknown|color_primaries=unknown|chroma_location=left|field_order=progressive|refs=1|ts_id=32776|ts_packetsize=188|id=0x31|r_frame_rate=60000/1001|avg_frame_rate=60000/1001|time_base=1/90000|start_pts=3912669846|start_time=43474.109400|duration_ts=19519|duration=0.216878|bit_rate=15000000|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=N/A|nb_read_packets=15|extradata_size=150|extradata_hash=CRC32:53134fa8|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|disposition:non_diegetic=0|disposition:captions=0|disposition:descriptions=0|disposition:metadata=0|disposition:dependent=0|disposition:still_image=0|disposition:multilayer=0|side_datum/cpb_properties:side_data_type=CPB properties|side_datum/cpb_properties:max_bitrate=15000000|side_datum/cpb_properties:min_bitrate=0|side_datum/cpb_properties:avg_bitrate=0|side_datum/cpb_properties:buffer_size=9781248|side_datum/cpb_properties:vbv_delay=-1
 stream|index=1|codec_name=ac3|profile=unknown|codec_type=audio|codec_tag_string=[4][0][0][0]|codec_tag=0x0004|sample_fmt=fltp|sample_rate=48000|channels=6|channel_layout=5.1(side)|bits_per_sample=0|initial_padding=0|dmix_mode=0|ltrt_cmixlev=0.000000|ltrt_surmixlev=0.000000|loro_cmixlev=0.000000|loro_surmixlev=0.000000|ts_id=32776|ts_packetsize=188|id=0x34|r_frame_rate=0/0|avg_frame_rate=0/0|time_base=1/90000|start_pts=3912633305|start_time=43473.703389|duration_ts=14400|duration=0.160000|bit_rate=384000|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=N/A|nb_read_packets=5|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|disposition:non_diegetic=0|disposition:captions=0|disposition:descriptions=0|disposition:metadata=0|disposition:dependent=0|disposition:still_image=0|disposition:multilayer=0|tag:language=eng
 stream|index=2|codec_name=ac3|profile=unknown|codec_type=audio|codec_tag_string=[4][0][0][0]|codec_tag=0x0004|sample_fmt=fltp|sample_rate=48000|channels=2|channel_layout=stereo|bits_per_sample=0|initial_padding=0|dmix_mode=0|ltrt_cmixlev=0.000000|ltrt_surmixlev=0.000000|loro_cmixlev=0.000000|loro_surmixlev=0.000000|ts_id=32776|ts_packetsize=188|id=0x35|r_frame_rate=0/0|avg_frame_rate=0/0|time_base=1/90000|start_pts=3912634060|start_time=43473.711778|duration_ts=14400|duration=0.160000|bit_rate=192000|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=N/A|nb_read_packets=5|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|disposition:non_diegetic=0|disposition:captions=0|disposition:descriptions=0|disposition:metadata=0|disposition:dependent=0|disposition:still_image=0|disposition:multilayer=0|tag:language=es
-format|filename=mp3ac325-4864-small.ts|nb_streams=3|nb_programs=1|nb_stream_groups=0|format_name=mpegts|start_time=43473.703389|duration=0.622889|size=512000|bit_rate=6575810|probe_score=50
+format|filename=mp3ac325-4864-small.ts|nb_streams=3|nb_programs=1|nb_stream_groups=0|format_name=mpegts|start_time=43473.703389|duration=0.622889|size=512000|bit_rate=6575810|probe_score=50|seekable=yes, by time(dts),byte-offset via packet-scan (forward only)
diff --git a/tests/ref/fate/ts-opus-demux b/tests/ref/fate/ts-opus-demux
index d13b97aa6f..46471a00b0 100644
--- a/tests/ref/fate/ts-opus-demux
+++ b/tests/ref/fate/ts-opus-demux
@@ -511,4 +511,4 @@ packet|codec_type=audio|stream_index=0|pts=916200|pts_time=10.180000|dts=916200|
 packet|codec_type=audio|stream_index=0|pts=918000|pts_time=10.200000|dts=918000|dts_time=10.200000|duration=1800|duration_time=0.020000|size=761|pos=510044|flags=K__|data_hash=CRC32:75113c11|side_datum/mpegts_stream_id:side_data_type=MPEGTS Stream ID|side_datum/mpegts_stream_id:id=189
 packet|codec_type=audio|stream_index=0|pts=919800|pts_time=10.220000|dts=919800|dts_time=10.220000|duration=1800|duration_time=0.020000|size=759|pos=510984|flags=K__|data_hash=CRC32:59fc266f|side_datum/mpegts_stream_id:side_data_type=MPEGTS Stream ID|side_datum/mpegts_stream_id:id=189
 stream|index=0|codec_name=opus|profile=unknown|codec_type=audio|codec_tag_string=Opus|codec_tag=0x7375704f|sample_fmt=fltp|sample_rate=48000|channels=8|channel_layout=7.1|bits_per_sample=0|initial_padding=0|ts_id=51338|ts_packetsize=188|id=0x44|r_frame_rate=0/0|avg_frame_rate=0/0|time_base=1/90000|start_pts=0|start_time=0.000000|duration_ts=919800|duration=10.220000|bit_rate=N/A|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=N/A|nb_read_packets=512|extradata_size=29|extradata_hash=CRC32:6d6089a7|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|disposition:non_diegetic=0|disposition:captions=0|disposition:descriptions=0|disposition:metadata=0|disposition:dependent=0|disposition:still_image=0|disposition:multilayer=0
-format|filename=test-8-7.1.opus-small.ts|nb_streams=1|nb_programs=1|nb_stream_groups=0|format_name=mpegts|start_time=0.000000|duration=10.220000|size=512000|bit_rate=400782|probe_score=50
+format|filename=test-8-7.1.opus-small.ts|nb_streams=1|nb_programs=1|nb_stream_groups=0|format_name=mpegts|start_time=0.000000|duration=10.220000|size=512000|bit_rate=400782|probe_score=50|seekable=yes, by time(dts),byte-offset via packet-scan (forward only)
diff --git a/tests/ref/fate/ts-small-demux b/tests/ref/fate/ts-small-demux
index 6e29b29896..8933d35d4a 100644
--- a/tests/ref/fate/ts-small-demux
+++ b/tests/ref/fate/ts-small-demux
@@ -73,4 +73,4 @@ packet|codec_type=video|stream_index=0|pts=552000|pts_time=6.133333|dts=552000|d
 packet|codec_type=video|stream_index=0|pts=558000|pts_time=6.200000|dts=558000|dts_time=6.200000|duration=6000|duration_time=0.066667|size=16|pos=15792|flags=___|data_hash=CRC32:27b943ef|side_datum/mpegts_stream_id:side_data_type=MPEGTS Stream ID|side_datum/mpegts_stream_id:id=224
 packet|codec_type=video|stream_index=0|pts=564000|pts_time=6.266667|dts=564000|dts_time=6.266667|duration=6000|duration_time=0.066667|size=16|pos=16356|flags=___|data_hash=CRC32:f7116111
 stream|index=0|codec_name=h264|profile=578|codec_type=video|codec_tag_string=[27][0][0][0]|codec_tag=0x001b|width=82|height=144|coded_width=82|coded_height=144|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=41:72|pix_fmt=yuv420p|level=10|color_range=unknown|color_space=unknown|color_transfer=unknown|color_primaries=unknown|chroma_location=left|field_order=progressive|refs=1|is_avc=false|nal_length_size=0|ts_id=1|ts_packetsize=188|id=0x100|r_frame_rate=15/1|avg_frame_rate=15/1|time_base=1/90000|start_pts=126000|start_time=1.400000|duration_ts=444000|duration=4.933333|bit_rate=N/A|max_bit_rate=N/A|bits_per_raw_sample=8|nb_frames=N/A|nb_read_frames=N/A|nb_read_packets=74|extradata_size=35|extradata_hash=CRC32:e62cae27|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|disposition:non_diegetic=0|disposition:captions=0|disposition:descriptions=0|disposition:metadata=0|disposition:dependent=0|disposition:still_image=0|disposition:multilayer=0
-format|filename=h264small.ts|nb_streams=1|nb_programs=1|nb_stream_groups=0|format_name=mpegts|start_time=1.400000|duration=4.933333|size=16544|bit_rate=26828|probe_score=50
+format|filename=h264small.ts|nb_streams=1|nb_programs=1|nb_stream_groups=0|format_name=mpegts|start_time=1.400000|duration=4.933333|size=16544|bit_rate=26828|probe_score=50|seekable=yes, by time(dts),byte-offset via packet-scan (forward only)
diff --git a/tests/ref/fate/ts-timed-id3-demux b/tests/ref/fate/ts-timed-id3-demux
index 3de1ca2990..17ce2539ab 100644
--- a/tests/ref/fate/ts-timed-id3-demux
+++ b/tests/ref/fate/ts-timed-id3-demux
@@ -1,4 +1,4 @@
 packet|codec_type=data|stream_index=0|pts=126000|pts_time=1.400000|dts=126000|dts_time=1.400000|duration=N/A|duration_time=N/A|size=26|pos=564|flags=K__|data_hash=CRC32:469f474b|side_datum/mpegts_stream_id:side_data_type=MPEGTS Stream ID|side_datum/mpegts_stream_id:id=189
 packet|codec_type=data|stream_index=0|pts=577350|pts_time=6.415000|dts=577350|dts_time=6.415000|duration=N/A|duration_time=N/A|size=26|pos=1316|flags=K__|data_hash=CRC32:469f474b|side_datum/mpegts_stream_id:side_data_type=MPEGTS Stream ID|side_datum/mpegts_stream_id:id=189
 stream|index=0|codec_name=timed_id3|profile=unknown|codec_type=data|codec_tag_string=ID3 |codec_tag=0x20334449|ts_id=1|ts_packetsize=188|id=0x100|r_frame_rate=0/0|avg_frame_rate=0/0|time_base=1/90000|start_pts=126000|start_time=1.400000|duration_ts=451350|duration=5.015000|bit_rate=N/A|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=N/A|nb_read_packets=2|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|disposition:non_diegetic=0|disposition:captions=0|disposition:descriptions=0|disposition:metadata=0|disposition:dependent=0|disposition:still_image=0|disposition:multilayer=0
-format|filename=id3.ts|nb_streams=1|nb_programs=1|nb_stream_groups=0|format_name=mpegts|start_time=1.400000|duration=5.015000|size=1504|bit_rate=2399|probe_score=2
+format|filename=id3.ts|nb_streams=1|nb_programs=1|nb_stream_groups=0|format_name=mpegts|start_time=1.400000|duration=5.015000|size=1504|bit_rate=2399|probe_score=2|seekable=yes, by time(dts),byte-offset via packet-scan (forward only)
-- 
2.49.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [FFmpeg-devel] [PATCH 1/2] avformat: add avformat_query_seekable
  2025-04-13 11:15 [FFmpeg-devel] [PATCH 1/2] avformat: add avformat_query_seekable Gyan Doshi
  2025-04-13 11:15 ` [FFmpeg-devel] [PATCH 2/2] ffprobe: show seekability details in format section Gyan Doshi
@ 2025-04-13 16:09 ` softworkz .
  2025-04-14  4:23   ` Gyan Doshi
  2025-04-13 16:42 ` Zhao Zhili
  2 siblings, 1 reply; 15+ messages in thread
From: softworkz . @ 2025-04-13 16:09 UTC (permalink / raw)
  To: FFmpeg development discussions and patches



> -----Original Message-----
> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of Gyan
> Doshi
> Sent: Sonntag, 13. April 2025 13:16
> To: ffmpeg-devel@ffmpeg.org
> Subject: [FFmpeg-devel] [PATCH 1/2] avformat: add
> avformat_query_seekable
> 
> Utility function to report seekability features for a given input.
> 
> Useful for ffprobe and to extend seek possibilities in fftools.
> ---
>  doc/APIchanges         |  3 +++
>  libavformat/avformat.h | 22 ++++++++++++++++++
>  libavformat/seek.c     | 53 ++++++++++++++++++++++++++++++++++++++++++
>  libavformat/version.h  |  2 +-
>  4 files changed, 79 insertions(+), 1 deletion(-)
> 
> diff --git a/doc/APIchanges b/doc/APIchanges
> index 65bf5a9419..879f56b572 100644
> --- a/doc/APIchanges
> +++ b/doc/APIchanges
> @@ -2,6 +2,9 @@ The last version increases of all libraries were on
> 2025-03-28
> 
>  API changes, most recent first:
> 
> +2025-04-xx - xxxxxxxxxx - lavf 62.1.100 - avformat.h
> +  Add avformat_query_seekable().
> +
>  2025-04-07 - 19e9a203b7 - lavu 60.01.100 - dict.h
>    Add AV_DICT_DEDUP.
> 
> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
> index 498c3020a5..e00f1ed0d9 100644
> --- a/libavformat/avformat.h
> +++ b/libavformat/avformat.h
> @@ -2338,6 +2338,28 @@ int av_seek_frame(AVFormatContext *s, int
> stream_index, int64_t timestamp,
>   */
>  int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t
> min_ts, int64_t ts, int64_t max_ts, int flags);

Hi Gyan,

I like the idea of showing seekability in FFprobe output!

As far as I understand, these flags are expressing three different things:


1. Seek method

> +#define AVSEEKABLE_NORMAL     0x01 ///< I/O is seekable like a local
> file
> +#define AVSEEKABLE_PROTOCOL   0x02 ///< I/O seek is through protocol
> request via avio_seek_time
> +#define AVSEEKABLE_DEMUXER    0x04 ///< demuxer has a seek function
> +#define AVSEEKABLE_PKTSCAN    0x08 ///< seek is performed by consuming

2. Seek parameter type

> and scanning packet timestamps
> +#define AVSEEKABLE_TIME       0x10 ///< seek target can be a timestamp
> +#define AVSEEKABLE_BYTE       0x20 ///< seek target can be in bytes
> +#define AVSEEKABLE_FRAME      0x40 ///< seek target can be a frame
> index

3. Additional seek behavior

> +#define AVSEEKABLE_PTS       0x100 ///< seek target timestamp is
> expected to be PTS
> +#define AVSEEKABLE_FAST      0x200 ///< demuxer allows fast but
> inaccurate seeking
> +#define AVSEEKABLE_FWDONLY   0x400 ///< set seek will be equal or
> forward of specified seek point


Wouldn't it be better for clarity when this differentiation would be 
reflected in the naming?

Maybe something like this:

AVSEEKABLE_VIA_DEMUXER

AVSEEKABLE_BY_TIME

AVSEEKABLE_BEHAVIOR_FAST


Another note:

> +#define AVSEEKABLE_NORMAL     0x01 ///< I/O is seekable like a local
> +#define AVSEEKABLE_PROTOCOL   0x02 ///< I/O seek is through protocol
> +#define AVSEEKABLE_DEMUXER    0x04 ///< demuxer has a seek function
> +#define AVSEEKABLE_PKTSCAN    0x08 ///< seek is performed by consuming

There's no (numeric) room for extending the first block

> +#define AVSEEKABLE_TIME       0x10 ///< seek target can be a timestamp
> +#define AVSEEKABLE_BYTE       0x20 ///< seek target can be in bytes
> +#define AVSEEKABLE_FRAME      0x40 ///< seek target can be a frame


> +    // TODO: no flag for frame seeking. Add flag and update this check
> +    if (s->iformat->flags & 0)
> +        ret |= AVSEEKABLE_FRAME;
> +
> +    if (s->iformat->flags & AVFMT_SEEK_TO_PTS)
> +        ret |= AVSEEKABLE_PTS;

Maybe add a check for AVSEEKABLE_TIME - for sanity?

> +    // TODO: flag exists but not added to the demuxers which support it
> +    if (s->iformat->flags & AVFMT_FLAG_FAST_SEEK)
> +        ret |= AVSEEKABLE_FAST;



Another idea would be to return a struct (like AVSeekability) with a clear
separation of those three types of information, maybe that would provide
better clarity?


Best,
sw
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [FFmpeg-devel] [PATCH 2/2] ffprobe: show seekability details in format section
  2025-04-13 11:15 ` [FFmpeg-devel] [PATCH 2/2] ffprobe: show seekability details in format section Gyan Doshi
@ 2025-04-13 16:18   ` softworkz .
  2025-04-14  4:39     ` Gyan Doshi
  0 siblings, 1 reply; 15+ messages in thread
From: softworkz . @ 2025-04-13 16:18 UTC (permalink / raw)
  To: FFmpeg development discussions and patches



> -----Original Message-----
> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of Gyan
> Doshi
> Sent: Sonntag, 13. April 2025 13:16
> To: ffmpeg-devel@ffmpeg.org
> Subject: [FFmpeg-devel] [PATCH 2/2] ffprobe: show seekability details in
> format section
> 
> ---
>  fftools/ffprobe.c                    | 49 +++++++++++++++++++++++++++-
>  tests/ref/fate/cavs-demux            |  2 +-
>  tests/ref/fate/ffprobe_compact       |  2 +-
>  tests/ref/fate/ffprobe_csv           |  2 +-
>  tests/ref/fate/ffprobe_default       |  1 +
>  tests/ref/fate/ffprobe_flat          |  1 +
>  tests/ref/fate/ffprobe_ini           |  1 +
>  tests/ref/fate/ffprobe_json          |  1 +
>  tests/ref/fate/ffprobe_xml           |  2 +-
>  tests/ref/fate/ffprobe_xsd           |  2 +-
>  tests/ref/fate/flv-demux             |  2 +-
>  tests/ref/fate/gapless-mp3-side-data |  2 +-
>  tests/ref/fate/oggopus-demux         |  2 +-
>  tests/ref/fate/ts-demux              |  2 +-
>  tests/ref/fate/ts-opus-demux         |  2 +-
>  tests/ref/fate/ts-small-demux        |  2 +-
>  tests/ref/fate/ts-timed-id3-demux    |  2 +-
>  17 files changed, 64 insertions(+), 13 deletions(-)
> 
> diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c
> index e0a7322523..8b09afb8c1 100644
> --- a/fftools/ffprobe.c
> +++ b/fftools/ffprobe.c
> @@ -2260,7 +2260,7 @@ static int show_format(AVTextFormatContext *tfc,
> InputFile *ifile)
>  {
>      AVFormatContext *fmt_ctx = ifile->fmt_ctx;
>      int64_t size = fmt_ctx->pb ? avio_size(fmt_ctx->pb) : -1;
> -    int ret = 0;
> +    int seekable, ret = 0;
> 
>      avtext_print_section_header(tfc, NULL, SECTION_ID_FORMAT);
>      print_str_validate("filename", fmt_ctx->url);
> @@ -2279,6 +2279,53 @@ static int show_format(AVTextFormatContext *tfc,
> InputFile *ifile)
>      if (fmt_ctx->bit_rate > 0) print_val    ("bit_rate", fmt_ctx-
> >bit_rate, unit_bit_per_second_str);
>      else                       print_str_opt("bit_rate", "N/A");
>      print_int("probe_score", fmt_ctx->probe_score);
> +
> +    seekable = avformat_query_seekable(fmt_ctx);
> +    if (seekable > 0) {
> +        int gen = 1, ante = 0;
> +        AVBPrint seek_str;
> +        av_bprint_init(&seek_str, 0, AV_BPRINT_SIZE_AUTOMATIC);
> +
> +        av_bprintf(&seek_str, "yes, by");
> +        if (seekable & AVSEEKABLE_TIME) {
> +            av_bprintf(&seek_str, " time");
> +            if (seekable & AVSEEKABLE_PTS)
> +                av_bprintf(&seek_str, "(pts)");
> +            else
> +                av_bprintf(&seek_str, "(dts)");
> +            ante = 1;
> +        }
> +        if (seekable & AVSEEKABLE_BYTE) {
> +            av_bprintf(&seek_str, "%cbyte-offset", ante ? ',':' ');
> +            ante = 1;
> +        }
> +        if (seekable & AVSEEKABLE_FRAME) {
> +            av_bprintf(&seek_str, "%cframe-index", ante ? ',':' ');
> +        }
> +
> +        ante = 0;
> +        av_bprintf(&seek_str, " via");
> +        if (seekable & AVSEEKABLE_DEMUXER) {
> +            av_bprintf(&seek_str, " demuxer");
> +            gen = 0;
> +            ante = 1;
> +        }
> +        if (seekable & AVSEEKABLE_PKTSCAN) {
> +            av_bprintf(&seek_str, "%cpacket-scan", ante ? ',':' ');
> +            gen = 0;
> +            ante = 0;
> +        }
> +        if (gen)
> +            av_bprintf(&seek_str, " generic seek");
> +
> +        if (seekable & AVSEEKABLE_FWDONLY)
> +            av_bprintf(&seek_str, " (forward only)");
> +
> +        print_str("seekable",      seek_str.str);
> +    }
> +    else
> +        print_str("seekable",      "no");
> +
>      if (do_show_format_tags)
>          ret = show_tags(tfc, fmt_ctx->metadata,
> SECTION_ID_FORMAT_TAGS);


Hi Gyan,

the problem that I see here is that it's not machine-readable and would require non-trivial parsing to translate back to the actual information behind it.
I think that either a separate sub-section or at least three separate values would be better.

Another note: When you skim through the ffprobe code, you can see that ffprobe rarely does its own "numbers-to-string" translations (only for cases of absence, like 'none', 'unknown', etc.). Normally, those translations are included in the libs where they are defined.

Oh, and I believe you also need to add new output fields to the xml schema file (ffprobe.xsd).

Still like it! 😊

Thanks,
sw





_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [FFmpeg-devel] [PATCH 1/2] avformat: add avformat_query_seekable
  2025-04-13 11:15 [FFmpeg-devel] [PATCH 1/2] avformat: add avformat_query_seekable Gyan Doshi
  2025-04-13 11:15 ` [FFmpeg-devel] [PATCH 2/2] ffprobe: show seekability details in format section Gyan Doshi
  2025-04-13 16:09 ` [FFmpeg-devel] [PATCH 1/2] avformat: add avformat_query_seekable softworkz .
@ 2025-04-13 16:42 ` Zhao Zhili
  2025-04-14  4:10   ` Gyan Doshi
  2 siblings, 1 reply; 15+ messages in thread
From: Zhao Zhili @ 2025-04-13 16:42 UTC (permalink / raw)
  To: FFmpeg development discussions and patches



> On Apr 13, 2025, at 19:15, Gyan Doshi <ffmpeg@gyani.pro> wrote:
> 
> Utility function to report seekability features for a given input.
> 
> Useful for ffprobe and to extend seek possibilities in fftools.
> ---
> doc/APIchanges         |  3 +++
> libavformat/avformat.h | 22 ++++++++++++++++++
> libavformat/seek.c     | 53 ++++++++++++++++++++++++++++++++++++++++++
> libavformat/version.h  |  2 +-
> 4 files changed, 79 insertions(+), 1 deletion(-)
> 
> diff --git a/doc/APIchanges b/doc/APIchanges
> index 65bf5a9419..879f56b572 100644
> --- a/doc/APIchanges
> +++ b/doc/APIchanges
> @@ -2,6 +2,9 @@ The last version increases of all libraries were on 2025-03-28
> 
> API changes, most recent first:
> 
> +2025-04-xx - xxxxxxxxxx - lavf 62.1.100 - avformat.h
> +  Add avformat_query_seekable().
> +
> 2025-04-07 - 19e9a203b7 - lavu 60.01.100 - dict.h
>   Add AV_DICT_DEDUP.
> 
> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
> index 498c3020a5..e00f1ed0d9 100644
> --- a/libavformat/avformat.h
> +++ b/libavformat/avformat.h
> @@ -2338,6 +2338,28 @@ int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp,
>  */
> int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags);
> 
> +#define AVSEEKABLE_NORMAL     0x01 ///< I/O is seekable like a local file
> +#define AVSEEKABLE_PROTOCOL   0x02 ///< I/O seek is through protocol request via avio_seek_time
> +#define AVSEEKABLE_DEMUXER    0x04 ///< demuxer has a seek function
> +#define AVSEEKABLE_PKTSCAN    0x08 ///< seek is performed by consuming and scanning packet timestamps
> +#define AVSEEKABLE_TIME       0x10 ///< seek target can be a timestamp
> +#define AVSEEKABLE_BYTE       0x20 ///< seek target can be in bytes
> +#define AVSEEKABLE_FRAME      0x40 ///< seek target can be a frame index
> +#define AVSEEKABLE_PTS       0x100 ///< seek target timestamp is expected to be PTS
> +#define AVSEEKABLE_FAST      0x200 ///< demuxer allows fast but inaccurate seeking
> +#define AVSEEKABLE_FWDONLY   0x400 ///< set seek will be equal or forward of specified seek point
> +
> +/**
> + * Report if and how a seek can be performed in a given input.
> + *
> + * @param s            media file handle
> + *
> + * @return 0 if no seek can be performed on input,
> + *         -1 if the fmt ctx is NULL or is not an input
> + *         else return AVSEEKABLE_ bitflags indicating seekability features.
> + */
> +int avformat_query_seekable(AVFormatContext *s);
> +
> /**
>  * Discard all internally buffered data. This can be useful when dealing with
>  * discontinuities in the byte stream. Generally works only with formats that
> diff --git a/libavformat/seek.c b/libavformat/seek.c
> index c0d94371e6..776a09744a 100644
> --- a/libavformat/seek.c
> +++ b/libavformat/seek.c
> @@ -712,6 +712,59 @@ int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts,
>     return ret;
> }
> 
> +int avformat_query_seekable(AVFormatContext *s)
> +{
> +    int ret = 0;
> +
> +    if (!s || !s->iformat)
> +        return -1;
> +
> +    if (!(s->pb && s->pb->seekable) || s->ctx_flags & AVFMTCTX_UNSEEKABLE)
> +        return 0;

I think RTSP doesn’t follow this rule, it’s seekable.

> +
> +    if (s->pb->seekable & AVIO_SEEKABLE_NORMAL)
> +        ret |= AVSEEKABLE_NORMAL;
> +
> +    if (s->pb->seekable & AVIO_SEEKABLE_TIME)
> +        ret |= AVSEEKABLE_PROTOCOL;
> +
> +    if (ffifmt(s->iformat)->read_seek || ffifmt(s->iformat)->read_seek2)
> +        ret |= AVSEEKABLE_DEMUXER;
> +
> +    if (ffifmt(s->iformat)->read_timestamp && !(s->iformat->flags & AVFMT_NOBINSEARCH))
> +        ret |= AVSEEKABLE_PKTSCAN;
> +
> +    if (!(s->iformat->flags & AVFMT_NOTIMESTAMPS))
> +        ret |= AVSEEKABLE_TIME;
> +
> +    // TODO: incomplete, a few demuxers don't set flag but error out on byte seek
> +    if (!(s->iformat->flags & AVFMT_NO_BYTE_SEEK))
> +        ret |= AVSEEKABLE_BYTE;
> +
> +    // TODO: no flag for frame seeking. Add flag and update this check
> +    if (s->iformat->flags & 0)
> +        ret |= AVSEEKABLE_FRAME;
> +
> +    if (s->iformat->flags & AVFMT_SEEK_TO_PTS)
> +        ret |= AVSEEKABLE_PTS;
> +
> +    // TODO: flag exists but not added to the demuxers which support it
> +    if (s->iformat->flags & AVFMT_FLAG_FAST_SEEK)
> +        ret |= AVSEEKABLE_FAST;
> +
> +    if (!(ret & AVSEEKABLE_DEMUXER) && ret & AVSEEKABLE_PKTSCAN)
> +        ret |= AVSEEKABLE_FWDONLY;
> +
> +    if ( !(ret & AVSEEKABLE_DEMUXER) &&
> +         !(ret & AVSEEKABLE_PKTSCAN) &&
> +         !(ret & AVSEEKABLE_BYTE) &&
> +         !(ret & AVSEEKABLE_PROTOCOL) &&
> +         (s->iformat->flags & AVFMT_NOGENSEARCH) )
> +        ret = 0;
> +
> +    return ret;
> +}
> +
> /** Flush the frame reader. */
> void ff_read_frame_flush(AVFormatContext *s)
> {
> diff --git a/libavformat/version.h b/libavformat/version.h
> index 752aac16f7..a7c80dc564 100644
> --- a/libavformat/version.h
> +++ b/libavformat/version.h
> @@ -31,7 +31,7 @@
> 
> #include "version_major.h"
> 
> -#define LIBAVFORMAT_VERSION_MINOR   0
> +#define LIBAVFORMAT_VERSION_MINOR   1
> #define LIBAVFORMAT_VERSION_MICRO 100
> 
> #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
> -- 
> 2.49.0
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [FFmpeg-devel] [PATCH 1/2] avformat: add avformat_query_seekable
  2025-04-13 16:42 ` Zhao Zhili
@ 2025-04-14  4:10   ` Gyan Doshi
  0 siblings, 0 replies; 15+ messages in thread
From: Gyan Doshi @ 2025-04-14  4:10 UTC (permalink / raw)
  To: ffmpeg-devel



On 2025-04-13 10:12 pm, Zhao Zhili wrote:
>
>> On Apr 13, 2025, at 19:15, Gyan Doshi <ffmpeg@gyani.pro> wrote:
>>
>> Utility function to report seekability features for a given input.
>>
>> Useful for ffprobe and to extend seek possibilities in fftools.
>> ---
>> doc/APIchanges         |  3 +++
>> libavformat/avformat.h | 22 ++++++++++++++++++
>> libavformat/seek.c     | 53 ++++++++++++++++++++++++++++++++++++++++++
>> libavformat/version.h  |  2 +-
>> 4 files changed, 79 insertions(+), 1 deletion(-)
>>
>> diff --git a/doc/APIchanges b/doc/APIchanges
>> index 65bf5a9419..879f56b572 100644
>> --- a/doc/APIchanges
>> +++ b/doc/APIchanges
>> @@ -2,6 +2,9 @@ The last version increases of all libraries were on 2025-03-28
>>
>> API changes, most recent first:
>>
>> +2025-04-xx - xxxxxxxxxx - lavf 62.1.100 - avformat.h
>> +  Add avformat_query_seekable().
>> +
>> 2025-04-07 - 19e9a203b7 - lavu 60.01.100 - dict.h
>>    Add AV_DICT_DEDUP.
>>
>> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
>> index 498c3020a5..e00f1ed0d9 100644
>> --- a/libavformat/avformat.h
>> +++ b/libavformat/avformat.h
>> @@ -2338,6 +2338,28 @@ int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp,
>>   */
>> int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags);
>>
>> +#define AVSEEKABLE_NORMAL     0x01 ///< I/O is seekable like a local file
>> +#define AVSEEKABLE_PROTOCOL   0x02 ///< I/O seek is through protocol request via avio_seek_time
>> +#define AVSEEKABLE_DEMUXER    0x04 ///< demuxer has a seek function
>> +#define AVSEEKABLE_PKTSCAN    0x08 ///< seek is performed by consuming and scanning packet timestamps
>> +#define AVSEEKABLE_TIME       0x10 ///< seek target can be a timestamp
>> +#define AVSEEKABLE_BYTE       0x20 ///< seek target can be in bytes
>> +#define AVSEEKABLE_FRAME      0x40 ///< seek target can be a frame index
>> +#define AVSEEKABLE_PTS       0x100 ///< seek target timestamp is expected to be PTS
>> +#define AVSEEKABLE_FAST      0x200 ///< demuxer allows fast but inaccurate seeking
>> +#define AVSEEKABLE_FWDONLY   0x400 ///< set seek will be equal or forward of specified seek point
>> +
>> +/**
>> + * Report if and how a seek can be performed in a given input.
>> + *
>> + * @param s            media file handle
>> + *
>> + * @return 0 if no seek can be performed on input,
>> + *         -1 if the fmt ctx is NULL or is not an input
>> + *         else return AVSEEKABLE_ bitflags indicating seekability features.
>> + */
>> +int avformat_query_seekable(AVFormatContext *s);
>> +
>> /**
>>   * Discard all internally buffered data. This can be useful when dealing with
>>   * discontinuities in the byte stream. Generally works only with formats that
>> diff --git a/libavformat/seek.c b/libavformat/seek.c
>> index c0d94371e6..776a09744a 100644
>> --- a/libavformat/seek.c
>> +++ b/libavformat/seek.c
>> @@ -712,6 +712,59 @@ int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts,
>>      return ret;
>> }
>>
>> +int avformat_query_seekable(AVFormatContext *s)
>> +{
>> +    int ret = 0;
>> +
>> +    if (!s || !s->iformat)
>> +        return -1;
>> +
>> +    if (!(s->pb && s->pb->seekable) || s->ctx_flags & AVFMTCTX_UNSEEKABLE)
>> +        return 0;
> I think RTSP doesn’t follow this rule, it’s seekable.

Ah, yes, the protocol implemented as a demuxer. Will add an exception.

Regards,
Gyan


>
>> +
>> +    if (s->pb->seekable & AVIO_SEEKABLE_NORMAL)
>> +        ret |= AVSEEKABLE_NORMAL;
>> +
>> +    if (s->pb->seekable & AVIO_SEEKABLE_TIME)
>> +        ret |= AVSEEKABLE_PROTOCOL;
>> +
>> +    if (ffifmt(s->iformat)->read_seek || ffifmt(s->iformat)->read_seek2)
>> +        ret |= AVSEEKABLE_DEMUXER;
>> +
>> +    if (ffifmt(s->iformat)->read_timestamp && !(s->iformat->flags & AVFMT_NOBINSEARCH))
>> +        ret |= AVSEEKABLE_PKTSCAN;
>> +
>> +    if (!(s->iformat->flags & AVFMT_NOTIMESTAMPS))
>> +        ret |= AVSEEKABLE_TIME;
>> +
>> +    // TODO: incomplete, a few demuxers don't set flag but error out on byte seek
>> +    if (!(s->iformat->flags & AVFMT_NO_BYTE_SEEK))
>> +        ret |= AVSEEKABLE_BYTE;
>> +
>> +    // TODO: no flag for frame seeking. Add flag and update this check
>> +    if (s->iformat->flags & 0)
>> +        ret |= AVSEEKABLE_FRAME;
>> +
>> +    if (s->iformat->flags & AVFMT_SEEK_TO_PTS)
>> +        ret |= AVSEEKABLE_PTS;
>> +
>> +    // TODO: flag exists but not added to the demuxers which support it
>> +    if (s->iformat->flags & AVFMT_FLAG_FAST_SEEK)
>> +        ret |= AVSEEKABLE_FAST;
>> +
>> +    if (!(ret & AVSEEKABLE_DEMUXER) && ret & AVSEEKABLE_PKTSCAN)
>> +        ret |= AVSEEKABLE_FWDONLY;
>> +
>> +    if ( !(ret & AVSEEKABLE_DEMUXER) &&
>> +         !(ret & AVSEEKABLE_PKTSCAN) &&
>> +         !(ret & AVSEEKABLE_BYTE) &&
>> +         !(ret & AVSEEKABLE_PROTOCOL) &&
>> +         (s->iformat->flags & AVFMT_NOGENSEARCH) )
>> +        ret = 0;
>> +
>> +    return ret;
>> +}
>> +
>> /** Flush the frame reader. */
>> void ff_read_frame_flush(AVFormatContext *s)
>> {
>> diff --git a/libavformat/version.h b/libavformat/version.h
>> index 752aac16f7..a7c80dc564 100644
>> --- a/libavformat/version.h
>> +++ b/libavformat/version.h
>> @@ -31,7 +31,7 @@
>>
>> #include "version_major.h"
>>
>> -#define LIBAVFORMAT_VERSION_MINOR   0
>> +#define LIBAVFORMAT_VERSION_MINOR   1
>> #define LIBAVFORMAT_VERSION_MICRO 100
>>
>> #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
>> -- 
>> 2.49.0
>>
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel@ffmpeg.org
>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>
>> To unsubscribe, visit link above, or email
>> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [FFmpeg-devel] [PATCH 1/2] avformat: add avformat_query_seekable
  2025-04-13 16:09 ` [FFmpeg-devel] [PATCH 1/2] avformat: add avformat_query_seekable softworkz .
@ 2025-04-14  4:23   ` Gyan Doshi
  2025-04-14  4:40     ` softworkz .
  0 siblings, 1 reply; 15+ messages in thread
From: Gyan Doshi @ 2025-04-14  4:23 UTC (permalink / raw)
  To: ffmpeg-devel



On 2025-04-13 09:39 pm, softworkz . wrote:
>
>> -----Original Message-----
>> From: ffmpeg-devel<ffmpeg-devel-bounces@ffmpeg.org>  On Behalf Of Gyan
>> Doshi
>> Sent: Sonntag, 13. April 2025 13:16
>> To:ffmpeg-devel@ffmpeg.org
>> Subject: [FFmpeg-devel] [PATCH 1/2] avformat: add
>> avformat_query_seekable
>>
>> Utility function to report seekability features for a given input.
>>
>> Useful for ffprobe and to extend seek possibilities in fftools.
>> ---
>>   doc/APIchanges         |  3 +++
>>   libavformat/avformat.h | 22 ++++++++++++++++++
>>   libavformat/seek.c     | 53 ++++++++++++++++++++++++++++++++++++++++++
>>   libavformat/version.h  |  2 +-
>>   4 files changed, 79 insertions(+), 1 deletion(-)
>>
>> diff --git a/doc/APIchanges b/doc/APIchanges
>> index 65bf5a9419..879f56b572 100644
>> --- a/doc/APIchanges
>> +++ b/doc/APIchanges
>> @@ -2,6 +2,9 @@ The last version increases of all libraries were on
>> 2025-03-28
>>
>>   API changes, most recent first:
>>
>> +2025-04-xx - xxxxxxxxxx - lavf 62.1.100 - avformat.h
>> +  Add avformat_query_seekable().
>> +
>>   2025-04-07 - 19e9a203b7 - lavu 60.01.100 - dict.h
>>     Add AV_DICT_DEDUP.
>>
>> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
>> index 498c3020a5..e00f1ed0d9 100644
>> --- a/libavformat/avformat.h
>> +++ b/libavformat/avformat.h
>> @@ -2338,6 +2338,28 @@ int av_seek_frame(AVFormatContext *s, int
>> stream_index, int64_t timestamp,
>>    */
>>   int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t
>> min_ts, int64_t ts, int64_t max_ts, int flags);
> Hi Gyan,
>
> I like the idea of showing seekability in FFprobe output!
>
> As far as I understand, these flags are expressing three different things:
>
>
> 1. Seek method
>
>> +#define AVSEEKABLE_NORMAL     0x01 ///< I/O is seekable like a local
>> file
>> +#define AVSEEKABLE_PROTOCOL   0x02 ///< I/O seek is through protocol
>> request via avio_seek_time
>> +#define AVSEEKABLE_DEMUXER    0x04 ///< demuxer has a seek function
>> +#define AVSEEKABLE_PKTSCAN    0x08 ///< seek is performed by consuming

The first is not a method. It indicates whether the input is streamed.

> 2. Seek parameter type
>
>> and scanning packet timestamps
>> +#define AVSEEKABLE_TIME       0x10 ///< seek target can be a timestamp
>> +#define AVSEEKABLE_BYTE       0x20 ///< seek target can be in bytes
>> +#define AVSEEKABLE_FRAME      0x40 ///< seek target can be a frame
>> index
> 3. Additional seek behavior
>
>> +#define AVSEEKABLE_PTS       0x100 ///< seek target timestamp is
>> expected to be PTS
>> +#define AVSEEKABLE_FAST      0x200 ///< demuxer allows fast but
>> inaccurate seeking
>> +#define AVSEEKABLE_FWDONLY   0x400 ///< set seek will be equal or
>> forward of specified seek point
>
> Wouldn't it be better for clarity when this differentiation would be
> reflected in the naming?
>
> Maybe something like this:
>
> AVSEEKABLE_VIA_DEMUXER
>
> AVSEEKABLE_BY_TIME
>
> AVSEEKABLE_BEHAVIOR_FAST

Will do.

> Another note:
>
>> +#define AVSEEKABLE_NORMAL     0x01 ///< I/O is seekable like a local
>> +#define AVSEEKABLE_PROTOCOL   0x02 ///< I/O seek is through protocol
>> +#define AVSEEKABLE_DEMUXER    0x04 ///< demuxer has a seek function
>> +#define AVSEEKABLE_PKTSCAN    0x08 ///< seek is performed by consuming
> There's no (numeric) room for extending the first block

At the moment, there are 21 unused bits so there's no need as such.

>
>> +#define AVSEEKABLE_TIME       0x10 ///< seek target can be a timestamp
>> +#define AVSEEKABLE_BYTE       0x20 ///< seek target can be in bytes
>> +#define AVSEEKABLE_FRAME      0x40 ///< seek target can be a frame
>
>> +    // TODO: no flag for frame seeking. Add flag and update this check
>> +    if (s->iformat->flags & 0)
>> +        ret |= AVSEEKABLE_FRAME;
>> +
>> +    if (s->iformat->flags & AVFMT_SEEK_TO_PTS)
>> +        ret |= AVSEEKABLE_PTS;
> Maybe add a check for AVSEEKABLE_TIME - for sanity?

Only a handful of demuxers have this flag, and all have TS.
This is a job for reviewers when adding the flag.

>
>> +    // TODO: flag exists but not added to the demuxers which support it
>> +    if (s->iformat->flags & AVFMT_FLAG_FAST_SEEK)
>> +        ret |= AVSEEKABLE_FAST;
>
>
> Another idea would be to return a struct (like AVSeekability) with a clear
> separation of those three types of information, maybe that would provide
> better clarity?

As alluded above, there's only a handful of attributes being indicated. 
I'd rather not spawn a new type when an inbuilt simple storage type will do.

Regards,
Gyan
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [FFmpeg-devel] [PATCH 2/2] ffprobe: show seekability details in format section
  2025-04-13 16:18   ` softworkz .
@ 2025-04-14  4:39     ` Gyan Doshi
  2025-04-14  4:52       ` softworkz .
  2025-04-14  8:34       ` Nicolas George
  0 siblings, 2 replies; 15+ messages in thread
From: Gyan Doshi @ 2025-04-14  4:39 UTC (permalink / raw)
  To: ffmpeg-devel



On 2025-04-13 09:48 pm, softworkz . wrote:
>
>> -----Original Message-----
>> From: ffmpeg-devel<ffmpeg-devel-bounces@ffmpeg.org>  On Behalf Of Gyan
>> Doshi
>> Sent: Sonntag, 13. April 2025 13:16
>> To:ffmpeg-devel@ffmpeg.org
>> Subject: [FFmpeg-devel] [PATCH 2/2] ffprobe: show seekability details in
>> format section
>>
>> ---
>>   fftools/ffprobe.c                    | 49 +++++++++++++++++++++++++++-
>>   tests/ref/fate/cavs-demux            |  2 +-
>>   tests/ref/fate/ffprobe_compact       |  2 +-
>>   tests/ref/fate/ffprobe_csv           |  2 +-
>>   tests/ref/fate/ffprobe_default       |  1 +
>>   tests/ref/fate/ffprobe_flat          |  1 +
>>   tests/ref/fate/ffprobe_ini           |  1 +
>>   tests/ref/fate/ffprobe_json          |  1 +
>>   tests/ref/fate/ffprobe_xml           |  2 +-
>>   tests/ref/fate/ffprobe_xsd           |  2 +-
>>   tests/ref/fate/flv-demux             |  2 +-
>>   tests/ref/fate/gapless-mp3-side-data |  2 +-
>>   tests/ref/fate/oggopus-demux         |  2 +-
>>   tests/ref/fate/ts-demux              |  2 +-
>>   tests/ref/fate/ts-opus-demux         |  2 +-
>>   tests/ref/fate/ts-small-demux        |  2 +-
>>   tests/ref/fate/ts-timed-id3-demux    |  2 +-
>>   17 files changed, 64 insertions(+), 13 deletions(-)
>>
>> diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c
>> index e0a7322523..8b09afb8c1 100644
>> --- a/fftools/ffprobe.c
>> +++ b/fftools/ffprobe.c
>> @@ -2260,7 +2260,7 @@ static int show_format(AVTextFormatContext *tfc,
>> InputFile *ifile)
>>   {
>>       AVFormatContext *fmt_ctx = ifile->fmt_ctx;
>>       int64_t size = fmt_ctx->pb ? avio_size(fmt_ctx->pb) : -1;
>> -    int ret = 0;
>> +    int seekable, ret = 0;
>>
>>       avtext_print_section_header(tfc, NULL, SECTION_ID_FORMAT);
>>       print_str_validate("filename", fmt_ctx->url);
>> @@ -2279,6 +2279,53 @@ static int show_format(AVTextFormatContext *tfc,
>> InputFile *ifile)
>>       if (fmt_ctx->bit_rate > 0) print_val    ("bit_rate", fmt_ctx-
>>> bit_rate, unit_bit_per_second_str);
>>       else                       print_str_opt("bit_rate", "N/A");
>>       print_int("probe_score", fmt_ctx->probe_score);
>> +
>> +    seekable = avformat_query_seekable(fmt_ctx);
>> +    if (seekable > 0) {
>> +        int gen = 1, ante = 0;
>> +        AVBPrint seek_str;
>> +        av_bprint_init(&seek_str, 0, AV_BPRINT_SIZE_AUTOMATIC);
>> +
>> +        av_bprintf(&seek_str, "yes, by");
>> +        if (seekable & AVSEEKABLE_TIME) {
>> +            av_bprintf(&seek_str, " time");
>> +            if (seekable & AVSEEKABLE_PTS)
>> +                av_bprintf(&seek_str, "(pts)");
>> +            else
>> +                av_bprintf(&seek_str, "(dts)");
>> +            ante = 1;
>> +        }
>> +        if (seekable & AVSEEKABLE_BYTE) {
>> +            av_bprintf(&seek_str, "%cbyte-offset", ante ? ',':' ');
>> +            ante = 1;
>> +        }
>> +        if (seekable & AVSEEKABLE_FRAME) {
>> +            av_bprintf(&seek_str, "%cframe-index", ante ? ',':' ');
>> +        }
>> +
>> +        ante = 0;
>> +        av_bprintf(&seek_str, " via");
>> +        if (seekable & AVSEEKABLE_DEMUXER) {
>> +            av_bprintf(&seek_str, " demuxer");
>> +            gen = 0;
>> +            ante = 1;
>> +        }
>> +        if (seekable & AVSEEKABLE_PKTSCAN) {
>> +            av_bprintf(&seek_str, "%cpacket-scan", ante ? ',':' ');
>> +            gen = 0;
>> +            ante = 0;
>> +        }
>> +        if (gen)
>> +            av_bprintf(&seek_str, " generic seek");
>> +
>> +        if (seekable & AVSEEKABLE_FWDONLY)
>> +            av_bprintf(&seek_str, " (forward only)");
>> +
>> +        print_str("seekable",      seek_str.str);
>> +    }
>> +    else
>> +        print_str("seekable",      "no");
>> +
>>       if (do_show_format_tags)
>>           ret = show_tags(tfc, fmt_ctx->metadata,
>> SECTION_ID_FORMAT_TAGS);
>
> Hi Gyan,
>
> the problem that I see here is that it's not machine-readable and would require non-trivial parsing to translate back to the actual information behind it.
> I think that either a separate sub-section or at least three separate values would be better.

I can add a delimiter like |

e.g.

yes|time(pts),frame-index|demuxer,packet-scan|fast

All of the phrases for an attribute are unique, and for that, they just 
need to grep, not parse the string.
Most CLI users will only care about two things: yes/no and forward-only.

> Another note: When you skim through the ffprobe code, you can see that ffprobe rarely does its own "numbers-to-string" translations (only for cases of absence, like 'none', 'unknown', etc.). Normally, those translations are included in the libs where they are defined.

The information is stored as bitflags in an int. How would the lib do it?

> Oh, and I believe you also need to add new output fields to the xml schema file (ffprobe.xsd).

Will do.

Regards,
Gyan


>
> Still like it! 😊
>
> Thanks,
> sw
>
>
>
>
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org  with subject "unsubscribe".
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [FFmpeg-devel] [PATCH 1/2] avformat: add avformat_query_seekable
  2025-04-14  4:23   ` Gyan Doshi
@ 2025-04-14  4:40     ` softworkz .
  0 siblings, 0 replies; 15+ messages in thread
From: softworkz . @ 2025-04-14  4:40 UTC (permalink / raw)
  To: FFmpeg development discussions and patches



> -----Original Message-----
> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of Gyan
> Doshi
> Sent: Montag, 14. April 2025 06:24
> To: ffmpeg-devel@ffmpeg.org
> Subject: Re: [FFmpeg-devel] [PATCH 1/2] avformat: add
> avformat_query_seekable
> 
> 
> 
> On 2025-04-13 09:39 pm, softworkz . wrote:
> >
> >> -----Original Message-----
> >> From: ffmpeg-devel<ffmpeg-devel-bounces@ffmpeg.org>  On Behalf Of
> Gyan
> >> Doshi
> >> Sent: Sonntag, 13. April 2025 13:16
> >> To:ffmpeg-devel@ffmpeg.org
> >> Subject: [FFmpeg-devel] [PATCH 1/2] avformat: add
> >> avformat_query_seekable
> >>
> >> Utility function to report seekability features for a given input.
> >>
> >> Useful for ffprobe and to extend seek possibilities in fftools.

[..]

> > Another note:
> >
> >> +#define AVSEEKABLE_NORMAL     0x01 ///< I/O is seekable like a local
> >> +#define AVSEEKABLE_PROTOCOL   0x02 ///< I/O seek is through protocol
> >> +#define AVSEEKABLE_DEMUXER    0x04 ///< demuxer has a seek function
> >> +#define AVSEEKABLE_PKTSCAN    0x08 ///< seek is performed by
> consuming
> > There's no (numeric) room for extending the first block
> 
> At the moment, there are 21 unused bits so there's no need as such.

Sorry, what I meant is like:

AVSEEKABLE_PKTSCAN    0x08
AVSEEKABLE_TIME      0x100

i.e. first block - first byte, second block - second byte, etc.
(just for aesthetics obviously)

sw
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [FFmpeg-devel] [PATCH 2/2] ffprobe: show seekability details in format section
  2025-04-14  4:39     ` Gyan Doshi
@ 2025-04-14  4:52       ` softworkz .
  2025-04-14  4:57         ` softworkz .
  2025-04-14  6:53         ` Gyan Doshi
  2025-04-14  8:34       ` Nicolas George
  1 sibling, 2 replies; 15+ messages in thread
From: softworkz . @ 2025-04-14  4:52 UTC (permalink / raw)
  To: FFmpeg development discussions and patches



> -----Original Message-----
> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of Gyan
> Doshi
> Sent: Montag, 14. April 2025 06:40
> To: ffmpeg-devel@ffmpeg.org
> Subject: Re: [FFmpeg-devel] [PATCH 2/2] ffprobe: show seekability
> details in format section
> 
> 
> 
> On 2025-04-13 09:48 pm, softworkz . wrote:
> >
> >> -----Original Message-----
> >> From: ffmpeg-devel<ffmpeg-devel-bounces@ffmpeg.org>  On Behalf Of
> Gyan
> >> Doshi
> >> Sent: Sonntag, 13. April 2025 13:16
> >> To:ffmpeg-devel@ffmpeg.org
> >> Subject: [FFmpeg-devel] [PATCH 2/2] ffprobe: show seekability details
> in
> >> format section
> >>
> >> ---
> >>   fftools/ffprobe.c                    | 49
> +++++++++++++++++++++++++++-
> >>   tests/ref/fate/cavs-demux            |  2 +-
> >>   tests/ref/fate/ffprobe_compact       |  2 +-
> >>   tests/ref/fate/ffprobe_csv           |  2 +-
> >>   tests/ref/fate/ffprobe_default       |  1 +
> >>   tests/ref/fate/ffprobe_flat          |  1 +
> >>   tests/ref/fate/ffprobe_ini           |  1 +
> >>   tests/ref/fate/ffprobe_json          |  1 +
> >>   tests/ref/fate/ffprobe_xml           |  2 +-
> >>   tests/ref/fate/ffprobe_xsd           |  2 +-
> >>   tests/ref/fate/flv-demux             |  2 +-
> >>   tests/ref/fate/gapless-mp3-side-data |  2 +-
> >>   tests/ref/fate/oggopus-demux         |  2 +-
> >>   tests/ref/fate/ts-demux              |  2 +-
> >>   tests/ref/fate/ts-opus-demux         |  2 +-
> >>   tests/ref/fate/ts-small-demux        |  2 +-
> >>   tests/ref/fate/ts-timed-id3-demux    |  2 +-
> >>   17 files changed, 64 insertions(+), 13 deletions(-)
> >>
> >> diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c
> >> index e0a7322523..8b09afb8c1 100644
> >> --- a/fftools/ffprobe.c
> >> +++ b/fftools/ffprobe.c
> >> @@ -2260,7 +2260,7 @@ static int show_format(AVTextFormatContext
> *tfc,
> >> InputFile *ifile)
> >>   {
> >>       AVFormatContext *fmt_ctx = ifile->fmt_ctx;
> >>       int64_t size = fmt_ctx->pb ? avio_size(fmt_ctx->pb) : -1;
> >> -    int ret = 0;
> >> +    int seekable, ret = 0;
> >>
> >>       avtext_print_section_header(tfc, NULL, SECTION_ID_FORMAT);
> >>       print_str_validate("filename", fmt_ctx->url);
> >> @@ -2279,6 +2279,53 @@ static int show_format(AVTextFormatContext
> *tfc,
> >> InputFile *ifile)
> >>       if (fmt_ctx->bit_rate > 0) print_val    ("bit_rate", fmt_ctx-
> >>> bit_rate, unit_bit_per_second_str);
> >>       else                       print_str_opt("bit_rate", "N/A");
> >>       print_int("probe_score", fmt_ctx->probe_score);
> >> +
> >> +    seekable = avformat_query_seekable(fmt_ctx);
> >> +    if (seekable > 0) {
> >> +        int gen = 1, ante = 0;
> >> +        AVBPrint seek_str;
> >> +        av_bprint_init(&seek_str, 0, AV_BPRINT_SIZE_AUTOMATIC);
> >> +
> >> +        av_bprintf(&seek_str, "yes, by");
> >> +        if (seekable & AVSEEKABLE_TIME) {
> >> +            av_bprintf(&seek_str, " time");
> >> +            if (seekable & AVSEEKABLE_PTS)
> >> +                av_bprintf(&seek_str, "(pts)");
> >> +            else
> >> +                av_bprintf(&seek_str, "(dts)");
> >> +            ante = 1;
> >> +        }
> >> +        if (seekable & AVSEEKABLE_BYTE) {
> >> +            av_bprintf(&seek_str, "%cbyte-offset", ante ? ',':' ');
> >> +            ante = 1;
> >> +        }
> >> +        if (seekable & AVSEEKABLE_FRAME) {
> >> +            av_bprintf(&seek_str, "%cframe-index", ante ? ',':' ');
> >> +        }
> >> +
> >> +        ante = 0;
> >> +        av_bprintf(&seek_str, " via");
> >> +        if (seekable & AVSEEKABLE_DEMUXER) {
> >> +            av_bprintf(&seek_str, " demuxer");
> >> +            gen = 0;
> >> +            ante = 1;
> >> +        }
> >> +        if (seekable & AVSEEKABLE_PKTSCAN) {
> >> +            av_bprintf(&seek_str, "%cpacket-scan", ante ? ',':' ');
> >> +            gen = 0;
> >> +            ante = 0;
> >> +        }
> >> +        if (gen)
> >> +            av_bprintf(&seek_str, " generic seek");
> >> +
> >> +        if (seekable & AVSEEKABLE_FWDONLY)
> >> +            av_bprintf(&seek_str, " (forward only)");
> >> +
> >> +        print_str("seekable",      seek_str.str);
> >> +    }
> >> +    else
> >> +        print_str("seekable",      "no");
> >> +
> >>       if (do_show_format_tags)
> >>           ret = show_tags(tfc, fmt_ctx->metadata,
> >> SECTION_ID_FORMAT_TAGS);
> >
> > Hi Gyan,
> >
> > the problem that I see here is that it's not machine-readable and
> would require non-trivial parsing to translate back to the actual
> information behind it.
> > I think that either a separate sub-section or at least three separate
> values would be better.
> 
> I can add a delimiter like |
> 
> e.g.
> 
> yes|time(pts),frame-index|demuxer,packet-scan|fast
> 
> All of the phrases for an attribute are unique, and for that, they just
> need to grep, not parse the string.
> Most CLI users will only care about two things: yes/no and forward-only.

When processing data using formats like XML or JSON by software, there is no "grep".
Machine-readable means (not only but including) that no additional parsing needs to be done. The XML schema must indicate the possible values and I don't believe that a pipe-delimited multi-string value can be described with an XML schema.

Best,
sw



_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [FFmpeg-devel] [PATCH 2/2] ffprobe: show seekability details in format section
  2025-04-14  4:52       ` softworkz .
@ 2025-04-14  4:57         ` softworkz .
  2025-04-14  6:53         ` Gyan Doshi
  1 sibling, 0 replies; 15+ messages in thread
From: softworkz . @ 2025-04-14  4:57 UTC (permalink / raw)
  To: FFmpeg development discussions and patches



> -----Original Message-----
> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of
> softworkz .
> Sent: Montag, 14. April 2025 06:52
> To: FFmpeg development discussions and patches <ffmpeg-
> devel@ffmpeg.org>
> Subject: Re: [FFmpeg-devel] [PATCH 2/2] ffprobe: show seekability
> details in format section
> 
> 
> 
> > -----Original Message-----
> > From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of
> Gyan
> > Doshi
> > Sent: Montag, 14. April 2025 06:40
> > To: ffmpeg-devel@ffmpeg.org
> > Subject: Re: [FFmpeg-devel] [PATCH 2/2] ffprobe: show seekability
> > details in format section
> >
> >
> >
> > On 2025-04-13 09:48 pm, softworkz . wrote:
> > >
> > >> -----Original Message-----
> > >> From: ffmpeg-devel<ffmpeg-devel-bounces@ffmpeg.org>  On Behalf Of
> > Gyan
> > >> Doshi
> > >> Sent: Sonntag, 13. April 2025 13:16
> > >> To:ffmpeg-devel@ffmpeg.org
> > >> Subject: [FFmpeg-devel] [PATCH 2/2] ffprobe: show seekability
> details
> > in
> > >> format section
> > >>
> > >> ---
> > >>   fftools/ffprobe.c                    | 49
> > +++++++++++++++++++++++++++-
> > >>   tests/ref/fate/cavs-demux            |  2 +-
> > >>   tests/ref/fate/ffprobe_compact       |  2 +-
> > >>   tests/ref/fate/ffprobe_csv           |  2 +-
> > >>   tests/ref/fate/ffprobe_default       |  1 +
> > >>   tests/ref/fate/ffprobe_flat          |  1 +
> > >>   tests/ref/fate/ffprobe_ini           |  1 +
> > >>   tests/ref/fate/ffprobe_json          |  1 +
> > >>   tests/ref/fate/ffprobe_xml           |  2 +-
> > >>   tests/ref/fate/ffprobe_xsd           |  2 +-
> > >>   tests/ref/fate/flv-demux             |  2 +-
> > >>   tests/ref/fate/gapless-mp3-side-data |  2 +-
> > >>   tests/ref/fate/oggopus-demux         |  2 +-
> > >>   tests/ref/fate/ts-demux              |  2 +-
> > >>   tests/ref/fate/ts-opus-demux         |  2 +-
> > >>   tests/ref/fate/ts-small-demux        |  2 +-
> > >>   tests/ref/fate/ts-timed-id3-demux    |  2 +-
> > >>   17 files changed, 64 insertions(+), 13 deletions(-)
> > >>
> > >> diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c
> > >> index e0a7322523..8b09afb8c1 100644
> > >> --- a/fftools/ffprobe.c
> > >> +++ b/fftools/ffprobe.c
> > >> @@ -2260,7 +2260,7 @@ static int show_format(AVTextFormatContext
> > *tfc,
> > >> InputFile *ifile)
> > >>   {
> > >>       AVFormatContext *fmt_ctx = ifile->fmt_ctx;
> > >>       int64_t size = fmt_ctx->pb ? avio_size(fmt_ctx->pb) : -1;
> > >> -    int ret = 0;
> > >> +    int seekable, ret = 0;
> > >>
> > >>       avtext_print_section_header(tfc, NULL, SECTION_ID_FORMAT);
> > >>       print_str_validate("filename", fmt_ctx->url);
> > >> @@ -2279,6 +2279,53 @@ static int show_format(AVTextFormatContext
> > *tfc,
> > >> InputFile *ifile)
> > >>       if (fmt_ctx->bit_rate > 0) print_val    ("bit_rate",
> fmt_ctx-
> > >>> bit_rate, unit_bit_per_second_str);
> > >>       else                       print_str_opt("bit_rate",
> "N/A");
> > >>       print_int("probe_score", fmt_ctx->probe_score);
> > >> +
> > >> +    seekable = avformat_query_seekable(fmt_ctx);
> > >> +    if (seekable > 0) {
> > >> +        int gen = 1, ante = 0;
> > >> +        AVBPrint seek_str;
> > >> +        av_bprint_init(&seek_str, 0, AV_BPRINT_SIZE_AUTOMATIC);
> > >> +
> > >> +        av_bprintf(&seek_str, "yes, by");
> > >> +        if (seekable & AVSEEKABLE_TIME) {
> > >> +            av_bprintf(&seek_str, " time");
> > >> +            if (seekable & AVSEEKABLE_PTS)
> > >> +                av_bprintf(&seek_str, "(pts)");
> > >> +            else
> > >> +                av_bprintf(&seek_str, "(dts)");
> > >> +            ante = 1;
> > >> +        }
> > >> +        if (seekable & AVSEEKABLE_BYTE) {
> > >> +            av_bprintf(&seek_str, "%cbyte-offset", ante ? ',':'
> ');
> > >> +            ante = 1;
> > >> +        }
> > >> +        if (seekable & AVSEEKABLE_FRAME) {
> > >> +            av_bprintf(&seek_str, "%cframe-index", ante ? ',':'
> ');
> > >> +        }
> > >> +
> > >> +        ante = 0;
> > >> +        av_bprintf(&seek_str, " via");
> > >> +        if (seekable & AVSEEKABLE_DEMUXER) {
> > >> +            av_bprintf(&seek_str, " demuxer");
> > >> +            gen = 0;
> > >> +            ante = 1;
> > >> +        }
> > >> +        if (seekable & AVSEEKABLE_PKTSCAN) {
> > >> +            av_bprintf(&seek_str, "%cpacket-scan", ante ? ',':'
> ');
> > >> +            gen = 0;
> > >> +            ante = 0;
> > >> +        }
> > >> +        if (gen)
> > >> +            av_bprintf(&seek_str, " generic seek");
> > >> +
> > >> +        if (seekable & AVSEEKABLE_FWDONLY)
> > >> +            av_bprintf(&seek_str, " (forward only)");
> > >> +
> > >> +        print_str("seekable",      seek_str.str);
> > >> +    }
> > >> +    else
> > >> +        print_str("seekable",      "no");
> > >> +
> > >>       if (do_show_format_tags)
> > >>           ret = show_tags(tfc, fmt_ctx->metadata,
> > >> SECTION_ID_FORMAT_TAGS);
> > >
> > > Hi Gyan,
> > >
> > > the problem that I see here is that it's not machine-readable and
> > would require non-trivial parsing to translate back to the actual
> > information behind it.
> > > I think that either a separate sub-section or at least three
> separate
> > values would be better.
> >
> > I can add a delimiter like |
> >
> > e.g.
> >
> > yes|time(pts),frame-index|demuxer,packet-scan|fast
> >
> > All of the phrases for an attribute are unique, and for that, they
> just
> > need to grep, not parse the string.
> > Most CLI users will only care about two things: yes/no and forward-
> only.
> 
> When processing data using formats like XML or JSON by software, there
> is no "grep".
> Machine-readable means (not only but including) that no additional
> parsing needs to be done. The XML schema must indicate the possible
> values and I don't believe that a pipe-delimited multi-string value
> can be described with an XML schema.

The string that you are constructing would be perfect though for the 
log output though which FFmpeg is printing as well on startup - not 
sure whether you want to print it there as well?

sw

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [FFmpeg-devel] [PATCH 2/2] ffprobe: show seekability details in format section
  2025-04-14  4:52       ` softworkz .
  2025-04-14  4:57         ` softworkz .
@ 2025-04-14  6:53         ` Gyan Doshi
  2025-04-14  7:27           ` softworkz .
  1 sibling, 1 reply; 15+ messages in thread
From: Gyan Doshi @ 2025-04-14  6:53 UTC (permalink / raw)
  To: ffmpeg-devel



On 2025-04-14 10:22 am, softworkz . wrote:
>>> Hi Gyan,
>>>
>>> the problem that I see here is that it's not machine-readable and
>> would require non-trivial parsing to translate back to the actual
>> information behind it.
>>> I think that either a separate sub-section or at least three separate
>> values would be better.
>>
>> I can add a delimiter like |
>>
>> e.g.
>>
>> yes|time(pts),frame-index|demuxer,packet-scan|fast
>>
>> All of the phrases for an attribute are unique, and for that, they just
>> need to grep, not parse the string.
>> Most CLI users will only care about two things: yes/no and forward-only.
> When processing data using formats like XML or JSON by software, there is no "grep".
> Machine-readable means (not only but including) that no additional parsing needs to be done. The XML schema must indicate the possible values and I don't believe that a pipe-delimited multi-string value can be described with an XML schema.

That would require one field for each bit i.e.

seekable_normal=yes
seekable_protocol=no
seekable_via_demuxer=yes
...

That seems like too much bloat for CLI usage.
Any workflow that needs to *take action* based on the seek features, as 
opposed to data archival, should have access to string parsing tools.

How about two fields:

seekability=no
seek-features=n/a

seekability=yes
seek-features=a,b,c|d,e,f|g,h,i

Regards,
Gyan
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [FFmpeg-devel] [PATCH 2/2] ffprobe: show seekability details in format section
  2025-04-14  6:53         ` Gyan Doshi
@ 2025-04-14  7:27           ` softworkz .
  2025-04-14 10:36             ` Gyan Doshi
  0 siblings, 1 reply; 15+ messages in thread
From: softworkz . @ 2025-04-14  7:27 UTC (permalink / raw)
  To: FFmpeg development discussions and patches



> -----Original Message-----
> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of Gyan
> Doshi
> Sent: Montag, 14. April 2025 08:54
> To: ffmpeg-devel@ffmpeg.org
> Subject: Re: [FFmpeg-devel] [PATCH 2/2] ffprobe: show seekability
> details in format section
> 
> 
> 
> On 2025-04-14 10:22 am, softworkz . wrote:
> >>> Hi Gyan,
> >>>
> >>> the problem that I see here is that it's not machine-readable and
> >> would require non-trivial parsing to translate back to the actual
> >> information behind it.
> >>> I think that either a separate sub-section or at least three
> separate
> >> values would be better.
> >>
> >> I can add a delimiter like |
> >>
> >> e.g.
> >>
> >> yes|time(pts),frame-index|demuxer,packet-scan|fast
> >>
> >> All of the phrases for an attribute are unique, and for that, they
> just
> >> need to grep, not parse the string.
> >> Most CLI users will only care about two things: yes/no and forward-
> only.
> > When processing data using formats like XML or JSON by software,
> there is no "grep".
> > Machine-readable means (not only but including) that no additional
> parsing needs to be done. The XML schema must indicate the possible
> values and I don't believe that a pipe-delimited multi-string value
> can be described with an XML schema.
> 
> That would require one field for each bit i.e.
> 
> seekable_normal=yes
> seekable_protocol=no
> seekable_via_demuxer=yes
> ...
> 
> That seems like too much bloat for CLI usage.
> Any workflow that needs to *take action* based on the seek features,
> as
> opposed to data archival, should have access to string parsing tools.

Start thinking from the other side: You want to define a class (be it Python, C#, Java, TypeScript or whatever) which corresponds to the FFprobe format output in a way that you can work with it efficiently in that application and then you serialize that class - that's how the output should be.


For the representation of bitfields in the output, there are multiple ways. 
One way is like it's done for disposition:

JSON:

            "disposition": {
                "default": 0,
                "dub": 0,
                "original": 0,
                "comment": 0,
                "lyrics": 0,
                "karaoke": 0,
                "forced": 0,
                "hearing_impaired": 0,
                "visual_impaired": 0,
                "clean_effects": 0,
                "attached_pic": 0,
                "timed_thumbnails": 0,
                "non_diegetic": 0,
                "captions": 0,
                "descriptions": 0,
                "metadata": 0,
                "dependent": 0,
                "still_image": 0,
                "multilayer": 0
            },

another way would be a list of predefined (enum) values:

which would look as follows in JSON:

"disposition": ["original", "dub"],


In an xml schema, the latter can be defined like this:

<xs:element name="Flags">
  <xs:complexType>
    <xs:sequence maxOccurs="unbounded">
      <xs:element name="disposition">
        <xs:simpleType>
          <xs:restriction base="xs:string">
            <xs:enumeration value="original"/>
            <xs:enumeration value="dub"/>
            <xs:enumeration value="lyrics"/>
            <!-- ... -->
          </xs:restriction>
        </xs:simpleType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>
</xs:element>


Then the XML would look like this:

<MyElement>
    <disposition>
        <dispositionvalue>original</dispositionvalue>
        <dispositionvalue>dub</dispositionvalue>
    </disposition>
</MyElement>


> That seems like too much bloat for CLI usage.

Whether it's "bloat" or not only depends on the output format.
In the default or flat format this might probably condense to a 

disposition: original,dub

output (not 100% sure, but it will be short in any case).


sw


_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [FFmpeg-devel] [PATCH 2/2] ffprobe: show seekability details in format section
  2025-04-14  4:39     ` Gyan Doshi
  2025-04-14  4:52       ` softworkz .
@ 2025-04-14  8:34       ` Nicolas George
  1 sibling, 0 replies; 15+ messages in thread
From: Nicolas George @ 2025-04-14  8:34 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

Gyan Doshi (HE12025-04-14):
> yes|time(pts),frame-index|demuxer,packet-scan|fast

Do not use delimiters that are active characters in regexps.

Regards,

-- 
  Nicolas George
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [FFmpeg-devel] [PATCH 2/2] ffprobe: show seekability details in format section
  2025-04-14  7:27           ` softworkz .
@ 2025-04-14 10:36             ` Gyan Doshi
  0 siblings, 0 replies; 15+ messages in thread
From: Gyan Doshi @ 2025-04-14 10:36 UTC (permalink / raw)
  To: ffmpeg-devel



On 2025-04-14 12:57 pm, softworkz . wrote:
>
>> -----Original Message-----
>> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of Gyan
>> Doshi
>> Sent: Montag, 14. April 2025 08:54
>> To: ffmpeg-devel@ffmpeg.org
>> Subject: Re: [FFmpeg-devel] [PATCH 2/2] ffprobe: show seekability
>> details in format section
>>
>>
>>
>> On 2025-04-14 10:22 am, softworkz . wrote:
>>>>> Hi Gyan,
>>>>>
>>>>> the problem that I see here is that it's not machine-readable and
>>>> would require non-trivial parsing to translate back to the actual
>>>> information behind it.
>>>>> I think that either a separate sub-section or at least three
>> separate
>>>> values would be better.
>>>>
>>>> I can add a delimiter like |
>>>>
>>>> e.g.
>>>>
>>>> yes|time(pts),frame-index|demuxer,packet-scan|fast
>>>>
>>>> All of the phrases for an attribute are unique, and for that, they
>> just
>>>> need to grep, not parse the string.
>>>> Most CLI users will only care about two things: yes/no and forward-
>> only.
>>> When processing data using formats like XML or JSON by software,
>> there is no "grep".
>>> Machine-readable means (not only but including) that no additional
>> parsing needs to be done. The XML schema must indicate the possible
>> values and I don't believe that a pipe-delimited multi-string value
>> can be described with an XML schema.
>>
>> That would require one field for each bit i.e.
>>
>> seekable_normal=yes
>> seekable_protocol=no
>> seekable_via_demuxer=yes
>> ...
>>
>> That seems like too much bloat for CLI usage.
>> Any workflow that needs to *take action* based on the seek features,
>> as
>> opposed to data archival, should have access to string parsing tools.
> Start thinking from the other side: You want to define a class (be it Python, C#, Java, TypeScript or whatever) which corresponds to the FFprobe format output in a way that you can work with it efficiently in that application and then you serialize that class - that's how the output should be.
>
>
> For the representation of bitfields in the output, there are multiple ways.
> One way is like it's done for disposition:
>
> JSON:
>
>              "disposition": {
>                  "default": 0,
>                  "dub": 0,
>                  "original": 0,
>                  "comment": 0,
>                  "lyrics": 0,
>                  "karaoke": 0,
>                  "forced": 0,
>                  "hearing_impaired": 0,
>                  "visual_impaired": 0,
>                  "clean_effects": 0,
>                  "attached_pic": 0,
>                  "timed_thumbnails": 0,
>                  "non_diegetic": 0,
>                  "captions": 0,
>                  "descriptions": 0,
>                  "metadata": 0,
>                  "dependent": 0,
>                  "still_image": 0,
>                  "multilayer": 0
>              },
>
> another way would be a list of predefined (enum) values:
>
> which would look as follows in JSON:
>
> "disposition": ["original", "dub"],
>
>
> In an xml schema, the latter can be defined like this:
>
> <xs:element name="Flags">
>    <xs:complexType>
>      <xs:sequence maxOccurs="unbounded">
>        <xs:element name="disposition">
>          <xs:simpleType>
>            <xs:restriction base="xs:string">
>              <xs:enumeration value="original"/>
>              <xs:enumeration value="dub"/>
>              <xs:enumeration value="lyrics"/>
>              <!-- ... -->
>            </xs:restriction>
>          </xs:simpleType>
>        </xs:element>
>      </xs:sequence>
>    </xs:complexType>
> </xs:element>
>
>
> Then the XML would look like this:
>
> <MyElement>
>      <disposition>
>          <dispositionvalue>original</dispositionvalue>
>          <dispositionvalue>dub</dispositionvalue>
>      </disposition>
> </MyElement>
>
>
>> That seems like too much bloat for CLI usage.
> Whether it's "bloat" or not only depends on the output format.
> In the default or flat format this might probably condense to a

Bloat in terms of number of fields, not necessarily size of textual 
representation.

I'll think I'll only report seekability and its directionality for now. 
The other data is academic for now.
When I extend the seek options in ffmpeg is when I'll extend the reporting.

Regards,
Gyan

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2025-04-14 10:37 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-04-13 11:15 [FFmpeg-devel] [PATCH 1/2] avformat: add avformat_query_seekable Gyan Doshi
2025-04-13 11:15 ` [FFmpeg-devel] [PATCH 2/2] ffprobe: show seekability details in format section Gyan Doshi
2025-04-13 16:18   ` softworkz .
2025-04-14  4:39     ` Gyan Doshi
2025-04-14  4:52       ` softworkz .
2025-04-14  4:57         ` softworkz .
2025-04-14  6:53         ` Gyan Doshi
2025-04-14  7:27           ` softworkz .
2025-04-14 10:36             ` Gyan Doshi
2025-04-14  8:34       ` Nicolas George
2025-04-13 16:09 ` [FFmpeg-devel] [PATCH 1/2] avformat: add avformat_query_seekable softworkz .
2025-04-14  4:23   ` Gyan Doshi
2025-04-14  4:40     ` softworkz .
2025-04-13 16:42 ` Zhao Zhili
2025-04-14  4:10   ` Gyan Doshi

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git