示例#1
0
mlt_frame transition_process( mlt_transition transition, mlt_frame a_frame, mlt_frame b_frame )
{
	mlt_frame_push_service( a_frame, transition );
	mlt_frame_push_frame( a_frame, b_frame );
	mlt_frame_push_get_image( a_frame, transition_get_image );
	return a_frame;
}
static mlt_frame process( mlt_transition transition, mlt_frame a_frame, mlt_frame b_frame )
{
	mlt_service service = MLT_TRANSITION_SERVICE(transition);

	if ( !GlslManager::init_chain( service ) ) {
		// Create the Movit effect chain
		EffectChain* chain = GlslManager::get_chain( service );
		mlt_profile profile = mlt_service_profile( service );
		Input* b_input = new MltInput( profile->width, profile->height );
		ImageFormat output_format;
		output_format.color_space = COLORSPACE_sRGB;
		output_format.gamma_curve = GAMMA_sRGB;
		chain->add_input( b_input );
		chain->add_output( output_format, OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED );
		chain->set_dither_bits( 8 );

		Effect* effect = chain->add_effect( new OverlayEffect(),
			GlslManager::get_input( service ), b_input );

		// Save these new input on properties for get_image
		mlt_properties_set_data( MLT_TRANSITION_PROPERTIES(transition),
			"movit input B", b_input, 0, NULL, NULL );
	}

	// Push the transition on to the frame
	mlt_frame_push_service( a_frame, transition );

	// Push the b_frame on to the stack
	mlt_frame_push_frame( a_frame, b_frame );

	// Push the transition method
	mlt_frame_push_get_image( a_frame, get_image );

	return a_frame;
}
示例#3
0
mlt_frame transition_process( mlt_transition transition, mlt_frame a_frame, mlt_frame b_frame )
{
	char *name = mlt_properties_get( MLT_TRANSITION_PROPERTIES( transition ), "_unique_id" );
	mlt_properties_set_position( MLT_FRAME_PROPERTIES( a_frame ), name, mlt_frame_get_position( a_frame ) );
	mlt_frame_push_service( a_frame, transition );
	mlt_frame_push_frame( a_frame, b_frame );
	mlt_frame_push_get_image( a_frame, transition_get_image );
	return a_frame;
}
示例#4
0
static mlt_frame transition_process( mlt_transition transition, mlt_frame a_frame, mlt_frame b_frame )
{
	// Push the transition on to the frame
	mlt_frame_push_service( a_frame, transition );

	// Push the b_frame on to the stack
	mlt_frame_push_frame( a_frame, b_frame );

	// Push the transition method
	mlt_frame_push_get_image( a_frame, transition_get_image );

	return a_frame;
}
示例#5
0
static mlt_frame transitionProcess(mlt_transition transition, mlt_frame aFrame, mlt_frame bFrame) {
    mlt_frame_push_service(aFrame, transition);
    mlt_frame_push_frame(aFrame, bFrame);
    mlt_frame_push_get_image(aFrame, transitionGetImage);
    return aFrame;
}
示例#6
0
static int transition_get_frame( mlt_service service, mlt_frame_ptr frame, int index )
{
	int error = 0;
	mlt_transition self = service->child;

	mlt_properties properties = MLT_TRANSITION_PROPERTIES( self );

	int accepts_blanks = mlt_properties_get_int( properties, "accepts_blanks" );
	int a_track = mlt_properties_get_int( properties, "a_track" );
	int b_track = mlt_properties_get_int( properties, "b_track" );
	mlt_position in = mlt_properties_get_position( properties, "in" );
	mlt_position out = mlt_properties_get_position( properties, "out" );
	int always_active = mlt_properties_get_int( properties, "always_active" );
	int type = mlt_properties_get_int( properties, "_transition_type" );
	int reverse_order = 0;

	// Ensure that we have the correct order
	if ( a_track > b_track )
	{
		reverse_order = 1;
		a_track = b_track;
		b_track = mlt_properties_get_int( properties, "a_track" );
	}

	// Only act on this operation once per multitrack iteration from the tractor
	if ( !self->held )
	{
		int active = 0;
		int i = 0;
		int a_frame = a_track;
		int b_frame = b_track;
		mlt_position position;
		int ( *invalid )( mlt_frame ) = type == 1 ? mlt_frame_is_test_card : mlt_frame_is_test_audio;

		// Initialise temporary store
		if ( self->frames == NULL )
			self->frames = calloc( b_track + 1, sizeof( mlt_frame ) );

		// Get all frames between a and b
		for( i = a_track; i <= b_track; i ++ )
			mlt_service_get_frame( self->producer, &self->frames[ i ], i );

		// We're holding these frames until the last_track frame property is received
		self->held = 1;

		// When we need to locate the a_frame
		switch( type )
		{
			case 1:
			case 2:
				// Some transitions (esp. audio) may accept blank frames
				active = accepts_blanks;

				// If we're not active then...
				if ( !active )
				{
					// Hunt for the a_frame
					while( a_frame <= b_frame && invalid( self->frames[ a_frame ] ) )
						a_frame ++;

					// Determine if we're active now
					active = a_frame != b_frame && !invalid( self->frames[ b_frame ] );
				}
				break;

			default:
				mlt_log( service, MLT_LOG_ERROR, "invalid transition type\n" );
				break;
		}

		// Now handle the non-always active case
		if ( active && !always_active && a_frame <= b_track )
		{
			// For non-always-active transitions, we need the current position of the a frame
			position = mlt_frame_get_position( self->frames[ a_frame ] );

			// If a is in range, we're active
			active = position >= in && ( out == 0 || position <= out );
		}

		// Finally, process the a and b frames
		if ( active && !mlt_properties_get_int( MLT_TRANSITION_PROPERTIES( self ), "disable" ) )
		{
			int frame_nb = ( !reverse_order && a_frame <= b_track )? a_frame : b_frame;
			mlt_frame a_frame_ptr = self->frames[ frame_nb ];
			frame_nb = ( !reverse_order || a_frame > b_track )? b_frame : a_frame;
			mlt_frame b_frame_ptr = self->frames[ frame_nb ];
			int a_hide = mlt_properties_get_int( MLT_FRAME_PROPERTIES( a_frame_ptr ), "hide" );
			int b_hide = mlt_properties_get_int( MLT_FRAME_PROPERTIES( b_frame_ptr ), "hide" );
			if ( !( a_hide & type ) && !( b_hide & type ) )
			{
				// Add hooks for pre-processing frames
				mlt_frame_push_service( a_frame_ptr, self );
				mlt_frame_push_get_image( a_frame_ptr, get_image_a );
				mlt_frame_push_frame( b_frame_ptr, a_frame_ptr );
				mlt_frame_push_service( b_frame_ptr, self );
				mlt_frame_push_get_image( b_frame_ptr, get_image_b );

				// Process the transition
				*frame = mlt_transition_process( self, a_frame_ptr, b_frame_ptr );

				// We need to ensure that the tractor doesn't consider this frame for output
				if ( *frame == a_frame_ptr )
					b_hide |= type;
				else
					a_hide |= type;

				mlt_properties_set_int( MLT_FRAME_PROPERTIES( a_frame_ptr ), "hide", a_hide );
				mlt_properties_set_int( MLT_FRAME_PROPERTIES( b_frame_ptr ), "hide", b_hide );
			}
		}
	}

	// Obtain the frame from the cache or the producer we're attached to
	if ( index >= a_track && index <= b_track )
		*frame = self->frames[ index ];
	else
		error = mlt_service_get_frame( self->producer, frame, index );

	// Determine if that was the last track
	self->held = !mlt_properties_get_int( MLT_FRAME_PROPERTIES( *frame ), "last_track" );

	return error;
}