IDeckLinkDisplayMode *BMDOutputDelegate::GetDisplayModeByIndex(int selectedIndex) { // Populate the display mode combo with a list of display modes supported by the installed DeckLink card IDeckLinkDisplayModeIterator* displayModeIterator; IDeckLinkDisplayMode* deckLinkDisplayMode; IDeckLinkDisplayMode* selectedMode = NULL; int index = 0; if (m_deckLinkOutput->GetDisplayModeIterator(&displayModeIterator) != S_OK) goto bail; while (displayModeIterator->Next(&deckLinkDisplayMode) == S_OK) { const char *modeName; if (deckLinkDisplayMode->GetName(&modeName) == S_OK) { if (index == selectedIndex) { printf("Selected mode: %s\n", modeName); selectedMode = deckLinkDisplayMode; goto bail; } } index++; } bail: displayModeIterator->Release(); return selectedMode; }
BMDDisplayMode getDisplayMode( mlt_profile profile, int vancLines ) { IDeckLinkDisplayModeIterator* iter = NULL; IDeckLinkDisplayMode* mode = NULL; BMDDisplayMode result = (BMDDisplayMode) bmdDisplayModeNotSupported; if ( m_decklinkInput->GetDisplayModeIterator( &iter ) == S_OK ) { while ( !result && iter->Next( &mode ) == S_OK ) { int width = mode->GetWidth(); int height = mode->GetHeight(); BMDTimeValue duration; BMDTimeScale timescale; mode->GetFrameRate( &duration, ×cale ); double fps = (double) timescale / duration; int p = mode->GetFieldDominance() == bmdProgressiveFrame; m_topFieldFirst = mode->GetFieldDominance() == bmdUpperFieldFirst; m_colorspace = ( mode->GetFlags() & bmdDisplayModeColorspaceRec709 ) ? 709 : 601; mlt_log_verbose( getProducer(), "BMD mode %dx%d %.3f fps prog %d tff %d\n", width, height, fps, p, m_topFieldFirst ); if ( width == profile->width && p == profile->progressive && ( height + vancLines == profile->height || ( height == 486 && profile->height == 480 + vancLines ) ) && fps == mlt_profile_fps( profile ) ) result = mode->GetDisplayMode(); SAFE_RELEASE( mode ); } SAFE_RELEASE( iter ); } return result; }
IDeckLinkDisplayMode* getDisplayMode() { mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( getConsumer() ) ); IDeckLinkDisplayModeIterator* iter = NULL; IDeckLinkDisplayMode* mode = NULL; IDeckLinkDisplayMode* result = 0; if ( m_deckLinkOutput->GetDisplayModeIterator( &iter ) == S_OK ) { while ( !result && iter->Next( &mode ) == S_OK ) { m_width = mode->GetWidth(); m_height = mode->GetHeight(); mode->GetFrameRate( &m_duration, &m_timescale ); m_fps = (double) m_timescale / m_duration; int p = mode->GetFieldDominance() == bmdProgressiveFrame; mlt_log_verbose( getConsumer(), "BMD mode %dx%d %.3f fps prog %d\n", m_width, m_height, m_fps, p ); if ( m_width == profile->width && p == profile->progressive && (int) m_fps == (int) mlt_profile_fps( profile ) && ( m_height == profile->height || ( m_height == 486 && profile->height == 480 ) ) ) result = mode; else SAFE_RELEASE( mode ); } SAFE_RELEASE( iter ); } return result; }
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 PlaybackHelper::setupDeckLinkOutput() { bool result = false; IDeckLinkDisplayModeIterator* displayModeIterator = NULL; IDeckLinkDisplayMode* deckLinkDisplayMode = NULL; m_width = -1; // set callback m_deckLinkOutput->SetScheduledFrameCompletionCallback(this); // get frame scale and duration for the video mode if (m_deckLinkOutput->GetDisplayModeIterator(&displayModeIterator) != S_OK) goto bail; while (displayModeIterator->Next(&deckLinkDisplayMode) == S_OK) { if (deckLinkDisplayMode->GetDisplayMode() == bmdModeNTSC) { m_width = deckLinkDisplayMode->GetWidth(); m_height = deckLinkDisplayMode->GetHeight(); deckLinkDisplayMode->GetFrameRate(&m_frameDuration, &m_timeScale); deckLinkDisplayMode->Release(); break; } deckLinkDisplayMode->Release(); } displayModeIterator->Release(); if (m_width == -1) { fprintf(stderr, "Unable to find requested video mode\n"); goto bail; } // enable video output if (m_deckLinkOutput->EnableVideoOutput(bmdModeNTSC, bmdVideoOutputFlagDefault) != S_OK) { fprintf(stderr, "Could not enable video output\n"); goto bail; } // create coloured frames if (! createFrames()) goto bail; result = true; bail: if (! result) { // release coloured frames releaseFrames(); } return result; }
IDeckLinkDisplayMode *Player::GetDisplayModeByIndex(int selectedIndex) { // Populate the display mode combo with a list of display modes supported by the installed DeckLink card IDeckLinkDisplayModeIterator *displayModeIterator; IDeckLinkDisplayMode *deckLinkDisplayMode; IDeckLinkDisplayMode *selectedMode = NULL; int index = 0; if (m_deckLinkOutput->GetDisplayModeIterator(&displayModeIterator) != S_OK) goto bail; while (displayModeIterator->Next(&deckLinkDisplayMode) == S_OK) { BMDProbeString str; if (deckLinkDisplayMode->GetName(&str) == S_OK) { if (index == selectedIndex) { printf("Selected mode: %s\n\n\n", ToStr(str)); selectedMode = deckLinkDisplayMode; FreeStr(str); goto bail; } } index++; } bail: displayModeIterator->Release(); return selectedMode; }
void CSignalGeneratorDlg::RefreshDisplayModeMenu(void) { // Populate the display mode combo with a list of display modes supported by the installed DeckLink card IDeckLinkDisplayModeIterator* displayModeIterator; IDeckLinkDisplayMode* deckLinkDisplayMode; BMDPixelFormat pixelFormat; pixelFormat = (BMDPixelFormat)m_pixelFormatCombo.GetItemData(m_pixelFormatCombo.GetCurSel()); for (int i = 1; i < m_videoFormatCombo.GetCount(); i++) { deckLinkDisplayMode = (IDeckLinkDisplayMode*)m_videoFormatCombo.GetItemDataPtr(i-1); deckLinkDisplayMode->Release(); } m_videoFormatCombo.ResetContent(); if (m_deckLinkOutput->GetDisplayModeIterator(&displayModeIterator) != S_OK) return; while (displayModeIterator->Next(&deckLinkDisplayMode) == S_OK) { BSTR modeName; int newIndex; HRESULT hr; BMDDisplayModeSupport displayModeSupport; BMDVideoOutputFlags videoOutputFlags = bmdVideoOutputDualStream3D; if (deckLinkDisplayMode->GetName(&modeName) != S_OK) { deckLinkDisplayMode->Release(); continue; } CString modeNameCString(modeName); newIndex = m_videoFormatCombo.AddString(modeNameCString); m_videoFormatCombo.SetItemDataPtr(newIndex, deckLinkDisplayMode); hr = m_deckLinkOutput->DoesSupportVideoMode(deckLinkDisplayMode->GetDisplayMode(), pixelFormat, videoOutputFlags, &displayModeSupport, NULL); if (hr != S_OK || ! displayModeSupport) { SysFreeString(modeName); continue; } CString modeName3DCString(modeName); modeName3DCString += _T(" 3D"); newIndex = m_videoFormatCombo.AddString(modeName3DCString); m_videoFormatCombo.SetItemDataPtr(newIndex, deckLinkDisplayMode); deckLinkDisplayMode->AddRef(); SysFreeString(modeName); } displayModeIterator->Release(); m_videoFormatCombo.SetCurSel(0); }
bool DeckLinkController::selectDevice(int index) { IDeckLinkAttributes* deckLinkAttributes = NULL; IDeckLinkDisplayModeIterator* displayModeIterator = NULL; IDeckLinkDisplayMode* displayMode = NULL; bool result = false; // Check index if (index >= deviceList.size()) { ofLogError("DeckLinkController") << "This application was unable to select the device."; goto bail; } // A new device has been selected. // Release the previous selected device and mode list if (deckLinkInput != NULL) deckLinkInput->Release(); while(modeList.size() > 0) { modeList.back()->Release(); modeList.pop_back(); } // Get the IDeckLinkInput for the selected device if ((deviceList[index]->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput) != S_OK)) { ofLogError("DeckLinkController") << "This application was unable to obtain IDeckLinkInput for the selected device."; deckLinkInput = NULL; goto bail; } // // Retrieve and cache mode list if (deckLinkInput->GetDisplayModeIterator(&displayModeIterator) == S_OK) { while (displayModeIterator->Next(&displayMode) == S_OK) modeList.push_back(displayMode); displayModeIterator->Release(); } // // Check if input mode detection format is supported. supportFormatDetection = false; // assume unsupported until told otherwise if (deviceList[index]->QueryInterface(IID_IDeckLinkAttributes, (void**) &deckLinkAttributes) == S_OK) { if (deckLinkAttributes->GetFlag(BMDDeckLinkSupportsInputFormatDetection, &supportFormatDetection) != S_OK) supportFormatDetection = false; deckLinkAttributes->Release(); } result = true; bail: return result; }
bool Output::startDeckLink(BMDDisplayMode mode) { IDeckLinkDisplayModeIterator* pDLDisplayModeIterator = NULL; IDeckLinkDisplayMode* pDLDisplayMode = NULL; if (pDLOutput->GetDisplayModeIterator(&pDLDisplayModeIterator) == S_OK) { while (pDLDisplayModeIterator->Next(&pDLDisplayMode) == S_OK) { if (pDLDisplayMode->GetDisplayMode() == mode) { break; } } pDLDisplayModeIterator->Release(); } if (!pDLDisplayMode) { ofLogError("ofxDeckLinkAPI::Output") << "invalid display mode"; return false; } uiFrameWidth = pDLDisplayMode->GetWidth(); uiFrameHeight = pDLDisplayMode->GetHeight(); pixels[0].allocate(uiFrameWidth, uiFrameHeight, 4); pixels[1].allocate(uiFrameWidth, uiFrameHeight, 4); front_buffer = &pixels[0]; back_buffer = &pixels[1]; pDLDisplayMode->GetFrameRate(&frameDuration, &frameTimescale); uiFPS = ((frameTimescale + (frameDuration - 1)) / frameDuration); if (pDLOutput->EnableVideoOutput(pDLDisplayMode->GetDisplayMode(), bmdVideoOutputFlagDefault) != S_OK) return false; if (pDLOutput->CreateVideoFrame(uiFrameWidth, uiFrameHeight, uiFrameWidth * 4, bmdFormat8BitARGB, bmdFrameFlagDefault, &pDLVideoFrame) != S_OK) return false; uiTotalFrames = 0; resetFrame(); setPreroll(); pDLOutput->StartScheduledPlayback(0, frameTimescale, 1); return true; }
// select output device bool DeckLinkController::selectOutputDevice(int index) { IDeckLinkAttributes* deckLinkAttributes = NULL; IDeckLinkDisplayModeIterator* displayModeIterator = NULL; IDeckLinkDisplayMode* displayMode = NULL; bool result = false; // Check index if (index >= deviceList.size()) { ofLogError("DeckLinkController") << "This application was unable to select the device."; goto bail; } // A new device has been selected. // Release the previous selected device and mode list if (deckLinkInput != NULL) deckLinkInput->Release(); while(modeList.size() > 0) { modeList.back()->Release(); modeList.pop_back(); } // Get the IDeckLinkOutput for the selected device if ((deviceList[index]->QueryInterface(IID_IDeckLinkOutput, (void**)&deckLinkOutput) != S_OK)) { ofLogError("DeckLinkController") << "This application was unable to obtain IDeckLinkOutput for the selected device."; deckLinkOutput = NULL; goto bail; } if ((deckLinkOutput->CreateVideoFrame(1280, 720, 1280*4,bmdFormat8BitBGRA, bmdFrameFlagDefault, &videoFrame) != S_OK)) { ofLogError("DeckLinkController") << "Create video frame error"; goto bail; } // Retrieve and cache mode list if (deckLinkOutput->GetDisplayModeIterator(&displayModeIterator) == S_OK) { while (displayModeIterator->Next(&displayMode) == S_OK) { modeList.push_back(displayMode); } displayModeIterator->Release(); } result = true; bail: return result; }
int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t direction) { struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data; struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; IDeckLinkDisplayModeIterator *itermode; IDeckLinkDisplayMode *mode; uint32_t format_code; HRESULT res; if (direction == DIRECTION_IN) { int ret; ret = decklink_select_input(avctx, bmdDeckLinkConfigAudioInputConnection); if (ret < 0) return ret; ret = decklink_select_input(avctx, bmdDeckLinkConfigVideoInputConnection); if (ret < 0) return ret; res = ctx->dli->GetDisplayModeIterator (&itermode); } else { res = ctx->dlo->GetDisplayModeIterator (&itermode); } if (res!= S_OK) { av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode Iterator\n"); return AVERROR(EIO); } av_log(avctx, AV_LOG_INFO, "Supported formats for '%s':\n\tformat_code\tdescription", avctx->filename); while (itermode->Next(&mode) == S_OK) { BMDTimeValue tb_num, tb_den; mode->GetFrameRate(&tb_num, &tb_den); format_code = av_bswap32(mode->GetDisplayMode()); av_log(avctx, AV_LOG_INFO, "\n\t%.4s\t\t%ldx%ld at %d/%d fps", (char*) &format_code, mode->GetWidth(), mode->GetHeight(), (int) tb_den, (int) tb_num); switch (mode->GetFieldDominance()) { case bmdLowerFieldFirst: av_log(avctx, AV_LOG_INFO, " (interlaced, lower field first)"); break; case bmdUpperFieldFirst: av_log(avctx, AV_LOG_INFO, " (interlaced, upper field first)"); break; } mode->Release(); } av_log(avctx, AV_LOG_INFO, "\n"); itermode->Release(); return 0; }
//---------- Specification DeckLink::open(shared_ptr<Base::InitialisationSettings> initialisationSettings) { auto settings = this->getTypedSettings<InitialisationSettings>(initialisationSettings); auto devices = ofxBlackmagic::Iterator::getDeviceList(); if (devices.empty()) { throw(ofxMachineVision::Exception("No DeckLink devices available")); } if (devices.size() <= (unsigned int)settings->deviceID) { string str = "deviceID [" + ofToString(settings->deviceID) + "] out of range. [" + ofToString(devices.size()) + "] devices available"; throw(ofxMachineVision::Exception(str)); } this->device = devices[settings->deviceID]; int width, height; this->displayMode = static_cast<_BMDDisplayMode>(settings->displayMode.get()); try { CHECK_ERRORS(device.device->QueryInterface(IID_IDeckLinkInput, (void**)&this->input), "Failed to query interface"); CHECK_ERRORS(this->input->SetCallback(this), "Failed to set input callback"); //find the current display mode IDeckLinkDisplayModeIterator * displayModeIterator = 0; CHECK_ERRORS(input->GetDisplayModeIterator(&displayModeIterator), "Couldn't get DisplayModeIterator"); IDeckLinkDisplayMode * displayModeTest = nullptr; IDeckLinkDisplayMode * displayModeFound = nullptr; while (displayModeIterator->Next(&displayModeTest) == S_OK) { if (displayModeTest->GetDisplayMode() == this->displayMode) { displayModeFound = displayModeTest; } } if (!displayModeFound) { CHECK_ERRORS(S_FALSE, "Cannot find displayMode"); } width = displayModeFound->GetWidth(); height = displayModeFound->GetHeight(); } catch (std::exception e) { throw(ofxMachineVision::Exception(e.what())); } this->openTime = ofGetElapsedTimeMicros(); this->frameIndex = 0; Specification specification(width, height, "BlackMagic", device.modelName); specification.addFeature(ofxMachineVision::Feature::Feature_DeviceID); specification.addFeature(ofxMachineVision::Feature::Feature_FreeRun); return specification; }
int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t direction) { struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data; struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; IDeckLinkDisplayModeIterator *itermode; IDeckLinkDisplayMode *mode; int i=0; HRESULT res; if (direction == DIRECTION_IN) { res = ctx->dli->GetDisplayModeIterator (&itermode); } else { res = ctx->dlo->GetDisplayModeIterator (&itermode); } if (res!= S_OK) { av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode Iterator\n"); return AVERROR(EIO); } av_log(avctx, AV_LOG_INFO, "Supported formats for '%s':\n", avctx->filename); while (itermode->Next(&mode) == S_OK) { BMDTimeValue tb_num, tb_den; mode->GetFrameRate(&tb_num, &tb_den); av_log(avctx, AV_LOG_INFO, "\t%d\t%ldx%ld at %d/%d fps", ++i,mode->GetWidth(), mode->GetHeight(), (int) tb_den, (int) tb_num); switch (mode->GetFieldDominance()) { case bmdLowerFieldFirst: av_log(avctx, AV_LOG_INFO, " (interlaced, lower field first)"); break; case bmdUpperFieldFirst: av_log(avctx, AV_LOG_INFO, " (interlaced, upper field first)"); break; } av_log(avctx, AV_LOG_INFO, "\n"); mode->Release(); } itermode->Release(); return 0; }
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" ); } }
IDeckLinkDisplayMode* BMDConfig::GetDeckLinkDisplayMode(IDeckLink* deckLink, int idx) { HRESULT result; IDeckLinkDisplayMode* displayMode = NULL; IDeckLinkInput* deckLinkInput = NULL; IDeckLinkDisplayModeIterator* displayModeIterator = NULL; int i = idx; result = deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput); if (result != S_OK) goto bail; result = deckLinkInput->GetDisplayModeIterator(&displayModeIterator); if (result != S_OK) goto bail; while ((result = displayModeIterator->Next(&displayMode)) == S_OK) { if (i == 0) break; --i; displayMode->Release(); } if (result != S_OK) goto bail; bail: if (displayModeIterator) displayModeIterator->Release(); if (deckLinkInput) deckLinkInput->Release(); return displayMode; }
bool BMDOpenGLOutput::Start() { IDeckLinkDisplayModeIterator* pDLDisplayModeIterator; IDeckLinkDisplayMode* pDLDisplayMode = NULL; // Get first avaliable video mode for Output if (pDLOutput->GetDisplayModeIterator(&pDLDisplayModeIterator) == S_OK) { if (pDLDisplayModeIterator->Next(&pDLDisplayMode) != S_OK) { QMessageBox::critical(NULL,"DeckLink error.", "Cannot find video mode."); pDLDisplayModeIterator->Release(); return false; } pDLDisplayModeIterator->Release(); } uiFrameWidth = pDLDisplayMode->GetWidth(); uiFrameHeight = pDLDisplayMode->GetHeight(); pDLDisplayMode->GetFrameRate(&frameDuration, &frameTimescale); uiFPS = ((frameTimescale + (frameDuration-1)) / frameDuration); if (pDLOutput->EnableVideoOutput(pDLDisplayMode->GetDisplayMode(), bmdVideoOutputFlagDefault) != S_OK) return false; // Flip frame vertical, because OpenGL rendering starts from left bottom corner if (pDLOutput->CreateVideoFrame(uiFrameWidth, uiFrameHeight, uiFrameWidth*4, bmdFormat8BitBGRA, bmdFrameFlagFlipVertical, &pDLVideoFrame) != S_OK) return false; uiTotalFrames = 0; ResetFrame(); SetPreroll(); pContext->makeCurrent(); pGLScene->InitScene(); glGenFramebuffersEXT(1, &idFrameBuf); glGenRenderbuffersEXT(1, &idColorBuf); glGenRenderbuffersEXT(1, &idDepthBuf); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, idFrameBuf); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, idColorBuf); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA8, uiFrameWidth, uiFrameHeight); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, idDepthBuf); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, uiFrameWidth, uiFrameHeight); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, idColorBuf); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, idDepthBuf); glStatus = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if (glStatus != GL_FRAMEBUFFER_COMPLETE_EXT) { QMessageBox::critical(NULL,"OpenGL initialization error.", "Cannot initialize framebuffer."); return false; } pFrameBuf = (char*)malloc(pDLVideoFrame->GetRowBytes() * uiFrameHeight); UpdateScene(); pDLOutput->StartScheduledPlayback(0, 100, 1.0); return true; }
int _tmain(int argc, _TCHAR* argv[]) { int numDevices = 0; HRESULT result; IDeckLinkAttributes *deckLinkAttributes = NULL; HRESULT attributeResult; BOOL keyingSupported; BOOL HDkeyingSupported; int selectedMode = 0; printf("GDI Keyer Sample Application\n\n"); // Initialize COM on this thread result = CoInitialize(NULL); if (FAILED(result)) { fprintf(stderr, "Initialization of COM failed - result = %08x.\n", result); return 1; } // Create an IDeckLinkIterator object to enumerate all DeckLink cards in the system result = CoCreateInstance(CLSID_CDeckLinkIterator, NULL, CLSCTX_ALL, IID_IDeckLinkIterator, (void**)&deckLinkIterator); if (FAILED(result)) { 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) { BSTR deviceNameBSTR = 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(&deviceNameBSTR); if (result == S_OK) { _bstr_t deviceName(deviceNameBSTR); printf("Found Blackmagic device: %s\n", (char*)deviceName); attributeResult = deckLink->QueryInterface(IID_IDeckLinkAttributes, (void**)&deckLinkAttributes); if (attributeResult != S_OK) { fprintf(stderr, "Could not obtain the IDeckLinkAttributes interface"); return 1; } else { attributeResult = deckLinkAttributes->GetFlag(BMDDeckLinkSupportsInternalKeying, &keyingSupported); // is keying supported on this device? if (attributeResult == S_OK && keyingSupported) { IDeckLinkDisplayModeIterator* displayModeIterator = NULL; IDeckLinkDisplayMode* deckLinkDisplayMode = NULL; attributeResult = deckLinkAttributes->GetFlag(BMDDeckLinkSupportsHDKeying, &HDkeyingSupported); if (attributeResult == S_OK && HDkeyingSupported) printf("HD Mode keying supported.\n"); else printf("SD Mode Keying supported.\n"); // check if automode detection support - if so, use it for autodetection if (CheckFormatDetect(deckLinkAttributes) == 0) { fprintf(stderr, "Input mode detection not supported\n"); if (deckLink->QueryInterface(IID_IDeckLinkOutput, (void**)&deckLinkOutput) != S_OK) { fprintf(stderr, "Could not obtain the IDeckLinkOutput interface\n"); } else { int index = 0; if (deckLinkOutput->GetDisplayModeIterator(&displayModeIterator) != S_OK) { fprintf(stderr, "Could not obtain the display mode iterator\n"); } else { printf("\n"); while (displayModeIterator->Next(&deckLinkDisplayMode) == S_OK) { BSTR displayModeBSTR = NULL; int modeWidth; int modeHeight; BMDTimeValue frameRateDuration; BMDTimeScale frameRateScale; // Obtain the display mode's properties modeWidth = deckLinkDisplayMode->GetWidth(); modeHeight = deckLinkDisplayMode->GetHeight(); deckLinkDisplayMode->GetFrameRate(&frameRateDuration, &frameRateScale); if ((deckLinkDisplayMode->GetWidth() > 720) && !HDkeyingSupported) continue; if (deckLinkDisplayMode->GetName(&displayModeBSTR) == S_OK) { _bstr_t modeName(displayModeBSTR, false); // Skip HD modes on cards such as DeckLink SDI (only PAL/NTSC are supported for keying) printf("%d %-20s \t %d x %d \t %g FPS\n", index, (char*)modeName, modeWidth, modeHeight, (double)frameRateScale / (double)frameRateDuration); } deckLinkDisplayMode->Release(); index++; } displayModeIterator->Release(); printf("Select Mode (0-%d):\n", index-1); scanf_s("%d", &selectedMode); printf("Mode selected: %d\n", selectedMode); if(selectedMode < index) { int modeCount = 0; if (deckLinkOutput->GetDisplayModeIterator(&displayModeIterator) != S_OK) { fprintf(stderr, "Could not obtain the display mode iterator\n"); } else { while(displayModeIterator->Next(&deckLinkDisplayMode) == S_OK) { if (selectedMode == modeCount) { OutputGraphic(deckLinkDisplayMode); deckLinkDisplayMode->Release(); break; } deckLinkDisplayMode->Release(); modeCount++; } displayModeIterator->Release(); } } else { printf("Illegal video mode selected\n"); } } deckLinkOutput->Release(); } } } deckLinkAttributes->Release(); printf("Press Enter key to exit.\n"); _getch(); } } deckLink->Release(); // Release the IDeckLink instance when we've finished with it to prevent leaks } if (deckLinkIterator != NULL) deckLinkIterator->Release(); // If no DeckLink cards were found in the system, inform the users if (numDevices == 0) printf("No Blackmagic Design devices were found.\n"); // Uninitalize COM on this thread CoUninitialize(); return 0; }
bool DeckLinkDevice::Init() { ComPtr<IDeckLinkAttributes> attributes; const HRESULT result = device->QueryInterface(IID_IDeckLinkAttributes, (void **)&attributes); if (result == S_OK) { decklink_bool_t detectable = false; if (attributes->GetFlag(BMDDeckLinkSupportsInputFormatDetection, &detectable) == S_OK && !!detectable) { DeckLinkDeviceMode *mode = new DeckLinkDeviceMode( "Auto", MODE_ID_AUTO); inputModes.push_back(mode); inputModeIdMap[MODE_ID_AUTO] = mode; } } // Find input modes ComPtr<IDeckLinkInput> input; if (device->QueryInterface(IID_IDeckLinkInput, (void **) &input) == S_OK) { IDeckLinkDisplayModeIterator *modeIterator; if (input->GetDisplayModeIterator(&modeIterator) == S_OK) { IDeckLinkDisplayMode *displayMode; long long modeId = 1; while (modeIterator->Next(&displayMode) == S_OK) { if (displayMode == nullptr) continue; DeckLinkDeviceMode *mode = new DeckLinkDeviceMode(displayMode, modeId); inputModes.push_back(mode); inputModeIdMap[modeId] = mode; displayMode->Release(); ++modeId; } modeIterator->Release(); } } // find output modes ComPtr<IDeckLinkOutput> output; if (device->QueryInterface(IID_IDeckLinkOutput, (void **) &output) == S_OK) { IDeckLinkDisplayModeIterator *modeIterator; if (output->GetDisplayModeIterator(&modeIterator) == S_OK) { IDeckLinkDisplayMode *displayMode; long long modeId = 1; while (modeIterator->Next(&displayMode) == S_OK) { if (displayMode == nullptr) continue; DeckLinkDeviceMode *mode = new DeckLinkDeviceMode(displayMode, modeId); outputModes.push_back(mode); outputModeIdMap[modeId] = mode; displayMode->Release(); ++modeId; } modeIterator->Release(); } } // get keyer support attributes->GetFlag(BMDDeckLinkSupportsExternalKeying, &supportsExternalKeyer); attributes->GetFlag(BMDDeckLinkSupportsInternalKeying, &supportsInternalKeyer); decklink_string_t decklinkModelName; decklink_string_t decklinkDisplayName; if (device->GetModelName(&decklinkModelName) != S_OK) return false; DeckLinkStringToStdString(decklinkModelName, name); if (device->GetDisplayName(&decklinkDisplayName) != S_OK) return false; DeckLinkStringToStdString(decklinkDisplayName, displayName); hash = displayName; if (result != S_OK) return true; int64_t channels; /* Intensity Shuttle for Thunderbolt return 2; however, it supports 8 channels */ if (name == "Intensity Shuttle Thunderbolt") maxChannel = 8; else if (attributes->GetInt(BMDDeckLinkMaximumAudioChannels, &channels) == S_OK) maxChannel = (int32_t)channels; else maxChannel = 2; /* http://forum.blackmagicdesign.com/viewtopic.php?f=12&t=33967 * BMDDeckLinkTopologicalID for older devices * BMDDeckLinkPersistentID for newer ones */ int64_t value; if (attributes->GetInt(BMDDeckLinkPersistentID, &value) != S_OK && attributes->GetInt(BMDDeckLinkTopologicalID, &value) != S_OK) return true; std::ostringstream os; os << value << "_" << name; hash = os.str(); return true; }
// Prepare IDeckLinkInput to capture video: // - Get frame width, height, duration, ... // - Setup callback object and video mode and // - Start streams bool CaptureHelper::setupDeckLinkInput() { bool result = false; IDeckLinkDisplayModeIterator* displayModeIterator = NULL; IDeckLinkDisplayMode* deckLinkDisplayMode = NULL; m_width = -1; // get frame scale and duration for the video mode if (m_deckLinkInput->GetDisplayModeIterator(&displayModeIterator) != S_OK) goto bail; while (displayModeIterator->Next(&deckLinkDisplayMode) == S_OK) { if (deckLinkDisplayMode->GetDisplayMode() == BMD_DISPLAYMODE) { m_width = deckLinkDisplayMode->GetWidth(); m_height = deckLinkDisplayMode->GetHeight(); deckLinkDisplayMode->GetFrameRate(&m_frameDuration, &m_timeScale); deckLinkDisplayMode->Release(); break; } deckLinkDisplayMode->Release(); } displayModeIterator->Release(); if (m_width == -1) { printf("Unable to find requested video mode\n"); goto bail; } // convert the in- and out-point timecodes to a frame count GET_FRAME_COUNT(m_inPointFrameCount, START_TC, m_timeScale, m_frameDuration); GET_FRAME_COUNT(m_outPointFrameCount, STOP_TC, m_timeScale, m_frameDuration); // set callback m_deckLinkInput->SetCallback(this); // enable video input if (m_deckLinkInput->EnableVideoInput(BMD_DISPLAYMODE, PIXEL_FMT, bmdVideoInputFlagDefault) != S_OK) { printf("Could not enable video input\n"); goto bail; } // start streaming if (m_deckLinkInput->StartStreams() != S_OK) { printf("Could not start streams\n"); goto bail; } result = true; bail: return result; }
void print_output_modes(IDeckLink *deckLink) { IDeckLinkOutput *deckLinkOutput = NULL; IDeckLinkDisplayModeIterator *displayModeIterator = NULL; IDeckLinkDisplayMode *displayMode = NULL; HRESULT result; int displayModeCount = 0; // Query the DeckLink for its configuration interface result = deckLink->QueryInterface(IID_IDeckLinkOutput, (void **)&deckLinkOutput); if (result != S_OK) { fprintf( stderr, "Could not obtain the IDeckLinkOutput interface - result = %08x\n", result); goto bail; } // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output result = deckLinkOutput->GetDisplayModeIterator(&displayModeIterator); if (result != S_OK) { fprintf( stderr, "Could not obtain the video output display mode iterator - result = %08x\n", result); goto bail; } // List all supported output display modes printf("Supported video output display modes and pixel formats:\n"); while (displayModeIterator->Next(&displayMode) == S_OK) { BMDProbeString str; result = displayMode->GetName(&str); if (result == S_OK) { char modeName[64]; int modeWidth; int modeHeight; BMDTimeValue frameRateDuration; BMDTimeScale frameRateScale; int pixelFormatIndex = 0; // index into the gKnownPixelFormats / gKnownFormatNames arrays BMDDisplayModeSupport displayModeSupport; // Obtain the display mode's properties modeWidth = displayMode->GetWidth(); modeHeight = displayMode->GetHeight(); displayMode->GetFrameRate(&frameRateDuration, &frameRateScale); printf(" %2d: %-20s \t %d x %d \t %7g FPS\n", displayModeCount++, ToStr(str), modeWidth, modeHeight, (double)frameRateScale / (double)frameRateDuration); FreeStr(str); } // Release the IDeckLinkDisplayMode object to prevent a leak displayMode->Release(); } // printf("\n"); bail: // Ensure that the interfaces we obtained are released to prevent a memory leak if (displayModeIterator != NULL) displayModeIterator->Release(); if (deckLinkOutput != NULL) deckLinkOutput->Release(); }
bool ofxBlackmagicGrabber::initGrabber(int w, int h) { IDeckLinkIterator *deckLinkIterator = CreateDeckLinkIteratorInstance(); int displayModeCount = 0; int exitStatus = 1; bool foundDisplayMode = false; HRESULT result; IDeckLinkDisplayModeIterator *displayModeIterator; if (!deckLinkIterator){ ofLogError(LOG_NAME) << "This application requires the DeckLink drivers installed."; goto bail; } for(int i=0;i<deviceID+1;i++){ result = deckLinkIterator->Next(&deckLink); if (result != S_OK){ ofLogError(LOG_NAME) << "Couldn't open device" << deviceID; goto bail; } } if (deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput) != S_OK) goto bail; deckLinkInput->SetCallback(this); // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output result = deckLinkInput->GetDisplayModeIterator(&displayModeIterator); if (result != S_OK){ ofLogError(LOG_NAME) << "Could not obtain the video output display mode iterator - result =" << result; goto bail; } if (g_videoModeIndex < 0){ ofLogError(LOG_NAME) << "No video mode specified, specify it before initGrabber using setVideoMode"; goto bail; } while (displayModeIterator->Next(&displayMode) == S_OK){ if (g_videoModeIndex == displayMode->GetDisplayMode()){ BMDDisplayModeSupport result; CFStringRef displayModeName; foundDisplayMode = true; displayMode->GetName(&displayModeName); selectedDisplayMode = displayMode->GetDisplayMode(); pixels[0].allocate(displayMode->GetWidth(),displayMode->GetHeight(),OF_IMAGE_COLOR); pixels[1].allocate(displayMode->GetWidth(),displayMode->GetHeight(),OF_IMAGE_COLOR); ofLogVerbose(LOG_NAME) << "device initialized:" << displayMode->GetWidth() << displayMode->GetHeight(); deckLinkInput->DoesSupportVideoMode(selectedDisplayMode, pixelFormat, bmdVideoInputFlagDefault, &result, NULL); if (result == bmdDisplayModeNotSupported){ ofLogError(LOG_NAME) << "The display mode" << displayModeName << "is not supported with the selected pixel format"; goto bail; } if (inputFlags & bmdVideoInputDualStream3D){ if (!(displayMode->GetFlags() & bmdDisplayModeSupports3D)){ ofLogError(LOG_NAME) << "The display mode" << displayModeName << "is not supported with 3D"; goto bail; } } break; } displayModeCount++; displayMode->Release(); } if (!foundDisplayMode){ ofLogError(LOG_NAME) << "Invalid mode" << g_videoModeIndex << "specified"; goto bail; } result = deckLinkInput->EnableVideoInput(selectedDisplayMode, pixelFormat, inputFlags); if(result != S_OK){ ofLogError(LOG_NAME) << "Failed to enable video input. Is another application using the card?"; goto bail; } #if 0 // no audio by now result = deckLinkInput->EnableAudioInput(bmdAudioSampleRate48kHz, g_audioSampleDepth, g_audioChannels); if(result != S_OK){ goto bail; } #endif result = deckLinkInput->StartStreams(); if(result != S_OK){ goto bail; } // All Okay. exitStatus = 0; return true; bail: if (displayModeIterator != NULL){ displayModeIterator->Release(); displayModeIterator = NULL; } if (deckLinkIterator != NULL) deckLinkIterator->Release(); close(); return false; }
static void print_output_modes (IDeckLink* deckLink) { IDeckLinkOutput* deckLinkOutput = NULL; IDeckLinkDisplayModeIterator* displayModeIterator = NULL; IDeckLinkDisplayMode* displayMode = NULL; HRESULT result; // Query the DeckLink for its configuration interface result = deckLink->QueryInterface(IID_IDeckLinkOutput, (void**)&deckLinkOutput); if (result != S_OK) { fprintf(stderr, "Could not obtain the IDeckLinkOutput interface - result = %08x\n", result); goto bail; } // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output result = deckLinkOutput->GetDisplayModeIterator(&displayModeIterator); if (result != S_OK) { fprintf(stderr, "Could not obtain the video output display mode iterator - result = %08x\n", result); goto bail; } // List all supported output display modes printf("Supported video output display modes and pixel formats:\n"); while (displayModeIterator->Next(&displayMode) == S_OK) { CFStringRef displayModeString; result = displayMode->GetName(&displayModeString); if (result == S_OK) { char modeName[64]; int modeWidth; int modeHeight; BMDTimeValue frameRateDuration; BMDTimeScale frameRateScale; int pixelFormatIndex = 0; // index into the gKnownPixelFormats / gKnownFormatNames arrays BMDDisplayModeSupport displayModeSupport; // Obtain the display mode's properties modeWidth = displayMode->GetWidth(); modeHeight = displayMode->GetHeight(); displayMode->GetFrameRate(&frameRateDuration, &frameRateScale); printf(" %-20s \t %d x %d \t %7g FPS\t", displayModeString, modeWidth, modeHeight, (double)frameRateScale / (double)frameRateDuration); // Print the supported pixel formats for this display mode while ((gKnownPixelFormats[pixelFormatIndex] != 0) && (gKnownPixelFormatNames[pixelFormatIndex] != NULL)) { if ((deckLinkOutput->DoesSupportVideoMode(displayMode->GetDisplayMode(), gKnownPixelFormats[pixelFormatIndex], bmdVideoOutputFlagDefault, &displayModeSupport, NULL) == S_OK) && (displayModeSupport != bmdDisplayModeNotSupported)) { printf("%s\t", gKnownPixelFormatNames[pixelFormatIndex]); } pixelFormatIndex++; } printf("\n"); // free(displayModeString); } // Release the IDeckLinkDisplayMode object to prevent a leak displayMode->Release(); } printf("\n"); bail: // Ensure that the interfaces we obtained are released to prevent a memory leak if (displayModeIterator != NULL) displayModeIterator->Release(); if (deckLinkOutput != NULL) deckLinkOutput->Release(); }
av_cold int ff_decklink_write_header(AVFormatContext *avctx) { struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data; struct decklink_ctx *ctx; IDeckLinkDisplayModeIterator *itermode; IDeckLinkIterator *iter; IDeckLink *dl = NULL; unsigned int n; ctx = (struct decklink_ctx *) av_mallocz(sizeof(struct decklink_ctx)); if (!ctx) return AVERROR(ENOMEM); ctx->list_devices = cctx->list_devices; ctx->list_formats = cctx->list_formats; ctx->preroll = cctx->preroll; cctx->ctx = ctx; iter = CreateDeckLinkIteratorInstance(); if (!iter) { av_log(avctx, AV_LOG_ERROR, "Could not create DeckLink iterator\n"); return AVERROR(EIO); } /* List available devices. */ if (ctx->list_devices) { ff_decklink_list_devices(avctx); return AVERROR_EXIT; } /* Open device. */ while (iter->Next(&dl) == S_OK) { const char *displayName; ff_decklink_get_display_name(dl, &displayName); if (!strcmp(avctx->filename, displayName)) { av_free((void *) displayName); ctx->dl = dl; break; } av_free((void *) displayName); dl->Release(); } iter->Release(); if (!ctx->dl) { av_log(avctx, AV_LOG_ERROR, "Could not open '%s'\n", avctx->filename); return AVERROR(EIO); } /* Get output device. */ if (ctx->dl->QueryInterface(IID_IDeckLinkOutput, (void **) &ctx->dlo) != S_OK) { av_log(avctx, AV_LOG_ERROR, "Could not open output device from '%s'\n", avctx->filename); ctx->dl->Release(); return AVERROR(EIO); } /* List supported formats. */ if (ctx->list_formats) { ff_decklink_list_formats(avctx); ctx->dlo->Release(); ctx->dl->Release(); return AVERROR_EXIT; } if (ctx->dlo->GetDisplayModeIterator(&itermode) != S_OK) { av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode Iterator\n"); ctx->dl->Release(); return AVERROR(EIO); } /* Setup streams. */ for (n = 0; n < avctx->nb_streams; n++) { AVStream *st = avctx->streams[n]; AVCodecContext *c = st->codec; if (c->codec_type == AVMEDIA_TYPE_AUDIO) { if (decklink_setup_audio(avctx, st)) goto error; } else if (c->codec_type == AVMEDIA_TYPE_VIDEO) { if (decklink_setup_video(avctx, st)) goto error; } else { av_log(avctx, AV_LOG_ERROR, "Unsupported stream type.\n"); goto error; } } itermode->Release(); return 0; error: ctx->dlo->Release(); ctx->dl->Release(); return AVERROR(EIO); }
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); }
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; }
av_cold int ff_decklink_read_header(AVFormatContext *avctx) { struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data; struct decklink_ctx *ctx; IDeckLinkDisplayModeIterator *itermode; IDeckLinkIterator *iter; IDeckLink *dl = NULL; AVStream *st; HRESULT result; char fname[1024]; char *tmp; int mode_num = 0; ctx = (struct decklink_ctx *) av_mallocz(sizeof(struct decklink_ctx)); if (!ctx) return AVERROR(ENOMEM); ctx->list_devices = cctx->list_devices; ctx->list_formats = cctx->list_formats; ctx->preroll = cctx->preroll; cctx->ctx = ctx; iter = CreateDeckLinkIteratorInstance(); if (!iter) { av_log(avctx, AV_LOG_ERROR, "Could not create DeckLink iterator\n"); return AVERROR(EIO); } /* List available devices. */ if (ctx->list_devices) { ff_decklink_list_devices(avctx); return AVERROR_EXIT; } strcpy (fname, avctx->filename); tmp=strchr (fname, '@'); if (tmp != NULL) { mode_num = atoi (tmp+1); *tmp = 0; } /* Open device. */ while (iter->Next(&dl) == S_OK) { const char *displayName; ff_decklink_get_display_name(dl, &displayName); if (!strcmp(fname, displayName)) { av_free((void *) displayName); ctx->dl = dl; break; } av_free((void *) displayName); dl->Release(); } iter->Release(); if (!ctx->dl) { av_log(avctx, AV_LOG_ERROR, "Could not open '%s'\n", fname); return AVERROR(EIO); } /* Get input device. */ if (ctx->dl->QueryInterface(IID_IDeckLinkInput, (void **) &ctx->dli) != S_OK) { av_log(avctx, AV_LOG_ERROR, "Could not open output device from '%s'\n", avctx->filename); ctx->dl->Release(); return AVERROR(EIO); } /* List supported formats. */ if (ctx->list_formats) { ff_decklink_list_formats(avctx, DIRECTION_IN); ctx->dli->Release(); ctx->dl->Release(); return AVERROR_EXIT; } if (ctx->dli->GetDisplayModeIterator(&itermode) != S_OK) { av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode Iterator\n"); ctx->dl->Release(); return AVERROR(EIO); } if (mode_num > 0) { if (ff_decklink_set_format(avctx, DIRECTION_IN, mode_num) < 0) { av_log(avctx, AV_LOG_ERROR, "Could not set mode %d for %s\n", mode_num, fname); goto error; } } itermode->Release(); /* Setup streams. */ st = avformat_new_stream(avctx, NULL); if (!st) { av_log(avctx, AV_LOG_ERROR, "Cannot add stream\n"); goto error; } st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = AV_CODEC_ID_PCM_S16LE; st->codec->sample_rate = bmdAudioSampleRate48kHz; st->codec->channels = 2; avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ ctx->audio_st=st; st = avformat_new_stream(avctx, NULL); if (!st) { av_log(avctx, AV_LOG_ERROR, "Cannot add stream\n"); goto error; } st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = AV_CODEC_ID_RAWVIDEO; st->codec->width = ctx->bmd_width; st->codec->height = ctx->bmd_height; st->codec->pix_fmt = AV_PIX_FMT_UYVY422; st->codec->time_base.den = ctx->bmd_tb_den; st->codec->time_base.num = ctx->bmd_tb_num; st->codec->bit_rate = avpicture_get_size(st->codec->pix_fmt, ctx->bmd_width, ctx->bmd_height) * 1/av_q2d(st->codec->time_base) * 8; st->codec->codec_tag = MKTAG('U', 'Y', 'V', 'Y'); avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ ctx->video_st=st; result = ctx->dli->EnableAudioInput(bmdAudioSampleRate48kHz, bmdAudioSampleType16bitInteger, 2); if (result != S_OK) { av_log(avctx, AV_LOG_ERROR, "Cannot enable audio input\n"); goto error; } result = ctx->dli->EnableVideoInput(ctx->bmd_mode, bmdFormat8BitYUV, bmdVideoInputFlagDefault); if (result != S_OK) { av_log(avctx, AV_LOG_ERROR, "Cannot enable video input\n"); goto error; } avpacket_queue_init (avctx, &ctx->queue); if (decklink_start_input (avctx) != S_OK) { av_log(avctx, AV_LOG_ERROR, "Cannot start input stream\n"); goto error; } return 0; error: ctx->dli->Release(); ctx->dl->Release(); return AVERROR(EIO); }
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(); } }
void SignalGenerator::setup() { IDeckLinkIterator* deckLinkIterator = NULL; bool success = false; // **** Find a DeckLink instance and obtain video output interface deckLinkIterator = CreateDeckLinkIteratorInstance(); if (deckLinkIterator == NULL) { QMessageBox::critical(this, "This application requires the DeckLink drivers installed.", "Please install the Blackmagic DeckLink drivers to use the features of this application."); goto bail; } // Connect to the first DeckLink instance if (deckLinkIterator->Next(&deckLink) != S_OK) { QMessageBox::critical(this, "This application requires a DeckLink PCI card.", "You will not be able to use the features of this application until a DeckLink PCI card is installed."); goto bail; } // Obtain the audio/video output interface (IDeckLinkOutput) if (deckLink->QueryInterface(IID_IDeckLinkOutput, (void**)&deckLinkOutput) != S_OK) goto bail; // Create a delegate class to allow the DeckLink API to call into our code playerDelegate = new PlaybackDelegate(this, deckLinkOutput); if (playerDelegate == NULL) goto bail; // Provide the delegate to the audio and video output interfaces deckLinkOutput->SetScheduledFrameCompletionCallback(playerDelegate); deckLinkOutput->SetAudioCallback(playerDelegate); // Populate the display mode menu with a list of display modes supported by the installed DeckLink card IDeckLinkDisplayModeIterator* displayModeIterator; IDeckLinkDisplayMode* deckLinkDisplayMode; ui->videoFormatPopup->clear(); if (deckLinkOutput->GetDisplayModeIterator(&displayModeIterator) != S_OK) goto bail; while (displayModeIterator->Next(&deckLinkDisplayMode) == S_OK) { const char * modeName; if (deckLinkDisplayMode->GetName(&modeName) == S_OK) { ui->videoFormatPopup->addItem(modeName, QVariant::fromValue((void *)deckLinkDisplayMode)); } } displayModeIterator->Release(); enableInterface(true); deckLinkOutput->SetScreenPreviewCallback(previewView); success = true; bail: if (success == false) { // Release any resources that were partially allocated if (deckLinkOutput != NULL) { deckLinkOutput->Release(); deckLinkOutput = NULL; } // if (deckLink != NULL) { deckLink->Release(); deckLink = NULL; } // Disable the user interface if we could not succsssfully connect to a DeckLink device ui->startButton->setEnabled(false); enableInterface(false); } if (deckLinkIterator != NULL) deckLinkIterator->Release(); }
int ff_decklink_set_format(AVFormatContext *avctx, int width, int height, int tb_num, int tb_den, decklink_direction_t direction, int num) { struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data; struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; BMDDisplayModeSupport support; IDeckLinkDisplayModeIterator *itermode; IDeckLinkDisplayMode *mode; int i = 1; HRESULT res; if (direction == DIRECTION_IN) { res = ctx->dli->GetDisplayModeIterator (&itermode); } else { res = ctx->dlo->GetDisplayModeIterator (&itermode); } if (res!= S_OK) { av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode Iterator\n"); return AVERROR(EIO); } if (tb_num == 1) { tb_num *= 1000; tb_den *= 1000; } ctx->bmd_mode = bmdModeUnknown; while ((ctx->bmd_mode == bmdModeUnknown) && itermode->Next(&mode) == S_OK) { BMDTimeValue bmd_tb_num, bmd_tb_den; int bmd_width = mode->GetWidth(); int bmd_height = mode->GetHeight(); mode->GetFrameRate(&bmd_tb_num, &bmd_tb_den); if ((bmd_width == width && bmd_height == height && bmd_tb_num == tb_num && bmd_tb_den == tb_den) || i == num) { ctx->bmd_mode = mode->GetDisplayMode(); ctx->bmd_width = bmd_width; ctx->bmd_height = bmd_height; ctx->bmd_tb_den = bmd_tb_den; ctx->bmd_tb_num = bmd_tb_num; ctx->bmd_field_dominance = mode->GetFieldDominance(); av_log(avctx, AV_LOG_INFO, "Found Decklink mode %d x %d with rate %.2f%s\n", bmd_width, bmd_height, (float)bmd_tb_den/(float)bmd_tb_num, (ctx->bmd_field_dominance==bmdLowerFieldFirst || ctx->bmd_field_dominance==bmdUpperFieldFirst)?"(i)":""); } mode->Release(); i++; } itermode->Release(); if (ctx->bmd_mode == bmdModeUnknown) return -1; if (direction == DIRECTION_IN) { if (ctx->dli->DoesSupportVideoMode(ctx->bmd_mode, bmdFormat8BitYUV, bmdVideoOutputFlagDefault, &support, NULL) != S_OK) return -1; } else { if (ctx->dlo->DoesSupportVideoMode(ctx->bmd_mode, bmdFormat8BitYUV, bmdVideoOutputFlagDefault, &support, NULL) != S_OK) return -1; } if (support == bmdDisplayModeSupported) return 0; return -1; }
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; }