]> git.sesse.net Git - vlc/commitdiff
Added an access using avformat protocol support.
authorLaurent Aimar <fenrir@videolan.org>
Sat, 12 Dec 2009 10:08:32 +0000 (11:08 +0100)
committerLaurent Aimar <fenrir@videolan.org>
Sat, 12 Dec 2009 18:23:56 +0000 (19:23 +0100)
The only way to test it for now is to use the following syntax:
avio://full_url
like for example avio://http://myhost/myfile.avi
It cannot be instanciated multiple times per process.

configure.ac
modules/access/Modules.am
modules/access/avio.c [new file with mode: 0644]
modules/access/avio.h [new file with mode: 0644]
modules/codec/avcodec/Modules.am
modules/codec/avcodec/avcodec.c

index aa556f8b7d54d09b0c5544ee2c5b63bb4e8234fe..1f1319b0e252ea632395f2fa4adac72ce4a22d12 100644 (file)
@@ -223,7 +223,7 @@ case "${host_os}" in
     VLC_ADD_LDFLAGS([mkv mp4], [-Wl,-framework,IOKit,-framework,CoreFoundation])
     VLC_ADD_LDFLAGS([vlc],[-Wl,-undefined,dynamic_lookup])
     VLC_ADD_LDFLAGS([libvlc],[-Wl,-undefined,dynamic_lookup])
-    VLC_ADD_LDFLAGS([avcodec avformat swscale postproc i420_rgb_mmx x264],[-Wl,-read_only_relocs,suppress])
+    VLC_ADD_LDFLAGS([avcodec avformat access_avio swscale postproc i420_rgb_mmx x264],[-Wl,-read_only_relocs,suppress])
     VLC_ADD_CFLAGS([motion],[-fconstant-cfstrings])
     VLC_ADD_LDFLAGS([libvlccore],[-Wl,-framework,CoreFoundation])
     VLC_ADD_LDFLAGS([motion],[-Wl,-framework,IOKit,-framework,CoreFoundation])
