Hi,

after recent patch for decklink producer and consumer i found a strange behavior when first decklink working in play mode (process X) and second decklink works in play-record-play mode (process Y).

Either some race condition or kind of deadlock happens on a driver level. For some reason code line:

126 if ( m_deckLink->QueryInterface( IID_IDeckLinkOutput, (void**) &m_deckLinkOutput ) == S_OK )

start thread:

(gdb) bt
#0  0x0000003ec22e8217 in ioctl () from /lib64/libc.so.6
#1 0x00007f1946d0743c in WaitForNotificationEvents () from /usr/lib64/libDeckLinkAPI.so #2 0x00007f1946ca2633 in CDeckLinkOutput::DriverNotificationThread() () from /usr/lib64/libDeckLinkAPI.so #3 0x00007f1946ca2709 in CDeckLinkOutput::DriverNotificationThreadFunction(void*) ()
   from /usr/lib64/libDeckLinkAPI.so
#4  0x0000003ec2607d90 in start_thread () from /lib64/libpthread.so.0
#5  0x0000003ec22ef48d in clone () from /lib64/libc.so.6

that stall next line that release m_deckLinkOutput:

#0  0x0000003ec2609080 in pthread_join () from /lib64/libpthread.so.0
#1 0x00007f8346a37b04 in CDeckLinkOutput::~CDeckLinkOutput() () from /usr/lib64/libDeckLinkAPI.so #2 0x00007f8346a20cca in CDeckLink::~CDeckLink() () from /usr/lib64/libDeckLinkAPI.so #3 0x00007f8346a2072f in CDeckLink::Release() () from /usr/lib64/libDeckLinkAPI.so #4 0x00007f8346a48c01 in CDeckLink_v8_0::~CDeckLink_v8_0() () from /usr/lib64/libDeckLinkAPI.so #5 0x00007f8346a48ea7 in CDeckLink_v8_0::Release() () from /usr/lib64/libDeckLinkAPI.so #6 0x00007f834e1ee5cb in listDevices (properties=0x7f82ec016768, this=0x7f82ec016760)
    at consumer_decklink.cpp:142

First i revised all decklink pointers for any leak:
    0001-care-about-NULL-pointers.patch

but that do not helps, so i checked mode iteration loop:
    0002-make-sure-all-is-release-in-mode-iteration-loop.patch

but the cure was to disable device listing:
    0003-make-device-listing-only-if-list_devices-property-se.patch

i dont know if it driver bug or some arch specific behaviour, but that patches is an only way for me to provide stable decklink operation...

--
________________________________________
Maksym Veremeyenko
>From 5ec0801c361a58628038c0ed9b334ae5086c36fc Mon Sep 17 00:00:00 2001
From: Maksym Veremeyenko <[email protected]>
Date: Sat, 17 Mar 2012 15:53:40 +0100
Subject: [PATCH 1/3] care about NULL pointers

---
 src/modules/decklink/consumer_decklink.cpp |   74 ++++++++++++++-------------
 src/modules/decklink/producer_decklink.cpp |   49 +++++++++++--------
 2 files changed, 67 insertions(+), 56 deletions(-)

diff --git a/src/modules/decklink/consumer_decklink.cpp b/src/modules/decklink/consumer_decklink.cpp
index 8645506..dceccdc 100644
--- a/src/modules/decklink/consumer_decklink.cpp
+++ b/src/modules/decklink/consumer_decklink.cpp
@@ -33,6 +33,8 @@
 #include "DeckLinkAPI.h"
 #endif
 
+#define SAFE_RELEASE(V) if (V) { V->Release(); V = NULL; }
+
 static const unsigned PREROLL_MINIMUM = 3;
 
 class DeckLinkConsumer
@@ -92,15 +94,19 @@ private:
 public:
 	mlt_consumer getConsumer()
 		{ return &m_consumer; }
-	
+
+	DeckLinkConsumer()
+	{
+		m_deckLinkKeyer = NULL;
+		m_deckLinkOutput = NULL;
+		m_deckLink = NULL;
+	}
+
 	~DeckLinkConsumer()
 	{
-		if ( m_deckLinkKeyer )
-			m_deckLinkKeyer->Release();
-		if ( m_deckLinkOutput )
-			m_deckLinkOutput->Release();
-		if ( m_deckLink )
-			m_deckLink->Release();
+		SAFE_RELEASE( m_deckLinkKeyer );
+		SAFE_RELEASE( m_deckLinkOutput );
+		SAFE_RELEASE( m_deckLink );
 	}
 	
 	bool listDevices( mlt_properties properties )
