X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmodules%2Fdecklink%2Fproducer_decklink.cpp;h=93489091d8dc46955eceaf8ed8e727b3f4150e85;hb=edce14a421c21c1a190ade2d16d74753fa0c0511;hp=77ed44b2b864ecb2cea777b0b1fe74e4de93d20e;hpb=6a82bf3b0a78db9e38f1e7e940c3cff5972063fe;p=mlt diff --git a/src/modules/decklink/producer_decklink.cpp b/src/modules/decklink/producer_decklink.cpp index 77ed44b2..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,57 @@ 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 ) + { + IDeckLinkIterator* decklinkIterator = NULL; + try + { + int i = 0; +#ifdef WIN32 + HRESULT result = CoInitialize( NULL ); + if ( FAILED( result ) ) + throw "COM initialization failed"; + result = CoCreateInstance( CLSID_CDeckLinkIterator, NULL, CLSCTX_ALL, IID_IDeckLinkIterator, (void**) &decklinkIterator ); + if ( FAILED( result ) ) + throw "The DeckLink drivers are not installed."; +#else + decklinkIterator = CreateDeckLinkIteratorInstance(); + if ( !decklinkIterator ) + throw "The DeckLink drivers are not installed."; +#endif + for ( ; decklinkIterator->Next( &m_decklink ) == S_OK; i++ ) + { + if ( m_decklink->QueryInterface( IID_IDeckLinkInput, (void**) &m_decklinkInput ) == S_OK ) + { + char *name = NULL; + if ( m_decklink->GetModelName( (const char**) &name ) == S_OK ) + { + const char *format = "device.%d"; + char *key = (char*) calloc( 1, strlen( format ) + 1 ); + + sprintf( key, format, i ); + mlt_properties_set( properties, key, name ); + free( key ); + free( name ); + } + SAFE_RELEASE( m_decklinkInput ); + } + SAFE_RELEASE( m_decklink ); + } + SAFE_RELEASE( decklinkIterator ); + mlt_properties_set_int( properties, "devices", i ); + return true; + } + catch ( const char *error ) + { + SAFE_RELEASE( decklinkIterator ); + mlt_log_error( getProducer(), "%s\n", error ); + return false; + } } bool open( unsigned card = 0 ) @@ -123,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 ) @@ -151,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; } @@ -193,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" ); @@ -396,7 +457,7 @@ public: else mlt_log_debug( getProducer(), "failed capture vanc line %d\n", i ); } - vanc->Release(); + SAFE_RELEASE(vanc); } } @@ -438,7 +499,7 @@ public: } if ( timecodeString ) free( (void*) timecodeString ); - timecode->Release(); + SAFE_RELEASE( timecode ); } } else @@ -633,7 +694,8 @@ mlt_producer producer_decklink_init( mlt_profile profile, mlt_service_type type, // If allocated and initializes if ( decklink && !mlt_producer_init( producer, decklink ) ) { - if ( decklink->open( arg? atoi( arg ) : 0 ) ) + if ( decklink->listDevices( MLT_PRODUCER_PROPERTIES( producer ) ) && + decklink->open( arg? atoi( arg ) : 0 ) ) { mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer );