[vlc-commits] lua: convert playlist parser to stream filter

Rémi Denis-Courmont git at videolan.org
Tue Apr 18 22:43:30 CEST 2017


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Tue Apr 18 22:35:47 2017 +0300| [ca74826ea7623ba3788c8b5eeb3f8b31dda37012] | committer: Rémi Denis-Courmont

lua: convert playlist parser to stream filter

ReadDir() is more logical and simpler than Demux() here.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=ca74826ea7623ba3788c8b5eeb3f8b31dda37012
---

 modules/lua/demux.c | 259 ++++++++++++++++++++++++++++++----------------------
 modules/lua/vlc.c   |  62 +------------
 modules/lua/vlc.h   |   3 -
 3 files changed, 150 insertions(+), 174 deletions(-)

diff --git a/modules/lua/demux.c b/modules/lua/demux.c
index 38fee11a43..92224961d2 100644
--- a/modules/lua/demux.c
+++ b/modules/lua/demux.c
@@ -29,35 +29,35 @@
 #endif
 
 #include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <vlc_common.h>
+#include <vlc_access.h>
 
 #include "vlc.h"
 #include "libs.h"
 
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-static int Demux( demux_t *p_demux );
-static int Control( demux_t *p_demux, int i_query, va_list args );
-
 /*****************************************************************************
  * Demux specific functions
  *****************************************************************************/