@@ -137,11 +143,11 @@ public:
 						free( key );
 						free( name );
 					}
-					m_deckLinkOutput->Release();
+					SAFE_RELEASE( m_deckLinkOutput );
 				}
-				m_deckLink->Release();
+				SAFE_RELEASE( m_deckLink );
 			}
-			decklinkIterator->Release();
+			SAFE_RELEASE( decklinkIterator );
 			mlt_properties_set_int( properties, "devices", i );
 			mlt_log_verbose( NULL, "[consumer decklink] devices = %d\n", i );
 
@@ -149,8 +155,7 @@ public:
 		}
 		catch ( const char *error )
 		{
-			if ( decklinkIterator )
-				decklinkIterator->Release();
+			SAFE_RELEASE( decklinkIterator );
 			mlt_log_error( getConsumer(), "%s\n", error );
 			return false;
 		}
@@ -182,30 +187,32 @@ public:
 			return false;
 		}
 #endif
-		
+
 		// Connect to the Nth DeckLink instance
-		do {
-			if ( deckLinkIterator->Next( &m_deckLink ) != S_OK )
-			{
-				mlt_log_error( getConsumer(), "DeckLink card not found\n" );
-				deckLinkIterator->Release();
-				return false;
-			}
-		} while ( ++i <= card );
-		deckLinkIterator->Release();
-		
+		for ( i = 0; deckLinkIterator->Next( &m_deckLink ) == S_OK ; i++)
+		{
+			if(i == card)
+				break;
+			else
+				SAFE_RELEASE( m_deckLink );
+		}
+		SAFE_RELEASE( deckLinkIterator );
+		if( !m_deckLink )
+		{
+			mlt_log_error( getConsumer(), "DeckLink card not found\n" );
+			return false;
+		}
+
 		// Obtain the audio/video output interface (IDeckLinkOutput)
 		if ( m_deckLink->QueryInterface( IID_IDeckLinkOutput, (void**)&m_deckLinkOutput ) != S_OK )
 		{
 			mlt_log_error( getConsumer(), "No DeckLink cards support output\n" );
-			m_deckLink->Release();
-			m_deckLink = 0;
+			SAFE_RELEASE( m_deckLink );
 			return false;
 		}
 		
 		// Get the keyer interface
 		IDeckLinkAttributes *deckLinkAttributes = 0;
-		m_deckLinkKeyer = 0;
 		if ( m_deckLink->QueryInterface( IID_IDeckLinkAttributes, (void**) &deckLinkAttributes ) == S_OK )
 		{
 #ifdef WIN32
@@ -218,14 +225,12 @@ public:
 				if ( m_deckLink->QueryInterface( IID_IDeckLinkKeyer, (void**) &m_deckLinkKeyer ) != S_OK )
 				{
 					mlt_log_error( getConsumer(), "Failed to get keyer\n" );
-					m_deckLinkOutput->Release();
-					m_deckLinkOutput = 0;
-					m_deckLink->Release();
-					m_deckLink = 0;
+					SAFE_RELEASE( m_deckLinkOutput );
+					SAFE_RELEASE( m_deckLink );
 					return false;
 				}
 			}
-			deckLinkAttributes->Release();
+			SAFE_RELEASE( deckLinkAttributes );
 		}
 
 		// Provide this class as a delegate to the audio and video output interfaces
@@ -341,9 +346,7 @@ public:
 		}
 
 		// release decklink frame
-		if ( m_decklinkFrame )
-			m_decklinkFrame->Release();
-		m_decklinkFrame = NULL;
+		SAFE_RELEASE( m_decklinkFrame );
 
 		if ( wasRunning )
 			pthread_join( m_prerollThread, NULL );
@@ -432,8 +435,7 @@ public:
 			uint8_t* buffer = 0;
 			int stride = m_width * ( m_isKeyer? 4 : 2 );
 
-			if ( m_decklinkFrame )
-				m_decklinkFrame->Release();
+			SAFE_RELEASE( m_decklinkFrame );
 			if ( createFrame( &m_decklinkFrame ) )
 				m_decklinkFrame->GetBytes( (void**) &buffer );
 
diff --git a/src/modules/decklink/producer_decklink.cpp b/src/modules/decklink/producer_decklink.cpp
index b3a3c8a..a75f522 100644
--- a/src/modules/decklink/producer_decklink.cpp
+++ b/src/modules/decklink/producer_decklink.cpp
@@ -31,6 +31,8 @@
 #include "DeckLinkAPI.h"
 #endif
 
