[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