From: ddennedy Date: Sat, 20 Dec 2008 01:18:33 +0000 (+0000) Subject: avformat/Makefile, avformat/factory.c, avformat/filter_swscale.c: X-Git-Url: http://research.m1stereo.tv/gitweb?a=commitdiff_plain;h=27464f5e6d9efb356afd7dc294a11e7c1a009de8;p=melted avformat/Makefile, avformat/factory.c, avformat/filter_swscale.c: add new image scaler using FFmpeg libswcale. fezzik.ini: add swscale at higher priority than gtk2/rescale. git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@1273 d19143bc-622f-0410-bfdd-b5b2a6649095 --- diff --git a/src/modules/avformat/Makefile b/src/modules/avformat/Makefile index 6a6dd5c..0007fd9 100644 --- a/src/modules/avformat/Makefile +++ b/src/modules/avformat/Makefile @@ -8,6 +8,10 @@ OBJS = factory.o \ filter_avresample.o \ filter_avdeinterlace.o +ifdef SWSCALE +OBJS += filter_swscale.o +endif + ifdef CODECS OBJS += producer_avformat.o \ consumer_avformat.o diff --git a/src/modules/avformat/factory.c b/src/modules/avformat/factory.c index 7e4332c..0952a95 100644 --- a/src/modules/avformat/factory.c +++ b/src/modules/avformat/factory.c @@ -28,6 +28,7 @@ extern mlt_consumer consumer_avformat_init( mlt_profile profile, char *file ); extern mlt_filter filter_avcolour_space_init( void *arg ); extern mlt_filter filter_avdeinterlace_init( void *arg ); extern mlt_filter filter_avresample_init( char *arg ); +extern mlt_filter filter_swscale_init( mlt_profile profile, char *arg ); extern mlt_producer producer_avformat_init( mlt_profile profile, char *file ); // ffmpeg Header files @@ -111,6 +112,8 @@ static void *create_service( mlt_profile profile, mlt_service_type type, const c return filter_avdeinterlace_init( arg ); if ( !strcmp( id, "avresample" ) ) return filter_avresample_init( arg ); + if ( !strcmp( id, "swscale" ) ) + return filter_swscale_init( profile, arg ); return NULL; } @@ -150,4 +153,5 @@ MLT_REPOSITORY MLT_REGISTER( filter_type, "avcolor_space", create_service ); MLT_REGISTER( filter_type, "avdeinterlace", create_service ); MLT_REGISTER( filter_type, "avresample", create_service ); + MLT_REGISTER( filter_type, "swscale", create_service ); } diff --git a/src/modules/avformat/filter_swscale.c b/src/modules/avformat/filter_swscale.c new file mode 100644 index 0000000..4571acd --- /dev/null +++ b/src/modules/avformat/filter_swscale.c @@ -0,0 +1,148 @@ +/* + * filter_swscale.c -- image scaling filter + * Copyright (C) 2008-2009 Ushodaya Enterprises Limited + * Author: Dan Dennedy + * + * This library 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 library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include + + +// ffmpeg Header files +#include +#include + +#include +#include +#include + +static inline int is_big_endian( ) +{ + union { int i; char c[ 4 ]; } big_endian_test; + big_endian_test.i = 1; + + return big_endian_test.c[ 0 ] != 1; +} + +static inline int convert_mlt_to_av_cs( mlt_image_format format ) +{ + int value = 0; + + switch( format ) + { + case mlt_image_rgb24: + value = PIX_FMT_RGB24; + break; + case mlt_image_rgb24a: + value = PIX_FMT_RGBA32; + break; + case mlt_image_yuv422: + value = PIX_FMT_YUV422; + break; + case mlt_image_yuv420p: + value = PIX_FMT_YUV420P; + break; + case mlt_image_opengl: + case mlt_image_none: + fprintf( stderr, "Invalid format...\n" ); + break; + } + + return value; +} + +static int filter_scale( mlt_frame this, uint8_t **image, mlt_image_format iformat, mlt_image_format oformat, int iwidth, int iheight, int owidth, int oheight ) +{ + // Get the properties + mlt_properties properties = MLT_FRAME_PROPERTIES( this ); + + // Get the requested interpolation method + char *interps = mlt_properties_get( properties, "rescale.interp" ); + + // Convert to the SwScale flag + int interp = SWS_BILINEAR; + if ( strcmp( interps, "nearest" ) == 0 || strcmp( interps, "neighbor" ) == 0 ) + interp = SWS_POINT; + else if ( strcmp( interps, "tiles" ) == 0 || strcmp( interps, "fast_bilinear" ) == 0 ) + interp = SWS_FAST_BILINEAR; + else if ( strcmp( interps, "bilinear" ) == 0 ) + interp = SWS_BILINEAR; + else if ( strcmp( interps, "bicubic" ) == 0 ) + interp = SWS_BICUBIC; + else if ( strcmp( interps, "bicublin" ) == 0 ) + interp = SWS_BICUBLIN; + else if ( strcmp( interps, "gauss" ) == 0 ) + interp = SWS_GAUSS; + else if ( strcmp( interps, "sinc" ) == 0 ) + interp = SWS_SINC; + else if ( strcmp( interps, "hyper" ) == 0 || strcmp( interps, "lanczos" ) == 0 ) + interp = SWS_LANCZOS; + else if ( strcmp( interps, "spline" ) == 0 ) + interp = SWS_SPLINE; + + // Convert the pixel formats + iformat = convert_mlt_to_av_cs( iformat ); + oformat = convert_mlt_to_av_cs( oformat ); + + // Create the context and output image + struct SwsContext *context = sws_getContext( iwidth, iheight, iformat, owidth, oheight, oformat, interp, NULL, NULL, NULL); + AVPicture input; + avpicture_fill( &input, *image, iformat, iwidth, iheight ); + AVPicture output; + uint8_t *outbuf = mlt_pool_alloc( owidth * ( oheight + 1 ) * 2 ); + avpicture_fill( &output, outbuf, oformat, owidth, oheight ); + + // Perform the scaling + sws_scale( context, input.data, input.linesize, 0, iheight, output.data, output.linesize); + sws_freeContext( context ); + + // Now update the frame + mlt_properties_set_data( properties, "image", outbuf, owidth * ( oheight + 1 ) * 2, ( mlt_destructor )mlt_pool_release, NULL ); + mlt_properties_set_int( properties, "width", owidth ); + mlt_properties_set_int( properties, "height", oheight ); + + // Return the output + *image = outbuf; + + return 0; +} + +/** Constructor for the filter. +*/ + +mlt_filter filter_swscale_init( mlt_profile profile, void *arg ) +{ + // Create a new scaler + mlt_filter this = mlt_factory_filter( profile, "rescale", arg ); + + // If successful, then initialise it + if ( this != NULL ) + { + // Get the properties + mlt_properties properties = MLT_FILTER_PROPERTIES( this ); + + // Set the inerpolation + mlt_properties_set( properties, "interpolation", arg == NULL ? "bilinear" : arg ); + + // Set the method + mlt_properties_set_data( properties, "method", filter_scale, 0, NULL, NULL ); + } + + return this; +} diff --git a/src/modules/fezzik.ini b/src/modules/fezzik.ini index c3d7fcc..f0b2382 100644 --- a/src/modules/fezzik.ini +++ b/src/modules/fezzik.ini @@ -7,7 +7,7 @@ # the second and third are applied as applicable). deinterlace=deinterlace,avdeinterlace -rescaler=mcrescale,gtkrescale,rescale +rescaler=mcrescale,swscale,gtkrescale,rescale resizer=resize resampler=resample,soxresample,avresample data=data_feed:attr_check