[FFmpeg-cvslog] avformat: introduce AVFormatContext io_close2 which returns an int

Marton Balint git at videolan.org
Sun Dec 12 01:39:56 EET 2021


ffmpeg | branch: master | Marton Balint <cus at passwd.hu> | Tue Nov 30 00:38:30 2021 +0100| [64834bb86a133400970d203656a30ae6a3d2832f] | committer: Marton Balint

avformat: introduce AVFormatContext io_close2 which returns an int

Otherwise there is no way to detect an error returned by avio_close() because
ff_format_io_close cannot get the return value.

Checking the return value of the close function is important in order to check
if all data was successfully written and the underlying close() operation was
successful.

It can also be useful even for read mode because it can return any pending
AVIOContext error, so the user don't have to manually check AVIOContext->error.

In order to still support if the user overrides io_close, the generic code only
uses io_close2 if io_close is either NULL or the default io_close callback.

Signed-off-by: Marton Balint <cus at passwd.hu>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=64834bb86a133400970d203656a30ae6a3d2832f
---

 doc/APIchanges         |  3 +++
 libavformat/avformat.h | 13 +++++++++++++
 libavformat/dashenc.c  |  1 +
 libavformat/fifo.c     |  1 +
 libavformat/hlsenc.c   |  1 +
 libavformat/internal.h | 10 +++++++++-
 libavformat/options.c  |  7 ++++---
 libavformat/segment.c  |  1 +
 libavformat/tee.c      |  1 +
 libavformat/utils.c    | 17 ++++++++++++++---
 libavformat/version.h  |  4 ++--
 11 files changed, 50 insertions(+), 9 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index 2d41d67818..17aa664ca3 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -14,6 +14,9 @@ libavutil:     2021-04-27
 
 API changes, most recent first:
 
+2021-12-xx - xxxxxxxxxx - lavf 59.10.100 - avformat.h
+  Add AVFormatContext io_close2 which returns an int
+
 2021-11-10 - xxxxxxxxxx - lavu 57.11.100 - hwcontext_vulkan.h
   Add AVVkFrame.offset and AVVulkanFramesContext.flags.
 
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 75699f3a32..70b36d7682 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1786,6 +1786,19 @@ typedef struct AVFormatContext {
      * - decoding: set by user
      */
     int max_probe_packets;
+
+    /**
+     * A callback for closing the streams opened with AVFormatContext.io_open().
+     *
+     * Using this is preferred over io_close, because this can return an error.
+     * Therefore this callback is used instead of io_close by the generic
+     * libavformat code if io_close is NULL or the default.
+     *
+     * @param s the format context
+     * @param pb IO context to be closed and freed
+     * @return 0 on success, a negative AVERROR code on failure
+     */
+    int (*io_close2)(struct AVFormatContext *s, AVIOContext *pb);
 } AVFormatContext;
 
 /**
diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 3f28f5ad71..4709bc6615 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -1546,6 +1546,7 @@ static int dash_init(AVFormatContext *s)
         ctx->interrupt_callback    = s->interrupt_callback;
         ctx->opaque                = s->opaque;
         ctx->io_close              = s->io_close;
+        ctx->io_close2             = s->io_close2;
         ctx->io_open               = s->io_open;
         ctx->strict_std_compliance = s->strict_std_compliance;
 
diff --git a/libavformat/fifo.c b/libavformat/fifo.c
index 2ee6dde830..86e5d369b5 100644
--- a/libavformat/fifo.c
+++ b/libavformat/fifo.c
@@ -499,6 +499,7 @@ static int fifo_mux_init(AVFormatContext *avf, const AVOutputFormat *oformat,
         return ret;
     avf2->opaque = avf->opaque;
     avf2->io_close = avf->io_close;
+    avf2->io_close2 = avf->io_close2;
     avf2->io_open = avf->io_open;
     avf2->flags = avf->flags;
 
diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 1c2a556375..4d48709bed 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -866,6 +866,7 @@ static int hls_mux_init(AVFormatContext *s, VariantStream *vs)
     oc->opaque                   = s->opaque;
     oc->io_open                  = s->io_open;
     oc->io_close                 = s->io_close;
+    oc->io_close2                = s->io_close2;
     oc->strict_std_compliance    = s->strict_std_compliance;
     av_dict_copy(&oc->metadata, s->metadata, 0);
 
diff --git a/libavformat/internal.h b/libavformat/internal.h
index 878c4f1164..eb8239cd3f 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -916,8 +916,16 @@ int ff_format_output_open(AVFormatContext *s, const char *url, AVDictionary **op
 /*
  * A wrapper around AVFormatContext.io_close that should be used
  * instead of calling the pointer directly.
+ *
+ * @param s AVFormatContext
+ * @param *pb the AVIOContext to be closed and freed. Can be NULL.
+ * @return >=0 on success, negative AVERROR in case of failure
  */
