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