From patchwork Tue Dec 4 11:44:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Semashev X-Patchwork-Id: 11271 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 518F044D613 for ; Tue, 4 Dec 2018 13:51:19 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id EC7EC68A56A; Tue, 4 Dec 2018 13:51:10 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lf1-f65.google.com (mail-lf1-f65.google.com [209.85.167.65]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 61FD8689A8E for ; Tue, 4 Dec 2018 13:51:04 +0200 (EET) Received: by mail-lf1-f65.google.com with SMTP id e26so11735962lfc.2 for ; Tue, 04 Dec 2018 03:51:12 -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=845q7gITJuc+/NCgpQd20ug6p9DGHK2cuy3A/XmVv9Q=; b=k3hvaCJdH4jtRDymA9Obza9I51DT9cizGvC4hIv904sIdFMlaRWq/80YXto9SXd8+9 +EdvmudBxjCXFxm22TxuFRPfwEn+gF7pO8Z1BLaR0TXSo0ROVHCtX0jYa1iNPiIQ7d7h 8iPnJqmHhvT0pN+p3cfkNiaDw+QWPdp4+ecsl5JQpYFilhY+h+MFUa1ETDu9tJ3HTMGe OoAPdkxCGdhIfIgRvWaYo/p0LLc2r2PP9BLCOAuObiHznKoNLi0nR4+WcTqU9j/2JjiZ GpniwV02D8/XZCEsq2JHgi5Hx58RPYqQc7iNhKPVaoxdQrEmYbBsldS1/v431tXHzDEq LuXQ== 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=845q7gITJuc+/NCgpQd20ug6p9DGHK2cuy3A/XmVv9Q=; b=uLxQpyvxANowhuSMkTIcbB3KqwDL1hfcTM37+venRg00l0XfhVwnNBYasNSkdsGAPM 7gUVwCSda5pgyqnPbrysNlBv+foLG9oMz+eaefd3j5mGyXkrCg+tMU9foZHniUJTr8JK 3kqUZtb9NF9A+ug+4F3tCRi2HCo5chAiPTgInLTqFFADSJaxp3/2bdx57GQlzBRgsYNK By3s0WOZB9dn0/QC0W3i+pSrL0HFezId+z1iknSd+5PWOYu/QYlNuzmBYNcbQK8Ntqop bDxNhKnd7gPI8u8N3Mcbvw5HUghzupo5v2ZUjP6BWtTUyVVe0gSf32kfKyNnS5cjoj2s XyyQ== X-Gm-Message-State: AA+aEWZTFSIEpTXTqYjAxqbdwNpidIuz31z8QdXWY5SJXTWegCBk3D1U TZkXx7DrgSSVSDirPdTjwk8MFFqaLik= X-Google-Smtp-Source: AFSGD/UVBn3j1bMbrZtNQlMUXWUtUpawpVx1dDeYqQvqapn8q6pp7yB6D9k3XTeBnp+qBPfx/RGXNw== X-Received: by 2002:a19:c801:: with SMTP id y1mr11157704lff.53.1543923851610; Tue, 04 Dec 2018 03:44:11 -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 f8sm2953009lfb.2.2018.12.04.03.44.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 04 Dec 2018 03:44:10 -0800 (PST) From: Andrey Semashev To: ffmpeg-devel@ffmpeg.org Date: Tue, 4 Dec 2018 14:44:05 +0300 Message-Id: <20181204114406.25933-1-andrey.semashev@gmail.com> X-Mailer: git-send-email 2.19.1 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 1/2] lavf: Add general API for IO buffer synchronization. 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. 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 + +/** + * 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