Skip to content

Commit

Permalink
DeckLink Input: Add frame saturation statistics
Browse files Browse the repository at this point in the history
Signed-off-by: Maxime Gervais <[email protected]>
  • Loading branch information
g-maxime committed Jun 6, 2024
1 parent 0e06994 commit 3ca00b8
Show file tree
Hide file tree
Showing 16 changed files with 387 additions and 10 deletions.
9 changes: 6 additions & 3 deletions Project/GNU/CLI/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,17 @@ if BUILD_AVFCTL
endif

if BUILD_DECKLINK
dvrescue_SOURCES += ../../../Source/Common/DecklinkWrapper.cpp
dvrescue_SOURCES += ../../../Source/Common/DecklinkWrapper.cpp \
../../../Source/Common/Output_Mkv.cpp \
../../../Source/Common/SignalStats.cpp
endif

if BUILD_DECKLINK
dvrescue_SOURCES += ../../../Source/Common/Output_Mkv.cpp

else
if BUILD_SIMULATOR
dvrescue_SOURCES += ../../../Source/Common/Output_Mkv.cpp
dvrescue_SOURCES += ../../../Source/Common/Output_Mkv.cpp \
../../../Source/Common/SignalStats.cpp
endif
endif

Expand Down
2 changes: 2 additions & 0 deletions Project/MSVC2017/CLI/DVRescue.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@
<ClCompile Include="..\..\..\Source\Common\Output_Webvtt.cpp" />
<ClCompile Include="..\..\..\Source\Common\Output_Xml.cpp" />
<ClCompile Include="..\..\..\Source\Common\Output_Mkv.cpp" />
<ClCompile Include="..\..\..\Source\Common\SignalStats.cpp" />
<ClCompile Include="..\..\..\Source\Common\ProcessFile.cpp" />
<ClCompile Include="..\..\..\Source\Common\ProcessFileWrapper.cpp" />
<ClCompile Include="..\..\..\Source\Common\SimulatorWrapper.cpp" />
Expand All @@ -184,6 +185,7 @@
<ClInclude Include="..\..\..\Source\Common\Output_Webvtt.h" />
<ClInclude Include="..\..\..\Source\Common\Output_Xml.h" />
<ClInclude Include="..\..\..\Source\Common\Output_Mkv.h" />
<ClInclude Include="..\..\..\Source\Common\SignalStats.h" />
<ClInclude Include="..\..\..\Source\Common\ProcessFile.h" />
<ClInclude Include="..\..\..\Source\Common\ProcessFileWrapper.h" />
<ClInclude Include="..\..\..\Source\Common\SimulatorWrapper.h" />
Expand Down
2 changes: 2 additions & 0 deletions Project/MSVC2019/CLI/DVRescue.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@
<ClCompile Include="..\..\..\Source\Common\Output_Webvtt.cpp" />
<ClCompile Include="..\..\..\Source\Common\Output_Xml.cpp" />
<ClCompile Include="..\..\..\Source\Common\Output_Mkv.cpp" />
<ClCompile Include="..\..\..\Source\Common\SignalStats.cpp" />
<ClCompile Include="..\..\..\Source\Common\ProcessFile.cpp" />
<ClCompile Include="..\..\..\Source\Common\ProcessFileWrapper.cpp" />
<ClCompile Include="..\..\..\Source\Common\SimulatorWrapper.cpp" />
Expand All @@ -185,6 +186,7 @@
<ClInclude Include="..\..\..\Source\Common\Output_Webvtt.h" />
<ClInclude Include="..\..\..\Source\Common\Output_Xml.h" />
<ClInclude Include="..\..\..\Source\Common\Output_Mkv.h" />
<ClInclude Include="..\..\..\Source\Common\SignalStats.h" />
<ClInclude Include="..\..\..\Source\Common\ProcessFile.h" />
<ClInclude Include="..\..\..\Source\Common\ProcessFileWrapper.h" />
<ClInclude Include="..\..\..\Source\Common\SimulatorWrapper.h" />
Expand Down
2 changes: 2 additions & 0 deletions Project/MSVC2022/CLI/DVRescue.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@
<ClCompile Include="..\..\..\Source\Common\Output_Webvtt.cpp" />
<ClCompile Include="..\..\..\Source\Common\Output_Xml.cpp" />
<ClCompile Include="..\..\..\Source\Common\Output_Mkv.cpp" />
<ClCompile Include="..\..\..\Source\Common\SignalStats.cpp" />
<ClCompile Include="..\..\..\Source\Common\ProcessFile.cpp" />
<ClCompile Include="..\..\..\Source\Common\ProcessFileWrapper.cpp" />
<ClCompile Include="..\..\..\Source\Common\SimulatorWrapper.cpp" />
Expand All @@ -185,6 +186,7 @@
<ClInclude Include="..\..\..\Source\Common\Output_Webvtt.h" />
<ClInclude Include="..\..\..\Source\Common\Output_Xml.h" />
<ClInclude Include="..\..\..\Source\Common\Output_Mkv.h" />
<ClInclude Include="..\..\..\Source\Common\SignalStats.h" />
<ClInclude Include="..\..\..\Source\Common\ProcessFile.h" />
<ClInclude Include="..\..\..\Source\Common\ProcessFileWrapper.h" />
<ClInclude Include="..\..\..\Source\Common\SimulatorWrapper.h" />
Expand Down
28 changes: 28 additions & 0 deletions Source/Common/DecklinkWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,17 @@ static uint32_t decklink_audio_sources[Decklink_Audio_Source_Max] =
bmdAudioConnectionMicrophone
};

