---
 libavformat/avio.c |   53 +++++++++++++++++++++++++++++++++++-
 libavformat/avio.h |   76 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 126 insertions(+), 3 deletions(-)

diff --git a/libavformat/avio.c b/libavformat/avio.c
index ac15407..b336b74 100644
--- a/libavformat/avio.c
+++ b/libavformat/avio.c
@@ -395,7 +395,7 @@ int ffurl_get_file_handle(URLContext *h)
 
 static int default_interrupt_cb(void)
 {
-    return 0;
+    return avio_interrupt_check(NULL);
 }
 
 void avio_set_interrupt_cb(int (*interrupt_cb)(void))
@@ -421,3 +421,54 @@ int64_t av_url_read_seek(URLContext *h,
     return h->prot->url_read_seek(h, stream_index, timestamp, flags);
 }
 #endif
+
+int avio_interrupt_check_default(AVIOInterruptContext* ctx, URLContext* h)
+{
+  return ctx->should_interrupt || (h && h->should_interrupt);
+}
+
+void avio_interrupt_mark_default(AVIOInterruptContext* ctx, URLContext* h) 
+{
+    if(h) 
+        h->should_interrupt = 1;
+}
+
+void avio_interrupt_mark_all_default(AVIOInterruptContext* ctx)
+{
+    ctx->should_interrupt = 1;
+}
+
+static AVIOInterruptContext avio_interrupt_context_default = { 
+    .should_interrupt   = 0, 
+    .interrupt_check    = avio_interrupt_check_default,
+    .interrupt_mark     = avio_interrupt_mark_default,
+    .interrupt_mark_all = avio_interrupt_mark_all_default,
+    .interrupt_close    = NULL,
+};
+
+static AVIOInterruptContext* avio_interrupt_context = 
&avio_interrupt_context_default;
+
+
+void avio_interrupt_set(AVIOInterruptContext* ctx)
+{
+    AVIOInterruptContext* old = avio_interrupt_context;
+    avio_interrupt_context    = ctx? ctx : &avio_interrupt_context_default;
+    if(old->interrupt_close)
+        old->interrupt_close(old);
+}
+
+int avio_interrupt_check(URLContext* h)
+{
+    return avio_interrupt_context->interrupt_check(avio_interrupt_context, h);
+}
+
+void avio_interrupt_mark(URLContext* h)
+{
+    avio_interrupt_context->interrupt_mark(avio_interrupt_context, h);
+}
+
+void avio_interrupt_mark_all(void)
+{
+    avio_interrupt_context->interrupt_mark_all(avio_interrupt_context);
+}
+
diff --git a/libavformat/avio.h b/libavformat/avio.h
index be14e3c..86c3dae 100644
--- a/libavformat/avio.h
+++ b/libavformat/avio.h
@@ -109,6 +109,7 @@ typedef struct URLContext {
     void *priv_data;
     char *filename; /**< specified URL */
     int is_connected;
+    int should_interrupt; /**< is non zero, reading from stream should be 
stopped */
 } URLContext;
 
 #define URL_PROTOCOL_FLAG_NESTED_SCHEME 1 /*< The protocol name can be the 
first part of a nested protocol scheme */
@@ -171,8 +172,79 @@ attribute_deprecated int url_poll(URLPollEntry 
*poll_table, int n, int timeout);
  */
 #define URL_FLAG_NONBLOCK 4
 
-typedef int URLInterruptCB(void);
-extern URLInterruptCB *url_interrupt_cb;
+/**
+ * @deprecated use avio_interrupt_set() instead
+ */
+typedef attribute_deprecated int URLInterruptCB(void);
+attribute_deprecated extern URLInterruptCB *url_interrupt_cb;
+
+
+/**
+ * Checks or sets the interrupt flag on a URLContext.
+ * 
+ * @param h the URLContext to operate on. if NULL the function applies to all 
URLContexts
+ * @param opaque an opaque value passed when setting the callback
+ * @param flags see AVIO_INTERRUPT_FLAG_*
+ */
+typedef struct AVIOInterruptContext {
+    int should_interrupt;
+
+    /**
+     * Check if the given URLContext or all URLContexts should be interrupted.
+     * @param h the URLContext to check. if it is NULL, performs a global 
check for all urls.
+     * @return non-zero if the URL should be interrupted
+     */
+    int (*interrupt_check)(struct AVIOInterruptContext* ctx, URLContext* h);
+
+    /**
+     * Marks the given URLContext for interruption.
+     * @param h the URLContext to mark. h should not be NULL.
+     */
+    void (*interrupt_mark)(struct AVIOInterruptContext* ctx, URLContext* h);
+
+    /**
+     * Marks all URLContexts for interruption.
+     */
+    void (*interrupt_mark_all)(struct AVIOInterruptContext* ctx);
+
+    /**
+     * Asks the interrupt context to releast all resources
+     * if this callback is NULL, no resources are freed
+     */
+    void (*interrupt_close)(struct AVIOInterruptContext* ctx);
+} AVIOInterruptContext;
+
+/**
+ * Changes the interrupt callback context to a user defined one or back to the 
default
+ * @param ctx the user-defined interrupt context. if it is NULL, the default 
interrupt context is used
+ */
+extern void avio_interrupt_set(AVIOInterruptContext* ctx);
+
+/**
+ * Check if the given URLContext or all URLContexts should be interrupted.
+ * if this function returns non-zero, it means that I/O should be interrupted, 
+ * and AVERROR_EXIT should be returned in this case by the interrupted 
function.
+ * @param h the URLContext to check. if it is NULL, performs a global check 
for all urls.
+ * @return non-zero if the URL should be interrupted
+ */ 
+extern int avio_interrupt_check(URLContext* h);
+
+/**
+ * Marks the given URLContext for interruption.
+ * @param h the URLContext to mark.
+ */
+extern void avio_interrupt_mark(URLContext* h);
+
+/**
+ * Marks all URLContexts for interruption.
+ * @param h the URLContext to mark. if it is NULL, marks all urls globally for 
interruption.
+ */
+extern void avio_interrupt_mark_all(void);
+
+extern int avio_interrupt_check_default(AVIOInterruptContext* ctx, URLContext* 
h);
+extern void avio_interrupt_mark_default(AVIOInterruptContext* ctx, URLContext* 
h);
+extern void avio_interrupt_mark_all_default(AVIOInterruptContext* ctx);
+
 
 /**
  * @defgroup old_url_funcs Old url_* functions
-- 
1.7.4.1

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to