2 * filter_swscale.c -- image scaling filter
3 * Copyright (C) 2008-2009 Ushodaya Enterprises Limited
4 * Author: Dan Dennedy <dan@dennedy.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <framework/mlt_filter.h>
22 #include <framework/mlt_frame.h>
23 #include <framework/mlt_factory.h>
24 #include <framework/mlt_factory.h>
27 // ffmpeg Header files
36 #if LIBAVUTIL_VERSION_INT < (50<<16)
37 #define PIX_FMT_RGB32 PIX_FMT_RGBA32
38 #define PIX_FMT_YUYV422 PIX_FMT_YUV422
41 static inline int convert_mlt_to_av_cs( mlt_image_format format )
48 value = PIX_FMT_RGB24;
50 case mlt_image_rgb24a:
51 case mlt_image_opengl:
52 value = PIX_FMT_RGB32;
54 case mlt_image_yuv422:
55 value = PIX_FMT_YUYV422;
57 case mlt_image_yuv420p:
58 value = PIX_FMT_YUV420P;
61 fprintf( stderr, "Invalid format...\n" );
68 static int filter_scale( mlt_frame this, uint8_t **image, mlt_image_format *format, int iwidth, int iheight, int owidth, int oheight )
71 mlt_properties properties = MLT_FRAME_PROPERTIES( this );
73 // Get the requested interpolation method
74 char *interps = mlt_properties_get( properties, "rescale.interp" );
76 // Convert to the SwScale flag
77 int interp = SWS_BILINEAR;
78 if ( strcmp( interps, "nearest" ) == 0 || strcmp( interps, "neighbor" ) == 0 )
80 else if ( strcmp( interps, "tiles" ) == 0 || strcmp( interps, "fast_bilinear" ) == 0 )
81 interp = SWS_FAST_BILINEAR;
82 else if ( strcmp( interps, "bilinear" ) == 0 )
83 interp = SWS_BILINEAR;
84 else if ( strcmp( interps, "bicubic" ) == 0 )
86 else if ( strcmp( interps, "bicublin" ) == 0 )
87 interp = SWS_BICUBLIN;
88 else if ( strcmp( interps, "gauss" ) == 0 )
90 else if ( strcmp( interps, "sinc" ) == 0 )
92 else if ( strcmp( interps, "hyper" ) == 0 || strcmp( interps, "lanczos" ) == 0 )
94 else if ( strcmp( interps, "spline" ) == 0 )
97 // Determine the bytes per pixel
101 case mlt_image_yuv422:
104 case mlt_image_rgb24:
107 case mlt_image_rgb24a:
108 case mlt_image_opengl:
112 // XXX: we only know how to rescale packed formats
116 // Convert the pixel formats
117 int avformat = convert_mlt_to_av_cs( *format );
119 // Fill out the AVPictures
122 uint8_t *outbuf = mlt_pool_alloc( owidth * ( oheight + 1 ) * bpp );
123 avpicture_fill( &input, *image, avformat, iwidth, iheight );
124 avpicture_fill( &output, outbuf, avformat, owidth, oheight );
126 // Create the context and output image
127 struct SwsContext *context = sws_getContext( iwidth, iheight, avformat, owidth, oheight, avformat, interp, NULL, NULL, NULL);
130 // Perform the scaling
131 sws_scale( context, input.data, input.linesize, 0, iheight, output.data, output.linesize);
132 sws_freeContext( context );
134 // Now update the frame
135 mlt_properties_set_data( properties, "image", output.data[0], owidth * ( oheight + 1 ) * bpp, ( mlt_destructor )mlt_pool_release, NULL );
136 mlt_properties_set_int( properties, "width", owidth );
137 mlt_properties_set_int( properties, "height", oheight );
140 *image = output.data[0];
142 // Scale the alpha channel only if exists and not correct size
144 mlt_properties_get_data( properties, "alpha", &alpha_size );
145 if ( alpha_size > 0 && alpha_size != ( owidth * oheight ) )
147 // Create the context and output image
148 uint8_t *alpha = mlt_frame_get_alpha_mask( this );
151 avformat = PIX_FMT_GRAY8;
152 struct SwsContext *context = sws_getContext( iwidth, iheight, avformat, owidth, oheight, avformat, interp, NULL, NULL, NULL);
153 avpicture_fill( &input, alpha, avformat, iwidth, iheight );
154 outbuf = mlt_pool_alloc( owidth * oheight );
155 avpicture_fill( &output, outbuf, avformat, owidth, oheight );
157 // Perform the scaling
158 sws_scale( context, input.data, input.linesize, 0, iheight, output.data, output.linesize);
159 sws_freeContext( context );
161 // Set it back on the frame
162 mlt_properties_set_data( MLT_FRAME_PROPERTIES( this ), "alpha", output.data[0], owidth * oheight, mlt_pool_release, NULL );
169 /** Constructor for the filter.
172 mlt_filter filter_swscale_init( mlt_profile profile, void *arg )
174 // Create a new scaler
175 mlt_filter this = mlt_factory_filter( profile, "rescale", arg );
177 // If successful, then initialise it
180 // Get the properties
181 mlt_properties properties = MLT_FILTER_PROPERTIES( this );
183 // Set the inerpolation
184 mlt_properties_set( properties, "interpolation", arg == NULL ? "bilinear" : arg );
187 mlt_properties_set_data( properties, "method", filter_scale, 0, NULL, NULL );