(This way it matches input_CreateThread and fixes a memleak)
Control variables are now created even for preparse, only callback are not added.
(This fix use of uninitialized variables)
{
input_StopThread( p_sd->p_sys->pp_input[i] );
input_DestroyThread( p_sd->p_sys->pp_input[i] );
{
input_StopThread( p_sd->p_sys->pp_input[i] );
input_DestroyThread( p_sd->p_sys->pp_input[i] );
- vlc_object_detach( p_sd->p_sys->pp_input[i] );
- vlc_object_destroy( p_sd->p_sys->pp_input[i] );
p_sd->p_sys->pp_input[i] = NULL;
}
}
p_sd->p_sys->pp_input[i] = NULL;
}
}
{
input_StopThread( p_sd->p_sys->pp_input[i] );
input_DestroyThread( p_sd->p_sys->pp_input[i] );
{
input_StopThread( p_sd->p_sys->pp_input[i] );
input_DestroyThread( p_sd->p_sys->pp_input[i] );
- vlc_object_detach( p_sd->p_sys->pp_input[i] );
- vlc_object_destroy( p_sd->p_sys->pp_input[i] );
p_sd->p_sys->pp_input[i] = NULL;
}
}
p_sd->p_sys->pp_input[i] = NULL;
}
}
* Local prototypes
*****************************************************************************/
static int Run ( input_thread_t *p_input );
* Local prototypes
*****************************************************************************/
static int Run ( input_thread_t *p_input );
-static int RunAndClean ( input_thread_t *p_input );
+static int RunAndDestroy ( input_thread_t *p_input );
static input_thread_t * Create ( vlc_object_t *, input_item_t *,
const char *, vlc_bool_t );
static input_thread_t * Create ( vlc_object_t *, input_item_t *,
const char *, vlc_bool_t );
input_ConfigVarInit( p_input );
/* Create Objects variables for public Get and Set */
input_ConfigVarInit( p_input );
/* Create Objects variables for public Get and Set */
- if( !p_input->b_preparsing )
- input_ControlVarInit( p_input );
+ input_ControlVarInit( p_input );
p_input->p->input.i_cr_average = var_GetInteger( p_input, "cr-average" );
p_input->p->input.i_cr_average = var_GetInteger( p_input, "cr-average" );
input_Control( p_input, INPUT_DEL_INFO, _(VLC_META_INFO_CAT),
VLC_META_NOW_PLAYING ); /* ? Don't translate as it might has been copied ? */
input_Control( p_input, INPUT_DEL_INFO, _(VLC_META_INFO_CAT),
VLC_META_NOW_PLAYING ); /* ? Don't translate as it might has been copied ? */
+ /* */
+ if( p_input->b_preparsing )
+ p_input->i_flags |= OBJECT_FLAGS_QUIET | OBJECT_FLAGS_NOINTERACT;
+
+ /* Attach only once we are ready */
+ vlc_object_attach( p_input, p_parent );
+
+static void Destroy( input_thread_t *p_input )
+{
+ vlc_object_detach( p_input );
+
+ vlc_mutex_destroy( &p_input->p->lock_control );
+ free( p_input->p );
+
+ vlc_object_destroy( p_input );
+}
/**
* Initialize an input thread and run it. You will need to monitor the
* thread to clean up after it is done
/**
* Initialize an input thread and run it. You will need to monitor the
* thread to clean up after it is done
if( !p_input )
return NULL;
if( !p_input )
return NULL;
- /* Now we can attach our new input */
- vlc_object_attach( p_input, p_parent );
-
/* Create thread and wait for its readiness. */
if( vlc_thread_create( p_input, "input", Run,
VLC_THREAD_PRIORITY_INPUT, VLC_TRUE ) )
{
input_ChangeState( p_input, ERROR_S );
msg_Err( p_input, "cannot create input thread" );
/* Create thread and wait for its readiness. */
if( vlc_thread_create( p_input, "input", Run,
VLC_THREAD_PRIORITY_INPUT, VLC_TRUE ) )
{
input_ChangeState( p_input, ERROR_S );
msg_Err( p_input, "cannot create input thread" );
- vlc_object_detach( p_input );
- free( p_input->p );
- vlc_object_destroy( p_input );
if( !p_input )
return VLC_EGENERIC;
if( !p_input )
return VLC_EGENERIC;
- /* Now we can attach our new input */
- vlc_object_attach( p_input, p_parent );
-
- RunAndClean( p_input );
+ RunAndDestroy( p_input );
return VLC_SUCCESS;
}
else
{
return VLC_SUCCESS;
}
else
{
- if( vlc_thread_create( p_input, "input", RunAndClean,
+ if( vlc_thread_create( p_input, "input", RunAndDestroy,
VLC_THREAD_PRIORITY_INPUT, VLC_TRUE ) )
{
input_ChangeState( p_input, ERROR_S );
msg_Err( p_input, "cannot create input thread" );
VLC_THREAD_PRIORITY_INPUT, VLC_TRUE ) )
{
input_ChangeState( p_input, ERROR_S );
msg_Err( p_input, "cannot create input thread" );
- vlc_object_detach( p_input );
- free( p_input->p );
- vlc_object_destroy( p_input );
if( !p_input )
return VLC_EGENERIC;
if( !p_input )
return VLC_EGENERIC;
- p_input->i_flags |= OBJECT_FLAGS_QUIET;
- p_input->i_flags |= OBJECT_FLAGS_NOINTERACT;
-
- /* Now we can attach our new input */
- vlc_object_attach( p_input, p_parent );
-
Init( p_input );
/* Clean up master */
InputSourceClean( p_input, &p_input->p->input );
Init( p_input );
/* Clean up master */
InputSourceClean( p_input, &p_input->p->input );
+ /* FIXME shouldn't we call End() to ? */
+
/* Unload all modules */
if( p_input->p->p_es_out ) input_EsOutDelete( p_input->p->p_es_out );
/* Unload all modules */
if( p_input->p->p_es_out ) input_EsOutDelete( p_input->p->p_es_out );
- vlc_object_detach( p_input );
- free( p_input->p );
- vlc_object_destroy( p_input );
/* Join the thread */
vlc_thread_join( p_input );
/* Join the thread */
vlc_thread_join( p_input );
- /* Delete input lock (only after thread joined) */
- vlc_mutex_destroy( &p_input->p->lock_control );
-
- /* TODO: maybe input_DestroyThread should also delete p_input instead
- * of the playlist but I'm not sure if it's possible */
+ /* */
+ Destroy( p_input );
}
/*****************************************************************************
}
/*****************************************************************************
}
/*****************************************************************************
}
/*****************************************************************************
- * RunAndClean: main thread loop
+ * RunAndDestroy: main thread loop
* This is the "just forget me" thread that spawns the input processing chain,
* reads the stream, cleans up and releases memory
*****************************************************************************/
* This is the "just forget me" thread that spawns the input processing chain,
* reads the stream, cleans up and releases memory
*****************************************************************************/
-static int RunAndClean( input_thread_t *p_input )
+static int RunAndDestroy( input_thread_t *p_input )
{
/* Signal that the thread is launched */
vlc_thread_ready( p_input );
if( Init( p_input ) )
{
/* Signal that the thread is launched */
vlc_thread_ready( p_input );
if( Init( p_input ) )
- {
- /* If we failed, just exit */
- return 0;
- }
/* Clean up */
End( p_input );
/* Clean up */
End( p_input );
- vlc_object_detach( p_input );
- free( p_input->p );
- vlc_object_destroy( p_input );
-
- msg_Dbg( p_input, "closing input" );
-
/* We are at the end */
input_ChangeState( p_input, END_S );
/* Clean control variables */
/* We are at the end */
input_ChangeState( p_input, END_S );
/* Clean control variables */
- if( !p_input->b_preparsing )
- input_ControlVarClean( p_input );
+ input_ControlVarClean( p_input );
/* Clean up master */
InputSourceClean( p_input, &p_input->p->input );
/* Clean up master */
InputSourceClean( p_input, &p_input->p->input );
+ /* XXX we put callback only in non preparsing mode. We need to create the variable
+ * unless someone want to check all var_Get/var_Change return value ... */
+#define ADD_CALLBACK( name, callback ) do { if( !p_input->b_preparsing ) { var_AddCallback( p_input, name, callback, NULL ); } } while(0)
/* State */
var_Create( p_input, "state", VLC_VAR_INTEGER );
val.i_int = p_input->i_state;
var_Change( p_input, "state", VLC_VAR_SETVALUE, &val, NULL );
/* State */
var_Create( p_input, "state", VLC_VAR_INTEGER );
val.i_int = p_input->i_state;
var_Change( p_input, "state", VLC_VAR_SETVALUE, &val, NULL );
- var_AddCallback( p_input, "state", StateCallback, NULL );
+ ADD_CALLBACK( "state", StateCallback );
/* Rate */
var_Create( p_input, "rate", VLC_VAR_INTEGER );
val.i_int = p_input->p->i_rate;
var_Change( p_input, "rate", VLC_VAR_SETVALUE, &val, NULL );
/* Rate */
var_Create( p_input, "rate", VLC_VAR_INTEGER );
val.i_int = p_input->p->i_rate;
var_Change( p_input, "rate", VLC_VAR_SETVALUE, &val, NULL );
- var_AddCallback( p_input, "rate", RateCallback, NULL );
+ ADD_CALLBACK( "rate", RateCallback );
var_Create( p_input, "rate-slower", VLC_VAR_VOID );
var_Create( p_input, "rate-slower", VLC_VAR_VOID );
- var_AddCallback( p_input, "rate-slower", RateCallback, NULL );
+ ADD_CALLBACK( "rate-slower", RateCallback );
var_Create( p_input, "rate-faster", VLC_VAR_VOID );
var_Create( p_input, "rate-faster", VLC_VAR_VOID );
- var_AddCallback( p_input, "rate-faster", RateCallback, NULL );
+ ADD_CALLBACK( "rate-faster", RateCallback );
/* Position */
var_Create( p_input, "position", VLC_VAR_FLOAT );
var_Create( p_input, "position-offset", VLC_VAR_FLOAT );
val.f_float = 0.0;
var_Change( p_input, "position", VLC_VAR_SETVALUE, &val, NULL );
/* Position */
var_Create( p_input, "position", VLC_VAR_FLOAT );
var_Create( p_input, "position-offset", VLC_VAR_FLOAT );
val.f_float = 0.0;
var_Change( p_input, "position", VLC_VAR_SETVALUE, &val, NULL );
- var_AddCallback( p_input, "position", PositionCallback, NULL );
- var_AddCallback( p_input, "position-offset", PositionCallback, NULL );
+ ADD_CALLBACK( "position", PositionCallback );
+ ADD_CALLBACK( "position-offset", PositionCallback );
/* Time */
var_Create( p_input, "time", VLC_VAR_TIME );
var_Create( p_input, "time-offset", VLC_VAR_TIME ); /* relative */
val.i_time = 0;
var_Change( p_input, "time", VLC_VAR_SETVALUE, &val, NULL );
/* Time */
var_Create( p_input, "time", VLC_VAR_TIME );
var_Create( p_input, "time-offset", VLC_VAR_TIME ); /* relative */
val.i_time = 0;
var_Change( p_input, "time", VLC_VAR_SETVALUE, &val, NULL );
- var_AddCallback( p_input, "time", TimeCallback, NULL );
- var_AddCallback( p_input, "time-offset", TimeCallback, NULL );
+ ADD_CALLBACK( "time", TimeCallback );
+ ADD_CALLBACK( "time-offset", TimeCallback );
/* Bookmark */
var_Create( p_input, "bookmark", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE |
VLC_VAR_ISCOMMAND );
val.psz_string = _("Bookmark");
var_Change( p_input, "bookmark", VLC_VAR_SETTEXT, &val, NULL );
/* Bookmark */
var_Create( p_input, "bookmark", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE |
VLC_VAR_ISCOMMAND );
val.psz_string = _("Bookmark");
var_Change( p_input, "bookmark", VLC_VAR_SETTEXT, &val, NULL );
- var_AddCallback( p_input, "bookmark", BookmarkCallback, NULL );
+ ADD_CALLBACK( "bookmark", BookmarkCallback );
/* Program */
var_Create( p_input, "program", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE |
/* Program */
var_Create( p_input, "program", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE |
var_Change( p_input, "program", VLC_VAR_DELCHOICE, &val, NULL );
text.psz_string = _("Program");
var_Change( p_input, "program", VLC_VAR_SETTEXT, &text, NULL );
var_Change( p_input, "program", VLC_VAR_DELCHOICE, &val, NULL );
text.psz_string = _("Program");
var_Change( p_input, "program", VLC_VAR_SETTEXT, &text, NULL );
- var_AddCallback( p_input, "program", ProgramCallback, NULL );
+ ADD_CALLBACK( "program", ProgramCallback );
/* Programs */
var_Create( p_input, "programs", VLC_VAR_LIST | VLC_VAR_DOINHERIT );
/* Programs */
var_Create( p_input, "programs", VLC_VAR_LIST | VLC_VAR_DOINHERIT );
var_Create( p_input, "title", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
text.psz_string = _("Title");
var_Change( p_input, "title", VLC_VAR_SETTEXT, &text, NULL );
var_Create( p_input, "title", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
text.psz_string = _("Title");
var_Change( p_input, "title", VLC_VAR_SETTEXT, &text, NULL );
- var_AddCallback( p_input, "title", TitleCallback, NULL );
+ ADD_CALLBACK( "title", TitleCallback );
/* Chapter */
var_Create( p_input, "chapter", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
text.psz_string = _("Chapter");
var_Change( p_input, "chapter", VLC_VAR_SETTEXT, &text, NULL );
/* Chapter */
var_Create( p_input, "chapter", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
text.psz_string = _("Chapter");
var_Change( p_input, "chapter", VLC_VAR_SETTEXT, &text, NULL );
- var_AddCallback( p_input, "chapter", SeekpointCallback, NULL );
+ ADD_CALLBACK( "chapter", SeekpointCallback );
/* Navigation The callback is added after */
var_Create( p_input, "navigation", VLC_VAR_VARIABLE | VLC_VAR_HASCHOICE );
/* Navigation The callback is added after */
var_Create( p_input, "navigation", VLC_VAR_VARIABLE | VLC_VAR_HASCHOICE );
var_Create( p_input, "audio-delay", VLC_VAR_TIME );
val.i_time = 0;
var_Change( p_input, "audio-delay", VLC_VAR_SETVALUE, &val, NULL );
var_Create( p_input, "audio-delay", VLC_VAR_TIME );
val.i_time = 0;
var_Change( p_input, "audio-delay", VLC_VAR_SETVALUE, &val, NULL );
- var_AddCallback( p_input, "audio-delay", EsDelayCallback, NULL );
+ ADD_CALLBACK( "audio-delay", EsDelayCallback );
var_Create( p_input, "spu-delay", VLC_VAR_TIME );
val.i_time = 0;
var_Change( p_input, "spu-delay", VLC_VAR_SETVALUE, &val, NULL );
var_Create( p_input, "spu-delay", VLC_VAR_TIME );
val.i_time = 0;
var_Change( p_input, "spu-delay", VLC_VAR_SETVALUE, &val, NULL );
- var_AddCallback( p_input, "spu-delay", EsDelayCallback, NULL );
+ ADD_CALLBACK( "spu-delay", EsDelayCallback );
/* Video ES */
var_Create( p_input, "video-es", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
text.psz_string = _("Video Track");
var_Change( p_input, "video-es", VLC_VAR_SETTEXT, &text, NULL );
/* Video ES */
var_Create( p_input, "video-es", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
text.psz_string = _("Video Track");
var_Change( p_input, "video-es", VLC_VAR_SETTEXT, &text, NULL );
- var_AddCallback( p_input, "video-es", ESCallback, NULL );
+ ADD_CALLBACK( "video-es", ESCallback );
/* Audio ES */
var_Create( p_input, "audio-es", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
text.psz_string = _("Audio Track");
var_Change( p_input, "audio-es", VLC_VAR_SETTEXT, &text, NULL );
/* Audio ES */
var_Create( p_input, "audio-es", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
text.psz_string = _("Audio Track");
var_Change( p_input, "audio-es", VLC_VAR_SETTEXT, &text, NULL );
- var_AddCallback( p_input, "audio-es", ESCallback, NULL );
+ ADD_CALLBACK( "audio-es", ESCallback );
/* Spu ES */
var_Create( p_input, "spu-es", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
text.psz_string = _("Subtitles Track");
var_Change( p_input, "spu-es", VLC_VAR_SETTEXT, &text, NULL );
/* Spu ES */
var_Create( p_input, "spu-es", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
text.psz_string = _("Subtitles Track");
var_Change( p_input, "spu-es", VLC_VAR_SETTEXT, &text, NULL );
- var_AddCallback( p_input, "spu-es", ESCallback, NULL );
+ ADD_CALLBACK( "spu-es", ESCallback );
/* Special read only objects variables for intf */
var_Create( p_input, "bookmarks", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
/* Special read only objects variables for intf */
var_Create( p_input, "bookmarks", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
val.i_time = 0;
var_Change( p_input, "length", VLC_VAR_SETVALUE, &val, NULL );
val.i_time = 0;
var_Change( p_input, "length", VLC_VAR_SETVALUE, &val, NULL );
- /* Special "intf-change" variable, it allows intf to set up a callback
- * to be notified of some changes.
- * TODO list all changes warn by this callbacks */
- var_Create( p_input, "intf-change", VLC_VAR_BOOL );
- var_SetBool( p_input, "intf-change", VLC_TRUE );
-
- /* item-change variable */
- var_Create( p_input, "item-change", VLC_VAR_INTEGER );
+ if( !p_input->b_preparsing )
+ {
+ /* Special "intf-change" variable, it allows intf to set up a callback
+ * to be notified of some changes.
+ * TODO list all changes warn by this callbacks */
+ var_Create( p_input, "intf-change", VLC_VAR_BOOL );
+ var_SetBool( p_input, "intf-change", VLC_TRUE );
+
+ /* item-change variable */
+ var_Create( p_input, "item-change", VLC_VAR_INTEGER );
+ }
+#undef ADD_CALLBACK
}
/*****************************************************************************
}
/*****************************************************************************
input_StopThread( p_input );
input_DestroyThread( p_input );
input_StopThread( p_input );
input_DestroyThread( p_input );
- vlc_object_detach( p_input );
- vlc_object_destroy( p_input );
}
free( psz_output );
free( psz_header );
}
free( psz_output );
free( psz_header );
{
input_StopThread( p_instance->p_input );
input_DestroyThread( p_instance->p_input );
{
input_StopThread( p_instance->p_input );
input_DestroyThread( p_instance->p_input );
- vlc_object_detach( p_instance->p_input );
- vlc_object_destroy( p_instance->p_input );
}
asprintf( &psz_header, _("Media: %s"), media->psz_name );
}
asprintf( &psz_header, _("Media: %s"), media->psz_name );
{
input_StopThread( p_instance->p_input );
input_DestroyThread( p_instance->p_input );
{
input_StopThread( p_instance->p_input );
input_DestroyThread( p_instance->p_input );
- vlc_object_detach( p_instance->p_input );
- vlc_object_destroy( p_instance->p_input );
}
input_ItemClean( &p_instance->item );
}
input_ItemClean( &p_instance->item );
input_StopThread( p_instance->p_input );
input_DestroyThread( p_instance->p_input );
input_StopThread( p_instance->p_input );
input_DestroyThread( p_instance->p_input );
- vlc_object_detach( p_instance->p_input );
- vlc_object_destroy( p_instance->p_input );
p_instance->i_index++;
if( p_instance->i_index == p_media->i_input &&
p_instance->i_index++;
if( p_instance->i_index == p_media->i_input &&
/* Destroy input */
input_DestroyThread( p_input );
/* Destroy input */
input_DestroyThread( p_input );
- /* Unlink current input
- * (_after_ input_DestroyThread for vout garbage collector) */
- vlc_object_detach( p_input );
-
- /* Destroy object */
- vlc_object_destroy( p_input );
-
PL_LOCK;
p_playlist->gc_date = mdate();
PL_LOCK;
p_playlist->gc_date = mdate();
/* Destroy input */
input_DestroyThread( p_input );
/* Destroy input */
input_DestroyThread( p_input );
- /* Unlink current input (_after_ input_DestroyThread for vout
- * garbage collector)*/
- vlc_object_detach( p_input );
-
- /* Destroy object */
- vlc_object_destroy( p_input );
continue;
}
else if( p_playlist->p_input->b_die )
continue;
}
else if( p_playlist->p_input->b_die )