@@ -730,7 +730,7 @@ AC_CHECK_LIB(m,cos,[
   VLC_ADD_LIBS([adjust wave ripple psychedelic gradient a52tofloat32 dtstofloat32 x264 goom visual panoramix rotate noise grain scene kate flac lua chorus_flanger],[-lm])
 ])
 AC_CHECK_LIB(m,pow,[
-  VLC_ADD_LIBS([avcodec avformat swscale postproc ffmpegaltivec i420_rgb faad twolame equalizer spatializer param_eq libvlccore freetype mod mpc dmo quicktime realaudio realvideo opengl],[-lm])
+  VLC_ADD_LIBS([avcodec avformat access_avio swscale postproc ffmpegaltivec i420_rgb faad twolame equalizer spatializer param_eq libvlccore freetype mod mpc dmo quicktime realaudio realvideo opengl],[-lm])
 ])
 AC_CHECK_LIB(m,sqrt,[
   VLC_ADD_LIBS([headphone_channel_mixer normvol audiobargraph_a speex mono colorthres extract],[-lm])
@@ -3043,6 +3043,10 @@ then
         VLC_ADD_PLUGIN([avformat])
         VLC_ADD_LIBS([avformat],[$AVFORMAT_LIBS $AVUTIL_LIBS])
         VLC_ADD_CFLAGS([avformat],[$AVFORMAT_CFLAGS $AVUTIL_CFLAGS])
+
+        VLC_ADD_PLUGIN([access_avio])
+        VLC_ADD_LIBS([access_avio],[$AVFORMAT_LIBS $AVUTIL_LIBS])
+        VLC_ADD_CFLAGS([access_avio],[$AVFORMAT_CFLAGS $AVUTIL_CFLAGS])
       ], [
         VLC_ADD_LIBS([avcodec],[$AVFORMAT_LIBS $AVUTIL_LIBS])
         VLC_ADD_CFLAGS([avcodec],[$AVFORMAT_CFLAGS $AVUTIL_CFLAGS])
index 1641f3d3470527b25b8bb44aebb165895d3ecc3a..fddd9e8ad82ce87c88ed423763ba30c6b74e305c 100644 (file)
@@ -43,6 +43,7 @@ SOURCES_access_oss = oss.c
 SOURCES_access_mtp = mtp.c
 SOURCES_access_sftp = sftp.c
 SOURCES_access_imem = imem.c
+SOURCES_access_avio = avio.c avio.h
 
 libaccess_rtmp_plugin_la_SOURCES = \
         rtmp/access.c \
diff --git a/modules/access/avio.c b/modules/access/avio.c
new file mode 100644 (file)
index 0000000..fb2aad8
--- /dev/null
@@ -0,0 +1,228 @@
+/*****************************************************************************
+ * avio.c: access using libavformat library
+ *****************************************************************************
+ * Copyright (C) 2009 Laurent Aimar
+ * $Id$
+ *
+ * Authors: Laurent Aimar <fenrir _AT_ videolan _DOT_ org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include <assert.h>
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_access.h>
+#include <vlc_avcodec.h>
+
+#include "avio.h"
+
+/*****************************************************************************
+ * Module descriptor
+ *****************************************************************************/
+vlc_module_begin()
+    AVIO_MODULE
+vlc_module_end()
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static ssize_t Read   (access_t *, uint8_t *, size_t);
+static int     Seek   (access_t *, int64_t);
+static int     Control(access_t *, int, va_list);
+
+static int     SetupAvio(access_t *);
+
+struct access_sys_t {
+    URLContext *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;
+
+    /* We can either accept only one user (actually) or multiple ones
+     * with an exclusive lock */
+    if (SetupAvio(access)) {
+        msg_Err(access, "Module aready in use");
+        return VLC_EGENERIC;
+    }
+
+    /* */
+    vlc_avcodec_lock();
+    av_register_all();
+    vlc_avcodec_unlock();
+
+    /* We accept:
+     * - avio://full_url
+     * - url (only a subset of available protocols).
+     */
+    char *url;
+    if (!strcmp(access->psz_access, "avio"))
+        url = strdup(access->psz_path);
+    else if (asprintf(&url, "%s://%s", access->psz_access, access->psz_path) < 0)
+        url = NULL;
+
+    if (!url)
+        goto error;
+
+    msg_Dbg(access, "Opening '%s'", url);
+    if (url_open(&sys->context, url, URL_RDONLY) < 0 )
+        sys->context = NULL;
+    free(url);
+
+    if (!sys->context) {
+        msg_Err(access, "Failed to open url using libavformat");
+        goto error;
+    }
+    const int64_t size = url_filesize(sys->context);
+    msg_Dbg(access, "is_streamed=%d size=%lld", sys->context->is_streamed, size);
+
+    /* */
+    access_InitFields(access);
+    access->info.i_size = size > 0 ? size : 0;
+
+    access->pf_read = Read;
+    access->pf_block = NULL;
+    access->pf_control = Control;
+    access->pf_seek = Seek;
+    access->p_sys = sys;
+
+    return VLC_SUCCESS;
+
+error:
+    SetupAvio(NULL);
+    free(sys);
+    return VLC_EGENERIC;
+}
+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);
+
+    free(sys);
+}
+
+static ssize_t Read(access_t *access, uint8_t *data, size_t size)
+{
+    access_sys_t *sys = access->p_sys;
+
+    /* 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;
+    return r;
+}
+static int Seek(access_t *access, int64_t position)
+{
+    access_sys_t *sys = access->p_sys;
+
+    if (url_seek(sys->context, position, SEEK_SET) < 0) {
+        msg_Err(access, "Seek to %lld failed\n", position);
+        if (access->info.i_size <= 0 || position != access->info.i_size)
+            return VLC_EGENERIC;
+    }
+    access->info.i_pos = position;
+    access->info.b_eof = false;
+    return VLC_SUCCESS;
+}
+static int Control(access_t *access, int query, va_list args)
+{
+    access_sys_t *sys = access->p_sys;
+
+    switch (query) {
+    case ACCESS_CAN_SEEK:
+    case ACCESS_CAN_FASTSEEK: { /* FIXME how to do that ? */
+        bool *b = va_arg(args, bool *);
+        *b = !sys->context->is_streamed;
+        return VLC_SUCCESS;
+    }
+    case ACCESS_CAN_PAUSE: {
+        bool *b = va_arg(args, bool *);
+        *b = sys->context->prot->url_read_pause != NULL; /* FIXME Unsure */
+        return VLC_SUCCESS;
+    }
+    case ACCESS_CAN_CONTROL_PACE: {
+        bool *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 */
+    }
+    case ACCESS_SET_PAUSE_STATE: {
+        bool is_paused = va_arg(args, int);
+        if (av_url_read_pause(sys->context, is_paused)< 0)
+            return VLC_EGENERIC;
+        return VLC_SUCCESS;
+    }
+    case ACCESS_GET_TITLE_INFO:
+    case ACCESS_GET_META:
+    case ACCESS_GET_CONTENT_TYPE:
+    case ACCESS_GET_SIGNAL:
+    case ACCESS_SET_TITLE:
+    case ACCESS_SET_SEEKPOINT:
+    case ACCESS_SET_PRIVATE_ID_STATE:
+    case ACCESS_SET_PRIVATE_ID_CA:
+    case ACCESS_GET_PRIVATE_ID_STATE:
+    default:
+        return VLC_EGENERIC;
+    }
+}
+
+/* */
+static vlc_mutex_t avio_lock = VLC_STATIC_MUTEX;
+static access_t *current_access = NULL;
+
+static int UrlInterruptCallback(void)
+{
+    assert(current_access);
+    return !vlc_object_alive(current_access);
+}
+static int SetupAvio(access_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;
+}
+
diff --git a/modules/access/avio.h b/modules/access/avio.h
new file mode 100644 (file)
index 0000000..7e956d0
--- /dev/null
@@ -0,0 +1,42 @@
+/*****************************************************************************
+ * avio.h: access using libavformat library
+ *****************************************************************************
+ * Copyright (C) 2009 Laurent Aimar
+ * $Id$
+ *
+ * Authors: Laurent Aimar <fenrir _AT_ videolan _DOT_ org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+/* ffmpeg header */
+#if defined(HAVE_LIBAVFORMAT_AVFORMAT_H)
+#   include <libavformat/avformat.h>
+#elif defined(HAVE_FFMPEG_AVFORMAT_H)
+#   include <ffmpeg/avformat.h>
+#endif
+int  OpenAvio (vlc_object_t *);
+void CloseAvio(vlc_object_t *);
+
+#define AVIO_MODULE \
+    set_shortname(N_("Avio"))               \
+    set_description(N_("FFmpeg access") )   \
+    set_category(CAT_INPUT)                 \
+    set_subcategory(SUBCAT_INPUT_ACCESS)    \
+    set_capability("access", -1)            \
+    add_shortcut("avio")                    \
+    add_shortcut("rtmp")                    \
+    set_callbacks(OpenAvio, CloseAvio)
+
index 9fed3b9d2d5b684188858349abce3f9e0d0409b1..db3195eca2ca0e9ef19d2a8d8f1b3df17e20b61d 100644 (file)
@@ -22,7 +22,8 @@ libavcodec_plugin_la_DEPENDENCIES =
 
 if MERGE_FFMPEG
 libavcodec_plugin_la_SOURCES += \
-       ../../demux/avformat/demux.c
+       ../../demux/avformat/demux.c \
+       ../../access/avio.c
 if ENABLE_SOUT
 libavcodec_plugin_la_SOURCES += \
        ../../demux/avformat/mux.c
index 937227345faff79e9ae0cc8c4295b29a57464dbf..56c818370d67788071d9b2b419cc48d9b6d9e6ae 100644 (file)
@@ -81,6 +81,7 @@ static const char *const enc_hq_list_text[] = {
 
 #ifdef MERGE_FFMPEG
 # include "../../demux/avformat/avformat.h"
+# include "../../access/avio.h"
 #endif
 
 /*****************************************************************************
@@ -214,6 +215,8 @@ vlc_module_begin ()
 #ifdef MERGE_FFMPEG
     add_submodule ()
 #   include "../../demux/avformat/avformat.c"
+    add_submodule ()
+        AVIO_MODULE
 #endif
 vlc_module_end ()