: public IDeckLinkInputCallback
{
private:
- mlt_producer_s m_producer;
+ mlt_producer m_producer;
IDeckLink* m_decklink;
IDeckLinkInput* m_decklinkInput;
mlt_deque m_queue;
public:
- mlt_producer getProducer()
- { return &m_producer; }
+ void setProducer( mlt_producer producer )
+ { m_producer = producer; }
+
+ mlt_producer getProducer() const
+ { return m_producer; }
~DeckLinkProducer()
{
}
}
- bool open( mlt_profile profile, unsigned card = 0 )
+ bool open( unsigned card = 0 )
{
IDeckLinkIterator* decklinkIterator = NULL;
try
static int get_frame( mlt_producer producer, mlt_frame_ptr frame, int index )
{
DeckLinkProducer* decklink = (DeckLinkProducer*) producer->child;
+ mlt_position pos = mlt_producer_position( producer );
+ mlt_position end = mlt_producer_get_playtime( producer );
+ end = ( mlt_producer_get_length( producer ) < end ? mlt_producer_get_length( producer ) : end ) - 1;
+
+ // Re-open if needed
+ if ( !decklink && pos < end )
+ {
+ producer->child = decklink = new DeckLinkProducer();
+ decklink->setProducer( producer );
+ decklink->open( mlt_properties_get_int( MLT_PRODUCER_PROPERTIES(producer), "resource" ) );
+ }
// Start if needed
- decklink->start( mlt_service_profile( MLT_PRODUCER_SERVICE( producer ) ) );
+ if ( decklink )
+ {
+ decklink->start( mlt_service_profile( MLT_PRODUCER_SERVICE( producer ) ) );
- // Get the next frame from the decklink object
- *frame = decklink->getFrame();
+ // Get the next frame from the decklink object
+ if ( ( *frame = decklink->getFrame() ))
+ {
+ // Add audio and video getters
+ mlt_frame_push_audio( *frame, (void*) get_audio );
+ mlt_frame_push_get_image( *frame, get_image );
+ }
+ }
if ( !*frame )
- *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) );
+ *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 );
- // Add audio and video getters
- mlt_frame_push_audio( *frame, (void*) get_audio );
- mlt_frame_push_get_image( *frame, get_image );
+ // Close DeckLink if at end
+ if ( pos >= end && decklink )
+ {
+ decklink->stop();
+ delete decklink;
+ producer->child = NULL;
+ }
return 0;
}
static void producer_close( mlt_producer producer )
{
+ delete (DeckLinkProducer*) producer->child;
producer->close = NULL;
mlt_producer_close( producer );
- delete (DeckLinkProducer*) producer->child;
}
extern "C" {
{
// Allocate the producer
DeckLinkProducer* decklink = new DeckLinkProducer();
- mlt_producer producer = NULL;
+ mlt_producer producer = (mlt_producer) calloc( 1, sizeof( *producer ) );
// If allocated and initializes
- if ( decklink && !mlt_producer_init( decklink->getProducer(), decklink ) )
+ if ( decklink && !mlt_producer_init( producer, decklink ) )
{
- if ( decklink->open( profile, arg? atoi( arg ) : 0 ) )
+ if ( decklink->open( arg? atoi( arg ) : 0 ) )
{
- producer = decklink->getProducer();
mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer );
+ // Close DeckLink and defer re-open to get_frame
+ delete decklink;
+ producer->child = NULL;
+
// Set callbacks
producer->close = (mlt_destructor) producer_close;
producer->get_frame = get_frame;
// Set properties
- mlt_properties_set( properties, "resource", arg? arg : "0" );
+ mlt_properties_set( properties, "resource", (arg && strcmp( arg, ""))? arg : "0" );
mlt_properties_set_int( properties, "channels", 2 );
mlt_properties_set_int( properties, "buffer", 25 );
mlt_properties_set_int( properties, "prefill", 25 );