[FFmpeg-devel] [PATCH v3 1/2] lavf: Add general API for IO buffer synchronization.

Andrey Semashev andrey.semashev at gmail.com
Sat Dec 15 08:24:18 EET 2018


Ping?

On December 10, 2018 3:05:54 PM Andrey Semashev <andrey.semashev at gmail.com> 
wrote:

> This commit adds a new set of functions to avio and url subsystems, which
> allow users to invoke IO buffer synchronization with the underlying media.
> The most obvious target for this extension if the filesystem streams. Invoking
> IO synchronization allows user applications to ensure that all written content
> has reached the filesystem on the media and can be observed by other processes.
>
> The public API for this is avio_sync() function, which can be called on
> AVIOContext. The internal, lower layer API is ffurl_sync(), which works
> directly on the underlying URLContext. URLContext backends can add support for
> this new API by setting the sync handler to the new url_sync member of
> URLProtocol. When no handler is set then the sync operation is a no-op,
> the result code is AVERROR(ENOSYS).
> ---
> libavformat/avio.c    |  7 +++++++
> libavformat/avio.h    | 20 ++++++++++++++++++++
> libavformat/aviobuf.c | 17 +++++++++++++++++
> libavformat/url.h     | 12 ++++++++++++
> 4 files changed, 56 insertions(+)
>
> diff --git a/libavformat/avio.c b/libavformat/avio.c
> index 663789ec02..5754a7c20d 100644
> --- a/libavformat/avio.c
> +++ b/libavformat/avio.c
> @@ -623,6 +623,13 @@ int64_t ffurl_size(URLContext *h)
>     return size;
> }
>
> +int ffurl_sync(URLContext *h)
> +{
> +    if (h->prot->url_sync)
> +        return h->prot->url_sync(h);
> +    return AVERROR(ENOSYS);
> +}
> +
> int ffurl_get_file_handle(URLContext *h)
> {
>     if (!h || !h->prot || !h->prot->url_get_file_handle)
> diff --git a/libavformat/avio.h b/libavformat/avio.h
> index 75912ce6be..9e2ef14e60 100644
> --- a/libavformat/avio.h
> +++ b/libavformat/avio.h
> @@ -349,6 +349,14 @@ typedef struct AVIOContext {
>      * Try to buffer at least this amount of data before flushing it
>      */
>     int min_packet_size;
> +
> +    /**
> +     * A callback for synchronizing buffers with the media state.
> +     *
> +     * @return 0 on success, AVERROR(ENOSYS) if the operation is not supported
> +     *         and ignored, or other AVERROR < 0 on error.
> +     */
> +    int (*sync)(void *opaque);
> } AVIOContext;
>
> /**
> @@ -586,6 +594,18 @@ int avio_printf(AVIOContext *s, const char *fmt, ...) 
> av_printf_format(2, 3);
>  */
> void avio_flush(AVIOContext *s);
>
> +/**
> + * Flush internal buffers and ensure the synchronized state of the
> + * resource associated with the context s. This call may be expensive.
> + * Not all resources support syncing, this operation is a no-op
> + * if sync is not supported or needed.
> + * This function can only be used if s was opened by avio_open().
> + *
> + * @return 0 on success, AVERROR(ENOSYS) if the operation is not supported
> + *         and ignored, or other AVERROR < 0 on error.
> + */
> +int avio_sync(AVIOContext *s);
> +
> /**
>  * Read size bytes from AVIOContext into buf.
>  * @return number of bytes read or AVERROR
> diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
> index 5a33f82950..c1c9334719 100644
> --- a/libavformat/aviobuf.c
> +++ b/libavformat/aviobuf.c
> @@ -243,6 +243,14 @@ void avio_flush(AVIOContext *s)
>         avio_seek(s, seekback, SEEK_CUR);
> }
>
> +int avio_sync(AVIOContext *s)
> +{
> +    avio_flush(s);
> +    if (s->sync)
> +        return s->sync(s->opaque);
> +    return AVERROR(ENOSYS);
> +}
> +
> int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
> {
>     int64_t offset1;
> @@ -978,6 +986,12 @@ static int64_t io_read_seek(void *opaque, int 
> stream_index, int64_t timestamp, i
>     return internal->h->prot->url_read_seek(internal->h, stream_index, 
>     timestamp, flags);
> }
>
> +static int io_sync(void *opaque)
> +{
> +    AVIOInternal *internal = opaque;
> +    return ffurl_sync(internal->h);
> +}
> +
> int ffio_fdopen(AVIOContext **s, URLContext *h)
> {
>     AVIOInternal *internal = NULL;
> @@ -1026,6 +1040,9 @@ int ffio_fdopen(AVIOContext **s, URLContext *h)
>
>         if (h->prot->url_read_seek)
>             (*s)->seekable |= AVIO_SEEKABLE_TIME;
> +
> +        if (h->prot->url_sync)
> +            (*s)->sync = io_sync;
>     }
>     (*s)->short_seek_get = io_short_seek;
>     (*s)->av_class = &ff_avio_class;
> diff --git a/libavformat/url.h b/libavformat/url.h
> index 4750bfff82..5b8cd22e5a 100644
> --- a/libavformat/url.h
> +++ b/libavformat/url.h
> @@ -97,6 +97,7 @@ typedef struct URLProtocol {
>     int (*url_delete)(URLContext *h);
>     int (*url_move)(URLContext *h_src, URLContext *h_dst);
>     const char *default_whitelist;
> +    int (*url_sync)(URLContext *h);
> } URLProtocol;
>
> /**
> @@ -228,6 +229,17 @@ int64_t ffurl_seek(URLContext *h, int64_t pos, int 
> whence);
> int ffurl_closep(URLContext **h);
> int ffurl_close(URLContext *h);
>
> +/**
> + * Flush any buffered data and synchronize the resource accessed
> + * by the URLContext h. This call may be expensive.
> + * Not all types of resources support syncing, the call is a no-op
> + * if sync is not supported or needed.
> + *
> + * @return 0 on success, AVERROR(ENOSYS) if the operation is not supported
> + *         and ignored, or other AVERROR < 0 on error.
> + */
> +int ffurl_sync(URLContext *h);
> +
> /**
>  * Return the filesize of the resource accessed by h, AVERROR(ENOSYS)
>  * if the operation is not supported by h, or another negative value
> --
> 2.19.1






More information about the ffmpeg-devel mailing list