Example #1
0
void mlt_producer_close( mlt_producer self )
{
	if ( self != NULL && mlt_properties_dec_ref( MLT_PRODUCER_PROPERTIES( self ) ) <= 0 )
	{
		self->parent.close = NULL;

		if ( self->close != NULL )
		{
			self->close( self->close_object );
		}
		else
		{
			int destroy = mlt_producer_is_cut( self );

#if _MLT_PRODUCER_CHECKS_ == 1
			// Show debug info
			mlt_properties_debug( MLT_PRODUCER_PROPERTIES( self ), "Producer closing", stderr );
#endif

#ifdef _MLT_PRODUCER_CHECKS_
			// Show current stats - these should match when the app is closed
			mlt_log( MLT_PRODUCER_SERVICE( self ), MLT_LOG_DEBUG, "Producers created %d, destroyed %d\n", producers_created, ++producers_destroyed );
#endif

			mlt_service_close( &self->parent );

			if ( destroy )
				free( self );
		}
	}
}
Example #2
0
static int attach_boundry_to_frame( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
{
	// Get the filter object
	mlt_filter filter = mlt_frame_pop_service( frame );

	// Get the filter's property object
	mlt_properties filter_properties = MLT_FILTER_PROPERTIES(filter);

	// Get the frame properties
	mlt_properties frame_properties = MLT_FRAME_PROPERTIES(frame);

	// Get the frame position
	mlt_position position = mlt_filter_get_position( filter, frame );
	
	mlt_service_lock( MLT_FILTER_SERVICE( filter ) );

	// Get the geometry object
	mlt_geometry geometry = mlt_properties_get_data(filter_properties, "filter_geometry", NULL);
	if (geometry == NULL) {
		mlt_geometry geom = mlt_geometry_init();
		char *arg = mlt_properties_get(filter_properties, "geometry");

		// Initialize with the supplied geometry
		struct mlt_geometry_item_s item;
		mlt_geometry_parse_item( geom, &item, arg  );

		item.frame = 0;
		item.key = 1;
		item.mix = 100;

		mlt_geometry_insert( geom, &item );
		mlt_geometry_interpolate( geom );
		mlt_properties_set_data( filter_properties, "filter_geometry", geom, 0, (mlt_destructor)mlt_geometry_close, (mlt_serialiser)mlt_geometry_serialise );
		geometry = mlt_properties_get_data(filter_properties, "filter_geometry", NULL);
	}

	mlt_service_unlock( MLT_FILTER_SERVICE( filter ) );

	// Get the current geometry item
	mlt_geometry_item geometry_item = mlt_pool_alloc( sizeof( struct mlt_geometry_item_s ) );
	mlt_geometry_fetch(geometry, geometry_item, position);

	// Cleanse the geometry item
	geometry_item->w = geometry_item->x < 0 ? geometry_item->w + geometry_item->x : geometry_item->w;
	geometry_item->h = geometry_item->y < 0 ? geometry_item->h + geometry_item->y : geometry_item->h;
	geometry_item->x = geometry_item->x < 0 ? 0 : geometry_item->x;
	geometry_item->y = geometry_item->y < 0 ? 0 : geometry_item->y;
	geometry_item->w = geometry_item->w < 0 ? 0 : geometry_item->w;
	geometry_item->h = geometry_item->h < 0 ? 0 : geometry_item->h;

	mlt_properties_set_data( frame_properties, "bounds", geometry_item, sizeof( struct mlt_geometry_item_s ), mlt_pool_release, NULL );

	// Get the new image
	int error = mlt_frame_get_image( frame, image, format, width, height, 1 );

	if( error != 0 )
		mlt_properties_debug( frame_properties, "error after mlt_frame_get_image() in autotrack_rectangle attach_boundry_to_frame", stderr );

	return error;
}
Example #3
0
static mlt_frame process(mlt_filter filter, mlt_frame frame)
{
	mlt_properties properties = MLT_FILTER_PROPERTIES(filter);
	mlt_transition transition = mlt_properties_get_data(properties, "instance", NULL);
	char *name = mlt_properties_get(MLT_FILTER_PROPERTIES(filter), "transition");

	if (!name || !strcmp("", name))
		return frame;

	// Create the transition if needed.
	if (!transition
		|| !mlt_properties_get(MLT_FILTER_PROPERTIES(transition), "mlt_service") 
		|| strcmp(name, mlt_properties_get(MLT_FILTER_PROPERTIES(transition), "mlt_service"))) {
		mlt_profile profile = mlt_service_profile(MLT_FILTER_SERVICE(filter));

		transition = mlt_factory_transition(profile, name, NULL);
		mlt_properties_set_data(MLT_FILTER_PROPERTIES(filter), "instance", transition, 0, (mlt_destructor) mlt_transition_close, NULL);
	}

	if (transition) {
		mlt_properties transition_props = MLT_TRANSITION_PROPERTIES(transition);
		int type = mlt_properties_get_int(transition_props, "_transition_type");
		int hide = mlt_properties_get_int(MLT_FRAME_PROPERTIES(frame), "hide");

		mlt_properties_pass_list(transition_props, properties, "in out");
		mlt_properties_pass(transition_props, properties, "transition." );

		// Only if video transition on visible track.
		if ((type & 1) && !mlt_frame_is_test_card(frame) && !(hide & 1)) {
			mlt_frame_push_service_int(frame,
				mlt_image_format_id(mlt_properties_get(properties, "mlt_image_format")));
			mlt_frame_push_service(frame, transition);
			mlt_frame_push_get_image(frame, get_image);
		}
		if (type == 0)
			mlt_properties_debug(transition_props, "unknown transition type", stderr);
	} else {
		mlt_properties_debug(properties, "mask_failed to create transition", stderr );
	}

	return frame;
}
Example #4
0
void process_queue( mlt_deque data_queue, mlt_frame frame, mlt_filter filter )
{
	if ( data_queue != NULL )
	{
		// Create a new queue for those that we can't handle
		mlt_deque temp_queue = mlt_deque_init( );

		// Iterate through each entry on the queue
		while ( mlt_deque_peek_front( data_queue ) != NULL )
		{
			// Get the data feed
			mlt_properties feed = mlt_deque_pop_front( data_queue );

			if ( mlt_properties_get( MLT_FILTER_PROPERTIES( filter ), "debug" ) != NULL )
				mlt_properties_debug( feed, mlt_properties_get( MLT_FILTER_PROPERTIES( filter ), "debug" ), stderr );

			// Process the data feed...
			if ( process_feed( feed, filter, frame ) == 0 )
				mlt_properties_close( feed );
			else
				mlt_deque_push_back( temp_queue, feed );
		}
	
		// Now put the unprocessed feeds back on the stack
		while ( mlt_deque_peek_front( temp_queue ) )
		{
			// Get the data feed
			mlt_properties feed = mlt_deque_pop_front( temp_queue );
	
			// Put it back on the data queue
			mlt_deque_push_back( data_queue, feed );
		}
	
		// Close the temporary queue
		mlt_deque_close( temp_queue );
	}
}
Example #5
0
// Image stack(able) method
static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
{

	// Get the filter object
	mlt_filter filter = mlt_frame_pop_service( frame );

	// Get the filter's property object
	mlt_properties filter_properties = MLT_FILTER_PROPERTIES(filter);

	// Get the frame properties
	mlt_properties frame_properties = MLT_FRAME_PROPERTIES(frame);

	// Get the frame position
	mlt_position position = mlt_filter_get_position( filter, frame );

	// Get the new image
	int error = mlt_frame_get_image( frame, image, format, width, height, 1 );

	if( error != 0 )
		mlt_properties_debug( frame_properties, "error after mlt_frame_get_image() in autotrack_rectangle", stderr );

	mlt_service_lock( MLT_FILTER_SERVICE( filter ) );

	// Get the geometry object
	mlt_geometry geometry = mlt_properties_get_data(filter_properties, "filter_geometry", NULL);

	// Get the current geometry item
	struct mlt_geometry_item_s boundry;
	mlt_geometry_fetch(geometry, &boundry, position);

	// Get the motion vectors
	struct motion_vector_s *vectors = mlt_properties_get_data( frame_properties, "motion_est.vectors", NULL );

	// Cleanse the geometry item
	boundry.w = boundry.x < 0 ? boundry.w + boundry.x : boundry.w;
	boundry.h = boundry.y < 0 ? boundry.h + boundry.y : boundry.h;
	boundry.x = boundry.x < 0 ? 0 : boundry.x;
	boundry.y = boundry.y < 0 ? 0 : boundry.y;
	boundry.w = boundry.w < 0 ? 0 : boundry.w;
	boundry.h = boundry.h < 0 ? 0 : boundry.h;

	// How did the rectangle move?
	if( vectors != NULL &&
	    boundry.key != 1 ) // Paused?
	{

		int method = mlt_properties_get_int( filter_properties, "method" );

		// Get the size of macroblocks in pixel units
		int macroblock_height = mlt_properties_get_int( frame_properties, "motion_est.macroblock_height" );
		int macroblock_width = mlt_properties_get_int( frame_properties, "motion_est.macroblock_width" );
		int mv_buffer_width = *width / macroblock_width;

		caculate_motion( vectors, &boundry, macroblock_width, macroblock_height, mv_buffer_width, method, *width, *height );


		// Make the geometry object a real boy
		boundry.key = 1;
		boundry.f[0] = 1;
		boundry.f[1] = 1;
		boundry.f[2] = 1;
		boundry.f[3] = 1;
		boundry.f[4] = 1;
		mlt_geometry_insert(geometry, &boundry);
		mlt_geometry_interpolate(geometry);
	}

	mlt_service_unlock( MLT_FILTER_SERVICE( filter ) );

	if( mlt_properties_get_int( filter_properties, "debug" ) == 1 )
	{
		init_arrows( format, *width, *height );
		draw_rectangle_outline(*image, boundry.x, boundry.y, boundry.w, boundry.h, 100);
	}

	if( mlt_properties_get_int( filter_properties, "_serialize" ) == 1 )
	{
		// Add the vector change to the list
		mlt_geometry key_frames = mlt_properties_get_data( filter_properties, "motion_vector_list", NULL );
		if ( !key_frames )
		{
			key_frames = mlt_geometry_init();
			mlt_properties_set_data( filter_properties, "motion_vector_list", key_frames, 0,
			                         (mlt_destructor) mlt_geometry_close, (mlt_serialiser) mlt_geometry_serialise );
			if ( key_frames )
				mlt_geometry_set_length( key_frames, mlt_filter_get_length2( filter, frame ) );
		}
		if ( key_frames )
		{
			struct mlt_geometry_item_s item;
			item.frame = (int) mlt_frame_get_position( frame );
			item.key = 1;
			item.x = boundry.x;
			item.y = boundry.y;
			item.w = boundry.w;
			item.h = boundry.h;
			item.mix = 0;
			item.f[0] = item.f[1] = item.f[2] = item.f[3] = 1;
			item.f[4] = 0;
			mlt_geometry_insert( key_frames, &item );
		}
	}
	
	if( mlt_properties_get_int( filter_properties, "obscure" ) == 1 )
	{
		mlt_filter obscure = mlt_properties_get_data( filter_properties, "_obscure", NULL );

		mlt_properties_pass_list( MLT_FILTER_PROPERTIES(obscure), filter_properties, "in, out");

		// Because filter_obscure needs to be rewritten to use mlt_geometry
		char geom[100];
		sprintf( geom, "%d/%d:%dx%d", (int)boundry.x, (int)boundry.y, (int)boundry.w, (int)boundry.h );
		mlt_properties_set( MLT_FILTER_PROPERTIES( obscure ), "start", geom );
		mlt_properties_set( MLT_FILTER_PROPERTIES( obscure ), "end", geom );
	}
		
	if( mlt_properties_get_int( filter_properties, "collect" ) == 1 )
	{
		fprintf( stderr, "%d,%d,%d,%d\n", (int)boundry.x, (int)boundry.y, (int)boundry.w, (int)boundry.h );
		fflush( stdout );
	}

	return error;
}