SignalGenerator3DVideoFrame* CSignalGeneratorDlg::CreateBlackFrame () { IDeckLinkMutableVideoFrame* referenceBlack = NULL; IDeckLinkMutableVideoFrame* scheduleBlack = NULL; HRESULT hr; BMDPixelFormat pixelFormat; int bytesPerPixel; IDeckLinkVideoConversion* frameConverter = NULL; SignalGenerator3DVideoFrame* ret = NULL; pixelFormat = (BMDPixelFormat)m_pixelFormatCombo.GetItemData(m_pixelFormatCombo.GetCurSel()); bytesPerPixel = GetBytesPerPixel(pixelFormat); hr = m_deckLinkOutput->CreateVideoFrame(m_frameWidth, m_frameHeight, m_frameWidth*bytesPerPixel, pixelFormat, bmdFrameFlagDefault, &scheduleBlack); if (hr != S_OK) goto bail; if (pixelFormat == bmdFormat8BitYUV) { FillBlack(scheduleBlack); } else { hr = m_deckLinkOutput->CreateVideoFrame(m_frameWidth, m_frameHeight, m_frameWidth*2, bmdFormat8BitYUV, bmdFrameFlagDefault, &referenceBlack); if (hr != S_OK) goto bail; FillBlack(referenceBlack); hr = CoCreateInstance(CLSID_CDeckLinkVideoConversion, NULL, CLSCTX_ALL, IID_IDeckLinkVideoConversion, (void**)&frameConverter); if (hr != S_OK) goto bail; hr = frameConverter->ConvertFrame(referenceBlack, scheduleBlack); if (hr != S_OK) goto bail; } ret = new SignalGenerator3DVideoFrame(scheduleBlack); bail: if (referenceBlack) referenceBlack->Release(); if (scheduleBlack) scheduleBlack->Release(); if (frameConverter) frameConverter->Release(); return ret; }
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(); }