vlc | branch: master | Rémi Denis-Courmont <[email protected]> | 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 ); _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
