* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#define __STDC_FORMAT_MACROS /* see inttypes.h */
#include <framework/mlt.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <limits.h>
+#ifdef WIN32
+#include <objbase.h>
+#include "DeckLinkAPI_h.h"
+#else
#include "DeckLinkAPI.h"
+#endif
static const unsigned PREROLL_MINIMUM = 3;
int m_isKeyer;
IDeckLinkKeyer* m_deckLinkKeyer;
bool m_terminate_on_pause;
+ uint32_t m_preroll;
+ uint32_t m_acnt;
IDeckLinkDisplayMode* getDisplayMode()
{
bool open( unsigned card = 0 )
{
- IDeckLinkIterator* deckLinkIterator = CreateDeckLinkIteratorInstance();
unsigned i = 0;
+#ifdef WIN32
+ IDeckLinkIterator* deckLinkIterator = NULL;
+ HRESULT result = CoInitialize( NULL );
+ if ( FAILED( result ) )
+ {
+ mlt_log_error( getConsumer(), "COM initialization failed\n" );
+ return false;
+ }
+ result = CoCreateInstance( CLSID_CDeckLinkIterator, NULL, CLSCTX_ALL, IID_IDeckLinkIterator, (void**) &deckLinkIterator );
+ if ( FAILED( result ) )
+ {
+ mlt_log_error( getConsumer(), "The DeckLink drivers not installed.\n" );
+ return false;
+ }
+#else
+ IDeckLinkIterator* deckLinkIterator = CreateDeckLinkIteratorInstance();
if ( !deckLinkIterator )
{
mlt_log_error( getConsumer(), "The DeckLink drivers not installed.\n" );
return false;
}
+#endif
// Connect to the Nth DeckLink instance
do {
m_deckLinkKeyer = 0;
if ( m_deckLink->QueryInterface( IID_IDeckLinkAttributes, (void**) &deckLinkAttributes ) == S_OK )
{
+#ifdef WIN32
+ BOOL flag = FALSE;
+#else
bool flag = false;
+#endif
if ( deckLinkAttributes->GetFlag( BMDDeckLinkSupportsInternalKeying, &flag ) == S_OK && flag )
{
if ( m_deckLink->QueryInterface( IID_IDeckLinkKeyer, (void**) &m_deckLinkKeyer ) != S_OK )
return false;
}
+ m_preroll = preroll;
+
// preroll frames
for( i = 0; i < preroll; i++ )
ScheduleNextFrame( true );
if ( !mlt_frame_get_audio( frame, (void**) &pcm, &format, &frequency, &m_channels, &samples ) )
{
uint32_t written = 0;
-
- m_deckLinkOutput->ScheduleAudioSamples( pcm, samples, m_count * frequency / m_fps, frequency, &written );
-
- if ( written != samples )
- mlt_log_verbose( getConsumer(), "renderAudio: samples=%d, written=%d\n", samples, written );
+ 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
+ m_deckLinkOutput->ScheduleAudioSamples( pcm, samples, streamTime, frequency, &written );
+#endif
+
+ if ( written != (uint32_t) samples )
+ mlt_log_verbose( getConsumer(), "renderAudio: samples=%d, written=%u\n", samples, written );
}
}
// Normal non-keyer playout - needs byte swapping
if ( !progressive && m_displayMode->GetFieldDominance() == bmdUpperFieldFirst )
// convert lower field first to top field first
- swab( image, buffer + stride, stride * ( m_height - 1 ) );
+ swab( (char*) image, (char*) buffer + stride, stride * ( m_height - 1 ) );
else
- swab( image, buffer, stride * m_height );
+ swab( (char*) image, (char*) buffer, stride * m_height );
}
else if ( !mlt_properties_get_int( MLT_FRAME_PROPERTIES( frame ), "test_image" ) )
{
virtual HRESULT STDMETHODCALLTYPE ScheduledFrameCompleted( IDeckLinkVideoFrame* completedFrame, BMDOutputFrameCompletionResult completed )
{
+ 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
mlt_log_verbose( getConsumer(), "ScheduledFrameCompleted: bmdOutputFrameDisplayedLate == completed\n");
m_count++;
}
+ if(bmdOutputFrameDropped == completed)
+ {
+ mlt_log_verbose( getConsumer(), "ScheduledFrameCompleted: bmdOutputFrameDropped == completed\n");
+ m_count++;
+ }
return S_OK;
}