#include <framework/mlt_filter.h>
#include <framework/mlt_frame.h>
#include <framework/mlt_factory.h>
-#include <framework/mlt_producer.h>
// ffmpeg Header files
-#include <avformat.h>
-#include <swscale.h>
+#include <libavformat/avformat.h>
+#include <libswscale/swscale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#if LIBAVUTIL_VERSION_INT < (50<<16)
-#define PIX_FMT_RGB32 PIX_FMT_RGBA32
-#define PIX_FMT_YUYV422 PIX_FMT_YUV422
-#endif
-
static inline int convert_mlt_to_av_cs( mlt_image_format format )
{
int value = 0;
break;
case mlt_image_rgb24a:
case mlt_image_opengl:
- value = PIX_FMT_RGB32;
+ value = PIX_FMT_RGBA;
break;
case mlt_image_yuv422:
value = PIX_FMT_YUYV422;
case mlt_image_yuv420p:
value = PIX_FMT_YUV420P;
break;
- case mlt_image_none:
+ default:
fprintf( stderr, "Invalid format...\n" );
break;
}
return value;
}
-static int filter_scale( mlt_frame this, uint8_t **image, mlt_image_format *format, int iwidth, int iheight, int owidth, int oheight )
+static int filter_scale( mlt_frame frame, uint8_t **image, mlt_image_format *format, int iwidth, int iheight, int owidth, int oheight )
{
// Get the properties
- mlt_properties properties = MLT_FRAME_PROPERTIES( this );
+ mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
// Get the requested interpolation method
char *interps = mlt_properties_get( properties, "rescale.interp" );
// Determine the bytes per pixel
int bpp;
+ mlt_image_format_size( *format, 0, 0, &bpp );
+
+ // Set swscale flags to get good quality
switch ( *format )
{
case mlt_image_yuv422:
- bpp = 2;
interp |= SWS_FULL_CHR_H_INP;
break;
case mlt_image_rgb24:
- bpp = 3;
interp |= SWS_FULL_CHR_H_INT;
break;
case mlt_image_rgb24a:
case mlt_image_opengl:
- bpp = 4;
interp |= SWS_FULL_CHR_H_INT;
break;
default:
avpicture_fill( &input, *image, avformat, iwidth, iheight );
avpicture_fill( &output, outbuf, avformat, owidth, oheight );
- // Get the cached swscale context
- mlt_producer producer = mlt_frame_get_original_producer( this );
- mlt_properties prod_props = MLT_PRODUCER_PROPERTIES( mlt_producer_cut_parent( producer ) );
- struct SwsContext *context = mlt_properties_get_data( prod_props, "swscale.context", NULL );
-
// Create the context and output image
owidth = owidth > 5120 ? 5120 : owidth;
- struct SwsContext *new_context = sws_getCachedContext( context, iwidth, iheight, avformat, owidth, oheight, avformat, interp, NULL, NULL, NULL);
- if ( !new_context )
+ struct SwsContext *context = sws_getContext( iwidth, iheight, avformat, owidth, oheight, avformat, interp, NULL, NULL, NULL);
+ if ( !context )
{
owidth = owidth > 2048 ? 2048 : owidth;
- new_context = sws_getCachedContext( context, iwidth, iheight, avformat, owidth, oheight, avformat, interp, NULL, NULL, NULL);
+ context = sws_getContext( iwidth, iheight, avformat, owidth, oheight, avformat, interp, NULL, NULL, NULL);
}
- if ( new_context != context )
- mlt_properties_set_data( properties, "swscale.context", new_context, 0, NULL, NULL );
- if ( new_context )
+ if ( context )
{
// Perform the scaling
- sws_scale( new_context, input.data, input.linesize, 0, iheight, output.data, output.linesize);
+ sws_scale( context, (const uint8_t* const*) input.data, input.linesize, 0, iheight, output.data, output.linesize);
+ sws_freeContext( context );
// Now update the frame
- mlt_properties_set_data( properties, "image", output.data[0], owidth * ( oheight + 1 ) * bpp, ( mlt_destructor )mlt_pool_release, NULL );
- mlt_properties_set_int( properties, "width", owidth );
- mlt_properties_set_int( properties, "height", oheight );
+ mlt_frame_set_image( frame, output.data[0], owidth * ( oheight + 1 ) * bpp, mlt_pool_release );
// Return the output
*image = output.data[0];
if ( alpha_size > 0 && alpha_size != ( owidth * oheight ) )
{
// Create the context and output image
- uint8_t *alpha = mlt_frame_get_alpha_mask( this );
+ uint8_t *alpha = mlt_frame_get_alpha_mask( frame );
if ( alpha )
{
- context = mlt_properties_get_data( prod_props, "swscale.context2", NULL );
- new_context = sws_getCachedContext( context, iwidth, iheight, avformat, owidth, oheight, avformat, interp, NULL, NULL, NULL);
- if ( new_context != context )
- mlt_properties_set_data( properties, "swscale.context2", new_context, 0, NULL, NULL );
-
avformat = PIX_FMT_GRAY8;
+ struct SwsContext *context = sws_getContext( iwidth, iheight, avformat, owidth, oheight, avformat, interp, NULL, NULL, NULL);
avpicture_fill( &input, alpha, avformat, iwidth, iheight );
outbuf = mlt_pool_alloc( owidth * oheight );
avpicture_fill( &output, outbuf, avformat, owidth, oheight );
// Perform the scaling
- sws_scale( new_context, input.data, input.linesize, 0, iheight, output.data, output.linesize);
+ sws_scale( context, (const uint8_t* const*) input.data, input.linesize, 0, iheight, output.data, output.linesize);
+ sws_freeContext( context );
// Set it back on the frame
- mlt_properties_set_data( MLT_FRAME_PROPERTIES( this ), "alpha", output.data[0], owidth * oheight, mlt_pool_release, NULL );
+ mlt_frame_set_alpha( frame, output.data[0], owidth * oheight, mlt_pool_release );
}
}
}
}
-static void filter_close( mlt_filter filter )
-{
- struct SwsContext *context = mlt_properties_get_data( MLT_FILTER_PROPERTIES(filter), "swscale.context", NULL );
- sws_freeContext( context );
- context = mlt_properties_get_data( MLT_FILTER_PROPERTIES(filter), "swscale.context2", NULL );
- sws_freeContext( context );
-}
-
/** Constructor for the filter.
*/
// Test to see if swscale accepts the arg as resolution
if ( arg )
{
- int width = (int) arg;
- struct SwsContext *context = sws_getContext( width, width, PIX_FMT_RGB32, 64, 64, PIX_FMT_RGB32, SWS_BILINEAR, NULL, NULL, NULL);
- if ( context )
- sws_freeContext( context );
- else
- return NULL;
- }
+ int *width = (int*) arg;
+ if ( *width > 0 )
+ {
+ struct SwsContext *context = sws_getContext( *width, *width, PIX_FMT_RGB32, 64, 64, PIX_FMT_RGB32, SWS_BILINEAR, NULL, NULL, NULL);
+ if ( context )
+ sws_freeContext( context );
+ else
+ return NULL;
+ } }
// Create a new scaler
- mlt_filter this = mlt_factory_filter( profile, "rescale", NULL );
+ mlt_filter filter = mlt_factory_filter( profile, "rescale", NULL );
// If successful, then initialise it
- if ( this != NULL )
+ if ( filter != NULL )
{
// Get the properties
- mlt_properties properties = MLT_FILTER_PROPERTIES( this );
+ mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
// Set the inerpolation
mlt_properties_set( properties, "interpolation", "bilinear" );
// Set the method
mlt_properties_set_data( properties, "method", filter_scale, 0, NULL, NULL );
-
- this->close = filter_close;
}
- return this;
+ return filter;
}