2 * filter_imagestab.c -- video stabilization with code from http://vstab.sourceforge.net/
3 * Copyright (c) 2011 Marco Gittler <g.marco@freenet.de>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 #include <framework/mlt_filter.h>
21 #include <framework/mlt_frame.h>
22 #include <framework/mlt_log.h>
23 #include <framework/mlt_producer.h>
24 #include <framework/mlt_geometry.h>
32 #include "stabilize.h"
33 #include "transform_image.h"
36 static void serialize_vectors( StabData* self, mlt_position length )
38 mlt_geometry g = mlt_geometry_init();
42 struct mlt_geometry_item_s item;
45 // Initialize geometry item
46 item.key = item.f[0] = item.f[1] = 1;
47 item.f[2] = item.f[3] = item.f[4] = 1;
49 tlist* transform_data =self->transs;
50 for ( i = 0; i < length; i++ )
52 // Set the geometry item
55 if ( transform_data->data){
56 Transform* t=transform_data->data;
61 transform_data=transform_data->next;
64 // Add the geometry item
65 mlt_geometry_insert( g, &item );
68 // Put the analysis results in a property
69 mlt_geometry_set_length( g, length );
70 mlt_properties_set( MLT_FILTER_PROPERTIES( (mlt_filter) self->parent ), "vectors", mlt_geometry_serialise( g ) );
71 mlt_geometry_close( g );
75 Transform* deserialize_vectors( char *vectors, mlt_position length )
77 mlt_geometry g = mlt_geometry_init();
79 // Parse the property as a geometry
80 if ( !mlt_geometry_parse( g, vectors, length, -1, -1 ) )
82 struct mlt_geometry_item_s item;
84 tx=malloc(sizeof(Transform)*length);
85 memset(tx,sizeof(Transform)*length,0);
86 // Copy the geometry items to a vc array for interp()
87 for ( i = 0; i < length; i++ )
89 mlt_geometry_fetch( g, &item, i );
102 //mlt_log_warning( NULL, "failed to parse vectors\n" );
105 // We are done with this mlt_geometry
106 if ( g ) mlt_geometry_close( g );
110 static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
112 mlt_filter filter = mlt_frame_pop_service( frame );
113 //*format = mlt_image_rgb24;
114 *format = mlt_image_yuv420p;
115 int error = mlt_frame_get_image( frame, image, format, width, height, 1 );
117 if ( !error && *image )
119 StabData* self = filter->child;
120 mlt_position length = mlt_filter_get_length2( filter, frame );
124 // Service locks are for concurrency control
125 mlt_service_lock( MLT_FILTER_SERVICE( filter ) );
126 if ( !self->initialized )
128 // Initialize our context
129 self->initialized = 1;
132 self->framesize=w*h* 3;//( mlt_image_format_size ( *format, w,h , 0) ; // 3/2 =1 too small
133 stabilize_configure(self);
135 char *vectors = mlt_properties_get( MLT_FILTER_PROPERTIES(filter), "vectors" );
139 mlt_position pos = mlt_filter_get_position( filter, frame );
140 stabilize_filter_video ( self, *image, (*format==mlt_image_rgb24?0:1) );
144 if ( pos == length - 1 )
146 serialize_vectors( self, length );
152 TransformData* tf=mlt_properties_get_data( MLT_FILTER_PROPERTIES(filter), "_transformdata", NULL);
154 tf=mlt_pool_alloc(sizeof(TransformData));
155 mlt_properties_set_data( MLT_FILTER_PROPERTIES(filter), "_transformdata", tf, 0, ( mlt_destructor )mlt_pool_release, NULL );
157 if ( self->initialized != 2 )
159 // Load analysis results from property
160 self->initialized = 2;
161 transform_configure(tf,w,h,(*format==mlt_image_rgb24?0:1) ,*image, deserialize_vectors( vectors, length ),length);
164 if ( self->initialized == 2 )
167 float pos = mlt_filter_get_position( filter, frame );
168 tf->current_trans=pos;
169 transform_filter_video(tf, *image,(*format==mlt_image_rgb24?0:1));
172 mlt_service_unlock( MLT_FILTER_SERVICE( filter ) );
177 static mlt_frame filter_process( mlt_filter filter, mlt_frame frame )
179 mlt_frame_push_service( frame, filter );
180 mlt_frame_push_get_image( frame, filter_get_image );
184 static void filter_close( mlt_filter parent )
186 StabData* self = parent->child;
187 stabilize_stop(self);
189 parent->close = NULL;
190 parent->child = NULL;
193 mlt_filter filter_videostab2_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
195 StabData* self = calloc( 1, sizeof(StabData) );
198 mlt_filter parent = mlt_filter_new();
199 parent->child = self;
200 parent->close = filter_close;
201 parent->process = filter_process;
202 self->parent = parent;
203 mlt_properties_set( MLT_FILTER_PROPERTIES(parent), "shutterangle", "0" ); // 0 - 180 , default 0