// Listen for the list_devices property to be set static void on_property_changed( void*, mlt_properties properties, const char *name ) { IDeckLinkIterator* decklinkIterator = NULL; IDeckLink* decklink = NULL; IDeckLinkInput* decklinkInput = NULL; int i = 0; if ( name && !strcmp( name, "list_devices" ) ) mlt_event_block( (mlt_event) mlt_properties_get_data( properties, "list-devices-event", NULL ) ); else return; #ifdef WIN32 if ( FAILED( CoInitialize( NULL ) ) ) return; if ( FAILED( CoCreateInstance( CLSID_CDeckLinkIterator, NULL, CLSCTX_ALL, IID_IDeckLinkIterator, (void**) &decklinkIterator ) ) ) return; #else if ( !( decklinkIterator = CreateDeckLinkIteratorInstance() ) ) return; #endif for ( ; decklinkIterator->Next( &decklink ) == S_OK; i++ ) { if ( decklink->QueryInterface( IID_IDeckLinkInput, (void**) &decklinkInput ) == 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_cstr ); free( key ); freeDLString( name ); freeCString( name_cstr ); } SAFE_RELEASE( decklinkInput ); } SAFE_RELEASE( decklink ); } SAFE_RELEASE( decklinkIterator ); mlt_properties_set_int( properties, "devices", i ); }
static void apply_profile_properties( mlt_consumer self, mlt_profile profile, mlt_properties properties ) { mlt_event_block( self->event_listener ); mlt_properties_set_double( properties, "fps", mlt_profile_fps( profile ) ); mlt_properties_set_int( properties, "frame_rate_num", profile->frame_rate_num ); mlt_properties_set_int( properties, "frame_rate_den", profile->frame_rate_den ); mlt_properties_set_int( properties, "width", profile->width ); mlt_properties_set_int( properties, "height", profile->height ); mlt_properties_set_int( properties, "progressive", profile->progressive ); mlt_properties_set_double( properties, "aspect_ratio", mlt_profile_sar( profile ) ); mlt_properties_set_int( properties, "sample_aspect_num", profile->sample_aspect_num ); mlt_properties_set_int( properties, "sample_aspect_den", profile->sample_aspect_den ); mlt_properties_set_double( properties, "display_ratio", mlt_profile_dar( profile ) ); mlt_properties_set_int( properties, "display_aspect_num", profile->display_aspect_num ); mlt_properties_set_int( properties, "display_aspect_num", profile->display_aspect_num ); mlt_properties_set_int( properties, "colorspace", profile->colorspace ); mlt_event_unblock( self->event_listener ); }
int mlt_consumer_start( mlt_consumer self ) { if ( !mlt_consumer_is_stopped( self ) ) return 0; // Stop listening to the property-changed event mlt_event_block( self->event_listener ); // Get the properies mlt_properties properties = MLT_CONSUMER_PROPERTIES( self ); // Determine if there's a test card producer char *test_card = mlt_properties_get( properties, "test_card" ); // Just to make sure nothing is hanging around... pthread_mutex_lock( &self->put_mutex ); self->put = NULL; self->put_active = 1; pthread_mutex_unlock( &self->put_mutex ); // Deal with it now. if ( test_card != NULL ) { if ( mlt_properties_get_data( properties, "test_card_producer", NULL ) == NULL ) { // Create a test card producer mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( self ) ); mlt_producer producer = mlt_factory_producer( profile, NULL, test_card ); // Do we have a producer if ( producer != NULL ) { // Test card should loop I guess... mlt_properties_set( MLT_PRODUCER_PROPERTIES( producer ), "eof", "loop" ); //mlt_producer_set_speed( producer, 0 ); //mlt_producer_set_in_and_out( producer, 0, 0 ); // Set the test card on the consumer mlt_properties_set_data( properties, "test_card_producer", producer, 0, ( mlt_destructor )mlt_producer_close, NULL ); } } } else { // Allow the hash table to speed things up mlt_properties_set_data( properties, "test_card_producer", NULL, 0, NULL, NULL ); } // The profile could have changed between a stop and a restart. apply_profile_properties( self, mlt_service_profile( MLT_CONSUMER_SERVICE(self) ), properties ); // Set the frame duration in microseconds for the frame-dropping heuristic int frame_rate_num = mlt_properties_get_int( properties, "frame_rate_num" ); int frame_rate_den = mlt_properties_get_int( properties, "frame_rate_den" ); int frame_duration = 0; if ( frame_rate_num && frame_rate_den ) { frame_duration = 1000000 / frame_rate_num * frame_rate_den; } mlt_properties_set_int( properties, "frame_duration", frame_duration ); // Check and run an ante command if ( mlt_properties_get( properties, "ante" ) ) if ( system( mlt_properties_get( properties, "ante" ) ) == -1 ) mlt_log( MLT_CONSUMER_SERVICE( self ), MLT_LOG_ERROR, "system(%s) failed!\n", mlt_properties_get( properties, "ante" ) ); // Set the real_time preference self->real_time = mlt_properties_get_int( properties, "real_time" ); // For worker threads implementation, buffer must be at least # threads if ( abs( self->real_time ) > 1 && mlt_properties_get_int( properties, "buffer" ) <= abs( self->real_time ) ) mlt_properties_set_int( properties, "_buffer", abs( self->real_time ) + 1 ); // Get the image format to use for rendering threads const char* format = mlt_properties_get( properties, "mlt_image_format" ); if ( format ) { if ( !strcmp( format, "rgb24" ) ) self->format = mlt_image_rgb24; else if ( !strcmp( format, "rgb24a" ) ) self->format = mlt_image_rgb24a; else if ( !strcmp( format, "yuv420p" ) ) self->format = mlt_image_yuv420p; else if ( !strcmp( format, "none" ) ) self->format = mlt_image_none; else self->format = mlt_image_yuv422; } // Start the service if ( self->start != NULL ) return self->start( self ); return 0; }