[vlc-devel] [PATCH 01/15] avio access: use new API

KO Myung-Hun komh78 at gmail.com
Fri Mar 2 16:02:58 CET 2012


From: Rafaël Carré <funman at videolan.org>

- fix bug in ACCESS_GET_PTS_DELAY where it would fall through the next case
- print error messages from libavformat
- remove useless strdup
- check for exclusive access to avio when context open succeeded
- support for multiple input / output at the same time with libavformat > 54 (untested)
(cherry picked from commit cca698a05ea024a380330e1f3144996bba4c20e0)

Signed-off-by: KO Myung-Hun <komh at chollian.net>
---
 modules/access/avio.c |  275 +++++++++++++++++++++++++++++--------------------
 1 files changed, 165 insertions(+), 110 deletions(-)

diff --git a/modules/access/avio.c b/modules/access/avio.c
index c6339ff..0850791 100644
--- a/modules/access/avio.c
+++ b/modules/access/avio.c
@@ -34,6 +34,20 @@
 
 #include "avio.h"
 
+#if LIBAVFORMAT_VERSION_MAJOR < 54
+# define AVIOContext URLContext
+
+# define avio_open url_open
+# define avio_close url_close
+# define avio_read url_read
+# define avio_seek url_seek
+# define avio_pause av_url_read_pause
+
+# define AVIO_FLAG_READ URL_RDONLY
+# define AVIO_FLAG_WRITE URL_WRONLY
+# define avio_size url_filesize
+#endif
+
 /*****************************************************************************
  * Module descriptor
  *****************************************************************************/
@@ -53,38 +67,58 @@ static ssize_t Write(sout_access_out_t *, block_t *);
 static int     OutControl(sout_access_out_t *, int, va_list);
 static int     OutSeek (sout_access_out_t *, off_t);
 
-static int     SetupAvio(vlc_object_t *);
+static int UrlInterruptCallback(void *access)
+{
+    return !vlc_object_alive((vlc_object_t*)access);
+}
 
 struct access_sys_t {
-    URLContext *context;
+    AVIOContext *context;
 };
 
 struct sout_access_out_sys_t {
-    URLContext *context;
+    AVIOContext *context;
 };
 
+
 /* */
