2 * filter_avcolour_space.c -- Colour space filter
3 * Copyright (C) 2004-2005 Ushodaya Enterprises Limited
4 * Author: Charles Yates <charles.yates@pandora.be>
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_log.h>
25 // ffmpeg Header files
31 #if LIBAVUTIL_VERSION_INT < (50<<16)
32 #define PIX_FMT_YUYV422 PIX_FMT_YUV422
38 #if 0 // This test might come in handy elsewhere someday.
39 static int is_big_endian( )
41 union { int i; char c[ 4 ]; } big_endian_test;
42 big_endian_test.i = 1;
44 return big_endian_test.c[ 0 ] != 1;
48 static int convert_mlt_to_av_cs( mlt_image_format format )
55 case mlt_image_rgb24_full:
56 value = PIX_FMT_RGB24;
58 case mlt_image_rgb24a:
59 case mlt_image_opengl:
60 case mlt_image_rgb24a_full:
63 case mlt_image_yuv422:
64 case mlt_image_yuv422_709:
65 value = PIX_FMT_YUYV422;
67 case mlt_image_yuv420p:
68 value = PIX_FMT_YUV420P;
71 mlt_log_error( NULL, "[filter avcolor_space] Invalid format\n" );
85 static void set_luma_transfer( struct SwsContext *context, int is_709, enum luma_scale scale )
88 int range_in, range_out;
89 int brightness, contrast, saturation;
91 if ( sws_getColorspaceDetails( context, &coefficients, &range_in, &coefficients, &range_out,
92 &brightness, &contrast, &saturation ) != -1 )
94 // Don't change these from defaults unless explicitly told to.
98 range_in = range_out = 1;
112 coefficients = sws_getCoefficients( SWS_CS_ITU709 );
113 sws_setColorspaceDetails( context, coefficients, range_in, coefficients, range_out,
114 brightness, contrast, saturation );
118 static void av_convert_image( uint8_t *out, uint8_t *in, int out_fmt, int in_fmt,
119 int width, int height, int is_709, int is_full )
123 int flags = SWS_BILINEAR | SWS_ACCURATE_RND;
125 if ( out_fmt == PIX_FMT_YUYV422 )
126 flags |= SWS_FULL_CHR_H_INP;
128 flags |= SWS_FULL_CHR_H_INT;
130 flags |= SWS_CPU_CAPS_MMX;
133 flags |= SWS_CPU_CAPS_MMX2;
136 avpicture_fill( &input, in, in_fmt, width, height );
137 avpicture_fill( &output, out, out_fmt, width, height );
139 struct SwsContext *context = sws_getContext( width, height, in_fmt,
140 width, height, out_fmt, flags, NULL, NULL, NULL);
141 set_luma_transfer( context, is_709, is_full );
142 sws_scale( context, input.data, input.linesize, 0, height,
143 output.data, output.linesize);
144 sws_freeContext( context );
146 img_convert( &output, out_fmt, &input, in_fmt, width, height );
153 static int convert_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, mlt_image_format output_format )
155 mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
156 int width = mlt_properties_get_int( properties, "width" );
157 int height = mlt_properties_get_int( properties, "height" );
160 if ( *format != output_format )
162 mlt_log_debug( NULL, "[filter avcolor_space] %s -> %s @ %dx%d\n",
163 mlt_image_format_name( *format ), mlt_image_format_name( output_format ),
166 int in_fmt = convert_mlt_to_av_cs( *format );
167 int out_fmt = convert_mlt_to_av_cs( output_format );
168 int size = avpicture_get_size( out_fmt, width, height );
169 uint8_t *output = mlt_pool_alloc( size );
171 if ( *format == mlt_image_rgb24a || *format == mlt_image_opengl )
173 register int len = width * height;
174 uint8_t *alpha = mlt_pool_alloc( len );
178 // Extract the alpha mask from the RGBA image using Duff's Device
179 register uint8_t *s = *image + 3; // start on the alpha component
180 register uint8_t *d = alpha;
181 register int n = ( len + 7 ) / 8;
185 case 0: do { *d++ = *s; s += 4;
186 case 7: *d++ = *s; s += 4;
187 case 6: *d++ = *s; s += 4;
188 case 5: *d++ = *s; s += 4;
189 case 4: *d++ = *s; s += 4;
190 case 3: *d++ = *s; s += 4;
191 case 2: *d++ = *s; s += 4;
192 case 1: *d++ = *s; s += 4;
196 mlt_properties_set_data( properties, "alpha", alpha, len, mlt_pool_release, NULL );
197 frame->get_alpha_mask = NULL;
202 int is_709 = output_format == mlt_image_yuv422 && width * height > 750000;
203 enum luma_scale luma = LUMA_SCALE_AUTO;
204 av_convert_image( output, *image, out_fmt, in_fmt, width, height, is_709, luma );
206 *format = output_format;
207 mlt_properties_set_data( properties, "image", output, size, mlt_pool_release, NULL );
208 mlt_properties_set_int( properties, "format", output_format );
210 if ( output_format == mlt_image_rgb24a || output_format == mlt_image_opengl )
212 register int len = width * height;
214 uint8_t *alpha = mlt_frame_get_alpha_mask( frame );
215 mlt_properties_get_data( properties, "alpha", &alpha_size );
217 if ( alpha && alpha_size >= len )
219 // Merge the alpha mask from into the RGBA image using Duff's Device
220 register uint8_t *s = alpha;
221 register uint8_t *d = *image + 3; // start on the alpha component
222 register int n = ( len + 7 ) / 8;
226 case 0: do { *d = *s++; d += 4;
227 case 7: *d = *s++; d += 4;
228 case 6: *d = *s++; d += 4;
229 case 5: *d = *s++; d += 4;
230 case 4: *d = *s++; d += 4;
231 case 3: *d = *s++; d += 4;
232 case 2: *d = *s++; d += 4;
233 case 1: *d = *s++; d += 4;
243 /** Filter processing.
246 static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
248 frame->convert_image = convert_image;
252 /** Constructor for the filter.
255 mlt_filter filter_avcolour_space_init( void *arg )
258 #if (LIBSWSCALE_VERSION_INT >= ((0<<16)+(7<<8)+2))
259 // Test to see if swscale accepts the arg as resolution
262 int width = (int) arg;
263 struct SwsContext *context = sws_getContext( width, width, PIX_FMT_RGB32, 64, 64, PIX_FMT_RGB32, SWS_BILINEAR, NULL, NULL, NULL);
265 sws_freeContext( context );
273 mlt_filter this = mlt_filter_new( );
275 this->process = filter_process;