static void init_devices (void) { IDeckLinkIterator *iterator; IDeckLink *decklink = NULL; HRESULT ret; int i; static gboolean inited = FALSE; if (inited) return; inited = TRUE; iterator = CreateDeckLinkIteratorInstance (); if (iterator == NULL) { GST_ERROR ("no driver"); return; } i = 0; ret = iterator->Next (&decklink); while (ret == S_OK) { devices[i].decklink = decklink; ret = decklink->QueryInterface (IID_IDeckLinkInput, (void **) &devices[i].input); if (ret != S_OK) { GST_WARNING ("selected device does not have input interface"); } ret = decklink->QueryInterface (IID_IDeckLinkOutput, (void **) &devices[i].output); if (ret != S_OK) { GST_WARNING ("selected device does not have output interface"); } ret = decklink->QueryInterface (IID_IDeckLinkConfiguration, (void **) &devices[i].config); if (ret != S_OK) { GST_WARNING ("selected device does not have config interface"); } ret = iterator->Next (&decklink); i++; if (i == 10) { GST_WARNING ("this hardware has more then 10 devices"); break; } } n_devices = i; iterator->Release(); }
void select_input_connection(unsigned int input) { IDeckLinkConfiguration *config; assert(deckLink != NULL); assert(input < sizeof(connections) / sizeof(struct decklink_connection)); if (deckLink->QueryInterface(IID_IDeckLinkConfiguration, (void**) &config) != S_OK) { throw std::runtime_error( "DeckLink input: get IDeckLinkConfiguration failed" ); } if (config->SetInt(bmdDeckLinkConfigVideoInputConnection, connections[input].connection) != S_OK) { throw std::runtime_error( "DeckLink input: set input connection failed" ); } fprintf(stderr, "DeckLink: input connection set to %s\n", connections[input].name); config->Release( ); }
void open_input(unsigned int norm) { IDeckLinkDisplayModeIterator *it; assert(deckLink != NULL); assert(norm < sizeof(norms) / sizeof(struct decklink_norm)); if (deckLink->QueryInterface(IID_IDeckLinkInput, (void **) &deckLinkInput) != S_OK) { throw std::runtime_error( "DeckLink input: failed to get IDeckLinkInput" ); } if (deckLinkInput->GetDisplayModeIterator(&it) != S_OK) { throw std::runtime_error( "DeckLink input: failed to get display mode iterator" ); } dominance = find_dominance(norms[norm].mode, it); it->Release( ); if (deckLinkInput->EnableVideoInput(norms[norm].mode, bpf, 0) != S_OK) { throw std::runtime_error( "DeckLink input: failed to enable video input" ); } fprintf(stderr, "DeckLink: opening input using norm %s\n", norms[norm].name); }
bool open( unsigned card = 0 ) { IDeckLinkIterator* decklinkIterator = NULL; try { #ifdef WIN32 HRESULT result = CoInitialize( NULL ); if ( FAILED( result ) ) throw "COM initialization failed"; result = CoCreateInstance( CLSID_CDeckLinkIterator, NULL, CLSCTX_ALL, IID_IDeckLinkIterator, (void**) &decklinkIterator ); if ( FAILED( result ) ) throw "The DeckLink drivers are not installed."; #else decklinkIterator = CreateDeckLinkIteratorInstance(); if ( !decklinkIterator ) throw "The DeckLink drivers are not installed."; #endif // Connect to the Nth DeckLink instance for ( unsigned i = 0; decklinkIterator->Next( &m_decklink ) == S_OK ; i++) { if ( i == card ) break; else SAFE_RELEASE( m_decklink ); } SAFE_RELEASE( decklinkIterator ); if ( !m_decklink ) throw "DeckLink card not found."; // Get the input interface if ( m_decklink->QueryInterface( IID_IDeckLinkInput, (void**) &m_decklinkInput ) != S_OK ) throw "No DeckLink cards support input."; // Provide this class as a delegate to the input callback m_decklinkInput->SetCallback( this ); // Initialize other members pthread_mutex_init( &m_mutex, NULL ); pthread_cond_init( &m_condition, NULL ); m_queue = mlt_deque_init(); m_started = false; m_dropped = 0; m_isBuffering = true; m_cache = mlt_cache_init(); // 3 covers YADIF and increasing framerate use cases mlt_cache_set_size( m_cache, 3 ); } catch ( const char *error ) { SAFE_RELEASE( m_decklinkInput ); SAFE_RELEASE( m_decklink ); mlt_log_error( getProducer(), "%s\n", error ); return false; } return true; }
void configure_card( ) { IDeckLinkConfiguration *config; assert(deckLink != NULL); if (deckLink->QueryInterface(IID_IDeckLinkConfiguration, (void**) &config) != S_OK) { throw std::runtime_error( "DeckLink output: get IDeckLinkConfiguration failed" ); } if (config->SetInt(bmdDeckLinkConfigLowLatencyVideoOutput, true) != S_OK) { fprintf(stderr, "DeckLink output: warning: " "cannot enable low-latency mode\n" ); } if (config->SetInt(bmdDeckLinkConfigVideoOutputConversionMode, bmdVideoOutputHardwareLetterboxDownconversion) != S_OK) { fprintf(stderr, "DeckLink output: warning: " "cannot enable hardware letterboxing\n"); } if (config->SetInt(bmdDeckLinkConfigBypass, -1) != S_OK) { fprintf(stderr, "DeckLink output: warning: " "cannot deactivate card bypass relay\n" ); } /* throw outputs at wall, see what sticks :) */ #if 0 config->SetInt(bmdDeckLinkConfigVideoOutputConnection, bmdVideoConnectionSDI); config->SetInt(bmdDeckLinkConfigVideoOutputConnection, bmdVideoConnectionHDMI); config->SetInt(bmdDeckLinkConfigVideoOutputConnection, bmdVideoConnectionComponent); config->SetInt(bmdDeckLinkConfigVideoOutputConnection, bmdVideoConnectionComposite); config->SetInt(bmdDeckLinkConfigVideoOutputConnection, bmdVideoConnectionSVideo); #endif config->Release( ); }
void VideoReceiverInterface::cameraFunction(bool useCompositeInput){ IDeckLink *deckLink; IDeckLinkInput *deckLinkInput; BMDVideoInputFlags inputFlags = 0; BMDDisplayMode displayMode; if (useCompositeInput){ displayMode = bmdModeNTSC; } else { displayMode = bmdModeHD1080i5994; } BMDPixelFormat pixelFormat = bmdFormat8BitYUV; IDeckLinkIterator *deckLinkIterator = CreateDeckLinkIteratorInstance(); DEBUG("Creating decklink iterator..."); if (deckLinkIterator == 0 ){ cerr << "\n\tUnable to create DeckLink Iterator. Video analysis will be disabled.\n\n"; return; } DEBUG("Creating decklink object..."); if ( deckLinkIterator->Next(&deckLink) != S_OK ) { Log::error("\n\tCould not create decklink object. Video analysis will be disabled\n"); return; } DEBUG("Querying decklink interface..."); if ( deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput) != S_OK ) { Log::error("\n\tCould not find a decklink interface. Video analysis will be disabled\n"); return; } DEBUG("Registering decklink input callback..."); if ( deckLinkInput->SetCallback(new VideoCallback(this)) != S_OK ) { Log::error("\n\tCould not set the decklink callback. Video analysis will be disabled\n"); return; } DEBUG("Enabling video input..."); if ( deckLinkInput->EnableVideoInput(displayMode,pixelFormat,inputFlags) != S_OK ) { Log::error("\n\tCould not enable video input. Video analysis will be disabled\n"); return; } DEBUG("Starting streams..."); if ( deckLinkInput->StartStreams() != S_OK ) { Log::error("\n\tCould not start streams. Video analysis will be disabled\n"); return; } }
// 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 ); }
QStringList BMDOutputDelegate::enumDeviceNames(bool forceReload) { if(!s_knownDevices.isEmpty()) { if(!forceReload) return s_knownDevices; else s_knownDevices.clear(); } IDeckLinkIterator *deckLinkIterator = CreateDeckLinkIteratorInstance(); if (deckLinkIterator == NULL) { fprintf(stderr, "BMDCaptureDelegate::enumDeviceNames: A DeckLink iterator could not be created. The DeckLink drivers may not be installed.\n"); return QStringList(); } IDeckLink *deckLink; IDeckLinkInput *deckLinkOutput; int index = 0; // Enumerate all cards in this system while (deckLinkIterator->Next(&deckLink) == S_OK) { if (deckLink->QueryInterface(IID_IDeckLinkOutput, (void**)&deckLinkOutput) == S_OK) { s_knownDevices << QString("bmd:%1").arg(index); deckLinkOutput->Release(); deckLinkOutput = NULL; } index ++; // Release the IDeckLink instance when we've finished with it to prevent leaks deckLink->Release(); } deckLinkIterator->Release(); return s_knownDevices; }
bool open( unsigned card = 0 ) { IDeckLinkIterator* deckLinkIterator = CreateDeckLinkIteratorInstance(); unsigned i = 0; if ( !deckLinkIterator ) { mlt_log_verbose( NULL, "The DeckLink drivers not installed.\n" ); return false; } // Connect to the Nth DeckLink instance do { if ( deckLinkIterator->Next( &m_deckLink ) != S_OK ) { mlt_log_verbose( NULL, "DeckLink card not found\n" ); deckLinkIterator->Release(); return false; } } while ( ++i <= card ); // Obtain the audio/video output interface (IDeckLinkOutput) if ( m_deckLink->QueryInterface( IID_IDeckLinkOutput, (void**)&m_deckLinkOutput ) != S_OK ) { mlt_log_verbose( NULL, "No DeckLink cards support output\n" ); m_deckLink->Release(); m_deckLink = 0; deckLinkIterator->Release(); return false; } // Provide this class as a delegate to the audio and video output interfaces m_deckLinkOutput->SetScheduledFrameCompletionCallback( this ); m_deckLinkOutput->SetAudioCallback( this ); pthread_mutex_init( &m_mutex, NULL ); pthread_cond_init( &m_condition, NULL ); m_maxAudioBuffer = bmdAudioSampleRate48kHz; m_videoFrameQ = mlt_deque_init(); return true; }
void open_card( ) { IDeckLinkDisplayModeIterator *it; /* get the DeckLinkOutput interface */ if (deckLink->QueryInterface(IID_IDeckLinkOutput, (void **)&deckLinkOutput) != S_OK) { throw std::runtime_error( "Failed to get DeckLink output interface handle" ); } if (deckLinkOutput->SetScheduledFrameCompletionCallback(this) != S_OK) { throw std::runtime_error( "Failed to set DeckLink frame completion callback" ); } /* attempt to determine field dominance */ if (deckLinkOutput->GetDisplayModeIterator(&it) != S_OK) { throw std::runtime_error( "DeckLink output: failed to get display mode iterator" ); } dominance = find_dominance(norms[norm].mode, it); it->Release( ); /* and we're off to the races */ if (deckLinkOutput->EnableVideoOutput(norms[norm].mode, bmdVideoOutputFlagDefault) != S_OK) { throw std::runtime_error( "Failed to enable DeckLink video output" ); } }
void select_audio_input_connection( ) { IDeckLinkConfiguration *config; assert(deckLink != NULL); if (deckLink->QueryInterface(IID_IDeckLinkConfiguration, (void**) &config) != S_OK) { throw std::runtime_error( "DeckLink input: get IDeckLinkConfiguration failed" ); } if (config->SetInt(bmdDeckLinkConfigAudioInputConnection, bmdAudioConnectionEmbedded) != S_OK) { throw std::runtime_error( "DeckLink input: set embedded audio input failed" ); } config->Release( ); }
void krad_decklink_capture_info () { IDeckLink *deckLink; IDeckLinkInput *deckLinkInput; IDeckLinkIterator *deckLinkIterator; IDeckLinkDisplayModeIterator *displayModeIterator; IDeckLinkDisplayMode *displayMode; HRESULT result; int displayModeCount; char *displayModeString; displayModeString = NULL; displayModeCount = 0; deckLinkIterator = CreateDeckLinkIteratorInstance(); if (!deckLinkIterator) { printke ("Krad Decklink: This application requires the DeckLink drivers installed.\n"); } /* Connect to the first DeckLink instance */ result = deckLinkIterator->Next(&deckLink); if (result != S_OK) { printke ("Krad Decklink: No DeckLink PCI cards found.\n"); } result = deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput); if (result != S_OK) { printke ("Krad Decklink: Fail QueryInterface\n"); } result = deckLinkInput->GetDisplayModeIterator(&displayModeIterator); if (result != S_OK) { printke ("Krad Decklink: Could not obtain the video output display mode iterator - result = %08x\n", result); } while (displayModeIterator->Next(&displayMode) == S_OK) { result = displayMode->GetName((const char **) &displayModeString); if (result == S_OK) { BMDTimeValue frameRateDuration, frameRateScale; displayMode->GetFrameRate(&frameRateDuration, &frameRateScale); printkd ("%2d: %-20s \t %li x %li \t %g FPS\n", displayModeCount, displayModeString, displayMode->GetWidth(), displayMode->GetHeight(), (double)frameRateScale / (double)frameRateDuration); free (displayModeString); displayModeCount++; } displayMode->Release(); } if (displayModeIterator != NULL) { displayModeIterator->Release(); displayModeIterator = NULL; } if (deckLinkInput != NULL) { deckLinkInput->Release(); deckLinkInput = NULL; } if (deckLink != NULL) { deckLink->Release(); deckLink = NULL; } if (deckLinkIterator != NULL) { deckLinkIterator->Release(); } }
int main(int argc, char *argv[]) { HRESULT result; int exitStatus = 1; int idx; IDeckLinkIterator* deckLinkIterator = NULL; IDeckLink* deckLink = NULL; IDeckLinkAttributes* deckLinkAttributes = NULL; bool formatDetectionSupported; IDeckLinkDisplayModeIterator* displayModeIterator = NULL; IDeckLinkDisplayMode* displayMode = NULL; char* displayModeName = NULL; BMDDisplayModeSupport displayModeSupported; DeckLinkCaptureDelegate* delegate = NULL; pthread_mutex_init(&g_sleepMutex, NULL); pthread_cond_init(&g_sleepCond, NULL); signal(SIGINT, sigfunc); signal(SIGTERM, sigfunc); signal(SIGHUP, sigfunc); // Network g_video_sock = socket(AF_INET, SOCK_STREAM, 0); g_video_addr.sin_family = AF_INET; g_video_addr.sin_port = htons(62310); g_video_addr.sin_addr.s_addr = inet_addr("192.168.100.31"); connect(g_video_sock, (struct sockaddr *)&g_video_addr, sizeof(g_video_addr)); g_audio_sock = socket(AF_INET, SOCK_STREAM, 0); g_audio_addr.sin_family = AF_INET; g_audio_addr.sin_port = htons(62311); g_audio_addr.sin_addr.s_addr = inet_addr("192.168.100.31"); connect(g_audio_sock, (struct sockaddr *)&g_audio_addr, sizeof(g_audio_addr)); // Process the command line arguments if (!g_config.ParseArguments(argc, argv)) { g_config.DisplayUsage(exitStatus); goto bail; } // Get the DeckLink device deckLinkIterator = CreateDeckLinkIteratorInstance(); if (!deckLinkIterator) { fprintf(stderr, "This application requires the DeckLink drivers installed.\n"); goto bail; } idx = g_config.m_deckLinkIndex; while ((result = deckLinkIterator->Next(&deckLink)) == S_OK) { if (idx == 0) break; --idx; deckLink->Release(); } if (result != S_OK || deckLink == NULL) { fprintf(stderr, "Unable to get DeckLink device %u\n", g_config.m_deckLinkIndex); goto bail; } // Get the input (capture) interface of the DeckLink device result = deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&g_deckLinkInput); if (result != S_OK) goto bail; // Get the display mode if (g_config.m_displayModeIndex == -1) { // Check the card supports format detection result = deckLink->QueryInterface(IID_IDeckLinkAttributes, (void**)&deckLinkAttributes); if (result == S_OK) { result = deckLinkAttributes->GetFlag(BMDDeckLinkSupportsInputFormatDetection, &formatDetectionSupported); if (result != S_OK || !formatDetectionSupported) { fprintf(stderr, "Format detection is not supported on this device\n"); goto bail; } } g_config.m_inputFlags |= bmdVideoInputEnableFormatDetection; // Format detection still needs a valid mode to start with idx = 0; } else { idx = g_config.m_displayModeIndex; } result = g_deckLinkInput->GetDisplayModeIterator(&displayModeIterator); if (result != S_OK) { goto bail; } while ((result = displayModeIterator->Next(&displayMode)) == S_OK) { if (idx == 0) { break; } --idx; displayMode->Release(); } if (result != S_OK || displayMode == NULL) { fprintf(stderr, "Unable to get display mode %d\n", g_config.m_displayModeIndex); goto bail; } // Get display mode name result = displayMode->GetName((const char**)&displayModeName); if (result != S_OK) { displayModeName = (char *)malloc(32); snprintf(displayModeName, 32, "[index %d]", g_config.m_displayModeIndex); } // Check display mode is supported with given options result = g_deckLinkInput->DoesSupportVideoMode(displayMode->GetDisplayMode(), g_config.m_pixelFormat, bmdVideoInputFlagDefault, &displayModeSupported, NULL); if (result != S_OK) goto bail; if (displayModeSupported == bmdDisplayModeNotSupported) { fprintf(stderr, "The display mode %s is not supported with the selected pixel format\n", displayModeName); goto bail; } if (g_config.m_inputFlags & bmdVideoInputDualStream3D) { if (!(displayMode->GetFlags() & bmdDisplayModeSupports3D)) { fprintf(stderr, "The display mode %s is not supported with 3D\n", displayModeName); goto bail; } } // Print the selected configuration g_config.DisplayConfiguration(); // Configure the capture callback delegate = new DeckLinkCaptureDelegate(); g_deckLinkInput->SetCallback(delegate); // Open output files // if (g_config.m_videoOutputFile != NULL) // { // g_videoOutputFile = open(g_config.m_videoOutputFile, O_WRONLY|O_CREAT|O_TRUNC, 0664); // if (g_videoOutputFile < 0) // { // fprintf(stderr, "Could not open video output file \"%s\"\n", g_config.m_videoOutputFile); // goto bail; // } // } // // if (g_config.m_audioOutputFile != NULL) // { // g_audioOutputFile = open(g_config.m_audioOutputFile, O_WRONLY|O_CREAT|O_TRUNC, 0664); // if (g_audioOutputFile < 0) // { // fprintf(stderr, "Could not open audio output file \"%s\"\n", g_config.m_audioOutputFile); // goto bail; // } // } // Block main thread until signal occurs while (!g_do_exit) { // Start capturing result = g_deckLinkInput->EnableVideoInput(displayMode->GetDisplayMode(), g_config.m_pixelFormat, g_config.m_inputFlags); if (result != S_OK) { fprintf(stderr, "Failed to enable video input. Is another application using the card?\n"); goto bail; } result = g_deckLinkInput->EnableAudioInput(bmdAudioSampleRate48kHz, g_config.m_audioSampleDepth, g_config.m_audioChannels); if (result != S_OK) goto bail; result = g_deckLinkInput->StartStreams(); if (result != S_OK) goto bail; // All Okay. exitStatus = 0; pthread_mutex_lock(&g_sleepMutex); pthread_cond_wait(&g_sleepCond, &g_sleepMutex); pthread_mutex_unlock(&g_sleepMutex); fprintf(stderr, "Stopping Capture\n"); g_deckLinkInput->StopStreams(); g_deckLinkInput->DisableAudioInput(); g_deckLinkInput->DisableVideoInput(); } bail: if (g_videoOutputFile != 0) close(g_videoOutputFile); if (g_audioOutputFile != 0) close(g_audioOutputFile); if (displayModeName != NULL) free(displayModeName); if (displayMode != NULL) displayMode->Release(); if (displayModeIterator != NULL) displayModeIterator->Release(); if (g_deckLinkInput != NULL) { g_deckLinkInput->Release(); g_deckLinkInput = NULL; } if (deckLinkAttributes != NULL) deckLinkAttributes->Release(); if (deckLink != NULL) deckLink->Release(); if (deckLinkIterator != NULL) deckLinkIterator->Release(); close(g_video_sock); close(g_audio_sock); return exitStatus; }
static gpointer init_devices (gpointer data) { IDeckLinkIterator *iterator; IDeckLink *decklink = NULL; HRESULT ret; int i; #ifdef _MSC_VER // Start COM thread for Windows g_mutex_lock (&com_init_lock); /* create the COM initialization thread */ g_thread_create ((GThreadFunc) gst_decklink_com_thread, NULL, FALSE, NULL); /* wait until the COM thread signals that COM has been initialized */ g_cond_wait (&com_init_cond, &com_init_lock); g_mutex_unlock (&com_init_lock); #endif /* _MSC_VER */ iterator = CreateDeckLinkIteratorInstance (); if (iterator == NULL) { GST_ERROR ("no driver"); return NULL; } i = 0; ret = iterator->Next (&decklink); while (ret == S_OK) { ret = decklink->QueryInterface (IID_IDeckLinkInput, (void **) &devices[i].input.input); if (ret != S_OK) { GST_WARNING ("selected device does not have input interface"); } else { devices[i].input.device = decklink; devices[i].input.clock = gst_decklink_clock_new ("GstDecklinkInputClock"); GST_DECKLINK_CLOCK_CAST (devices[i].input.clock)->input = &devices[i].input; devices[i].input. input->SetCallback (new GStreamerDecklinkInputCallback (&devices[i]. input)); } ret = decklink->QueryInterface (IID_IDeckLinkOutput, (void **) &devices[i].output.output); if (ret != S_OK) { GST_WARNING ("selected device does not have output interface"); } else { devices[i].output.device = decklink; devices[i].output.clock = gst_decklink_clock_new ("GstDecklinkOutputClock"); GST_DECKLINK_CLOCK_CAST (devices[i].output.clock)->output = &devices[i].output; } ret = decklink->QueryInterface (IID_IDeckLinkConfiguration, (void **) &devices[i].input.config); if (ret != S_OK) { GST_WARNING ("selected device does not have config interface"); } ret = decklink->QueryInterface (IID_IDeckLinkAttributes, (void **) &devices[i].input.attributes); if (ret != S_OK) { GST_WARNING ("selected device does not have attributes interface"); } ret = iterator->Next (&decklink); i++; if (i == 10) { GST_WARNING ("this hardware has more then 10 devices"); break; } } n_devices = i; iterator->Release (); return NULL; }
void BMDConfig::DisplayUsage(int status) { HRESULT result = E_FAIL; IDeckLinkIterator* deckLinkIterator = CreateDeckLinkIteratorInstance(); IDeckLinkDisplayModeIterator* displayModeIterator = NULL; IDeckLink* deckLink = NULL; IDeckLink* deckLinkSelected = NULL; int deckLinkCount = 0; char* deckLinkName = NULL; IDeckLinkAttributes* deckLinkAttributes = NULL; bool formatDetectionSupported; IDeckLinkInput* deckLinkInput = NULL; IDeckLinkDisplayMode* displayModeUsage; int displayModeCount = 0; char* displayModeName; fprintf(stderr, "Usage: Capture -d <device id> -m <mode id> [OPTIONS]\n" "\n" " -d <device id>:\n" ); // Loop through all available devices while (deckLinkIterator->Next(&deckLink) == S_OK) { result = deckLink->GetModelName((const char**)&deckLinkName); if (result == S_OK) { fprintf(stderr, " %2d: %s%s\n", deckLinkCount, deckLinkName, deckLinkCount == m_deckLinkIndex ? " (selected)" : "" ); free(deckLinkName); } if (deckLinkCount == m_deckLinkIndex) deckLinkSelected = deckLink; else deckLink->Release(); ++deckLinkCount; } if (deckLinkCount == 0) fprintf(stderr, " No DeckLink devices found. Is the driver loaded?\n"); deckLinkName = NULL; if (deckLinkSelected != NULL) deckLinkSelected->GetModelName((const char**)&deckLinkName); fprintf(stderr, " -m <mode id>: (%s)\n", deckLinkName ? deckLinkName : "" ); if (deckLinkName != NULL) free(deckLinkName); // Loop through all available display modes on the delected DeckLink device if (deckLinkSelected == NULL) { fprintf(stderr, " No DeckLink device selected\n"); goto bail; } result = deckLinkSelected->QueryInterface(IID_IDeckLinkAttributes, (void**)&deckLinkAttributes); if (result == S_OK) { result = deckLinkAttributes->GetFlag(BMDDeckLinkSupportsInputFormatDetection, &formatDetectionSupported); if (result == S_OK && formatDetectionSupported) fprintf(stderr, " -1: auto detect format\n"); } result = deckLinkSelected->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput); if (result != S_OK) goto bail; result = deckLinkInput->GetDisplayModeIterator(&displayModeIterator); if (result != S_OK) goto bail; while (displayModeIterator->Next(&displayModeUsage) == S_OK) { result = displayModeUsage->GetName((const char **)&displayModeName); if (result == S_OK) { BMDTimeValue frameRateDuration; BMDTimeValue frameRateScale; displayModeUsage->GetFrameRate(&frameRateDuration, &frameRateScale); fprintf(stderr, " %2d: %-20s \t %li x %li \t %g FPS\n", displayModeCount, displayModeName, displayModeUsage->GetWidth(), displayModeUsage->GetHeight(), (double)frameRateScale / (double)frameRateDuration ); free(displayModeName); } displayModeUsage->Release(); ++displayModeCount; } bail: fprintf(stderr, " -p <pixelformat>\n" " 0: 8 bit YUV (4:2:2) (default)\n" " 1: 10 bit YUV (4:2:2)\n" " 2: 10 bit RGB (4:4:4)\n" " -t <format> Print timecode\n" " rp188: RP 188\n" " vitc: VITC\n" " serial: Serial Timecode\n" " -v <filename> Filename raw video will be written to\n" " -a <filename> Filename raw audio will be written to\n" " -l <lcm channel> Channel name to publish images to LCM\n" " -q <jpeg quality> JPEG compression quality for LCM images (1-100 - default is 90)\n" " -c <channels> Audio Channels (2, 8 or 16 - default is 2)\n" " -s <depth> Audio Sample Depth (16 or 32 - default is 16)\n" " -n <frames> Number of frames to capture (default is unlimited)\n" " -3 Capture Stereoscopic 3D (Requires 3D Hardware support)\n" "\n" "Capture video and/or audio to a file. Raw video and/or audio can be viewed with mplayer eg:\n" "\n" " Capture -d 0 -m 2 -n 50 -v video.raw -a audio.raw\n" " mplayer video.raw -demuxer rawvideo -rawvideo pal:uyvy -audiofile audio.raw -audio-demuxer 20 -rawaudio rate=48000\n" "\n" "LCM capture example command line:\n" "\n" " DecklinkCapture -d 0 -m 14 -q 95 -l DECKLINK_VIDEO_CAPTURE\n" "\n" ); if (deckLinkIterator != NULL) deckLinkIterator->Release(); if (displayModeIterator != NULL) displayModeIterator->Release(); if (deckLinkInput != NULL) deckLinkInput->Release(); if (deckLinkAttributes != NULL) deckLinkAttributes->Release(); if (deckLinkSelected != NULL) deckLinkSelected->Release(); exit(status); }
int main (int argc, char* argv[]) { printf("DeckControl Test Application\n\n"); IDeckLinkIterator* deckLinkIterator; IDeckLink* deckLink; int numDevices = 0; HRESULT result; fdSerial = -1; // Create an IDeckLinkIterator object to enumerate all DeckLink cards in the system deckLinkIterator = CreateDeckLinkIteratorInstance(); if (deckLinkIterator == NULL) { fprintf(stderr, "A DeckLink iterator could not be created. The DeckLink drivers may not be installed.\n"); return 1; } // Enumerate all cards in this system while (deckLinkIterator->Next(&deckLink) == S_OK) { CFStringRef deviceNameCFString = NULL; // Increment the total number of DeckLink cards found numDevices++; if (numDevices > 1) printf("\n\n"); // *** Print the model name of the DeckLink card result = deckLink->GetModelName(&deviceNameCFString); if (result == S_OK) { IDeckLinkAttributes* deckLinkAttributes; char deviceName[64]; HRESULT attributeResult; CFStringRef serialName; bool serialSupported; CFStringGetCString(deviceNameCFString, deviceName, sizeof(deviceName), kCFStringEncodingMacRoman); printf("Found Blackmagic device: %s\n", deviceName); attributeResult = deckLink->QueryInterface(IID_IDeckLinkAttributes, (void**)&deckLinkAttributes); if (attributeResult != S_OK) { fprintf(stderr, "Could not obtain the IDeckLinkAttributes interface"); } else { attributeResult = deckLinkAttributes->GetFlag(BMDDeckLinkHasSerialPort, &serialSupported); // are serial ports supported on device? if (attributeResult == S_OK && serialSupported) { attributeResult = deckLinkAttributes->GetString(BMDDeckLinkSerialPortDeviceName, &serialName); // get serial port name if (attributeResult == S_OK) { char portName[64]; CFStringGetCString(serialName, portName, sizeof(portName), kCFStringEncodingMacRoman); printf("Serial port name: %s\n",portName); if (openSerialDevice((char*)&portName)== true) // open serial port { printf("Device opened\n"); playCommand(); // Play deck, printf("Delay 3 seconds\n"); sleep(3); timeCodeCommand(); // DisplayTC printf("Delay 3 seconds\n"); sleep(3); stopCommand(); // Stop deck closeSerialDevice(); // close serial port } else printf("Device open fail\n"); CFRelease(serialName); } else printf("Unable to get serial port device name\n"); } else printf("Serial port not supported\n"); } CFRelease(deviceNameCFString); // Release the IDeckLink instance when we've finished with it to prevent leaks } deckLink->Release(); } if (deckLinkIterator) deckLinkIterator->Release(); // If no DeckLink cards were found in the system, inform the user if (numDevices == 0) printf("No Blackmagic Design devices were found.\n"); printf("\n"); return 0; }
bool OpenGLComposite::InitDeckLink() { bool bSuccess = false; IDeckLinkIterator* pDLIterator = NULL; IDeckLink* pDL = NULL; IDeckLinkDisplayModeIterator* pDLDisplayModeIterator = NULL; IDeckLinkDisplayMode* pDLDisplayMode = NULL; BMDDisplayMode displayMode = bmdModeHD1080i5994; // mode to use for capture and playout float fps; HRESULT result; result = CoCreateInstance(CLSID_CDeckLinkIterator, NULL, CLSCTX_ALL, IID_IDeckLinkIterator, (void**)&pDLIterator); if (FAILED(result)) { MessageBox(NULL, _T("Please install the Blackmagic DeckLink drivers to use the features of this application."), _T("This application requires the DeckLink drivers installed."), MB_OK); return false; } while (pDLIterator->Next(&pDL) == S_OK) { // Use first board found as capture device, second board will be playout device if (! mDLInput) { if (pDL->QueryInterface(IID_IDeckLinkInput, (void**)&mDLInput) != S_OK) goto error; } else if (! mDLOutput) { if (pDL->QueryInterface(IID_IDeckLinkOutput, (void**)&mDLOutput) != S_OK) goto error; } } if (! mDLOutput || ! mDLInput) { MessageBox(NULL, _T("Expected both Input and Output DeckLink devices"), _T("This application requires two DeckLink devices."), MB_OK); goto error; } if (mDLOutput->GetDisplayModeIterator(&pDLDisplayModeIterator) != S_OK) { MessageBox(NULL, _T("Cannot get Display Mode Iterator."), _T("DeckLink error."), MB_OK); goto error; } while (pDLDisplayModeIterator->Next(&pDLDisplayMode) == S_OK) { if (pDLDisplayMode->GetDisplayMode() == displayMode) break; pDLDisplayMode->Release(); pDLDisplayMode = NULL; } pDLDisplayModeIterator->Release(); if (pDLDisplayMode == NULL) { MessageBox(NULL, _T("Cannot get specified BMDDisplayMode."), _T("DeckLink error."), MB_OK); goto error; } mFrameWidth = pDLDisplayMode->GetWidth(); mFrameHeight = pDLDisplayMode->GetHeight(); if (! CheckOpenGLExtensions()) goto error; if (! InitOpenGLState()) goto error; // Compute a rotate angle rate so box will spin at a rate independent of video mode frame rate pDLDisplayMode->GetFrameRate(&mFrameDuration, &mFrameTimescale); fps = (float)mFrameTimescale / (float)mFrameDuration; mRotateAngleRate = 35.0f / fps; // rotate box through 35 degrees every second // Resize window to match video frame, but scale large formats down by half for viewing if (mFrameWidth < 1920) resizeWindow(mFrameWidth, mFrameHeight); else resizeWindow(mFrameWidth / 2, mFrameHeight / 2); if (mFastTransferExtensionAvailable) { // Initialize fast video frame transfers if (! VideoFrameTransfer::initialize(mFrameWidth, mFrameHeight, mCaptureTexture, mFBOTexture)) { MessageBox(NULL, _T("Cannot initialize video transfers."), _T("VideoFrameTransfer error."), MB_OK); goto error; } } // Capture will use a user-supplied frame memory allocator mCaptureAllocator = new PinnedMemoryAllocator(hGLDC, hGLRC, VideoFrameTransfer::CPUtoGPU, 3); if (mDLInput->SetVideoInputFrameMemoryAllocator(mCaptureAllocator) != S_OK) goto error; if (mDLInput->EnableVideoInput(displayMode, bmdFormat8BitYUV, bmdVideoInputFlagDefault) != S_OK) goto error; mCaptureDelegate = new CaptureDelegate(this); if (mDLInput->SetCallback(mCaptureDelegate) != S_OK) goto error; // Playout will use a user-supplied frame memory allocator mPlayoutAllocator = new PinnedMemoryAllocator(hGLDC, hGLRC, VideoFrameTransfer::GPUtoCPU, 1); if (mDLOutput->SetVideoOutputFrameMemoryAllocator(mPlayoutAllocator) != S_OK) goto error; if (mDLOutput->EnableVideoOutput(displayMode, bmdVideoOutputFlagDefault) != S_OK) goto error; // Create a queue of 10 IDeckLinkMutableVideoFrame objects to use for scheduling output video frames. // The ScheduledFrameCompleted() callback will immediately schedule a new frame using the next video frame from this queue. for (int i = 0; i < 10; i++) { // The frame read back from the GPU frame buffer and used for the playout video frame is in BGRA format. // The BGRA frame will be converted on playout to YCbCr either in hardware on most DeckLink cards or in software // within the DeckLink API for DeckLink devices without this hardware conversion. // If you want RGB 4:4:4 format to be played out "over the wire" in SDI, turn on the "Use 4:4:4 SDI" in the control // panel or turn on the bmdDeckLinkConfig444SDIVideoOutput flag using the IDeckLinkConfiguration interface. IDeckLinkMutableVideoFrame* outputFrame; if (mDLOutput->CreateVideoFrame(mFrameWidth, mFrameHeight, mFrameWidth*4, bmdFormat8BitBGRA, bmdFrameFlagFlipVertical, &outputFrame) != S_OK) goto error; mDLOutputVideoFrameQueue.push_back(outputFrame); } mPlayoutDelegate = new PlayoutDelegate(this); if (mPlayoutDelegate == NULL) goto error; if (mDLOutput->SetScheduledFrameCompletionCallback(mPlayoutDelegate) != S_OK) goto error; bSuccess = true; error: if (!bSuccess) { if (mDLInput != NULL) { mDLInput->Release(); mDLInput = NULL; } if (mDLOutput != NULL) { mDLOutput->Release(); mDLOutput = NULL; } } if (pDL != NULL) { pDL->Release(); pDL = NULL; } if (pDLIterator != NULL) { pDLIterator->Release(); pDLIterator = NULL; } return bSuccess; }
bool start( mlt_profile profile = 0 ) { if ( m_started ) return false; try { // Initialize some members m_vancLines = mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( getProducer() ), "vanc" ); if ( m_vancLines == -1 ) m_vancLines = profile->height <= 512 ? 26 : 32; if ( !profile ) profile = mlt_service_profile( MLT_PRODUCER_SERVICE( getProducer() ) ); // Get the display mode BMDDisplayMode displayMode = getDisplayMode( profile, m_vancLines ); if ( displayMode == (BMDDisplayMode) bmdDisplayModeNotSupported ) { mlt_log_info( getProducer(), "profile = %dx%d %f fps %s\n", profile->width, profile->height, mlt_profile_fps( profile ), profile->progressive? "progressive" : "interlace" ); throw "Profile is not compatible with decklink."; } // Determine if supports input format detection #ifdef WIN32 BOOL doesDetectFormat = FALSE; #else bool doesDetectFormat = false; #endif IDeckLinkAttributes *decklinkAttributes = 0; if ( m_decklink->QueryInterface( IID_IDeckLinkAttributes, (void**) &decklinkAttributes ) == S_OK ) { if ( decklinkAttributes->GetFlag( BMDDeckLinkSupportsInputFormatDetection, &doesDetectFormat ) != S_OK ) doesDetectFormat = false; SAFE_RELEASE( decklinkAttributes ); } mlt_log_verbose( getProducer(), "%s format detection\n", doesDetectFormat ? "supports" : "does not support" ); // Enable video capture BMDPixelFormat pixelFormat = bmdFormat8BitYUV; BMDVideoInputFlags flags = doesDetectFormat ? bmdVideoInputEnableFormatDetection : bmdVideoInputFlagDefault; if ( S_OK != m_decklinkInput->EnableVideoInput( displayMode, pixelFormat, flags ) ) throw "Failed to enable video capture."; // Enable audio capture BMDAudioSampleRate sampleRate = bmdAudioSampleRate48kHz; BMDAudioSampleType sampleType = bmdAudioSampleType16bitInteger; int channels = mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( getProducer() ), "channels" ); if ( S_OK != m_decklinkInput->EnableAudioInput( sampleRate, sampleType, channels ) ) throw "Failed to enable audio capture."; // Start capture m_dropped = 0; mlt_properties_set_int( MLT_PRODUCER_PROPERTIES( getProducer() ), "dropped", m_dropped ); m_started = m_decklinkInput->StartStreams() == S_OK; if ( !m_started ) throw "Failed to start capture."; } catch ( const char *error ) { m_decklinkInput->DisableVideoInput(); mlt_log_error( getProducer(), "%s\n", error ); return false; } return true; }
OFX_DECKLINK_API_BEGIN_NAMESPACE vector<Device> listDevice() { vector<Device> devinfo; IDeckLinkIterator* deckLinkIterator = CreateDeckLinkIteratorInstance(); if (deckLinkIterator == NULL) { ofLogError("ofxDeckLinkAPI::Monitor") << "This application requires the DeckLink drivers installed." << "\n" << "Please install the Blackmagic DeckLink drivers to use the features of this application."; } cout << "==== ofxDeckLinkAPI::listDevice() ====" << endl; IDeckLink* deckLink = NULL; HRESULT result; int num_device = 0; while (deckLinkIterator->Next(&deckLink) == S_OK) { Device dev; CFStringRef deviceNameCFString = NULL; result = deckLink->GetModelName(&deviceNameCFString); if (result == S_OK) { char deviceName[64]; CFStringGetCString(deviceNameCFString, deviceName, sizeof(deviceName), kCFStringEncodingUTF8); cout << num_device << ": " << deviceName; CFRelease(deviceNameCFString); dev.model_name = (string)deviceName; } IDeckLinkAttributes* attr = NULL; deckLink->QueryInterface(IID_IDeckLinkAttributes, (void**)&attr); if (attr != NULL) { { int64_t v = 0; if (attr->GetInt(BMDDeckLinkPersistentID, &v) == S_OK) { dev.persistent_id = v; cout << ", pid:" << v; } } { int64_t v = 0; if (attr->GetInt(BMDDeckLinkTopologicalID, &v) == S_OK) { dev.topological_id = v; cout << ", tid:" << v; } } } cout << endl; devinfo.push_back(dev); deckLink->Release(); num_device++; } if (num_device == 0) cout << "device not found" << endl; cout << "======================================" << endl << endl; if (deckLinkIterator != NULL) { deckLinkIterator->Release(); deckLinkIterator = NULL; } return devinfo; }
int ff_decklink_list_devices(AVFormatContext *avctx, struct AVDeviceInfoList *device_list, int show_inputs, int show_outputs) { IDeckLink *dl = NULL; IDeckLinkIterator *iter = decklink_create_iterator(avctx); int ret = 0; if (!iter) return AVERROR(EIO); while (ret == 0 && iter->Next(&dl) == S_OK) { IDeckLinkOutput *output_config; IDeckLinkInput *input_config; const char *displayName; AVDeviceInfo *new_device = NULL; int add = 0; ff_decklink_get_display_name(dl, &displayName); if (show_outputs) { if (dl->QueryInterface(IID_IDeckLinkOutput, (void **)&output_config) == S_OK) { output_config->Release(); add = 1; } } if (show_inputs) { if (dl->QueryInterface(IID_IDeckLinkInput, (void **)&input_config) == S_OK) { input_config->Release(); add = 1; } } if (add == 1) { new_device = (AVDeviceInfo *) av_mallocz(sizeof(AVDeviceInfo)); if (!new_device) { ret = AVERROR(ENOMEM); goto next; } new_device->device_name = av_strdup(displayName); new_device->device_description = av_strdup(displayName); if (!new_device->device_name || !new_device->device_description || av_dynarray_add_nofree(&device_list->devices, &device_list->nb_devices, new_device) < 0) { ret = AVERROR(ENOMEM); av_freep(&new_device->device_name); av_freep(&new_device->device_description); av_freep(&new_device); goto next; } } next: av_freep(&displayName); dl->Release(); } iter->Release(); return ret; }