示例#1
0
int mlt_animation_get_item( mlt_animation self, mlt_animation_item item, int position )
{
    int error = 0;
    // Need to find the nearest keyframe to the position specifed
    animation_node node = self->nodes;

    // Iterate through the keyframes until we reach last or have
    while ( node && node->next && position >= node->next->item.frame )
        node = node->next;

    if ( node )
    {
        item->keyframe_type = node->item.keyframe_type;

        // Position is before the first keyframe.
        if ( position < node->item.frame )
        {
            item->is_key = 0;
            if ( item->property )
                mlt_property_pass( item->property, node->item.property );
        }
        // Item exists.
        else if ( position == node->item.frame )
        {
            item->is_key = node->item.is_key;
            if ( item->property )
                mlt_property_pass( item->property, node->item.property );
        }
        // Position is after the last keyframe.
        else if ( !node->next )
        {
            item->is_key = 0;
            if ( item->property )
                mlt_property_pass( item->property, node->item.property );
        }
        // Interpolation needed.
        else
        {
            double progress;
            mlt_property points[4];
            points[0] = node->prev? node->prev->item.property : node->item.property;
            points[1] = node->item.property;
            points[2] = node->next->item.property;
            points[3] = node->next->next? node->next->next->item.property : node->next->item.property;
            progress = position - node->item.frame;
            progress /= node->next->item.frame - node->item.frame;
            mlt_property_interpolate( item->property, points, progress,
                                      self->fps, self->locale, item->keyframe_type );
            item->is_key = 0;
        }
    }
    else
    {
        item->frame = item->is_key = 0;
        error = 1;
    }
    item->frame = position;

    return error;
}
示例#2
0
void mlt_animation_interpolate( mlt_animation self )
{
	// Parse all items to ensure non-keyframes are calculated correctly.
	if ( self->nodes )
	{
		animation_node current = self->nodes;
		while ( current )
		{
			if ( !current->item.is_key )
			{
				double progress;
				mlt_property points[4];
				animation_node prev = current->prev;
				animation_node next = current->next;

				while ( prev && !prev->item.is_key ) prev = prev->prev;
				while ( next && !next->item.is_key ) next = next->next;

				if ( !prev ) {
					current->item.is_key = 1;
					prev = current;
				}
				if ( !next ) {
					next = current;
				}
				points[0] = prev->prev? prev->prev->item.property : prev->item.property;
				points[1] = prev->item.property;
				points[2] = next->item.property;
				points[3] = next->next? next->next->item.property : next->item.property;
				progress = current->item.frame - prev->item.frame;
				progress /= next->item.frame - prev->item.frame;
				mlt_property_interpolate( current->item.property, points, progress,
					self->fps, self->locale, current->item.keyframe_type );
			}

			// Move to the next item
			current = current->next;
		}
	}
}