input/input_internal.h \
input/input_interface.h \
input/vlm_internal.h \
- input/ressource.h \
- input/ressource.c \
+ input/resource.h \
+ input/resource.c \
input/stream.c \
input/stream_demux.c \
input/stream_filter.c \
#include "input_internal.h"
#include "event.h"
-#include "ressource.h"
+#include "resource.h"
static void UpdateBookmarksOption( input_thread_t * );
case INPUT_GET_AOUT:
{
- aout_instance_t *p_aout = input_ressource_HoldAout( p_input->p->p_ressource );
+ aout_instance_t *p_aout = input_resource_HoldAout( p_input->p->p_resource );
if( !p_aout )
return VLC_EGENERIC;
vout_thread_t ***ppp_vout = (vout_thread_t***)va_arg( args, vout_thread_t*** );
int *pi_vout = (int*)va_arg( args, int* );
- input_ressource_HoldVouts( p_input->p->p_ressource, ppp_vout, pi_vout );
+ input_resource_HoldVouts( p_input->p->p_resource, ppp_vout, pi_vout );
if( *pi_vout <= 0 )
return VLC_EGENERIC;
return VLC_SUCCESS;
#include "clock.h"
#include "decoder.h"
#include "event.h"
-#include "ressource.h"
+#include "resource.h"
#include "../video_output/vout_control.h"
stats_UpdateInteger( p_dec, p_input->p->counters.p_decoded_sub, 1, NULL );
vlc_mutex_unlock( &p_input->p->counters.counters_lock );
- p_vout = input_ressource_HoldVout( p_input->p->p_ressource );
+ p_vout = input_resource_HoldVout( p_input->p->p_resource );
if( p_vout && p_owner->p_spu_vout == p_vout )
{
/* Preroll does not work very well with subtitle */
if( b_flush && p_owner->p_spu_vout )
{
- p_vout = input_ressource_HoldVout( p_input->p->p_ressource );
+ p_vout = input_resource_HoldVout( p_input->p->p_resource );
if( p_vout && p_owner->p_spu_vout == p_vout )
spu_Control( p_vout->p_spu, SPU_CHANNEL_CLEAR,
aout_DecDelete( p_owner->p_aout, p_owner->p_aout_input );
if( p_owner->p_aout )
{
- input_ressource_RequestAout( p_owner->p_input->p->p_ressource,
+ input_resource_RequestAout( p_owner->p_input->p->p_resource,
p_owner->p_aout );
input_SendEventAout( p_owner->p_input );
p_owner->p_aout = NULL;
vout_ChangePause( p_owner->p_vout, false, mdate() );
/* */
- input_ressource_RequestVout( p_owner->p_input->p->p_ressource, p_owner->p_vout, NULL, true );
+ input_resource_RequestVout( p_owner->p_input->p->p_resource, p_owner->p_vout, NULL, true );
input_SendEventVout( p_owner->p_input );
}
{
vout_thread_t *p_vout;
- p_vout = input_ressource_HoldVout( p_owner->p_input->p->p_ressource );
+ p_vout = input_resource_HoldVout( p_owner->p_input->p->p_resource );
if( p_vout )
{
if( p_owner->p_spu_vout == p_vout )
decoder_t *p_dec = p_private;
input_thread_t *p_input = p_dec->p_owner->p_input;
- p_vout = input_ressource_RequestVout( p_input->p->p_ressource, p_vout, p_fmt, b_recyle );
+ p_vout = input_resource_RequestVout( p_input->p->p_resource, p_vout, p_fmt, b_recyle );
input_SendEventVout( p_input );
return p_vout;
p_aout = p_owner->p_aout;
if( !p_aout )
- p_aout = input_ressource_RequestAout( p_owner->p_input->p->p_ressource, NULL );
+ p_aout = input_resource_RequestAout( p_owner->p_input->p->p_resource, NULL );
p_aout_input = aout_DecNew( p_dec, &p_aout,
&format, &p_dec->fmt_out.audio_replay_gain, &request_vout );
p_owner->p_vout = NULL;
vlc_mutex_unlock( &p_owner->lock );
- p_vout = input_ressource_RequestVout( p_owner->p_input->p->p_ressource,
+ p_vout = input_resource_RequestVout( p_owner->p_input->p->p_resource,
p_vout, &p_dec->fmt_out.video, true );
vlc_mutex_lock( &p_owner->lock );
if( p_dec->b_die || p_dec->b_error )
break;
- p_vout = input_ressource_HoldVout( p_owner->p_input->p->p_ressource );
+ p_vout = input_resource_HoldVout( p_owner->p_input->p->p_resource );
if( p_vout )
break;
decoder_owner_sys_t *p_owner = p_dec->p_owner;
vout_thread_t *p_vout = NULL;
- p_vout = input_ressource_HoldVout( p_owner->p_input->p->p_ressource );
+ p_vout = input_resource_HoldVout( p_owner->p_input->p->p_resource );
if( !p_vout || p_owner->p_spu_vout != p_vout )
{
if( p_vout )
(int)(mdate() - i_decoder_buffering_start)/1000 );
/* Here is a good place to destroy unused vout with every demuxer */
- input_ressource_TerminateVout( p_sys->p_input->p->p_ressource );
+ input_resource_TerminateVout( p_sys->p_input->p->p_resource );
/* */
const mtime_t i_wakeup_delay = 10*1000; /* FIXME CLEANUP thread wake up time*/
break;
}
if( i >= p_sys->i_es )
- input_ressource_TerminateVout( p_sys->p_input->p->p_ressource );
+ input_resource_TerminateVout( p_sys->p_input->p->p_resource );
}
p_sys->b_active = b;
return VLC_SUCCESS;
/* Clean up vout after user action (in active mode only).
* FIXME it does not work well with multiple video windows */
if( p_sys->b_active )
- input_ressource_TerminateVout( p_sys->p_input->p->p_ressource );
+ input_resource_TerminateVout( p_sys->p_input->p->p_resource );
return i_ret;
}
#include "demux.h"
#include "stream.h"
#include "item.h"
-#include "ressource.h"
+#include "resource.h"
#include <vlc_sout.h>
#include "../stream_output/stream_output.h"
static void *RunAndDestroy ( vlc_object_t *p_this );
static input_thread_t * Create ( vlc_object_t *, input_item_t *,
- const char *, bool, input_ressource_t * );
+ const char *, bool, input_resource_t * );
static int Init ( input_thread_t *p_input );
static void End ( input_thread_t *p_input );
static void MainLoop( input_thread_t *p_input );
*****************************************************************************/
static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
const char *psz_header, bool b_quick,
- input_ressource_t *p_ressource )
+ input_resource_t *p_resource )
{
static const char input_name[] = "input";
input_thread_t *p_input = NULL; /* thread descriptor */
p_input->p->slave = NULL;
/* */
- if( p_ressource )
- p_input->p->p_ressource = p_ressource;
+ if( p_resource )
+ p_input->p->p_resource = p_resource;
else
- p_input->p->p_ressource = input_ressource_New();
- input_ressource_SetInput( p_input->p->p_ressource, p_input );
+ p_input->p->p_resource = input_resource_New();
+ input_resource_SetInput( p_input->p->p_resource, p_input );
/* Init control buffer */
vlc_mutex_init( &p_input->p->lock_control );
stats_TimerDump( p_input, STATS_TIMER_INPUT_LAUNCHING );
stats_TimerClean( p_input, STATS_TIMER_INPUT_LAUNCHING );
- if( p_input->p->p_ressource )
- input_ressource_Delete( p_input->p->p_ressource );
+ if( p_input->p->p_resource )
+ input_resource_Delete( p_input->p->p_resource );
vlc_gc_decref( p_input->p->p_item );
/* */
input_thread_t *__input_CreateThreadExtended( vlc_object_t *p_parent,
input_item_t *p_item,
- const char *psz_log, input_ressource_t *p_ressource )
+ const char *psz_log, input_resource_t *p_resource )
{
input_thread_t *p_input;
- p_input = Create( p_parent, p_item, psz_log, false, p_ressource );
+ p_input = Create( p_parent, p_item, psz_log, false, p_resource );
if( !p_input )
return NULL;
input_ControlPush( p_input, INPUT_CONTROL_SET_DIE, NULL );
}
-input_ressource_t *input_DetachRessource( input_thread_t *p_input )
+input_resource_t *input_DetachRessource( input_thread_t *p_input )
{
assert( p_input->b_dead );
- input_ressource_t *p_ressource = p_input->p->p_ressource;
- input_ressource_SetInput( p_ressource, NULL );
+ input_resource_t *p_resource = p_input->p->p_resource;
+ input_resource_SetInput( p_resource, NULL );
- p_input->p->p_ressource = NULL;
+ p_input->p->p_resource = NULL;
p_input->p->p_sout = NULL;
- return p_ressource;
+ return p_resource;
}
/**
char *psz = var_GetNonEmptyString( p_input, "sout" );
if( psz && strncasecmp( p_input->p->p_item->psz_uri, "vlc:", 4 ) )
{
- p_input->p->p_sout = input_ressource_RequestSout( p_input->p->p_ressource, NULL, psz );
+ p_input->p->p_sout = input_resource_RequestSout( p_input->p->p_resource, NULL, psz );
if( !p_input->p->p_sout )
{
input_ChangeState( p_input, ERROR_S );
}
else
{
- input_ressource_RequestSout( p_input->p->p_ressource, NULL, NULL );
+ input_resource_RequestSout( p_input->p->p_resource, NULL, NULL );
}
free( psz );
es_out_Delete( p_input->p->p_es_out );
if( p_input->p->p_es_out_display )
es_out_Delete( p_input->p->p_es_out_display );
- if( p_input->p->p_ressource )
+ if( p_input->p->p_resource )
{
if( p_input->p->p_sout )
- input_ressource_RequestSout( p_input->p->p_ressource,
+ input_resource_RequestSout( p_input->p->p_resource,
p_input->p->p_sout, NULL );
- input_ressource_SetInput( p_input->p->p_ressource, NULL );
+ input_resource_SetInput( p_input->p->p_resource, NULL );
}
#ifdef ENABLE_SOUT
}
/* */
- input_ressource_RequestSout( p_input->p->p_ressource,
+ input_resource_RequestSout( p_input->p->p_resource,
p_input->p->p_sout, NULL );
- input_ressource_SetInput( p_input->p->p_ressource, NULL );
+ input_resource_SetInput( p_input->p->p_resource, NULL );
}
/*****************************************************************************
input_stats_t *stats_NewInputStats( input_thread_t *p_input );
/**
- * This defines an opaque input ressource handler.
+ * This defines an opaque input resource handler.
*/
-typedef struct input_ressource_t input_ressource_t;
+typedef struct input_resource_t input_resource_t;
/**
- * This function releases an input_ressource_t and all associated ressources.
+ * This function releases an input_resource_t and all associated resources.
*/
-void input_ressource_Delete( input_ressource_t * );
+void input_resource_Delete( input_resource_t * );
/**
- * This function deletes the current sout in the ressources.
+ * This function deletes the current sout in the resources.
*/
-void input_ressource_TerminateSout( input_ressource_t *p_ressource );
+void input_resource_TerminateSout( input_resource_t *p_resource );
/**
- * This function deletes the current vout in the ressources.
+ * This function deletes the current vout in the resources.
*/
-void input_ressource_TerminateVout( input_ressource_t *p_ressource );
+void input_resource_TerminateVout( input_resource_t *p_resource );
/**
- * This function return true if there is at least one vout in the ressources.
+ * This function return true if there is at least one vout in the resources.
*
- * It can only be called on detached ressources.
+ * It can only be called on detached resources.
*/
-bool input_ressource_HasVout( input_ressource_t *p_ressource );
+bool input_resource_HasVout( input_resource_t *p_resource );
/* input.c */
#define input_CreateThreadExtended(a,b,c,d) __input_CreateThreadExtended(VLC_OBJECT(a),b,c,d)
-input_thread_t *__input_CreateThreadExtended ( vlc_object_t *, input_item_t *, const char *, input_ressource_t * );
+input_thread_t *__input_CreateThreadExtended ( vlc_object_t *, input_item_t *, const char *, input_resource_t * );
/**
- * This function detaches ressources from a dead input.
+ * This function detaches resources from a dead input.
*
* It MUST be called on a dead input (p_input->b_dead true) otherwise
* it will assert.
* It does not support concurrent calls.
*/
-input_ressource_t *input_DetachRessource( input_thread_t * );
+input_resource_t *input_DetachRessource( input_thread_t * );
/* */
typedef enum
input_source_t **slave;
/* Ressources */
- input_ressource_t *p_ressource;
+ input_resource_t *p_resource;
/* Stats counters */
struct {
--- /dev/null
+/*****************************************************************************
+ * resource.c
+ *****************************************************************************
+ * Copyright (C) 2008 Laurent Aimar
+ * $Id$
+ *
+ * Authors: Laurent Aimar < fenrir _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
+ * (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
+ *****************************************************************************/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_vout.h>
+#include <vlc_osd.h>
+#include <vlc_aout.h>
+#include <vlc_sout.h>
+#include "../libvlc.h"
+#include "../stream_output/stream_output.h"
+#include "../audio_output/aout_internal.h"
+#include "../video_output/vout_control.h"
+#include "input_interface.h"
+#include "resource.h"
+
+struct input_resource_t
+{
+ /* This lock is used to serialize request and protect
+ * our variables */
+ vlc_mutex_t lock;
+
+ /* */
+ input_thread_t *p_input;
+
+ sout_instance_t *p_sout;
+ vout_thread_t *p_vout_free;
+ aout_instance_t *p_aout;
+
+ /* This lock is used to protect vout resources access (for hold)
+ * It is a special case because of embed video (possible deadlock
+ * between vout window request and vout holds in some(qt4) interface) */
+ vlc_mutex_t lock_vout;
+ int i_vout;
+ vout_thread_t **pp_vout;
+};
+
+/* */
+static void DestroySout( input_resource_t *p_resource )
+{
+#ifdef ENABLE_SOUT
+ if( p_resource->p_sout )
+ sout_DeleteInstance( p_resource->p_sout );
+#endif
+ p_resource->p_sout = NULL;
+}
+static sout_instance_t *RequestSout( input_resource_t *p_resource,
+ sout_instance_t *p_sout, const char *psz_sout )
+{
+#ifdef ENABLE_SOUT
+ if( !p_sout && !psz_sout )
+ {
+ if( p_resource->p_sout )
+ msg_Dbg( p_resource->p_sout, "destroying useless sout" );
+ DestroySout( p_resource );
+ return NULL;
+ }
+
+ assert( p_resource->p_input );
+ assert( !p_sout || ( !p_resource->p_sout && !psz_sout ) );
+
+ /* Check the validity of the sout */
+ if( p_resource->p_sout &&
+ strcmp( p_resource->p_sout->psz_sout, psz_sout ) )
+ {
+ msg_Dbg( p_resource->p_input, "destroying unusable sout" );
+ DestroySout( p_resource );
+ }
+
+ if( psz_sout )
+ {
+ if( p_resource->p_sout )
+ {
+ /* Reuse it */
+ msg_Dbg( p_resource->p_input, "reusing sout" );
+ msg_Dbg( p_resource->p_input, "you probably want to use gather stream_out" );
+ vlc_object_attach( p_resource->p_sout, p_resource->p_input );
+ }
+ else
+ {
+ /* Create a new one */
+ p_resource->p_sout = sout_NewInstance( p_resource->p_input, psz_sout );
+ }
+
+ p_sout = p_resource->p_sout;
+ p_resource->p_sout = NULL;
+
+ return p_sout;
+ }
+ else
+ {
+ vlc_object_detach( p_sout );
+ p_resource->p_sout = p_sout;
+
+ return NULL;
+ }
+#else
+ return NULL;
+#endif
+}
+
+/* */
+static void DestroyVout( input_resource_t *p_resource )
+{
+ assert( p_resource->i_vout == 0 );
+
+ if( p_resource->p_vout_free )
+ vout_CloseAndRelease( p_resource->p_vout_free );
+
+ p_resource->p_vout_free = NULL;
+}
+static void DisplayVoutTitle( input_resource_t *p_resource,
+ vout_thread_t *p_vout )
+{
+ assert( p_resource->p_input );
+
+ /* TODO display the title only one time for the same input ? */
+
+ input_item_t *p_item = input_GetItem( p_resource->p_input );
+
+ char *psz_nowplaying = input_item_GetNowPlaying( p_item );
+ if( psz_nowplaying && *psz_nowplaying )
+ {
+ vout_DisplayTitle( p_vout, psz_nowplaying );
+ }
+ else
+ {
+ char *psz_artist = input_item_GetArtist( p_item );
+ char *psz_name = input_item_GetTitle( p_item );
+
+ if( !psz_name || *psz_name == '\0' )
+ {
+ free( psz_name );
+ psz_name = input_item_GetName( p_item );
+ }
+ if( psz_artist && *psz_artist )
+ {
+ char *psz_string;
+ if( asprintf( &psz_string, "%s - %s", psz_name, psz_artist ) != -1 )
+ {
+ vout_DisplayTitle( p_vout, psz_string );
+ free( psz_string );
+ }
+ }
+ else if( psz_name )
+ {
+ vout_DisplayTitle( p_vout, psz_name );
+ }
+ free( psz_name );
+ free( psz_artist );
+ }
+ free( psz_nowplaying );
+}
+static vout_thread_t *RequestVout( input_resource_t *p_resource,
+ vout_thread_t *p_vout, video_format_t *p_fmt,
+ bool b_recycle )
+{
+ if( !p_vout && !p_fmt )
+ {
+ if( p_resource->p_vout_free )
+ {
+ msg_Dbg( p_resource->p_vout_free, "destroying useless vout" );
+ vout_CloseAndRelease( p_resource->p_vout_free );
+ p_resource->p_vout_free = NULL;
+ }
+ return NULL;
+ }
+
+ assert( p_resource->p_input );
+ if( p_fmt )
+ {
+ /* */
+ if( !p_vout && p_resource->p_vout_free )
+ {
+ msg_Dbg( p_resource->p_input, "trying to reuse free vout" );
+ p_vout = p_resource->p_vout_free;
+
+ p_resource->p_vout_free = NULL;
+ }
+ else if( p_vout )
+ {
+ assert( p_vout != p_resource->p_vout_free );
+
+ vlc_mutex_lock( &p_resource->lock_vout );
+ TAB_REMOVE( p_resource->i_vout, p_resource->pp_vout, p_vout );
+ vlc_mutex_unlock( &p_resource->lock_vout );
+ }
+
+ /* */
+ p_vout = vout_Request( p_resource->p_input, p_vout, p_fmt );
+ if( !p_vout )
+ return NULL;
+
+ DisplayVoutTitle( p_resource, p_vout );
+
+ vlc_mutex_lock( &p_resource->lock_vout );
+ TAB_APPEND( p_resource->i_vout, p_resource->pp_vout, p_vout );
+ vlc_mutex_unlock( &p_resource->lock_vout );
+
+ return p_vout;
+ }
+ else
+ {
+ assert( p_vout );
+
+ vlc_mutex_lock( &p_resource->lock_vout );
+ TAB_REMOVE( p_resource->i_vout, p_resource->pp_vout, p_vout );
+ const int i_vout_active = p_resource->i_vout;
+ vlc_mutex_unlock( &p_resource->lock_vout );
+
+ if( p_resource->p_vout_free || i_vout_active > 0 || !b_recycle )
+ {
+ if( b_recycle )
+ msg_Dbg( p_resource->p_input, "detroying vout (already one saved or active)" );
+ vout_CloseAndRelease( p_vout );
+ }
+ else
+ {
+ msg_Dbg( p_resource->p_input, "saving a free vout" );
+ vout_Flush( p_vout, 1 );
+ spu_Control( p_vout->p_spu, SPU_CHANNEL_CLEAR, -1 );
+
+ p_resource->p_vout_free = p_vout;
+ }
+ return NULL;
+ }
+}
+static vout_thread_t *HoldVout( input_resource_t *p_resource )
+{
+ if( p_resource->i_vout <= 0 )
+ return NULL;
+
+ /* TODO FIXME: p_resource->pp_vout order is NOT stable */
+ vlc_mutex_lock( &p_resource->lock_vout );
+
+ vout_thread_t *p_vout = p_resource->pp_vout[0];
+
+ vlc_object_hold( p_vout );
+
+ vlc_mutex_unlock( &p_resource->lock_vout );
+
+ return p_vout;
+}
+static void HoldVouts( input_resource_t *p_resource, vout_thread_t ***ppp_vout, int *pi_vout )
+{
+ vout_thread_t **pp_vout;
+
+ *pi_vout = 0;
+ *ppp_vout = NULL;
+
+ vlc_mutex_lock( &p_resource->lock_vout );
+
+ if( p_resource->i_vout <= 0 )
+ goto exit;
+
+ pp_vout = calloc( p_resource->i_vout, sizeof(*pp_vout) );
+ if( !pp_vout )
+ goto exit;
+
+ *ppp_vout = pp_vout;
+ *pi_vout = p_resource->i_vout;
+
+ for( int i = 0; i < p_resource->i_vout; i++ )
+ {
+ pp_vout[i] = p_resource->pp_vout[i];
+ vlc_object_hold( pp_vout[i] );
+ }
+
+exit:
+ vlc_mutex_unlock( &p_resource->lock_vout );
+}
+
+/* */
+static void DestroyAout( input_resource_t *p_resource )
+{
+ if( p_resource->p_aout )
+ vlc_object_release( p_resource->p_aout );
+ p_resource->p_aout = NULL;
+}
+static aout_instance_t *RequestAout( input_resource_t *p_resource, aout_instance_t *p_aout )
+{
+ assert( p_resource->p_input );
+
+ if( p_aout )
+ {
+ msg_Dbg( p_resource->p_input, "releasing aout" );
+ vlc_object_release( p_aout );
+ return NULL;
+ }
+ else
+ {
+ if( !p_resource->p_aout )
+ {
+ msg_Dbg( p_resource->p_input, "creating aout" );
+ p_resource->p_aout = aout_New( p_resource->p_input );
+ }
+ else
+ {
+ msg_Dbg( p_resource->p_input, "reusing aout" );
+ }
+
+ if( !p_resource->p_aout )
+ return NULL;
+
+ vlc_object_detach( p_resource->p_aout );
+ vlc_object_attach( p_resource->p_aout, p_resource->p_input );
+ vlc_object_hold( p_resource->p_aout );
+ return p_resource->p_aout;
+ }
+}
+static aout_instance_t *HoldAout( input_resource_t *p_resource )
+{
+ if( !p_resource->p_aout )
+ return NULL;
+
+ aout_instance_t *p_aout = p_resource->p_aout;
+
+ vlc_object_hold( p_aout );
+
+ return p_aout;
+}
+
+/* */
+input_resource_t *input_resource_New( void )
+{
+ input_resource_t *p_resource = calloc( 1, sizeof(*p_resource) );
+ if( !p_resource )
+ return NULL;
+
+ vlc_mutex_init( &p_resource->lock );
+ vlc_mutex_init( &p_resource->lock_vout );
+ return p_resource;
+}
+
+void input_resource_Delete( input_resource_t *p_resource )
+{
+ DestroySout( p_resource );
+ DestroyVout( p_resource );
+ DestroyAout( p_resource );
+
+ vlc_mutex_destroy( &p_resource->lock_vout );
+ vlc_mutex_destroy( &p_resource->lock );
+ free( p_resource );
+}
+
+void input_resource_SetInput( input_resource_t *p_resource, input_thread_t *p_input )
+{
+ vlc_mutex_lock( &p_resource->lock );
+
+ if( p_resource->p_input && !p_input )
+ {
+ if( p_resource->p_aout )
+ vlc_object_detach( p_resource->p_aout );
+
+ assert( p_resource->i_vout == 0 );
+ if( p_resource->p_vout_free )
+ vlc_object_detach( p_resource->p_vout_free );
+
+ if( p_resource->p_sout )
+ vlc_object_detach( p_resource->p_sout );
+ }
+
+ /* */
+ p_resource->p_input = p_input;
+
+ vlc_mutex_unlock( &p_resource->lock );
+}
+
+vout_thread_t *input_resource_RequestVout( input_resource_t *p_resource,
+ vout_thread_t *p_vout, video_format_t *p_fmt, bool b_recycle )
+{
+ vlc_mutex_lock( &p_resource->lock );
+ vout_thread_t *p_ret = RequestVout( p_resource, p_vout, p_fmt, b_recycle );
+ vlc_mutex_unlock( &p_resource->lock );
+
+ return p_ret;
+}
+vout_thread_t *input_resource_HoldVout( input_resource_t *p_resource )
+{
+ return HoldVout( p_resource );
+}
+void input_resource_HoldVouts( input_resource_t *p_resource, vout_thread_t ***ppp_vout, int *pi_vout )
+{
+ HoldVouts( p_resource, ppp_vout, pi_vout );
+}
+void input_resource_TerminateVout( input_resource_t *p_resource )
+{
+ input_resource_RequestVout( p_resource, NULL, NULL, false );
+}
+bool input_resource_HasVout( input_resource_t *p_resource )
+{
+ vlc_mutex_lock( &p_resource->lock );
+ assert( !p_resource->p_input );
+ const bool b_vout = p_resource->p_vout_free != NULL;
+ vlc_mutex_unlock( &p_resource->lock );
+
+ return b_vout;
+}
+
+/* */
+aout_instance_t *input_resource_RequestAout( input_resource_t *p_resource, aout_instance_t *p_aout )
+{
+ vlc_mutex_lock( &p_resource->lock );
+ aout_instance_t *p_ret = RequestAout( p_resource, p_aout );
+ vlc_mutex_unlock( &p_resource->lock );
+
+ return p_ret;
+}
+aout_instance_t *input_resource_HoldAout( input_resource_t *p_resource )
+{
+ vlc_mutex_lock( &p_resource->lock );
+ aout_instance_t *p_ret = HoldAout( p_resource );
+ vlc_mutex_unlock( &p_resource->lock );
+
+ return p_ret;
+}
+/* */
+sout_instance_t *input_resource_RequestSout( input_resource_t *p_resource, sout_instance_t *p_sout, const char *psz_sout )
+{
+ vlc_mutex_lock( &p_resource->lock );
+ sout_instance_t *p_ret = RequestSout( p_resource, p_sout, psz_sout );
+ vlc_mutex_unlock( &p_resource->lock );
+
+ return p_ret;
+}
+void input_resource_TerminateSout( input_resource_t *p_resource )
+{
+ input_resource_RequestSout( p_resource, NULL, NULL );
+}
+
/*****************************************************************************
- * ressource.h
+ * resource.h
*****************************************************************************
* Copyright (C) 2008 Laurent Aimar
* $Id$
#include <vlc_common.h>
/**
- * This function creates an empty input_ressource_t.
+ * This function creates an empty input_resource_t.
*/
-input_ressource_t *input_ressource_New( void );
+input_resource_t *input_resource_New( void );
/**
* This function set the associated input.
*/
-void input_ressource_SetInput( input_ressource_t *, input_thread_t * );
+void input_resource_SetInput( input_resource_t *, input_thread_t * );
/**
* This function handles sout request.
*/
-sout_instance_t *input_ressource_RequestSout( input_ressource_t *, sout_instance_t *, const char *psz_sout );
+sout_instance_t *input_resource_RequestSout( input_resource_t *, sout_instance_t *, const char *psz_sout );
/**
* This function handles aout request.
*/
-aout_instance_t *input_ressource_RequestAout( input_ressource_t *, aout_instance_t * );
+aout_instance_t *input_resource_RequestAout( input_resource_t *, aout_instance_t * );
/**
* This function return the current aout if any.
*
* You must call vlc_object_release on the value returned (if non NULL).
*/
-aout_instance_t *input_ressource_HoldAout( input_ressource_t *p_ressource );
+aout_instance_t *input_resource_HoldAout( input_resource_t *p_resource );
/**
* This function handles vout request.
*/
-vout_thread_t *input_ressource_RequestVout( input_ressource_t *, vout_thread_t *, video_format_t *, bool b_recycle );
+vout_thread_t *input_resource_RequestVout( input_resource_t *, vout_thread_t *, video_format_t *, bool b_recycle );
/**
* This function return one of the current vout if any.
*
* You must call vlc_object_release on the value returned (if non NULL).
*/
-vout_thread_t *input_ressource_HoldVout( input_ressource_t * );
+vout_thread_t *input_resource_HoldVout( input_resource_t * );
/**
* This function return all current vouts if any.
*
* You must call vlc_object_release on all values returned (if non NULL).
*/
-void input_ressource_HoldVouts( input_ressource_t *, vout_thread_t ***, int * );
+void input_resource_HoldVouts( input_resource_t *, vout_thread_t ***, int * );
#endif
+++ /dev/null
-/*****************************************************************************
- * ressource.c
- *****************************************************************************
- * Copyright (C) 2008 Laurent Aimar
- * $Id$
- *
- * Authors: Laurent Aimar < fenrir _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
- * (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
- *****************************************************************************/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <vlc_common.h>
-#include <vlc_vout.h>
-#include <vlc_osd.h>
-#include <vlc_aout.h>
-#include <vlc_sout.h>
-#include "../libvlc.h"
-#include "../stream_output/stream_output.h"
-#include "../audio_output/aout_internal.h"
-#include "../video_output/vout_control.h"
-#include "input_interface.h"
-#include "ressource.h"
-
-struct input_ressource_t
-{
- /* This lock is used to serialize request and protect
- * our variables */
- vlc_mutex_t lock;
-
- /* */
- input_thread_t *p_input;
-
- sout_instance_t *p_sout;
- vout_thread_t *p_vout_free;
- aout_instance_t *p_aout;
-
- /* This lock is used to protect vout ressources access (for hold)
- * It is a special case because of embed video (possible deadlock
- * between vout window request and vout holds in some(qt4) interface) */
- vlc_mutex_t lock_vout;
- int i_vout;
- vout_thread_t **pp_vout;
-};
-
-/* */
-static void DestroySout( input_ressource_t *p_ressource )
-{
-#ifdef ENABLE_SOUT
- if( p_ressource->p_sout )
- sout_DeleteInstance( p_ressource->p_sout );
-#endif
- p_ressource->p_sout = NULL;
-}
-static sout_instance_t *RequestSout( input_ressource_t *p_ressource,
- sout_instance_t *p_sout, const char *psz_sout )
-{
-#ifdef ENABLE_SOUT
- if( !p_sout && !psz_sout )
- {
- if( p_ressource->p_sout )
- msg_Dbg( p_ressource->p_sout, "destroying useless sout" );
- DestroySout( p_ressource );
- return NULL;
- }
-
- assert( p_ressource->p_input );
- assert( !p_sout || ( !p_ressource->p_sout && !psz_sout ) );
-
- /* Check the validity of the sout */
- if( p_ressource->p_sout &&
- strcmp( p_ressource->p_sout->psz_sout, psz_sout ) )
- {
- msg_Dbg( p_ressource->p_input, "destroying unusable sout" );
- DestroySout( p_ressource );
- }
-
- if( psz_sout )
- {
- if( p_ressource->p_sout )
- {
- /* Reuse it */
- msg_Dbg( p_ressource->p_input, "reusing sout" );
- msg_Dbg( p_ressource->p_input, "you probably want to use gather stream_out" );
- vlc_object_attach( p_ressource->p_sout, p_ressource->p_input );
- }
- else
- {
- /* Create a new one */
- p_ressource->p_sout = sout_NewInstance( p_ressource->p_input, psz_sout );
- }
-
- p_sout = p_ressource->p_sout;
- p_ressource->p_sout = NULL;
-
- return p_sout;
- }
- else
- {
- vlc_object_detach( p_sout );
- p_ressource->p_sout = p_sout;
-
- return NULL;
- }
-#else
- return NULL;
-#endif
-}
-
-/* */
-static void DestroyVout( input_ressource_t *p_ressource )
-{
- assert( p_ressource->i_vout == 0 );
-
- if( p_ressource->p_vout_free )
- vout_CloseAndRelease( p_ressource->p_vout_free );
-
- p_ressource->p_vout_free = NULL;
-}
-static void DisplayVoutTitle( input_ressource_t *p_ressource,
- vout_thread_t *p_vout )
-{
- assert( p_ressource->p_input );
-
- /* TODO display the title only one time for the same input ? */
-
- input_item_t *p_item = input_GetItem( p_ressource->p_input );
-
- char *psz_nowplaying = input_item_GetNowPlaying( p_item );
- if( psz_nowplaying && *psz_nowplaying )
- {
- vout_DisplayTitle( p_vout, psz_nowplaying );
- }
- else
- {
- char *psz_artist = input_item_GetArtist( p_item );
- char *psz_name = input_item_GetTitle( p_item );
-
- if( !psz_name || *psz_name == '\0' )
- {
- free( psz_name );
- psz_name = input_item_GetName( p_item );
- }
- if( psz_artist && *psz_artist )
- {
- char *psz_string;
- if( asprintf( &psz_string, "%s - %s", psz_name, psz_artist ) != -1 )
- {
- vout_DisplayTitle( p_vout, psz_string );
- free( psz_string );
- }
- }
- else if( psz_name )
- {
- vout_DisplayTitle( p_vout, psz_name );
- }
- free( psz_name );
- free( psz_artist );
- }
- free( psz_nowplaying );
-}
-static vout_thread_t *RequestVout( input_ressource_t *p_ressource,
- vout_thread_t *p_vout, video_format_t *p_fmt,
- bool b_recycle )
-{
- if( !p_vout && !p_fmt )
- {
- if( p_ressource->p_vout_free )
- {
- msg_Dbg( p_ressource->p_vout_free, "destroying useless vout" );
- vout_CloseAndRelease( p_ressource->p_vout_free );
- p_ressource->p_vout_free = NULL;
- }
- return NULL;
- }
-
- assert( p_ressource->p_input );
- if( p_fmt )
- {
- /* */
- if( !p_vout && p_ressource->p_vout_free )
- {
- msg_Dbg( p_ressource->p_input, "trying to reuse free vout" );
- p_vout = p_ressource->p_vout_free;
-
- p_ressource->p_vout_free = NULL;
- }
- else if( p_vout )
- {
- assert( p_vout != p_ressource->p_vout_free );
-
- vlc_mutex_lock( &p_ressource->lock_vout );
- TAB_REMOVE( p_ressource->i_vout, p_ressource->pp_vout, p_vout );
- vlc_mutex_unlock( &p_ressource->lock_vout );
- }
-
- /* */
- p_vout = vout_Request( p_ressource->p_input, p_vout, p_fmt );
- if( !p_vout )
- return NULL;
-
- DisplayVoutTitle( p_ressource, p_vout );
-
- vlc_mutex_lock( &p_ressource->lock_vout );
- TAB_APPEND( p_ressource->i_vout, p_ressource->pp_vout, p_vout );
- vlc_mutex_unlock( &p_ressource->lock_vout );
-
- return p_vout;
- }
- else
- {
- assert( p_vout );
-
- vlc_mutex_lock( &p_ressource->lock_vout );
- TAB_REMOVE( p_ressource->i_vout, p_ressource->pp_vout, p_vout );
- const int i_vout_active = p_ressource->i_vout;
- vlc_mutex_unlock( &p_ressource->lock_vout );
-
- if( p_ressource->p_vout_free || i_vout_active > 0 || !b_recycle )
- {
- if( b_recycle )
- msg_Dbg( p_ressource->p_input, "detroying vout (already one saved or active)" );
- vout_CloseAndRelease( p_vout );
- }
- else
- {
- msg_Dbg( p_ressource->p_input, "saving a free vout" );
- vout_Flush( p_vout, 1 );
- spu_Control( p_vout->p_spu, SPU_CHANNEL_CLEAR, -1 );
-
- p_ressource->p_vout_free = p_vout;
- }
- return NULL;
- }
-}
-static vout_thread_t *HoldVout( input_ressource_t *p_ressource )
-{
- if( p_ressource->i_vout <= 0 )
- return NULL;
-
- /* TODO FIXME: p_ressource->pp_vout order is NOT stable */
- vlc_mutex_lock( &p_ressource->lock_vout );
-
- vout_thread_t *p_vout = p_ressource->pp_vout[0];
-
- vlc_object_hold( p_vout );
-
- vlc_mutex_unlock( &p_ressource->lock_vout );
-
- return p_vout;
-}
-static void HoldVouts( input_ressource_t *p_ressource, vout_thread_t ***ppp_vout, int *pi_vout )
-{
- vout_thread_t **pp_vout;
-
- *pi_vout = 0;
- *ppp_vout = NULL;
-
- vlc_mutex_lock( &p_ressource->lock_vout );
-
- if( p_ressource->i_vout <= 0 )
- goto exit;
-
- pp_vout = calloc( p_ressource->i_vout, sizeof(*pp_vout) );
- if( !pp_vout )
- goto exit;
-
- *ppp_vout = pp_vout;
- *pi_vout = p_ressource->i_vout;
-
- for( int i = 0; i < p_ressource->i_vout; i++ )
- {
- pp_vout[i] = p_ressource->pp_vout[i];
- vlc_object_hold( pp_vout[i] );
- }
-
-exit:
- vlc_mutex_unlock( &p_ressource->lock_vout );
-}
-
-/* */
-static void DestroyAout( input_ressource_t *p_ressource )
-{
- if( p_ressource->p_aout )
- vlc_object_release( p_ressource->p_aout );
- p_ressource->p_aout = NULL;
-}
-static aout_instance_t *RequestAout( input_ressource_t *p_ressource, aout_instance_t *p_aout )
-{
- assert( p_ressource->p_input );
-
- if( p_aout )
- {
- msg_Dbg( p_ressource->p_input, "releasing aout" );
- vlc_object_release( p_aout );
- return NULL;
- }
- else
- {
- if( !p_ressource->p_aout )
- {
- msg_Dbg( p_ressource->p_input, "creating aout" );
- p_ressource->p_aout = aout_New( p_ressource->p_input );
- }
- else
- {
- msg_Dbg( p_ressource->p_input, "reusing aout" );
- }
-
- if( !p_ressource->p_aout )
- return NULL;
-
- vlc_object_detach( p_ressource->p_aout );
- vlc_object_attach( p_ressource->p_aout, p_ressource->p_input );
- vlc_object_hold( p_ressource->p_aout );
- return p_ressource->p_aout;
- }
-}
-static aout_instance_t *HoldAout( input_ressource_t *p_ressource )
-{
- if( !p_ressource->p_aout )
- return NULL;
-
- aout_instance_t *p_aout = p_ressource->p_aout;
-
- vlc_object_hold( p_aout );
-
- return p_aout;
-}
-
-/* */
-input_ressource_t *input_ressource_New( void )
-{
- input_ressource_t *p_ressource = calloc( 1, sizeof(*p_ressource) );
- if( !p_ressource )
- return NULL;
-
- vlc_mutex_init( &p_ressource->lock );
- vlc_mutex_init( &p_ressource->lock_vout );
- return p_ressource;
-}
-
-void input_ressource_Delete( input_ressource_t *p_ressource )
-{
- DestroySout( p_ressource );
- DestroyVout( p_ressource );
- DestroyAout( p_ressource );
-
- vlc_mutex_destroy( &p_ressource->lock_vout );
- vlc_mutex_destroy( &p_ressource->lock );
- free( p_ressource );
-}
-
-void input_ressource_SetInput( input_ressource_t *p_ressource, input_thread_t *p_input )
-{
- vlc_mutex_lock( &p_ressource->lock );
-
- if( p_ressource->p_input && !p_input )
- {
- if( p_ressource->p_aout )
- vlc_object_detach( p_ressource->p_aout );
-
- assert( p_ressource->i_vout == 0 );
- if( p_ressource->p_vout_free )
- vlc_object_detach( p_ressource->p_vout_free );
-
- if( p_ressource->p_sout )
- vlc_object_detach( p_ressource->p_sout );
- }
-
- /* */
- p_ressource->p_input = p_input;
-
- vlc_mutex_unlock( &p_ressource->lock );
-}
-
-vout_thread_t *input_ressource_RequestVout( input_ressource_t *p_ressource,
- vout_thread_t *p_vout, video_format_t *p_fmt, bool b_recycle )
-{
- vlc_mutex_lock( &p_ressource->lock );
- vout_thread_t *p_ret = RequestVout( p_ressource, p_vout, p_fmt, b_recycle );
- vlc_mutex_unlock( &p_ressource->lock );
-
- return p_ret;
-}
-vout_thread_t *input_ressource_HoldVout( input_ressource_t *p_ressource )
-{
- return HoldVout( p_ressource );
-}
-void input_ressource_HoldVouts( input_ressource_t *p_ressource, vout_thread_t ***ppp_vout, int *pi_vout )
-{
- HoldVouts( p_ressource, ppp_vout, pi_vout );
-}
-void input_ressource_TerminateVout( input_ressource_t *p_ressource )
-{
- input_ressource_RequestVout( p_ressource, NULL, NULL, false );
-}
-bool input_ressource_HasVout( input_ressource_t *p_ressource )
-{
- vlc_mutex_lock( &p_ressource->lock );
- assert( !p_ressource->p_input );
- const bool b_vout = p_ressource->p_vout_free != NULL;
- vlc_mutex_unlock( &p_ressource->lock );
-
- return b_vout;
-}
-
-/* */
-aout_instance_t *input_ressource_RequestAout( input_ressource_t *p_ressource, aout_instance_t *p_aout )
-{
- vlc_mutex_lock( &p_ressource->lock );
- aout_instance_t *p_ret = RequestAout( p_ressource, p_aout );
- vlc_mutex_unlock( &p_ressource->lock );
-
- return p_ret;
-}
-aout_instance_t *input_ressource_HoldAout( input_ressource_t *p_ressource )
-{
- vlc_mutex_lock( &p_ressource->lock );
- aout_instance_t *p_ret = HoldAout( p_ressource );
- vlc_mutex_unlock( &p_ressource->lock );
-
- return p_ret;
-}
-/* */
-sout_instance_t *input_ressource_RequestSout( input_ressource_t *p_ressource, sout_instance_t *p_sout, const char *psz_sout )
-{
- vlc_mutex_lock( &p_ressource->lock );
- sout_instance_t *p_ret = RequestSout( p_ressource, p_sout, psz_sout );
- vlc_mutex_unlock( &p_ressource->lock );
-
- return p_ret;
-}
-void input_ressource_TerminateSout( input_ressource_t *p_ressource )
-{
- input_ressource_RequestSout( p_ressource, NULL, NULL );
-}
-
p_instance->i_index = 0;
p_instance->b_sout_keep = false;
p_instance->p_input = NULL;
- p_instance->p_input_ressource = NULL;
+ p_instance->p_input_resource = NULL;
return p_instance;
}
input_thread_t *p_input = p_instance->p_input;
if( p_input )
{
- input_ressource_t *p_ressource;
+ input_resource_t *p_resource;
input_StopThread( p_input );
vlc_thread_join( p_input );
- p_ressource = input_DetachRessource( p_input );
- input_ressource_Delete( p_ressource );
+ p_resource = input_DetachRessource( p_input );
+ input_resource_Delete( p_resource );
vlc_object_release( p_input );
}
- if( p_instance->p_input_ressource )
- input_ressource_Delete( p_instance->p_input_ressource );
+ if( p_instance->p_input_resource )
+ input_resource_Delete( p_instance->p_input_resource );
vlc_gc_decref( p_instance->p_item );
free( p_instance->psz_name );
input_StopThread( p_input );
vlc_thread_join( p_input );
- p_instance->p_input_ressource = input_DetachRessource( p_input );
+ p_instance->p_input_resource = input_DetachRessource( p_input );
vlc_object_release( p_input );
if( !p_instance->b_sout_keep )
- input_ressource_TerminateSout( p_instance->p_input_ressource );
- input_ressource_TerminateVout( p_instance->p_input_ressource );
+ input_resource_TerminateSout( p_instance->p_input_resource );
+ input_resource_TerminateVout( p_instance->p_input_resource );
}
/* Start new one */
if( asprintf( &psz_log, _("Media: %s"), p_media->cfg.psz_name ) != -1 )
{
p_instance->p_input = input_CreateThreadExtended( p_vlm, p_instance->p_item,
- psz_log, p_instance->p_input_ressource );
- p_instance->p_input_ressource = NULL;
+ psz_log, p_instance->p_input_resource );
+ p_instance->p_input_resource = NULL;
if( !p_instance->p_input )
{
input_item_t *p_item;
input_thread_t *p_input;
- input_ressource_t *p_input_ressource;
+ input_resource_t *p_input_resource;
} vlm_media_instance_sys_t;
* Destroy the message queues
*
* This functions prints all messages remaining in the queues,
- * then frees all the allocated ressources
+ * then frees all the allocated resources
* No other messages interface functions should be called after this one.
*/
void msg_Destroy (libvlc_int_t *p_libvlc)
playlist_private_t *p_sys = pl_priv(p_playlist);
assert( !p_sys->p_input );
- assert( !p_sys->p_input_ressource );
+ assert( !p_sys->p_input_resource );
assert( !p_sys->p_preparser );
assert( !p_sys->p_fetcher );
int i_sds; /**< Number of service discovery modules */
input_thread_t * p_input; /**< the input thread associated
* with the current item */
- input_ressource_t * p_input_ressource; /**< input ressources */
+ input_resource_t * p_input_resource; /**< input resources */
struct {
/* Current status. These fields are readonly, only the playlist
* main loop can touch it*/
if( p_fetcher )
playlist_fetcher_Delete( p_fetcher );
- /* release input ressources */
- if( p_sys->p_input_ressource )
- input_ressource_Delete( p_sys->p_input_ressource );
- p_sys->p_input_ressource = NULL;
+ /* release input resources */
+ if( p_sys->p_input_resource )
+ input_resource_Delete( p_sys->p_input_resource );
+ p_sys->p_input_resource = NULL;
/* */
playlist_MLDump( p_playlist );
assert( p_sys->p_input == NULL );
input_thread_t *p_input_thread =
- input_CreateThreadExtended( p_playlist, p_input, NULL, p_sys->p_input_ressource );
+ input_CreateThreadExtended( p_playlist, p_input, NULL, p_sys->p_input_resource );
if( p_input_thread )
{
var_AddCallback( p_input_thread, "intf-event", InputEvent, p_playlist );
}
- p_sys->p_input_ressource = NULL;
+ p_sys->p_input_resource = NULL;
char *psz_uri = input_item_GetURI( p_item->p_input );
if( psz_uri && ( !strncmp( psz_uri, "directory:", 10 ) ||
{
PL_DEBUG( "dead input" );
- assert( p_sys->p_input_ressource == NULL );
+ assert( p_sys->p_input_resource == NULL );
- p_sys->p_input_ressource = input_DetachRessource( p_input );
+ p_sys->p_input_resource = input_DetachRessource( p_input );
PL_UNLOCK;
/* We can unlock as we return VLC_EGENERIC (no event will be lost) */
- /* input_ressource_t must be manipulated without playlist lock */
+ /* input_resource_t must be manipulated without playlist lock */
if( !var_CreateGetBool( p_input, "sout-keep" ) )
- input_ressource_TerminateSout( p_sys->p_input_ressource );
+ input_resource_TerminateSout( p_sys->p_input_resource );
/* The DelCallback must be issued without playlist lock */
var_DelCallback( p_input, "intf-event", InputEvent, p_playlist );
{
p_sys->status.i_status = PLAYLIST_STOPPED;
- if( p_sys->p_input_ressource &&
- input_ressource_HasVout( p_sys->p_input_ressource ) )
+ if( p_sys->p_input_resource &&
+ input_resource_HasVout( p_sys->p_input_resource ) )
{
/* XXX We can unlock if we don't issue the wait as we will be
* call again without anything else done between the calls */
PL_UNLOCK;
- /* input_ressource_t must be manipulated without playlist lock */
- input_ressource_TerminateVout( p_sys->p_input_ressource );
+ /* input_resource_t must be manipulated without playlist lock */
+ input_resource_TerminateVout( p_sys->p_input_resource );
PL_LOCK;
}