mlt_properties_set_double( properties, "fps", 25.0 );
mlt_properties_set_int( properties, "width", 720 );
mlt_properties_set_int( properties, "height", 576 );
+ mlt_properties_set_int( properties, "progressive", 0 );
}
else
{
mlt_properties_set_double( properties, "fps", 30000.0 / 1001.0 );
mlt_properties_set_int( properties, "width", 720 );
mlt_properties_set_int( properties, "height", 480 );
+ mlt_properties_set_int( properties, "progressive", 0 );
}
+ mlt_properties_set_double( properties, "aspect_ratio", 4.0 / 3.0 );
// Default rescaler for all consumers
mlt_properties_set( properties, "rescale", "bilinear" );
if ( test_card != NULL )
{
// Create a test card producer
+ // TODO: do we want to use fezzik here?
mlt_producer producer = mlt_factory_producer( "fezzik", test_card );
// Do we have a producer
mlt_properties_set( frame_properties, "rescale.interp", mlt_properties_get( properties, "rescale" ) );
// TODO: Aspect ratio and other jiggery pokery
+ mlt_properties_set_double( frame_properties, "consumer_aspect_ratio", mlt_properties_get_double( properties, "aspect_ratio" ) );
+
}
// Return the frame
*buffer = NULL;
break;
case mlt_image_rgb24:
+ // IRRIGATE ME
size *= 3;
+ size += *width * 3;
*buffer = malloc( size );
if ( *buffer )
memset( *buffer, 255, size );
break;
case mlt_image_rgb24a:
+ // IRRIGATE ME
size *= 4;
+ size += *width * 4;
*buffer = malloc( size );
if ( *buffer )
memset( *buffer, 255, size );
break;
case mlt_image_yuv422:
+ // IRRIGATE ME
size *= 2;
+ size += *width * 2;
*buffer = malloc( size );
p = *buffer;
q = p + size;
if ( iwidth != owidth || iheight != oheight )
{
// Create the output image
- uint8_t *output = malloc( owidth * oheight * 2 );
+ // IRRIGATE ME
+ uint8_t *output = malloc( owidth * ( oheight + 1 ) * 2 );
// Call the generic resize
mlt_resize_yuv422( output, owidth, oheight, input, iwidth, iheight );
// Now update the frame
- mlt_properties_set_data( properties, "image", output, owidth * oheight * 2, free, NULL );
+ mlt_properties_set_data( properties, "image", output, owidth * ( oheight + 1 ) * 2, free, NULL );
mlt_properties_set_int( properties, "width", owidth );
mlt_properties_set_int( properties, "height", oheight );
- mlt_frame_set_aspect_ratio( this, 4.0/3.0/*( float )owidth / oheight*/ );
// Return the output
return output;
}
-
// No change, return input
return input;
}
if ( iwidth != owidth || iheight != oheight )
{
// Create the output image
- uint8_t *output = malloc( owidth * oheight * 2 );
+ // IRRIGATE ME
+ uint8_t *output = malloc( owidth * ( oheight + 1 ) * 2 );
// Calculate strides
int istride = iwidth * 2;
char *eof = mlt_properties_get( mlt_producer_properties( this ), "eof" );
// A properly instatiated producer will have a get_frame method...
-//fprintf( stderr, "PRODUCER get_frame %p eof %s pos %lld out %lld\n",
-//this->get_frame, eof, mlt_producer_position( this ), mlt_producer_get_out( this ) );
if ( this->get_frame == NULL || ( !strcmp( eof, "continue" ) && mlt_producer_position( this ) > mlt_producer_get_out( this ) ) )
{
// Generate a test frame
pthread_mutex_lock( &avformat_mutex );
// Now attempt to open the file
- error = av_open_input_file( &context, file, NULL, 0, NULL ) < 0;
+ error = av_open_input_file( &context, file, NULL, 0, NULL );
+// fprintf( stderr, "AVFORMAT: open %d %s\n", error, file );
+ error = error < 0;
// If successful, then try to get additional info
if ( error == 0 )
if ( output == NULL )
{
int size = avpicture_get_size( PIX_FMT_YUV422, *width, *height );
+ // IRRIGATE ME
+ size += *width * 2;
uint8_t *buf = malloc( size );
output = malloc( sizeof( AVPicture ) );
avpicture_fill( output, buf, PIX_FMT_YUV422, *width, *height );
uint8_t *image = mlt_properties_get_data( properties, "current_image", &size );
// Duplicate it
+ // IRRIGATE ME
*buffer = malloc( size );
memcpy( *buffer, image, size );
if ( image == NULL || size != *width * *height * 2 )
{
- size = *width * *height * 2;
+ size = *width * ( *height + 1 ) * 2;
+ // IRRIGATE ME
image = malloc( size );
mlt_properties_set_data( properties, "current_image", image, size, free, NULL );
}
+ // IRRIGATE ME
*buffer = malloc( size );
img_convert( output, PIX_FMT_YUV422, (AVPicture *)&frame, codec_context->pix_fmt, *width, *height );
memcpy( image, output->data[ 0 ], size );
double aspect_ratio = 0;
// Set aspect ratio
+ fprintf( stderr, "AVFORMAT: sample aspect %d\n", codec_context->sample_aspect_ratio.num );
if ( codec_context->sample_aspect_ratio.num == 0)
aspect_ratio = 0;
else
static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
{
+ mlt_properties properties = mlt_frame_properties( this );
int owidth = *width;
int oheight = *height;
- mlt_frame_get_image( this, image, format, &owidth, &oheight, 0 );
+
+ mlt_frame_get_image( this, image, format, &owidth, &oheight, writable );
+
if ( *width == 0 )
*width = 720;
if ( *height == 0 )
*height = 576;
- if ( !strcmp( mlt_properties_get( mlt_frame_properties( this ), "resize.scale" ), "affine" ) )
+
+ // Correct field order if needed
+ if ( mlt_properties_get_int( properties, "top_field_first" ) == 1 )
+ {
+ // Get the input image, width and height
+ int size;
+ uint8_t *image = mlt_properties_get_data( properties, "image", &size );
+
+ // Keep the original image around to be destroyed on frame close
+ mlt_properties_rename( properties, "image", "original_image" );
+
+ // Offset the image pointer by one line
+ image += owidth * 2;
+ size -= owidth * 2;
+
+ // Set the new image pointer with no destructor
+ mlt_properties_set_data( properties, "image", image, size, NULL, NULL );
+
+ // Set the normalised field order
+ mlt_properties_set_int( properties, "top_field_first", 0 );
+ }
+
+ if ( !strcmp( mlt_properties_get( properties, "resize.scale" ), "affine" ) )
*image = mlt_frame_rescale_yuv422( this, *width, *height );
- else
+ else if ( strcmp( mlt_properties_get( properties, "resize.scale" ), "none" ) != 0 )
*image = mlt_frame_resize_yuv422( this, *width, *height );
+ else
+ {
+ *width = owidth;
+ *height = oheight;
+ }
return 0;
}
*/
#include "producer_ppm.h"
+
#include <framework/mlt_frame.h>
+
#include <stdlib.h>
#include <string.h>
// Convert to requested format
if ( *format == mlt_image_yuv422 )
{
- uint8_t *image = malloc( *width * *height * 2 );
+ // IRRIGATE ME
+ uint8_t *image = malloc( *width * ( *height + 1 ) * 2 );
mlt_convert_rgb24_to_yuv422( rgb, *width, *height, *width * 3, image );
- mlt_properties_set_data( properties, "image", image, *width * *height * 2, free, NULL );
+ mlt_properties_set_data( properties, "image", image, *width * ( *height + 1 ) * 2, free, NULL );
*buffer = image;
}
else if ( *format == mlt_image_rgb24 )
{
// Allocate an image
- uint8_t *image = malloc( width * height * 3 );
+ // IRRIGATE ME
+ uint8_t *image = malloc( width * ( height + 1 ) * 3 );
// Read it
fread( image, width * height * 3, 1, video );
// Pass the data on the frame properties
- mlt_properties_set_data( properties, "image", image, width * height * 3, free, NULL );
+ mlt_properties_set_data( properties, "image", image, width * ( height + 1 ) * 3, free, NULL );
mlt_properties_set_int( properties, "width", width );
mlt_properties_set_int( properties, "height", height );
mlt_properties_set_int( properties, "has_image", 1 );
+ mlt_properties_set_int( properties, "progressive", 1 );
+ mlt_properties_set_double( properties, "aspect_ratio", ( double )width / height );
// Push the image callback
mlt_frame_push_get_image( *frame, producer_get_image );
#define _PRODUCER_PPM_H_
#include <framework/mlt_producer.h>
-#include <stdio.h>
extern mlt_producer producer_ppm_init( void *command );
int x = ( int )( ( float )width_dest * geometry.x / 100 );
int y = ( int )( ( float )height_dest * geometry.y / 100 );
float weight = geometry.mix / 100;
+
+ // Compute the dimensioning rectangle
int width_src = ( int )( ( float )width_dest * geometry.w / 100 );
int height_src = ( int )( ( float )height_dest * geometry.h / 100 );
if ( mlt_properties_get( properties, "distort" ) == NULL &&
mlt_properties_get( mlt_frame_properties( that ), "real_width" ) != NULL )
{
- int width_b = mlt_properties_get_int( mlt_frame_properties( that ), "real_width" );
- int height_b = mlt_properties_get_int( mlt_frame_properties( that ), "real_height" );
+ int width_b = mlt_properties_get_double( b_props, "real_width" );
+ int height_b = mlt_properties_get_double( b_props, "real_height" );
+
+ // See if we need to normalise pixel aspect ratio
+ // We can use consumer_aspect_ratio because the a_frame will take on this aspect
+ double aspect = mlt_properties_get_double( b_props, "consumer_aspect_ratio" );
+ if ( aspect != 0 )
+ {
+ // Derive the consumer pixel aspect
+ double oaspect = aspect / ( double )width_dest * height_dest;
+
+ // Get the b frame pixel aspect - usually 1
+ double iaspect = mlt_properties_get_double( b_props, "aspect_ratio" ) / width_b * height_b;
+
+ // Normalise pixel aspect
+ if ( iaspect != 0 && iaspect != oaspect )
+ width_b = iaspect / oaspect * ( double )width_b + 0.5;
+
+ // Tell rescale not to normalise display aspect
+ mlt_frame_set_aspect_ratio( that, aspect );
+ }
+ // Constrain the overlay to the dimensioning rectangle
if ( width_b < width_src )
width_src = width_b;
if ( height_b < height_src )
height_src = height_b;
- mlt_properties_set( mlt_frame_properties( that ), "rescale.interp", "none" );
+
+ // Adjust overall scale for consumer
+ double consumer_scale = mlt_properties_get_double( b_props, "consumer_scale" );
+ if ( consumer_scale > 0 )
+ {
+ width_src = consumer_scale * width_src + 0.5;
+ height_src = consumer_scale * height_src + 0.5;
+ }
}
- else if ( mlt_properties_get( mlt_frame_properties( that ), "real_width" ) != NULL )
+ else if ( mlt_properties_get( b_props, "real_width" ) != NULL )
{
- mlt_properties_set( mlt_frame_properties( that ), "rescale.interp", "none" );
+ // Tell rescale not to normalise display aspect
+ mlt_properties_set_double( b_props, "consumer_aspect_ratio", 0 );
}
x -= x % 2;
+ // optimization points - no work to do
if ( width_src <= 0 || height_src <= 0 )
return ret;
- // optimization point - no work to do
if ( ( x < 0 && -x >= width_src ) || ( y < 0 && -y >= height_src ) )
return ret;
// Do the calculation
geometry_calculate( &result, &start, &end, position );
+ // Since we are the consumer of the b_frame, we must pass along these
+ // consumer properties from the a_frame
+ mlt_properties_set_double( b_props, "consumer_aspect_ratio",
+ mlt_properties_get_double( mlt_frame_properties( a_frame ), "consumer_aspect_ratio" ) );
+ mlt_properties_set_double( b_props, "consumer_scale",
+ mlt_properties_get_double( mlt_frame_properties( a_frame ), "consumer_scale" ) );
+
// Composite the b_frame on the a_frame
composite_yuv( *image, *format, *width, *height, b_frame, result );
}
int top_field_first = mlt_properties_get_int( b_props, "top_field_first" );
int reverse = mlt_properties_get_int( b_props, "luma.reverse" );
+ // Since we are the consumer of the b_frame, we must pass along this
+ // consumer property from the a_frame
+ mlt_properties_set_double( b_props, "consumer_aspect_ratio",
+ mlt_properties_get_double( mlt_frame_properties( this ), "consumer_aspect_ratio" ) );
+ mlt_properties_set_double( b_props, "consumer_scale",
+ mlt_properties_get_double( mlt_frame_properties( this ), "consumer_scale" ) );
+
// Honour the reverse here
mix = reverse ? 1 - mix : mix;
// determine if this is one or two bytes per pixel
bpp = maxval > 255 ? 2 : 1;
- // allocate temporary storage for the raw data
+
+ // allocate temporary storage for the raw data
+ // IRRIGATE ME
data = malloc( *width * *height * bpp );
if ( data == NULL )
break;
break;
// allocate the luma bitmap
+ // IRRIGATE ME
*map = p = (float*) malloc( *width * *height * sizeof( float ) );
if ( *map == NULL )
break;
static int producer_collect_info( producer_libdv this )
{
int valid = 0;
+ // IRRIGATE ME
uint8_t *dv_data = malloc( frame_size_625_50 );
if ( dv_data != NULL )
if ( *format == mlt_image_yuv422 )
{
// Allocate an image
- uint8_t *image = malloc( *width * *height * 2 );
+ // IRRIGATE ME
+ uint8_t *image = malloc( *width * ( *height + 1 ) * 2 );
// Pass to properties for clean up
- mlt_properties_set_data( properties, "image", image, *width * *height * 2, free, NULL );
+ mlt_properties_set_data( properties, "image", image, *width * ( *height + 1 ) * 2, free, NULL );
// Decode the image
pitches[ 0 ] = *width * 2;
else if ( *format == mlt_image_rgb24 )
{
// Allocate an image
- uint8_t *image = malloc( *width * *height * 3 );
+ // IRRIGATE ME
+ uint8_t *image = malloc( *width * ( *height + 1 ) * 3 );
// Pass to properties for clean up
- mlt_properties_set_data( properties, "image", image, *width * *height * 3, free, NULL );
+ mlt_properties_set_data( properties, "image", image, *width * ( *height + 1 ) * 3, free, NULL );
// Decode the frame
pitches[ 0 ] = 720 * 3;
if ( video != NULL && read_ffmpeg_header( this, &width, &height ) == 2 )
{
// Allocate an image
- uint8_t *image = malloc( width * height * 2 );
+ // IRRIGATE ME
+ uint8_t *image = malloc( width * ( height + 1 ) * 2 );
// Read it
while( skip -- )
mlt_convert_yuv420p_to_yuv422( this->buffer, width, height, width, image );
// Pass the data on the frame properties
- mlt_properties_set_data( properties, "image", image, width * height * 2, free, NULL );
+ mlt_properties_set_data( properties, "image", image, width * ( height + 1 ) * 2, free, NULL );
mlt_properties_set_int( properties, "width", width );
mlt_properties_set_int( properties, "height", height );
mlt_properties_set_int( properties, "has_image", 1 );
#include <stdlib.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
+
/** Do it :-).
*/
else if ( strcmp( interps, "hyper" ) == 0 )
interp = PIXOPS_INTERP_HYPER;
- mlt_frame_get_image( this, &input, format, &iwidth, &iheight, 0 );
+ mlt_frame_get_image( this, &input, format, &iwidth, &iheight, writable );
- if ( o_aspect_ratio != 0 && o_aspect_ratio != i_aspect_ratio && mlt_properties_get_int( properties, "distort" ) == 0 )
+ if ( o_aspect_ratio != 0 && o_aspect_ratio != i_aspect_ratio && mlt_properties_get( properties, "distort" ) == NULL )
{
- // Determine maximum size within the aspect ratio:
+ int temp_width = i_aspect_ratio / o_aspect_ratio * owidth + 0.5;
- if ( ( owidth * i_aspect_ratio * o_aspect_ratio ) > owidth )
- oheight *= o_aspect_ratio / i_aspect_ratio;
+ // Determine maximum size within the aspect ratio:
+ if ( temp_width > owidth )
+ if ( i_aspect_ratio > o_aspect_ratio )
+ oheight = o_aspect_ratio / i_aspect_ratio * oheight + 0.5;
+ else
+ oheight = i_aspect_ratio / o_aspect_ratio * oheight + 0.5;
else
- owidth *= i_aspect_ratio * o_aspect_ratio;
- //fprintf( stderr, "rescale: from %dx%d (aspect %f) to %dx%d (aspect %f)\n", iwidth, iheight, i_aspect_ratio, owidth, oheight, o_aspect_ratio );
+ owidth = temp_width;
+
+ // Tell frame we have conformed the aspect to the consumer
+ mlt_frame_set_aspect_ratio( this, o_aspect_ratio );
}
-
- // If width and height are correct, don't do anything
- if ( strcmp( interps, "none" ) && input != NULL && ( iwidth != owidth || iheight != oheight ) )
+ //fprintf( stderr, "rescale: from %dx%d (aspect %f) to %dx%d (aspect %f)\n", iwidth, iheight, i_aspect_ratio, owidth, oheight, o_aspect_ratio );
+
+ if ( input != NULL )
{
- if ( *format == mlt_image_yuv422 )
+ // If width and height are correct, don't do anything
+ if ( *format == mlt_image_yuv422 && strcmp( interps, "none" ) && ( iwidth != owidth || iheight != oheight ) )
{
// Create the output image
- uint8_t *output = malloc( owidth * oheight * 2 );
+ // IRRIGATE ME
+ uint8_t *output = malloc( owidth * ( oheight + 1 ) * 2 );
// Calculate strides
int istride = iwidth * 2;
yuv422_scale_simple( output, owidth, oheight, ostride, input, iwidth, iheight, istride, interp );
// Now update the frame
- mlt_properties_set_data( properties, "image", output, owidth * oheight * 2, free, NULL );
+ mlt_properties_set_data( properties, "image", output, owidth * ( oheight + 1 ) * 2, free, NULL );
mlt_properties_set_int( properties, "width", owidth );
mlt_properties_set_int( properties, "height", oheight );
else if ( *format == mlt_image_rgb24 || *format == mlt_image_rgb24a )
{
int bpp = (*format == mlt_image_rgb24a ? 4 : 3 );
- GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data( input, GDK_COLORSPACE_RGB,
- (*format == mlt_image_rgb24a), 24, iwidth, iheight,
- iwidth * bpp, NULL, NULL );
- GdkPixbuf *scaled = gdk_pixbuf_scale_simple( pixbuf, owidth, oheight, interp );
-
- // Create the output image
- uint8_t *output = malloc( owidth * oheight * bpp );
-
- int i;
- for ( i = 0; i < oheight; i++ )
- memcpy( output + i * owidth * bpp,
- gdk_pixbuf_get_pixels( scaled ) + i * gdk_pixbuf_get_rowstride( scaled ),
- gdk_pixbuf_get_width( scaled ) * bpp );
-
- g_object_unref( pixbuf );
- g_object_unref( scaled );
+ // Create the yuv image
+ // IRRIGATE ME
+ uint8_t *output = malloc( owidth * ( oheight + 1 ) * 2 );
+
+ if ( strcmp( interps, "none" ) && ( iwidth != owidth || iheight != oheight ) )
+ {
+ GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data( input, GDK_COLORSPACE_RGB,
+ ( *format == mlt_image_rgb24a ), 8, iwidth, iheight,
+ iwidth * bpp, NULL, NULL );
+
+ GdkPixbuf *scaled = gdk_pixbuf_scale_simple( pixbuf, owidth, oheight, interp );
+ g_object_unref( pixbuf );
+
+ // Extract YUV422 and alpha
+ if ( bpp == 4 )
+ {
+ // Allocate the alpha mask
+ // IRRIGATE ME
+ uint8_t *alpha = malloc( owidth * ( oheight + 1 ) );
+
+ // Convert the image and extract alpha
+ mlt_convert_rgb24a_to_yuv422( gdk_pixbuf_get_pixels( scaled ),
+ owidth, oheight,
+ gdk_pixbuf_get_rowstride( scaled ),
+ output, alpha );
+
+ mlt_properties_set_data( properties, "alpha", alpha, owidth * ( oheight + 1 ), free, NULL );
+ }
+ else
+ {
+ // No alpha to extract
+ mlt_convert_rgb24_to_yuv422( gdk_pixbuf_get_pixels( scaled ),
+ owidth, oheight,
+ gdk_pixbuf_get_rowstride( scaled ),
+ output );
+ }
+ g_object_unref( scaled );
+ }
+ else
+ {
+ // Extract YUV422 and alpha
+ if ( bpp == 4 )
+ {
+ // Allocate the alpha mask
+ // IRRIGATE ME
+ uint8_t *alpha = malloc( owidth * ( oheight + 1 ) );
+
+ // Convert the image and extract alpha
+ mlt_convert_rgb24a_to_yuv422( input,
+ owidth, oheight,
+ owidth * 4,
+ output, alpha );
+
+ mlt_properties_set_data( properties, "alpha", alpha, owidth * ( oheight + 1 ), free, NULL );
+ }
+ else
+ {
+ // No alpha to extract
+ mlt_convert_rgb24_to_yuv422( input,
+ owidth, oheight,
+ owidth * 3,
+ output );
+ }
+ }
+
// Now update the frame
- mlt_properties_set_data( properties, "image", output, owidth * oheight * bpp, free, NULL );
+ mlt_properties_set_data( properties, "image", output, owidth * ( oheight + 1 ) * 2, free, NULL );
mlt_properties_set_int( properties, "width", owidth );
mlt_properties_set_int( properties, "height", oheight );
// Return the output
+ *width = owidth;
+ *height = oheight;
*image = output;
}
+ else
+ *image = input;
}
else
*image = input;
return 0;
}
+static uint8_t *producer_get_alpha_mask( mlt_frame this )
+{
+ // Obtain properties of frame
+ mlt_properties properties = mlt_frame_properties( this );
+
+ // Return the alpha mask
+ return mlt_properties_get_data( properties, "alpha", NULL );
+}
+
/** Filter processing.
*/
mlt_frame_push_get_image( frame, filter_get_image );
mlt_properties_set( mlt_frame_properties( frame ), "rescale.interp",
mlt_properties_get( mlt_filter_properties( this ), "interpolation" ) );
+
+ // Set alpha call back
+ frame->get_alpha_mask = producer_get_alpha_mask;
return frame;
}
int width;
int height;
uint8_t *image;
- uint8_t *alpha;
char *fgcolor;
char *bgcolor;
int align;
// Store the width/height of the pixbuf temporarily
this->width = gdk_pixbuf_get_width( pixbuf );
this->height = gdk_pixbuf_get_height( pixbuf );
+
+ mlt_properties_set_int( producer_props, "bpp", gdk_pixbuf_get_has_alpha( pixbuf ) ? 4 : 3 );
}
}
else if ( this->image == NULL || width != this->width || height != this->height )
{
pixbuf = mlt_properties_get_data( producer_props, "pixbuf", NULL );
+ mlt_properties_set_int( producer_props, "bpp", gdk_pixbuf_get_has_alpha( pixbuf ) ? 4 : 3 );
}
+ int bpp = mlt_properties_get_int( producer_props, "bpp" );
+
// If we have a pixbuf and a valid width
if ( pixbuf && width > 0 )
{
+ int i;
+
// Note - the original pixbuf is already safe and ready for destruction
pixbuf = gdk_pixbuf_scale_simple( pixbuf, width, height, GDK_INTERP_HYPER );
this->width = gdk_pixbuf_get_width( pixbuf );
this->height = gdk_pixbuf_get_height( pixbuf );
- // Allocate/define image and alpha
- uint8_t *image = malloc( this->width * this->height * 2 );
- uint8_t *alpha = NULL;
+ // Allocate/define image
+ // IRRIGATE ME
+ uint8_t *image = malloc( this->width * ( this->height + 1 )* bpp );
- // Extract YUV422 and alpha
- if ( gdk_pixbuf_get_has_alpha( pixbuf ) )
- {
- // Allocate the alpha mask
- alpha = malloc( this->width * this->height );
-
- // Convert the image
- mlt_convert_rgb24a_to_yuv422( gdk_pixbuf_get_pixels( pixbuf ),
- this->width, this->height,
- gdk_pixbuf_get_rowstride( pixbuf ),
- image, alpha );
- }
- else
- {
- // No alpha to extract
- mlt_convert_rgb24_to_yuv422( gdk_pixbuf_get_pixels( pixbuf ),
- this->width, this->height,
- gdk_pixbuf_get_rowstride( pixbuf ),
- image );
- }
+ for ( i = 0; i < height; i++ )
+ memcpy( image + i * width * bpp,
+ gdk_pixbuf_get_pixels( pixbuf ) + i * gdk_pixbuf_get_rowstride( pixbuf ),
+ gdk_pixbuf_get_width( pixbuf ) * bpp );
// Finished with pixbuf now
g_object_unref( pixbuf );
- // if single picture, reference the image and alpha in the producer
+ // reference the image in the producer
free( this->image );
this->image = image;
- free( this->alpha );
- this->alpha = alpha;
}
// Set width/height
mlt_properties_set_int( properties, "real_width", mlt_properties_get_int( producer_props, "real_width" ) );
mlt_properties_set_int( properties, "real_height", mlt_properties_get_int( producer_props, "real_height" ) );
- // pass the image and alpha data without destructor
- mlt_properties_set_data( properties, "image", this->image, this->width * this->height * 2, NULL, NULL );
- mlt_properties_set_data( properties, "alpha", this->alpha, this->width * this->height, NULL, NULL );
+ // pass the image data without destructor
+ mlt_properties_set_data( properties, "image", this->image, this->width * ( this->height + 1 ) * bpp, NULL, NULL );
}
static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable )
// Refresh the image
refresh_image( frame, *width, *height );
+ // Determine format
+ mlt_producer this = mlt_properties_get_data( properties, "producer_pango", NULL );
+ *format = ( mlt_properties_get_int( mlt_producer_properties( this ), "bpp" ) == 4 ) ? mlt_image_rgb24a : mlt_image_rgb24;
+
// May need to know the size of the image to clone it
int size = 0;
if ( writable )
{
// Clone our image
+ // IRRIGATE ME
uint8_t *copy = malloc( size );
memcpy( copy, image, size );
return 0;
}
-static uint8_t *producer_get_alpha_mask( mlt_frame this )
-{
- // Obtain properties of frame
- mlt_properties properties = mlt_frame_properties( this );
-
- // Return the alpha mask
- return mlt_properties_get_data( properties, "alpha", NULL );
-}
-
static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index )
{
producer_pango this = producer->child;
// Refresh the pango image
refresh_image( *frame, 0, 0 );
- // Set alpha mask call back
- ( *frame )->get_alpha_mask = producer_get_alpha_mask;
+ // Set producer-specific frame properties
+ mlt_properties_set_int( properties, "progressive", 1 );
+ mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( properties, "real_width" ) / mlt_properties_get_double( properties, "real_height" ) );
// Stack the get image callback
mlt_frame_push_get_image( *frame, producer_get_image );
{
producer_pango this = parent->child;
free( this->image );
- free( this->alpha );
free( this->fgcolor );
free( this->bgcolor );
free( this->markup );
// Obtain properties of frame
mlt_properties properties = mlt_frame_properties( frame );
- // Obtain the producer pango for this frame
+ // Obtain the producer for this frame
producer_pixbuf this = mlt_properties_get_data( properties, "producer_pixbuf", NULL );
// Obtain the producer
if ( width != this->width || height != this->height )
{
pixbuf = mlt_properties_get_data( producer_props, "pixbuf", NULL );
+ mlt_properties_set_int( producer_props, "bpp", gdk_pixbuf_get_has_alpha( pixbuf ) ? 4 : 3 );
}
}
else
{
- free( this->image );
- this->image = NULL;
- free( this->alpha );
- this->alpha = NULL;
this->image_idx = image_idx;
pixbuf = gdk_pixbuf_new_from_file( this->filenames[ image_idx ], &error );
// Store the width/height of the pixbuf temporarily
this->width = gdk_pixbuf_get_width( pixbuf );
this->height = gdk_pixbuf_get_height( pixbuf );
+
+ mlt_properties_set_int( producer_props, "bpp", gdk_pixbuf_get_has_alpha( pixbuf ) ? 4 : 3 );
}
}
+ int bpp = mlt_properties_get_int( producer_props, "bpp" );
+
// If we have a pixbuf
if ( pixbuf && width > 0 )
{
+ int i;
+ //fprintf( stderr, "SCALING PIXBUF from %dx%d to %dx%d\n", gdk_pixbuf_get_width( pixbuf ), gdk_pixbuf_get_height( pixbuf ), width, height );
+
// Note - the original pixbuf is already safe and ready for destruction
pixbuf = gdk_pixbuf_scale_simple( pixbuf, width, height, GDK_INTERP_HYPER );
-
+
// Store width and height
this->width = gdk_pixbuf_get_width( pixbuf );
this->height = gdk_pixbuf_get_height( pixbuf );
+
+ // Allocate/define image
+ // IRRIGATE ME
+ uint8_t *image = malloc( width * ( height + 1 ) * bpp );
- // Allocate/define image and alpha
- uint8_t *image = malloc( this->width * this->height * 2 );
- uint8_t *alpha = NULL;
-
- // Extract YUV422 and alpha
- if ( gdk_pixbuf_get_has_alpha( pixbuf ) )
- {
- // Allocate the alpha mask
- alpha = malloc( this->width * this->height );
-
- // Convert the image
- mlt_convert_rgb24a_to_yuv422( gdk_pixbuf_get_pixels( pixbuf ),
- this->width, this->height,
- gdk_pixbuf_get_rowstride( pixbuf ),
- image, alpha );
- }
- else
- {
- // No alpha to extract
- mlt_convert_rgb24_to_yuv422( gdk_pixbuf_get_pixels( pixbuf ),
- this->width, this->height,
- gdk_pixbuf_get_rowstride( pixbuf ),
- image );
- }
+ for ( i = 0; i < height; i++ )
+ memcpy( image + i * width * bpp,
+ gdk_pixbuf_get_pixels( pixbuf ) + i * gdk_pixbuf_get_rowstride( pixbuf ),
+ gdk_pixbuf_get_width( pixbuf ) * bpp );
// Finished with pixbuf now
g_object_unref( pixbuf );
- // Pass alpha and image on properties with or without destructor
+ // Pass image on properties with or without destructor
+ free( this->image );
this->image = image;
- this->alpha = alpha;
}
// Set width/height of frame
mlt_properties_set_int( properties, "real_width", mlt_properties_get_int( producer_props, "real_width" ) );
mlt_properties_set_int( properties, "real_height", mlt_properties_get_int( producer_props, "real_height" ) );
- // pass the image and alpha data without destructor
- mlt_properties_set_data( properties, "image", this->image, this->width * this->height * 2, NULL, NULL );
- mlt_properties_set_data( properties, "alpha", this->alpha, this->width * this->height, NULL, NULL );
+ // pass the image data without destructor
+ mlt_properties_set_data( properties, "image", this->image, this->width * ( this->height + 1 ) * bpp, NULL, NULL );
}
static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable )
// Refresh the image
refresh_image( frame, *width, *height );
+ // Determine format
+ mlt_producer this = mlt_properties_get_data( properties, "producer_pixbuf", NULL );
+ *format = ( mlt_properties_get_int( mlt_producer_properties( this ), "bpp" ) == 4 ) ? mlt_image_rgb24a : mlt_image_rgb24;
+
// May need to know the size of the image to clone it
int size = 0;
// The fault is not in the design of mlt, but in the implementation of pixbuf...
//if ( writable )
{
- size = *width * *height * 2;
-
// Clone our image
+ // IRRIGATE ME
uint8_t *copy = malloc( size );
memcpy( copy, image, size );
return 0;
}
-static uint8_t *producer_get_alpha_mask( mlt_frame this )
-{
- // Obtain properties of frame
- mlt_properties properties = mlt_frame_properties( this );
-
- // Return the alpha mask
- return mlt_properties_get_data( properties, "alpha", NULL );
-}
-
static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index )
{
// Get the real structure for this producer
// Set the producer on the frame properties
mlt_properties_set_data( properties, "producer_pixbuf", this, 0, NULL, NULL );
- // Refresh the pango image
+ // Refresh the image
refresh_image( *frame, 0, 0 );
- // Set alpha call back
- ( *frame )->get_alpha_mask = producer_get_alpha_mask;
+ // Set producer-specific frame properties
+ mlt_properties_set_int( properties, "progressive", 1 );
+ mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( properties, "real_width" ) / mlt_properties_get_double( properties, "real_height" ) );
// Push the get_image method
mlt_frame_push_get_image( *frame, producer_get_image );
{
producer_pixbuf this = parent->child;
free( this->image );
- free( this->alpha );
parent->close = NULL;
mlt_producer_close( parent );
free( this );
// Default scaler (for now we'll use nearest)
mlt_properties_set( this->properties, "rescale", "nearest" );
+ // Get aspect ratio
+ this->aspect_ratio = mlt_properties_get_double( this->properties, "aspect_ratio" );
+
// process actual param
if ( arg == NULL || sscanf( arg, "%dx%d", &this->width, &this->height ) != 2 )
{
this->height = mlt_properties_get_int( this->properties, "height" );
}
- // Default window size and aspect ratio
- this->aspect_ratio = 4.0 / 3.0;
+ // Default window size
this->window_width = (int)( (float)this->height * this->aspect_ratio ) + 1;
this->window_height = this->height;
-
+
// Set the sdl flags
this->sdl_flags = SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_HWACCEL | SDL_RESIZABLE;
mlt_frame_close( frame );
if ( this->count )
+ {
+ // Tell the producers about our scale relative to the normalisation
+ mlt_properties_set_double( mlt_frame_properties( this->queue[ this->count - 1 ] ), "consumer_scale",
+ ( double )height / mlt_properties_get_double( properties, "height" ) );
mlt_frame_get_image( this->queue[ this->count - 1 ], &image, &vfmt, &width, &height, 0 );
+ }
return 0;
}
// Ensure that we have a frame
if ( frame != NULL )
{
+ // SDL adapts display aspect, but set this so pixel aspect can be normalised
+ mlt_properties_set_double( mlt_frame_properties( frame ), "consumer_aspect_ratio",
+ mlt_frame_get_aspect_ratio( frame ) );
+
init_audio = consumer_play_audio( this, frame, init_audio );
consumer_play_video( this, frame );
}
else
strncpy( id, mlt_properties_get( properties, "id" ), ID_SIZE );
- xmlNewProp( child, "in", mlt_properties_get( properties, "in" ) );
- xmlNewProp( child, "out", mlt_properties_get( properties, "out" ) );
-
// Add producer to the map
snprintf( key, 10, "%p", service );
mlt_properties_set( context->producer_map, key, id );
xmlNode *entry = xmlNewChild( child, NULL, "entry", NULL );
snprintf( key, 10, "%p", MLT_SERVICE( info.producer ) );
xmlNewProp( entry, "producer", mlt_properties_get( context->producer_map, key ) );
+ xmlNewProp( entry, "in", mlt_properties_get( mlt_producer_properties( info.producer ), "in" ) );
+ xmlNewProp( entry, "out", mlt_properties_get( mlt_producer_properties( info.producer ), "out" ) );
}
}
}