//---------------------------------------------------------------------------
static uint32_t decklink_pixel_formats[Decklink_Pixel_Format_Max] =
{
bmdFormatUnspecified,
bmdFormat8BitYUV,
bmdFormat10BitYUV,
bmdFormat8BitARGB,
bmdFormat8BitBGRA,
bmdFormat10BitRGB
};

//---------------------------------------------------------------------------
static uint32_t decklink_timecode_formats[Decklink_Timecode_Format_Max] =
{
Expand Down Expand Up @@ -129,9 +140,26 @@ HRESULT DecklinkWrapper::CaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoI
}
}

uint8_t PixelFormat = (uint8_t)Decklink_Pixel_Format_Unspecified;
switch (VideoFrame->GetPixelFormat())
{
case bmdFormat8BitYUV:
PixelFormat = (uint8_t)Decklink_Pixel_Format_8BitYUV; break;
case bmdFormat10BitYUV:
PixelFormat = (uint8_t)Decklink_Pixel_Format_10BitYUV; break;
case bmdFormat8BitARGB:
PixelFormat = (uint8_t)Decklink_Pixel_Format_8BitARGB; break;
case bmdFormat8BitBGRA:
PixelFormat = (uint8_t)Decklink_Pixel_Format_8BitBGRA; break;
case bmdFormat10BitRGB:
PixelFormat = (uint8_t)Decklink_Pixel_Format_10BitRGB; break;
default:;
}

