Skip to content

Commit

Permalink
Merge pull request mipops#823 from MediaArea/decklink-xml
Browse files Browse the repository at this point in the history
XML output for DeckLink capture
  • Loading branch information
dericed authored Mar 1, 2024
2 parents c6b5f51 + eff342e commit 06f1b1f
Show file tree
Hide file tree
Showing 7 changed files with 338 additions and 37 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/dvrescue-gui.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
- name: Set Qt5 environment path
run: |
echo "/usr/local/opt/qt5/bin" >> $GITHUB_PATH
echo "/usr/local/opt/qt@5/bin" >> $GITHUB_PATH
- name: Build dvrescue-gui
env:
Expand Down Expand Up @@ -166,7 +166,7 @@ jobs:
- name: Set Qt5 environment path
run: |
echo "/usr/local/opt/qt5/bin" >> $GITHUB_PATH
echo "/usr/local/opt/qt@5/bin" >> $GITHUB_PATH
- name: Build qwt
run: |
Expand Down
39 changes: 30 additions & 9 deletions Source/Common/DecklinkWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ string PlatformStr2StdStr(PlatformStr Str)
}

//---------------------------------------------------------------------------
DecklinkWrapper::CaptureDelegate::CaptureDelegate(std::vector<output> Writers, const uint32_t TimecodeFormat) : Writers(Writers), TimecodeFormat(TimecodeFormat)
DecklinkWrapper::CaptureDelegate::CaptureDelegate(DecklinkWrapper* Wrapper, std::vector<output> Writers, const uint32_t TimecodeFormat) : Wrapper(Wrapper), Writers(Writers), TimecodeFormat(TimecodeFormat)
{
}

Expand Down Expand Up @@ -123,11 +123,22 @@ HRESULT DecklinkWrapper::CaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoI
{
IDeckLinkTimecode* DeckLinkTimecode;
if (VideoFrame->GetTimecode(TimecodeFormat, &DeckLinkTimecode) == S_OK)
{
DeckLinkTimecode->GetComponents(&Timecode.hours, &Timecode.minutes, &Timecode.seconds, &Timecode.frames);
Timecode.dropframe = (DeckLinkTimecode->GetFlags() & bmdTimecodeIsDropFrame) != 0;
}
}

for (output& Writer : Writers)
Writer.Writer->write_frame((const char*)VideoBuffer, VideoBufferSize, (const char*)AudioBuffer, AudioBufferSize, Timecode);

double FrameRate = (double)Wrapper->frames.video_rate_num / Wrapper->frames.video_rate_den;
double ElapsedTime = (double)Wrapper->frames.frames.size() / FrameRate;
Wrapper->frames.frames.push_back(decklink_frames::frame {
.tc = Timecode,
.pts = ElapsedTime * 1000000000.0,
.dur = 1.0 / FrameRate
});
}

return S_OK;
Expand Down Expand Up @@ -574,27 +585,36 @@ void DecklinkWrapper::CreateCaptureSession(FileWrapper* Wrapper_)
DeckLinkInput=nullptr;
}

uint32_t Width = 720;
uint32_t Height = DeckLinkVideoMode == bmdModeNTSC ? 486 : 576;
uint32_t Num = DeckLinkVideoMode == bmdModeNTSC ? 30000 : 25;
uint32_t Den = DeckLinkVideoMode == bmdModeNTSC ? 1001 : 1;
uint32_t SampleRate = 48000;
uint8_t Channels = 2;
for (string OutputFile : Merge_OutputFileNames)
{
uint32_t Lines = DeckLinkVideoMode == bmdModeNTSC ? 486 : 576;
uint32_t Num = DeckLinkVideoMode == bmdModeNTSC ? 30000 : 25;
uint32_t Den = DeckLinkVideoMode == bmdModeNTSC ? 1001 : 1;

output Output;
if (OutputFile == "-")
Output.Writer = new matroska_writer(&cout, 720, Lines, Num, Den, DeckLinkTimecodeFormat != (uint32_t)-1);
Output.Writer = new matroska_writer(&cout, Width, Height, Num, Den, DeckLinkTimecodeFormat != (uint32_t)-1);
else
{
Output.Output = new ofstream(OutputFile, ios_base::binary | ios_base::trunc);
Output.Writer = new matroska_writer(Output.Output, 720, Lines, Num, Den, DeckLinkTimecodeFormat != (uint32_t)-1);
Output.Writer = new matroska_writer(Output.Output, Width, Height, Num, Den, DeckLinkTimecodeFormat != (uint32_t)-1);
}
Outputs.push_back(Output);
}

