📄 swscale.c
字号:
/***************************************************************************** * swscale.c: scaling and chroma conversion using libswscale ***************************************************************************** * Copyright (C) 1999-2008 the VideoLAN team * $Id: 81a963259dad1893873d3414feecca226d47e8d1 $ * * Authors: Laurent Aimar <fenrir@via.ecp.fr> * Gildas Bazin <gbazin@videolan.org> * * 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 * (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. * * 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. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include <vlc_plugin.h>#include <vlc_vout.h>#include <vlc_filter.h>#ifdef HAVE_LIBSWSCALE_SWSCALE_H# include <libswscale/swscale.h>#elif defined(HAVE_FFMPEG_SWSCALE_H)# include <ffmpeg/swscale.h>#endif/* Gruikkkkkkkkkk!!!!! */#include "../codec/avcodec/chroma.h"/***************************************************************************** * Module descriptor *****************************************************************************/static int OpenScaler( vlc_object_t * );static void CloseScaler( vlc_object_t * );#define SCALEMODE_TEXT N_("Scaling mode")#define SCALEMODE_LONGTEXT N_("Scaling mode to use.")static const int pi_mode_values[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };const char *const ppsz_mode_descriptions[] ={ N_("Fast bilinear"), N_("Bilinear"), N_("Bicubic (good quality)"), N_("Experimental"), N_("Nearest neighbour (bad quality)"), N_("Area"), N_("Luma bicubic / chroma bilinear"), N_("Gauss"), N_("SincR"), N_("Lanczos"), N_("Bicubic spline") };vlc_module_begin(); set_description( N_("Video scaling filter") ); set_capability( "video filter2", 150 ); set_category( CAT_VIDEO ); set_subcategory( SUBCAT_VIDEO_VFILTER ); set_callbacks( OpenScaler, CloseScaler ); add_integer( "swscale-mode", 2, NULL, SCALEMODE_TEXT, SCALEMODE_LONGTEXT, true ); change_integer_list( pi_mode_values, ppsz_mode_descriptions, NULL );vlc_module_end();/* Version checking */#if LIBSWSCALE_VERSION_INT >= ((0<<16)+(5<<8)+0)/**************************************************************************** * Local prototypes ****************************************************************************/void *( *swscale_fast_memcpy )( void *, const void *, size_t );/** * Internal swscale filter structure. */struct filter_sys_t{ SwsFilter *p_src_filter; SwsFilter *p_dst_filter; int i_cpu_mask, i_sws_flags; video_format_t fmt_in; video_format_t fmt_out; struct SwsContext *ctx; struct SwsContext *ctxA; picture_t *p_src_a; picture_t *p_dst_a; int i_extend_factor; picture_t *p_src_e; picture_t *p_dst_e; bool b_add_a;};static picture_t *Filter( filter_t *, picture_t * );static int Init( filter_t * );static void Clean( filter_t * );typedef struct{ int i_fmti; int i_fmto; bool b_has_a; bool b_add_a; int i_sws_flags;} ScalerConfiguration;static int GetParameters( ScalerConfiguration *, const video_format_t *p_fmti, const video_format_t *p_fmto, int i_sws_flags_default );static int GetSwsCpuMask(void);/* SwScaler point resize quality seems really bad, let our scale module do it * (change it to true to try) */#define ALLOW_YUVP (false)/* SwScaler does not like too small picture */#define MINIMUM_WIDTH (16)/* XXX is it always 3 even for BIG_ENDIAN (blend.c seems to think so) ? */#define OFFSET_A (3)/***************************************************************************** * OpenScaler: probe the filter and return score *****************************************************************************/static int OpenScaler( vlc_object_t *p_this ){ filter_t *p_filter = (filter_t*)p_this; filter_sys_t *p_sys; int i_sws_mode; float sws_lum_gblur = 0.0, sws_chr_gblur = 0.0; int sws_chr_vshift = 0, sws_chr_hshift = 0; float sws_chr_sharpen = 0.0, sws_lum_sharpen = 0.0; if( GetParameters( NULL, &p_filter->fmt_in.video, &p_filter->fmt_out.video, 0 ) ) return VLC_EGENERIC; /* */ p_filter->pf_video_filter = Filter; /* Allocate the memory needed to store the decoder's structure */ if( ( p_filter->p_sys = p_sys = malloc(sizeof(filter_sys_t)) ) == NULL ) return VLC_ENOMEM; /* FIXME pointer assignment may not be atomic */ swscale_fast_memcpy = vlc_memcpy; /* Set CPU capabilities */ p_sys->i_cpu_mask = GetSwsCpuMask(); /* */ i_sws_mode = var_CreateGetInteger( p_filter, "swscale-mode" ); switch( i_sws_mode ) { case 0: p_sys->i_sws_flags = SWS_FAST_BILINEAR; break; case 1: p_sys->i_sws_flags = SWS_BILINEAR; break; case 2: p_sys->i_sws_flags = SWS_BICUBIC; break; case 3: p_sys->i_sws_flags = SWS_X; break; case 4: p_sys->i_sws_flags = SWS_POINT; break; case 5: p_sys->i_sws_flags = SWS_AREA; break; case 6: p_sys->i_sws_flags = SWS_BICUBLIN; break; case 7: p_sys->i_sws_flags = SWS_GAUSS; break; case 8: p_sys->i_sws_flags = SWS_SINC; break; case 9: p_sys->i_sws_flags = SWS_LANCZOS; break; case 10: p_sys->i_sws_flags = SWS_SPLINE; break; default: p_sys->i_sws_flags = SWS_BICUBIC; i_sws_mode = 2; break; } p_sys->p_src_filter = sws_getDefaultFilter( sws_lum_gblur, sws_chr_gblur, sws_lum_sharpen, sws_chr_sharpen, sws_chr_hshift, sws_chr_vshift, 0 ); p_sys->p_dst_filter = NULL; /* Misc init */ p_sys->ctx = NULL; p_sys->ctxA = NULL; p_sys->p_src_a = NULL; p_sys->p_dst_a = NULL; p_sys->p_src_e = NULL; p_sys->p_dst_e = NULL; memset( &p_sys->fmt_in, 0, sizeof(p_sys->fmt_in) ); memset( &p_sys->fmt_out, 0, sizeof(p_sys->fmt_out) ); if( Init( p_filter ) ) { if( p_sys->p_src_filter ) sws_freeFilter( p_sys->p_src_filter ); free( p_sys ); return VLC_EGENERIC; } msg_Dbg( p_filter, "%ix%i chroma: %4.4s -> %ix%i chroma: %4.4s with scaling using %s", p_filter->fmt_in.video.i_width, p_filter->fmt_in.video.i_height, (char *)&p_filter->fmt_in.video.i_chroma, p_filter->fmt_out.video.i_width, p_filter->fmt_out.video.i_height, (char *)&p_filter->fmt_out.video.i_chroma, ppsz_mode_descriptions[i_sws_mode] ); return VLC_SUCCESS;}/***************************************************************************** * CloseFilter: clean up the filter *****************************************************************************/static void CloseScaler( vlc_object_t *p_this ){ filter_t *p_filter = (filter_t*)p_this; filter_sys_t *p_sys = p_filter->p_sys; Clean( p_filter ); if( p_sys->p_src_filter ) sws_freeFilter( p_sys->p_src_filter ); free( p_sys );}/***************************************************************************** * Helpers *****************************************************************************/static int GetSwsCpuMask(void){ const unsigned int i_cpu = vlc_CPU(); int i_sws_cpu = 0; if( i_cpu & CPU_CAPABILITY_MMX ) i_sws_cpu |= SWS_CPU_CAPS_MMX;#if (LIBSWSCALE_VERSION_INT >= ((0<<16)+(5<<8)+0)) if( i_cpu & CPU_CAPABILITY_MMXEXT ) i_sws_cpu |= SWS_CPU_CAPS_MMX2;#endif if( i_cpu & CPU_CAPABILITY_3DNOW ) i_sws_cpu |= SWS_CPU_CAPS_3DNOW; if( i_cpu & CPU_CAPABILITY_ALTIVEC ) i_sws_cpu |= SWS_CPU_CAPS_ALTIVEC; return i_sws_cpu;}static bool IsFmtSimilar( const video_format_t *p_fmt1, const video_format_t *p_fmt2 ){ return p_fmt1->i_chroma == p_fmt2->i_chroma && p_fmt1->i_width == p_fmt2->i_width && p_fmt1->i_height == p_fmt2->i_height;}static int GetParameters( ScalerConfiguration *p_cfg, const video_format_t *p_fmti, const video_format_t *p_fmto, int i_sws_flags_default ){ int i_fmti = -1; int i_fmto = -1; bool b_has_ai = false; bool b_has_ao = false; int i_sws_flags = i_sws_flags_default; GetFfmpegChroma( &i_fmti, *p_fmti ); GetFfmpegChroma( &i_fmto, *p_fmto ); if( p_fmti->i_chroma == p_fmto->i_chroma ) { if( p_fmti->i_chroma == VLC_FOURCC( 'Y', 'U', 'V', 'P' ) && ALLOW_YUVP ) { i_fmti = i_fmto = PIX_FMT_GRAY8; i_sws_flags = SWS_POINT; } } if( p_fmti->i_chroma == VLC_FOURCC( 'Y', 'U', 'V', 'A' ) ) { i_fmti = PIX_FMT_YUV444P; b_has_ai = true; } else if( p_fmti->i_chroma == VLC_FOURCC( 'R', 'G', 'B', 'A' ) ) { i_fmti = PIX_FMT_BGR32; b_has_ai = true; } if( p_fmto->i_chroma == VLC_FOURCC( 'Y', 'U', 'V', 'A' ) ) { i_fmto = PIX_FMT_YUV444P; b_has_ao = true; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -