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; }
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; }
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; }
int usage (int status) { HRESULT result; IDeckLinkDisplayMode *displayMode; int displayModeCount = 0; fprintf (stderr, "Usage: Capture -m <mode id> [OPTIONS]\n" "\n" " -m <mode id>:\n"); while (displayModeIterator->Next (&displayMode) == S_OK) { char *displayModeString = NULL; result = displayMode->GetName ((const char **) &displayModeString); if (result == S_OK) { BMDTimeValue frameRateDuration, frameRateScale; displayMode->GetFrameRate (&frameRateDuration, &frameRateScale); fprintf (stderr, " %2d: %-20s \t %li x %li \t %g FPS\n", displayModeCount, displayModeString, displayMode->GetWidth (), displayMode->GetHeight (), (double) frameRateScale / (double) frameRateDuration); free (displayModeString); displayModeCount++; } // Release the IDeckLinkDisplayMode object to prevent a leak displayMode->Release (); } 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" " -f <filename> Filename raw video will be written to\n" " -a <filename> Filename raw audio will be written to\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 -m2 -n 50 -f video.raw -a audio.raw\n" " mplayer video.raw -demuxer rawvideo -rawvideo pal:uyvy -audiofile audio.raw -audio-demuxer 20 -rawaudio rate=48000\n"); exit (status); }
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; }
//---------- 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; 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; }
void Player::StartRunning(int videomode) { IDeckLinkDisplayMode *videoDisplayMode = NULL; unsigned long audioSamplesPerFrame; // Get the display mode for 1080i 59.95 videoDisplayMode = GetDisplayModeByIndex(videomode); if (!videoDisplayMode) return; m_frameWidth = videoDisplayMode->GetWidth(); m_frameHeight = videoDisplayMode->GetHeight(); videoDisplayMode->GetFrameRate(&m_frameDuration, &m_frameTimescale); // Set the video output mode if (m_deckLinkOutput->EnableVideoOutput(videoDisplayMode->GetDisplayMode(), bmdVideoOutputFlagDefault) != S_OK) { fprintf(stderr, "Failed to enable video output\n"); return; } // Set the audio output mode if (m_deckLinkOutput->EnableAudioOutput(bmdAudioSampleRate48kHz, m_audioSampleDepth, audio_st->codec->channels, bmdAudioOutputStreamTimestamped) != S_OK) { fprintf(stderr, "Failed to enable audio output\n"); return; } for (unsigned i = 0; i < 10; i++) ScheduleNextFrame(true); // Begin audio preroll. This will begin calling our audio callback, which will start the DeckLink output stream. // m_audioBufferOffset = 0; if (m_deckLinkOutput->BeginAudioPreroll() != S_OK) { fprintf(stderr, "Failed to begin audio preroll\n"); return; } m_running = true; return; }
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 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(); } }
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; }
int ff_decklink_set_format(AVFormatContext *avctx, int width, int height, int tb_num, int tb_den, enum AVFieldOrder field_order, 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; av_log(avctx, AV_LOG_DEBUG, "Trying to find mode for frame size %dx%d, frame timing %d/%d, field order %d, direction %d, mode number %d, format code %s\n", width, height, tb_num, tb_den, field_order, direction, num, (cctx->format_code) ? cctx->format_code : "(unset)"); if (ctx->duplex_mode) { DECKLINK_BOOL duplex_supported = false; if (ctx->attr->GetFlag(BMDDeckLinkSupportsDuplexModeConfiguration, &duplex_supported) != S_OK) duplex_supported = false; if (duplex_supported) { res = ctx->cfg->SetInt(bmdDeckLinkConfigDuplexMode, ctx->duplex_mode == 2 ? bmdDuplexModeFull : bmdDuplexModeHalf); if (res != S_OK) av_log(avctx, AV_LOG_WARNING, "Setting duplex mode failed.\n"); else av_log(avctx, AV_LOG_VERBOSE, "Successfully set duplex mode to %s duplex.\n", ctx->duplex_mode == 2 ? "full" : "half"); } else { av_log(avctx, AV_LOG_WARNING, "Unable to set duplex mode, because it is not supported.\n"); } } 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); } char format_buf[] = " "; if (cctx->format_code) memcpy(format_buf, cctx->format_code, FFMIN(strlen(cctx->format_code), sizeof(format_buf))); BMDDisplayMode target_mode = (BMDDisplayMode)AV_RB32(format_buf); AVRational target_tb = av_make_q(tb_num, tb_den); 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(); BMDDisplayMode bmd_mode = mode->GetDisplayMode(); BMDFieldDominance bmd_field_dominance = mode->GetFieldDominance(); mode->GetFrameRate(&bmd_tb_num, &bmd_tb_den); AVRational mode_tb = av_make_q(bmd_tb_num, bmd_tb_den); if ((bmd_width == width && bmd_height == height && !av_cmp_q(mode_tb, target_tb) && field_order_eq(field_order, bmd_field_dominance)) || i == num || target_mode == bmd_mode) { ctx->bmd_mode = bmd_mode; 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 = bmd_field_dominance; av_log(avctx, AV_LOG_INFO, "Found Decklink mode %d x %d with rate %.2f%s\n", bmd_width, bmd_height, 1/av_q2d(mode_tb), (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; }
void CSignalGeneratorDlg::StartRunning () { IDeckLinkDisplayMode* videoDisplayMode = NULL; BMDVideoOutputFlags videoOutputFlags = bmdVideoOutputFlagDefault; int curSelection; CString videoFormatName; curSelection = m_videoFormatCombo.GetCurSel(); m_videoFormatCombo.GetLBText(curSelection, videoFormatName); if (videoFormatName.Find(_T(" 3D"), 0) != -1) videoOutputFlags = bmdVideoOutputDualStream3D; // Determine the audio and video properties for the output stream m_outputSignal = (OutputSignal)m_outputSignalCombo.GetCurSel(); m_audioChannelCount = m_audioChannelCombo.GetItemData(m_audioChannelCombo.GetCurSel()); m_audioSampleDepth = (BMDAudioSampleType)m_audioSampleDepthCombo.GetItemData(m_audioSampleDepthCombo.GetCurSel()); m_audioSampleRate = bmdAudioSampleRate48kHz; // // - Extract the IDeckLinkDisplayMode from the display mode popup menu (stashed in the item's tag) videoDisplayMode = (IDeckLinkDisplayMode*)m_videoFormatCombo.GetItemDataPtr(m_videoFormatCombo.GetCurSel()); m_frameWidth = videoDisplayMode->GetWidth(); m_frameHeight = videoDisplayMode->GetHeight(); videoDisplayMode->GetFrameRate(&m_frameDuration, &m_frameTimescale); // Calculate the number of frames per second, rounded up to the nearest integer. For example, for NTSC (29.97 FPS), framesPerSecond == 30. m_framesPerSecond = (unsigned long)((m_frameTimescale + (m_frameDuration-1)) / m_frameDuration); // Set the video output mode if (m_deckLinkOutput->EnableVideoOutput(videoDisplayMode->GetDisplayMode(), videoOutputFlags) != S_OK) goto bail; // Set the audio output mode if (m_deckLinkOutput->EnableAudioOutput(bmdAudioSampleRate48kHz, m_audioSampleDepth, m_audioChannelCount, bmdAudioOutputStreamTimestamped) != S_OK) goto bail; // Generate one second of audio tone m_audioSamplesPerFrame = (unsigned long)((m_audioSampleRate * m_frameDuration) / m_frameTimescale); m_audioBufferSampleLength = (unsigned long)((m_framesPerSecond * m_audioSampleRate * m_frameDuration) / m_frameTimescale); m_audioBuffer = HeapAlloc(GetProcessHeap(), 0, (m_audioBufferSampleLength * m_audioChannelCount * (m_audioSampleDepth / 8))); if (m_audioBuffer == NULL) goto bail; FillSine(m_audioBuffer, m_audioBufferSampleLength, m_audioChannelCount, m_audioSampleDepth); // Generate a frame of black m_videoFrameBlack = CreateBlackFrame(); if (! m_videoFrameBlack) goto bail; // Generate a frame of colour bars m_videoFrameBars = CreateBarsFrame(); if (! m_videoFrameBars) goto bail; // Begin video preroll by scheduling a second of frames in hardware m_totalFramesScheduled = 0; for (unsigned i = 0; i < m_framesPerSecond; i++) ScheduleNextFrame(true); // Begin audio preroll. This will begin calling our audio callback, which will start the DeckLink output stream. m_totalAudioSecondsScheduled = 0; if (m_deckLinkOutput->BeginAudioPreroll() != S_OK) goto bail; // Success; update the UI m_running = true; m_startButton.SetWindowText(_T("Stop")); // Disable the user interface while running (prevent the user from making changes to the output signal) EnableInterface(FALSE); return; bail: // *** Error-handling code. Cleanup any resources that were allocated. *** // StopRunning(); }
void SignalGenerator::startRunning() { IDeckLinkDisplayMode* videoDisplayMode = NULL; BMDVideoOutputFlags videoOutputFlags = 0; QVariant v; // Determine the audio and video properties for the output stream v = ui->outputSignalPopup->itemData(ui->outputSignalPopup->currentIndex()); outputSignal = (OutputSignal)v.value<int>(); v = ui->audioChannelPopup->itemData(ui->audioChannelPopup->currentIndex()); audioChannelCount = v.value<int>(); v = ui->audioSampleDepthPopup->itemData(ui->audioSampleDepthPopup->currentIndex()); audioSampleDepth = v.value<int>(); audioSampleRate = bmdAudioSampleRate48kHz; // // - Extract the IDeckLinkDisplayMode from the display mode popup menu (stashed in the item's tag) v = ui->videoFormatPopup->itemData(ui->videoFormatPopup->currentIndex()); videoDisplayMode = (IDeckLinkDisplayMode *)v.value<void*>(); frameWidth = videoDisplayMode->GetWidth(); frameHeight = videoDisplayMode->GetHeight(); videoDisplayMode->GetFrameRate(&frameDuration, &frameTimescale); // Calculate the number of frames per second, rounded up to the nearest integer. For example, for NTSC (29.97 FPS), framesPerSecond == 30. framesPerSecond = (frameTimescale + (frameDuration-1)) / frameDuration; if (videoDisplayMode->GetDisplayMode() == bmdModeNTSC || videoDisplayMode->GetDisplayMode() == bmdModeNTSC2398 || videoDisplayMode->GetDisplayMode() == bmdModePAL) { timeCodeFormat = bmdTimecodeVITC; videoOutputFlags |= bmdVideoOutputVITC; } else { timeCodeFormat = bmdTimecodeRP188Any; videoOutputFlags |= bmdVideoOutputRP188; } if (timeCode) delete timeCode; timeCode = new Timecode(framesPerSecond); // Set the video output mode if (deckLinkOutput->EnableVideoOutput(videoDisplayMode->GetDisplayMode(), videoOutputFlags) != S_OK) goto bail; // Set the audio output mode if (deckLinkOutput->EnableAudioOutput(bmdAudioSampleRate48kHz, audioSampleDepth, audioChannelCount, bmdAudioOutputStreamTimestamped) != S_OK) goto bail; // Generate one second of audio tone audioSamplesPerFrame = ((audioSampleRate * frameDuration) / frameTimescale); audioBufferSampleLength = (framesPerSecond * audioSampleRate * frameDuration) / frameTimescale; audioBuffer = malloc(audioBufferSampleLength * audioChannelCount * (audioSampleDepth / 8)); if (audioBuffer == NULL) goto bail; FillSine(audioBuffer, audioBufferSampleLength, audioChannelCount, audioSampleDepth); // Generate a frame of black if (deckLinkOutput->CreateVideoFrame(frameWidth, frameHeight, frameWidth*2, bmdFormat8BitYUV, bmdFrameFlagDefault, &videoFrameBlack) != S_OK) goto bail; FillBlack(videoFrameBlack); // Generate a frame of colour bars if (deckLinkOutput->CreateVideoFrame(frameWidth, frameHeight, frameWidth*2, bmdFormat8BitYUV, bmdFrameFlagDefault, &videoFrameBars) != S_OK) goto bail; FillColourBars(videoFrameBars); // Begin video preroll by scheduling a second of frames in hardware totalFramesScheduled = 0; for (unsigned int i = 0; i < framesPerSecond; i++) scheduleNextFrame(true); // Begin audio preroll. This will begin calling our audio callback, which will start the DeckLink output stream. totalAudioSecondsScheduled = 0; if (deckLinkOutput->BeginAudioPreroll() != S_OK) goto bail; // Success; update the UI running = true; ui->startButton->setText("Stop"); // Disable the user interface while running (prevent the user from making changes to the output signal) enableInterface(false); return; bail: QMessageBox::critical(this, "Failed to start output", "Failed to start output"); // *** Error-handling code. Cleanup any resources that were allocated. *** // stopRunning(); }
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; }
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; }
/** * process the arugments * return negative value of failed */ int Window::processArguments(int argc, char* argv[]){ IDeckLinkAttributes *deckLinkAttributes = NULL; DeckLinkCaptureDelegate *delegate; IDeckLinkDisplayMode *displayMode; BMDVideoInputFlags inputFlags = 0; BMDDisplayMode selectedDisplayMode = bmdModeNTSC; BMDPixelFormat pixelFormat = bmdFormat8BitYUV; int displayModeCount = 0; int exitStatus = 1; int ch; bool foundDisplayMode = false; HRESULT result; int dnum = 0; IDeckLink *tempLink = NULL; int found = 0; bool supported = 0; int64_t ports; int itemCount; int vinput = 0; int64_t vport = 0; IDeckLinkConfiguration *deckLinkConfiguration = NULL; bool flickerremoval = true; bool pnotpsf = true; // Parse command line options while ((ch = getopt(argc, argv, "?h3c:d:s:f:a:m:n:p:t:u::vi:jy")) != -1) { switch (ch) { case 'i': vinput = atoi(optarg); break; case 'd': card = atoi(optarg); break; case 'm': g_videoModeIndex = atoi(optarg); break; case 'n': g_maxFrames = atoi(optarg); break; case '3': inputFlags |= bmdVideoInputDualStream3D; break; case 'p': switch(atoi(optarg)) { case 0: pixelFormat = bmdFormat8BitYUV; break; case 1: pixelFormat = bmdFormat10BitYUV; break; case 2: pixelFormat = bmdFormat10BitRGB; break; default: fprintf(stderr, "Invalid argument: Pixel format %d is not valid", atoi(optarg)); exit(1); } break; case 't': if (!strcmp(optarg, "rp188")) g_timecodeFormat = bmdTimecodeRP188Any; else if (!strcmp(optarg, "vitc")) g_timecodeFormat = bmdTimecodeVITC; else if (!strcmp(optarg, "serial")) g_timecodeFormat = bmdTimecodeSerial; else { fprintf(stderr, "Invalid argument: Timecode format \"%s\" is invalid\n", optarg); exit(1); } break; case '?': case 'h': usage(); } } if (!deckLinkIterator) { fprintf(stderr, "This application requires the DeckLink drivers installed.\n"); return -1; } /* Connect to the first DeckLink instance */ while (deckLinkIterator->Next(&tempLink) == S_OK) { if (card != dnum) { dnum++; // Release the IDeckLink instance when we've finished with it to prevent leaks tempLink->Release(); continue; } else { deckLink = tempLink; found = 1; } dnum++; } if (! found ) { fprintf(stderr, "No DeckLink PCI cards found.\n"); return -1; } if (deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput) != S_OK) return -1; // Query the DeckLink for its attributes interface result = deckLink->QueryInterface(IID_IDeckLinkAttributes, (void**)&deckLinkAttributes); if (result != S_OK) { fprintf(stderr, "Could not obtain the IDeckLinkAttributes interface - result = %08x\n", result); } result = deckLinkAttributes->GetFlag(BMDDeckLinkSupportsInputFormatDetection, &supported); if (result == S_OK) { fprintf(stderr, " %-40s %s\n", "Input mode detection supported ?", (supported == true) ? "Yes" : "No"); } else { fprintf(stderr, "Could not query the input mode detection attribute- result = %08x\n", result); } fprintf(stderr, "Supported video input connections (-i [input #]:\n "); itemCount = 0; result = deckLinkAttributes->GetInt(BMDDeckLinkVideoInputConnections, &ports); if (result == S_OK) { if (ports & bmdVideoConnectionSDI) { fprintf(stderr, "%d: SDI, ", bmdVideoConnectionSDI); itemCount++; } if (ports & bmdVideoConnectionHDMI) { fprintf(stderr, "%d: HDMI, ", bmdVideoConnectionHDMI); itemCount++; } if (ports & bmdVideoConnectionOpticalSDI) { fprintf(stderr, "%d: Optical SDI, ", bmdVideoConnectionOpticalSDI); itemCount++; } if (ports & bmdVideoConnectionComponent) { fprintf(stderr, "%d: Component, ", bmdVideoConnectionComponent); itemCount++; } if (ports & bmdVideoConnectionComposite) { fprintf(stderr, "%d: Composite, ", bmdVideoConnectionComposite); itemCount++; } if (ports & bmdVideoConnectionSVideo) { fprintf(stderr, "%d: S-Video, ", bmdVideoConnectionSVideo); itemCount++; } } fprintf(stderr, "\n"); //glWidget->initShaderProgram(); delegate = new DeckLinkCaptureDelegate(glWidget); connect(delegate, SIGNAL(updateGLSignal()), glWidget, SLOT(updateGLSlot())); deckLinkInput->SetCallback(delegate); // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output result = deckLinkInput->GetDisplayModeIterator(&displayModeIterator); if (result != S_OK) { fprintf(stderr, "Could not obtain the video output display mode iterator - result = %08x\n", result); return -1; } if (g_videoModeIndex < 0) { fprintf(stderr, "No video mode specified\n"); usage(); return -1; } while (displayModeIterator->Next(&displayMode) == S_OK) { if (g_videoModeIndex == displayModeCount) { BMDDisplayModeSupport result; const char *displayModeName; foundDisplayMode = true; displayMode->GetName(&displayModeName); selectedDisplayMode = displayMode->GetDisplayMode(); deckLinkInput->DoesSupportVideoMode(selectedDisplayMode, pixelFormat, bmdVideoInputFlagDefault, &result, NULL); if (result == bmdDisplayModeNotSupported) { fprintf(stderr, "The display mode %s is not supported with the selected pixel format\n", displayModeName); return -1; } if (inputFlags & bmdVideoInputDualStream3D) { if (!(displayMode->GetFlags() & bmdDisplayModeSupports3D)) { fprintf(stderr, "The display mode %s is not supported with 3D\n", displayModeName); return -1; } } fprintf(stderr, "Selecting mode: %s\n", displayModeName); break; } displayModeCount++; displayMode->Release(); } if (!foundDisplayMode) { fprintf(stderr, "Invalid mode %d specified\n", g_videoModeIndex); return -1; } // Query the DeckLink for its configuration interface result = deckLinkInput->QueryInterface(IID_IDeckLinkConfiguration, (void**)&deckLinkConfiguration); if (result != S_OK) { fprintf(stderr, "Could not obtain the IDeckLinkConfiguration interface: %08x\n", result); } BMDVideoConnection conn; switch (vinput) { case 0: conn = bmdVideoConnectionSDI; break; case 1: conn = bmdVideoConnectionHDMI; break; case 2: conn = bmdVideoConnectionComponent; break; case 3: conn = bmdVideoConnectionComposite; break; case 4: conn = bmdVideoConnectionSVideo; break; case 5: conn = bmdVideoConnectionOpticalSDI; break; default: break; } conn = vinput; // Set the input desired result = deckLinkConfiguration->SetInt(bmdDeckLinkConfigVideoInputConnection, conn); if(result != S_OK) { fprintf(stderr, "Cannot set the input to [%d]\n", conn); return -1; } // check input result = deckLinkConfiguration->GetInt(bmdDeckLinkConfigVideoInputConnection, &vport); if (vport == bmdVideoConnectionSDI) fprintf(stderr, "Before Input configured for SDI\n"); if (vport == bmdVideoConnectionHDMI) fprintf(stderr, "Before Input configured for HDMI\n"); if (deckLinkConfiguration->SetFlag(bmdDeckLinkConfigFieldFlickerRemoval, flickerremoval) == S_OK) { fprintf(stderr, "Flicker removal set : %d\n", flickerremoval); } else { fprintf(stderr, "Flicker removal NOT set\n"); } if (deckLinkConfiguration->SetFlag(bmdDeckLinkConfigUse1080pNotPsF, pnotpsf) == S_OK) { fprintf(stderr, "bmdDeckLinkConfigUse1080pNotPsF: %d\n", pnotpsf); } else { fprintf(stderr, "bmdDeckLinkConfigUse1080pNotPsF NOT set\n"); } //if (deckLinkConfiguration->SetFlag(bmdDeckLinkConfigVideoInputConnection, conn) == S_OK) { //fprintf(stderr, "Input set to: %d\n", vinput); //} result = deckLinkConfiguration->GetInt(bmdDeckLinkConfigVideoInputConnection, &vport); if (vport == bmdVideoConnectionSDI) fprintf(stderr, "After Input configured for SDI\n"); if (vport == bmdVideoConnectionHDMI) fprintf(stderr, "After Input configured for HDMI\n"); result = deckLinkInput->EnableVideoInput(selectedDisplayMode, pixelFormat, inputFlags); if(result != S_OK) { fprintf(stderr, "Failed to enable video input. Is another application using the card?\n"); return -1; } displayWidth = displayMode->GetWidth(); displayHeight = displayMode->GetHeight(); displayMode->GetFrameRate(&frameRateDuration, &frameRateScale); displayFPS = (double)frameRateScale / (double)frameRateDuration; //set to delegate delegate->setWidth(displayWidth); delegate->setHeight(displayHeight); delegate->setFPS(displayFPS); delegate->setFrameRateDuration(frameRateDuration); delegate->setFrameRateScale(frameRateScale); //set texture width and height glWidget->setTextureWidth(displayWidth); glWidget->setTextureHeight(displayHeight); glWidget->initBuffer(); fprintf(stderr, "GetFrameRate: %10ld %10ld --> fps %g\n", (long)frameRateScale, (long)frameRateDuration, displayFPS); result = deckLinkInput->StartStreams(); if(result != S_OK){ fprintf(stderr, "Cannot start streams...\n"); return -1; } fprintf(stderr, "Finish procesing arguments \n"); }
static int Open(vlc_object_t *p_this) { demux_t *demux = (demux_t*)p_this; demux_sys_t *sys; int ret = VLC_EGENERIC; int card_index; int physical_channels = 0; int rate; BMDVideoInputFlags flags = bmdVideoInputFlagDefault; /* Only when selected */ if (*demux->psz_access == '\0') return VLC_EGENERIC; /* Set up demux */ demux->pf_demux = NULL; demux->pf_control = Control; demux->info.i_update = 0; demux->info.i_title = 0; demux->info.i_seekpoint = 0; demux->p_sys = sys = (demux_sys_t*)calloc(1, sizeof(demux_sys_t)); if (!sys) return VLC_ENOMEM; vlc_mutex_init(&sys->pts_lock); sys->tenbits = var_InheritBool(p_this, "decklink-tenbits"); IDeckLinkIterator *decklink_iterator = CreateDeckLinkIteratorInstance(); if (!decklink_iterator) { msg_Err(demux, "DeckLink drivers not found."); goto finish; } card_index = var_InheritInteger(demux, "decklink-card-index"); if (card_index < 0) { msg_Err(demux, "Invalid card index %d", card_index); goto finish; } for (int i = 0; i <= card_index; i++) { if (sys->card) sys->card->Release(); if (decklink_iterator->Next(&sys->card) != S_OK) { msg_Err(demux, "DeckLink PCI card %d not found", card_index); goto finish; } } const char *model_name; if (sys->card->GetModelName(&model_name) != S_OK) model_name = "unknown"; msg_Dbg(demux, "Opened DeckLink PCI card %d (%s)", card_index, model_name); if (sys->card->QueryInterface(IID_IDeckLinkInput, (void**)&sys->input) != S_OK) { msg_Err(demux, "Card has no inputs"); goto finish; } /* Set up the video and audio sources. */ if (sys->card->QueryInterface(IID_IDeckLinkConfiguration, (void**)&sys->config) != S_OK) { msg_Err(demux, "Failed to get configuration interface"); goto finish; } if (sys->card->QueryInterface(IID_IDeckLinkAttributes, (void**)&sys->attributes) != S_OK) { msg_Err(demux, "Failed to get attributes interface"); goto finish; } if (GetVideoConn(demux) || GetAudioConn(demux)) goto finish; BMDPixelFormat fmt; fmt = sys->tenbits ? bmdFormat10BitYUV : bmdFormat8BitYUV; if (sys->attributes->GetFlag(BMDDeckLinkSupportsInputFormatDetection, &sys->autodetect) != S_OK) { msg_Err(demux, "Failed to query card attribute"); goto finish; } /* Get the list of display modes. */ IDeckLinkDisplayModeIterator *mode_it; if (sys->input->GetDisplayModeIterator(&mode_it) != S_OK) { msg_Err(demux, "Failed to enumerate display modes"); goto finish; } union { BMDDisplayMode id; char str[4]; } u; u.id = 0; char *mode; mode = var_CreateGetNonEmptyString(demux, "decklink-mode"); if (mode) sys->autodetect = false; // disable autodetection if mode was set if (sys->autodetect) { msg_Dbg(demux, "Card supports input format detection"); flags |= bmdVideoInputEnableFormatDetection; /* Enable a random format, we will reconfigure on format detection */ u.id = htonl(bmdModeHD1080p2997); } else { if (!mode || strlen(mode) < 3 || strlen(mode) > 4) { msg_Err(demux, "Invalid mode: \'%s\'", mode ? mode : ""); free(mode); goto finish; } msg_Dbg(demux, "Looking for mode \'%s\'", mode); memcpy(u.str, mode, 4); if (u.str[3] == '\0') u.str[3] = ' '; /* 'pal'\0 -> 'pal ' */ free(mode); } es_format_t video_fmt; video_fmt.video.i_width = 0; for (IDeckLinkDisplayMode *m;; m->Release()) { if ((mode_it->Next(&m) != S_OK) || !m) break; const char *mode_name; BMDTimeValue frame_duration, time_scale; uint32_t field_flags; const char *field = GetFieldDominance(m->GetFieldDominance(), &field_flags); BMDDisplayMode id = ntohl(m->GetDisplayMode()); if (m->GetName(&mode_name) != S_OK) mode_name = "unknown"; if (m->GetFrameRate(&frame_duration, &time_scale) != S_OK) { time_scale = 0; frame_duration = 1; } msg_Dbg(demux, "Found mode '%4.4s': %s (%dx%d, %.3f fps%s)", (char*)&id, mode_name, (int)m->GetWidth(), (int)m->GetHeight(), double(time_scale) / frame_duration, field); if (u.id == id) { video_fmt = GetModeSettings(demux, m); msg_Dbg(demux, "Using that mode"); } } mode_it->Release(); if (video_fmt.video.i_width == 0) { msg_Err(demux, "Unknown video mode `%4.4s\' specified.", (char*)&u.id); goto finish; } if (sys->input->EnableVideoInput(htonl(u.id), fmt, flags) != S_OK) { msg_Err(demux, "Failed to enable video input"); goto finish; } /* Set up audio. */ sys->channels = var_InheritInteger(demux, "decklink-audio-channels"); switch (sys->channels) { case 0: break; case 2: physical_channels = AOUT_CHANS_STEREO; break; case 8: physical_channels = AOUT_CHANS_7_1; break; //case 16: default: msg_Err(demux, "Invalid number of channels (%d), disabling audio", sys->channels); sys->channels = 0; } rate = var_InheritInteger(demux, "decklink-audio-rate"); if (rate > 0 && sys->channels > 0) { if (sys->input->EnableAudioInput(rate, bmdAudioSampleType16bitInteger, sys->channels) != S_OK) { msg_Err(demux, "Failed to enable audio input"); goto finish; } } sys->delegate = new DeckLinkCaptureDelegate(demux); sys->input->SetCallback(sys->delegate); if (sys->input->StartStreams() != S_OK) { msg_Err(demux, "Could not start streaming from SDI card. This could be caused " "by invalid video mode or flags, access denied, or card already in use."); goto finish; } msg_Dbg(demux, "added new video es %4.4s %dx%d", (char*)&video_fmt.i_codec, video_fmt.video.i_width, video_fmt.video.i_height); sys->video_es = es_out_Add(demux->out, &video_fmt); es_format_t audio_fmt; es_format_Init(&audio_fmt, AUDIO_ES, VLC_CODEC_S16N); audio_fmt.audio.i_channels = sys->channels; audio_fmt.audio.i_physical_channels = physical_channels; audio_fmt.audio.i_rate = rate; audio_fmt.audio.i_bitspersample = 16; audio_fmt.audio.i_blockalign = audio_fmt.audio.i_channels * audio_fmt.audio.i_bitspersample / 8; audio_fmt.i_bitrate = audio_fmt.audio.i_channels * audio_fmt.audio.i_rate * audio_fmt.audio.i_bitspersample; msg_Dbg(demux, "added new audio es %4.4s %dHz %dbpp %dch", (char*)&audio_fmt.i_codec, audio_fmt.audio.i_rate, audio_fmt.audio.i_bitspersample, audio_fmt.audio.i_channels); sys->audio_es = es_out_Add(demux->out, &audio_fmt); ret = VLC_SUCCESS; finish: if (decklink_iterator) decklink_iterator->Release(); if (ret != VLC_SUCCESS) Close(p_this); return ret; }
// 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 BMDOutputDelegate::StartRunning () { IDeckLinkDisplayMode* videoDisplayMode = NULL; // Get the display mode for 1080i 59.95 - mode 6 // Changed to NTSC 23.98 - JB 20110215 videoDisplayMode = GetDisplayModeByIndex(1); if (!videoDisplayMode) return; m_frameWidth = videoDisplayMode->GetWidth(); m_frameHeight = videoDisplayMode->GetHeight(); videoDisplayMode->GetFrameRate(&m_frameDuration, &m_frameTimescale); // Calculate the number of frames per second, rounded up to the nearest integer. For example, for NTSC (29.97 FPS), framesPerSecond == 30. m_framesPerSecond = (unsigned long)((m_frameTimescale + (m_frameDuration-1)) / m_frameDuration); QImage image(m_frameWidth,m_frameHeight, QImage::Format_ARGB32); image.fill(Qt::green); //m_frame = VideoFramePtr(new VideoFrame(image, 1000/30)); HRESULT res; // Set the video output mode if (m_deckLinkOutput->EnableVideoOutput(videoDisplayMode->GetDisplayMode(), bmdVideoOutputFlagDefault) != S_OK) { //fprintf(stderr, "Failed to enable video output\n"); qDebug() << "BMDOutputDelegate::StartRunning(): Failed to EnableVideoOutput()"; goto bail; } res = m_deckLinkOutput->CreateVideoFrame( m_frameWidth, m_frameHeight, m_frameWidth * 4, bmdFormat8BitBGRA, bmdFrameFlagDefault, &m_rgbFrame); if(res != S_OK) { qDebug() << "BMDOutputDelegate::StartRunning: Error creating RGB frame, res:"<<res; goto bail; } res = m_deckLinkOutput->CreateVideoFrame( m_frameWidth, m_frameHeight, m_frameWidth * 2, bmdFormat8BitYUV, bmdFrameFlagDefault, &m_yuvFrame); if(res != S_OK) { qDebug() << "BMDOutputDelegate::StartRunning: Error creating YUV frame, res:"<<res; goto bail; } // // Generate a frame of black // if (m_deckLinkOutput->CreateVideoFrame(m_frameWidth, m_frameHeight, m_frameWidth*2, bmdFormat8BitYUV, bmdFrameFlagDefault, &m_videoFrameBlack) != S_OK) // { // fprintf(stderr, "Failed to create video frame\n"); // goto bail; // } // FillBlack(m_videoFrameBlack); // // // Generate a frame of colour bars // if (m_deckLinkOutput->CreateVideoFrame(m_frameWidth, m_frameHeight, m_frameWidth*2, bmdFormat8BitYUV, bmdFrameFlagDefault, &m_videoFrameBars) != S_OK) // { // fprintf(stderr, "Failed to create video frame\n"); // goto bail; // } // FillColourBars(m_videoFrameBars); // Begin video preroll by scheduling a second of frames in hardware m_totalFramesScheduled = 0; for (unsigned i = 0; i < m_framesPerSecond; i++) { PrepareFrame(); ScheduleNextFrame(true); } // Args: startTime, timeScale, playback speed (1.0 = normal) m_deckLinkOutput->StartScheduledPlayback(0, 100, 1.0); m_running = true; return; bail: // *** Error-handling code. Cleanup any resources that were allocated. *** // StopRunning(); }
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(); }
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(); }
int ff_decklink_set_format(AVFormatContext *avctx, int width, int height, int tb_num, int tb_den, enum AVFieldOrder field_order, 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; av_log(avctx, AV_LOG_DEBUG, "Trying to find mode for frame size %dx%d, frame timing %d/%d, field order %d, direction %d, mode number %d, format code %s\n", width, height, tb_num, tb_den, field_order, direction, num, (cctx->format_code) ? cctx->format_code : "(unset)"); 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); } char format_buf[] = " "; if (cctx->format_code) memcpy(format_buf, cctx->format_code, FFMIN(strlen(cctx->format_code), sizeof(format_buf))); BMDDisplayMode target_mode = (BMDDisplayMode)AV_RB32(format_buf); AVRational target_tb = av_make_q(tb_num, tb_den); 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(); BMDDisplayMode bmd_mode = mode->GetDisplayMode(); BMDFieldDominance bmd_field_dominance = mode->GetFieldDominance(); mode->GetFrameRate(&bmd_tb_num, &bmd_tb_den); AVRational mode_tb = av_make_q(bmd_tb_num, bmd_tb_den); if ((bmd_width == width && bmd_height == height && !av_cmp_q(mode_tb, target_tb) && field_order_eq(field_order, bmd_field_dominance)) || i == num || target_mode == bmd_mode) { ctx->bmd_mode = bmd_mode; 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 = bmd_field_dominance; av_log(avctx, AV_LOG_INFO, "Found Decklink mode %d x %d with rate %.2f%s\n", bmd_width, bmd_height, 1/av_q2d(mode_tb), (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, (BMDPixelFormat) cctx->raw_format, 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; }
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); }