[FFmpeg-devel] [PATCH v2 1/2] avformat: add avformat_query_seekable
Gyan Doshi
ffmpeg at gyani.pro
Wed Apr 16 15:25:03 EEST 2025
On 2025-04-16 10:37 am, Andreas Rheinhardt wrote:
> Gyan Doshi:
>> Utility function to report seekability features for a given input.
>>
>> Useful for ffprobe and to extend seek possibilities in fftools.
>> ---
>> v2:
>> made constants more descriptive
>> add exception for rtsp false negative seekability
>>
>> 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..f9da5e9e79 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_IO_NORMAL 0x00000001 ///< I/O is seekable like a local file
>> +#define AVSEEKABLE_IO_PROTOCOL 0x00000002 ///< I/O seek is through protocol request via avio_seek_time
>> +#define AVSEEKABLE_VIA_DEMUXER 0x00000004 ///< demuxer has a seek function
>> +#define AVSEEKABLE_VIA_PKTSCAN 0x00000008 ///< seek is performed by consuming and scanning packet timestamps
>> +#define AVSEEKABLE_BY_TIME 0x00000100 ///< seek target can be a timestamp
>> +#define AVSEEKABLE_BY_BYTE 0x00000200 ///< seek target can be in bytes
>> +#define AVSEEKABLE_BY_FRAME 0x00000400 ///< seek target can be a frame index
>> +#define AVSEEKABLE_PROP_PTS 0x00010000 ///< seek target timestamp is expected to be PTS
>> +#define AVSEEKABLE_PROP_FAST 0x00020000 ///< demuxer allows fast but inaccurate seeking
>> +#define AVSEEKABLE_PROP_FWDONLY 0x00040000 ///< 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..8be1bdec30 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 ( strcmp(s->iformat->name, "rtsp") && (!(s->pb && s->pb->seekable) || s->ctx_flags & AVFMTCTX_UNSEEKABLE) )
>> + return 0;
>> +
>> + if (s->pb->seekable & AVIO_SEEKABLE_NORMAL)
>> + ret |= AVSEEKABLE_IO_NORMAL;
>> +
>> + if (s->pb->seekable & AVIO_SEEKABLE_TIME)
>> + ret |= AVSEEKABLE_IO_PROTOCOL;
>> +
>> + if (ffifmt(s->iformat)->read_seek || ffifmt(s->iformat)->read_seek2)
>> + ret |= AVSEEKABLE_VIA_DEMUXER;
> The existence of these functions does not imply that a given input is
> seekable: E.g. some read_seek functions rely on an index being present
> in the file and are useless/not better than reading linearly in case the
> index is absent.
Seek performance is a secondary concern.
Basic seek support means that the client can reduce the number of
packets they have to deal with before they start receiving the desired
packets.
If the demuxer or framework needs to scan and discard packets
individually, that's still a seek being carried out.
Nonetheless, I've added a flag for 'slow' seeking and added that for
packet scanned seeking.
Fur fully qualified reporting, the flags in demuxers will need to be
updated. That's next on my todo after the basic functionality is present.
Regards,
Gyan
More information about the ffmpeg-devel
mailing list