avformat: fix compilation due to recent PIX_FMT changes in libavutil v50.
[melted] / src / modules / avformat / filter_swscale.c
1 /*
2 * filter_swscale.c -- image scaling filter
3 * Copyright (C) 2008-2009 Ushodaya Enterprises Limited
4 * Author: Dan Dennedy <dan@dennedy.org>
5 *
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.
10 *
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.
15 *
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
19 */
20
21 #include <framework/mlt_filter.h>
22 #include <framework/mlt_frame.h>
23 #include <framework/mlt_factory.h>
24 #include <framework/mlt_factory.h>
25
26
27 // ffmpeg Header files
28 #include <avformat.h>
29 #include <swscale.h>
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <assert.h>
35
36 #if LIBAVUTIL_VERSION_INT < (50<<16)
37 #define PIX_FMT_RGB32 PIX_FMT_RGBA32
38 #define PIX_FMT_YUYV422 PIX_FMT_YUV422
39 #endif
40
41 static inline int is_big_endian( )
42 {
43 union { int i; char c[ 4 ]; } big_endian_test;
44 big_endian_test.i = 1;
45
46 return big_endian_test.c[ 0 ] != 1;
47 }
48
49 static inline int convert_mlt_to_av_cs( mlt_image_format format )
50 {
51 int value = 0;
52
53 switch( format )
54 {
55 case mlt_image_rgb24:
56 value = PIX_FMT_RGB24;
57 break;
58 case mlt_image_rgb24a:
59 value = PIX_FMT_RGB32;
60 break;
61 case mlt_image_yuv422:
62 value = PIX_FMT_YUYV422;
63 break;
64 case mlt_image_yuv420p:
65 value = PIX_FMT_YUV420P;
66 break;
67 case mlt_image_opengl:
68 case mlt_image_none:
69 fprintf( stderr, "Invalid format...\n" );
70 break;
71 }
72
73 return value;
74 }
75
76 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 )
77 {
78 // Get the properties
79 mlt_properties properties = MLT_FRAME_PROPERTIES( this );
80
81 // Get the requested interpolation method
82 char *interps = mlt_properties_get( properties, "rescale.interp" );
83
84 // Convert to the SwScale flag
85 int interp = SWS_BILINEAR;
86 if ( strcmp( interps, "nearest" ) == 0 || strcmp( interps, "neighbor" ) == 0 )
87 interp = SWS_POINT;
88 else if ( strcmp( interps, "tiles" ) == 0 || strcmp( interps, "fast_bilinear" ) == 0 )
89 interp = SWS_FAST_BILINEAR;
90 else if ( strcmp( interps, "bilinear" ) == 0 )
91 interp = SWS_BILINEAR;
92 else if ( strcmp( interps, "bicubic" ) == 0 )
93 interp = SWS_BICUBIC;
94 else if ( strcmp( interps, "bicublin" ) == 0 )
95 interp = SWS_BICUBLIN;
96 else if ( strcmp( interps, "gauss" ) == 0 )
97 interp = SWS_GAUSS;
98 else if ( strcmp( interps, "sinc" ) == 0 )
99 interp = SWS_SINC;
100 else if ( strcmp( interps, "hyper" ) == 0 || strcmp( interps, "lanczos" ) == 0 )
101 interp = SWS_LANCZOS;
102 else if ( strcmp( interps, "spline" ) == 0 )
103 interp = SWS_SPLINE;
104
105 AVPicture input;
106 AVPicture output;
107 uint8_t *outbuf = mlt_pool_alloc( owidth * ( oheight + 1 ) * 2 );
108
109 // Convert the pixel formats
110 iformat = convert_mlt_to_av_cs( iformat );
111 oformat = convert_mlt_to_av_cs( oformat );
112
113 avpicture_fill( &input, *image, iformat, iwidth, iheight );
114 avpicture_fill( &output, outbuf, oformat, owidth, oheight );
115
116 // Extract the alpha channel
117 if ( iformat == PIX_FMT_RGB32 && oformat == PIX_FMT_YUYV422 )
118 {
119 // Allocate the alpha mask
120 uint8_t *alpha = mlt_pool_alloc( iwidth * ( iheight + 1 ) );
121 if ( alpha )
122 {
123 // Convert the image and extract alpha
124 mlt_convert_rgb24a_to_yuv422( *image, iwidth, iheight, iwidth * 4, outbuf, alpha );
125 mlt_properties_set_data( properties, "alpha", alpha, iwidth * ( iheight + 1 ), ( mlt_destructor )mlt_pool_release, NULL );
126 iformat = PIX_FMT_YUYV422;
127 avpicture_fill( &input, outbuf, iformat, iwidth, iheight );
128 avpicture_fill( &output, *image, oformat, owidth, oheight );
129 }
130 }
131
132 // Create the context and output image
133 struct SwsContext *context = sws_getContext( iwidth, iheight, iformat, owidth, oheight, oformat, interp, NULL, NULL, NULL);
134 assert(context);
135
136 // Perform the scaling
137 sws_scale( context, input.data, input.linesize, 0, iheight, output.data, output.linesize);
138 sws_freeContext( context );
139
140 // Now update the frame
141 mlt_properties_set_data( properties, "image", output.data[0], owidth * ( oheight + 1 ) * 2, ( mlt_destructor )mlt_pool_release, NULL );
142 mlt_properties_set_int( properties, "width", owidth );
143 mlt_properties_set_int( properties, "height", oheight );
144
145 // Return the output
146 *image = output.data[0];
147
148 // Scale the alpha channel only if exists and not correct size
149 int alpha_size = 0;
150 mlt_properties_get_data( properties, "alpha", &alpha_size );
151 if ( alpha_size > 0 && alpha_size != ( owidth * oheight ) )
152 {
153 // Create the context and output image
154 uint8_t *alpha = mlt_frame_get_alpha_mask( this );
155 if ( alpha )
156 {
157 iformat = oformat = PIX_FMT_GRAY8;
158 struct SwsContext *context = sws_getContext( iwidth, iheight, iformat, owidth, oheight, oformat, interp, NULL, NULL, NULL);
159 avpicture_fill( &input, alpha, iformat, iwidth, iheight );
160 outbuf = mlt_pool_alloc( owidth * oheight );
161 avpicture_fill( &output, outbuf, oformat, owidth, oheight );
162
163 // Perform the scaling
164 sws_scale( context, input.data, input.linesize, 0, iheight, output.data, output.linesize);
165 sws_freeContext( context );
166
167 // Set it back on the frame
168 mlt_properties_set_data( MLT_FRAME_PROPERTIES( this ), "alpha", output.data[0], owidth * oheight, mlt_pool_release, NULL );
169 }
170 }
171
172 return 0;
173 }
174
175 /** Constructor for the filter.
176 */
177
178 mlt_filter filter_swscale_init( mlt_profile profile, void *arg )
179 {
180 // Create a new scaler
181 mlt_filter this = mlt_factory_filter( profile, "rescale", arg );
182
183 // If successful, then initialise it
184 if ( this != NULL )
185 {
186 // Get the properties
187 mlt_properties properties = MLT_FILTER_PROPERTIES( this );
188
189 // Set the inerpolation
190 mlt_properties_set( properties, "interpolation", arg == NULL ? "bilinear" : arg );
191
192 // Set the method
193 mlt_properties_set_data( properties, "method", filter_scale, 0, NULL, NULL );
194 }
195
196 return this;
197 }