if ( mlt_properties_get( properties, "meta.volume" ) )
{
double value = mlt_properties_get_double( properties, "meta.volume" );
+
if ( value == 0.0 )
{
memset( *buffer, 0, *samples * *channels * 2 );
- mlt_properties_set_double( properties, "meta.volume", 1.0 );
}
else if ( value != 1.0 )
{
*p = *p * value;
p ++;
}
- mlt_properties_set_double( properties, "meta.volume", 1.0 );
}
+
+ mlt_properties_set( properties, "meta.volume", NULL );
}
return 0;
if ( input != NULL && ( iwidth != owidth || iheight != oheight ) && ( owidth > 6 && oheight > 6 ) )
{
- uint8_t *in_line = input;
uint8_t *out_line;
+ int offset_x = ( owidth - iwidth ) / 2;
+ int offset_y = ( oheight - iheight ) / 2;
+ int iused = iwidth;
output = mlt_pool_alloc( owidth * oheight );
memset( output, 0, owidth * oheight );
- out_line = output + ( ( oheight - iheight ) / 2 ) * owidth;
- out_line += 2 * ( int )( ( owidth - iwidth ) / 2 );
+ offset_x -= offset_x % 2;
+
+ out_line = output + offset_y * owidth;
+ out_line += offset_x;
// Loop for the entirety of our output height.
while ( iheight -- )
{
// We're in the input range for this row.
- memcpy( out_line, input, iwidth );
+ memcpy( out_line, input, iused );
// Move to next input line
- in_line += iwidth;
+ input += iwidth;
// Move to next output line
out_line += owidth;
// Calculate strides
int istride = iwidth * 2;
int ostride = owidth * 2;
+ int offset_x = ( owidth - iwidth );
+ int offset_y = ( oheight - iheight ) / 2;
+ uint8_t *in_line = input;
+ uint8_t *out_line;
+ int size = owidth * oheight;
+ uint8_t *p = output;
// Optimisation point
if ( output == NULL || input == NULL || ( owidth <= 6 || oheight <= 6 || iwidth <= 6 || oheight <= 6 ) )
return;
}
- uint8_t *in_line = input;
- uint8_t *out_line;
-
- int size = owidth * oheight;
- uint8_t *p = output;
-
while( size -- )
{
*p ++ = 16;
*p ++ = 128;
}
- out_line = output + ( ( oheight - iheight ) / 2 ) * ostride;
- out_line += 4 * ( int )( ( owidth - iwidth ) / 4 );
-
+ offset_x -= offset_x % 4;
+
+ out_line = output + offset_y * ostride;
+ out_line += offset_x;
+
// Loop for the entirety of our output height.
while ( iheight -- )
{
// We're in the input range for this row.
- memcpy( out_line, in_line, istride );
+ memcpy( out_line, in_line, iwidth * 2 );
// Move to next input line
in_line += istride;
alpha = mlt_resize_alpha( alpha, owidth, oheight, iwidth, iheight );
if ( alpha != NULL )
{
- mlt_properties_set_data( properties, "alpha", alpha, owidth * ( oheight + 1 ), ( mlt_destructor )mlt_pool_release, NULL );
+ mlt_properties_set_data( properties, "alpha", alpha, owidth * oheight, ( mlt_destructor )mlt_pool_release, NULL );
this->get_alpha_mask = NULL;
}
video = temp;
if ( first_video == NULL )
first_video = temp;
+
+ // Ensure that all frames know the aspect ratio of the background
+ mlt_properties_set_double( temp_properties, "output_ratio",
+ mlt_properties_get_double( MLT_FRAME_PROPERTIES( first_video ), "aspect_ratio" ) );
+
mlt_properties_set_int( MLT_FRAME_PROPERTIES( temp ), "image_count", ++ image_count );
image_count = 1;
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+#include <math.h>
typedef int ( *image_scaler )( mlt_frame this, uint8_t **image, mlt_image_format iformat, mlt_image_format oformat, int iwidth, int iheight, int owidth, int oheight );
static void scale_alpha( mlt_frame this, int iwidth, int iheight, int owidth, int oheight )
{
- int size = 0;
- uint8_t *input = mlt_properties_get_data( MLT_FRAME_PROPERTIES( this ), "alpha", &size );
-
- if ( input != NULL && ( ( size == iwidth * iheight ) || size == ( iwidth * ( iheight + 1 ) ) ) )
+ uint8_t *output = NULL;
+ uint8_t *input = mlt_frame_get_alpha_mask( this );
+
+ if ( input != NULL )
{
- uint8_t *output = mlt_pool_alloc( owidth * oheight );
-
- // Derived coordinates
- int dy, dx;
-
- // Calculate ranges
- int out_x_range = owidth / 2;
- int out_y_range = oheight / 2;
- int in_x_range = iwidth / 2;
- int in_y_range = iheight / 2;
-
- // Output pointers
- register uint8_t *out_line = output;
- register uint8_t *out_ptr;
-
- // Calculate a middle pointer
- uint8_t *in_middle = input + iwidth * in_y_range + in_x_range;
- uint8_t *in_line;
-
- // Generate the affine transform scaling values
- register int scale_width = ( iwidth << 16 ) / owidth;
- register int scale_height = ( iheight << 16 ) / oheight;
- register int base = 0;
-
- int outer = out_x_range * scale_width;
- int bottom = out_y_range * scale_height;
-
- // Loop for the entirety of our output height.
- for ( dy = - bottom; dy < bottom; dy += scale_height )
- {
- // Start at the beginning of the line
- out_ptr = out_line;
-
- // Pointer to the middle of the input line
- in_line = in_middle + ( dy >> 16 ) * iwidth;
-
- // Loop for the entirety of our output row.
- for ( dx = - outer; dx < outer; dx += scale_width )
- {
- base = dx >> 15;
- *out_ptr ++ = *( in_line + base );
- }
-
- // Move to next output line
- out_line += owidth;
- }
-
- this->get_alpha_mask = NULL;
- mlt_properties_set_data( MLT_FRAME_PROPERTIES( this ), "alpha", output, 0, mlt_pool_release, NULL );
+ uint8_t *out_line;
+ int x, y;
+ int ox = ( iwidth << 10 ) / owidth;
+ int oy = ( iheight << 10 ) / oheight;
+
+ output = mlt_pool_alloc( owidth * oheight );
+ out_line = output;
+
+ // Loop for the entirety of our output height.
+ for ( y = 0; y < oheight; y ++ )
+ for ( x = 0; x < owidth; x ++ )
+ *out_line ++ = *( input + ( ( 512 + ( y * oy * iwidth ) + x * ox ) >> 10 ) );
+
+ // Set it back on the frame
+ mlt_properties_set_data( MLT_FRAME_PROPERTIES( this ), "alpha", output, owidth * oheight, mlt_pool_release, NULL );
}
}
else
{
// When no scaling is requested, revert the requested dimensions if possible
- mlt_properties_set_int( properties, "rescale_width", ( iwidth / 2 ) * 2 );
+ mlt_properties_set_int( properties, "rescale_width", iwidth );
mlt_properties_set_int( properties, "rescale_height", iheight );
}
}
else
{
+ // Scale the alpha
+ scale_alpha( this, iwidth, iheight, owidth, oheight );
*width = iwidth;
*height = iheight;
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+#include <math.h>
/** Do it :-).
*/
//fprintf( stderr, "normalised %dx%d output %dx%d %f %f\n", normalised_width, normalised_height, owidth, oheight, ( float )output_ar, ( float )mlt_properties_get_double( properties, "consumer_aspect_ratio" ) * owidth / oheight );
// Optimised for the input_ar > output_ar case (e.g. widescreen on standard)
- int scaled_width = ( input_ar * normalised_width ) / output_ar + 0.5;
+ int scaled_width = rint( 0.5 + ( input_ar * normalised_width ) / output_ar );
int scaled_height = normalised_height;
// Now ensure that our images fit in the output frame
if ( scaled_width > normalised_width )
{
scaled_width = normalised_width;
- scaled_height = ( output_ar * normalised_height ) / input_ar + 0.5;
+ scaled_height = rint( 0.5 + ( output_ar * normalised_height ) / input_ar );
}
// Now calculate the actual image size that we want
- owidth = scaled_width * owidth / normalised_width;
- oheight = scaled_height * oheight / normalised_height;
+ owidth = rint( 0.5 + scaled_width * owidth / normalised_width );
+ oheight = rint( 0.5 + scaled_height * oheight / normalised_height );
// Tell frame we have conformed the aspect to the consumer
mlt_frame_set_aspect_ratio( this, mlt_properties_get_double( properties, "consumer_aspect_ratio" ) );
mlt_frame_set_position( b_frame, position );
mlt_properties_set_double( b_props, "consumer_aspect_ratio", mlt_properties_get_double( a_props, "consumer_aspect_ratio" ) );
mlt_properties_set_int( b_props, "consumer_deinterlace", mlt_properties_get_double( a_props, "consumer_deinterlace" ) );
+ mlt_properties_set_int( b_props, "output_ratio", mlt_properties_get_double( a_props, "output_ratio" ) );
// Check for the special case - no aspect ratio means no problem :-)
if ( mlt_frame_get_aspect_ratio( b_frame ) == 0 )
// Now update properties so we free the copy after
mlt_properties_set_data( properties, "image", copy, size, mlt_pool_release, NULL );
mlt_properties_set_data( properties, "alpha", alpha, size >> 1, mlt_pool_release, NULL );
+ mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( producer_props, "aspect_ratio" ) );
}
// Pass on the image
register int j;
register int a;
register int mix;
- int uneven_w = width % 2;
for ( j = 0; j < width; j ++ )
{
a = *alpha_b ++;
mix = ( luma == NULL ) ? weight : smoothstep( luma[ j ], luma[ j ] + softness, weight + softness );
mix = ( mix * a ) >> 8;
- *dest = ( *src++ * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
+ *dest = ( ( *src++ + uneven_x ) * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
dest++;
*dest = ( *( src ++ + uneven_x ) * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
dest++;
*alpha_a = mix | *alpha_a;
alpha_a ++;
}
-
- if ( uneven_w )
- {
- a = *alpha_b ++;
- mix = ( luma == NULL ) ? weight : smoothstep( luma[ j ], luma[ j ] + softness, weight + softness );
- mix = ( mix * a ) >> 8;
- *dest = ( *src ++ * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
- dest++;
- *alpha_a = mix | *alpha_a;
- alpha_a ++;
- }
}
static void composite_line_yuv_or( uint8_t *dest, uint8_t *src, int width, uint8_t *alpha_b, uint8_t *alpha_a, int weight, uint16_t *luma, int softness, int uneven_x )
register int j;
register int a;
register int mix;
- int uneven_w = width % 2;
for ( j = 0; j < width; j ++ )
{
*alpha_a = mix | *alpha_a;
alpha_a ++;
}
-
- if ( uneven_w )
- {
- a = *alpha_b ++ | *alpha_a;
- mix = ( luma == NULL ) ? weight : smoothstep( luma[ j ], luma[ j ] + softness, weight + softness );
- mix = ( mix * a ) >> 8;
- *dest = ( *( src ++ + uneven_x ) * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
- dest++;
- *alpha_a = mix | *alpha_a;
- alpha_a ++;
- }
}
static void composite_line_yuv_and( uint8_t *dest, uint8_t *src, int width, uint8_t *alpha_b, uint8_t *alpha_a, int weight, uint16_t *luma, int softness, int uneven_x )
register int j;
register int a;
register int mix;
- int uneven_w = width % 2;
for ( j = 0; j < width; j ++ )
{
*alpha_a = mix | *alpha_a;
alpha_a ++;
}
-
- if ( uneven_w )
- {
- a = *alpha_b ++ & *alpha_a;
- mix = ( luma == NULL ) ? weight : smoothstep( luma[ j ], luma[ j ] + softness, weight + softness );
- mix = ( mix * a ) >> 8;
- *dest = ( *src ++ * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
- dest++;
- *alpha_a = mix | *alpha_a;
- alpha_a ++;
- }
}
static void composite_line_yuv_xor( uint8_t *dest, uint8_t *src, int width, uint8_t *alpha_b, uint8_t *alpha_a, int weight, uint16_t *luma, int softness, int uneven_x )
register int j;
register int a;
register int mix;
- int uneven_w = width % 2;
for ( j = 0; j < width; j ++ )
{
*alpha_a = mix | *alpha_a;
alpha_a ++;
}
-
- if ( uneven_w )
- {
- a = *alpha_b ++ ^ *alpha_a;
- mix = ( luma == NULL ) ? weight : smoothstep( luma[ j ], luma[ j ] + softness, weight + softness );
- mix = ( mix * a ) >> 8;
- *dest = ( *( src ++ + uneven_x ) * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
- dest++;
- *alpha_a = mix | *alpha_a;
- alpha_a ++;
- }
}
/** Composite function.
int alpha_b_stride = stride_src / bpp;
int alpha_a_stride = stride_dest / bpp;
- // Incorrect, but keeps noise away?
- height_src --;
-
// now do the compositing only to cropped extents
for ( i = 0; i < height_src; i += step )
{
int real_width = get_value( b_props, "real_width", "width" );
int real_height = get_value( b_props, "real_height", "height" );
double input_ar = mlt_properties_get_double( b_props, "aspect_ratio" );
- double output_ar = mlt_properties_get_double( b_props, "consumer_aspect_ratio" );
- int scaled_width = ( input_ar == 0.0 ? output_ar : input_ar ) / output_ar * real_width;
+ double consumer_ar = mlt_properties_get_double( b_props, "consumer_aspect_ratio" );
+ double background_ar = mlt_properties_get_double( b_props, "output_ratio" );
+ double output_ar = background_ar != 0.0 ? background_ar : consumer_ar;
+ int scaled_width = rint( 0.5 + ( input_ar == 0.0 ? output_ar : input_ar ) / output_ar * real_width );
int scaled_height = real_height;
// Now ensure that our images fit in the normalised frame
if ( scaled_width > normalised_width )
{
- scaled_height = scaled_height * normalised_width / scaled_width;
+ scaled_height = rint( 0.5 + scaled_height * normalised_width / scaled_width );
scaled_width = normalised_width;
}
if ( scaled_height > normalised_height )
{
- scaled_width = scaled_width * normalised_height / scaled_height;
+ scaled_width = rint( 0.5 + scaled_width * normalised_height / scaled_height );
scaled_height = normalised_height;
}
{
if ( scaled_height < normalised_height && scaled_width * normalised_height / scaled_height < normalised_width )
{
- scaled_width = scaled_width * normalised_height / scaled_height;
+ scaled_width = rint( 0.5 + scaled_width * normalised_height / scaled_height );
scaled_height = normalised_height;
}
else if ( scaled_width < normalised_width && scaled_height * normalised_width / scaled_width < normalised_height )
{
- scaled_height = scaled_height * normalised_width / scaled_width;
+ scaled_height = rint( 0.5 + scaled_height * normalised_width / scaled_width );
scaled_width = normalised_width;
}
}
}
// We want to ensure that we bypass resize now...
- mlt_properties_set_int( b_props, "distort", 1 );
+ mlt_properties_set_int( b_props, "distort", mlt_properties_get_int( properties, "distort" ) );
- // Take into consideration alignment for optimisation
+ // Take into consideration alignment for optimisation (titles are a special case)
if ( !mlt_properties_get_int( properties, "titles" ) )
alignment_calculate( geometry );
// Adjust to consumer scale
- *width = geometry->sw * *width / geometry->nw;
- *height = geometry->sh * *height / geometry->nh;
+ *width = rint( 0.5 + geometry->sw * *width / geometry->nw );
+ *height = rint( 0.5 + geometry->sh * *height / geometry->nh );
ret = mlt_frame_get_image( b_frame, image, &format, width, height, 1 );
return start;
}
-static inline void inline_memcpy( uint8_t *dest, uint8_t *src, int length )
-{
- uint8_t *end = src + length;
- while ( src < end )
- {
- *dest ++ = *src ++;
- *dest ++ = *src ++;
- }
-}
-
mlt_frame composite_copy_region( mlt_transition this, mlt_frame a_frame, mlt_position frame_position )
{
// Create a frame to return
while ( h -- )
{
- inline_memcpy( dest, p, w * 2 );
+ memcpy( dest, p, w * 2 );
dest += ds;
p += ss;
}
if ( mlt_properties_get_int( properties, "titles" ) )
{
- result.item.w = *width * ( result.item.w / result.nw );
+ result.item.w = rint( 0.5 + *width * ( result.item.w / result.nw ) );
result.nw = result.item.w;
- result.item.h = *height * ( result.item.h / result.nh );
+ result.item.h = rint( 0.5 + *height * ( result.item.h / result.nh ) );
result.nh = *height;
result.sw = width_b;
result.sh = height_b;
// Inform apps and framework that this is a video only transition
mlt_properties_set_int( properties, "_transition_type", 1 );
-
-#ifdef USE_MMX
- //mlt_properties_set_int( properties, "_MMX", composite_have_mmx() );
-#endif
}
return this;
}
.composite.softness=.3
.filter[0]=watermark
.filter[0].resource=colour:0x6c0101ff
+.filter[0].composite.distort=1
.filter[1]=watermark
.filter[1].resource=pango:
.filter[1].producer.text=
.composite.softness=.3
.filter[0]=watermark
.filter[0].resource=colour:0x6c0101ff
+.filter[0].composite.distort=1
.filter[1]=watermark
.filter[1].resource=pango:
.filter[1].producer.text=
.composite.geometry=-230,115:230x30;12=0
.filter[0]=watermark
.filter[0].resource=colour:0x6c0101ff
+.filter[0].composite.distort=1
.filter[1]=watermark
.filter[1].resource=pango:
.filter[1].producer.text=ETV Exclusive
.composite.geometry=590,160:80x25:0;12=,:x:100
.filter[0]=watermark
.filter[0].resource=colour:0x6c0101ff
+.filter[0].composite.distort=1
.filter[1]=watermark
.filter[1].resource=pango:
.filter[1].producer.text=File Shot
.filter[0]=watermark
.filter[0].resource=colour:0x6c0101ff
.filter[0].composite.geometry=100%,0%:100%x100%:0;12=0%,0%:x:100
+.filter[0].composite.distort=1
.filter[1]=watermark
.filter[1].resource=pango:
.filter[1].producer.text=Special
.filter[0]=watermark
.filter[0].resource=colour:0xbbbbbbff
.filter[0].composite.geometry=0,0:100%:100%:70
+.filter[0].composite.distort=1
.filter[1]=watermark
.filter[1].resource=pango:
.filter[1].producer.text=