1 /*****************************************************************************
2 * vlc_internal.c: vlcinternal python binding module
3 *****************************************************************************
4 * Copyright (C) 2006 the VideoLAN team
7 * Authors: Olivier Aubert <oaubert at bat710.univ-lyon1.fr>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 #include "vlc_internal.h"
25 #include "../../src/libvlc.h"
27 /**************************************************************************
29 **************************************************************************/
31 #ifndef vlcinternalMODINIT_FUNC /* declarations for DLL import/export */
32 #define vlcinternalMODINIT_FUNC void
35 static PyMethodDef vlcinternal_methods[] = {
36 { NULL } /* Sentinel */
39 vlcinternalMODINIT_FUNC
40 initvlcinternal( void )
44 p_module = Py_InitModule3( "vlcinternal", vlcinternal_methods,
45 "VLC media player internal module" );
50 if( PyType_Ready( &vlcObject_Type ) < 0 )
54 Py_INCREF( &vlcObject_Type );
55 PyModule_AddObject( p_module, "Object",
56 ( PyObject * )&vlcObject_Type );
60 /* Make libpostproc happy... */
61 void * fast_memcpy( void * to, const void * from, size_t len )
63 return memcpy( to, from, len );
66 /*****************************************************************************
67 * VLCObject implementation
68 *****************************************************************************/
71 *vlcObject_new( PyTypeObject *p_type, PyObject *p_args, PyObject *p_kwds )
74 vlc_object_t *p_object;
77 self = PyObject_New( vlcObject, &vlcObject_Type );
79 if( !PyArg_ParseTuple( p_args, "i", &i_id ) )
82 /* Maybe we were already initialized */
83 p_object = ( vlc_object_t* )vlc_current_object( i_id );
87 /* Try to initialize */
91 PyErr_SetString( PyExc_StandardError, "Unable to create a VLC instance." );
94 p_object = ( vlc_object_t* )vlc_current_object( i_id );
99 PyErr_SetString( PyExc_StandardError, "Unable to get object." );
103 self->p_object = p_object;
104 self->b_released = 0;
106 Py_INCREF( self ); /* Ah bon ? */
107 return ( PyObject * )self;
111 vlcObject_release( PyObject *self, PyObject *p_args )
113 if( (vlcObject*)self->b_released == 0 )
115 vlc_object_release( VLCOBJ(self) );
116 (vlcObject*)self->b_released = 1;
118 Py_INCREF( Py_None );
123 vlcObject_dealloc( PyObject *self )
125 vlcObject_release( self, NULL );
126 PyObject_DEL( self );
130 vlcObject_find_object( PyObject *self, PyObject *args )
137 if( !PyArg_ParseTuple( args, "s", &psz_name ) )
141 ( aout, decoder, input, httpd, intf, playlist, root, vlc, vout )
143 if( !strncmp( psz_name, "aout", 4 ) )
145 i_object_type = VLC_OBJECT_AOUT;
147 else if (! strncmp( psz_name, "decoder", 7 ) )
149 i_object_type = VLC_OBJECT_DECODER;
151 else if (! strncmp( psz_name, "httpd", 5 ) )
153 i_object_type = VLC_OBJECT_HTTPD;
155 else if (! strncmp( psz_name, "intf", 4 ) )
157 i_object_type = VLC_OBJECT_INTF;
159 else if (! strncmp( psz_name, "input", 5 ) )
161 i_object_type = VLC_OBJECT_INPUT;
163 else if (! strncmp( psz_name, "playlist", 8 ) )
165 i_object_type = VLC_OBJECT_PLAYLIST;
167 else if (! strncmp( psz_name, "libvlc", 6 ) )
169 i_object_type = VLC_OBJECT_LIBVLC;
171 else if (! strncmp( psz_name, "vout", 4 ) )
173 i_object_type = VLC_OBJECT_VOUT;
175 else if (! strncmp( psz_name, "sout", 4 ) )
177 i_object_type = VLC_OBJECT_SOUT;
179 else if (! strncmp( psz_name, "global", 6 ) )
181 i_object_type = VLC_OBJECT_GLOBAL;
183 else if (! strncmp( psz_name, "packetizer", 10 ) )
185 i_object_type = VLC_OBJECT_PACKETIZER;
187 else if (! strncmp( psz_name, "encoder", 7 ) )
189 i_object_type = VLC_OBJECT_ENCODER;
191 else if (! strncmp( psz_name, "vlm", 3 ) )
193 i_object_type = VLC_OBJECT_VLM;
195 else if (! strncmp( psz_name, "announce", 8 ) )
197 i_object_type = VLC_OBJECT_ANNOUNCE;
199 else if (! strncmp( psz_name, "demux", 5 ) )
201 i_object_type = VLC_OBJECT_DEMUX;
203 else if (! strncmp( psz_name, "access", 6 ) )
205 i_object_type = VLC_OBJECT_ACCESS;
207 else if (! strncmp( psz_name, "stream", 6 ) )
209 i_object_type = VLC_OBJECT_STREAM;
211 else if (! strncmp( psz_name, "filter", 6 ) )
213 i_object_type = VLC_OBJECT_FILTER;
215 else if (! strncmp( psz_name, "vod", 3 ) )
217 i_object_type = VLC_OBJECT_VOD;
219 else if (! strncmp( psz_name, "xml", 3 ) )
221 i_object_type = VLC_OBJECT_XML;
223 else if (! strncmp( psz_name, "osdmenu", 7 ) )
225 i_object_type = VLC_OBJECT_OSDMENU;
227 else if (! strncmp( psz_name, "stats", 5 ) )
229 i_object_type = VLC_OBJECT_STATS;
231 else if (! strncmp( psz_name, "metaengine", 10 ) )
233 i_object_type = VLC_OBJECT_META_ENGINE;
237 /* FIXME: raise an exception ? */
238 Py_INCREF( Py_None );
242 p_obj = vlc_object_find( VLCOBJ(self), i_object_type, FIND_ANYWHERE );
246 Py_INCREF( Py_None );
250 p_retval = PyObject_New( vlcObject, &vlcObject_Type );
252 p_retval->p_object = p_obj;
254 return ( PyObject * )p_retval;
258 vlcObject_find_name( PyObject *self, PyObject *args )
264 if( !PyArg_ParseTuple( args, "s", &psz_name ) )
267 p_obj = vlc_object_find_name( VLCOBJ(self), psz_name, FIND_ANYWHERE );
271 Py_INCREF( Py_None );
275 p_retval = PyObject_New( vlcObject, &vlcObject_Type );
277 p_retval->p_object = p_obj;
279 return ( PyObject * )p_retval;
283 vlcObject_info( PyObject *self, PyObject *args )
287 vlc_object_internals_t *p_priv;
289 p_obj = VLCOBJ(self);
290 p_priv = vlc_internals( p_obj );
292 /* Return information about the object as a dict. */
293 p_retval = PyDict_New();
295 PyDict_SetItemString( p_retval, "object-id",
296 Py_BuildValue( "l", p_obj->i_object_id ) );
297 PyDict_SetItemString( p_retval, "object-type",
298 Py_BuildValue( "s", p_obj->psz_object_type ) );
299 PyDict_SetItemString( p_retval, "object-name",
300 Py_BuildValue( "s", p_obj->psz_object_name ) );
301 PyDict_SetItemString( p_retval, "thread",
302 PyBool_FromLong( p_priv->b_thread ) );
303 PyDict_SetItemString( p_retval, "thread-id",
304 PyLong_FromLongLong( p_priv->thread_id ) );
305 PyDict_SetItemString( p_retval, "refcount",
306 PyInt_FromLong( p_priv->i_refcount ) );
311 vlcObject_find_id( PyObject *self, PyObject *args )
314 vlc_object_t* p_object;
317 if( !PyArg_ParseTuple( args, "i", &i_id ) )
320 p_object = ( vlc_object_t* )vlc_current_object( i_id );
324 Py_INCREF( Py_None );
328 p_retval = PyObject_NEW( vlcObject, &vlcObject_Type );
330 p_retval->p_object = p_object;
332 return ( PyObject * )p_retval;
335 /* Do a var_Get call on the object. Parameter: the variable name. */
337 vlcObject_var_get( PyObject *self, PyObject *args )
344 if( !PyArg_ParseTuple( args, "s", &psz_name ) )
347 if( var_Get( VLCOBJ(self), psz_name, &value ) != VLC_SUCCESS )
349 PyErr_SetString( PyExc_StandardError,
350 "Error: variable does not exist.\n" );
354 i_type = var_Type ( VLCOBJ(self), psz_name );
359 p_retval = PyString_FromString( "A void variable" );
362 p_retval = PyBool_FromLong( value.b_bool );
364 case VLC_VAR_INTEGER :
365 p_retval = PyInt_FromLong( ( long )value.i_int );
367 case VLC_VAR_HOTKEY :
368 p_retval = PyString_FromFormat( "A hotkey variable ( %d )", value.i_int );
371 case VLC_VAR_STRING :
372 case VLC_VAR_DIRECTORY :
373 case VLC_VAR_VARIABLE :
374 p_retval = PyString_FromString( value.psz_string );
376 case VLC_VAR_MODULE :
377 p_retval = ( PyObject* )PyObject_New( vlcObject, &vlcObject_Type );
378 ( ( vlcObject* )p_retval )->p_object = value.p_object;
381 p_retval = PyFloat_FromDouble( ( double )value.f_float );
384 p_retval = PyLong_FromLongLong( value.i_time );
386 case VLC_VAR_ADDRESS :
387 p_retval = PyString_FromString( "A VLC address ( not handled yet )" );
390 p_retval = PyString_FromString( "A VLC list ( not handled yet )" );
393 p_retval = PyString_FromString( "A mutex" );
399 Py_INCREF( p_retval );
404 vlcObject_var_type( PyObject *self, PyObject *args )
410 if( !PyArg_ParseTuple( args, "s", &psz_name ) )
413 i_type = var_Type( VLCOBJ(self), psz_name );
418 p_retval = PyString_FromString( "Void" );
421 p_retval = PyString_FromString( "Boolean" );
423 case VLC_VAR_INTEGER :
424 p_retval = PyString_FromString( "Integer" );
426 case VLC_VAR_HOTKEY :
427 p_retval = PyString_FromString( "Hotkey" );
430 p_retval = PyString_FromString( "File" );
432 case VLC_VAR_STRING :
433 p_retval = PyString_FromString( "String" );
435 case VLC_VAR_DIRECTORY :
436 p_retval = PyString_FromString( "Directory" );
438 case VLC_VAR_VARIABLE :
439 p_retval = PyString_FromString( "Variable" );
441 case VLC_VAR_MODULE :
442 p_retval = PyString_FromString( "Module" );
445 p_retval = PyString_FromString( "Float" );
448 p_retval = PyString_FromString( "Time" );
450 case VLC_VAR_ADDRESS :
451 p_retval = PyString_FromString( "Address" );
454 p_retval = PyString_FromString( "List" );
457 p_retval = PyString_FromString( "Mutex" );
460 p_retval = PyString_FromString( "Unknown" );
465 /* Do a var_Set call on the object. Parameter: the variable name. */
467 vlcObject_var_set( PyObject *self, PyObject *args )
475 if( !PyArg_ParseTuple( args, "sO", &psz_name, &py_value ) )
478 p_obj = VLCOBJ(self);
479 i_type = var_Type( p_obj, psz_name );
486 value.b_bool = PyInt_AsLong( py_value );
488 case VLC_VAR_INTEGER :
489 case VLC_VAR_HOTKEY :
490 value.i_int = PyInt_AsLong( py_value );
493 case VLC_VAR_STRING :
494 case VLC_VAR_DIRECTORY :
495 case VLC_VAR_VARIABLE :
496 value.psz_string = strdup( PyString_AsString( py_value ) );
498 case VLC_VAR_MODULE :
499 /* FIXME: we should check the PyObject type and get its p_object */
500 value.p_object = ( ( vlcObject* )p_obj )->p_object;
503 value.f_float = PyFloat_AsDouble( py_value );
506 value.i_time = PyLong_AsLongLong( py_value );
508 case VLC_VAR_ADDRESS :
509 value.p_address = ( char* )PyLong_AsVoidPtr( py_value );
519 var_Set( p_obj, psz_name, value );
521 Py_INCREF( Py_None );
526 vlcObject_var_list( PyObject *self, PyObject *args )
531 vlc_object_internals_t *p_priv;
533 p_priv = vlc_internals( VLCOBJ(self) );
534 i_size = p_priv->i_vars;
535 p_retval = PyTuple_New( i_size );
538 for ( i_index = 0 ; i_index < i_size ; i_index++ )
540 PyTuple_SetItem( p_retval, i_index,
541 Py_BuildValue( "s", p_priv->p_vars[i_index].psz_name ) );
547 /* Do a config_Get call on the object. Parameter: the variable name. */
549 vlcObject_config_get( PyObject *self, PyObject *args )
554 module_config_t *p_config;
556 if( !PyArg_ParseTuple( args, "s", &psz_name ) )
559 p_config = config_FindConfig( VLCOBJ(self), psz_name );
563 PyErr_SetString( PyExc_StandardError,
564 "Error: config variable does not exist.\n" );
568 switch ( p_config->i_type )
570 case CONFIG_ITEM_BOOL :
571 p_retval = PyBool_FromLong( p_config->value.i );
573 case CONFIG_ITEM_INTEGER :
574 p_retval = PyInt_FromLong( ( long )p_config->value.i );
576 case CONFIG_ITEM_KEY :
577 p_retval = PyString_FromFormat( "A hotkey variable ( %d )", p_config->value.i );
579 case CONFIG_ITEM_FILE :
580 case CONFIG_ITEM_STRING :
581 case CONFIG_ITEM_DIRECTORY :
582 case CONFIG_ITEM_MODULE :
583 vlc_mutex_lock( p_config->p_lock );
584 if( p_config->value.psz )
585 p_retval = PyString_FromString( p_config->value.psz );
587 p_retval = PyString_FromString( "" );
588 vlc_mutex_unlock( p_config->p_lock );
590 p_retval = ( PyObject* )PyObject_New( vlcObject, &vlcObject_Type );
591 ( ( vlcObject* )p_retval )->p_object = value.p_object;
593 case CONFIG_ITEM_FLOAT :
594 p_retval = PyFloat_FromDouble( ( double )p_config->value.f );
598 Py_INCREF( p_retval );
604 /* Do a config_put* call on the object. Parameter: the variable name. */
606 vlcObject_config_set( PyObject *self, PyObject *args )
611 module_config_t *p_config;
614 if( !PyArg_ParseTuple( args, "sO", &psz_name, &py_value ) )
617 p_obj = VLCOBJ(self);
618 p_config = config_FindConfig( p_obj, psz_name );
622 PyErr_SetString( PyExc_StandardError,
623 "Error: option does not exist.\n" );
627 switch ( p_config->i_type )
629 case CONFIG_ITEM_BOOL :
630 case CONFIG_ITEM_INTEGER :
631 case CONFIG_ITEM_KEY :
632 config_PutInt( p_obj, psz_name, PyInt_AsLong( py_value ) );
634 case CONFIG_ITEM_FILE :
635 case CONFIG_ITEM_STRING :
636 case CONFIG_ITEM_DIRECTORY :
637 case CONFIG_ITEM_MODULE :
638 config_PutPsz( p_obj, psz_name, PyString_AsString( py_value ) );
640 case CONFIG_ITEM_FLOAT :
641 config_PutFloat( p_obj, psz_name, PyFloat_AsDouble( py_value ) );
644 Py_INCREF( Py_None );
649 vlcObject_children( PyObject *self, PyObject *args )
655 i_size = VLCOBJ(self)->i_children;
656 p_retval = PyTuple_New( i_size );
658 for ( i_index = 0 ; i_index < i_size ; i_index++ )
660 PyTuple_SetItem( p_retval, i_index, Py_BuildValue( "i",
661 VLCOBJ(self)->pp_children[i_index]->i_object_id ) );
669 static PyMethodDef vlcObject_methods[] =
671 { "get", vlcObject_var_get, METH_VARARGS,
672 "get( str ) -> value Get a variable value."},
673 { "set", vlcObject_var_set, METH_VARARGS,
674 "set( str, value ) Set a variable value" },
675 { "config_get", vlcObject_config_get, METH_VARARGS,
676 "config_get( str ) -> value Get a configuration option." },
677 { "config_set", vlcObject_config_set, METH_VARARGS,
678 "config_set( str, value ) Set a configuration option" },
679 { "type", vlcObject_var_type, METH_VARARGS,
680 "type( str ) -> str Get a variable type" },
681 { "list", vlcObject_var_list, METH_NOARGS,
682 "list( ) List the available variables" },
683 { "children", vlcObject_children, METH_NOARGS,
684 "children( ) List the children ids" },
685 { "find_object", vlcObject_find_object, METH_VARARGS,
686 "find_object( str ) -> Object Find the object of a given type.\n\nAvailable types are : aout, decoder, input, httpd, intf, playlist, root, vlc, vout"},
687 { "find_id", vlcObject_find_id, METH_VARARGS,
688 "find_id( int ) -> Object Find an object by id" },
689 { "find_name", vlcObject_find_name, METH_VARARGS,
690 "find_name( str ) -> Object Find an object by name" },
691 { "info", vlcObject_info, METH_NOARGS,
692 "info( ) -> dict Return information about the object" },
693 { "release", vlcObject_release, METH_NOARGS,
694 "release( ) -> Release the VLC Object" },
695 { NULL, NULL, 0, NULL },
698 static PyTypeObject vlcObject_Type =
700 PyObject_HEAD_INIT( NULL )
702 "vlc.Object", /*tp_name*/
703 sizeof( vlcObject_Type ), /*tp_basicsize*/
705 ( destructor )vlcObject_dealloc, /*tp_dealloc*/
712 0, /*tp_as_sequence*/
720 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
721 "Expose VLC object internal infrastructure.\n\nConstructor: vlc.Object(object_id)\n\nPLEASE BE AWARE that accessing internal features of VLC voids the guarantee for the product and is not advised except if you know what you are doing.", /* tp_doc */
724 0, /* tp_richcompare */
725 0, /* tp_weaklistoffset */
728 vlcObject_methods, /* tp_methods */
733 0, /* tp_descr_get */
734 0, /* tp_descr_set */
735 0, /* tp_dictoffset */
738 vlcObject_new, /* tp_new */