From 9c7d043e0c13911fc12817e434363604cbd1d8c6 Mon Sep 17 00:00:00 2001 From: j-b-m Date: Wed, 5 Nov 2008 19:09:29 +0000 Subject: [PATCH] kdenlive/filter_freeze.c: added simple freeze filter git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@1219 d19143bc-622f-0410-bfdd-b5b2a6649095 --- src/modules/kdenlive/Makefile | 1 + src/modules/kdenlive/factory.c | 2 + src/modules/kdenlive/filter_freeze.c | 117 ++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+), 0 deletions(-) create mode 100644 src/modules/kdenlive/filter_freeze.c diff --git a/src/modules/kdenlive/Makefile b/src/modules/kdenlive/Makefile index e2cc49b..cfe0811 100644 --- a/src/modules/kdenlive/Makefile +++ b/src/modules/kdenlive/Makefile @@ -4,6 +4,7 @@ TARGET = ../libmltkdenlive$(LIBSUF) OBJS = factory.o \ filter_boxblur.o \ + filter_freeze.o \ filter_wave.o \ producer_framebuffer.o diff --git a/src/modules/kdenlive/factory.c b/src/modules/kdenlive/factory.c index 430a24c..80914c7 100644 --- a/src/modules/kdenlive/factory.c +++ b/src/modules/kdenlive/factory.c @@ -21,12 +21,14 @@ #include extern mlt_filter filter_boxblur_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); +extern mlt_filter filter_freeze_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_filter filter_wave_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_producer producer_framebuffer_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); MLT_REPOSITORY { MLT_REGISTER( filter_type, "boxblur", filter_boxblur_init ); + MLT_REGISTER( filter_type, "freeze", filter_freeze_init ); MLT_REGISTER( filter_type, "wave", filter_wave_init ); MLT_REGISTER( producer_type, "framebuffer", producer_framebuffer_init ); } diff --git a/src/modules/kdenlive/filter_freeze.c b/src/modules/kdenlive/filter_freeze.c new file mode 100644 index 0000000..a389e01 --- /dev/null +++ b/src/modules/kdenlive/filter_freeze.c @@ -0,0 +1,117 @@ +/* + * filter_freeze.c -- simple frame freezing filter + * Copyright (C) 2007 Jean-Baptiste Mardelle + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include + +static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) +{ + // Get the image + + + mlt_position currentpos = mlt_frame_get_position( this ); + + mlt_filter filter = mlt_frame_pop_service( this ); + mlt_properties properties = MLT_FILTER_PROPERTIES( filter ); + + 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" ); + + int do_freeze = 0; + if (freeze_before == 0 && freeze_after == 0) { + do_freeze = 1; + } else if (freeze_before != 0 && pos > currentpos) { + do_freeze = 1; + } else if (freeze_after != 0 && pos < currentpos) { + do_freeze = 1; + } + + if (do_freeze == 1) { + freeze_frame = mlt_properties_get_data( properties, "freeze_frame", NULL ); + + if( freeze_frame == NULL) + { + // freeze_frame has not been fetched yet, so fetch it and cache it. + mlt_producer producer = mlt_frame_get_original_producer(this); + mlt_producer_seek( producer, pos ); + + // Get the frame + mlt_service_get_frame( mlt_producer_service(producer), &freeze_frame, 0 ); + + mlt_properties props = MLT_FRAME_PROPERTIES( this ); + 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_int( freeze_properties, "progressive", mlt_properties_get_int( props, "progressive" ) ); + + mlt_properties_set_data( properties, "freeze_frame", freeze_frame, 0, NULL, NULL ); + } + int error = mlt_frame_get_image( freeze_frame, image, format, width, height, 1 ); + return error; + } + + int error = mlt_frame_get_image( this, image, format, width, height, 1 ); + return error; +} + +/** Filter processing. +*/ + +static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) +{ + + // Push the filter on to the stack + mlt_frame_push_service( frame, this ); + + // Push the frame filter + mlt_frame_push_get_image( frame, filter_get_image ); + + return frame; +} + +/** Constructor for the filter. +*/ + +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 ) + { + this->process = filter_process; + // Set the frame which will be chosen for freeze + mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "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" ); + + // If freeze_before = 1, only frames after the "frame" value will be frozen + mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "freeze_before", "0" ); + } + return this; +} + + + -- 1.7.4.4