Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add P010 HDR10 video format support #968

Merged
merged 1 commit into from
Nov 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/lut-calibrator/BestResult.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ struct BestResult
double upYLimit = 0;
double downYLimit = 0;
double yShift = 0;
bool isSourceP010 = false;
} signal;

long long int minError = MAX_CALIBRATION_ERROR;
Expand Down Expand Up @@ -121,6 +122,7 @@ struct BestResult
out << "bestResult.signal.upYLimit = " << std::to_string(signal.upYLimit) << ";" << std::endl;
out << "bestResult.signal.downYLimit = " << std::to_string(signal.downYLimit) << ";" << std::endl;
out << "bestResult.signal.yShift = " << std::to_string(signal.yShift) << ";" << std::endl;
out << "bestResult.signal.isSourceP010 = " << std::to_string(signal.isSourceP010) << ";" << std::endl;
out << "bestResult.minError = " << std::to_string(std::round(minError * 100.0) / 30000.0) << ";" << std::endl;
out << "*/" << std::endl;
}
Expand Down
2 changes: 1 addition & 1 deletion include/lut-calibrator/BoardUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ namespace BoardUtils
constexpr int SCREEN_CRC_LINES = 2;
constexpr int SCREEN_CRC_COUNT = 5;
constexpr int SCREEN_MAX_CRC_BRIGHTNESS_ERROR = 1;
constexpr int SCREEN_MAX_COLOR_NOISE_ERROR = 8;
constexpr int SCREEN_MAX_COLOR_NOISE_ERROR = 16;
constexpr int SCREEN_SAMPLES_PER_BOARD = (SCREEN_BLOCKS_X / 2) * (SCREEN_BLOCKS_Y - SCREEN_CRC_LINES);
const int SCREEN_LAST_BOARD_INDEX = std::pow(SCREEN_COLOR_DIMENSION, 3) / SCREEN_SAMPLES_PER_BOARD;

Expand Down
4 changes: 3 additions & 1 deletion include/lut-calibrator/ColorSpace.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ using namespace aliases;

namespace ColorSpaceMath
{
enum PRIMARIES { SRGB = 0, BT_2020, WIDE_GAMMUT };
enum PRIMARIES { SRGB = 0, BT_2020, WIDE_GAMMUT };

QString gammaToString(HDR_GAMMA gamma);

Expand Down Expand Up @@ -85,6 +85,8 @@ namespace ColorSpaceMath

double3 bt2020_linear_to_nonlinear(double3 input);

double srgb_nonlinear_to_linear(double input);

double3 srgb_nonlinear_to_linear(double3 input);

double3 srgb_linear_to_nonlinear(double3 input);
Expand Down
2 changes: 1 addition & 1 deletion include/lut-calibrator/LutCalibrator.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ namespace linalg {
}

namespace ColorSpaceMath {
enum HDR_GAMMA { PQ = 0, HLG, sRGB, BT2020inSRGB, PQinSRGB};
enum HDR_GAMMA { PQ = 0, HLG, sRGB, BT2020inSRGB, PQinSRGB, P010 };
}

struct BestResult;
Expand Down
10 changes: 8 additions & 2 deletions include/utils/FrameDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,23 @@
// some stuff for HDR tone mapping
#define LUT_INDEX(y,u,v) ((y + (u<<8) + (v<<16))*3)

namespace FrameDecoderUtils
{
double unpackChromaP010(double x);
double unpackLuminanceP010(double val);
}

class FrameDecoder
{
public:
static void processImage(
int _cropLeft, int _cropRight, int _cropTop, int _cropBottom,
const uint8_t* data, const uint8_t* dataUV, int width, int height, int lineLength,
const PixelFormat pixelFormat, const uint8_t* lutBuffer, Image<ColorRgb>& outputImage);
const PixelFormat pixelFormat, const uint8_t* lutBuffer, Image<ColorRgb>& outputImage, bool toneMapping = true);

static void processQImage(
const uint8_t* data, const uint8_t* dataUV, int width, int height, int lineLength,
const PixelFormat pixelFormat, const uint8_t* lutBuffer, Image<ColorRgb>& outputImage);
const PixelFormat pixelFormat, const uint8_t* lutBuffer, Image<ColorRgb>& outputImage, bool toneMapping = true);

