Hi,

i was testing a recording from decklink into the avformat consumer with simple code:

#include <stdio.h>
#include <unistd.h>
#include <framework/mlt.h>

int main( int argc, char *argv[] )
{
    mlt_consumer consumer;
    mlt_producer producer;
    mlt_profile profile;
    mlt_repository repo;

    repo = mlt_factory_init(NULL);

    mlt_log_set_level(MLT_LOG_DEBUG);

    // Initialise the factory
    if(repo) {
        profile = mlt_profile_init("dv_pal");
        producer = mlt_factory_producer(profile, "decklink", "0");
        if(!producer)
            fprintf(stderr, "ERROR: Failed to create producer\n");
        else {
consumer = mlt_factory_consumer(profile, "avformat", "mlt_rec_01.mov");
            if(!consumer)
                fprintf(stderr, "ERROR: Failed to create consumer\n");
            else {
mlt_properties consumer_properties = mlt_consumer_properties(consumer); mlt_properties_set(consumer_properties, "properties", "DV"); mlt_consumer_connect(consumer, mlt_producer_service(producer));
                mlt_consumer_start(consumer);
                fprintf(stderr, "press any key to stop");
//                getchar();
                mlt_consumer_stop(consumer);
                fprintf(stderr, "\nstopped\n");
                mlt_consumer_close(consumer);
            };
            mlt_producer_close(producer);
        };
        mlt_factory_close();
    }
    else
        fprintf(stderr, "ERROR: Unable to locate factory modules\n" );

    return 0;
};


but that cause a SIGSEGV:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffeb243700 (LWP 568)]
flush_cluster_buffer (s=0x7fffe400b2e0) at libavformat/movenc.c:2210
2210        for (i=0; i<mov->nb_streams; i++){
Missing separate debuginfos, use: debuginfo-install SDL-1.2.14-11.fc14.x86_64 alsa-lib-1.0.24-1.fc14.x86_64 cairo-1.10.2-1.fc14.x86_64 expat-2.0.1-10.fc13.x86_64 fontconfig-2.8.0-2.fc14.x86_64 freetype-2.4.2-5.fc14.x86_64 gdk-pixbuf2-2.22.0-2.fc14.x86_64 glib2-2.26.0-2.fc14.x86_64 glibc-2.13-2.x86_64 gsm-1.0.13-2.fc12.x86_64 gtk2-2.22.0-2.fc14.x86_64 libX11-1.3.4-4.fc14.x86_64 libXau-1.0.6-1.fc14.x86_64 libXcomposite-0.4.2-1.fc14.x86_64 libXcursor-1.1.10-5.fc14.x86_64 libXdamage-1.1.3-1.fc14.x86_64 libXext-1.1.2-2.fc14.x86_64 libXfixes-4.0.5-1.fc14.x86_64 libXi-1.3.2-1.fc14.x86_64 libXinerama-1.1-2.fc13.x86_64 libXrandr-1.3.0-5.fc13.x86_64 libXrender-0.9.6-1.fc14.x86_64 libdv-1.0.0-9.fc13.x86_64 libgcc-4.5.1-4.fc14.x86_64 libgomp-4.5.1-4.fc14.x86_64 libogg-1.2.0-1.fc14.x86_64 libpng-1.2.46-1.fc14.x86_64 libselinux-2.0.96-6.fc14.1.x86_64 libstdc++-4.5.1-4.fc14.x86_64 libtheora-1.1.1-1.fc13.x86_64 libtool-ltdl-2.2.10-3.fc14.x86_64 libvorbis-1.3.1-2.fc14.x86_64 libxcb-1.7-1.fc14.x86_64 libxml2-2.7.7-3.fc14.x86_64 pango-1.28.1-5.fc14.x86_64 pixman-0.18.4-1.fc14.x86_64 sox-14.3.2-1.fc14.x86_64 speex-1.2-0.12.rc1.fc12.x86_64 zlib-1.2.5-2.fc14.x86_64
(gdb) bt
#0  flush_cluster_buffer (s=0x7fffe400b2e0) at libavformat/movenc.c:2210
#1 0x00007fffef2edb37 in mov_write_trailer (s=<value optimized out>) at libavformat/movenc.c:2645 #2 0x00007fffef34af06 in av_write_trailer (s=0x7fffe400b2e0) at libavformat/utils.c:3562 #3 0x00007fffef5ab9a2 in consumer_thread (arg=0x693bf0) at consumer_avformat.c:1872
#4  0x0000003a71006ccb in start_thread () from /lib64/libpthread.so.0
#5  0x0000003a70ce0c2d in clone () from /lib64/libc.so.6

wrong test code where mlt_consumer_stop was called immediately after mlt_consumer_start caused that sideeffect.

to resolve such condition i attached a patch that properly determinate consumer's thread finish and avoid writing /trailer/ if no /header was written..


--
________________________________________
Maksym Veremeyenko
>From 467bbee676c7347f6e4fbe8774c9d282d8ad607e Mon Sep 17 00:00:00 2001
From: Maksym Veremeyenko <ve...@m1stereo.tv>
Date: Mon, 16 Jan 2012 14:03:25 +0200
Subject: [PATCH] fix thread exit on error and thread termination

---
 src/modules/avformat/consumer_avformat.c |   38 ++++++++++++++++++++---------
 1 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/src/modules/avformat/consumer_avformat.c b/src/modules/avformat/consumer_avformat.c
index 07e80ea..5665ba9 100644
--- a/src/modules/avformat/consumer_avformat.c
+++ b/src/modules/avformat/consumer_avformat.c
@@ -352,7 +352,7 @@ static int consumer_start( mlt_consumer consumer )
 			mlt_properties_set_int( properties, "frequency", mlt_properties_get_int( properties, "ar" ) );
 
 		// Assign the thread to properties
-		mlt_properties_set_data( properties, "thread", thread, sizeof( pthread_t ), free, NULL );
+		mlt_properties_set_int64( properties, "thread", (uint64_t)thread);
 
 		// Set the running state
 		mlt_properties_set_int( properties, "running", 1 );
@@ -371,17 +371,23 @@ static int consumer_stop( mlt_consumer consumer )
 	// Get the properties
 	mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer );
 
