[FFmpeg-devel] [PATCH 1/2] avformat/avformat: Introduced `AVInputFormat.read_timestamp2` to fix keyframe seeking for formats that rely on `read_timestamp` for seeking

James Almer jamrial at gmail.com
Mon Sep 2 23:07:05 EEST 2019


On 8/31/2019 7:10 AM, fumoboy007 at me.com wrote:
> From: fumoboy007 <fumoboy007 at me.com>
> 
> If the user omits `AVSEEK_FLAG_ANY`, then the result of the seek should be a keyframe. `ff_gen_search` did not respect that contract because it had no good way to determine whether a timestamp returned by `read_timestamp` was for a keyframe packet.
> 
> Therefore, we introduce `read_timestamp2`, which adds a new parameter named `prefer_keyframe`. This new parameter tells the input format whether to skip non-keyframe packets. The parameter is named `prefer_keyframe` instead of something like `keyframe_only` because some formats do not distinguish between keyframe and non-keyframe packets.
> 
> This commit adds the new function and deprecates the old function. Subsequent commits will migrate input formats to the new function.
> 
> Signed-off-by: fumoboy007 <fumoboy007 at me.com>
> ---
>  libavformat/avformat.h |  9 +++++++
>  libavformat/internal.h |  6 +++--
>  libavformat/nutdec.c   |  6 ++---
>  libavformat/utils.c    | 56 +++++++++++++++++++++++++++++++++---------
>  4 files changed, 60 insertions(+), 17 deletions(-)
> 
> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
> index 6eb329f13f..1db548663c 100644
> --- a/libavformat/avformat.h
> +++ b/libavformat/avformat.h
> @@ -741,6 +741,7 @@ typedef struct AVInputFormat {
>       * Get the next timestamp in stream[stream_index].time_base units.
>       * @return the timestamp or AV_NOPTS_VALUE if an error occurred
>       */
> +    attribute_deprecated
>      int64_t (*read_timestamp)(struct AVFormatContext *s, int stream_index,
>                                int64_t *pos, int64_t pos_limit);
>  
> @@ -781,6 +782,14 @@ typedef struct AVInputFormat {
>       * @see avdevice_capabilities_free() for more details.
>       */
>      int (*free_device_capabilities)(struct AVFormatContext *s, struct AVDeviceCapabilitiesQuery *caps);
> +
> +    /**
> +     * Get the next timestamp in stream[stream_index].time_base units.
> +     * @param prefer_keyframe Whether to skip over non-keyframe packets (if possible).
> +     * @return the timestamp or AV_NOPTS_VALUE if an error occurred
> +     */
> +    int64_t (*read_timestamp2)(struct AVFormatContext *s, int stream_index,
> +                               int64_t *pos, int64_t pos_limit, int prefer_keyframe);
>  } AVInputFormat;
>  /**
>   * @}
AVInputFormat.read_timestamp() is not a public field. There's no need to
deprecate it and add a replacement. Just change it as you see fit,
making sure to update all demuxers that may use it.


More information about the ffmpeg-devel mailing list