Message ID | 20181210120549.17179-1-andrey.semashev@gmail.com |
---|---|
State | New |
Headers | show |
Ping? On December 10, 2018 3:05:54 PM Andrey Semashev <andrey.semashev@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
Andrey Semashev (2018-12-10): > 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(+) I have no more objections to the patch as it is, thanks. But I have no opinion in favor of it either; it is useful in principle, but I do not know if it is worth the extra maintenance for a use case like this project. I will leave the judgement to others. Regards,
On Thu, Dec 20, 2018 at 11:00:32AM +0100, Nicolas George wrote: > Andrey Semashev (2018-12-10): > > 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(+) > > I have no more objections to the patch as it is, thanks. But I have no > opinion in favor of it either; it is useful in principle, but I do not > know if it is worth the extra maintenance for a use case like this > project. I will leave the judgement to others. IMHO, it looks useful and extra maintaince needed seems not major thx [...]
On 12/21/18 2:48 AM, Michael Niedermayer wrote: > On Thu, Dec 20, 2018 at 11:00:32AM +0100, Nicolas George wrote: >> Andrey Semashev (2018-12-10): >>> 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(+) >> >> I have no more objections to the patch as it is, thanks. But I have no >> opinion in favor of it either; it is useful in principle, but I do not >> know if it is worth the extra maintenance for a use case like this >> project. I will leave the judgement to others. > > IMHO, it looks useful and extra maintaince needed seems not major So, will this patchset be merged then?
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