* TODO: support for reusing video outputs with proper _thread-safe_
* reference handling. */
if( p_vout )
- {
- spu_Attach( p_vout->p_spu, p_this, false );
- vlc_object_kill( p_vout );
- vlc_thread_join( p_vout );
- module_Unneed( p_vout, p_vout->p_module );
- vlc_object_release( p_vout );
- }
+ vout_CloseAndRelease( p_vout );
return NULL;
}
p_vout->b_filter_change )
{
/* We are not interested in this format, close this vout */
- vlc_object_release( p_vout );
+ vout_CloseAndRelease( p_vout );
vlc_object_release( p_vout );
p_vout = NULL;
}
if( p_vout->b_error )
{
msg_Err( p_vout, "video output creation failed" );
-
- /* Make sure the thread is destroyed and data released */
- vlc_object_kill( p_vout );
- vlc_thread_join( p_vout );
- module_Unneed( p_vout, p_vout->p_module );
- vlc_object_release( p_vout );
+ vout_CloseAndRelease( p_vout );
return NULL;
}
return p_vout;
}
+/*****************************************************************************
+ * vout_Close: Close a vout created by vout_Create.
+ *****************************************************************************
+ * You HAVE to call it on vout created by vout_Create before vlc_object_release.
+ * You should NEVER call it on vout not obtained though vout_Create
+ * (like with vout_Request or vlc_object_find.)
+ * You can use vout_CloseAndRelease() as a convenient method.
+ *****************************************************************************/
+void vout_Close( vout_thread_t *p_vout )
+{
+ assert( p_vout );
+
+ vlc_object_kill( p_vout );
+ vlc_thread_join( p_vout );
+ module_Unneed( p_vout, p_vout->p_module );
+ p_vout->p_module = NULL;
+}
+
+/* */
static void vout_Destructor( vlc_object_t * p_this )
{
vout_thread_t *p_vout = (vout_thread_t *)p_this;
+ /* Make sure the vout was stopped first */
+ assert( !p_vout->p_module );
+
/* Destroy the locks */
vlc_mutex_destroy( &p_vout->picture_lock );
vlc_mutex_destroy( &p_vout->change_lock );
*****************************************************************************/
static int ChromaCreate( vout_thread_t *p_vout );
static void ChromaDestroy( vout_thread_t *p_vout );
+static void DropPicture( vout_thread_t *p_vout, picture_t *p_picture );
static int InitThread( vout_thread_t *p_vout )
{
* Main loop - it is not executed if an error occurred during
* initialization
*/
- while( (vlc_object_alive( p_vout )) && (!p_vout->b_error) )
+ while( vlc_object_alive( p_vout ) && !p_vout->b_error )
{
/* Initialize loop variables */
p_picture = NULL;
current_date = mdate();
i_loops++;
- if( !p_input )
- {
- p_input = vlc_object_find( p_vout, VLC_OBJECT_INPUT,
- FIND_PARENT );
- }
- if( p_input )
- {
- vlc_mutex_lock( &p_input->p->counters.counters_lock );
- stats_UpdateInteger( p_vout, p_input->p->counters.p_lost_pictures,
- i_lost , NULL);
- stats_UpdateInteger( p_vout,
- p_input->p->counters.p_displayed_pictures,
- i_displayed , NULL);
- i_displayed = i_lost = 0;
- vlc_mutex_unlock( &p_input->p->counters.counters_lock );
- vlc_object_release( p_input );
- p_input = NULL;
- }
+ if( !p_input )
+ {
+ p_input = vlc_object_find( p_vout, VLC_OBJECT_INPUT,
+ FIND_PARENT );
+ }
+ if( p_input )
+ {
+ vlc_mutex_lock( &p_input->p->counters.counters_lock );
+ stats_UpdateInteger( p_vout, p_input->p->counters.p_lost_pictures,
+ i_lost , NULL);
+ stats_UpdateInteger( p_vout,
+ p_input->p->counters.p_displayed_pictures,
+ i_displayed , NULL);
+ i_displayed = i_lost = 0;
+ vlc_mutex_unlock( &p_input->p->counters.counters_lock );
+ vlc_object_release( p_input );
+ p_input = NULL;
+ }
#if 0
p_vout->c_loops++;
if( !(p_vout->c_loops % VOUT_STATS_NB_LOOPS) )
/* If we found better than the last picture, destroy it */
if( p_last_picture && p_picture != p_last_picture )
{
- vlc_mutex_lock( &p_vout->picture_lock );
- if( p_last_picture->i_refcount )
- {
- p_last_picture->i_status = DISPLAYED_PICTURE;
- }
- else
- {
- p_last_picture->i_status = DESTROYED_PICTURE;
- p_vout->i_heap_size--;
- }
- vlc_mutex_unlock( &p_vout->picture_lock );
+ DropPicture( p_vout, p_last_picture );
p_last_picture = NULL;
}
{
/* Picture is late: it will be destroyed and the thread
* will directly choose the next picture */
- vlc_mutex_lock( &p_vout->picture_lock );
- if( p_picture->i_refcount )
- {
- /* Pretend we displayed the picture, but don't destroy
- * it since the decoder might still need it. */
- p_picture->i_status = DISPLAYED_PICTURE;
- }
- else
- {
- /* Destroy the picture without displaying it */
- p_picture->i_status = DESTROYED_PICTURE;
- p_vout->i_heap_size--;
- }
+ DropPicture( p_vout, p_picture );
+ i_lost++;
msg_Warn( p_vout, "late picture skipped (%"PRId64")",
current_date - display_date );
- i_lost++;
- vlc_mutex_unlock( &p_vout->picture_lock );
-
continue;
}
current_date + p_vout->i_pts_delay + VOUT_BOGUS_DELAY )
{
/* Picture is waaay too early: it will be destroyed */
- vlc_mutex_lock( &p_vout->picture_lock );
- if( p_picture->i_refcount )
- {
- /* Pretend we displayed the picture, but don't destroy
- * it since the decoder might still need it. */
- p_picture->i_status = DISPLAYED_PICTURE;
- }
- else
- {
- /* Destroy the picture without displaying it */
- p_picture->i_status = DESTROYED_PICTURE;
- p_vout->i_heap_size--;
- }
+ DropPicture( p_vout, p_picture );
i_lost++;
msg_Warn( p_vout, "vout warning: early picture skipped "
"(%"PRId64")", display_date - current_date
- p_vout->i_pts_delay );
- vlc_mutex_unlock( &p_vout->picture_lock );
-
continue;
}
static int ChromaCreate( vout_thread_t *p_vout )
{
+ static const char typename[] = "chroma";
filter_t *p_chroma;
/* Choose the best module */
- p_chroma = p_vout->p_chroma = vlc_object_create( p_vout, sizeof(filter_t) );
+ p_chroma = p_vout->p_chroma =
+ vlc_custom_create( p_vout, sizeof(filter_t), VLC_OBJECT_GENERIC,
+ typename );
vlc_object_attach( p_chroma, p_vout );
p_vout->p_chroma = NULL;
}
+static void DropPicture( vout_thread_t *p_vout, picture_t *p_picture )
+{
+ vlc_mutex_lock( &p_vout->picture_lock );
+ if( p_picture->i_refcount )
+ {
+ /* Pretend we displayed the picture, but don't destroy
+ * it since the decoder might still need it. */
+ p_picture->i_status = DISPLAYED_PICTURE;
+ }
+ else
+ {
+ /* Destroy the picture without displaying it */
+ p_picture->i_status = DESTROYED_PICTURE;
+ p_vout->i_heap_size--;
+ }
+ vlc_mutex_unlock( &p_vout->picture_lock );
+}
+
/* following functions are local */
*pi_right = (8 - i_high + i_low);
}
-/*****************************************************************************
- * vout_VarCallback: generic callback for intf variables
- *****************************************************************************/
-int vout_VarCallback( vlc_object_t * p_this, const char * psz_variable,
- vlc_value_t oldval, vlc_value_t newval,
- void *p_data )
-{
- vout_thread_t * p_vout = (vout_thread_t *)p_this;
- vlc_value_t val;
- (void)psz_variable; (void)newval; (void)oldval; (void)p_data;
- val.b_bool = true;
- var_Set( p_vout, "intf-change", val );
- return VLC_SUCCESS;
-}
-
/*****************************************************************************
* Helper thread for object variables callbacks.
* Only used to avoid deadlocks when using the video embedded mode.
var_Get( p_input, "video-es", &val );
if( val.i_int >= 0 )
{
+ static const char typename[] = "kludge";
suxor_thread_t *p_suxor =
- vlc_object_create( p_vout, sizeof(suxor_thread_t) );
+ vlc_custom_create( p_vout, sizeof(suxor_thread_t),
+ VLC_OBJECT_GENERIC, typename );
p_suxor->p_input = p_input;
p_vout->b_filter_change = true;
vlc_object_yield( p_input );
input_thread_t *p_input;
mtime_t i_now, i_stop;
+ if( !config_GetInt( p_vout, "osd" ) ) return;
+
p_input = (input_thread_t *)vlc_object_find( p_vout,
VLC_OBJECT_INPUT, FIND_ANYWHERE );
if( p_input )