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 static inline int is_big_endian( )
38 union
{ int i
; char c
[ 4 ]; } big_endian_test
;
39 big_endian_test
.i
= 1;
41 return big_endian_test
.c
[ 0 ] != 1;
44 static inline int convert_mlt_to_av_cs( mlt_image_format format
)
51 value
= PIX_FMT_RGB24
;
53 case mlt_image_rgb24a
:
54 value
= PIX_FMT_RGBA32
;
56 case mlt_image_yuv422
:
57 value
= PIX_FMT_YUV422
;
59 case mlt_image_yuv420p
:
60 value
= PIX_FMT_YUV420P
;
62 case mlt_image_opengl
:
64 fprintf( stderr
, "Invalid format...\n" );
71 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
)
74 mlt_properties properties
= MLT_FRAME_PROPERTIES( this );
76 // Get the requested interpolation method
77 char *interps
= mlt_properties_get( properties
, "rescale.interp" );
79 // Convert to the SwScale flag
80 int interp
= SWS_BILINEAR
;
81 if ( strcmp( interps
, "nearest" ) == 0 || strcmp( interps
, "neighbor" ) == 0 )
83 else if ( strcmp( interps
, "tiles" ) == 0 || strcmp( interps
, "fast_bilinear" ) == 0 )
84 interp
= SWS_FAST_BILINEAR
;
85 else if ( strcmp( interps
, "bilinear" ) == 0 )
86 interp
= SWS_BILINEAR
;
87 else if ( strcmp( interps
, "bicubic" ) == 0 )
89 else if ( strcmp( interps
, "bicublin" ) == 0 )
90 interp
= SWS_BICUBLIN
;
91 else if ( strcmp( interps
, "gauss" ) == 0 )
93 else if ( strcmp( interps
, "sinc" ) == 0 )
95 else if ( strcmp( interps
, "hyper" ) == 0 || strcmp( interps
, "lanczos" ) == 0 )
97 else if ( strcmp( interps
, "spline" ) == 0 )
102 uint8_t *outbuf
= mlt_pool_alloc( owidth
* ( oheight
+ 1 ) * 2 );
104 // Convert the pixel formats
105 iformat
= convert_mlt_to_av_cs( iformat
);
106 oformat
= convert_mlt_to_av_cs( oformat
);
108 avpicture_fill( &input
, *image
, iformat
, iwidth
, iheight
);
109 avpicture_fill( &output
, outbuf
, oformat
, owidth
, oheight
);
111 // Extract the alpha channel
112 if ( iformat
== PIX_FMT_RGBA32
&& oformat
== PIX_FMT_YUV422
)
114 // Allocate the alpha mask
115 uint8_t *alpha
= mlt_pool_alloc( iwidth
* ( iheight
+ 1 ) );
118 // Convert the image and extract alpha
119 mlt_convert_rgb24a_to_yuv422( *image
, iwidth
, iheight
, iwidth
* 4, outbuf
, alpha
);
120 mlt_properties_set_data( properties
, "alpha", alpha
, iwidth
* ( iheight
+ 1 ), ( mlt_destructor
)mlt_pool_release
, NULL
);
121 iformat
= PIX_FMT_YUV422
;
122 avpicture_fill( &input
, outbuf
, iformat
, iwidth
, iheight
);
123 avpicture_fill( &output
, *image
, oformat
, owidth
, oheight
);
127 // Create the context and output image
128 struct SwsContext
*context
= sws_getContext( iwidth
, iheight
, iformat
, owidth
, oheight
, oformat
, interp
, NULL
, NULL
, NULL
);
131 // Perform the scaling
132 sws_scale( context
, input
.data
, input
.linesize
, 0, iheight
, output
.data
, output
.linesize
);
133 sws_freeContext( context
);
135 // Now update the frame
136 mlt_properties_set_data( properties
, "image", output
.data
[0], owidth
* ( oheight
+ 1 ) * 2, ( mlt_destructor
)mlt_pool_release
, NULL
);
137 mlt_properties_set_int( properties
, "width", owidth
);
138 mlt_properties_set_int( properties
, "height", oheight
);
141 *image
= output
.data
[0];
143 // Scale the alpha channel only if exists and not correct size
145 mlt_properties_get_data( properties
, "alpha", &alpha_size
);
146 if ( alpha_size
> 0 && alpha_size
!= ( owidth
* oheight
) )
148 // Create the context and output image
149 uint8_t *alpha
= mlt_frame_get_alpha_mask( this );
152 iformat
= oformat
= PIX_FMT_GRAY8
;
153 struct SwsContext
*context
= sws_getContext( iwidth
, iheight
, iformat
, owidth
, oheight
, oformat
, interp
, NULL
, NULL
, NULL
);
154 avpicture_fill( &input
, alpha
, iformat
, iwidth
, iheight
);
155 outbuf
= mlt_pool_alloc( owidth
* oheight
);
156 avpicture_fill( &output
, outbuf
, oformat
, owidth
, oheight
);
158 // Perform the scaling
159 sws_scale( context
, input
.data
, input
.linesize
, 0, iheight
, output
.data
, output
.linesize
);
160 sws_freeContext( context
);
162 // Set it back on the frame
163 mlt_properties_set_data( MLT_FRAME_PROPERTIES( this ), "alpha", output
.data
[0], owidth
* oheight
, mlt_pool_release
, NULL
);
170 /** Constructor for the filter.
173 mlt_filter
filter_swscale_init( mlt_profile profile
, void *arg
)
175 // Create a new scaler
176 mlt_filter
this = mlt_factory_filter( profile
, "rescale", arg
);
178 // If successful, then initialise it
181 // Get the properties
182 mlt_properties properties
= MLT_FILTER_PROPERTIES( this );
184 // Set the inerpolation
185 mlt_properties_set( properties
, "interpolation", arg
== NULL ?
"bilinear" : arg
);
188 mlt_properties_set_data( properties
, "method", filter_scale
, 0, NULL
, NULL
);