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