-int OpenAvio(vlc_object_t *object)
-{
-    access_t *access = (access_t*)object;
-    access_sys_t *sys;
 
-    /* */
-    access->p_sys = sys = malloc(sizeof(*sys));
-    if (!sys)
-        return VLC_ENOMEM;
+#if LIBAVFORMAT_VERSION_MAJOR < 54
+static vlc_object_t *current_access = NULL;
 
-    /* We can either accept only one user (actually) or multiple ones
-     * with an exclusive lock */
-    if (SetupAvio(VLC_OBJECT(access))) {
-        msg_Err(access, "Module aready in use");
+static int UrlInterruptCallbackSingle(void)
+{
+    return UrlInterruptCallback(current_access);
+}
+
+static int SetupAvioCb(vlc_object_t *access)
+{
+    static vlc_mutex_t avio_lock = VLC_STATIC_MUTEX;
+    vlc_mutex_lock(&avio_lock);
+    assert(!access != !current_access);
+    if (access && current_access) {
+        vlc_mutex_unlock(&avio_lock);
         return VLC_EGENERIC;
     }
+    url_set_interrupt_cb(access ? UrlInterruptCallback : NULL);
 
-    /* */
-    vlc_avcodec_lock();
-    av_register_all();
-    vlc_avcodec_unlock();
+    current_access = access;
+
+    vlc_mutex_unlock(&avio_lock);
+
+    return VLC_SUCCESS;
+}
+#endif
+
+/* */
+
+int OpenAvio(vlc_object_t *object)
+{
+    access_t *access = (access_t*)object;
+    access_sys_t *sys = malloc(sizeof(*sys));
+    if (!sys)
+        return VLC_ENOMEM;
+    sys->context = NULL;
 
     /* We accept:
      * - avio://full_url
@@ -97,20 +131,51 @@ int OpenAvio(vlc_object_t *object)
                       access->psz_location) < 0)
         url = NULL;
 
-    if (!url)
-        goto error;
+    if (!url) {
+        free(sys);
+        return VLC_ENOMEM;
+    }
 
-    msg_Dbg(access, "Opening '%s'", url);
-    if (url_open(&sys->context, url, URL_RDONLY) < 0)
-        sys->context = NULL;
+    /* */
+    vlc_avcodec_lock();
+    av_register_all();
+    vlc_avcodec_unlock();
+
+    int ret;
+#if LIBAVFORMAT_VERSION_MAJOR < 54
+    ret = avio_open(&sys->context, url, AVIO_FLAG_READ);
+#else
+    AVIOInterruptCB cb = {
+        .callback = UrlInterruptCallback,
+        .opaque = access,
+    };
+    ret = avio_open2(&sys->context, url, AVIO_FLAG_READ, &cb, NULL /* options */);
+#endif
+    if (ret < 0) {
+        errno = AVUNERROR(ret);
+        msg_Err(access, "Failed to open %s: %m", url);
+        free(url);
+        goto error;
+    }
     free(url);
 
-    if (!sys->context) {
-        msg_Err(access, "Failed to open url using libavformat");
+#if LIBAVFORMAT_VERSION_MAJOR < 54
+    /* We can accept only one active user at any time */
+    if (SetupAvioCb(VLC_OBJECT(access))) {
+        msg_Err(access, "Module aready in use");
+        avio_close(sys->context);
         goto error;
     }
-    const int64_t size = url_filesize(sys->context);
-    msg_Dbg(access, "is_streamed=%d size=%"PRIi64, sys->context->is_streamed, size);
+#endif
+
+    int64_t size = avio_size(sys->context);
+    bool seekable;
+#if LIBAVFORMAT_VERSION_MAJOR < 54
+    seekable = !sys->context->is_streamed;
+#else
+    seekable = sys->context->seekable;
+#endif
+    msg_Dbg(access, "%sseekable, size=%"PRIi64, seekable ? "" : "not ", size);
 
     /* */
     access_InitFields(access);
@@ -125,7 +190,6 @@ int OpenAvio(vlc_object_t *object)
     return VLC_SUCCESS;
 
 error:
-    SetupAvio(NULL);
     free(sys);
     return VLC_EGENERIC;
 }
@@ -134,42 +198,43 @@ error:
 int OutOpenAvio(vlc_object_t *object)
 {
     sout_access_out_t *access = (sout_access_out_t*)object;
-    sout_access_out_sys_t *sys;
-
-    /* */
-    access->p_sys = sys = malloc(sizeof(*sys));
+    sout_access_out_sys_t *sys = malloc(sizeof(*sys));
     if (!sys)
         return VLC_ENOMEM;
-
-    /* We can either accept only one user (actually) or multiple ones
-     * with an exclusive lock */
-    if (SetupAvio(VLC_OBJECT(access))) {
-        msg_Err(access, "Module aready in use");
-        free(sys);
-        return VLC_EGENERIC;
-    }
+    sys->context = NULL;
 
     /* */
     vlc_avcodec_lock();
     av_register_all();
     vlc_avcodec_unlock();
 
-    char *url = NULL;
-    if (access->psz_path)
-        url = strdup(access->psz_path);
-
-    if (!url)
+    if (!access->psz_path)
         goto error;
 
-    msg_Dbg(access, "avio_output Opening '%s'", url);
-    if (url_open(&sys->context, url, URL_WRONLY) < 0)
-        sys->context = NULL;
-    free(url);
+    int ret;
+#if LIBAVFORMAT_VERSION_MAJOR < 54
+    ret = avio_open(&sys->context, access->psz_path, AVIO_FLAG_WRITE);
+#else
+    AVIOInterruptCB cb = {
+        .callback = UrlInterruptCallback,
+        .opaque = access,
+    };
+    ret = avio_open2(&sys->context, access->psz_path, AVIO_FLAG_WRITE,
+                     &cb, NULL /* options */);
+#endif
+    if (ret < 0) {
+        errno = AVUNERROR(ret);
+        msg_Err(access, "Failed to open %s", access->psz_path);
+        goto error;
+    }
 
-    if (!sys->context) {
-        msg_Err(access, "Failed to open url using libavformat");
+#if LIBAVFORMAT_VERSION_MAJOR < 54
+    /* We can accept only one active user at any time */
+    if (SetupAvioCb(VLC_OBJECT(access))) {
+        msg_Err(access, "Module aready in use");
         goto error;
     }
+#endif
 
     access->pf_write = Write;
     access->pf_control = OutControl;
@@ -179,7 +244,6 @@ int OutOpenAvio(vlc_object_t *object)
     return VLC_SUCCESS;
 
 error:
-    SetupAvio(NULL);
     free(sys);
     return VLC_EGENERIC;
 }
@@ -189,10 +253,11 @@ void CloseAvio(vlc_object_t *object)
     access_t *access = (access_t*)object;
     access_sys_t *sys = access->p_sys;
 
-    url_close(sys->context);
-
-    SetupAvio(NULL);
+#if LIBAVFORMAT_VERSION_MAJOR < 54
+    SetupAvioCb(NULL);
+#endif
 
+    avio_close(sys->context);
     free(sys);
 }
 
@@ -201,23 +266,21 @@ void OutCloseAvio(vlc_object_t *object)
     sout_access_out_t *access = (sout_access_out_t*)object;
     sout_access_out_sys_t *sys = access->p_sys;
 
-    url_close(sys->context);
-
-    SetupAvio(NULL);
+#if LIBAVFORMAT_VERSION_MAJOR < 54
+    SetupAvioCb(NULL);
+#endif
 
+    avio_close(sys->context);
     free(sys);
 }
 
 static ssize_t Read(access_t *access, uint8_t *data, size_t size)
 {
-    /* FIXME I am unsure of the meaning of the return value in case
-     * of error.
-     */
-    int r = url_read(access->p_sys->context, data, size);
-    access->info.b_eof = r <= 0;
-    if (r < 0)
-        return -1;
-    access->info.i_pos += r;
+    int r = avio_read(access->p_sys->context, data, size);
+    if (r > 0)
+        access->info.i_pos += r;
+    else
+        access->info.b_eof = true;
     return r;
 }
 
@@ -232,7 +295,14 @@ static ssize_t Write(sout_access_out_t *p_access, block_t *p_buffer)
     while (p_buffer != NULL) {
         block_t *p_next = p_buffer->p_next;;
 
+#if LIBAVFORMAT_VERSION_MAJOR < 54
         i_write += url_write(p_sys->context, p_buffer->p_buffer, p_buffer->i_buffer);
+#else
+        /* FIXME : how are errors notified ?? */
+        avio_write(p_sys->context, p_buffer->p_buffer, p_buffer->i_buffer);
+        i_write += p_buffer->i_buffer;
+#endif
+
         block_Release(p_buffer);
 
         p_buffer = p_next;
@@ -244,10 +314,15 @@ static ssize_t Write(sout_access_out_t *p_access, block_t *p_buffer)
 static int Seek(access_t *access, uint64_t position)
 {
     access_sys_t *sys = access->p_sys;
-
-    if (position > INT64_MAX ||
-        url_seek(sys->context, position, SEEK_SET) < 0) {
-        msg_Err(access, "Seek to %"PRIu64" failed\n", position);
+    int ret;
+
+    if (position > INT64_MAX)
+        ret = AVERROR(EOVERFLOW);
+    else
+        ret = avio_seek(sys->context, position, SEEK_SET);
+    if (ret < 0) {
+        errno = AVUNERROR(ret);
+        msg_Err(access, "Seek to %"PRIu64" failed: %m", position);
         if (access->info.i_size <= 0 || position != access->info.i_size)
             return VLC_EGENERIC;
     }
@@ -260,7 +335,7 @@ static int OutSeek(sout_access_out_t *p_access, off_t i_pos)
 {
     sout_access_out_sys_t *sys = p_access->p_sys;
 
-    if (url_seek(sys->context, i_pos, SEEK_SET) < 0)
+    if (avio_seek(sys->context, i_pos, SEEK_SET) < 0)
         return VLC_EGENERIC;
     return VLC_SUCCESS;
 }
@@ -287,31 +362,38 @@ static int OutControl(sout_access_out_t *p_access, int i_query, va_list args)
 static int Control(access_t *access, int query, va_list args)
 {
     access_sys_t *sys = access->p_sys;
+    bool *b;
 
     switch (query) {
     case ACCESS_CAN_SEEK:
-    case ACCESS_CAN_FASTSEEK: { /* FIXME how to do that ? */
-        bool *b = va_arg(args, bool *);
+    case ACCESS_CAN_FASTSEEK: /* FIXME how to do that ? */
+        b = va_arg(args, bool *);
+#if LIBAVFORMAT_VERSION_MAJOR < 54
         *b = !sys->context->is_streamed;
+#else
+        *b = sys->context->seekable;
+#endif
         return VLC_SUCCESS;
-    }
-    case ACCESS_CAN_PAUSE: {
-        bool *b = va_arg(args, bool *);
-        *b = sys->context->prot->url_read_pause != NULL; /* FIXME Unsure */
+    case ACCESS_CAN_PAUSE:
+        b = va_arg(args, bool *);
+#if LIBAVFORMAT_VERSION_MAJOR < 54
+        *b = sys->context->prot->url_read_pause != NULL;
+#else
+        *b = sys->context->read_pause != NULL;
+#endif
         return VLC_SUCCESS;
-    }
-    case ACCESS_CAN_CONTROL_PACE: {
-        bool *b = va_arg(args, bool *);
+    case ACCESS_CAN_CONTROL_PACE:
+        b = va_arg(args, bool *);
         *b = true; /* FIXME */
         return VLC_SUCCESS;
-    }
     case ACCESS_GET_PTS_DELAY: {
         int64_t *delay = va_arg(args, int64_t *);
         *delay = DEFAULT_PTS_DELAY; /* FIXME */
+        return VLC_SUCCESS;
     }
     case ACCESS_SET_PAUSE_STATE: {
         bool is_paused = va_arg(args, int);
-        if (av_url_read_pause(sys->context, is_paused)< 0)
+        if (avio_pause(sys->context, is_paused)< 0)
             return VLC_EGENERIC;
         return VLC_SUCCESS;
     }
@@ -328,30 +410,3 @@ static int Control(access_t *access, int query, va_list args)
         return VLC_EGENERIC;
     }
 }
-
-/* */
-static vlc_mutex_t avio_lock = VLC_STATIC_MUTEX;
-static vlc_object_t *current_access = NULL;
-
-
-static int UrlInterruptCallback(void)
-{
-    assert(current_access);
-    return !vlc_object_alive(current_access);
-}
-
-
-static int SetupAvio(vlc_object_t *access)
-{
-    vlc_mutex_lock(&avio_lock);
-    assert(!access != !current_access);
-    if (access && current_access) {
-        vlc_mutex_unlock(&avio_lock);
-        return VLC_EGENERIC;
-    }
-    url_set_interrupt_cb(access ? UrlInterruptCallback : NULL);
-    current_access = access;
-    vlc_mutex_unlock(&avio_lock);
-
-    return VLC_SUCCESS;
-}
-- 
1.7.3.2




More information about the vlc-devel mailing list