+#define SAFE_RELEASE(V) if (V) { V->Release(); V = NULL; }
+
 class DeckLinkProducer
 	: public IDeckLinkInputCallback
 {
@@ -88,6 +90,12 @@ public:
 	mlt_producer getProducer() const
 		{ return m_producer; }
 
+	DeckLinkProducer()
+	{
+		m_decklink = NULL;
+		m_decklinkInput = NULL;
+	}
+
 	~DeckLinkProducer()
 	{
 		if ( m_queue )
@@ -98,10 +106,8 @@ public:
 			pthread_cond_destroy( &m_condition );
 			mlt_cache_close( m_cache );
 		}
-		if ( m_decklinkInput )
-			m_decklinkInput->Release();
-		if ( m_decklink )
-			m_decklink->Release();
+		SAFE_RELEASE( m_decklinkInput );
+		SAFE_RELEASE( m_decklink );
 	}
 
 	bool listDevices( mlt_properties properties )
@@ -137,18 +143,17 @@ public:
 						free( key );
 						free( name );
 					}
-					m_decklinkInput->Release();
+					SAFE_RELEASE( m_decklinkInput );
 				}
-				m_decklink->Release();
+				SAFE_RELEASE( m_decklink );
 			}
-			decklinkIterator->Release();
+			SAFE_RELEASE( decklinkIterator );
 			mlt_properties_set_int( properties, "devices", i );
 			return true;
 		}
 		catch ( const char *error )
 		{
-			if ( decklinkIterator )
-				decklinkIterator->Release();
+			SAFE_RELEASE( decklinkIterator );
 			mlt_log_error( getProducer(), "%s\n", error );
 			return false;
 		}
@@ -173,12 +178,16 @@ public:
 #endif
 
 			// Connect to the Nth DeckLink instance
-			unsigned i = 0;
-			do {
-				if ( decklinkIterator->Next( &m_decklink ) != S_OK )
-					throw "DeckLink card not found.";
-			} while ( ++i <= card );
-			decklinkIterator->Release();
+			for ( unsigned i = 0; decklinkIterator->Next( &m_decklink ) == S_OK ; i++)
+			{
+				if(i == card)
+					break;
+				else
+					SAFE_RELEASE( m_decklink );
+			}
+			SAFE_RELEASE( decklinkIterator );
+			if( !m_decklink )
+				throw "DeckLink card not found.";
 
 			// Get the input interface
 			if ( m_decklink->QueryInterface( IID_IDeckLinkInput, (void**) &m_decklinkInput ) != S_OK )
@@ -201,8 +210,8 @@ public:
 		}
 		catch ( const char *error )
 		{
-			if ( decklinkIterator )
-				decklinkIterator->Release();
+			SAFE_RELEASE( m_decklinkInput );
+			SAFE_RELEASE( m_decklink );
 			mlt_log_error( getProducer(), "%s\n", error );
 			return false;
 		}
@@ -243,7 +252,7 @@ public:
 			{
 				if ( decklinkAttributes->GetFlag( BMDDeckLinkSupportsInputFormatDetection, &doesDetectFormat ) != S_OK )
 					doesDetectFormat = false;
-				decklinkAttributes->Release();
+				SAFE_RELEASE( decklinkAttributes );
 			}
 			mlt_log_verbose( getProducer(), "%s format detection\n", doesDetectFormat ? "supports" : "does not support" );
 
@@ -446,7 +455,7 @@ public:
 							else
 								mlt_log_debug( getProducer(), "failed capture vanc line %d\n", i );
 						}
-						vanc->Release();
+						SAFE_RELEASE(vanc);
 					}
 				}
 
@@ -488,7 +497,7 @@ public:
 				}
 				if ( timecodeString )
 					free( (void*) timecodeString );
-				timecode->Release();
+				SAFE_RELEASE( timecode );
 			}
 		}
 		else
-- 
1.7.7.6

>From fc01a3efb28ca7557d311d1b523237fa046bd19e Mon Sep 17 00:00:00 2001
From: Maksym Veremeyenko <[email protected]>
Date: Mon, 19 Mar 2012 11:27:21 +0100
Subject: [PATCH 2/3] make sure all is release in mode iteration loop

---
 src/modules/decklink/consumer_decklink.cpp |    7 ++++++-
 src/modules/decklink/producer_decklink.cpp |    6 ++++--
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/src/modules/decklink/consumer_decklink.cpp b/src/modules/decklink/consumer_decklink.cpp
index dceccdc..700d221 100644
--- a/src/modules/decklink/consumer_decklink.cpp
+++ b/src/modules/decklink/consumer_decklink.cpp
@@ -66,7 +66,7 @@ private:
 	IDeckLinkDisplayMode* getDisplayMode()
 	{
 		mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( getConsumer() ) );
