Andrey Semashev (2018-12-04): > 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. > Users can distinguish this case from the successful completion by the result > code AVIO_SYNC_NOT_SUPPORTED, which is also considered a successful result > (i.e. >0). > --- > libavformat/avio.c | 7 +++++++ > libavformat/avio.h | 33 +++++++++++++++++++++++++++++++++ > libavformat/aviobuf.c | 17 +++++++++++++++++ > libavformat/url.h | 13 +++++++++++++ > 4 files changed, 70 insertions(+) > > diff --git a/libavformat/avio.c b/libavformat/avio.c > index 663789ec02..662d4ed971 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 AVIO_SYNC_NOT_SUPPORTED; > +} > + > 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..403ee0fc7b 100644 > --- a/libavformat/avio.h > +++ b/libavformat/avio.h > @@ -349,6 +349,15 @@ 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 AVIO_SYNC_SUCCESS on success, AVIO_SYNC_NOT_SUPPORTED if > + * the operation is not supported and ignored, an AVERROR < 0 > + * on error. > + */ > + int (*sync)(void *opaque); > } AVIOContext; > > /** > @@ -586,6 +595,30 @@ int avio_printf(AVIOContext *s, const char *fmt, ...) > av_printf_format(2, 3); > */ > void avio_flush(AVIOContext *s); >
> +/** > + * Indicates that the sync operation has been carried out successfully > + */ > +#define AVIO_SYNC_SUCCESS 0 > + > +/** > + * Indicates that the sync operation is not supported by the underlying > + * resource and has been ignored > + */ > +#define AVIO_SYNC_NOT_SUPPORTED 1 I must say, I really do not like this version at all. ENOTSUP feels like a much more consistent solution. > + > +/** > + * 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 AVIO_SYNC_SUCCESS on success, AVIO_SYNC_NOT_SUPPORTED if > + * the operation is a not supported and ignored, 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..c2aca7c6af 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 AVIO_SYNC_NOT_SUPPORTED; > +} > + > 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..d032b45b65 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,18 @@ 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 AVIO_SYNC_SUCCESS on success, AVIO_SYNC_NOT_SUPPORTED if > + * the operation is not supported and ignored, an 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 Regards, -- Nicolas George
signature.asc
Description: Digital signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel