From edce14a421c21c1a190ade2d16d74753fa0c0511 Mon Sep 17 00:00:00 2001 From: Maksym Veremeyenko Date: Mon, 19 Mar 2012 20:53:32 -0700 Subject: [PATCH] Initialize all decklink interface pointers and reset them upon release. Also, add a couple of missing releases. --- src/modules/decklink/consumer_decklink.cpp | 83 ++++++++++++---------- src/modules/decklink/producer_decklink.cpp | 55 ++++++++------ 2 files changed, 78 insertions(+), 60 deletions(-) diff --git a/src/modules/decklink/consumer_decklink.cpp b/src/modules/decklink/consumer_decklink.cpp index 8645506b..288e52f2 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 @@ -64,8 +66,8 @@ private: IDeckLinkDisplayMode* getDisplayMode() { mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( getConsumer() ) ); - IDeckLinkDisplayModeIterator* iter; - IDeckLinkDisplayMode* mode; + IDeckLinkDisplayModeIterator* iter = NULL; + IDeckLinkDisplayMode* mode = NULL; IDeckLinkDisplayMode* result = 0; if ( m_deckLinkOutput->GetDisplayModeIterator( &iter ) == S_OK ) @@ -83,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; @@ -92,15 +97,21 @@ private: public: mlt_consumer getConsumer() { return &m_consumer; } - + + DeckLinkConsumer() + { + m_displayMode = NULL; + 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_displayMode ); + SAFE_RELEASE( m_deckLinkKeyer ); + SAFE_RELEASE( m_deckLinkOutput ); + SAFE_RELEASE( m_deckLink ); } bool listDevices( mlt_properties properties ) @@ -137,11 +148,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 +160,7 @@ public: } catch ( const char *error ) { - if ( decklinkIterator ) - decklinkIterator->Release(); + SAFE_RELEASE( decklinkIterator ); mlt_log_error( getConsumer(), "%s\n", error ); return false; } @@ -182,30 +192,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 +230,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 +351,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 +440,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 b3a3c8a8..93489091 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 { @@ -51,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 ) @@ -74,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; @@ -88,6 +92,12 @@ public: mlt_producer getProducer() const { return m_producer; } + DeckLinkProducer() + { + m_decklink = NULL; + m_decklinkInput = NULL; + } + ~DeckLinkProducer() { if ( m_queue ) @@ -98,10 +108,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 +145,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 +180,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 +212,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 +254,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 +457,7 @@ public: else mlt_log_debug( getProducer(), "failed capture vanc line %d\n", i ); } - vanc->Release(); + SAFE_RELEASE(vanc); } } @@ -488,7 +499,7 @@ public: } if ( timecodeString ) free( (void*) timecodeString ); - timecode->Release(); + SAFE_RELEASE( timecode ); } } else -- 2.39.2