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; }
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; }
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; }
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; }
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; }