From d7f9be0634acea4a311066054258d2b0f6b4b7a5 Mon Sep 17 00:00:00 2001 From: ddennedy Date: Wed, 18 Feb 2004 17:06:01 +0000 Subject: [PATCH] split getting of b_frame image and composite git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@150 d19143bc-622f-0410-bfdd-b5b2a6649095 --- src/modules/core/filter_deinterlace.c | 1 + src/modules/core/transition_composite.c | 185 +++++++++++++++++-------------- src/modules/core/transition_luma.c | 10 +- 3 files changed, 109 insertions(+), 87 deletions(-) diff --git a/src/modules/core/filter_deinterlace.c b/src/modules/core/filter_deinterlace.c index 7fc04b6..3b4598a 100644 --- a/src/modules/core/filter_deinterlace.c +++ b/src/modules/core/filter_deinterlace.c @@ -86,6 +86,7 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format * { mlt_frame_get_image( this, image, format, width, height, 1 ); deinterlace_yuv( *image, *image, *width * 2, *height ); + mlt_properties_set_int( mlt_frame_properties( this ), "progressive", 1 ); return 0; } diff --git a/src/modules/core/transition_composite.c b/src/modules/core/transition_composite.c index 2cec6a6..49f7c94 100644 --- a/src/modules/core/transition_composite.c +++ b/src/modules/core/transition_composite.c @@ -141,80 +141,16 @@ static int get_value( mlt_properties properties, char *preferred, char *fallback /** Composite function. */ -static int composite_yuv( uint8_t *p_dest, mlt_image_format format_dest, int width_dest, int height_dest, mlt_frame that, struct geometry_s geometry ) +static int composite_yuv( uint8_t *p_dest, int width_dest, int height_dest, uint8_t *p_src, int width_src, int height_src, uint8_t *p_alpha, struct geometry_s geometry ) { int ret = 0; - uint8_t *p_src; int i, j; - int stride_src; - int stride_dest; int x_src = 0, y_src = 0; - - mlt_image_format format_src = format_dest; float weight = geometry.mix / 100; - - // Compute the dimensioning rectangle - mlt_properties b_props = mlt_frame_properties( that ); - mlt_transition this = mlt_properties_get_data( b_props, "transition_composite", NULL ); - mlt_properties properties = mlt_transition_properties( this ); - - if ( mlt_properties_get( properties, "distort" ) == NULL ) - { - // Now do additional calcs based on real_width/height etc - //int normalised_width = mlt_properties_get_int( b_props, "normalised_width" ); - //int normalised_height = mlt_properties_get_int( b_props, "normalised_height" ); - int normalised_width = geometry.w; - int normalised_height = geometry.h; - int real_width = get_value( b_props, "real_width", "width" ); - int real_height = get_value( b_props, "real_height", "height" ); - double input_ar = mlt_frame_get_aspect_ratio( that ); - double output_ar = mlt_properties_get_double( b_props, "consumer_aspect_ratio" ); - int scaled_width = ( input_ar > output_ar ? input_ar / output_ar : output_ar / input_ar ) * real_width; - int scaled_height = ( input_ar > output_ar ? input_ar / output_ar : output_ar / input_ar ) * 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_width = normalised_width; - } - if ( scaled_height > normalised_height ) - { - scaled_width = scaled_width * normalised_height / scaled_height; - scaled_height = normalised_height; - } - - // Special case - if ( scaled_height == normalised_height ) - scaled_width = normalised_width; - - // Now we need to align to the geometry - if ( scaled_width <= geometry.w && scaled_height <= geometry.h ) - { - // TODO: Should take into account requested alignment here... - // Assume centred alignment for now - - geometry.x = geometry.x + ( geometry.w - scaled_width ) / 2; - geometry.y = geometry.y + ( geometry.h - scaled_height ) / 2; - geometry.w = scaled_width; - geometry.h = scaled_height; - mlt_properties_set( b_props, "distort", "true" ); - } - else - { - mlt_properties_set( b_props, "distort", "true" ); - } - } - else - { - // We want to ensure that we bypass resize now... - mlt_properties_set( b_props, "distort", "true" ); - } - int x = ( geometry.x * width_dest ) / geometry.nw; int y = ( geometry.y * height_dest ) / geometry.nh; - int width_src = ( geometry.w * width_dest ) / geometry.nw; - int height_src = ( geometry.h * height_dest ) / geometry.nh; + int stride_src = width_src * 2; + int stride_dest = width_dest * 2; x -= x % 2; @@ -225,14 +161,6 @@ static int composite_yuv( uint8_t *p_dest, mlt_image_format format_dest, int wid if ( ( x < 0 && -x >= width_src ) || ( y < 0 && -y >= height_src ) ) return ret; - format_src = mlt_image_yuv422; - format_dest = mlt_image_yuv422; - - mlt_frame_get_image( that, &p_src, &format_src, &width_src, &height_src, 1 /* writable */ ); - - stride_src = width_src * 2; - stride_dest = width_dest * 2; - // crop overlay off the left edge of frame if ( x < 0 ) { @@ -261,9 +189,6 @@ static int composite_yuv( uint8_t *p_dest, mlt_image_format format_dest, int wid // offset pointer into frame buffer based upon positive, even coordinates only! p_dest += ( x < 0 ? 0 : x ) * 2 + ( y < 0 ? 0 : y ) * stride_dest; - // Get the alpha channel of the overlay - uint8_t *p_alpha = mlt_frame_get_alpha_mask( that ); - // offset pointer into alpha channel based upon cropping if ( p_alpha ) p_alpha += x_src + y_src * stride_src / 2; @@ -306,6 +231,92 @@ static int composite_yuv( uint8_t *p_dest, mlt_image_format format_dest, int wid } +/** Get the properly sized image from b_frame. +*/ + +static int get_b_frame_image( mlt_frame b_frame, uint8_t **image, int *width, int *height, struct geometry_s *geometry ) +{ + int ret = 0; + mlt_image_format format = mlt_image_yuv422; + + // Compute the dimensioning rectangle + mlt_properties b_props = mlt_frame_properties( b_frame ); + mlt_transition this = mlt_properties_get_data( b_props, "transition_composite", NULL ); + mlt_properties properties = mlt_transition_properties( this ); + + if ( mlt_properties_get( properties, "distort" ) == NULL ) + { + // Now do additional calcs based on real_width/height etc + //int normalised_width = mlt_properties_get_int( b_props, "normalised_width" ); + //int normalised_height = mlt_properties_get_int( b_props, "normalised_height" ); + int normalised_width = geometry->w; + int normalised_height = geometry->h; + int real_width = get_value( b_props, "real_width", "width" ); + int real_height = get_value( b_props, "real_height", "height" ); + double input_ar = mlt_frame_get_aspect_ratio( b_frame ); + double output_ar = mlt_properties_get_double( b_props, "consumer_aspect_ratio" ); + int scaled_width = ( input_ar > output_ar ? input_ar / output_ar : output_ar / input_ar ) * real_width; + int scaled_height = ( input_ar > output_ar ? input_ar / output_ar : output_ar / input_ar ) * 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_width = normalised_width; + } + if ( scaled_height > normalised_height ) + { + scaled_width = scaled_width * normalised_height / scaled_height; + scaled_height = normalised_height; + } + + // Special case + if ( scaled_height == normalised_height ) + scaled_width = normalised_width; + + // Now we need to align to the geometry + if ( scaled_width <= geometry->w && scaled_height <= geometry->h ) + { + // TODO: Should take into account requested alignment here... + // Assume centred alignment for now + + geometry->x = geometry->x + ( geometry->w - scaled_width ) / 2; + geometry->y = geometry->y + ( geometry->h - scaled_height ) / 2; + geometry->w = scaled_width; + geometry->h = scaled_height; + mlt_properties_set( b_props, "distort", "true" ); + } + else + { + mlt_properties_set( b_props, "distort", "true" ); + } + } + else + { + // We want to ensure that we bypass resize now... + mlt_properties_set( b_props, "distort", "true" ); + } + + int x = ( geometry->x * *width ) / geometry->nw; + int y = ( geometry->y * *height ) / geometry->nh; + *width = ( geometry->w * *width ) / geometry->nw; + *height = ( geometry->h * *height ) / geometry->nh; + + x -= x % 2; + + // optimization points - no work to do + if ( *width <= 0 || *height <= 0 ) + return 1; + + if ( ( x < 0 && -x >= *width ) || ( y < 0 && -y >= *height ) ) + return 1; + + ret = mlt_frame_get_image( b_frame, image, &format, width, height, 1 /* writable */ ); + + return ret; +} + + /** Get the image. */ @@ -314,6 +325,9 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f // Get the b frame from the stack mlt_frame b_frame = mlt_frame_pop_frame( a_frame ); + // This compositer is yuv422 only + *format = mlt_image_yuv422; + // Get the image from the a frame mlt_frame_get_image( a_frame, image, format, width, height, 1 ); @@ -354,9 +368,18 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f // consumer properties from the a_frame mlt_properties_set_double( b_props, "consumer_aspect_ratio", mlt_properties_get_double( a_props, "consumer_aspect_ratio" ) ); mlt_properties_set_double( b_props, "consumer_scale", mlt_properties_get_double( a_props, "consumer_scale" ) ); - - // Composite the b_frame on the a_frame - composite_yuv( *image, *format, *width, *height, b_frame, result ); + + // Get the image from the b frame + uint8_t *image_b; + int width_b = *width; + int height_b = *height; + if ( get_b_frame_image( b_frame, &image_b, &width_b, &height_b, &result ) == 0 ) + { + uint8_t *alpha = mlt_frame_get_alpha_mask( b_frame ); + + // Composite the b_frame on the a_frame + composite_yuv( *image, *width, *height, image_b, width_b, height_b, alpha, result ); + } } return 0; diff --git a/src/modules/core/transition_luma.c b/src/modules/core/transition_luma.c index ebc8915..6c57339 100644 --- a/src/modules/core/transition_luma.c +++ b/src/modules/core/transition_luma.c @@ -249,16 +249,14 @@ static int transition_get_image( mlt_frame this, uint8_t **image, mlt_image_form int luma_height = mlt_properties_get_int( b_props, "luma.height" ); float *luma_bitmap = mlt_properties_get_data( b_props, "luma.bitmap", NULL ); float luma_softness = mlt_properties_get_double( b_props, "luma.softness" ); - int progressive = mlt_properties_get_int( b_props, "progressive" ); + int progressive = mlt_properties_get_int( b_props, "progressive" ) || mlt_properties_get_int( a_props, "consumer_progressive" ); 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" ) ); + mlt_properties_set_double( b_props, "consumer_aspect_ratio", mlt_properties_get_double( a_props, "consumer_aspect_ratio" ) ); + mlt_properties_set_double( b_props, "consumer_scale", mlt_properties_get_double( a_props, "consumer_scale" ) ); // Honour the reverse here mix = reverse ? 1 - mix : mix; @@ -269,7 +267,7 @@ static int transition_get_image( mlt_frame this, uint8_t **image, mlt_image_form if ( luma_width > 0 && luma_height > 0 && luma_bitmap != NULL ) // Composite the frames using a luma map luma_composite( this, b_frame, luma_width, luma_height, luma_bitmap, mix, frame_delta, - luma_softness, progressive > 0 ? -1 : top_field_first, width, height ); + luma_softness, progressive ? -1 : top_field_first, width, height ); else // Dissolve the frames using the time offset for mix value frame_composite_yuv( this, b_frame, 0, 0, mix, width, height ); -- 1.7.4.4