-		IDeckLinkDisplayModeIterator* iter;
+		IDeckLinkDisplayModeIterator* iter = NULL;
 		IDeckLinkDisplayMode* mode;
 		IDeckLinkDisplayMode* result = 0;
 		
@@ -85,7 +85,10 @@ private:
 					 && m_fps == mlt_profile_fps( profile )
 					 && ( m_height == profile->height || ( m_height == 486 && profile->height == 480 ) ) )
 					result = mode;
+				else
+					SAFE_RELEASE( mode );
 			}
+			SAFE_RELEASE( iter );
 		}
 		
 		return result;
@@ -97,6 +100,7 @@ public:
 
 	DeckLinkConsumer()
 	{
+		m_displayMode = NULL;
 		m_deckLinkKeyer = NULL;
 		m_deckLinkOutput = NULL;
 		m_deckLink = NULL;
@@ -104,6 +108,7 @@ public:
 
 	~DeckLinkConsumer()
 	{
+		SAFE_RELEASE( m_displayMode );
 		SAFE_RELEASE( m_deckLinkKeyer );
 		SAFE_RELEASE( m_deckLinkOutput );
 		SAFE_RELEASE( m_deckLink );
diff --git a/src/modules/decklink/producer_decklink.cpp b/src/modules/decklink/producer_decklink.cpp
index a75f522..146c73e 100644
--- a/src/modules/decklink/producer_decklink.cpp
+++ b/src/modules/decklink/producer_decklink.cpp
@@ -53,8 +53,8 @@ private:
 
 	BMDDisplayMode getDisplayMode( mlt_profile profile, int vancLines )
 	{
-		IDeckLinkDisplayModeIterator* iter;
-		IDeckLinkDisplayMode* mode;
+		IDeckLinkDisplayModeIterator* iter = NULL;
+		IDeckLinkDisplayMode* mode = NULL;
 		BMDDisplayMode result = (BMDDisplayMode) bmdDisplayModeNotSupported;
 
 		if ( m_decklinkInput->GetDisplayModeIterator( &iter ) == S_OK )
@@ -76,7 +76,9 @@ private:
 					 && ( height + vancLines == profile->height || ( height == 486 && profile->height == 480 + vancLines ) )
 					 && fps == mlt_profile_fps( profile ) )
 					result = mode->GetDisplayMode();
+				SAFE_RELEASE( mode );
 			}
+			SAFE_RELEASE( iter );
 		}
 
 		return result;
-- 
1.7.7.6

>From d557612ffc19aba2516ecfe7ca8d3d424fe78e33 Mon Sep 17 00:00:00 2001
From: Maksym Veremeyenko <[email protected]>
Date: Mon, 19 Mar 2012 11:33:12 +0100
Subject: [PATCH 3/3] make device listing only if list_devices property set

---
 src/modules/decklink/consumer_decklink.cpp |    3 +++
 src/modules/decklink/producer_decklink.cpp |    3 +++
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/src/modules/decklink/consumer_decklink.cpp b/src/modules/decklink/consumer_decklink.cpp
index 700d221..095dc29 100644
--- a/src/modules/decklink/consumer_decklink.cpp
+++ b/src/modules/decklink/consumer_decklink.cpp
@@ -116,6 +116,9 @@ public:
 	
 	bool listDevices( mlt_properties properties )
 	{
+		if ( !mlt_properties_get_int( properties, "list_devices" ) )
+			return true;
+
 		IDeckLinkIterator* decklinkIterator = NULL;
 		try
 		{
diff --git a/src/modules/decklink/producer_decklink.cpp b/src/modules/decklink/producer_decklink.cpp
index 146c73e..7612b46 100644
--- a/src/modules/decklink/producer_decklink.cpp
+++ b/src/modules/decklink/producer_decklink.cpp
@@ -114,6 +114,9 @@ public:
 
 	bool listDevices( mlt_properties properties )
 	{
+		if ( !mlt_properties_get_int( properties, "list_devices" ) )
+			return true;
+
 		IDeckLinkIterator* decklinkIterator = NULL;
 		try
 		{
-- 
1.7.7.6

------------------------------------------------------------------------------
This SF email is sponsosred by:
Try Windows Azure free for 90 days Click Here 
http://p.sf.net/sfu/sfd2d-msazure
_______________________________________________
Mlt-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mlt-devel

Reply via email to