X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmodules%2Fkdenlive%2Ffilter_freeze.c;h=9c0b489893602f09232af071bddad40c2710436d;hb=11ceb3a29fd27c05bfac2b05463eff1790309a81;hp=5a8497395424500e87177059f6021689312fb182;hpb=e7ee8b906479732ca0ba4fcf5ee779b87359f1f4;p=mlt diff --git a/src/modules/kdenlive/filter_freeze.c b/src/modules/kdenlive/filter_freeze.c index 5a849739..9c0b4898 100755 --- a/src/modules/kdenlive/filter_freeze.c +++ b/src/modules/kdenlive/filter_freeze.c @@ -27,18 +27,18 @@ #include #include -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) +static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) { // Get the image - mlt_filter filter = mlt_frame_pop_service( this ); + mlt_filter filter = mlt_frame_pop_service( frame ); mlt_properties properties = MLT_FILTER_PROPERTIES( filter ); - mlt_properties props = MLT_FRAME_PROPERTIES( this ); + mlt_properties props = MLT_FRAME_PROPERTIES( frame ); mlt_frame freeze_frame = NULL;; int freeze_before = mlt_properties_get_int( properties, "freeze_before" ); int freeze_after = mlt_properties_get_int( properties, "freeze_after" ); - mlt_position pos = mlt_properties_get_position( properties, "frame" ); - mlt_position currentpos = mlt_properties_get_position( properties, "_seek_frame" ); + mlt_position pos = mlt_properties_get_position( properties, "frame" ) + mlt_producer_get_in( mlt_frame_get_original_producer( frame ) ); + mlt_position currentpos = mlt_filter_get_position( filter, frame ); int do_freeze = 0; if (freeze_before == 0 && freeze_after == 0) { @@ -50,73 +50,60 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format * } if (do_freeze == 1) { + mlt_service_lock( MLT_FILTER_SERVICE( filter ) ); freeze_frame = mlt_properties_get_data( properties, "freeze_frame", NULL ); - if( freeze_frame == NULL || mlt_properties_get_position( properties, "_frame" ) != pos || mlt_properties_get_int( props , "width" ) != mlt_properties_get_int( MLT_FRAME_PROPERTIES( freeze_frame ), "width" ) || mlt_properties_get_int( props , "height" ) != mlt_properties_get_int( MLT_FRAME_PROPERTIES( freeze_frame ), "height" ) ) + if ( !freeze_frame || mlt_properties_get_position( properties, "_frame" ) != pos ) { // freeze_frame has not been fetched yet or is not useful, so fetch it and cache it. - mlt_producer producer = mlt_frame_get_original_producer(this); + // get parent producer + mlt_producer producer = mlt_producer_cut_parent( mlt_frame_get_original_producer( frame ) ); mlt_producer_seek( producer, pos ); - + // Get the frame mlt_service_get_frame( mlt_producer_service(producer), &freeze_frame, 0 ); mlt_properties freeze_properties = MLT_FRAME_PROPERTIES( freeze_frame ); - mlt_properties_set_double( freeze_properties, "consumer_aspect_ratio", mlt_properties_get_double( props, "consumer_aspect_ratio" ) ); mlt_properties_set( freeze_properties, "rescale.interp", mlt_properties_get( props, "rescale.interp" ) ); - mlt_properties_set_double( freeze_properties, "aspect_ratio", mlt_frame_get_aspect_ratio( this ) ); + mlt_properties_set_double( freeze_properties, "aspect_ratio", mlt_frame_get_aspect_ratio( frame ) ); mlt_properties_set_int( freeze_properties, "progressive", mlt_properties_get_int( props, "progressive" ) ); mlt_properties_set_int( freeze_properties, "consumer_deinterlace", mlt_properties_get_int( props, "consumer_deinterlace" ) || mlt_properties_get_int( properties, "deinterlace" ) ); - mlt_properties_set_double( freeze_properties, "output_ratio", mlt_properties_get_double( props, "output_ratio" ) ); mlt_properties_set_data( properties, "freeze_frame", freeze_frame, 0, ( mlt_destructor )mlt_frame_close, NULL ); mlt_properties_set_position( properties, "_frame", pos ); } + mlt_service_unlock( MLT_FILTER_SERVICE( filter ) ); // Get frozen image uint8_t *buffer = NULL; int error = mlt_frame_get_image( freeze_frame, &buffer, format, width, height, 1 ); - int size = 0; - switch ( *format ) - { - case mlt_image_yuv420p: - size = *width * 3 * ( *height + 1 ) / 2; - break; - case mlt_image_rgb24: - size = *width * ( *height + 1 ) * 3; - break; - case mlt_image_rgb24a: - case mlt_image_opengl: - size = *width * ( *height + 1 ) * 4; - break; - default: - *format = mlt_image_yuv422; - size = *width * ( *height + 1 ) * 2; - break; - } - // Copy it to current frame - uint8_t *image_copy = mlt_pool_alloc( size ); + int size = mlt_image_format_size( *format, *width, *height, NULL ); + uint8_t *image_copy = mlt_pool_alloc( size ); memcpy( image_copy, buffer, size ); *image = image_copy; - mlt_properties_set_data( props, "image", *image, size, ( mlt_destructor ) mlt_pool_release, NULL ); + mlt_frame_set_image( frame, *image, size, mlt_pool_release ); + + uint8_t *alpha_buffer = mlt_frame_get_alpha_mask( freeze_frame ); + int alphasize = *width * *height; + uint8_t *alpha_copy = mlt_pool_alloc( alphasize ); + memcpy( alpha_copy, alpha_buffer, alphasize ); + mlt_frame_set_alpha( frame, alpha_copy, alphasize, mlt_pool_release ); + return error; } - int error = mlt_frame_get_image( this, image, format, width, height, 1 ); + int error = mlt_frame_get_image( frame, image, format, width, height, 1 ); return error; } /** Filter processing. */ -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) +static mlt_frame filter_process( mlt_filter filter, mlt_frame frame ) { // Push the filter on to the stack - mlt_frame_push_service( frame, this ); - - // Determine the time position of this frame - mlt_properties_set_position( MLT_FILTER_PROPERTIES( this ), "_seek_frame", mlt_frame_get_position( frame ) - mlt_filter_get_in( this ) ); + mlt_frame_push_service( frame, filter ); // Push the frame filter mlt_frame_push_get_image( frame, filter_get_image ); @@ -129,20 +116,20 @@ static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) mlt_filter filter_freeze_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) { - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) + mlt_filter filter = mlt_filter_new( ); + if ( filter != NULL ) { - this->process = filter_process; + filter->process = filter_process; // Set the frame which will be chosen for freeze - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "frame", "0" ); + mlt_properties_set( MLT_FILTER_PROPERTIES( filter ), "frame", "0" ); // If freeze_after = 1, only frames after the "frame" value will be frozen - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "freeze_after", "0" ); + mlt_properties_set( MLT_FILTER_PROPERTIES( filter ), "freeze_after", "0" ); - // If freeze_before = 1, only frames after the "frame" value will be frozen - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "freeze_before", "0" ); + // If freeze_before = 1, only frames before the "frame" value will be frozen + mlt_properties_set( MLT_FILTER_PROPERTIES( filter ), "freeze_before", "0" ); } - return this; + return filter; }