static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ) { if ( frame ) { // Construct a new frame *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) ); // Stack the producer and producer's get image mlt_frame_push_service_int( *frame, index ); mlt_frame_push_service( *frame, producer ); mlt_frame_push_service( *frame, framebuffer_get_image ); mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); mlt_properties frame_properties = MLT_FRAME_PROPERTIES(*frame); // Get frame from the real producer mlt_frame first_frame = mlt_properties_get_data( properties, "first_frame", NULL ); if ( first_frame == NULL ) { // Get the frame to cache from the real producer mlt_producer real_producer = mlt_properties_get_data( properties, "producer", NULL ); // Seek the producer to the correct place mlt_producer_seek( real_producer, mlt_producer_position( producer ) ); // Get the frame mlt_service_get_frame( MLT_PRODUCER_SERVICE( real_producer ), &first_frame, index ); // Cache the frame mlt_properties_set_data( properties, "first_frame", first_frame, 0, ( mlt_destructor )mlt_frame_close, NULL ); } mlt_properties_inherit( frame_properties, MLT_FRAME_PROPERTIES(first_frame) ); double force_aspect_ratio = mlt_properties_get_double( properties, "force_aspect_ratio" ); if ( force_aspect_ratio <= 0.0 ) force_aspect_ratio = mlt_properties_get_double( properties, "aspect_ratio" ); mlt_properties_set_double( frame_properties, "aspect_ratio", force_aspect_ratio ); // Give the returned frame temporal identity mlt_frame_set_position( *frame, mlt_producer_position( producer ) ); mlt_properties_set_int( frame_properties, "meta.media.width", mlt_properties_get_int( properties, "width" ) ); mlt_properties_set_int( frame_properties, "meta.media.height", mlt_properties_get_int( properties, "height" ) ); mlt_properties_pass_list( frame_properties, properties, "width, height" ); } return 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; }