From patchwork Mon Dec 3 12:38:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Semashev X-Patchwork-Id: 11261 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 355D944DFDF for ; Mon, 3 Dec 2018 14:38:37 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id BE32C68A3A4; Mon, 3 Dec 2018 14:38:37 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lj1-f193.google.com (mail-lj1-f193.google.com [209.85.208.193]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 9F7ED68A375 for ; Mon, 3 Dec 2018 14:38:31 +0200 (EET) Received: by mail-lj1-f193.google.com with SMTP id u6-v6so11214455ljd.1 for ; Mon, 03 Dec 2018 04:38:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=f602XNU/VcmUIBH3s/3XkvdgucmrRGjrZhts4a78G/0=; b=dDzk+a173fXSPvR1zj1GTzm1TmXmnhP+Jtqp7BuFLzBhPFCNkOuC9hm1f8k9MbWNpB uKfmKvYCsll7eyUHv4ov5kPLl1O7UxfgsUYHbiHgBU8bj6h0sNOP9osxnOSZ3rE4e5Wy PARymMineu7DWIs7ANsxkOOOy54bfocZfqzs01dUNzFc7+yNijLDPqO9hyDT2ECXGMBt COkCK80hxi1b3QNFSwJmn4s/ju+S5WxMZMuvRS9borp9kJENnzW2dCWguZQUroyxWemo TqIOsy5RzImfM4vDnQAs9aCHO6MuHw2szGgIQDmwH56AOeyLjEl6FfrOqJKwYjfNQNp8 KewQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=f602XNU/VcmUIBH3s/3XkvdgucmrRGjrZhts4a78G/0=; b=GCn7c/c0Jv+BiRLTVZGp6vhBSNXa0PjIbhMkV5WglV6NAWMeWU7fJebGQxhLPHmf/d 0Ta0/kpN2v36DR+mUuNnpbZboP+sexOSNwwBcwRkmJCjRw8ZKTCXQ450cv79lIdv5aLI UaX7Bb+NaxvVto1jS1d+GB1nadHePIalZmDzzx6dA5lhq+54Yw6NMi+qIW+bcuANkTkX tFa0eE5xyx1zq3oCeHnnL5zdV6mshPygbrIGCn14jpBcrTJUzw+UnHFut1G5f8svcGSG zl2naWkh8XLwH/xR2m+VabnuJSipHF8o3rpmb/7yRdT9dzxXxpk3sINebWOuKrzSFfA+ 9CiQ== X-Gm-Message-State: AA+aEWa5imQnmk9f2Xqu6L8Fd3AINDp0EEahPHAEEl1IvPtmImLgABqE Z92rRvVMfSzRgsq1rLtBfzHZDMCKOn8= X-Google-Smtp-Source: AFSGD/Ukq1VthlehfYFNpm5KNtSMWvKr18J2sJIhenxwTjmMnJ6hh4sXsOAbjZf/oMA4ZijdxSgXJg== X-Received: by 2002:a2e:98c9:: with SMTP id s9-v6mr837099ljj.166.1543840718271; Mon, 03 Dec 2018 04:38:38 -0800 (PST) Received: from localhost.localdomain (broadband-37-110-31-10.ip.moscow.rt.ru. [37.110.31.10]) by smtp.gmail.com with ESMTPSA id h203sm2339434lfe.44.2018.12.03.04.38.36 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Dec 2018 04:38:37 -0800 (PST) From: Andrey Semashev To: ffmpeg-devel@ffmpeg.org Date: Mon, 3 Dec 2018 15:38:30 +0300 Message-Id: <20181203123831.7915-1-andrey.semashev@gmail.com> X-Mailer: git-send-email 2.19.1 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/2] lavf: Add general API for IO buffer synchtonization. X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Andrey Semashev Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" 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; +} + 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