VLC_EXPORT( char *, input_CreateFilename, ( vlc_object_t *, const char *psz_path, const char *psz_prefix, const char *psz_extension ) );
/**
- * This function detaches resources from a dead input.
+ * It creates an empty input resource handler.
*
- * It MUST be called on a dead input (p_input->b_dead true) otherwise
- * it will assert.
- * It does not support concurrent calls.
+ * The given object MUST stay alive as long as the input_resource_t is
+ * not deleted.
*/
-VLC_EXPORT(input_resource_t *, input_DetachResource, ( input_thread_t * ) );
+VLC_EXPORT( input_resource_t *, input_resource_New, ( vlc_object_t * ) );
/**
- * This function releases the input resource.
+ * It deletes an input resource.
*/
VLC_EXPORT(void, input_resource_Delete, ( input_resource_t * ) );
assert( p_input_thread->b_dead );
- /* Store the input resource for future use. */
- assert( p_mi->input.p_resource == NULL );
- p_mi->input.p_resource = input_DetachResource( p_input_thread );
-
p_mi->input.p_thread = NULL;
vlc_object_release( p_input_thread );
}
return -1;
}
+ if( !p_mi->input.p_resource )
+ p_mi->input.p_resource = input_resource_New( VLC_OBJECT( p_mi ) );
p_input_thread = input_Create( p_mi, p_mi->p_md->p_input_item, NULL,
p_mi->input.p_resource );
unlock(p_mi);
return -1;
}
- p_mi->input.p_resource = NULL;
-
var_AddCallback( p_input_thread, "can-seek", input_seekable_changed, p_mi );
var_AddCallback( p_input_thread, "can-pause", input_pausable_changed, p_mi );
var_AddCallback( p_input_thread, "intf-event", input_event_changed, p_mi );
input_ControlPush( p_input, INPUT_CONTROL_SET_DIE, NULL );
}
-input_resource_t *input_DetachResource( input_thread_t *p_input )
-{
- assert( p_input->b_dead );
-
- input_resource_SetInput( p_input->p->p_resource, NULL );
-
- input_resource_t *p_resource = input_resource_Detach( p_input->p->p_resource );
- p_input->p->p_sout = NULL;
-
- return p_resource;
-}
-
/**
* Get the item from an input thread
* FIXME it does not increase ref count of the item.
/* */
if( p_resource )
+ {
+ p_input->p->p_resource_private = NULL;
p_input->p->p_resource = p_resource;
+ }
else
- p_input->p->p_resource = input_resource_New();
+ {
+ p_input->p->p_resource_private = input_resource_New( VLC_OBJECT( p_input ) );
+ p_input->p->p_resource = p_input->p->p_resource_private;
+ }
input_resource_SetInput( p_input->p->p_resource, p_input );
/* Init control buffer */
if( p_input->p->p_es_out_display )
es_out_Delete( p_input->p->p_es_out_display );
- if( p_input->p->p_resource )
- input_resource_Delete( p_input->p->p_resource );
+ if( p_input->p->p_resource_private )
+ input_resource_Delete( p_input->p->p_resource_private );
vlc_gc_decref( p_input->p->p_item );
input_resource_RequestSout( p_input->p->p_resource,
p_input->p->p_sout, NULL );
input_resource_SetInput( p_input->p->p_resource, NULL );
+ if( p_input->p->p_resource_private )
+ input_resource_Terminate( p_input->p->p_resource_private );
}
if( !p_input->b_preparsing && libvlc_stats( p_input ) )
input_resource_RequestSout( p_input->p->p_resource,
p_input->p->p_sout, NULL );
input_resource_SetInput( p_input->p->p_resource, NULL );
+ if( p_input->p->p_resource_private )
+ input_resource_Terminate( p_input->p->p_resource_private );
}
/*****************************************************************************
/* Resources */
input_resource_t *p_resource;
+ input_resource_t *p_resource_private;
/* Stats counters */
struct {
struct input_resource_t
{
+ vlc_object_t *p_parent;
+
/* This lock is used to serialize request and protect
* our variables */
vlc_mutex_t lock;
p_resource->p_sout = NULL;
}
-static sout_instance_t *DetachSout( input_resource_t *p_resource )
-{
- sout_instance_t *p_sout = p_resource->p_sout;
- p_resource->p_sout = NULL;
-
- return p_sout;
-}
-
static sout_instance_t *RequestSout( input_resource_t *p_resource,
sout_instance_t *p_sout, const char *psz_sout )
{
if( p_resource->p_sout &&
strcmp( p_resource->p_sout->psz_sout, psz_sout ) )
{
- msg_Dbg( p_resource->p_input, "destroying unusable sout" );
+ msg_Dbg( p_resource->p_parent, "destroying unusable sout" );
DestroySout( p_resource );
}
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 );
+ msg_Dbg( p_resource->p_parent, "reusing sout" );
+ msg_Dbg( p_resource->p_parent, "you probably want to use gather stream_out" );
}
else
{
/* Create a new one */
- p_resource->p_sout = sout_NewInstance( p_resource->p_input, psz_sout );
+ p_resource->p_sout = sout_NewInstance( p_resource->p_parent, psz_sout );
}
p_sout = p_resource->p_sout;
}
else
{
- vlc_object_detach( p_sout );
p_resource->p_sout = p_sout;
-
return NULL;
}
#else
p_resource->p_vout_free = NULL;
}
-static vout_thread_t *DetachVout( input_resource_t *p_resource )
-{
- vlc_assert_locked( &p_resource->lock );
- assert( p_resource->i_vout == 0 );
- vout_thread_t *p_vout = p_resource->p_vout_free;
- p_resource->p_vout_free = NULL;
-
- return p_vout;
-}
static void DisplayVoutTitle( input_resource_t *p_resource,
vout_thread_t *p_vout )
/* */
if( !p_vout && p_resource->p_vout_free )
{
- msg_Dbg( p_resource->p_input, "trying to reuse free vout" );
+ msg_Dbg( p_resource->p_parent, "trying to reuse free vout" );
p_vout = p_resource->p_vout_free;
p_resource->p_vout_free = NULL;
.fmt = p_fmt,
.dpb_size = dpb_size,
};
- p_vout = vout_Request( p_resource->p_input, &cfg );
+ p_vout = vout_Request( p_resource->p_parent, &cfg );
if( !p_vout )
return NULL;
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)" );
+ msg_Dbg( p_resource->p_parent, "detroying vout (already one saved or active)" );
vout_CloseAndRelease( p_vout );
}
else
{
- msg_Dbg( p_resource->p_input, "saving a free vout" );
+ msg_Dbg( p_resource->p_parent, "saving a free vout" );
vout_Flush( p_vout, 1 );
vout_FlushSubpictureChannel( p_vout, -1 );
.fmt = NULL,
.dpb_size = 0,
};
- p_resource->p_vout_free = vout_Request( p_resource->p_input, &cfg );
+ p_resource->p_vout_free = vout_Request( p_resource->p_parent, &cfg );
}
return NULL;
}
vlc_object_release( p_resource->p_aout );
p_resource->p_aout = NULL;
}
-static aout_instance_t *DetachAout( input_resource_t *p_resource )
-{
- vlc_assert_locked( &p_resource->lock );
- vlc_mutex_lock( &p_resource->lock_hold );
-
- aout_instance_t *p_aout = p_resource->p_aout;
- p_resource->p_aout = NULL;
-
- vlc_mutex_unlock( &p_resource->lock_hold );
-
- return p_aout;
-}
-
static aout_instance_t *RequestAout( input_resource_t *p_resource, aout_instance_t *p_aout )
{
vlc_assert_locked( &p_resource->lock );
if( p_aout )
{
- msg_Dbg( p_resource->p_input, "releasing aout" );
+ msg_Dbg( p_resource->p_parent, "releasing aout" );
vlc_object_release( p_aout );
return NULL;
}
p_aout = p_resource->p_aout;
if( !p_aout )
{
- msg_Dbg( p_resource->p_input, "creating aout" );
- p_aout = aout_New( p_resource->p_input );
+ msg_Dbg( p_resource->p_parent, "creating aout" );
+ p_aout = aout_New( p_resource->p_parent );
vlc_mutex_lock( &p_resource->lock_hold );
p_resource->p_aout = p_aout;
}
else
{
- msg_Dbg( p_resource->p_input, "reusing aout" );
+ msg_Dbg( p_resource->p_parent, "reusing aout" );
}
if( !p_aout )
return NULL;
-
- vlc_object_detach( p_aout );
- vlc_object_attach( p_aout, p_resource->p_input );
vlc_object_hold( p_aout );
return p_aout;
}
return p_aout;
}
+static void TerminateAout( input_resource_t *p_resource )
+{
+ vlc_mutex_lock( &p_resource->lock_hold );
+
+ aout_instance_t *p_aout = p_resource->p_aout;
+ p_resource->p_aout = NULL;
+
+ vlc_mutex_unlock( &p_resource->lock_hold );
+
+ if( p_aout )
+ vlc_object_release( p_aout );
+}
+
/* */
-input_resource_t *input_resource_New( void )
+input_resource_t *input_resource_New( vlc_object_t *p_parent )
{
input_resource_t *p_resource = calloc( 1, sizeof(*p_resource) );
if( !p_resource )
return NULL;
+ p_resource->p_parent = p_parent;
vlc_mutex_init( &p_resource->lock );
vlc_mutex_init( &p_resource->lock_hold );
return p_resource;
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 );
}
-input_resource_t *input_resource_Detach( input_resource_t *p_resource )
-{
- input_resource_t *p_ret = input_resource_New();
- if( !p_ret )
- return NULL;
-
- vlc_mutex_lock( &p_resource->lock );
- assert( !p_resource->p_input );
- p_ret->p_sout = DetachSout( p_resource );
- p_ret->p_vout_free = DetachVout( p_resource );
- p_ret->p_aout = DetachAout( p_resource );
- vlc_mutex_unlock( &p_resource->lock );
-
- return p_ret;
-}
-
vout_thread_t *input_resource_RequestVout( input_resource_t *p_resource,
vout_thread_t *p_vout,
video_format_t *p_fmt, unsigned dpb_size,
{
return HoldAout( p_resource );
}
+
/* */
sout_instance_t *input_resource_RequestSout( input_resource_t *p_resource, sout_instance_t *p_sout, const char *psz_sout )
{
input_resource_RequestSout( p_resource, NULL, NULL );
}
+void input_resource_Terminate( input_resource_t *p_resource )
+{
+ input_resource_TerminateSout( p_resource );
+
+ vlc_mutex_lock( &p_resource->lock );
+ TerminateAout( p_resource );
+ vlc_mutex_unlock( &p_resource->lock );
+
+ input_resource_TerminateVout( p_resource );
+}
+
#include <vlc_common.h>
-/**
- * This function creates an empty input_resource_t.
- */
-input_resource_t *input_resource_New( void );
-
/**
* This function set the associated input.
*/
void input_resource_SetInput( input_resource_t *, input_thread_t * );
-/**
- * This function return a input_resource_t with all resources detach from the
- * given input_resource_t.
- * It must not be associated to an input.
- */
-input_resource_t *input_resource_Detach( input_resource_t * );
-
/**
* This function handles sout request.
*/
*/
void input_resource_HoldVouts( input_resource_t *, vout_thread_t ***, size_t * );
+/**
+ * This function releases all resources (object).
+ */
+void input_resource_Terminate( input_resource_t * );
+
#endif
input_thread_t *p_input = p_instance->p_input;
if( p_input )
{
- input_resource_t *p_resource;
-
input_Stop( p_input, true );
vlc_thread_join( p_input );
- p_resource = input_DetachResource( p_input );
- input_resource_Delete( p_resource );
-
var_DelCallback( p_instance->p_input, "intf-event", InputEvent, p_media );
vlc_object_release( p_input );
input_Stop( p_input, true );
vlc_thread_join( p_input );
- p_instance->p_input_resource = input_DetachResource( p_input );
-
var_DelCallback( p_instance->p_input, "intf-event", InputEvent, p_media );
vlc_object_release( p_input );
vlc_object_t *p_parent = p_media->cfg.b_vod ?
VLC_OBJECT(p_vlm->p_vod) :
VLC_OBJECT(p_vlm->p_libvlc);
+ if( !p_instance->p_input_resource )
+ p_instance->p_input_resource = input_resource_New( VLC_OBJECT( p_vlm ) );
p_instance->p_input = input_Create( p_parent, p_instance->p_item,
psz_log, p_instance->p_input_resource );
if( p_instance->p_input )
p_instance->p_input = NULL;
}
}
- p_instance->p_input_resource = NULL;
if( !p_instance->p_input )
{
input_DecoderDecode
input_DecoderDelete
input_DecoderNew
-input_DetachResource
input_GetItem
input_item_AddInfo
input_item_AddOption
input_item_SetURI
input_item_WriteMeta
input_Read
+input_resource_New
input_resource_Delete
input_SplitMRL
input_Start
assert( p_sys->p_input == NULL );
+ if( !p_sys->p_input_resource )
+ p_sys->p_input_resource = input_resource_New( VLC_OBJECT( p_playlist ) );
input_thread_t *p_input_thread = input_Create( p_playlist, p_input, NULL, p_sys->p_input_resource );
if( p_input_thread )
{
}
}
- p_sys->p_input_resource = NULL;
-
char *psz_uri = input_item_GetURI( p_item->p_input );
if( psz_uri && ( !strncmp( psz_uri, "directory:", 10 ) ||
!strncmp( psz_uri, "vlc:", 4 ) ) )
{
PL_DEBUG( "dead input" );
- assert( p_sys->p_input_resource == NULL );
-
- p_sys->p_input_resource = input_DetachResource( p_input );
-
PL_UNLOCK;
/* We can unlock as we return VLC_EGENERIC (no event will be lost) */
/* If a vout is provided, try reusing it */
if (vout) {
- vlc_object_detach(vout);
- vlc_object_attach(vout, object);
-
if (vout->p->input != cfg->input) {
if (vout->p->input)
spu_Attach(vout->p->p_spu, vout->p->input, false);