-void ff_format_io_close(AVFormatContext *s, AVIOContext **pb);
+int ff_format_io_close(AVFormatContext *s, AVIOContext **pb);
+
+/* Default io_close callback, not to be used directly, use ff_format_io_close
+ * instead. */
+void ff_format_io_close_default(AVFormatContext *s, AVIOContext *pb);
 
 /**
  * Utility function to check if the file uses http or https protocol
diff --git a/libavformat/options.c b/libavformat/options.c
index 72c9bdcefe..1634388acb 100644
--- a/libavformat/options.c
+++ b/libavformat/options.c
@@ -146,9 +146,9 @@ static int io_open_default(AVFormatContext *s, AVIOContext **pb,
     return ffio_open_whitelist(pb, url, flags, &s->interrupt_callback, options, s->protocol_whitelist, s->protocol_blacklist);
 }
 
-static void io_close_default(AVFormatContext *s, AVIOContext *pb)
+static int io_close2_default(AVFormatContext *s, AVIOContext *pb)
 {
-    avio_close(pb);
+    return avio_close(pb);
 }
 
 AVFormatContext *avformat_alloc_context(void)
@@ -162,7 +162,8 @@ AVFormatContext *avformat_alloc_context(void)
     s = &si->pub;
     s->av_class = &av_format_context_class;
     s->io_open  = io_open_default;
-    s->io_close = io_close_default;
+    s->io_close = ff_format_io_close_default;
+    s->io_close2= io_close2_default;
 
     av_opt_set_defaults(s);
 
diff --git a/libavformat/segment.c b/libavformat/segment.c
index d531286c31..e9b0aa4fa8 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -158,6 +158,7 @@ static int segment_mux_init(AVFormatContext *s)
     av_dict_copy(&oc->metadata, s->metadata, 0);
     oc->opaque             = s->opaque;
     oc->io_close           = s->io_close;
+    oc->io_close2          = s->io_close2;
     oc->io_open            = s->io_open;
     oc->flags              = s->flags;
 
diff --git a/libavformat/tee.c b/libavformat/tee.c
index dfdf70cb08..b3bcd70b9f 100644
--- a/libavformat/tee.c
+++ b/libavformat/tee.c
@@ -237,6 +237,7 @@ static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave)
     avf2->opaque   = avf->opaque;
     avf2->io_open  = avf->io_open;
     avf2->io_close = avf->io_close;
+    avf2->io_close2 = avf->io_close2;
     avf2->interrupt_callback = avf->interrupt_callback;
     avf2->flags = avf->flags;
     avf2->strict_std_compliance = avf->strict_std_compliance;
diff --git a/libavformat/utils.c b/libavformat/utils.c
index c368b60864..b5a4a09ae8 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -1831,11 +1831,22 @@ int ff_format_output_open(AVFormatContext *s, const char *url, AVDictionary **op
     return 0;
 }
 
-void ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
+void ff_format_io_close_default(AVFormatContext *s, AVIOContext *pb)
 {
-    if (*pb)
-        s->io_close(s, *pb);
+    avio_close(pb);
+}
+
+int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
+{
+    int ret = 0;
+    if (*pb) {
+        if (s->io_close == ff_format_io_close_default || s->io_close == NULL)
+            ret = s->io_close2(s, *pb);
+        else
+            s->io_close(s, *pb);
+    }
     *pb = NULL;
+    return ret;
 }
 
 int ff_is_http_proto(const char *filename) {
diff --git a/libavformat/version.h b/libavformat/version.h
index 0705ee4112..1623835a78 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -32,8 +32,8 @@
 // Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium)
 // Also please add any ticket numbers that you believe might be affected here
 #define LIBAVFORMAT_VERSION_MAJOR  59
-#define LIBAVFORMAT_VERSION_MINOR   9
-#define LIBAVFORMAT_VERSION_MICRO 102
+#define LIBAVFORMAT_VERSION_MINOR  10
+#define LIBAVFORMAT_VERSION_MICRO 100
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
                                                LIBAVFORMAT_VERSION_MINOR, \



More information about the ffmpeg-cvslog mailing list