[FFmpeg-devel] [PATCH v2 4/5] avformat: introduce AVFormatContext io_close2 which returns an int

Marton Balint cus at passwd.hu
Sat Dec 4 21:59:16 EET 2021


Otherwise there is no way to detect any error during avio_close().

Signed-off-by: Marton Balint <cus at passwd.hu>
---
 doc/APIchanges         |  3 +++
 libavformat/avformat.h | 13 +++++++++++++
 libavformat/dashenc.c  |  1 +
 libavformat/fifo.c     |  1 +
 libavformat/hlsenc.c   |  1 +
 libavformat/internal.h |  6 +++++-
 libavformat/options.c  |  6 ++++++
 libavformat/segment.c  |  1 +
 libavformat/tee.c      |  1 +
 libavformat/utils.c    | 12 +++++++++---
 libavformat/version.h  |  4 ++--
 11 files changed, 43 insertions(+), 6 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index bc9f4e38da..140745df4d 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-22 - xxxxxxxxxx - lavu 57.9.100 - pixfmt.h
   Add AV_PIX_FMT_P210, AV_PIX_FMT_P410, AV_PIX_FMT_P216, and AV_PIX_FMT_P416.
 
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 75699f3a32..a3fc0dc49e 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 it is available.
+     *
+     * @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 cfd0c036d1..ae288e408d 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -867,6 +867,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 20e93d9267..4f28885f3c 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -905,8 +905,12 @@ 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);
 
 /**
  * Utility function to check if the file uses http or https protocol
diff --git a/libavformat/options.c b/libavformat/options.c
index 72c9bdcefe..05fdaedeb9 100644
--- a/libavformat/options.c
+++ b/libavformat/options.c
@@ -151,6 +151,11 @@ static void io_close_default(AVFormatContext *s, AVIOContext *pb)
     avio_close(pb);
 }
 
+static int io_close2_default(AVFormatContext *s, AVIOContext *pb)
+{
+    return avio_close(pb);
+}
+
 AVFormatContext *avformat_alloc_context(void)
 {
     FFFormatContext *const si = av_mallocz(sizeof(*si));
@@ -163,6 +168,7 @@ AVFormatContext *avformat_alloc_context(void)
     s->av_class = &av_format_context_class;
     s->io_open  = io_open_default;
     s->io_close = 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 9861462405..27c5c1b70f 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 7840e8717c..e5d6023224 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -1829,11 +1829,17 @@ int ff_format_output_open(AVFormatContext *s, const char *url, AVDictionary **op
     return 0;
 }
 
-void ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
+int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
 {
-    if (*pb)
-        s->io_close(s, *pb);
+    int ret = 0;
+    if (*pb) {
+        if (s->io_close2)
+            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, \
-- 
2.31.1



More information about the ffmpeg-devel mailing list