X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fvideo_output%2Fvideo_output.c;h=74bcacdebfac32bec0cbfa36a0ce3531e730eaff;hb=a11817c9ba314e5f4f13d33c24d248f51b6ad2d3;hp=59fb56e7c00f11cbb04323cfc55091e90d80b56f;hpb=594067729597cc5867ff2094958d59c759bf0445;p=vlc diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c index 59fb56e7c0..74bcacdebf 100644 --- a/src/video_output/video_output.c +++ b/src/video_output/video_output.c @@ -29,6 +29,10 @@ /***************************************************************************** * Preamble *****************************************************************************/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #include #include /* free() */ @@ -62,12 +66,13 @@ static int InitThread ( vout_thread_t * ); static void RunThread ( vout_thread_t * ); static void ErrorThread ( vout_thread_t * ); static void EndThread ( vout_thread_t * ); -static void DestroyThread ( vout_thread_t * ); static void AspectRatio ( int, int *, int * ); static int BinaryLog ( uint32_t ); static void MaskToShift ( int *, int *, uint32_t ); +static void vout_Destructor ( vlc_object_t * p_this ); + /* Object variables callbacks */ static int DeinterlaceCallback( vlc_object_t *, char const *, vlc_value_t, vlc_value_t, void * ); @@ -123,11 +128,9 @@ vout_thread_t *__vout_Request( vlc_object_t *p_this, vout_thread_t *p_vout, /* Reattach video output to playlist before bailing out */ if( p_vout ) { - playlist_t *p_playlist = pl_Yield( p_this ); spu_Attach( p_vout->p_spu, p_this, VLC_FALSE ); vlc_object_detach( p_vout ); - vlc_object_attach( p_vout, p_playlist ); - pl_Release( p_this ); + vlc_object_attach( p_vout, p_this->p_libvlc ); } return NULL; } @@ -143,20 +146,16 @@ vout_thread_t *__vout_Request( vlc_object_t *p_this, vout_thread_t *p_vout, if( !p_vout ) { - playlist_t *p_playlist = pl_Yield( p_this ); - vlc_mutex_lock( &p_playlist->gc_lock ); - p_vout = vlc_object_find( p_playlist, + p_vout = vlc_object_find( p_this->p_libvlc, VLC_OBJECT_VOUT, FIND_CHILD ); /* only first children of p_input for unused vout */ - if( p_vout && p_vout->p_parent != (vlc_object_t *)p_playlist ) + if( p_vout && p_vout->p_parent != VLC_OBJECT(p_this->p_libvlc) ) { vlc_object_release( p_vout ); p_vout = NULL; } if( p_vout ) vlc_object_detach( p_vout ); /* Remove it from the GC */ - vlc_mutex_unlock( &p_playlist->gc_lock ); - pl_Release( p_this ); } } @@ -189,12 +188,11 @@ vout_thread_t *__vout_Request( vlc_object_t *p_this, vout_thread_t *p_vout, p_vout->b_filter_change = VLC_FALSE; } - if( psz_filter_chain ) free( psz_filter_chain ); + free( psz_filter_chain ); } if( ( p_vout->fmt_render.i_width != p_fmt->i_width ) || ( p_vout->fmt_render.i_height != p_fmt->i_height ) || - ( p_vout->fmt_render.i_chroma != p_fmt->i_chroma ) || ( p_vout->fmt_render.i_aspect != p_fmt->i_aspect ) || p_vout->b_filter_change ) { @@ -208,6 +206,8 @@ vout_thread_t *__vout_Request( vlc_object_t *p_this, vout_thread_t *p_vout, /* This video output is cool! Hijack it. */ spu_Attach( p_vout->p_spu, p_this, VLC_TRUE ); vlc_object_attach( p_vout, p_this ); + if( p_vout->b_title_show ) + DisplayTitleOnOSD( p_vout ); vlc_object_release( p_vout ); } } @@ -393,14 +393,14 @@ vout_thread_t * __vout_Create( vlc_object_t *p_parent, video_format_t *p_fmt ) p_vout->p_cfg = p_cfg; p_vout->p_module = module_Need( p_vout, ( p_vout->psz_filter_chain && *p_vout->psz_filter_chain ) ? - "video filter" : "video output", psz_name, 0 ); + "video filter" : "video output", psz_name, p_vout->psz_filter_chain && *p_vout->psz_filter_chain ); free( psz_name ); if( p_vout->p_module == NULL ) { msg_Err( p_vout, "no suitable vout module" ); vlc_object_detach( p_vout ); - vlc_object_destroy( p_vout ); + vlc_object_release( p_vout ); return NULL; } @@ -426,7 +426,7 @@ vout_thread_t * __vout_Create( vlc_object_t *p_parent, video_format_t *p_fmt ) if( var_Get( p_vout, "deinterlace-mode", &val ) == VLC_SUCCESS ) { var_Set( p_vout, "deinterlace", val ); - if( val.psz_string ) free( val.psz_string ); + free( val.psz_string ); } var_AddCallback( p_vout, "deinterlace", DeinterlaceCallback, NULL ); @@ -453,8 +453,7 @@ vout_thread_t * __vout_Create( vlc_object_t *p_parent, video_format_t *p_fmt ) { msg_Err( p_vout, "out of memory" ); module_Unneed( p_vout, p_vout->p_module ); - vlc_object_detach( p_vout ); - vlc_object_destroy( p_vout ); + vlc_object_release( p_vout ); return NULL; } @@ -463,14 +462,12 @@ vout_thread_t * __vout_Create( vlc_object_t *p_parent, video_format_t *p_fmt ) msg_Err( p_vout, "video output creation failed" ); /* Make sure the thread is destroyed */ - vlc_object_kill( p_vout ); - vlc_thread_join( p_vout ); - - vlc_object_detach( p_vout ); - vlc_object_destroy( p_vout ); + vlc_object_release( p_vout ); return NULL; } + vlc_object_set_destructor( p_vout, vout_Destructor ); + return p_vout; } @@ -484,40 +481,55 @@ vout_thread_t * __vout_Create( vlc_object_t *p_parent, video_format_t *p_fmt ) *****************************************************************************/ void vout_Destroy( vout_thread_t *p_vout ) { - vout_thread_t *p_another_vout; - playlist_t *p_playlist = pl_Yield( p_vout ); + /* XXX: should go in the destructor */ + var_Destroy( p_vout, "intf-change" ); - /* Request thread destruction */ - vlc_object_kill( p_vout ); - vlc_thread_join( p_vout ); + vlc_object_release( p_vout ); +} - var_Destroy( p_vout, "intf-change" ); +static void vout_Destructor( vlc_object_t * p_this ) +{ + vout_thread_t *p_vout = (vout_thread_t *)p_this; - if( p_vout->psz_filter_chain ) free( p_vout->psz_filter_chain ); + /* Destroy the locks */ + vlc_mutex_destroy( &p_vout->picture_lock ); + vlc_mutex_destroy( &p_vout->change_lock ); + vlc_mutex_destroy( &p_vout->vfilter_lock ); + + /* Release the module */ + if( p_vout->p_module ) + { + module_Unneed( p_vout, p_vout->p_module ); + } + + free( p_vout->psz_filter_chain ); config_ChainDestroy( p_vout->p_cfg ); - /* Free structure */ - vlc_object_destroy( p_vout ); #ifndef __APPLE__ - /* This is a dirty hack for mostly Linux, where there is no way to get the GUI - back if you closed it while playing video. This is solved in Mac OS X, - where we have this novelty called menubar, that will always allow you access - to the applications main functionality. They should try that on linux sometime */ - p_another_vout = vlc_object_find( p_playlist, - VLC_OBJECT_VOUT, FIND_ANYWHERE ); - if( p_another_vout == NULL ) - { - vlc_value_t val; - val.b_bool = VLC_TRUE; - var_Set( p_playlist, "intf-show", val ); + vout_thread_t *p_another_vout; + + playlist_t *p_playlist = pl_Get( p_vout ); + if( p_playlist->b_die ) return; + vlc_object_yield( p_playlist ); +/* This is a dirty hack for mostly Linux, where there is no way to get the GUI + back if you closed it while playing video. This is solved in Mac OS X, + where we have this novelty called menubar, that will always allow you access + to the applications main functionality. They should try that on linux sometime */ + p_another_vout = vlc_object_find( p_this->p_libvlc, + VLC_OBJECT_VOUT, FIND_ANYWHERE ); + if( p_another_vout == NULL ) + { + vlc_value_t val; + val.b_bool = VLC_TRUE; + var_Set( p_playlist, "intf-show", val ); } else { vlc_object_release( p_another_vout ); } -#endif vlc_object_release( p_playlist ); +#endif } /***************************************************************************** @@ -752,11 +764,7 @@ static void RunThread( vout_thread_t *p_vout) vlc_thread_ready( p_vout ); if( p_vout->b_error ) - { - /* Destroy thread structures allocated by Create and InitThread */ - DestroyThread( p_vout ); return; - } if( p_vout->b_title_show ) DisplayTitleOnOSD( p_vout ); @@ -772,15 +780,7 @@ static void RunThread( vout_thread_t *p_vout) display_date = 0; current_date = mdate(); - if( p_input && p_input->b_die ) - { - vlc_object_release( p_input ); - p_input = NULL; - } - i_loops++; - if( i_loops % 20 == 0 ) - { if( !p_input ) { p_input = vlc_object_find( p_vout, VLC_OBJECT_INPUT, @@ -796,8 +796,9 @@ static void RunThread( vout_thread_t *p_vout) 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) ) @@ -996,7 +997,7 @@ static void RunThread( vout_thread_t *p_vout) msg_Err( p_vout, "no video filter found (%s)", p_vout->psz_vfilters[i] ); vlc_object_detach( p_vfilter ); - vlc_object_destroy( p_vfilter ); + vlc_object_release( p_vfilter ); } } p_vout->b_vfilter_change = VLC_FALSE; @@ -1053,6 +1054,9 @@ static void RunThread( vout_thread_t *p_vout) } p_subpic = spu_SortSubpictures( p_vout->p_spu, display_date, p_input ? var_GetBool( p_input, "state" ) == PAUSE_S : VLC_FALSE ); + if( p_input ) + vlc_object_release( p_input ); + p_input = NULL; } /* @@ -1216,9 +1220,6 @@ static void RunThread( vout_thread_t *p_vout) /* End of thread */ EndThread( p_vout ); - - /* Destroy thread structures allocated by CreateThread */ - DestroyThread( p_vout ); } /***************************************************************************** @@ -1286,26 +1287,6 @@ static void EndThread( vout_thread_t *p_vout ) vlc_mutex_unlock( &p_vout->change_lock ); } -/***************************************************************************** - * DestroyThread: thread destruction - ***************************************************************************** - * This function is called when the thread ends. It frees all ressources - * allocated by CreateThread. Status is available at this stage. - *****************************************************************************/ -static void DestroyThread( vout_thread_t *p_vout ) -{ - /* Destroy the locks */ - vlc_mutex_destroy( &p_vout->picture_lock ); - vlc_mutex_destroy( &p_vout->change_lock ); - vlc_mutex_destroy( &p_vout->vfilter_lock ); - - /* Release the module */ - if( p_vout && p_vout->p_module ) - { - module_Unneed( p_vout, p_vout->p_module ); - } -} - /* following functions are local */ static int ReduceHeight( int i_ratio ) @@ -1446,11 +1427,7 @@ static void SuxorRestartVideoES( suxor_thread_t *p_this ) vlc_object_release( p_this->p_input ); -#ifdef WIN32 - CloseHandle( p_this->thread_id ); -#endif - - vlc_object_destroy( p_this ); + vlc_object_release( p_this ); } /***************************************************************************** @@ -1507,7 +1484,7 @@ static int DeinterlaceCallback( vlc_object_t *p_this, char const *psz_cmd, val.psz_string = psz_filter; var_Set( p_vout, "vout-filter", val ); - if( psz_filter ) free( psz_filter ); + free( psz_filter ); return VLC_SUCCESS; } @@ -1566,11 +1543,8 @@ static int ParseVideoFilter2Chain( vout_thread_t *p_vout, char *psz_vfilters ) struct config_chain_t *p_cfg = p_vout->p_vfilters_cfg[p_vout->i_vfilters_cfg]; config_ChainDestroy( p_cfg ); - if( p_vout->psz_vfilters[p_vout->i_vfilters_cfg] ) - { - free( p_vout->psz_vfilters[p_vout->i_vfilters_cfg] ); - p_vout->psz_vfilters[p_vout->i_vfilters_cfg] = NULL; - } + free( p_vout->psz_vfilters[p_vout->i_vfilters_cfg] ); + p_vout->psz_vfilters[p_vout->i_vfilters_cfg] = NULL; } p_vout->i_vfilters_cfg = 0; if( psz_vfilters && *psz_vfilters ) @@ -1628,7 +1602,7 @@ static void RemoveVideoFilters2( vout_thread_t *p_vout ) } free( p_vout->pp_vfilters[i]->p_owner ); - vlc_object_destroy( p_vout->pp_vfilters[i] ); + vlc_object_release( p_vout->pp_vfilters[i] ); } p_vout->i_vfilters = 0; } @@ -1644,12 +1618,19 @@ static void DisplayTitleOnOSD( vout_thread_t *p_vout ) { i_now = mdate(); i_stop = i_now + (mtime_t)(p_vout->i_title_timeout * 1000); - if( input_GetItem(p_input)->p_meta && - input_GetItem(p_input)->p_meta->psz_nowplaying && - *input_GetItem(p_input)->p_meta->psz_nowplaying ) + char *psz_nowplaying = + input_item_GetNowPlaying( input_GetItem( p_input ) ); + char *psz_artist = input_item_GetArtist( input_GetItem( p_input ) ); + char *psz_name = input_item_GetTitle( input_GetItem( p_input ) ); + if( EMPTY_STR( psz_name ) ) + { + free( psz_name ); + psz_name = input_item_GetName( input_GetItem( p_input ) ); + } + if( !EMPTY_STR( psz_nowplaying ) ) { vout_ShowTextAbsolute( p_vout, DEFAULT_CHAN, - input_GetItem(p_input)->p_meta->psz_nowplaying, NULL, + psz_nowplaying, NULL, p_vout->i_title_position, 30 + p_vout->fmt_in.i_width - p_vout->fmt_in.i_visible_width @@ -1657,20 +1638,11 @@ static void DisplayTitleOnOSD( vout_thread_t *p_vout ) 20 + p_vout->fmt_in.i_y_offset, i_now, i_stop ); } - else if( input_GetItem(p_input)->p_meta && - input_GetItem(p_input)->p_meta->psz_artist && - *input_GetItem(p_input)->p_meta->psz_artist ) + else if( !EMPTY_STR( psz_artist ) ) { char *psz_string = NULL; - - psz_string = malloc( strlen(input_GetItem(p_input)->psz_name) + - strlen(input_GetItem(p_input)->p_meta->psz_artist) ); - if( psz_string ) + if( asprintf( &psz_string, "%s - %s", psz_name, psz_artist ) != -1 ) { - sprintf( psz_string, "%s - %s", - input_GetItem(p_input)->psz_name, - input_GetItem(p_input)->p_meta->psz_artist ); - vout_ShowTextAbsolute( p_vout, DEFAULT_CHAN, psz_string, NULL, p_vout->i_title_position, @@ -1685,7 +1657,7 @@ static void DisplayTitleOnOSD( vout_thread_t *p_vout ) else { vout_ShowTextAbsolute( p_vout, DEFAULT_CHAN, - input_GetItem(p_input)->psz_name, NULL, + psz_name, NULL, p_vout->i_title_position, 30 + p_vout->fmt_in.i_width - p_vout->fmt_in.i_visible_width @@ -1694,5 +1666,9 @@ static void DisplayTitleOnOSD( vout_thread_t *p_vout ) i_now, i_stop ); } vlc_object_release( p_input ); + free( psz_artist ); + free( psz_name ); + free( psz_nowplaying ); } } +