X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmodules%2Fdecklink%2Fconsumer_decklink.cpp;h=e6323a181cb69462ae30e90082b37786b223fc67;hb=b0e27fe79ba477055ce7d7deab212f1449c062ac;hp=b6b5fa59bbcaf95466be99e0293517425e804a06;hpb=59de3fb9545b4fbc30305f270526c4ef4689c5ef;p=mlt diff --git a/src/modules/decklink/consumer_decklink.cpp b/src/modules/decklink/consumer_decklink.cpp index b6b5fa59..e6323a18 100644 --- a/src/modules/decklink/consumer_decklink.cpp +++ b/src/modules/decklink/consumer_decklink.cpp @@ -17,6 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#define __STDC_FORMAT_MACROS /* see inttypes.h */ #include #include #include @@ -54,6 +55,9 @@ private: int m_isKeyer; IDeckLinkKeyer* m_deckLinkKeyer; bool m_terminate_on_pause; + uint32_t m_preroll; + uint32_t m_acnt; + bool m_reprio; IDeckLinkDisplayMode* getDisplayMode() { @@ -199,7 +203,7 @@ public: // Set the keyer if ( m_deckLinkKeyer && ( m_isKeyer = mlt_properties_get_int( properties, "keyer" ) ) ) { - bool external = (m_isKeyer == 2); + bool external = ( m_isKeyer == 2 ); double level = mlt_properties_get_double( properties, "keyer_level" ); if ( m_deckLinkKeyer->Enable( external ) != S_OK ) @@ -213,7 +217,7 @@ public: } // Set the video output mode - if ( S_OK != m_deckLinkOutput->EnableVideoOutput( m_displayMode->GetDisplayMode(), bmdVideoOutputFlagDefault) ) + if ( S_OK != m_deckLinkOutput->EnableVideoOutput( m_displayMode->GetDisplayMode(), bmdVideoOutputFlagDefault ) ) { mlt_log_error( getConsumer(), "Failed to enable video output\n" ); return false; @@ -233,6 +237,9 @@ public: return false; } + m_preroll = preroll; + m_reprio = false; + // preroll frames for( i = 0; i < preroll; i++ ) ScheduleNextFrame( true ); @@ -281,7 +288,12 @@ public: { uint32_t written = 0; BMDTimeValue streamTime = m_count * frequency * m_duration / m_timescale; - + m_deckLinkOutput->GetBufferedAudioSampleFrameCount( &written ); + if ( written > (m_preroll + 1) * samples ) + { + mlt_log_verbose( getConsumer(), "renderAudio: will flush %d audiosamples\n", written ); + m_deckLinkOutput->FlushBufferedAudioSamples(); + }; #ifdef WIN32 m_deckLinkOutput->ScheduleAudioSamples( pcm, samples, streamTime, frequency, (unsigned long*) &written ); #else @@ -429,19 +441,71 @@ public: virtual HRESULT STDMETHODCALLTYPE ScheduledFrameCompleted( IDeckLinkVideoFrame* completedFrame, BMDOutputFrameCompletionResult completed ) { + if( !m_reprio ) + { + mlt_properties properties = MLT_CONSUMER_PROPERTIES( getConsumer() ); + + 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( getConsumer(), + "ScheduledFrameCompleted: pthread_setschedparam retured %d\n", r); + else + mlt_log_verbose( getConsumer(), + "ScheduledFrameCompleted: param.sched_priority=%d\n", param.sched_priority); + }; + + m_reprio = true; + }; + + uint32_t cnt; + m_deckLinkOutput->GetBufferedAudioSampleFrameCount( &cnt ); + if ( cnt != m_acnt ) + { + mlt_log_verbose( getConsumer(), + "ScheduledFrameCompleted: GetBufferedAudioSampleFrameCount %u -> %u, m_count=%"PRIu64"\n", + m_acnt, cnt, m_count ); + m_acnt = cnt; + } + // When a video frame has been released by the API, schedule another video frame to be output // ignore handler if frame was flushed - if(bmdOutputFrameFlushed == completed) + if ( bmdOutputFrameFlushed == completed ) return S_OK; // schedule next frame - ScheduleNextFrame(false); + ScheduleNextFrame( false ); // step forward frames counter if underrun - if(bmdOutputFrameDisplayedLate == completed) + if ( bmdOutputFrameDisplayedLate == completed ) + { + mlt_log_verbose( getConsumer(), "ScheduledFrameCompleted: bmdOutputFrameDisplayedLate == completed\n" ); + m_count++; + } + if ( bmdOutputFrameDropped == completed ) { - mlt_log_verbose( getConsumer(), "ScheduledFrameCompleted: bmdOutputFrameDisplayedLate == completed\n"); + mlt_log_verbose( getConsumer(), "ScheduledFrameCompleted: bmdOutputFrameDropped == completed\n" ); m_count++; } @@ -454,7 +518,7 @@ public: } - void ScheduleNextFrame(bool preroll) + void ScheduleNextFrame( bool preroll ) { // get the consumer mlt_consumer consumer = getConsumer(); @@ -475,8 +539,8 @@ public: mlt_events_fire( properties, "consumer-frame-show", frame, NULL ); // terminate on pause - if (m_terminate_on_pause && - mlt_properties_get_double( MLT_FRAME_PROPERTIES( frame ), "_speed" ) == 0.0) + if ( m_terminate_on_pause && + mlt_properties_get_double( MLT_FRAME_PROPERTIES( frame ), "_speed" ) == 0.0 ) stop(); mlt_frame_close( frame );