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
signature.asc
Description: Digital signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel