Skip to content

Commit

Permalink
Add P010 HDR10 video format support (2024-11-24) (#968)
Browse files Browse the repository at this point in the history
  • Loading branch information
awawa-dev authored Nov 24, 2024
1 parent 7e94683 commit 9bb1b48
Show file tree
Hide file tree
Showing 16 changed files with 428 additions and 66 deletions.
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

0 comments on commit 9bb1b48

Please sign in to comment.