decklink_frame Buffer = {
.Width = (uint32_t)VideoFrame->GetWidth(),
.Height = (uint32_t)VideoFrame->GetHeight(),
.Pixel_Format = PixelFormat,
.Video_Buffer = (uint8_t*)VideoBuffer,
.Video_Buffer_Size = VideoBufferSize,
.Audio_Buffer = (uint8_t*)AudioBuffer,
Expand Down
1 change: 1 addition & 0 deletions Source/Common/Merge.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ extern const char* Control_Port;
extern uint8_t DeckLinkVideoMode;
extern uint8_t DeckLinkVideoSource;
extern uint8_t DeckLinkAudioSource;
extern uint8_t DeckLinkPixelFormat;
extern uint8_t DeckLinkTimecodeFormat;
#endif
extern size_t Merge_Rewind_Count;
Expand Down
62 changes: 58 additions & 4 deletions Source/Common/Output_Xml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ static void Aud_Element(string& Text, size_t o, size_t n, vector<uint16_t> Audio

#if defined(ENABLE_DECKLINK) || defined(ENABLE_SIMULATOR)
//---------------------------------------------------------------------------
static string decklink_videosource_to_string(uint8_t value)
string decklink_videosource_to_string(uint8_t value)
{
string ToReturn;
switch (value)
Expand All @@ -153,7 +153,7 @@ static string decklink_videosource_to_string(uint8_t value)
}

//---------------------------------------------------------------------------
static string decklink_audiosource_to_string(uint8_t value)
string decklink_audiosource_to_string(uint8_t value)
{
string ToReturn;
switch (value)
Expand All @@ -170,7 +170,23 @@ static string decklink_audiosource_to_string(uint8_t value)
}

//---------------------------------------------------------------------------
static string decklink_timecodeformat_to_string(uint8_t value)
string decklink_pixelformat_to_string(uint8_t value)
{
string ToReturn;
switch (value)
{
case (uint8_t)Decklink_Pixel_Format_8BitYUV: ToReturn = "uyvy"; break;
case (uint8_t)Decklink_Pixel_Format_10BitYUV: ToReturn = "v210"; break;
case (uint8_t)Decklink_Pixel_Format_8BitARGB: ToReturn = "argb"; break;
case (uint8_t)Decklink_Pixel_Format_8BitBGRA: ToReturn = "bgra"; break;
case (uint8_t)Decklink_Pixel_Format_10BitRGB: ToReturn = "r210"; break;
default:;
}
return ToReturn;
}

//---------------------------------------------------------------------------
string decklink_timecodeformat_to_string(uint8_t value)
{
string ToReturn;
switch (value)
Expand Down Expand Up @@ -359,6 +375,14 @@ return_value Output_Xml(ostream& Out, std::vector<file*>& PerFile, bitset<Option
Text += to_string(File->Wrapper->FramesInfo.video_height);
Text += '\"';
}

if (File->Wrapper->FramesInfo.pixel_format)
{
Text += " pixel_format=\"";
Text += decklink_pixelformat_to_string(File->Wrapper->FramesInfo.pixel_format);
Text += '\"';
}

if (File->Wrapper->FramesInfo.video_rate_num)
{
Text += " video_rate=\"";
Expand Down Expand Up @@ -418,7 +442,37 @@ return_value Output_Xml(ostream& Out, std::vector<file*>& PerFile, bitset<Option
Text += " tc_nc=\"1\"";
}

Text += "/>\n";
if (File->Wrapper->FramesInfo.frames[Pos].st.HasValue())
{
Text += ">\n";
Text += "\t\t\t\t<signalstats";
if (!isnan(File->Wrapper->FramesInfo.frames[Pos].st.SatAvg))
{
stringstream ss;
ss << File->Wrapper->FramesInfo.frames[Pos].st.SatAvg;
Text += " satavg=\"";
Text += ss.str();
Text += '\"';
}

if (File->Wrapper->FramesInfo.frames[Pos].st.SatHi != (uint16_t)-1)
{
Text += " sathi=\"";
Text += to_string(File->Wrapper->FramesInfo.frames[Pos].st.SatHi);
Text += '\"';
}

if (File->Wrapper->FramesInfo.frames[Pos].st.SatMax != (uint16_t)-1)
{
Text += " satmax=\"";
Text += to_string(File->Wrapper->FramesInfo.frames[Pos].st.SatMax);
Text += '\"';
}
Text += "/>\n";
Text += "\t\t\t</frame>\n";
}
else
Text += "/>\n";
}

// Media footer
Expand Down
5 changes: 5 additions & 0 deletions Source/Common/Output_Xml.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,8 @@ class file;
//---------------------------------------------------------------------------

return_value Output_Xml(ostream& Out, vector<file*>& PerFile, bitset<Option_Max> Options, ostream* Err = nullptr);

//---------------------------------------------------------------------------
#if defined(ENABLE_DECKLINK) || defined(ENABLE_SIMULATOR)
string decklink_pixelformat_to_string(uint8_t value);
#endif
1 change: 1 addition & 0 deletions Source/Common/ProcessFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ bool DeckLinkNativeControl = false;
uint8_t DeckLinkVideoMode = (uint8_t)Decklink_Video_Mode_NTSC;
uint8_t DeckLinkVideoSource = (uint8_t)Decklink_Video_Source_SDI;
uint8_t DeckLinkAudioSource = (uint8_t)Decklink_Audio_Source_Embedded;
uint8_t DeckLinkPixelFormat = (uint8_t)Decklink_Pixel_Format_Unspecified;
uint8_t DeckLinkTimecodeFormat = (uint8_t)Decklink_Timecode_Format_VITC;
#endif
bool InControl = false;
Expand Down
10 changes: 10 additions & 0 deletions Source/Common/ProcessFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@ enum decklink_audio_source {
Decklink_Audio_Source_Max
};

enum decklink_pixel_format {
Decklink_Pixel_Format_Unspecified,
Decklink_Pixel_Format_8BitYUV,
Decklink_Pixel_Format_10BitYUV,
Decklink_Pixel_Format_8BitARGB,
Decklink_Pixel_Format_8BitBGRA,
Decklink_Pixel_Format_10BitRGB,
Decklink_Pixel_Format_Max
};

enum decklink_timecode_format {
Decklink_Timecode_Format_RP188_VITC,
Decklink_Timecode_Format_RP188_VITC2,
Expand Down
20 changes: 18 additions & 2 deletions Source/Common/ProcessFileWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@
#include "Common/ProcessFile.h"

#if defined(ENABLE_DECKLINK) || defined(ENABLE_SIMULATOR)
#include "Common/SignalStats.h"
#include "Common/Output_Mkv.h"
#include "Common/Output_Xml.h"
#include "Common/Merge.h"

#include <iostream>
#include <cmath>
#endif

using namespace std;
Expand Down Expand Up @@ -78,11 +81,15 @@ void FileWrapper::Parse_Buffer(const uint8_t *Buffer, size_t Buffer_Size)
if (IsMatroska)
{
decklink_frame* Frame=(decklink_frame*)Buffer;
if (!FramesInfo.pixel_format && Frame->Pixel_Format)
FramesInfo.pixel_format = Frame->Pixel_Format;

for (matroska_output& Output : Outputs)
{
Output.Writer->write_frame((const char*)Frame->Video_Buffer, Frame->Video_Buffer_Size,
(const char*)Frame->Audio_Buffer, Frame->Audio_Buffer_Size, Frame->TC);
}
SignalStats::Stats ST = SignalStats::ComputeStats(Frame);

bool TimeCode_Repeat = false;
bool TimeCode_NonConsecutive = false;
Expand All @@ -108,6 +115,7 @@ void FileWrapper::Parse_Buffer(const uint8_t *Buffer, size_t Buffer_Size)
double FrameRate = (double)FramesInfo.video_rate_num / FramesInfo.video_rate_den;
double ElapsedTime = (double)FramesInfo.frames.size() / FrameRate;
FramesInfo.frames.push_back(decklink_framesinfo::frame {
ST,
Frame->TC,
TimeCode_Repeat,
(uint8_t)(TimeCode_NonConsecutive ? (TimeCode_NonConsecutive_IsLess ? 2 : 1) : 0),
Expand All @@ -119,12 +127,16 @@ void FileWrapper::Parse_Buffer(const uint8_t *Buffer, size_t Buffer_Size)
{
if (!FrameCount)
{
cout << "FramePos,abst,abst_r,abst_nc,tc,tc_r,tc_nc,rdt,rdt_r,rdt_nc,rec_start,rec_end,Used,Status,Comments,BlockErrors,BlockErrors_Even,IssueFixed"
cout << "FramePos,abst,abst_r,abst_nc,tc,tc_r,tc_nc,rdt,rdt_r,rdt_nc,rec_start,rec_end,pix_fmt,satavg,sathi,satmax,Used,Status,Comments,BlockErrors,BlockErrors_Even,IssueFixed"
<< (Verbosity > 5 ? ",SourceSpeed,FrameSpeed,InputPos,OutputPos" : "")
<< (ShowFrames_Intermediate ? ",RewindStatus" : "")
<< endl;
}

stringstream ss;
if (!isnan(ST.SatAvg))
ss << ST.SatAvg;

cout << FrameCount++ // framePos
<< "," // abst
"," // abst_r
Expand All @@ -138,7 +150,11 @@ void FileWrapper::Parse_Buffer(const uint8_t *Buffer, size_t Buffer_Size)
"," // rec_start
"," // rec_end
"," // Used
"," // Status
<< "," << decklink_pixelformat_to_string(Frame->Pixel_Format) // pix_fmt
<< "," << ss.str() // satavg
<< "," << (ST.SatHi != (uint16_t)-1 ? to_string(ST.SatHi) : "") // sathi
<< "," << (ST.SatMax != (uint16_t)-1 ? to_string(ST.SatMax) : "") // satmax
<< "," // Status
"," // Comments
"," // BlockErrors
"," // BlocksErrors_Even
Expand Down
5 changes: 4 additions & 1 deletion Source/Common/ProcessFileWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <vector>

#include "ThirdParty/TimeCode/TimeCode.h"
#include "Common/SignalStats.h"

class file;
#if defined(ENABLE_DECKLINK) || defined(ENABLE_SIMULATOR)
Expand All @@ -37,6 +38,7 @@ struct decklink_frame
{
uint32_t Width = 0;
uint32_t Height = 0;
uint8_t Pixel_Format = 0;
uint8_t* Video_Buffer = nullptr;
size_t Video_Buffer_Size = 0;
uint8_t* Audio_Buffer = nullptr;
Expand All @@ -46,6 +48,7 @@ struct decklink_frame

struct decklink_framesinfo {
struct frame {
SignalStats::Stats st;
TimeCode tc;
bool tc_r;
uint8_t tc_nc;
Expand All @@ -57,9 +60,9 @@ struct decklink_framesinfo {
uint32_t video_height = 0;
uint32_t video_rate_num = 0;
uint32_t video_rate_den = 0;
uint8_t pixel_format = 0;
uint8_t audio_channels = 0;
uint32_t audio_rate = 0;

std::vector<frame> frames;
};

Expand Down
Loading

0 comments on commit 3ca00b8

Please sign in to comment.