+	// Get the thread
+	pthread_t *thread = (pthread_t *)mlt_properties_get_int64( properties, "thread" );
+
 	// Check that we're running
-	if ( mlt_properties_get_int( properties, "running" ) )
+	if ( thread )
 	{
-		// Get the thread
-		pthread_t *thread = mlt_properties_get_data( properties, "thread", NULL );
-
 		// Stop the thread
 		mlt_properties_set_int( properties, "running", 0 );
 
 		// Wait for termination
 		pthread_join( *thread, NULL );
+
+		// free thread var
+		free(thread);
+
+		// set null prop
+		mlt_properties_set_int64( properties, "thread", 0);
 	}
 
 	return 0;
@@ -1031,6 +1037,8 @@ static void write_transmitter( mlt_listener listener, mlt_properties owner, mlt_
 
 static void *consumer_thread( void *arg )
 {
+	int err = 0;
+
 	// Map the argument to the object
 	mlt_consumer consumer = arg;
 
@@ -1389,12 +1397,12 @@ static void *consumer_thread( void *arg )
 #endif
 			{
 				mlt_log_error( MLT_CONSUMER_SERVICE( consumer ), "Could not open '%s'\n", filename );
-				mlt_properties_set_int( properties, "running", 0 );
+				err++;
 			}
 		}
 	
 		// Write the stream header.
-		if ( mlt_properties_get_int( properties, "running" ) )
+		if ( !err )
 #if LIBAVFORMAT_VERSION_INT >= ((53<<16)+(2<<8)+0)
 			avformat_write_header( oc, NULL );
 #else
@@ -1405,18 +1413,22 @@ static void *consumer_thread( void *arg )
 	else
 	{
 		mlt_log_error( MLT_CONSUMER_SERVICE( consumer ), "Invalid output format parameters\n" );
-		mlt_properties_set_int( properties, "running", 0 );
+		err++;
 	}
 #endif
 
+	// Last check - need at least one stream
+	if ( !audio_st[0] && !video_st && !err )
+		err++;
+
+	// any initialization errors happens
+	if ( err )
+		goto on_init_error;
+
 	// Allocate picture
 	if ( video_st )
 		output = alloc_picture( video_st->codec->pix_fmt, width, height );
 
-	// Last check - need at least one stream
-	if ( !audio_st[0] && !video_st )
-		mlt_properties_set_int( properties, "running", 0 );
-
 	// Get the starting time (can ignore the times above)
 	gettimeofday( &ante, NULL );
 
@@ -1871,6 +1883,8 @@ on_fatal_error:
 	// Write the trailer, if any
 	av_write_trailer( oc );
 
+on_init_error:
+
 	// close each codec
 	if ( video_st )
 		close_video(oc, video_st);
-- 
1.7.4.4

------------------------------------------------------------------------------
RSA(R) Conference 2012
Mar 27 - Feb 2
Save $400 by Jan. 27
Register now!
http://p.sf.net/sfu/rsa-sfdev2dev2
_______________________________________________
Mlt-devel mailing list
Mlt-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mlt-devel

Reply via email to