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

Nicolas George george at nsup.org
Mon Dec 3 14:43:45 EET 2018


Andrey Semashev (2018-12-03):
> 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.
> ---
>  libavformat/avio.c    |  7 +++++++
>  libavformat/avio.h    | 16 ++++++++++++++++
>  libavformat/aviobuf.c | 17 +++++++++++++++++
>  libavformat/url.h     | 12 ++++++++++++
>  4 files changed, 52 insertions(+)
> 
> diff --git a/libavformat/avio.c b/libavformat/avio.c
> index 663789ec02..19413ac586 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 0;

I think it should be an error, probably ENOSUP. Otherwise, the
application will assume it was done.

The doc needs to be changed accordingly of course.

> +}
> +
>  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..784cd1b509 100644
> --- a/libavformat/avio.h
> +++ b/libavformat/avio.h
> @@ -349,6 +349,11 @@ 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.
> +     */
> +    int (*sync)(void *opaque);
>  } AVIOContext;
>  
>  /**
> @@ -586,6 +591,17 @@ 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, an 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..10be372bce 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 0;
> +}
> +
>  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..26658695b0 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 a negative value if an error condition occurred, 0
> + * otherwise
> + */
> +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

Regards,

-- 
  Nicolas George
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20181203/9c073fdb/attachment.sig>


More information about the ffmpeg-devel mailing list