13.05.13 21:21, Dan Dennedy написав(ла):
On Mon, May 13, 2013 at 9:58 AM, Maksym Veremeyenko<ve...@m1stereo.tv>  wrote:
Hi,

could anybody give me advice on how to play with speed 0.1 ... 0.9 or
another non-integer speed value.

mlt_types.h has very interesting lines code:
[...]
/* I don't want to break anyone's applications without warning. -Zach */
#undef DOUBLE_MLT_POSITION
#ifdef DOUBLE_MLT_POSITION
typedef double mlt_position;
#else
typedef int32_t mlt_position;
#endif
[...]

that define to use integer type for position, so any float speed values
would be truncated to int value:

void mlt_producer_prepare_next( mlt_producer self )
{
if ( mlt_producer_get_speed( self ) != 0 )
mlt_producer_seek( self, mlt_producer_position( self ) +
mlt_producer_get_speed( self ) );
}

so first possible approach would be define DOUBLE_MLT_POSITION, but
could it break MLT?

Yes, it is an interesting unused code that I should probably remove.
It quite likely will break all sorts of things; it is certainly not as
simple a switch as it appears. :-) You are completely on your own
should you choose to use it as I know nothing about it. Of course, you
can go all in and get something working here and feel free to share
your fork for review and merge.

i did a change to make mlt_position type double (patch attached) and it seems it working fine for me currently. at least it playback clips and speed could be changed from [0..1] range easy.

i will try to do more tests next day.

i think it would be usefull to add an option to configure for controlling macro DOUBLE_MLT_POSITION definition.

i found producer_slowmotion that sounds like proper solution but i have
no glue how to use it. Could anybody give me a code sample that show how
to use playlist and slowmotion producer?