DeckLinkCaptureDelegate = new CaptureDelegate(Outputs, DeckLinkTimecodeFormat);
frames.video_width = Width;
frames.video_height = Height;
frames.video_rate_num = Num;
frames.video_rate_den = Den;
frames.audio_rate = SampleRate;
frames.audio_channels = Channels;

DeckLinkCaptureDelegate = new CaptureDelegate(this, Outputs, DeckLinkTimecodeFormat);

if (DeckLinkInput->EnableVideoInput(DeckLinkVideoMode, bmdFormat10BitYUV, bmdVideoInputFlagDefault) != S_OK ||
DeckLinkInput->EnableAudioInput(bmdAudioSampleRate48kHz, bmdAudioSampleType32bitInteger, 2) != S_OK ||
DeckLinkInput->EnableAudioInput(bmdAudioSampleRate48kHz, bmdAudioSampleType32bitInteger, Channels) != S_OK ||
DeckLinkInput->SetCallback(DeckLinkCaptureDelegate) != S_OK)
{
DeckLinkConfiguration->Release();
Expand Down Expand Up @@ -688,6 +708,7 @@ bool DecklinkWrapper::WaitForSessionEnd(uint64_t Timeout)
if (difftime(time(NULL), LastInput) > Timeout)
return true;
}
PlaybackMode = GetMode();
this_thread::sleep_for(std::chrono::milliseconds(500));
}
while (PlaybackMode == Playback_Mode_Playing);
Expand Down
23 changes: 22 additions & 1 deletion Source/Common/DecklinkWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,23 @@ enum decklink_timecode_format {
Decklink_Timecode_Format_Max
};

struct decklink_frames {
struct frame {
timecode_struct tc;
double pts;
double dur;
};

uint32_t video_width = 0;
uint32_t video_height = 0;
uint32_t video_rate_num = 0;
uint32_t video_rate_den = 0;
uint8_t audio_channels = 0;
uint32_t audio_rate = 0;

std::vector<frame> frames;
};

//***************************************************************************
// Class DecklinkWrapper
//***************************************************************************
Expand Down Expand Up @@ -97,7 +114,7 @@ class DecklinkWrapper : public BaseWrapper {
class CaptureDelegate : public IDeckLinkInputCallback {
public:
// Constructor/Destructor
CaptureDelegate(std::vector<output> Writers, const uint32_t TimecodeFormat);
CaptureDelegate(DecklinkWrapper* Wrapper, std::vector<output> Writers, const uint32_t TimecodeFormat);

// Functions
ULONG AddRef();
Expand All @@ -107,6 +124,7 @@ class DecklinkWrapper : public BaseWrapper {
HRESULT VideoInputFormatChanged(BMDVideoInputFormatChangedEvents, IDeckLinkDisplayMode*, BMDDetectedVideoInputFormatFlags);

private:
DecklinkWrapper* Wrapper;
std::vector<output> Writers;
uint32_t TimecodeFormat;
};
Expand Down Expand Up @@ -163,6 +181,9 @@ class DecklinkWrapper : public BaseWrapper {
// Attributes
static const std::string Interface;

// Results
decklink_frames frames;

private:
playback_mode PlaybackMode = Playback_Mode_NotPlaying;
bool Capture = false;
Expand Down
Loading

0 comments on commit 06f1b1f

Please sign in to comment.