-struct demux_sys_t
+struct vlclua_playlist
 {
     lua_State *L;
-    char *psz_filename;
+    char *filename;
+    char *access;
+    const char *path;
 };
 
 static int vlclua_demux_peek( lua_State *L )
 {
-    demux_t *p_demux = (demux_t *)vlclua_get_this( L );
+    stream_t *s = (stream_t *)vlclua_get_this(L);
     int n = luaL_checkint( L, 1 );
     const uint8_t *p_peek;
 
-    int i_peek = vlc_stream_Peek( p_demux->s, &p_peek, n );
-    if( i_peek > 0 )
-        lua_pushlstring( L, (const char *)p_peek, i_peek );
+    ssize_t val = vlc_stream_Peek(s->p_source, &p_peek, n);
+    if (val > 0)
+        lua_pushlstring(L, (const char *)p_peek, val);
     else
         lua_pushnil( L );
     return 1;
@@ -65,16 +65,16 @@ static int vlclua_demux_peek( lua_State *L )
 
 static int vlclua_demux_read( lua_State *L )
 {
-    demux_t *p_demux = (demux_t *)vlclua_get_this( L );
+    stream_t *s = (stream_t *)vlclua_get_this(L);
     const uint8_t *p_read;
     int n = luaL_checkint( L, 1 );
-    int i_read = vlc_stream_Peek( p_demux->s, &p_read, n );
+    ssize_t val = vlc_stream_Peek(s->p_source, &p_read, n);
 
-    if( i_read > 0 )
+    if (val > 0)
     {
-        lua_pushlstring( L, (const char *)p_read, i_read );
-        int i_seek = vlc_stream_Read( p_demux->s, NULL, i_read );
-        assert( i_read == i_seek );
+        lua_pushlstring(L, (const char *)p_read, val);
+        int i_seek = vlc_stream_Read(s->p_source, NULL, val);
+        assert(val == i_seek );
     }
     else
         lua_pushnil( L );
@@ -84,17 +84,17 @@ static int vlclua_demux_read( lua_State *L )
 
 static int vlclua_demux_readline( lua_State *L )
 {
-    demux_t *p_demux = (demux_t *)vlclua_get_this( L );
-    char *psz_line = vlc_stream_ReadLine( p_demux->s );
-    if( psz_line )
+    stream_t *s = (stream_t *)vlclua_get_this(L);
+    char *line = vlc_stream_ReadLine(s->p_source);
+
+    if (line != NULL)
     {
-        lua_pushstring( L, psz_line );
-        free( psz_line );
+        lua_pushstring(L, line);
+        free(line);
     }
     else
-    {
         lua_pushnil( L );
-    }
+
     return 1;
 }
 
@@ -120,70 +120,71 @@ static const luaL_Reg p_reg_parse[] =
  * Called through lua_scripts_batch_execute to call 'probe' on
  * the script pointed by psz_filename.
  *****************************************************************************/
-static int probe_luascript( vlc_object_t *p_this, const char * psz_filename,
-                            const luabatch_context_t *p_context )
+static int probe_luascript(vlc_object_t *obj, const char *filename,
+                           const luabatch_context_t *ctx)
 {
-    VLC_UNUSED(p_context);
-    demux_t * p_demux = (demux_t *)p_this;
-
-    p_demux->p_sys->psz_filename = strdup(psz_filename);
+    stream_t *s = (stream_t *)obj;
+    struct vlclua_playlist *sys = s->p_sys;
 
     /* Initialise Lua state structure */
     lua_State *L = luaL_newstate();
     if( !L )
-    {
-        msg_Err( p_demux, "Could not create new Lua State" );
-        goto error;
-    }
-    p_demux->p_sys->L = L;
+        return VLC_ENOMEM;
+
+    sys->L = L;
 
     /* Load Lua libraries */
     luaL_openlibs( L ); /* FIXME: Don't open all the libs? */
 
-    vlclua_set_this( L, p_demux );
+    vlclua_set_this(L, s);
     luaL_register_namespace( L, "vlc", p_reg );
     luaopen_msg( L );
     luaopen_strings( L );
     luaopen_stream( L );
     luaopen_variables( L );
     luaopen_xml( L );
-    lua_pushstring( L, p_demux->psz_location );
+
+    if (sys->path != NULL)
+        lua_pushstring(L, sys->path);
+    else
+        lua_pushnil(L);
     lua_setfield( L, -2, "path" );
-    lua_pushstring( L, p_demux->psz_access );
+
+    if (sys->access != NULL)
+        lua_pushstring(L, sys->access);
+    else
+        lua_pushnil(L);
     lua_setfield( L, -2, "access" );
 
     lua_pop( L, 1 );
 
     /* Setup the module search path */
-    if( vlclua_add_modules_path( L, psz_filename ) )
+    if (vlclua_add_modules_path(L, filename))
     {
-        msg_Warn( p_demux, "Error while setting the module search path for %s",
-                  psz_filename );
+        msg_Warn(s, "error setting the module search path for %s", filename);
         goto error;
     }
 
     /* Load and run the script(s) */
-    if( vlclua_dofile( VLC_OBJECT(p_demux), L, psz_filename ) )
+    if (vlclua_dofile(VLC_OBJECT(s), L, filename))
     {
-        msg_Warn( p_demux, "Error loading script %s: %s", psz_filename,
-                  lua_tostring( L, lua_gettop( L ) ) );
+        msg_Warn(s, "error loading script %s: %s", filename,
+                 lua_tostring(L, lua_gettop(L)));
         goto error;
     }
 
     lua_getglobal( L, "probe" );
-
     if( !lua_isfunction( L, -1 ) )
     {
-        msg_Warn( p_demux, "Error while running script %s, "
-                  "function probe() not found", psz_filename );
+        msg_Warn(s, "error running script %s: function %s(): %s",
+                 filename, "probe", "not found");
         goto error;
     }
 
     if( lua_pcall( L, 0, 1, 0 ) )
     {
-        msg_Warn( p_demux, "Error while running script %s, "
-                  "function probe(): %s", psz_filename,
-                  lua_tostring( L, lua_gettop( L ) ) );
+        msg_Warn(s, "error running script %s: function %s(): %s",
+                 filename, "probe", lua_tostring(L, lua_gettop(L)));
         goto error;
     }
 
@@ -191,92 +192,130 @@ static int probe_luascript( vlc_object_t *p_this, const char * psz_filename,
     {
         if( lua_toboolean( L, 1 ) )
         {
-            msg_Dbg( p_demux, "Lua playlist script %s's "
-                     "probe() function was successful", psz_filename );
+            msg_Dbg(s, "Lua playlist script %s's "
+                    "probe() function was successful", filename );
             lua_pop( L, 1 );
+            sys->filename = strdup(filename);
             return VLC_SUCCESS;
         }
     }
 
+    (void) ctx;
 error:
     lua_pop( L, 1 );
-    lua_close( p_demux->p_sys->L );
-    p_demux->p_sys->L = NULL;
-    FREENULL( p_demux->p_sys->psz_filename );
+    lua_close(sys->L);
     return VLC_EGENERIC;
 }
 
-/*****************************************************************************
- * Import_LuaPlaylist: main import function
- *****************************************************************************/
-int Import_LuaPlaylist( vlc_object_t *p_this )
+static int ReadDir(stream_t *s, input_item_node_t *node)
 {
-    demux_t *p_demux = (demux_t *)p_this;
-    int ret;
+    struct vlclua_playlist *sys = s->p_sys;
+    lua_State *L = sys->L;
 
-    p_demux->p_sys = calloc( 1, sizeof( demux_sys_t ) );
-    if( !p_demux->p_sys )
-        return VLC_ENOMEM;
+    luaL_register_namespace( L, "vlc", p_reg_parse );
 
-    p_demux->pf_control = Control;
-    p_demux->pf_demux = Demux;
+    lua_getglobal( L, "parse" );
 
-    ret = vlclua_scripts_batch_execute( p_this, "playlist",
-                                        &probe_luascript, NULL );
-    if( ret )
-        Close_LuaPlaylist( p_this );
-    return ret;
-}
+    if( !lua_isfunction( L, -1 ) )
+    {
+        msg_Warn(s, "error running script %s: function %s(): %s",
+                 sys->filename, "parse", "not found");
+        return VLC_ENOITEM;
+    }
+
+    if( lua_pcall( L, 0, 1, 0 ) )
+    {
+        msg_Warn(s, "error running script %s: function %s(): %s",
+                 sys->filename, "parse", lua_tostring(L, lua_gettop(L)));
+        return VLC_ENOITEM;
+    }
 
+    if (!lua_gettop(L))
+    {
+        msg_Err(s, "script went completely foobar");
+        return VLC_ENOITEM;
+    }
 
-/*****************************************************************************
- * Deactivate: frees unused data
- *****************************************************************************/
-void Close_LuaPlaylist( vlc_object_t *p_this )
-{
-    demux_t *p_demux = (demux_t *)p_this;
-    if( p_demux->p_sys->L )
-        lua_close( p_demux->p_sys->L );
-    free( p_demux->p_sys->psz_filename );
-    free( p_demux->p_sys );
+    if (!lua_istable(L, -1))
+    {
+        msg_Warn(s, "Playlist should be a table.");
+        return VLC_ENOITEM;
+    }
+
+    lua_pushnil(L);
+
+    /* playlist nil */
+    while (lua_next(L, -2))
+    {
+        input_item_t *item = vlclua_read_input_item(VLC_OBJECT(s), L);
+        if (item != NULL)
+        {
+            /* copy the original URL to the meta data,
+             * if "URL" is still empty */
+            char *url = input_item_GetURL(item);
+            if (url == NULL && s->psz_url != NULL)
+                input_item_SetURL(item, s->psz_url);
+            free(url);
+
+            input_item_node_AppendItem(node, item);
+            input_item_Release(item);
+        }
+        /* pop the value, keep the key for the next lua_next() call */
+        lua_pop(L, 1);
+    }
+    /* playlist */
+
+    return VLC_SUCCESS;
 }
 
-static int Demux( demux_t *p_demux )
+/*****************************************************************************
+ * Import_LuaPlaylist: main import function
+ *****************************************************************************/
+int Import_LuaPlaylist(vlc_object_t *obj)
 {
-    lua_State *L = p_demux->p_sys->L;
-    char *psz_filename = p_demux->p_sys->psz_filename;
-
-    input_item_t *p_current_input = input_GetItem( p_demux->p_input );
+    stream_t *s = (stream_t *)obj;
+    struct vlclua_playlist *sys = malloc(sizeof (*sys));
 
-    luaL_register_namespace( L, "vlc", p_reg_parse );
+    if (unlikely(sys == NULL))
+        return VLC_ENOMEM;
 
-    lua_getglobal( L, "parse" );
+    s->p_sys = sys;
+    sys->access = NULL;
+    sys->path = NULL;
 
-    if( !lua_isfunction( L, -1 ) )
-    {
-        msg_Warn( p_demux, "Error while running script %s, "
-                  "function parse() not found", psz_filename );
-        return VLC_DEMUXER_EGENERIC;
+    if (s->psz_url != NULL)
+    {   /* Backward compatibility hack: Lua scripts expect the URI scheme and
+         * the rest of the URI separately. */
+        const char *p = strstr(s->psz_url, "://");
+        if (p != NULL)
+        {
+            sys->access = strndup(s->psz_url, p - s->psz_url);
+            sys->path = p + 3;
+        }
     }
 
-    if( lua_pcall( L, 0, 1, 0 ) )
+    int ret = vlclua_scripts_batch_execute(VLC_OBJECT(s), "playlist",
+                                           probe_luascript, NULL);
+    if (ret != VLC_SUCCESS)
     {
-        msg_Warn( p_demux, "Error while running script %s, "
-                  "function parse(): %s", psz_filename,
-                  lua_tostring( L, lua_gettop( L ) ) );
-        return VLC_DEMUXER_EGENERIC;
+        free(sys->access);
+        free(sys);
+        return ret;
     }
 
-    if( lua_gettop( L ) )
-        vlclua_playlist_add_internal( p_demux, L, p_current_input );
-    else
-        msg_Err( p_demux, "Script went completely foobar" );
-
-    return VLC_DEMUXER_EOF;
+    s->pf_readdir = ReadDir;
+    s->pf_control = access_vaDirectoryControlHelper;
+    return VLC_SUCCESS;
 }
 
-static int Control( demux_t *p_demux, int i_query, va_list args )
+void Close_LuaPlaylist(vlc_object_t *obj)
 {
-    VLC_UNUSED(p_demux); VLC_UNUSED(i_query); VLC_UNUSED(args);
-    return VLC_EGENERIC;
+    stream_t *s = (stream_t *)obj;
+    struct vlclua_playlist *sys = s->p_sys;
+
+    free(sys->filename);
+    assert(sys->L != NULL);
+    lua_close(sys->L);
+    free(sys->access);
+    free(sys);
 }
diff --git a/modules/lua/vlc.c b/modules/lua/vlc.c
index ed95ac039b..441113fe61 100644
--- a/modules/lua/vlc.c
+++ b/modules/lua/vlc.c
@@ -147,7 +147,7 @@ vlc_module_begin ()
         add_shortcut( "luaplaylist" )
         set_shortname( N_("Lua Playlist") )
         set_description( N_("Lua Playlist Parser Interface") )
-        set_capability( "demux", 2 )
+        set_capability( "stream_filter", 2 )
         set_callbacks( Import_LuaPlaylist, Close_LuaPlaylist )
 
     add_submodule ()
@@ -543,66 +543,6 @@ out:
     return item;
 }
 
-#undef vlclua_playlist_add_internal
-void vlclua_playlist_add_internal(vlc_object_t *obj, lua_State *L,
-                                  input_item_t *parent)
-{
-    bool post = false;
-
-    /* playlist */
-    if (!lua_istable(L, -1))
-    {
-        msg_Warn(obj, "Playlist should be a table.");
-        return;
-    }
-
-    input_item_node_t *node = input_item_node_Create(parent);
-
-    lua_pushnil(L);
-
-    /* playlist nil */
-    while (lua_next(L, -2))
-    {
-        input_item_t *item = vlclua_read_input_item(obj, L);
-        if (item != NULL)
-        {
-            /* copy the original URL to the meta data,
-             * if "URL" is still empty */
-            char *url = input_item_GetURL(item);
-            if (url == NULL)
-            {
-                url = input_item_GetURI(parent);
-                if (likely(url != NULL))
-                {
-                    EnsureUTF8(url);
-                    msg_Dbg(obj, "meta-URL: %s", url);
-                    input_item_SetURL(item, url);
-                }
-            }
-            free(url);
-
-            input_item_CopyOptions(item, parent);
-
-            if (likely(node != NULL)) /* Add to node */
-                input_item_node_AppendItem(node, item);
-
-            input_item_Release(item);
-            post = true;
-        }
-        /* pop the value, keep the key for the next lua_next() call */
-        lua_pop(L, 1);
-    }
-    /* playlist */
-
-    if (likely(node != NULL))
-    {
-        if (post)
-            input_item_node_PostAndDelete(node);
-        else
-            input_item_node_Delete(node);
-    }
-}
-
 static int vlc_sd_probe_Open( vlc_object_t *obj )
 {
     vlc_dictionary_t name_d;
diff --git a/modules/lua/vlc.h b/modules/lua/vlc.h
index 7b979cd4f1..141f331329 100644
--- a/modules/lua/vlc.h
+++ b/modules/lua/vlc.h
@@ -182,9 +182,6 @@ void vlclua_read_custom_meta_data( vlc_object_t *, lua_State *,
 #define vlclua_read_custom_meta_data( a, b, c ) vlclua_read_custom_meta_data( VLC_OBJECT( a ), b, c )
 
 input_item_t *vlclua_read_input_item(vlc_object_t *, lua_State *);
-void vlclua_playlist_add_internal(vlc_object_t *, lua_State *, input_item_t *);
-#define vlclua_playlist_add_internal( a, b, c ) \
-        vlclua_playlist_add_internal( VLC_OBJECT( a ), b, c )
 
 int vlclua_add_modules_path( lua_State *, const char *psz_filename );
 



More information about the vlc-commits mailing list