X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmodules%2Fdecklink%2Fproducer_decklink.cpp;h=877c0eacc400742e3ea686e92eb3b2613b74f94e;hb=307a2ef3af84a5dba60a5026a1a24f430a0e0bf2;hp=5682a713b58dd3458d9d0c6e7b1350c5cf9a05d5;hpb=2762a88436a78e235bf0e11586c14a5fd3b4eec9;p=mlt diff --git a/src/modules/decklink/producer_decklink.cpp b/src/modules/decklink/producer_decklink.cpp index 5682a713..877c0eac 100644 --- a/src/modules/decklink/producer_decklink.cpp +++ b/src/modules/decklink/producer_decklink.cpp @@ -24,14 +24,7 @@ #include #include #include -#ifdef WIN32 -#include -#include "DeckLinkAPI_h.h" -#else -#include "DeckLinkAPI.h" -#endif - -#define SAFE_RELEASE(V) if (V) { V->Release(); V = NULL; } +#include "common.h" class DeckLinkProducer : public IDeckLinkInputCallback @@ -50,6 +43,7 @@ private: int m_colorspace; int m_vancLines; mlt_cache m_cache; + bool m_reprio; BMDDisplayMode getDisplayMode( mlt_profile profile, int vancLines ) { @@ -74,7 +68,7 @@ private: if ( width == profile->width && p == profile->progressive && ( height + vancLines == profile->height || ( height == 486 && profile->height == 480 + vancLines ) ) - && fps == mlt_profile_fps( profile ) ) + && (int) fps == (int) mlt_profile_fps( profile ) ) result = mode->GetDisplayMode(); SAFE_RELEASE( mode ); } @@ -94,11 +88,12 @@ public: DeckLinkProducer() { + m_producer = NULL; m_decklink = NULL; m_decklinkInput = NULL; } - ~DeckLinkProducer() + virtual ~DeckLinkProducer() { if ( m_queue ) { @@ -249,6 +244,8 @@ public: pthread_mutex_unlock( &m_mutex ); m_decklinkInput->StopStreams(); + m_decklinkInput->DisableVideoInput(); + m_decklinkInput->DisableAudioInput(); // Cleanup queue pthread_mutex_lock( &m_mutex ); @@ -259,12 +256,11 @@ public: mlt_frame getFrame() { - mlt_frame frame = NULL; struct timeval now; struct timespec tm; double fps = mlt_producer_get_fps( getProducer() ); mlt_position position = mlt_producer_position( getProducer() ); - mlt_cache_item cached = mlt_cache_get( m_cache, (void*) position ); + mlt_frame frame = mlt_cache_get_frame( m_cache, position ); // Allow the buffer to fill to the requested initial buffer level. if ( m_isBuffering ) @@ -289,13 +285,7 @@ public: pthread_mutex_unlock( &m_mutex ); } - if ( cached ) - { - // Copy cached frame instead of pulling from queue - frame = mlt_frame_clone( (mlt_frame) mlt_cache_item_data( cached, NULL ), 0 ); - mlt_cache_item_close( cached ); - } - else + if ( !frame ) { // Wait if queue is empty pthread_mutex_lock( &m_mutex ); @@ -316,8 +306,10 @@ public: // add to cache if ( frame ) - mlt_cache_put( m_cache, (void*) position, mlt_frame_clone( frame, 1 ), 0, - (mlt_destructor) mlt_frame_close ); + { + mlt_frame_set_position( frame, position ); + mlt_cache_put_frame( m_cache, frame ); + } } // Set frame timestamp and properties @@ -366,6 +358,43 @@ public: IDeckLinkVideoInputFrame* video, IDeckLinkAudioInputPacket* audio ) { + if( !m_reprio ) + { + mlt_properties properties = MLT_PRODUCER_PROPERTIES( getProducer() ); + + if ( mlt_properties_get( properties, "priority" ) ) + { + int r; + pthread_t thread; + pthread_attr_t tattr; + struct sched_param param; + + pthread_attr_init(&tattr); + pthread_attr_setschedpolicy(&tattr, SCHED_FIFO); + + if ( !strcmp( "max", mlt_properties_get( properties, "priority" ) ) ) + param.sched_priority = sched_get_priority_max(SCHED_FIFO) - 1; + else if ( !strcmp( "min", mlt_properties_get( properties, "priority" ) ) ) + param.sched_priority = sched_get_priority_min(SCHED_FIFO) + 1; + else + param.sched_priority = mlt_properties_get_int( properties, "priority" ); + + pthread_attr_setschedparam(&tattr, ¶m); + + thread = pthread_self(); + + r = pthread_setschedparam(thread, SCHED_FIFO, ¶m); + if( r ) + mlt_log_verbose( getProducer(), + "VideoInputFrameArrived: pthread_setschedparam returned %d\n", r); + else + mlt_log_verbose( getProducer(), + "VideoInputFrameArrived: param.sched_priority=%d\n", param.sched_priority); + }; + + m_reprio = true; + }; + if ( mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( getProducer() ), "preview" ) && mlt_producer_get_speed( getProducer() ) == 0.0 && !mlt_deque_count( m_queue )) { @@ -403,7 +432,7 @@ public: for ( int i = 1; i < m_vancLines + 1; i++ ) { if ( vanc->GetBufferForVerticalBlankingLine( i, &buffer ) == S_OK ) - swab( (char*) buffer, (char*) image + ( i - 1 ) * video->GetRowBytes(), video->GetRowBytes() ); + swab2( (char*) buffer, (char*) image + ( i - 1 ) * video->GetRowBytes(), video->GetRowBytes() ); else mlt_log_debug( getProducer(), "failed capture vanc line %d\n", i ); } @@ -416,7 +445,7 @@ public: if ( image && buffer ) { size = video->GetRowBytes() * video->GetHeight(); - swab( (char*) buffer, (char*) image + m_vancLines * video->GetRowBytes(), size ); + swab2( (char*) buffer, (char*) image + m_vancLines * video->GetRowBytes(), size ); mlt_frame_set_image( frame, (uint8_t*) image, size, mlt_pool_release ); } else if ( image ) @@ -436,19 +465,16 @@ public: IDeckLinkTimecode* timecode = 0; if ( video->GetTimecode( bmdTimecodeVITC, &timecode ) == S_OK && timecode ) { - const char* timecodeString = 0; + DLString timecodeString = 0; -#ifdef WIN32 - if ( timecode->GetString( (BSTR*) &timecodeString ) == S_OK ) -#else if ( timecode->GetString( &timecodeString ) == S_OK ) -#endif { - mlt_properties_set( MLT_FRAME_PROPERTIES( frame ), "meta.attr.vitc.markup", timecodeString ); - mlt_log_debug( getProducer(), "timecode %s\n", timecodeString ); + char* s = getCString( timecodeString ); + mlt_properties_set( MLT_FRAME_PROPERTIES( frame ), "meta.attr.vitc.markup", s ); + mlt_log_debug( getProducer(), "timecode %s\n", s ); + freeCString( s ); } - if ( timecodeString ) - free( (void*) timecodeString ); + freeDLString( timecodeString ); SAFE_RELEASE( timecode ); } } @@ -500,7 +526,7 @@ public: { mlt_frame_close( frame ); mlt_properties_set_int( MLT_PRODUCER_PROPERTIES( getProducer() ), "dropped", ++m_dropped ); - mlt_log_warning( getProducer(), "frame dropped %d\n", m_dropped ); + mlt_log_warning( getProducer(), "buffer overrun, frame dropped %d\n", m_dropped ); } pthread_mutex_unlock( &m_mutex ); } @@ -609,7 +635,6 @@ static int get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ) *frame = mlt_frame_init( MLT_PRODUCER_SERVICE(producer) ); // Calculate the next timecode - mlt_frame_set_position( *frame, mlt_producer_position( producer ) ); mlt_producer_prepare_next( producer ); // Close DeckLink if at end @@ -658,16 +683,18 @@ static void on_property_changed( void*, mlt_properties properties, const char *n { if ( decklink->QueryInterface( IID_IDeckLinkInput, (void**) &decklinkInput ) == S_OK ) { - char *name = NULL; - if ( decklink->GetModelName( (const char**) &name ) == S_OK ) + DLString name = NULL; + if ( decklink->GetModelName( &name ) == S_OK ) { + char *name_cstr = getCString( name ); const char *format = "device.%d"; char *key = (char*) calloc( 1, strlen( format ) + 1 ); sprintf( key, format, i ); - mlt_properties_set( properties, key, name ); + mlt_properties_set( properties, key, name_cstr ); free( key ); - free( name ); + freeDLString( name ); + freeCString( name_cstr ); } SAFE_RELEASE( decklinkInput ); }