static void processSystemImageBGRA(Image<ColorRgb>& image, int targetSizeX, int targetSizeY,
int startX, int startY,
Expand Down
2 changes: 1 addition & 1 deletion sources/base/Grabber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ void Grabber::setEnabled(bool enable)

void Grabber::setMonitorNits(int nits)
{
if (_targetMonitorNits != nits)
if (static_cast<int>(_targetMonitorNits) != nits)
{
_targetMonitorNits = nits;

Expand Down
36 changes: 31 additions & 5 deletions sources/grabber/linux/v4l2/V4L2Grabber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,30 @@
// some stuff for HDR tone mapping
#define LUT_FILE_SIZE 50331648

namespace
{
#ifdef V4L2_PIX_FMT_P010
#pragma message "P010 is supported on the build machine"
bool supportedP010 = true;
#else
#pragma message "P010 is NOT supported on the build machine"
bool supportedP010 = false;
#endif
};

#ifndef V4L2_PIX_FMT_P010
#define V4L2_PIX_FMT_P010 v4l2_fourcc('P', '0', '1', '0')
#endif

static const V4L2Grabber::HyperHdrFormat supportedFormats[] =
{
{ V4L2_PIX_FMT_YUYV, PixelFormat::YUYV },
{ V4L2_PIX_FMT_XRGB32, PixelFormat::XRGB },
{ V4L2_PIX_FMT_RGB24, PixelFormat::RGB24 },
{ V4L2_PIX_FMT_YUV420, PixelFormat::I420 },
{ V4L2_PIX_FMT_NV12, PixelFormat::NV12 },
{ V4L2_PIX_FMT_MJPEG, PixelFormat::MJPEG }
#ifdef V4L2_PIX_FMT_P010
,{ V4L2_PIX_FMT_P010, PixelFormat::P010 }
#endif
{ V4L2_PIX_FMT_MJPEG, PixelFormat::MJPEG },
{ V4L2_PIX_FMT_P010, PixelFormat::P010 }
};


Expand All @@ -84,6 +97,8 @@ V4L2Grabber::V4L2Grabber(const QString& device, const QString& configurationPath
{
// Refresh devices
getV4L2devices();

Debug(_log, "P010 was %s on the build machine", (supportedP010) ? "supported" : "unsupported");
}

QString V4L2Grabber::GetSharedLut()
Expand Down Expand Up @@ -132,7 +147,8 @@ void V4L2Grabber::setHdrToneMappingEnabled(int mode)
{
Debug(_log, "setHdrToneMappingMode replacing LUT and restarting");
_V4L2WorkerManager.Stop();
if ((_actualVideoFormat == PixelFormat::YUYV) || (_actualVideoFormat == PixelFormat::I420) || (_actualVideoFormat == PixelFormat::NV12) || (_actualVideoFormat == PixelFormat::MJPEG))
if ((_actualVideoFormat == PixelFormat::YUYV) || (_actualVideoFormat == PixelFormat::I420) || (_actualVideoFormat == PixelFormat::NV12)
|| (_actualVideoFormat == PixelFormat::P010) || (_actualVideoFormat == PixelFormat::MJPEG))
loadLutFile(PixelFormat::YUYV);
else
loadLutFile(PixelFormat::RGB24);
Expand Down Expand Up @@ -985,6 +1001,16 @@ bool V4L2Grabber::init_device(QString selectedDeviceName, DevicePropertiesItem p
}
break;

case V4L2_PIX_FMT_P010:
{
loadLutFile(PixelFormat::YUYV);
_actualVideoFormat = PixelFormat::P010;
_frameByteSize = (props.x * props.y * 6) / 2;
_lineLength = props.x * 2;
Info(_log, "Video pixel format is set to: P010");
}
break;

case V4L2_PIX_FMT_NV12:
{
loadLutFile(PixelFormat::YUYV);
Expand Down
4 changes: 2 additions & 2 deletions sources/grabber/linux/v4l2/V4L2Worker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ void V4L2Worker::runMe()
{
Image<ColorRgb> image(_width >> 1, _height >> 1);
FrameDecoder::processQImage(
_sharedData, nullptr, _width, _height, _lineLength, _pixelFormat, _lutBuffer, image);
_sharedData, nullptr, _width, _height, _lineLength, _pixelFormat, _lutBuffer, image, _hdrToneMappingEnabled);

image.setBufferCacheSize();
if (!_directAccess)
Expand All @@ -222,7 +222,7 @@ void V4L2Worker::runMe()

FrameDecoder::processImage(
_cropLeft, _cropRight, _cropTop, _cropBottom,
_sharedData, nullptr, _width, _height, _lineLength, _pixelFormat, _lutBuffer, image);
_sharedData, nullptr, _width, _height, _lineLength, _pixelFormat, _lutBuffer, image, _hdrToneMappingEnabled);

image.setBufferCacheSize();
if (!_directAccess)
Expand Down
10 changes: 9 additions & 1 deletion sources/grabber/windows/MF/MFGrabber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ void MFGrabber::setHdrToneMappingEnabled(int mode)
{
Debug(_log, "setHdrToneMappingMode replacing LUT and restarting");
_MFWorkerManager.Stop();
if ((_actualVideoFormat == PixelFormat::YUYV) || (_actualVideoFormat == PixelFormat::I420) || (_actualVideoFormat == PixelFormat::NV12) || (_actualVideoFormat == PixelFormat::MJPEG))
if ((_actualVideoFormat == PixelFormat::YUYV) || (_actualVideoFormat == PixelFormat::I420) || (_actualVideoFormat == PixelFormat::P010) || (_actualVideoFormat == PixelFormat::NV12) || (_actualVideoFormat == PixelFormat::MJPEG))
loadLutFile(PixelFormat::YUYV);
else
loadLutFile(PixelFormat::RGB24);
Expand Down Expand Up @@ -869,6 +869,14 @@ bool MFGrabber::init_device(QString selectedDeviceName, DevicePropertiesItem pro
}
break;

case PixelFormat::P010:
{
loadLutFile(PixelFormat::YUYV);
_frameByteSize = (6 * props.x * props.y) / 2;
_lineLength = props.x * 2;
}
break;

case PixelFormat::RGB24:
{
loadLutFile(PixelFormat::RGB24);
Expand Down
4 changes: 2 additions & 2 deletions sources/grabber/windows/MF/MFWorker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ void MFWorker::runMe()
{
Image<ColorRgb> image(_width >> 1, _height >> 1);
FrameDecoder::processQImage(
_localBuffer.data(), nullptr, _width, _height, _lineLength, _pixelFormat, _lutBuffer, image);
_localBuffer.data(), nullptr, _width, _height, _lineLength, _pixelFormat, _lutBuffer, image, _hdrToneMappingEnabled);

image.setBufferCacheSize();
if (!_directAccess)
Expand All @@ -218,7 +218,7 @@ void MFWorker::runMe()

FrameDecoder::processImage(
_cropLeft, _cropRight, _cropTop, _cropBottom,
_localBuffer.data(), nullptr, _width, _height, _lineLength, _pixelFormat, _lutBuffer, image);
_localBuffer.data(), nullptr, _width, _height, _lineLength, _pixelFormat, _lutBuffer, image, _hdrToneMappingEnabled);

image.setBufferCacheSize();
if (!_directAccess)
Expand Down
2 changes: 1 addition & 1 deletion sources/lut-calibrator/BoardUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ namespace BoardUtils
}
}

if (black.Y() > SCREEN_YUV_RANGE_LIMIT || white.Y() < 255 - SCREEN_YUV_RANGE_LIMIT)
if (black.Y() > SCREEN_YUV_RANGE_LIMIT)
{
if (allColors.getRange() == YuvConverter::COLOR_RANGE::FULL)
Error(_log, "The YUV range is changing. Now is LIMITED.");
Expand Down
2 changes: 2 additions & 0 deletions sources/lut-calibrator/ColorSpace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ namespace ColorSpaceMath
return "BT2020 with sRGB TRC";
else if (gamma == HDR_GAMMA::PQinSRGB)
return "PQ in SRGB";
else if (gamma == HDR_GAMMA::P010)
return "P010";
return "UNKNOWN";
}

Expand Down
Loading
Loading