[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