X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fvideo_filter%2Fpostproc.c;h=3211333c2b3d3ddbbbf5aca62cf44288e9d6e079;hb=98cea7a2a22ceedb3c6eebc4b4f3fb40d263ba09;hp=2779c098a1435ce3937d19d0bb70f2733cde94e1;hpb=174f75debc6ff4b0b3a7037bc21e7b77bfe2a9d8;p=vlc diff --git a/modules/video_filter/postproc.c b/modules/video_filter/postproc.c index 2779c098a1..3211333c2b 100644 --- a/modules/video_filter/postproc.c +++ b/modules/video_filter/postproc.c @@ -1,35 +1,44 @@ /***************************************************************************** * postproc.c: video postprocessing using libpostproc ***************************************************************************** - * Copyright (C) 1999-2008 the VideoLAN team + * Copyright (C) 1999-2009 VLC authors and VideoLAN * $Id$ * * Authors: Laurent Aimar * Gildas Bazin * Antoine Cellerier * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ +/***************************************************************************** + * NOTA BENE: this module requires the linking against a library which is + * known to require licensing under the GNU General Public License version 2 + * (or later). Therefore, the result of compiling this module will normally + * be subject to the terms of that later license. + *****************************************************************************/ + + #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include -#include +#include +#include #include "filter_picture.h" @@ -58,9 +67,10 @@ static int PPNameCallback( vlc_object_t *, char const *, #define Q_TEXT N_("Post processing quality") #define Q_LONGTEXT N_( \ - "Quality of post processing. Valid range is 0 to 6\n" \ - "Higher levels require considerable more CPU power, but produce " \ - "better looking pictures." ) + "Quality of post processing. Valid range is 0 (disabled) to 6 (highest)\n" \ + "Higher levels require more CPU power, but produce higher quality pictures.\n" \ + "With default filter chain, the values map to the following filters:\n" \ + "1: hb, 2-4: hb+vb, 5-6: hb+vb+dr" ) #define NAME_TEXT N_("FFmpeg post processing filter chains") #define NAME_LONGTEXT NAME_TEXT @@ -73,8 +83,7 @@ static int PPNameCallback( vlc_object_t *, char const *, vlc_module_begin () set_description( N_("Video post processing filter") ) set_shortname( N_("Postproc" ) ) - add_shortcut( "postprocess" ) /* name is "postproc" */ - add_shortcut( "pp" ) + add_shortcut( "postprocess", "pp" ) /* name is "postproc" */ set_category( CAT_VIDEO ) set_subcategory( SUBCAT_VIDEO_VFILTER ) @@ -83,12 +92,10 @@ vlc_module_begin () set_callbacks( OpenPostproc, ClosePostproc ) add_integer_with_range( FILTER_PREFIX "q", PP_QUALITY_MAX, 0, - PP_QUALITY_MAX, NULL, Q_TEXT, Q_LONGTEXT, false ) - add_deprecated_alias( "ffmpeg-pp-q" ) + PP_QUALITY_MAX, Q_TEXT, Q_LONGTEXT, false ) change_safe() - add_string( FILTER_PREFIX "name", "default", NULL, NAME_TEXT, + add_string( FILTER_PREFIX "name", "default", NAME_TEXT, NAME_LONGTEXT, true ) - add_deprecated_alias( "ffmpeg-pp-name" ) vlc_module_end () static const char *const ppsz_filter_options[] = { @@ -100,12 +107,14 @@ static const char *const ppsz_filter_options[] = { *****************************************************************************/ struct filter_sys_t { - pp_context_t *pp_context; /* Never changes after init */ - pp_mode_t *pp_mode; /* Set to NULL if post processing is disabled */ + /* Never changes after init */ + pp_context *pp_context; - bool b_had_matrix; /* Set to true if previous pic had a quant matrix (used to prevent spamming warning messages */ + /* Set to NULL if post processing is disabled */ + pp_mode *pp_mode; - vlc_mutex_t lock; /* Lock when using or changing pp_mode */ + /* Lock when using or changing pp_mode */ + vlc_mutex_t lock; }; @@ -117,7 +126,6 @@ static int OpenPostproc( vlc_object_t *p_this ) filter_t *p_filter = (filter_t *)p_this; filter_sys_t *p_sys; vlc_value_t val, val_orig, text; - unsigned i_cpu = vlc_CPU(); int i_flags = 0; if( p_filter->fmt_in.video.i_chroma != p_filter->fmt_out.video.i_chroma || @@ -129,20 +137,26 @@ static int OpenPostproc( vlc_object_t *p_this ) } /* Set CPU capabilities */ - if( i_cpu & CPU_CAPABILITY_MMX ) +#if defined(__i386__) || defined(__x86_64__) + if( vlc_CPU_MMX() ) i_flags |= PP_CPU_CAPS_MMX; - if( i_cpu & CPU_CAPABILITY_MMXEXT ) + if( vlc_CPU_MMXEXT() ) i_flags |= PP_CPU_CAPS_MMX2; - if( i_cpu & CPU_CAPABILITY_3DNOW ) + if( vlc_CPU_3dNOW() ) i_flags |= PP_CPU_CAPS_3DNOW; - if( i_cpu & CPU_CAPABILITY_ALTIVEC ) +#elif defined(__ppc__) || defined(__ppc64__) || defined(__powerpc__) + if( vlc_CPU_ALTIVEC() ) i_flags |= PP_CPU_CAPS_ALTIVEC; +#endif switch( p_filter->fmt_in.video.i_chroma ) { case VLC_CODEC_I444: case VLC_CODEC_J444: - /* case VLC_CODEC_YUVA: FIXME Should work but alpha plane needs to be copied manually and I'm kind of feeling too lazy to write the code to do that ATM (i_pitch vs i_visible_pitch...). */ + /* case VLC_CODEC_YUVA: + FIXME: Should work but alpha plane needs to be copied manually and + I'm kind of feeling too lazy to write the code to do that ATM + (i_pitch vs i_visible_pitch...). */ i_flags |= PP_FORMAT_444; break; case VLC_CODEC_I422: @@ -158,7 +172,7 @@ static int OpenPostproc( vlc_object_t *p_this ) i_flags |= PP_FORMAT_420; break; default: - msg_Err( p_filter, "Unsupported input chroma (%4s)", + msg_Err( p_filter, "Unsupported input chroma (%4.4s)", (char*)&p_filter->fmt_in.video.i_chroma ); return VLC_EGENERIC; } @@ -180,23 +194,20 @@ static int OpenPostproc( vlc_object_t *p_this ) config_ChainParse( p_filter, FILTER_PREFIX, ppsz_filter_options, p_filter->p_cfg ); - var_Create( p_filter, FILTER_PREFIX "q", - VLC_VAR_INTEGER | VLC_VAR_HASCHOICE | VLC_VAR_DOINHERIT | - VLC_VAR_ISCOMMAND ); - var_Change( p_filter, FILTER_PREFIX "q", VLC_VAR_SETISCOMMAND, NULL, NULL ); /* For some obscure reason the VLC_VAR_ISCOMMAND isn't taken into account in during var_Create */ - var_AddCallback( p_filter, FILTER_PREFIX "q", PPQCallback, NULL ); + var_Create( p_filter, FILTER_PREFIX "q", VLC_VAR_INTEGER | + VLC_VAR_HASCHOICE | VLC_VAR_DOINHERIT | VLC_VAR_ISCOMMAND ); + text.psz_string = _("Post processing"); var_Change( p_filter, FILTER_PREFIX "q", VLC_VAR_SETTEXT, &text, NULL ); var_Get( p_filter, FILTER_PREFIX "q", &val_orig ); var_Change( p_filter, FILTER_PREFIX "q", VLC_VAR_DELCHOICE, &val_orig, NULL ); - val.psz_string = var_CreateGetNonEmptyStringCommand( - p_filter, FILTER_PREFIX "name" ); - var_AddCallback( p_filter, FILTER_PREFIX "name", PPNameCallback, NULL ); + val.psz_string = var_GetNonEmptyString( p_filter, FILTER_PREFIX "name" ); if( val_orig.i_int ) { - p_sys->pp_mode = pp_get_mode_by_name_and_quality( val.psz_string?: + p_sys->pp_mode = pp_get_mode_by_name_and_quality( val.psz_string ? + val.psz_string : "default", val_orig.i_int ); @@ -204,7 +215,6 @@ static int OpenPostproc( vlc_object_t *p_this ) { msg_Err( p_filter, "Error while creating post processing mode." ); free( val.psz_string ); - var_Destroy( p_filter, FILTER_PREFIX "q" ); pp_free_context( p_sys->pp_context ); free( p_sys ); return VLC_EGENERIC; @@ -239,9 +249,14 @@ static int OpenPostproc( vlc_object_t *p_this ) vlc_mutex_init( &p_sys->lock ); + /* Add the callback at the end to prevent crashes */ + var_AddCallback( p_filter, FILTER_PREFIX "q", PPQCallback, NULL ); + var_AddCallback( p_filter, FILTER_PREFIX "name", PPNameCallback, NULL ); + p_filter->pf_video_filter = PostprocPict; - p_sys->b_had_matrix = true; + msg_Warn( p_filter, "Quantification table was not set by video decoder. " + "Postprocessing won't look good." ); return VLC_SUCCESS; } @@ -252,6 +267,12 @@ static void ClosePostproc( vlc_object_t *p_this ) { filter_t *p_filter = (filter_t *)p_this; filter_sys_t *p_sys = p_filter->p_sys; + + /* delete the callback before destroying the mutex */ + var_DelCallback( p_filter, FILTER_PREFIX "q", PPQCallback, NULL ); + var_DelCallback( p_filter, FILTER_PREFIX "name", PPNameCallback, NULL ); + + /* Destroy the resources */ vlc_mutex_destroy( &p_sys->lock ); pp_free_context( p_sys->pp_context ); if( p_sys->pp_mode ) pp_free_mode( p_sys->pp_mode ); @@ -270,21 +291,23 @@ static picture_t *PostprocPict( filter_t *p_filter, picture_t *p_pic ) int i_plane; int i_src_stride[3], i_dst_stride[3]; - vlc_mutex_lock( &p_sys->lock ); /* Lock to prevent issues if pp_mode is changed */ - if( !p_sys->pp_mode ) - { - vlc_mutex_unlock( &p_sys->lock ); - return p_pic; - } - picture_t *p_outpic = filter_NewPicture( p_filter ); if( !p_outpic ) { picture_Release( p_pic ); - vlc_mutex_unlock( &p_sys->lock ); return NULL; } + /* Lock to prevent issues if pp_mode is changed */ + vlc_mutex_lock( &p_sys->lock ); + if( !p_sys->pp_mode ) + { + vlc_mutex_unlock( &p_sys->lock ); + picture_CopyPixels( p_outpic, p_pic ); + return CopyInfoAndRelease( p_outpic, p_pic ); + } + + for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ ) { src[i_plane] = p_pic->p[i_plane].p_pixels; @@ -296,29 +319,17 @@ static picture_t *PostprocPict( filter_t *p_filter, picture_t *p_pic ) i_dst_stride[i_plane] = p_outpic->p[i_plane].i_pitch; } - if( !p_pic->p_q && p_sys->b_had_matrix ) - { - msg_Warn( p_filter, "Quantification table was not set by video decoder. Postprocessing won't look good." ); - p_sys->b_had_matrix = false; - } - else if( p_pic->p_q ) - { - p_sys->b_had_matrix = true; - } - pp_postprocess( src, i_src_stride, dst, i_dst_stride, p_filter->fmt_in.video.i_width, - p_filter->fmt_in.video.i_height, - p_pic->p_q, p_pic->i_qstride, - p_sys->pp_mode, p_sys->pp_context, - p_pic->i_qtype == QTYPE_MPEG2 ? PP_PICT_TYPE_QP2 : 0 ); + p_filter->fmt_in.video.i_height, NULL, 0, + p_sys->pp_mode, p_sys->pp_context, 0 ); vlc_mutex_unlock( &p_sys->lock ); return CopyInfoAndRelease( p_outpic, p_pic ); } /***************************************************************************** - * + * PPChangeMode: change the current mode and quality *****************************************************************************/ static void PPChangeMode( filter_t *p_filter, const char *psz_name, int i_quality ) @@ -327,7 +338,8 @@ static void PPChangeMode( filter_t *p_filter, const char *psz_name, vlc_mutex_lock( &p_sys->lock ); if( i_quality > 0 ) { - pp_mode_t *pp_mode = pp_get_mode_by_name_and_quality( psz_name?: + pp_mode *pp_mode = pp_get_mode_by_name_and_quality( psz_name ? + psz_name : "default", i_quality ); if( pp_mode ) @@ -366,6 +378,7 @@ static int PPNameCallback( vlc_object_t *p_this, const char *psz_var, filter_t *p_filter = (filter_t *)p_this; int i_quality = var_GetInteger( p_filter, FILTER_PREFIX "q" ); - PPChangeMode( p_filter, *newval.psz_string?newval.psz_string:NULL, i_quality ); + PPChangeMode( p_filter, *newval.psz_string ? newval.psz_string : NULL, + i_quality ); return VLC_SUCCESS; }