Commit e10d4311 authored by Antoine Cellerier's avatar Antoine Cellerier

Port the http interface to the Lua Interface Module framework.

 * share/luaintf/http.lua: Equivalent of the legacy modules/control/http/
   module. (The new module takes 272 lines of Lua, instead of 5475 lines for
   the old one.) Functionality is basically the same except for CGI support
   which is missing.
 * share/http-lua/: The HTML files using the new <?vlc [lua code] ?> syntax.
 * modules/misc/lua/: Add Lua bindings for a few VLC function, the most
   important being the HTTPd high level functions, ACLs, stat and opendir.

The Lua code still needs to be cleaned up a bit.
parent 050188ce
......@@ -441,6 +441,38 @@ VLC-release.app: vlc
for i in $(srcdir)/share/luaintf/modules/*.* ; do \
$(INSTALL) -m 644 $${i} $(top_builddir)/VLC-release.app/Contents/MacOS/share/luaintf/modules/`basename $${i}` ; \
done ; \
$(INSTALL) -d $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/dialogs
$(INSTALL) -d $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/js
$(INSTALL) -d $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/old
$(INSTALL) -d $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/old/admin
$(INSTALL) -d $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/old/vlm
$(INSTALL) -d $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/images
$(INSTALL) -d $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/requests
for i in $(srcdir)/share/http-lua/*.* ; do \
$(INSTALL) -m 644 $${i} $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/`basename $${i}` ; \
done ; \
for i in $(srcdir)/share/http-lua/dialogs/* ; do \
$(INSTALL) -m 644 $${i} $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/dialogs/`basename $${i}` ; \
done ; \
for i in $(srcdir)/share/http-lua/js/*.* ; do \
$(INSTALL) -m 644 $${i} $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/js/`basename $${i}` ; \
done ; \
for i in $(srcdir)/share/http-lua/old/*.* ; do \
$(INSTALL) -m 644 $${i} $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/old/`basename $${i}` ; \
done ; \
for i in $(srcdir)/share/http-lua/old/admin/*.* ; do \
$(INSTALL) -m 644 $${i} $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/old/admin/`basename $${i}` ; \
done ; \
for i in $(srcdir)/share/http-lua/old/vlm/*.* ; do \
$(INSTALL) -m 644 $${i} $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/old/vlm/`basename $${i}` ; \
done ; \
for i in $(srcdir)/share/http-lua/images/*.* ; do \
$(INSTALL) -m 644 $${i} $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/images/`basename $${i}` ; \
done ; \
for i in $(srcdir)/share/http-lua/requests/*.* ; do \
$(INSTALL) -m 644 $${i} $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/requests/`basename $${i}` ; \
done ; \
$(INSTALL) -m 644 $(srcdir)/share/http-lua/requests/readme $(top_builddir)/VLC-release.app/Contents/MacOS/share/http-lua/requests/readme.txt
$(INSTALL) -d $(top_builddir)/VLC-release.app/Contents/MacOS/share/http/dialogs
$(INSTALL) -d $(top_builddir)/VLC-release.app/Contents/MacOS/share/http/js
$(INSTALL) -d $(top_builddir)/VLC-release.app/Contents/MacOS/share/http/old
......@@ -646,6 +678,43 @@ package-win-common:
|| true ; \
done
mkdir -p "$(top_builddir)/vlc-${VERSION}/http-lua/images"
mkdir -p "$(top_builddir)/vlc-${VERSION}/http-lua/requests"
mkdir -p "$(top_builddir)/vlc-${VERSION}/http-lua/js"
mkdir -p "$(top_builddir)/vlc-${VERSION}/http-lua/dialogs"
mkdir -p "$(top_builddir)/vlc-${VERSION}/http-lua/old"
mkdir -p "$(top_builddir)/vlc-${VERSION}/http-lua/old/vlm"
mkdir -p "$(top_builddir)/vlc-${VERSION}/http-lua/old/admin"
cp $(srcdir)/share/http-lua/*.html $(top_builddir)/vlc-${VERSION}/http-lua/ ;
unix2dos $(top_builddir)/vlc-${VERSION}/http-lua/*.html ;
cp $(srcdir)/share/http-lua/.hosts $(top_builddir)/vlc-${VERSION}/http-lua/ ;
unix2dos $(top_builddir)/vlc-${VERSION}/http-lua/.hosts ;
cp $(srcdir)/share/http-lua/*.css $(top_builddir)/vlc-${VERSION}/http-lua/ ;
unix2dos $(top_builddir)/vlc-${VERSION}/http-lua/*.css ;
cp $(srcdir)/share/http-lua/js/*.js $(top_builddir)/vlc-${VERSION}/http-lua/js/ ;
unix2dos $(top_builddir)/vlc-${VERSION}/http-lua/js/*.js ;
cp $(srcdir)/share/http-lua/dialogs/* $(top_builddir)/vlc-${VERSION}/http-lua/dialogs/ ;
unix2dos $(top_builddir)/vlc-${VERSION}/http-lua/dialogs/* ;
cp $(srcdir)/share/http-lua/dialogs/.hosts $(top_builddir)/vlc-${VERSION}/http-lua/dialogs/ ;
unix2dos $(top_builddir)/vlc-${VERSION}/http-lua/dialogs/.hosts ;
cp $(srcdir)/share/http-lua/*.ico $(top_builddir)/vlc-${VERSION}/http-lua/ ;
cp $(srcdir)/share/http-lua/images/*.png $(top_builddir)/vlc-${VERSION}/http-lua/images/
cp $(srcdir)/share/http-lua/requests/*.xml $(top_builddir)/vlc-${VERSION}/http-lua/requests/ ;
unix2dos $(top_builddir)/vlc-${VERSION}/http-lua/requests/*.xml ;
cp $(srcdir)/share/http-lua/requests/readme $(top_builddir)/vlc-${VERSION}/http-lua/requests/readme.txt ;
unix2dos $(top_builddir)/vlc-${VERSION}/http-lua/requests/readme.txt ;
cp $(srcdir)/share/http-lua/old/*.html $(top_builddir)/vlc-${VERSION}/http-lua/old/ ;
unix2dos $(top_builddir)/vlc-${VERSION}/http-lua/old/*.html ;
cp $(srcdir)/share/http-lua/old/*.css $(top_builddir)/vlc-${VERSION}/http-lua/old/ ;
cp $(srcdir)/share/http-lua/old/.hosts $(top_builddir)/vlc-${VERSION}/http-lua/old/ ;
cp $(srcdir)/share/http-lua/old/*.png $(top_builddir)/vlc-${VERSION}/http-lua/old/ ;
cp $(srcdir)/share/http-lua/old/vlm/*.html $(top_builddir)/vlc-${VERSION}/http-lua/old/vlm/ ;
unix2dos $(top_builddir)/vlc-${VERSION}/http-lua/old/vlm/*.html ;
cp $(srcdir)/share/http-lua/old/admin/*.html $(top_builddir)/vlc-${VERSION}/http-lua/old/admin/ ;
unix2dos $(top_builddir)/vlc-${VERSION}/http-lua/old/admin/*.html ;
cp $(srcdir)/share/http-lua/old/admin/.access $(top_builddir)/vlc-${VERSION}/http-lua/old/admin/ ;
mkdir -p "$(top_builddir)/vlc-${VERSION}/http/images"
mkdir -p "$(top_builddir)/vlc-${VERSION}/http/requests"
mkdir -p "$(top_builddir)/vlc-${VERSION}/http/js"
......
SOURCES_lua = playlist.c meta.c intf.c vlc.c vlc.h callbacks.c objects.c variables.c configuration.c net.c vlm.c
SOURCES_lua = playlist.c meta.c intf.c vlc.c vlc.h callbacks.c objects.c variables.c configuration.c net.c vlm.c httpd.c acl.c
/*****************************************************************************
* acl.c: Access list related functions
*****************************************************************************
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Authors: Antoine Cellerier <dionoea at videolan tod 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.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
#include <vlc/vlc.h>
#include <vlc_acl.h>
#include <lua.h> /* Low level lua C API */
#include <lauxlib.h> /* Higher level C API */
#include <lualib.h> /* Lua libs */
#include "vlc.h"
/*****************************************************************************
*
*****************************************************************************/
int vlclua_acl_create( lua_State *L )
{
vlc_object_t *p_this = vlclua_get_this( L );
vlc_bool_t b_allow = luaL_checkboolean( L, 1 ) ? VLC_TRUE : VLC_FALSE;
vlc_acl_t *p_acl = ACL_Create( p_this, b_allow );
if( !p_acl )
return luaL_error( L, "ACL creation failed." );
lua_pushlightuserdata( L, p_acl ); /* FIXME */
return 1;
}
int vlclua_acl_delete( lua_State *L )
{
vlc_acl_t *p_acl = (vlc_acl_t*)luaL_checklightuserdata( L, 1 );
ACL_Destroy( p_acl );
return 0;
}
int vlclua_acl_check( lua_State *L )
{
vlc_acl_t *p_acl = (vlc_acl_t*)luaL_checklightuserdata( L, 1 );
const char *psz_ip = luaL_checkstring( L, 2 );
lua_pushinteger( L, ACL_Check( p_acl, psz_ip ) );
return 1;
}
int vlclua_acl_duplicate( lua_State *L )
{
vlc_object_t *p_this = vlclua_get_this( L );
vlc_acl_t *p_acl = (vlc_acl_t*)luaL_checklightuserdata( L, 1 );
vlc_acl_t *p_acl_new = ACL_Duplicate( p_this, p_acl );
lua_pushlightuserdata( L, p_acl_new );
return 1;
}
int vlclua_acl_add_host( lua_State *L )
{
vlc_acl_t *p_acl = (vlc_acl_t*)luaL_checklightuserdata( L, 1 );
const char *psz_ip = luaL_checkstring( L, 2 );
vlc_bool_t b_allow = luaL_checkboolean( L, 3 ) ? VLC_TRUE : VLC_FALSE;
lua_pushinteger( L, ACL_AddHost( p_acl, psz_ip, b_allow ) );
return 1;
}
int vlclua_acl_add_net( lua_State *L )
{
vlc_acl_t *p_acl = (vlc_acl_t*)luaL_checklightuserdata( L, 1 );
const char *psz_ip = luaL_checkstring( L, 2 );
int i_len = luaL_checkint( L, 3 );
vlc_bool_t b_allow = luaL_checkboolean( L, 4 ) ? VLC_TRUE : VLC_FALSE;
lua_pushinteger( L, ACL_AddNet( p_acl, psz_ip, i_len, b_allow ) );
return 1;
}
int vlclua_acl_load_file( lua_State *L )
{
vlc_acl_t *p_acl = (vlc_acl_t*)luaL_checklightuserdata( L, 1 );
const char *psz_path = luaL_checkstring( L, 2 );
lua_pushinteger( L, ACL_LoadFile( p_acl, psz_path ) );
return 1;
}
......@@ -159,7 +159,7 @@ int vlclua_add_callback( lua_State *L )
* the function in the stack to nil) */
p_callback->i_index = i_index;
p_callback->i_type = var_Type( p_obj, psz_var );
p_callback->L = lua_newthread( L );
p_callback->L = lua_newthread( L ); /* Do we have to keep a reference to this thread somewhere to prevent garbage collection? */
var_AddCallback( p_obj, psz_var, vlclua_callback, p_callback );
return 0;
......
/*****************************************************************************
* httpd.c: HTTPd wrapper
*****************************************************************************
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Authors: Antoine Cellerier <dionoea at videolan tod 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.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
#include <vlc/vlc.h>
#include <vlc_httpd.h>
#include <lua.h> /* Low level lua C API */
#include <lauxlib.h> /* Higher level C API */
#include <lualib.h> /* Lua libs */
#include "vlc.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static uint8_t *vlclua_todata( lua_State *L, int narg, int *i_data );
/*****************************************************************************
* HTTPD Host
*****************************************************************************/
#if 0
/* This is kind of a useless function since TLS with the 4 last args
* unset does the same thing as far as I know. */
int vlclua_httpd_host_new( lua_State *L )
{
vlc_object_t *p_this = vlclua_get_this( L );
const char *psz_host = luaL_checkstring( L, 1 );
int i_port = luaL_checkint( L, 2 );
httpd_host_t *p_httpd_host = httpd_HostNew( p_this, psz_host, i_port );
if( !p_httpd_host )
return luaL_error( L, "Failed to create HTTP host \"%s:%d\".",
psz_host, i_port );
vlclua_push_vlc_object( L, p_httpd_host, vlclua_httpd_host_delete );
return 1;
}
#endif
int vlclua_httpd_tls_host_new( lua_State *L )
{
vlc_object_t *p_this = vlclua_get_this( L );
const char *psz_host = luaL_checkstring( L, 1 );
int i_port = luaL_checkint( L, 2 );
const char *psz_cert = luaL_optstring( L, 3, NULL );
const char *psz_key = luaL_optstring( L, 4, NULL );
const char *psz_ca = luaL_optstring( L, 5, NULL );
const char *psz_crl = luaL_optstring( L, 6, NULL );
httpd_host_t *p_httpd_host = httpd_TLSHostNew( p_this, psz_host, i_port,
psz_cert, psz_key,
psz_ca, psz_crl );
if( !p_httpd_host )
return luaL_error( L, "Failed to create HTTP TLS host \"%s:%d\" "
"(cert: \"%s\", key: \"%s\", ca: \"%s\", "
"crl: \"%s\").", psz_host, i_port,
psz_cert, psz_key, psz_ca, psz_crl );
vlclua_push_vlc_object( L, (vlc_object_t*)p_httpd_host, vlclua_httpd_host_delete );
return 1;
}
#define ARG_1_IS_HTTPD_HOST httpd_host_t *p_httpd_host = \
(httpd_host_t*)vlclua_checkobject( L, 1, VLC_OBJECT_HTTPD_HOST );
int vlclua_httpd_host_delete( lua_State *L )
{
ARG_1_IS_HTTPD_HOST
httpd_HostDelete( p_httpd_host );
return 0;
}
/*****************************************************************************
* HTTPd Handler
*****************************************************************************/
struct httpd_handler_sys_t
{
lua_State *L;
int ref;
};
static int vlclua_httpd_handler_callback(
httpd_handler_sys_t *p_sys, httpd_handler_t *p_handler, char *psz_url,
uint8_t *psz_request, int i_type, uint8_t *p_in, int i_in,
char *psz_remote_addr, char *psz_remote_host,
uint8_t **pp_data, int *pi_data )
{
lua_State *L = p_sys->L;
/* function data */
lua_pushvalue( L, 1 );
lua_pushvalue( L, 2 );
/* function data function data */
lua_pushstring( L, psz_url );
/* function data function data url */
lua_pushstring( L, (const char *)psz_request );
/* function data function data url request */
lua_pushinteger( L, i_type ); /* Q: what does i_type stand for? */
/* function data function data url request type */
lua_pushlstring( L, (const char *)p_in, i_in ); /* Q: what do p_in contain? */
/* function data function data url request type in */
lua_pushstring( L, psz_remote_addr );
/* function data function data url request type in addr */
lua_pushstring( L, psz_remote_host );
/* function data function data url request type in addr host */
if( lua_pcall( L, 7, 1, 0 ) )
{
/* function data err */
vlc_object_t *p_this = vlclua_get_this( L );
const char *psz_err = lua_tostring( L, -1 );
msg_Err( p_this, "Error while runing the lua HTTPd handler "
"callback: %s", psz_err );
lua_settop( L, 2 );
/* function data */
return VLC_EGENERIC;
}
/* function data outdata */
*pp_data = vlclua_todata( L, -1, pi_data );
lua_pop( L, 1 );
/* function data */
return VLC_SUCCESS;
}
int vlclua_httpd_handler_new( lua_State * L )
{
ARG_1_IS_HTTPD_HOST
const char *psz_url = luaL_checkstring( L, 2 );
const char *psz_user = luaL_nilorcheckstring( L, 3 );
const char *psz_password = luaL_nilorcheckstring( L, 4 );
const vlc_acl_t *p_acl = NULL; /* FIXME 5 */
/* Stack item 6 is the callback function */
luaL_argcheck( L, lua_isfunction( L, 6 ), 6, "Should be a function" );
/* Stack item 7 is the callback data */
lua_settop( L, 7 );
httpd_handler_sys_t *p_sys = (httpd_handler_sys_t*)
malloc( sizeof( httpd_handler_sys_t ) );
if( !p_sys )
return luaL_error( L, "Failed to allocate private buffer." );
p_sys->L = lua_newthread( L );
p_sys->ref = luaL_ref( L, LUA_REGISTRYINDEX ); /* pops the object too */
/* use lua_xmove to move the lua callback function and data to
* the callback's stack. */
lua_xmove( L, p_sys->L, 2 );
httpd_handler_t *p_handler = httpd_HandlerNew(
p_httpd_host, psz_url, psz_user, psz_password,
p_acl, vlclua_httpd_handler_callback, p_sys );
if( !p_handler )
return luaL_error( L, "Failed to create HTTPd handler." );
lua_pushlightuserdata( L, p_handler ); /* FIXME */
return 1;
}
int vlclua_httpd_handler_delete( lua_State *L )
{
httpd_handler_t *p_handler = (httpd_handler_t*)luaL_checklightuserdata( L, 1 ); /* FIXME */
httpd_handler_sys_t *p_sys = httpd_HandlerDelete( p_handler );
luaL_unref( p_sys->L, LUA_REGISTRYINDEX, p_sys->ref );
free( p_sys );
return 0;
}
/*****************************************************************************
* HTTPd File
*****************************************************************************/
struct httpd_file_sys_t
{
lua_State *L;
int ref;
};
static int vlclua_httpd_file_callback(
httpd_file_sys_t *p_sys, httpd_file_t *p_file, uint8_t *psz_request,
uint8_t **pp_data, int *pi_data )
{
lua_State *L = p_sys->L;
/* function data */
lua_pushvalue( L, 1 );
lua_pushvalue( L, 2 );
/* function data function data */
lua_pushstring( L, (const char *)psz_request );
/* function data function data request */
if( lua_pcall( L, 2, 1, 0 ) )
{
/* function data err */
vlc_object_t *p_this = vlclua_get_this( L );
const char *psz_err = lua_tostring( L, -1 );
msg_Err( p_this, "Error while runing the lua HTTPd file callback: %s",
psz_err );
lua_settop( L, 2 );
/* function data */
return VLC_EGENERIC;
}
/* function data outdata */
*pp_data = vlclua_todata( L, -1, pi_data );
lua_pop( L, 1 );
/* function data */
return VLC_SUCCESS;
}
int vlclua_httpd_file_new( lua_State *L )
{
ARG_1_IS_HTTPD_HOST
const char *psz_url = luaL_checkstring( L, 2 );
const char *psz_mime = luaL_nilorcheckstring( L, 3 );
const char *psz_user = luaL_nilorcheckstring( L, 4 );
const char *psz_password = luaL_nilorcheckstring( L, 5 );
const vlc_acl_t *p_acl = lua_isnil( L, 6 ) ? NULL : luaL_checklightuserdata( L, 6 );
/* Stack item 7 is the callback function */
luaL_argcheck( L, lua_isfunction( L, 7 ), 7, "Should be a function" );
/* Stack item 8 is the callback data */
httpd_file_sys_t *p_sys = (httpd_file_sys_t *)
malloc( sizeof( httpd_file_sys_t ) );
if( !p_sys )
return luaL_error( L, "Failed to allocate private buffer." );
p_sys->L = lua_newthread( L );
p_sys->ref = luaL_ref( L, LUA_REGISTRYINDEX ); /* pops the object too */
lua_xmove( L, p_sys->L, 2 );
httpd_file_t *p_file = httpd_FileNew( p_httpd_host, psz_url, psz_mime,
psz_user, psz_password, p_acl,
vlclua_httpd_file_callback, p_sys );
if( !p_file )
return luaL_error( L, "Failed to create HTTPd file." );
lua_pushlightuserdata( L, p_file ); /* FIXME */
return 1;
}
int vlclua_httpd_file_delete( lua_State *L )
{
httpd_file_t *p_file = (httpd_file_t*)luaL_checklightuserdata( L, 1 ); /* FIXME */
/* FIXME: How do we delete p_sys ? the struct is hidden in the VLC core */
httpd_file_sys_t *p_sys = httpd_FileDelete( p_file );
luaL_unref( p_sys->L, LUA_REGISTRYINDEX, p_sys->ref );
free( p_sys );
return 0;
}
/*****************************************************************************
* HTTPd Redirect
*****************************************************************************/
int vlclua_httpd_redirect_new( lua_State *L )
{
ARG_1_IS_HTTPD_HOST
const char *psz_url_dst = luaL_checkstring( L, 2 );
const char *psz_url_src = luaL_checkstring( L, 3 );
httpd_redirect_t *p_redirect = httpd_RedirectNew( p_httpd_host,
psz_url_dst,
psz_url_src );
if( !p_redirect )
return luaL_error( L, "Failed to create HTTPd redirect." );
lua_pushlightuserdata( L, p_redirect ); /* FIXME */
return 1;
}
int vlclua_httpd_redirect_delete( lua_State *L )
{
httpd_redirect_t *p_redirect = (httpd_redirect_t*)luaL_checklightuserdata( L, 1 ); /* FIXME */
httpd_RedirectDelete( p_redirect );
return 0;
}
/*****************************************************************************
* Utils
*****************************************************************************/
static uint8_t *vlclua_todata( lua_State *L, int narg, int *pi_data )
{
size_t i_data;
const char *psz_data = lua_tolstring( L, narg, &i_data );
uint8_t *p_data = (uint8_t*)malloc( i_data * sizeof(uint8_t) );
*pi_data = (int)i_data;
if( !p_data )
{
luaL_error( L, "Error while allocating buffer." );
return NULL; /* To please gcc even though luaL_error longjmp-ed out of here */
}
memcpy( p_data, psz_data, i_data );
return p_data;
}
......@@ -122,7 +122,7 @@ static int vlclua_input_info( lua_State *L )
int i_cat;
int i;
if( !p_input ) return vlclua_error( L );
vlc_mutex_lock( &input_GetItem(p_input)->lock );
//vlc_mutex_lock( &input_GetItem(p_input)->lock );
i_cat = input_GetItem(p_input)->i_categories;
lua_createtable( L, 0, i_cat );
for( i = 0; i < i_cat; i++ )
......@@ -141,7 +141,7 @@ static int vlclua_input_info( lua_State *L )
}
lua_settable( L, -3 );
}
vlc_object_release( p_input );
//vlc_object_release( p_input );
return 1;
}
......@@ -165,6 +165,36 @@ static int vlclua_get_title( lua_State *L )
return 1;
}
static int vlclua_input_stats( lua_State *L )
{
input_thread_t *p_input = vlclua_get_input_internal( L );
input_item_t *p_item = p_input && p_input->p ? input_GetItem( p_input ) : NULL;
lua_newtable( L );
if( p_item )
{
#define STATS_INT( n ) lua_pushinteger( L, p_item->p_stats->i_ ## n ); \
lua_setfield( L, -2, #n );
#define STATS_FLOAT( n ) lua_pushnumber( L, p_item->p_stats->f_ ## n ); \
lua_setfield( L, -2, #n );
STATS_INT( read_bytes )
STATS_FLOAT( input_bitrate )
STATS_INT( demux_read_bytes )
STATS_FLOAT( demux_bitrate )
STATS_INT( decoded_video )
STATS_INT( displayed_pictures )
STATS_INT( lost_pictures )
STATS_INT( decoded_audio )
STATS_INT( played_abuffers )
STATS_INT( lost_abuffers )
STATS_INT( sent_packets )
STATS_INT( sent_bytes )
STATS_FLOAT( send_bitrate )
#undef STATS_INT
#undef STATS_FLOAT
}
return 1;
}
/*****************************************************************************
* Vout control
*****************************************************************************/
......@@ -454,7 +484,10 @@ static int vlclua_playlist_get( lua_State *L )
lua_setfield( L, -2, "name" );
lua_pushstring( L, p_input->psz_uri );
lua_setfield( L, -2, "path" );
lua_pushnumber( L, ((double)p_input->i_duration)*1e-6 );
if( p_input->i_duration < 0 )
lua_pushnumber( L, -1 );
else
lua_pushnumber( L, ((double)p_input->i_duration)*1e-6 );
lua_setfield( L, -2, "duration" );
lua_pushinteger( L, p_input->i_nb_played );
lua_setfield( L, -2, "nb_played" );
......@@ -476,15 +509,16 @@ static int vlclua_playlist_status( lua_State *L )
{
intf_thread_t *p_intf = (intf_thread_t *)vlclua_get_this( L );
playlist_t *p_playlist = pl_Yield( p_intf );
/*
int i_count = 0;
lua_settop( L, 0 );
lua_settop( L, 0 );*/
if( p_playlist->p_input )
{
char *psz_uri =
/*char *psz_uri =
input_item_GetURI( input_GetItem( p_playlist->p_input ) );
lua_pushstring( L, psz_uri );
free( psz_uri );
lua_pushnumber( L, config_GetInt( p_intf, "volume" ) );
lua_pushnumber( L, config_GetInt( p_intf, "volume" ) );*/
vlc_mutex_lock( &p_playlist->object_lock );
switch( p_playlist->status.i_status )
{
......@@ -492,7 +526,7 @@ static int vlclua_playlist_status( lua_State *L )
lua_pushstring( L, "stopped" );
break;
case PLAYLIST_RUNNING:
lua_pushstring( L, "running" );
lua_pushstring( L, "playing" );
break;
case PLAYLIST_PAUSED:
lua_pushstring( L, "paused" );
......@@ -502,10 +536,14 @@ static int vlclua_playlist_status( lua_State *L )
break;
}
vlc_mutex_unlock( &p_playlist->object_lock );
i_count += 3;
/*i_count += 3;*/
}
else
{
lua_pushstring( L, "stopped" );
}
vlc_object_release( p_playlist );
return i_count;