X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fvideo_output%2Fvideo_output.c;h=6e5dd3714cbc2ca8056883da85ea24433370e6a4;hb=88c63e2e1cdca4fc42acfb42c2c53af1824b2bfb;hp=0dcfd2a38ada322bbfb63f5736aeb23a4e38317c;hpb=2ba646a5ea654996b0e627d589bd712acebb2bf8;p=vlc diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c index 0dcfd2a38a..6e5dd3714c 100644 --- a/src/video_output/video_output.c +++ b/src/video_output/video_output.c @@ -1,5 +1,6 @@ /***************************************************************************** * video_output.c : video output thread + * * This module describes the programming interface for video output threads. * It includes functions allowing to open a new thread, send pictures to a * thread, and destroy a previously oppened video output thread. @@ -136,12 +137,14 @@ vout_thread_t * __vout_Request ( vlc_object_t *p_this, vout_thread_t *p_vout, if( p_vout ) { char *psz_filter_chain; + vlc_value_t val; /* We don't directly check for the "filter" variable for obvious * performance reasons. */ if( p_vout->b_filter_change ) { - psz_filter_chain = config_GetPsz( p_this, "filter" ); + var_Get( p_vout, "filter", &val ); + psz_filter_chain = val.psz_string; if( psz_filter_chain && !*psz_filter_chain ) { @@ -154,9 +157,7 @@ vout_thread_t * __vout_Request ( vlc_object_t *p_this, vout_thread_t *p_vout, p_vout->psz_filter_chain = NULL; } - if( ( !psz_filter_chain && !p_vout->psz_filter_chain ) || - ( psz_filter_chain && p_vout->psz_filter_chain && - !strcmp( psz_filter_chain, p_vout->psz_filter_chain ) ) ) + if( !psz_filter_chain && !p_vout->psz_filter_chain ) { p_vout->b_filter_change = VLC_FALSE; } @@ -420,15 +421,9 @@ vout_thread_t * __vout_Create( vlc_object_t *p_parent, var_AddCallback( p_vout, "deinterlace", DeinterlaceCallback, NULL ); - var_Create( p_vout, "filter", VLC_VAR_STRING ); + var_Create( p_vout, "filter", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); text.psz_string = _("Filters"); var_Change( p_vout, "filter", VLC_VAR_SETTEXT, &text, NULL ); - var_Change( p_vout, "filter", VLC_VAR_INHERITVALUE, &val, NULL ); - if( val.psz_string ) - { - var_Set( p_vout, "filter", val ); - free( val.psz_string ); - } var_AddCallback( p_vout, "filter", FilterCallback, NULL ); /* Calculate delay created by internal caching */ @@ -560,30 +555,6 @@ static int InitThread( vout_thread_t *p_vout ) msg_Dbg( p_vout, "got %i direct buffer(s)", I_OUTPUTPICTURES ); -#if 0 - if( !p_vout->psz_filter_chain ) - { - char *psz_aspect = config_GetPsz( p_vout, "pixel-ratio" ); - - if( psz_aspect ) - { - int i_new_aspect = p_vout->output.i_width * VOUT_ASPECT_FACTOR - * atof( psz_aspect ) - / p_vout->output.i_height; - free( psz_aspect ); - - if( i_new_aspect && i_new_aspect != p_vout->output.i_aspect ) - { - AspectRatio( i_new_aspect, &i_aspect_x, &i_aspect_y ); - - msg_Dbg( p_vout, "output ratio forced to %i:%i\n", - i_aspect_x, i_aspect_y ); - p_vout->output.i_aspect = i_new_aspect; - } - } - } -#endif - AspectRatio( p_vout->render.i_aspect, &i_aspect_x, &i_aspect_y ); msg_Dbg( p_vout, "picture in %ix%i, chroma 0x%.8x (%4.4s), aspect ratio %i:%i", @@ -1297,6 +1268,40 @@ int vout_VarCallback( vlc_object_t * p_this, const char * psz_variable, return VLC_SUCCESS; } +/***************************************************************************** + * Helper thread for object variables callbacks. + * Only used to avoid deadlocks when using the video embedded mode. + *****************************************************************************/ +typedef struct suxor_thread_t +{ + VLC_COMMON_MEMBERS + input_thread_t *p_input; + +} suxor_thread_t; + +static void SuxorRestartVideoES( suxor_thread_t *p_this ) +{ + vlc_value_t val; + + /* Now restart current video stream */ + var_Get( p_this->p_input, "video-es", &val ); + if( val.i_int >= 0 ) + { + vlc_value_t val_es; + val_es.i_int = -VIDEO_ES; + var_Set( p_this->p_input, "video-es", val_es ); + var_Set( p_this->p_input, "video-es", val ); + } + + vlc_object_release( p_this->p_input ); + +#ifdef WIN32 + CloseHandle( p_this->thread_id ); +#endif + + vlc_object_destroy( p_this ); +} + /***************************************************************************** * object variables callbacks: a bunch of object variables are used by the * interfaces to interact with the vout. @@ -1309,33 +1314,28 @@ static int DeinterlaceCallback( vlc_object_t *p_this, char const *psz_cmd, vlc_value_t val; char *psz_mode = newval.psz_string; - char *psz_filter; + char *psz_filter, *psz_deinterlace = NULL; - psz_filter = config_GetPsz( p_vout, "filter" ); + var_Get( p_vout, "filter", &val ); + psz_filter = val.psz_string; + if( psz_filter ) psz_deinterlace = strstr( psz_filter, "deinterlace" ); if( !psz_mode || !*psz_mode ) { - config_PutPsz( p_vout, "filter", "" ); - } - else - { - if( !psz_filter || !*psz_filter ) - { - config_PutPsz( p_vout, "filter", "deinterlace" ); - } - else + if( psz_deinterlace ) { - if( strstr( psz_filter, "deinterlace" ) == NULL ) - { - psz_filter = realloc( psz_filter, strlen( psz_filter ) + 20 ); - strcat( psz_filter, ",deinterlace" ); - } - config_PutPsz( p_vout, "filter", psz_filter ); + char *psz_src = psz_deinterlace + sizeof("deinterlace") - 1; + if( psz_src[0] == ',' ) psz_src++; + memmove( psz_deinterlace, psz_src, strlen(psz_src) + 1 ); } } - - if( psz_filter ) free( psz_filter ); - + else if( !psz_deinterlace ) + { + psz_filter = realloc( psz_filter, strlen( psz_filter ) + + sizeof(",deinterlace") ); + if( psz_filter && *psz_filter ) strcat( psz_filter, "," ); + strcat( psz_filter, "deinterlace" ); + } p_input = (input_thread_t *)vlc_object_find( p_this, VLC_OBJECT_INPUT, FIND_PARENT ); @@ -1343,28 +1343,20 @@ static int DeinterlaceCallback( vlc_object_t *p_this, char const *psz_cmd, if( psz_mode && *psz_mode ) { - val.psz_string = psz_mode; - var_Set( p_vout, "deinterlace-mode", val ); /* Modify input as well because the vout might have to be restarted */ + val.psz_string = psz_mode; var_Create( p_input, "deinterlace-mode", VLC_VAR_STRING ); var_Set( p_input, "deinterlace-mode", val ); } - - /* Now restart current video stream */ - var_Get( p_input, "video-es", &val ); - if( val.i_int >= 0 ) - { - vlc_value_t val_es; - val_es.i_int = -VIDEO_ES; - p_vout->b_filter_change = VLC_TRUE; - var_Set( p_input, "video-es", val_es ); - var_Set( p_input, "video-es", val ); - } - vlc_object_release( p_input ); val.b_bool = VLC_TRUE; var_Set( p_vout, "intf-change", val ); + + val.psz_string = psz_filter; + var_Set( p_vout, "filter", val ); + if( psz_filter ) free( psz_filter ); + return VLC_SUCCESS; } @@ -1377,27 +1369,34 @@ static int FilterCallback( vlc_object_t *p_this, char const *psz_cmd, p_input = (input_thread_t *)vlc_object_find( p_this, VLC_OBJECT_INPUT, FIND_PARENT ); - if (!p_input) { msg_Err( p_vout, "Input not found" ); return( VLC_EGENERIC ); } + val.b_bool = VLC_TRUE; + var_Set( p_vout, "intf-change", val ); + + /* Modify input as well because the vout might have to be restarted */ + val.psz_string = newval.psz_string; + var_Create( p_input, "filter", VLC_VAR_STRING ); + var_Set( p_input, "filter", val ); + /* Now restart current video stream */ var_Get( p_input, "video-es", &val ); if( val.i_int >= 0 ) { - vlc_value_t val_es; - val_es.i_int = -VIDEO_ES; p_vout->b_filter_change = VLC_TRUE; - var_Set( p_input, "video-es", val_es ); - var_Set( p_input, "video-es", val ); + suxor_thread_t *p_suxor = + vlc_object_create( p_vout, sizeof(suxor_thread_t) ); + p_suxor->p_input = p_input; + vlc_object_yield( p_input ); + vlc_thread_create( p_suxor, "suxor", SuxorRestartVideoES, + VLC_THREAD_PRIORITY_LOW, VLC_FALSE ); } vlc_object_release( p_input ); - val.b_bool = VLC_TRUE; - var_Set( p_vout, "intf-change", val ); return VLC_SUCCESS; }