And that producer is basically useless as well because the resulting
image quality is so poor. It attempted to use macroblock motion
estimation to do fast frame interpolation. If you just want to repeat
or drop frames, then take a look at the framebuffer producer (as used
by kdenlive's speed effect). Please be aware that this does not convey
the encapsulated producer's audio.

framebuffer:some.mp4?0.5
speed<  0 : reverse
0<  abs(speed)<  1.0 : slow
1.0<  abs(speed) : fast
could you give a hint on how to use playlist producer and framebuffer producer with C-code?


--
________________________________________
Maksym Veremeyenko
>From 4948bc16263d42366e7595f244f70ea98c7bfab3 Mon Sep 17 00:00:00 2001
From: Maksym Veremeyenko <ve...@m1stereo.tv>
Date: Tue, 14 May 2013 11:28:10 +0300
Subject: [PATCH] make mlt_position type double

---
 src/framework/mlt_consumer.c                |    2 +-
 src/framework/mlt_frame.c                   |    2 +-
 src/framework/mlt_types.h                   |    6 +++++-
 src/modules/avformat/producer_avformat.c    |    2 +-
 src/modules/avsync/consumer_blipflash.c     |    4 ++--
 src/modules/core/filter_luma.c              |    6 +++---
 src/modules/dgraft/filter_telecide.c        |    8 ++++----
 src/modules/gtk2/producer_count.c           |    8 ++++----
 src/modules/kdenlive/producer_framebuffer.c |    2 +-
 src/modules/xine/filter_deinterlace.c       |    2 +-
 10 files changed, 23 insertions(+), 19 deletions(-)

diff --git a/src/framework/mlt_consumer.c b/src/framework/mlt_consumer.c
index f9eb806..2791a01 100644
--- a/src/framework/mlt_consumer.c
+++ b/src/framework/mlt_consumer.c
@@ -990,7 +990,7 @@ static void *consumer_worker_thread( void *arg )
 		frame = mlt_deque_peek( priv->queue, index );
 		if ( frame )
 		{
-			mlt_log_debug( MLT_CONSUMER_SERVICE(self), "worker processing index = %d frame %d queue count = %d\n",
+			mlt_log_debug( MLT_CONSUMER_SERVICE(self), "worker processing index = %d frame " MLT_POSITION_FMT " queue count = %d\n",
 				index, mlt_frame_get_position(frame), mlt_deque_count( priv->queue ) );
 			frame->is_processing = 1;
 			mlt_properties_inc_ref( MLT_FRAME_PROPERTIES( frame ) );
diff --git a/src/framework/mlt_frame.c b/src/framework/mlt_frame.c
index 988b310..7c8b5f8 100644
--- a/src/framework/mlt_frame.c
+++ b/src/framework/mlt_frame.c
@@ -982,7 +982,7 @@ void mlt_frame_write_ppm( mlt_frame frame )
 		FILE *file;
 		char filename[16];
 		
-		sprintf( filename, "frame-%05d.ppm", mlt_frame_get_position( frame ) );
+		sprintf( filename, "frame-%05d.ppm", (int)mlt_frame_get_position( frame ) );
 		file = fopen( filename, "wb" );
 		if ( !file )
 			return;
diff --git a/src/framework/mlt_types.h b/src/framework/mlt_types.h
index c1574d4..764c0c4 100644
--- a/src/framework/mlt_types.h
+++ b/src/framework/mlt_types.h
@@ -103,10 +103,14 @@ typedef enum
 mlt_service_type;
 
 /* I don't want to break anyone's applications without warning. -Zach */
-#undef DOUBLE_MLT_POSITION
+#define DOUBLE_MLT_POSITION
 #ifdef DOUBLE_MLT_POSITION
+#define MLT_POSITION_FMT "%f"
+#define MLT_POSITION_MOD(A, B) (A - B * ((int)(A / B)))
 typedef double mlt_position;
 #else
+#define MLT_POSITION_MOD(A, B) A % B
+#define MLT_POSITION_FMT "%d"
 typedef int32_t mlt_position;
 #endif
 
diff --git a/src/modules/avformat/producer_avformat.c b/src/modules/avformat/producer_avformat.c
index de9b44f..a3c7e4a 100644
--- a/src/modules/avformat/producer_avformat.c
+++ b/src/modules/avformat/producer_avformat.c
@@ -939,7 +939,7 @@ static int seek_video( producer_avformat self, mlt_position position,
 				timestamp -= 2 / av_q2d( self->video_time_base );
 			if ( timestamp < 0 )
 				timestamp = 0;
-			mlt_log_debug( MLT_PRODUCER_SERVICE(producer), "seeking timestamp %"PRId64" position %d expected %d last_pos %"PRId64"\n",
+			mlt_log_debug( MLT_PRODUCER_SERVICE(producer), "seeking timestamp %"PRId64" position " MLT_POSITION_FMT " expected "MLT_POSITION_FMT" last_pos %"PRId64"\n",
 				timestamp, position, self->video_expected, self->last_position );
 
 			// Seek to the timestamp
diff --git a/src/modules/avsync/consumer_blipflash.c b/src/modules/avsync/consumer_blipflash.c
index 5de8a55..8c8faa5 100644
--- a/src/modules/avsync/consumer_blipflash.c
+++ b/src/modules/avsync/consumer_blipflash.c
@@ -324,13 +324,13 @@ static void report_results( avsync_stats* stats, mlt_position pos )
 	{
 		if( stats->sample_offset == INT_MAX )
 		{
-			fprintf( stats->out_file, "%d\t??\n", pos );
+			fprintf( stats->out_file, MLT_POSITION_FMT "\t??\n", pos );
 		}
 		else
 		{
 			// Convert to milliseconds.
 			double ms_offset = (double)stats->sample_offset * 1000.0 / (double)SAMPLE_FREQ;
-			fprintf( stats->out_file, "%d\t%02.02f\n", pos, ms_offset );
+			fprintf( stats->out_file, MLT_POSITION_FMT "\t%02.02f\n", pos, ms_offset );
 		}
 	}
 	stats->blip = 0;
diff --git a/src/modules/core/filter_luma.c b/src/modules/core/filter_luma.c
index 71af836..37ceeb4 100644
--- a/src/modules/core/filter_luma.c
+++ b/src/modules/core/filter_luma.c
@@ -76,8 +76,8 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
 		}
 	}
 
-	mlt_position modulo_pos = position % out;
-	mlt_log_debug( MLT_FILTER_SERVICE(filter), "pos %d mod period %d\n", position, modulo_pos );
+	mlt_position modulo_pos = MLT_POSITION_MOD(position, out);
+	mlt_log_debug( MLT_FILTER_SERVICE(filter), "pos " MLT_POSITION_FMT " mod period " MLT_POSITION_FMT "\n", position, modulo_pos );
 	if ( luma != NULL &&
 	     ( mlt_properties_get( properties, "blur" ) != NULL ||
 		   ( position >= duration && modulo_pos < duration - 1 ) ) )
@@ -103,7 +103,7 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
 
 		if ( dst != NULL )
 		{
-			mlt_log_debug( MLT_FILTER_SERVICE(filter), "copying frame %d\n", modulo_pos );
+			mlt_log_debug( MLT_FILTER_SERVICE(filter), "copying frame " MLT_POSITION_FMT "\n", modulo_pos );
 			mlt_properties b_props = MLT_FRAME_PROPERTIES( b_frame );
 			memcpy( dst, src, size );
 			mlt_frame_set_image( b_frame, dst, size, mlt_pool_release );
diff --git a/src/modules/dgraft/filter_telecide.c b/src/modules/dgraft/filter_telecide.c
index 545def2..ab63b87 100644
--- a/src/modules/dgraft/filter_telecide.c
+++ b/src/modules/dgraft/filter_telecide.c
@@ -786,7 +786,7 @@ static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format
 		uint8_t *image_copy = mlt_pool_alloc( image_size );
 		memcpy( image_copy, *image, image_size );
 		char key[20];
-		sprintf( key, "%d", pos );
+		sprintf( key, MLT_POSITION_FMT, pos );
 		mlt_properties_set_data( cx->image_cache, key, image_copy, image_size, (mlt_destructor)mlt_pool_release, NULL );
 		
 		// Only if we have enough frame images cached
@@ -794,7 +794,7 @@ static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format
 		{
 			pos -= cx->cycle + 1;
 			// Get the current frame image
-			sprintf( key, "%d", pos );
+			sprintf( key, MLT_POSITION_FMT, pos );
 			cx->fcrp = mlt_properties_get_data( cx->image_cache, key, NULL );
 			if (!cx->fcrp) return error;
 			 
@@ -1148,7 +1148,7 @@ static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format
 
 final:			
 			// Flush frame at tail of period from the cache
-			sprintf( key, "%d", pos - 1 );
+			sprintf( key, MLT_POSITION_FMT, pos - 1 );
 			mlt_properties_set_data( cx->image_cache, key, NULL, 0, NULL, NULL );
 		}
 		else
@@ -1159,7 +1159,7 @@ final:
 	}
 	else if ( error == 0 && *format == mlt_image_yuv420p )
 	{
-		fprintf(stderr,"%s: %d pos %d\n", __FUNCTION__, *width * *height * 3/2, mlt_frame_get_position(frame) );
+		fprintf(stderr,"%s: %d pos " MLT_POSITION_FMT "\n", __FUNCTION__, *width * *height * 3/2, mlt_frame_get_position(frame) );
 	}
 
 	return error;
diff --git a/src/modules/gtk2/producer_count.c b/src/modules/gtk2/producer_count.c
index 7e8c2c9..40ee1a4 100644
--- a/src/modules/gtk2/producer_count.c
+++ b/src/modules/gtk2/producer_count.c
@@ -217,7 +217,7 @@ static mlt_frame get_text_frame( mlt_producer producer, mlt_position position )
 
 		// Calculate clock values
 		int seconds = position / fps;
-		int frames = position % fps;
+		int frames = MLT_POSITION_MOD(position, fps);
 		int minutes = seconds / 60;
 		seconds = seconds % 60;
 		int hours = minutes / 60;
@@ -226,7 +226,7 @@ static mlt_frame get_text_frame( mlt_producer producer, mlt_position position )
 		// Apply the time style
 		if( !strcmp( style, "frames" ) )
 		{
-			snprintf( text, MAX_TEXT_LEN - 1, "%d", position );
+			snprintf( text, MAX_TEXT_LEN - 1, MLT_POSITION_FMT, position );
 		}
 		else if( !strcmp( style, "timecode" ) )
 		{
@@ -464,12 +464,12 @@ static void add_clock_to_frame( mlt_producer producer, mlt_frame frame, mlt_posi
 	if( !strcmp( direction, "down" ) )
 	{
 		int out = mlt_producer_get_out( producer );
-		int frames = fps - (( out - position ) % fps);
+		int frames = fps - MLT_POSITION_MOD(out - position, fps);
 		clock_angle = lrint( (frames + 1) * 360 / fps );
 	}
 	else
 	{
-		int frames = position % fps;
+		int frames = MLT_POSITION_MOD(position, fps);
 		clock_angle = lrint( (frames + 1) * 360 / fps );
 	}
 
diff --git a/src/modules/kdenlive/producer_framebuffer.c b/src/modules/kdenlive/producer_framebuffer.c
index bad5005..e478072 100644
--- a/src/modules/kdenlive/producer_framebuffer.c
+++ b/src/modules/kdenlive/producer_framebuffer.c
@@ -74,7 +74,7 @@ static int framebuffer_get_image( mlt_frame frame, uint8_t **image, mlt_image_fo
 		{
 			// Strobe effect wanted, calculate frame position
 			need_first = floor( actual_position );
-			need_first -= need_first % strobe;
+			need_first -= MLT_POSITION_MOD(need_first, strobe);
 		}
 		if ( freeze )
 		{
diff --git a/src/modules/xine/filter_deinterlace.c b/src/modules/xine/filter_deinterlace.c
index 34e763c..70457e9 100644
--- a/src/modules/xine/filter_deinterlace.c
+++ b/src/modules/xine/filter_deinterlace.c
@@ -111,7 +111,7 @@ static int deinterlace_yadif( mlt_frame frame, mlt_filter filter, uint8_t **imag
 	int next_width = *width;
 	int next_height = *height;
 	
-	mlt_log_debug( MLT_FILTER_SERVICE(filter), "previous %d current %d next %d\n",
+	mlt_log_debug( MLT_FILTER_SERVICE(filter), "previous " MLT_POSITION_FMT " current " MLT_POSITION_FMT " next " MLT_POSITION_FMT "\n",
 		previous_frame? mlt_frame_original_position(previous_frame) : -1,
 		mlt_frame_original_position(frame),
 		next_frame?  mlt_frame_original_position(next_frame) : -1);
-- 
1.7.7.6

------------------------------------------------------------------------------
AlienVault Unified Security Management (USM) platform delivers complete
security visibility with the essential security capabilities. Easily and
efficiently configure, manage, and operate all of your security controls
from a single console and one unified framework. Download a free trial.
http://p.sf.net/sfu/alienvault_d2d
_______________________________________________
Mlt-devel mailing list
Mlt-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mlt-devel

Reply via email to