-/*****************************************************************************
- * Post-processing
- *****************************************************************************/
-static bool PostProcessIsPresent( const char *psz_filter )
-{
- const char *psz_pp = "postproc";
- const size_t i_pp = strlen(psz_pp);
- return psz_filter &&
- !strncmp( psz_filter, psz_pp, strlen(psz_pp) ) &&
- ( psz_filter[i_pp] == '\0' || psz_filter[i_pp] == ':' );
-}
-
-static int PostProcessCallback( vlc_object_t *p_this, char const *psz_cmd,
- vlc_value_t oldval, vlc_value_t newval, void *p_data )
-{
- vout_thread_t *p_vout = (vout_thread_t *)p_this;
- VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval); VLC_UNUSED(p_data);
-
- static const char *psz_pp = "postproc";
-
- char *psz_vf2 = var_GetString( p_vout, "video-filter" );
-
- if( newval.i_int <= 0 )
- {
- if( PostProcessIsPresent( psz_vf2 ) )
- {
- strcpy( psz_vf2, &psz_vf2[strlen(psz_pp)] );
- if( *psz_vf2 == ':' )
- strcpy( psz_vf2, &psz_vf2[1] );
- }
- }
- else
- {
- if( !PostProcessIsPresent( psz_vf2 ) )
- {
- if( psz_vf2 )
- {
- char *psz_tmp = psz_vf2;
- if( asprintf( &psz_vf2, "%s:%s", psz_pp, psz_tmp ) < 0 )
- psz_vf2 = psz_tmp;
- else
- free( psz_tmp );
- }
- else
- {
- psz_vf2 = strdup( psz_pp );
- }
- }
- }
- if( psz_vf2 )
- {
- var_SetString( p_vout, "video-filter", psz_vf2 );
- free( psz_vf2 );
- }
-
- return VLC_SUCCESS;
-}
-static void PostProcessEnable( vout_thread_t *p_vout )
-{
- msg_Dbg( p_vout, "Post-processing available" );
- var_Create( p_vout, "postprocess", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
- for( int i = 0; i <= 6; i++ )
- {
- vlc_value_t val;
- vlc_value_t text;
- char psz_text[1+1];
-
- val.i_int = i;
- snprintf( psz_text, sizeof(psz_text), "%d", i );
- if( i == 0 )
- text.psz_string = _("Disable");
- else
- text.psz_string = psz_text;
- var_Change( p_vout, "postprocess", VLC_VAR_ADDCHOICE, &val, &text );
- }
- var_AddCallback( p_vout, "postprocess", PostProcessCallback, NULL );
-
- /* */
- char *psz_filter = var_GetNonEmptyString( p_vout, "video-filter" );
- int i_postproc_q = 0;
- if( PostProcessIsPresent( psz_filter ) )
- i_postproc_q = var_CreateGetInteger( p_vout, "postproc-q" );
-
- var_SetInteger( p_vout, "postprocess", i_postproc_q );
-
- free( psz_filter );
-}
-static void PostProcessDisable( vout_thread_t *p_vout )
-{
- msg_Dbg( p_vout, "Post-processing no more available" );
- var_Destroy( p_vout, "postprocess" );
-}
-static void PostProcessSetFilterQuality( vout_thread_t *p_vout )
-{
- vlc_object_t *p_pp = vlc_object_find_name( p_vout, "postproc", FIND_CHILD );
- if( !p_pp )
- return;
-
- var_SetInteger( p_pp, "postproc-q", var_GetInteger( p_vout, "postprocess" ) );
- vlc_object_release( p_pp );
-}
-
-
-static void DisplayTitleOnOSD( vout_thread_t *p_vout )
-{
- const mtime_t i_start = mdate();
- const mtime_t i_stop = i_start + INT64_C(1000) * p_vout->p->i_title_timeout;
-
- if( i_stop <= i_start )
- return
-
- vlc_assert_locked( &p_vout->change_lock );
-
- vout_ShowTextAbsolute( p_vout, DEFAULT_CHAN,
- p_vout->p->psz_title, NULL,
- p_vout->p->i_title_position,
- 30 + p_vout->fmt_in.i_width
- - p_vout->fmt_in.i_visible_width
- - p_vout->fmt_in.i_x_offset,
- 20 + p_vout->fmt_in.i_y_offset,
- i_start, i_stop );
-
- free( p_vout->p->psz_title );
-
- p_vout->p->psz_title = NULL;
-}
-
-/*****************************************************************************
- * Deinterlacing
- *****************************************************************************/
-typedef struct
-{
- const char *psz_mode;
- const char *psz_description;
- bool b_vout_filter;
-} deinterlace_mode_t;
-
-/* XXX
- * You can use the non vout filter if and only if the video properties stay the
- * same (width/height/chroma/fps), at least for now.
- */
-static const deinterlace_mode_t p_deinterlace_mode[] = {
- { "", "Disable", false },
- { "discard", "Discard", true },
- { "blend", "Blend", false },
- { "mean", "Mean", true },
- { "bob", "Bob", true },
- { "linear", "Linear", true },
- { "x", "X", false },
- { NULL, NULL, true }
-};
-
-static char *FilterFind( char *psz_filter_base, const char *psz_module )
-{
- const size_t i_module = strlen( psz_module );
- const char *psz_filter = psz_filter_base;
-
- if( !psz_filter || i_module <= 0 )
- return NULL;
-
- for( ;; )
- {
- char *psz_find = strstr( psz_filter, psz_module );
- if( !psz_find )
- return NULL;
- if( psz_find[i_module] == '\0' || psz_find[i_module] == ':' )
- return psz_find;
- psz_filter = &psz_find[i_module];
- }
-}
-
-static bool DeinterlaceIsPresent( vout_thread_t *p_vout, bool b_vout_filter )
-{
- char *psz_filter = var_GetNonEmptyString( p_vout, b_vout_filter ? "vout-filter" : "video-filter" );
-
- bool b_found = FilterFind( psz_filter, "deinterlace" ) != NULL;
-
- free( psz_filter );
-
- return b_found;
-}
-
-static void DeinterlaceRemove( vout_thread_t *p_vout, bool b_vout_filter )
-{
- const char *psz_variable = b_vout_filter ? "vout-filter" : "video-filter";
- char *psz_filter = var_GetNonEmptyString( p_vout, psz_variable );
-
- char *psz = FilterFind( psz_filter, "deinterlace" );
- if( !psz )
- {
- free( psz_filter );
- return;
- }
-
- /* */
- strcpy( &psz[0], &psz[strlen("deinterlace")] );
- if( *psz == ':' )
- strcpy( &psz[0], &psz[1] );
-
- var_SetString( p_vout, psz_variable, psz_filter );
- free( psz_filter );
-}
-static void DeinterlaceAdd( vout_thread_t *p_vout, bool b_vout_filter )
-{
- const char *psz_variable = b_vout_filter ? "vout-filter" : "video-filter";
-
- char *psz_filter = var_GetNonEmptyString( p_vout, psz_variable );
-
- if( FilterFind( psz_filter, "deinterlace" ) )
- {
- free( psz_filter );
- return;
- }
-
- /* */
- if( psz_filter )
- {
- char *psz_tmp = psz_filter;
- if( asprintf( &psz_filter, "%s:%s", psz_tmp, "deinterlace" ) < 0 )
- psz_filter = psz_tmp;
- else
- free( psz_tmp );
- }
- else
- {
- psz_filter = strdup( "deinterlace" );
- }
-
- if( psz_filter )
- {
- var_SetString( p_vout, psz_variable, psz_filter );
- free( psz_filter );
- }
-}
-
-static int DeinterlaceCallback( vlc_object_t *p_this, char const *psz_cmd,
- vlc_value_t oldval, vlc_value_t newval, void *p_data )
-{
- vout_thread_t *p_vout = (vout_thread_t *)p_this;
-
- /* */
- const deinterlace_mode_t *p_mode;
- for( p_mode = &p_deinterlace_mode[0]; p_mode->psz_mode; p_mode++ )
- {
- if( !strcmp( p_mode->psz_mode,
- newval.psz_string ? newval.psz_string : "" ) )
- break;
- }
- if( !p_mode->psz_mode )
- {
- msg_Err( p_this, "Invalid value (%s) ignored", newval.psz_string );
- return VLC_EGENERIC;
- }
-
- /* We have to set input variable to ensure restart support
- * XXX it is only needed because of vout-filter but must be done
- * for non video filter anyway */
- input_thread_t *p_input = (input_thread_t *)vlc_object_find( p_this, VLC_OBJECT_INPUT, FIND_PARENT );
- if( p_input )
- {
- var_Create( p_input, "vout-deinterlace", VLC_VAR_STRING );
- var_SetString( p_input, "vout-deinterlace", p_mode->psz_mode );
-
- var_Create( p_input, "deinterlace-mode", VLC_VAR_STRING );
- var_SetString( p_input, "deinterlace-mode", p_mode->psz_mode );
-
- var_Create( p_input, "sout-deinterlace-mode", VLC_VAR_STRING );
- var_SetString( p_input, "sout-deinterlace-mode", p_mode->psz_mode );
-
- vlc_object_release( p_input );
- }
-
- char *psz_old;
-
- if( p_mode->b_vout_filter )
- {
- psz_old = var_CreateGetString( p_vout, "deinterlace-mode" );
- }
- else
- {
- psz_old = var_CreateGetString( p_vout, "sout-deinterlace-mode" );
- var_SetString( p_vout, "sout-deinterlace-mode", p_mode->psz_mode );
- }
-
- /* */
- if( !strcmp( p_mode->psz_mode, "" ) )
- {
- DeinterlaceRemove( p_vout, false );
- DeinterlaceRemove( p_vout, true );
- }
- else if( !DeinterlaceIsPresent( p_vout, p_mode->b_vout_filter ) )
- {
- DeinterlaceRemove( p_vout, !p_mode->b_vout_filter );
- DeinterlaceAdd( p_vout, p_mode->b_vout_filter );
- }
- else
- {
- DeinterlaceRemove( p_vout, !p_mode->b_vout_filter );
- if( psz_old && strcmp( psz_old, p_mode->psz_mode ) )
- var_TriggerCallback( p_vout, p_mode->b_vout_filter ? "vout-filter" : "video-filter" );
- }
- free( psz_old );
-
- (void)psz_cmd; (void) oldval; (void) p_data;
- return VLC_SUCCESS;
-}
-
-static void DeinterlaceEnable( vout_thread_t *p_vout )