Commit be973dfb authored by Derk-Jan Hartman's avatar Derk-Jan Hartman

NOTE: libvlc API changes

* renamed VLC_Stop to VLC_CleanUp since this name is closer to what it actually does.
* added a new VLC_Stop that just does playlist_Stop analogous to VLC_Play and VLC_Pause.
* reordered the functions in libvlc. everything was mixed up.
* added doxygen info to all the functions
* fixed several functions to use the correct underlying API calls
* corrected the copyright info


This is in preparation of the new libvlc calls for mozilla plugin
temp. moved the playlist_command_t typedef to vlc_common.h awaiting implementation of playlist_Control()
parent 2d64aa5c
......@@ -27,6 +27,14 @@ Description: Streaming wizard
Finish the streaming wizard
Status: Assigned to zorglub
Task
Difficulty: Hard
Platform: WinCE
Urgency: Wishlist
Description: WinCE port
A WinCE port for PocketPC and the likes. (95% finished)
Status: Assigned to MixerAnderson
Task
Difficulty: Hard
Urgency: Normal
......@@ -240,6 +248,14 @@ Implement a system to
- Inform the user, without disturbing him. (Buffering stream)
Status: Todo
Task
Difficulty: Hard
Urgency: Wishlist
Platform: any
Description: Full H323 Videoconferencing
VLC isn't really suited for this yet, because it introduces quite large latencies. This should fixed before the H323 can ever come close to working in VLC.
Status: Todo
Task
Difficulty: Guru
Urgency: Normal
......
......@@ -2,7 +2,7 @@
* vlc.c: the vlc player, WinCE version
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: vlc.c,v 1.6 2004/01/24 21:06:52 hartman Exp $
* $Id$
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -140,7 +140,7 @@ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
VLC_Die( 0 );
/* Finish the threads */
VLC_Stop( 0 );
VLC_CleanUp( 0 );
/* Destroy the libvlc structure */
VLC_Destroy( 0 );
......
/*****************************************************************************
* vlc.h: global header for vlc
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
* Copyright (C) 1998-2004 VideoLAN
* $Id$
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
* Gildas Bazin <gbazin@netcourrier.com>
* Derk-Jan Hartman <hartman at videolan dot 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
......@@ -21,7 +26,7 @@
/**
* \defgroup libvlc Libvlc
* This is libvlc.
* This is libvlc, the base library of the VLC program.
*
* @{
*/
......@@ -107,7 +112,7 @@ struct vlc_list_t
* Playlist
*****************************************************************************/
/* Used by playlist_Add */
/* Used by VLC_AddTarget() */
#define PLAYLIST_INSERT 0x0001
#define PLAYLIST_REPLACE 0x0002
#define PLAYLIST_APPEND 0x0004
......@@ -116,18 +121,6 @@ struct vlc_list_t
#define PLAYLIST_END -666
/**
* Playlist commands
*/
typedef enum {
PLAYLIST_PLAY, /**< Starts playing. No arg. */
PLAYLIST_PAUSE, /**< Toggles playlist pause. No arg. */
PLAYLIST_STOP, /**< Stops playing. No arg. */
PLAYLIST_SKIP, /**< Skip X items and play. */
PLAYLIST_GOTO, /**< Goto Xth item. */
PLAYLIST_MODE /**< Set playlist mode. ??? */
} playlist_command_t;
/*****************************************************************************
* Required internal headers
*****************************************************************************/
......@@ -180,11 +173,27 @@ int VLC_Create ( void );
*/
int VLC_Init ( int, int, char *[] );
/**
* Add an interface
*
* This function opens an interface plugin and runs it. If b_block is set
* to 0, VLC_AddIntf will return immediately and let the interface run in a
* separate thread. If b_block is set to 1, VLC_AddIntf will continue until
* user requests to quit.
*
* \param i_object a vlc object id
* \param psz_module a vlc module name of an interface
* \param b_block make this interface blocking
* \param b_play start playing when the interface is done loading
* \return VLC_SUCCESS on success
*/
int VLC_AddIntf ( int, char const *, vlc_bool_t, vlc_bool_t );
/**
* Ask vlc to die
*
* This function sets p_vlc->b_die to VLC_TRUE, but does not do any other
* task. It is your duty to call VLC_End and VLC_Destroy afterwards.
* task. It is your duty to call VLC_CleanUp and VLC_Destroy afterwards.
*
* \param i_object a vlc object id
* \return VLC_SUCCESS on success
......@@ -192,10 +201,23 @@ int VLC_Init ( int, int, char *[] );
int VLC_Die ( int );
/**
* Stop playing and destroy everything.
* Clean up all the intf, playlist, vout and aout
*
* This function requests all intf, playlist, vout and aout objects to finish
* and CleanUp. Only a blank VLC object should remain after this.
*
* \param i_object a vlc object id
* \return VLC_SUCCESS on success
*/
int VLC_CleanUp ( int );
/**
* Destroy all threads and the VLC object
*
* This function requests the running threads to finish, waits for their
* termination, and destroys their structure.
* Then it will de-init all VLC object initializations.
*
* \param i_object a vlc object id
* \return VLC_SUCCESS on success
*/
......@@ -226,16 +248,88 @@ int VLC_Set ( int, char const *, vlc_value_t );
*/
int VLC_Get ( int, char const *, vlc_value_t * );
int VLC_AddIntf ( int, char const *, vlc_bool_t, vlc_bool_t );
/**
* Add a target to the current playlist
*
* This funtion will add a target to the current playlist. If a playlist does
* not exist, it will be created.
*
* \param i_object a vlc object id
* \param psz_target the URI of the target to play
* \param ppsz_options an array of strings with input options (ie. :input-repeat)
* \param i_options the amount of options in the ppsz_options array
* \param i_mode the insert mode to insert the target into the playlist (PLAYLIST_* defines)
* \param i_pos the position at which to add the new target (PLAYLIST_END for end)
* \return VLC_SUCCESS on success
*/
int VLC_AddTarget ( int, char const *, const char **, int, int, int );
/**
* Start the playlist and play the currently selected playlist item
*
* If there is something in the playlist, and the playlist is not running,
* then start the playlist and play the currently selected playlist item.
* If an item is currently paused, then resume it.
*
* \param i_object a vlc object id
* \return VLC_SUCCESS on success
*/
int VLC_Play ( int );
/**
* Pause the currently playing item. Resume it if already paused
*
* If an item is currently playing then pause it.
* If the item is already paused, then resume playback.
*
* \param i_object a vlc object id
* \return VLC_SUCCESS on success
*/
int VLC_Pause ( int );
/**
* Stop the playlist
*
* If an item is currently playing then stop it.
* Set the playlist to a stopped state.
*
* \param i_object a vlc object id
* \return VLC_SUCCESS on success
*/
int VLC_Stop ( int );
int VLC_FullScreen ( int );
int VLC_ClearPlaylist( int );
/**
* Stop the playlist
*
* If an item is currently playing then stop it.
* Set the playlist to a stopped state.
*
* \param i_object a vlc object id
* \return VLC_SUCCESS on success
*/
vlc_bool_t VLC_IsPlaying ( int );
/**
* Clear the contents of the playlist
*
* Completly empty the entire playlist.
*
* \param i_object a vlc object id
* \return VLC_SUCCESS on success
*/
int VLC_ClearPlaylist( int );
/**
* Toggle Fullscreen mode
*
* Switch between normal and fullscreen video
*
* \param i_object a vlc object id
* \return VLC_SUCCESS on success
*/
int VLC_FullScreen ( int );
# ifdef __cplusplus
}
# endif
......
......@@ -189,6 +189,20 @@ typedef struct msg_bank_t msg_bank_t;
typedef struct msg_subscription_t msg_subscription_t;
/* Playlist */
/* FIXME */
/**
* Playlist commands
*/
typedef enum {
PLAYLIST_PLAY, /**< Starts playing. No arg. */
PLAYLIST_PAUSE, /**< Toggles playlist pause. No arg. */
PLAYLIST_STOP, /**< Stops playing. No arg. */
PLAYLIST_SKIP, /**< Skip X items and play. */
PLAYLIST_GOTO, /**< Goto Xth item. */
} playlist_command_t;
typedef struct playlist_t playlist_t;
typedef struct playlist_item_t playlist_item_t;
typedef struct playlist_group_t playlist_group_t;
......
......@@ -57,6 +57,6 @@ mediacontrol_exit(mediacontrol_Instance *self)
{
vlc_object_release((vlc_object_t*)self->p_playlist);
vlc_object_release((vlc_object_t*)self->p_intf);
VLC_Stop(self->vlc_object_id);
VLC_CleanUp(self->vlc_object_id);
VLC_Destroy(self->vlc_object_id);
}
......@@ -2,7 +2,7 @@
* vlcpeer.cpp: scriptable peer descriptor
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: vlcpeer.cpp,v 1.9 2003/10/23 17:04:39 sam Exp $
* $Id$
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -110,7 +110,7 @@ NS_IMETHODIMP VlcPeer::Stop()
{
if( p_plugin )
{
VLC_Stop( p_plugin->i_vlc );
VLC_CleanUp( p_plugin->i_vlc );
p_plugin->b_stream = 0;
}
return NS_OK;
......
......@@ -428,7 +428,7 @@ NPError NPP_Destroy( NPP instance, NPSavedData** save )
if( p_plugin->i_vlc )
{
#if USE_LIBVLC
VLC_Stop( p_plugin->i_vlc );
VLC_CleanUp( p_plugin->i_vlc );
VLC_Destroy( p_plugin->i_vlc );
#endif
p_plugin->i_vlc = 0;
......
......@@ -59,7 +59,7 @@ static PyObject *vlc_stop(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "i", &iVlc))
return NULL;
iRc = VLC_Stop(iVlc);
iRc = VLC_CleanUp(iVlc);
return Py_BuildValue("i", iRc);
}
......
......@@ -705,7 +705,108 @@ int VLC_AddIntf( int i_object, char const *psz_module,
}
/*****************************************************************************
* VLC_Destroy: stop playing and destroy everything.
* VLC_Die: ask vlc to die.
*****************************************************************************
* This function sets p_vlc->b_die to VLC_TRUE, but does not do any other
* task. It is your duty to call VLC_CleanUp and VLC_Destroy afterwards.
*****************************************************************************/
int VLC_Die( int i_object )
{
vlc_t *p_vlc = vlc_current_object( i_object );
if( !p_vlc )
{
return VLC_ENOOBJ;
}
p_vlc->b_die = VLC_TRUE;
if( i_object ) vlc_object_release( p_vlc );
return VLC_SUCCESS;
}
/*****************************************************************************
* VLC_CleanUp: CleanUp all the intf, playlist, vout, aout
*****************************************************************************/
int VLC_CleanUp( int i_object )
{
intf_thread_t * p_intf;
playlist_t * p_playlist;
vout_thread_t * p_vout;
aout_instance_t * p_aout;
announce_handler_t * p_announce;
vlc_t *p_vlc = vlc_current_object( i_object );
/* Check that the handle is valid */
if( !p_vlc )
{
return VLC_ENOOBJ;
}
/*
* Ask the interfaces to stop and destroy them
*/
msg_Dbg( p_vlc, "removing all interfaces" );
while( (p_intf = vlc_object_find( p_vlc, VLC_OBJECT_INTF, FIND_CHILD )) )
{
intf_StopThread( p_intf );
vlc_object_detach( p_intf );
vlc_object_release( p_intf );
intf_Destroy( p_intf );
}
/*
* Free playlists
*/
msg_Dbg( p_vlc, "removing all playlists" );
while( (p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST,
FIND_CHILD )) )
{
vlc_object_detach( p_playlist );
vlc_object_release( p_playlist );
playlist_Destroy( p_playlist );
}
/*
* Free video outputs
*/
msg_Dbg( p_vlc, "removing all video outputs" );
while( (p_vout = vlc_object_find( p_vlc, VLC_OBJECT_VOUT, FIND_CHILD )) )
{
vlc_object_detach( p_vout );
vlc_object_release( p_vout );
vout_Destroy( p_vout );
}
/*
* Free audio outputs
*/
msg_Dbg( p_vlc, "removing all audio outputs" );
while( (p_aout = vlc_object_find( p_vlc, VLC_OBJECT_AOUT, FIND_CHILD )) )
{
vlc_object_detach( (vlc_object_t *)p_aout );
vlc_object_release( (vlc_object_t *)p_aout );
aout_Delete( p_aout );
}
/*
* Free announce handler(s?)
*/
msg_Dbg( p_vlc, "removing announce handler" );
while( (p_announce = vlc_object_find( p_vlc, VLC_OBJECT_ANNOUNCE,
FIND_CHILD ) ) )
{
vlc_object_detach( p_announce );
vlc_object_release( p_announce );
announce_HandlerDestroy( p_announce );
}
if( i_object ) vlc_object_release( p_vlc );
return VLC_SUCCESS;
}
/*****************************************************************************
* VLC_Destroy: Destroy everything.
*****************************************************************************
* This function requests the running threads to finish, waits for their
* termination, and destroys their structure.
......@@ -758,9 +859,6 @@ int VLC_Destroy( int i_object )
/* Destroy mutexes */
vlc_mutex_destroy( &p_vlc->config_lock );
#ifdef SYS_DARWIN
vlc_mutex_destroy( &p_vlc->quicktime_lock );
#endif
vlc_object_detach( p_vlc );
......@@ -775,75 +873,8 @@ int VLC_Destroy( int i_object )
return VLC_SUCCESS;
}
/*****************************************************************************
* VLC_Die: ask vlc to die.
*****************************************************************************
* This function sets p_vlc->b_die to VLC_TRUE, but does not do any other
* task. It is your duty to call VLC_End and VLC_Destroy afterwards.
*****************************************************************************/
int VLC_Die( int i_object )
{
vlc_t *p_vlc = vlc_current_object( i_object );
if( !p_vlc )
{
return VLC_ENOOBJ;
}
p_vlc->b_die = VLC_TRUE;
if( i_object ) vlc_object_release( p_vlc );
return VLC_SUCCESS;
}
/*****************************************************************************
* VLC_AddTarget: adds a target for playing.
*****************************************************************************
* This function adds psz_target to the current playlist. If a playlist does
* not exist, it will create one.
*****************************************************************************/
int VLC_AddTarget( int i_object, char const *psz_target,
char const **ppsz_options, int i_options,
int i_mode, int i_pos )
{
int i_err;
playlist_t *p_playlist;
vlc_t *p_vlc = vlc_current_object( i_object );
if( !p_vlc )
{
return VLC_ENOOBJ;
}
p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( p_playlist == NULL )
{
msg_Dbg( p_vlc, "no playlist present, creating one" );
p_playlist = playlist_Create( p_vlc );
if( p_playlist == NULL )
{
if( i_object ) vlc_object_release( p_vlc );
return VLC_EGENERIC;
}
vlc_object_yield( p_playlist );
}
i_err = playlist_AddExt( p_playlist, psz_target, psz_target,
i_mode, i_pos, -1, ppsz_options, i_options);
vlc_object_release( p_playlist );
if( i_object ) vlc_object_release( p_vlc );
return i_err;
}
/*****************************************************************************
* VLC_Set: set a vlc variable
*****************************************************************************
*
*****************************************************************************/
int VLC_Set( int i_object, char const *psz_var, vlc_value_t value )
{
......@@ -894,8 +925,6 @@ int VLC_Set( int i_object, char const *psz_var, vlc_value_t value )
/*****************************************************************************
* VLC_Get: get a vlc variable
*****************************************************************************
*
*****************************************************************************/
int VLC_Get( int i_object, char const *psz_var, vlc_value_t *p_value )
{
......@@ -913,53 +942,56 @@ int VLC_Get( int i_object, char const *psz_var, vlc_value_t *p_value )
return i_ret;
}
/* FIXME: temporary hacks */
/*****************************************************************************
* VLC_IsPlaying: Query for Playlist Status
* VLC_AddTarget: adds a target for playing.
*****************************************************************************
* This function adds psz_target to the current playlist. If a playlist does
* not exist, it will create one.
*****************************************************************************/
vlc_bool_t VLC_IsPlaying( int i_object )
int VLC_AddTarget( int i_object, char const *psz_target,
char const **ppsz_options, int i_options,
int i_mode, int i_pos )
{
playlist_t * p_playlist;
vlc_bool_t playing;
int i_err;
playlist_t *p_playlist;
vlc_t *p_vlc = vlc_current_object( i_object );
/* Check that the handle is valid */
if( !p_vlc )
{
return VLC_ENOOBJ;
}
p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( !p_playlist )
if( p_playlist == NULL )
{
if( i_object ) vlc_object_release( p_vlc );
return VLC_ENOOBJ;
msg_Dbg( p_vlc, "no playlist present, creating one" );
p_playlist = playlist_Create( p_vlc );
if( p_playlist == NULL )
{
if( i_object ) vlc_object_release( p_vlc );
return VLC_EGENERIC;
}
vlc_object_yield( p_playlist );
}
playing = playlist_IsPlaying( p_playlist );
i_err = playlist_AddExt( p_playlist, psz_target, psz_target,
i_mode, i_pos, -1, ppsz_options, i_options);
vlc_object_release( p_playlist );
if( i_object ) vlc_object_release( p_vlc );
return playing;
return i_err;
}
/*****************************************************************************
* VLC_ClearPlaylist: Query for Playlist Status
*
* return: 0
* VLC_Play: play
*****************************************************************************/
int VLC_ClearPlaylist( int i_object )
int VLC_Play( int i_object )
{
int i_err;
playlist_t * p_playlist;
vlc_t *p_vlc = vlc_current_object( i_object );
......@@ -977,20 +1009,19 @@ int VLC_ClearPlaylist( int i_object )
return VLC_ENOOBJ;
}
playlist_Clear(p_playlist);
i_err = playlist_Play( p_playlist );
vlc_object_release( p_playlist );
if( i_object ) vlc_object_release( p_vlc );
return 0;
return i_err;
}
/*****************************************************************************
* VLC_Play: play
* VLC_Pause: toggle pause
*****************************************************************************/
int VLC_Play( int i_object )
int VLC_Pause( int i_object )
{
int i_err;
playlist_t * p_playlist;
vlc_t *p_vlc = vlc_current_object( i_object );
......@@ -1008,33 +1039,20 @@ int VLC_Play( int i_object )
return VLC_ENOOBJ;
}
vlc_mutex_lock( &p_playlist->object_lock );
if( p_playlist->i_size )
{
vlc_mutex_unlock( &p_playlist->object_lock );
playlist_Play( p_playlist );
}
else
{
vlc_mutex_unlock( &p_playlist->object_lock );
}
i_err = playlist_Pause( p_playlist );
vlc_object_release( p_playlist );
if( i_object ) vlc_object_release( p_vlc );
return VLC_SUCCESS;
return i_err;
}
/*****************************************************************************
* VLC_Stop: stop
* VLC_Pause: toggle pause
*****************************************************************************/
int VLC_Stop( int i_object )
{
intf_thread_t * p_intf;
playlist_t * p_playlist;
vout_thread_t * p_vout;
aout_instance_t * p_aout;
announce_handler_t * p_announce;
int i_err;
playlist_t * p_playlist;
vlc_t *p_vlc = vlc_current_object( i_object );
/* Check that the handle is valid */
......@@ -1043,96 +1061,83 @@ int VLC_Stop( int i_object )
return VLC_ENOOBJ;
}
/*
* Ask the interfaces to stop and destroy them
*/
msg_Dbg( p_vlc, "removing all interfaces" );
p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
while( (p_intf = vlc_object_find( p_vlc, VLC_OBJECT_INTF, FIND_CHILD )) )
if( !p_playlist )
{
intf_StopThread( p_intf );
vlc_object_detach( p_intf );
vlc_object_release( p_intf );
intf_Destroy( p_intf );
if( i_object ) vlc_object_release( p_vlc );
return VLC_ENOOBJ;
}
/*
* Free playlists
*/
i_err = playlist_Stop( p_playlist );
vlc_object_release( p_playlist );
msg_Dbg( p_vlc, "removing all playlists" );
while( (p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST,
FIND_CHILD )) )
{
vlc_object_detach( p_playlist );
vlc_object_release( p_playlist );
playlist_Destroy( p_playlist );
}
if( i_object ) vlc_object_release( p_vlc );
return i_err;
}
/*
* Free video outputs
*/
msg_Dbg( p_vlc, "removing all video outputs" );
while( (p_vout = vlc_object_find( p_vlc, VLC_OBJECT_VOUT, FIND_CHILD )) )
/*****************************************************************************
* VLC_IsPlaying: Query for Playlist Status
*****************************************************************************/
vlc_bool_t VLC_IsPlaying( int i_object )
{
playlist_t * p_playlist;
vlc_bool_t b_playing;
vlc_t *p_vlc = vlc_current_object( i_object );
/* Check that the handle is valid */
if( !p_vlc )
{
vlc_object_detach( p_vout );
vlc_object_release( p_vout );
vout_Destroy( p_vout );
return VLC_ENOOBJ;
}
/*
* Free audio outputs
*/
msg_Dbg( p_vlc, "removing all audio outputs" );
while( (p_aout = vlc_object_find( p_vlc, VLC_OBJECT_AOUT, FIND_CHILD )) )
p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
if( !p_playlist )
{
vlc_object_detach( (vlc_object_t *)p_aout );
vlc_object_release( (vlc_object_t *)p_aout );
aout_Delete( p_aout );
if( i_object ) vlc_object_release( p_vlc );
return VLC_ENOOBJ;
}
/*
* Free announce handler(s?)
*/
msg_Dbg( p_vlc, "removing announce handler" );
while( (p_announce = vlc_object_find( p_vlc, VLC_OBJECT_ANNOUNCE,
FIND_CHILD ) ) )
{
vlc_object_detach( p_announce );
vlc_object_release( p_announce );
announce_HandlerDestroy( p_announce );
}
b_playing = playlist_IsPlaying( p_playlist );
vlc_object_release( p_playlist );
if( i_object ) vlc_object_release( p_vlc );
return VLC_SUCCESS;
return b_playing;
}
/*****************************************************************************
* VLC_Pause: toggle pause
* VLC_ClearPlaylist: Empty the playlist
*****************************************************************************/
int VLC_Pause( int i_object )
int VLC_ClearPlaylist( int i_object )
{
input_thread_t *p_input;
int i_err;
playlist_t * p_playlist;
vlc_t *p_vlc = vlc_current_object( i_object );
/* Check that the handle is valid */
if( !p_vlc )
{
return VLC_ENOOBJ;
}
p_input = vlc_object_find( p_vlc, VLC_OBJECT_INPUT, FIND_CHILD );
p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
if( !p_input )
if( !p_playlist )
{
if( i_object ) vlc_object_release( p_vlc );
return VLC_ENOOBJ;
}
input_SetStatus( p_input, INPUT_STATUS_PAUSE );
vlc_object_release( p_input );
i_err = playlist_Clear(p_playlist);
vlc_object_release( p_playlist );
if( i_object ) vlc_object_release( p_vlc );
return VLC_SUCCESS;
return i_err;
}
/*****************************************************************************
......
......@@ -102,7 +102,7 @@ int main( int i_argc, char *ppsz_argv[] )
i_ret = VLC_AddIntf( 0, NULL, VLC_TRUE, VLC_TRUE );
/* Finish the threads */
VLC_Stop( 0 );
VLC_CleanUp( 0 );
/* Destroy the libvlc structure */
VLC_Destroy( 0 );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment