Skip to content

Commit

Permalink
Refactor the YUV presets and align the RGB and YUV implementations of…
Browse files Browse the repository at this point in the history
… the presets.
  • Loading branch information
ChristianFeldmann committed Feb 26, 2024
1 parent 0084766 commit 01edae3
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 128 deletions.
69 changes: 25 additions & 44 deletions YUViewLib/src/video/rgb/videoHandlerRGB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,6 @@ const auto componentShowMapper =
{ComponentDisplayMode::B, "B", "Blue Only"},
{ComponentDisplayMode::A, "A", "Alpha Only"}});

QStringList getFormattedNames(const std::vector<rgb::PixelFormatRGB> &rgbFormatList)
{
QStringList formattedNames;
for (size_t i = 0; i < rgbFormatList.size(); i++)
formattedNames.append(QString::fromStdString(rgbFormatList.at(i).getName()));
return formattedNames;
}

} // namespace

// Activate this if you want to know when which buffer is loaded/converted to image and so on.
Expand Down Expand Up @@ -92,17 +84,7 @@ QStringList getFormattedNames(const std::vector<rgb::PixelFormatRGB> &rgbFormatL
#endif
#endif

// PixelFormatRGB videoHandlerRGB::RGBFormatList::getFromName(const std::string &name) const
// {
// for (int i = 0; i < count(); i++)
// if (at(i).getName() == name)
// return at(i);

// // If the format could not be found, we return the "Unknown Pixel Format" format
// return {};
// }

std::vector<rgb::PixelFormatRGB> videoHandlerRGB::rgbPresetList = {
std::vector<rgb::PixelFormatRGB> videoHandlerRGB::formatPresetList = {
PixelFormatRGB(8, DataLayout::Packed, ChannelOrder::RGB),
PixelFormatRGB(10, DataLayout::Packed, ChannelOrder::RGB),
PixelFormatRGB(8, DataLayout::Packed, ChannelOrder::RGB, AlphaMode::First),
Expand Down Expand Up @@ -244,20 +226,21 @@ QLayout *videoHandlerRGB::createVideoHandlerControls(bool isSizeFixed)

ui.setupUi();

// Set all the values of the properties widget to the values of this class
ui.rgbFormatComboBox->addItems(getFormattedNames(this->rgbPresetList));
ui.rgbFormatComboBox->addItem("Custom...");
ui.rgbFormatComboBox->setEnabled(!isSizeFixed);
for (const auto &format : videoHandlerRGB::formatPresetList)
ui.rgbFormatComboBox->addItem(QString::fromStdString(format.getName()));

if (!vectorContains(videoHandlerRGB::rgbPresetList, this->srcPixelFormat) &&
this->srcPixelFormat.isValid())
const auto currentFormatInPresetList =
vectorContains(videoHandlerRGB::formatPresetList, this->srcPixelFormat);
if (!currentFormatInPresetList && this->srcPixelFormat.isValid())
{
this->rgbPresetList.push_back(this->srcPixelFormat);
const auto nrItems = ui.rgbFormatComboBox->count();
ui.rgbFormatComboBox->insertItem(nrItems - 1,
QString::fromStdString(this->srcPixelFormat.getName()));
videoHandlerRGB::formatPresetList.push_back(this->srcPixelFormat);
ui.rgbFormatComboBox->addItem(QString::fromStdString(this->srcPixelFormat.getName()));
}
if (const auto presetIndex = vectorIndexOf(videoHandlerRGB::rgbPresetList, this->srcPixelFormat))
ui.rgbFormatComboBox->addItem("Custom...");
ui.rgbFormatComboBox->setEnabled(!isSizeFixed);

if (const auto presetIndex =
vectorIndexOf(videoHandlerRGB::formatPresetList, this->srcPixelFormat))
ui.rgbFormatComboBox->setCurrentIndex(static_cast<int>(*presetIndex));

ui.RScaleSpinBox->setValue(componentScale[0]);
Expand Down Expand Up @@ -384,42 +367,40 @@ void videoHandlerRGB::updateControlsForNewPixelFormat()
}
}

void videoHandlerRGB::slotRGBFormatControlChanged()
void videoHandlerRGB::slotRGBFormatControlChanged(int selectionIndex)
{
auto selectionIdx = ui.rgbFormatComboBox->currentIndex();
auto nrBytesOldFormat = getBytesPerFrame();
const auto nrBytesOldFormat = getBytesPerFrame();

const auto customFormatSelected = (selectionIdx == this->rgbPresetList.size());
const auto customFormatSelected = (selectionIndex == videoHandlerRGB::formatPresetList.size());
if (customFormatSelected)
{
DEBUG_RGB("videoHandlerRGB::slotRGBFormatControlChanged custom format");

videoHandlerRGBCustomFormatDialog dialog(this->srcPixelFormat);
if (dialog.exec() == QDialog::Accepted)
if (dialog.exec() == QDialog::Accepted && dialog.getSelectedRGBFormat().isValid())
this->srcPixelFormat = dialog.getSelectedRGBFormat();

const auto isInPresetList =
vectorContains(videoHandlerRGB::rgbPresetList, this->srcPixelFormat);
vectorContains(videoHandlerRGB::formatPresetList, this->srcPixelFormat);
if (!isInPresetList && this->srcPixelFormat.isValid())
{
this->rgbPresetList.push_back(this->srcPixelFormat);
const auto nrItems = ui.rgbFormatComboBox->count();

videoHandlerRGB::formatPresetList.push_back(this->srcPixelFormat);
const QSignalBlocker blocker(this->ui.rgbFormatComboBox);
ui.rgbFormatComboBox->insertItem(nrItems - 1,
const auto insertPositionBeforeCustom = (this->ui.rgbFormatComboBox->count() - 1);
ui.rgbFormatComboBox->insertItem(insertPositionBeforeCustom,
QString::fromStdString(this->srcPixelFormat.getName()));
}

if (const auto presetIndex =
vectorIndexOf(videoHandlerRGB::rgbPresetList, this->srcPixelFormat))
vectorIndexOf(videoHandlerRGB::formatPresetList, this->srcPixelFormat))
{
const QSignalBlocker blocker(this->ui.rgbFormatComboBox);
selectionIdx = static_cast<int>(*presetIndex);
ui.rgbFormatComboBox->setCurrentIndex(selectionIdx);
selectionIndex = static_cast<int>(*presetIndex);
ui.rgbFormatComboBox->setCurrentIndex(selectionIndex);
}
}

this->setSrcPixelFormat(this->rgbPresetList.at(selectionIdx));
this->setSrcPixelFormat(videoHandlerRGB::formatPresetList.at(selectionIndex));

// Set the current frame in the buffer to be invalid and clear the cache.
// Emit that this item needs redraw and the cache needs updating.
Expand Down
8 changes: 3 additions & 5 deletions YUViewLib/src/video/rgb/videoHandlerRGB.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,10 @@ class videoHandlerRGB : public videoHandler
protected:
ComponentDisplayMode componentDisplayMode{ComponentDisplayMode::RGBA};

static std::vector<rgb::PixelFormatRGB> rgbPresetList;
static std::vector<PixelFormatRGB> formatPresetList;

// The currently selected RGB format
rgb::PixelFormatRGB srcPixelFormat;
PixelFormatRGB srcPixelFormat;

// Parameters for the RGBA transformation (like scaling, invert)
int componentScale[4]{1, 1, 1, 1};
Expand Down Expand Up @@ -204,9 +204,7 @@ class videoHandlerRGB : public videoHandler

private slots:

// One of the controls for the RGB format changed.
void slotRGBFormatControlChanged();
// One of the controls for the RGB display settings changed.
void slotRGBFormatControlChanged(int selectionIndex);
void slotDisplayOptionsChanged();
};

Expand Down
131 changes: 54 additions & 77 deletions YUViewLib/src/video/yuv/videoHandlerYUV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2471,22 +2471,22 @@ void convertYUVToImage(const QByteArray & sourceBuffer,

} // namespace

std::vector<PixelFormatYUV> videoHandlerYUV::formatPresetList = {
PixelFormatYUV(Subsampling::YUV_420, 8, PlaneOrder::YUV),
PixelFormatYUV(Subsampling::YUV_420, 10, PlaneOrder::YUV),
PixelFormatYUV(Subsampling::YUV_422, 8, PlaneOrder::YUV),
PixelFormatYUV(Subsampling::YUV_444, 8, PlaneOrder::YUV),
PixelFormatYUV(PredefinedPixelFormat::V210)};

videoHandlerYUV::videoHandlerYUV() : videoHandler()
{
// Set the default YUV transformation parameters.
this->conversionSettings.mathParameters[Component::Luma] = MathParameters(1, 125, false);
this->conversionSettings.mathParameters[Component::Chroma] = MathParameters(1, 128, false);

// If we know nothing about the YUV format, assume YUV 4:2:0 8 bit planar by default.
this->srcPixelFormat = PixelFormatYUV(Subsampling::YUV_420, 8, PlaneOrder::YUV);

this->presetList.append(PixelFormatYUV(Subsampling::YUV_420, 8, PlaneOrder::YUV)); // YUV 4:2:0
this->presetList.append(
PixelFormatYUV(Subsampling::YUV_420, 10, PlaneOrder::YUV)); // YUV 4:2:0 10 bit
this->presetList.append(PixelFormatYUV(Subsampling::YUV_422, 8, PlaneOrder::YUV)); // YUV 4:2:2
this->presetList.append(PixelFormatYUV(Subsampling::YUV_444, 8, PlaneOrder::YUV)); // YUV 4:4:4
for (auto e : PredefinedPixelFormatMapper.getEnums())
this->presetList.append(e);
const auto defaultPixelFormat = PixelFormatYUV(Subsampling::YUV_420, 8, PlaneOrder::YUV);
this->srcPixelFormat = defaultPixelFormat;
}

videoHandlerYUV::~videoHandlerYUV()
Expand Down Expand Up @@ -2684,18 +2684,18 @@ void videoHandlerYUV::yuv420_to_argb8888(quint8 *yp,
}
#endif

QLayout *videoHandlerYUV::createVideoHandlerControls(bool isSizeFixed)
QLayout *videoHandlerYUV::createVideoHandlerControls(bool isSizeAndFormatFixed)
{
// Absolutely always only call this function once!
assert(!ui.created());

QVBoxLayout *newVBoxLayout = nullptr;
if (!isSizeFixed)
if (!isSizeAndFormatFixed)
{
// Our parent (videoHandler) also has controls to add. Create a new vBoxLayout and append the
// parent controls and our controls into that layout, separated by a line. Return that layout
newVBoxLayout = new QVBoxLayout;
newVBoxLayout->addLayout(FrameHandler::createFrameHandlerControls(isSizeFixed));
newVBoxLayout->addLayout(FrameHandler::createFrameHandlerControls(false));

QFrame *line = new QFrame;
line->setObjectName(QStringLiteral("line"));
Expand All @@ -2707,22 +2707,22 @@ QLayout *videoHandlerYUV::createVideoHandlerControls(bool isSizeFixed)
// Create the UI and setup all the controls
ui.setupUi();

// Add the preset YUV formats. If the current format is in the list, add it and select it.
for (auto format : presetList)
for (const auto &format : videoHandlerYUV::formatPresetList)
ui.yuvFormatComboBox->addItem(QString::fromStdString(format.getName()));

int idx = presetList.indexOf(srcPixelFormat);
if (idx == -1 && srcPixelFormat.isValid())
const auto currentFormatInPresetList =
vectorContains(videoHandlerYUV::formatPresetList, this->srcPixelFormat);
if (!currentFormatInPresetList && this->srcPixelFormat.isValid())
{
// The currently set pixel format is not in the presets list. Add and select it.
ui.yuvFormatComboBox->addItem(QString::fromStdString(srcPixelFormat.getName()));
presetList.append(srcPixelFormat);
idx = presetList.indexOf(srcPixelFormat);
videoHandlerYUV::formatPresetList.push_back(this->srcPixelFormat);
ui.yuvFormatComboBox->addItem(QString::fromStdString(this->srcPixelFormat.getName()));
}
ui.yuvFormatComboBox->setCurrentIndex(idx);
// Add the custom... entry that allows the user to add custom formats
ui.yuvFormatComboBox->addItem("Custom...");
ui.yuvFormatComboBox->setEnabled(!isSizeFixed);
ui.yuvFormatComboBox->setEnabled(!isSizeAndFormatFixed);

if (const auto presetIndex =
vectorIndexOf(videoHandlerYUV::formatPresetList, this->srcPixelFormat))
ui.yuvFormatComboBox->setCurrentIndex(static_cast<int>(*presetIndex));

// Set all the values of the properties widget to the values of this class
const auto hasChroma = (srcPixelFormat.getSubsampling() != Subsampling::YUV_400);
Expand Down Expand Up @@ -2794,62 +2794,43 @@ QLayout *videoHandlerYUV::createVideoHandlerControls(bool isSizeFixed)
this,
&videoHandlerYUV::slotYUVControlChanged);

if (!isSizeFixed && newVBoxLayout)
if (!isSizeAndFormatFixed && newVBoxLayout)
newVBoxLayout->addLayout(ui.topVBoxLayout);

return (isSizeFixed) ? ui.topVBoxLayout : newVBoxLayout;
return (isSizeAndFormatFixed) ? ui.topVBoxLayout : newVBoxLayout;
}

void videoHandlerYUV::slotYUVFormatControlChanged(int idx)
void videoHandlerYUV::slotYUVFormatControlChanged(int selectionIndex)
{
PixelFormatYUV newFormat;
auto newFormat = this->srcPixelFormat;

if (idx == presetList.count())
const auto customFormatSelected = (selectionIndex == videoHandlerYUV::formatPresetList.size());
if (customFormatSelected)
{
// The user selected the "custom format..." option
videoHandlerYUVCustomFormatDialog dialog(srcPixelFormat);
if (dialog.exec() == QDialog::Accepted && dialog.getSelectedYUVFormat().isValid())
{
// Set the custom format
// Check if the user specified a new format
newFormat = dialog.getSelectedYUVFormat();

// Check if the custom format it in the presets list. If not, add it
int idx = presetList.indexOf(newFormat);
if (idx == -1 && newFormat.isValid())
{
// Valid pixel format with is not in the list. Add it...
presetList.append(newFormat);
int nrItems = ui.yuvFormatComboBox->count();
const QSignalBlocker blocker(ui.yuvFormatComboBox);
ui.yuvFormatComboBox->insertItem(nrItems - 1, QString::fromStdString(newFormat.getName()));
// Select the added format
idx = presetList.indexOf(newFormat);
ui.yuvFormatComboBox->setCurrentIndex(idx);
}
else
{
// The format is already in the list. Select it without invoking another signal.
const QSignalBlocker blocker(ui.yuvFormatComboBox);
ui.yuvFormatComboBox->setCurrentIndex(idx);
}
const auto isInPresetList = vectorContains(videoHandlerYUV::formatPresetList, newFormat);
if (!isInPresetList)
{
videoHandlerYUV::formatPresetList.push_back(newFormat);
const QSignalBlocker blocker(this->ui.yuvFormatComboBox);
const auto insertPositionBeforeCustom = (this->ui.yuvFormatComboBox->count() - 1);
ui.yuvFormatComboBox->insertItem(insertPositionBeforeCustom,
QString::fromStdString(newFormat.getName()));
}
else

if (const auto presetIndex = vectorIndexOf(videoHandlerYUV::formatPresetList, newFormat))
{
// The user pressed cancel. Go back to the old format
int idx = presetList.indexOf(srcPixelFormat);
Q_ASSERT(idx != -1); // The previously selected format should always be in the list
const QSignalBlocker blocker(ui.yuvFormatComboBox);
ui.yuvFormatComboBox->setCurrentIndex(idx);
const QSignalBlocker blocker(this->ui.yuvFormatComboBox);
ui.yuvFormatComboBox->setCurrentIndex(*presetIndex);
}
}
else
// One of the preset formats was selected
newFormat = presetList.at(idx);

// Set the new format (if new) and emit a signal that a new format was selected.
if (srcPixelFormat != newFormat && newFormat.isValid())
setSrcPixelFormat(newFormat);
if (newFormat != this->srcPixelFormat && newFormat.isValid())
this->setSrcPixelFormat(newFormat);
}

void videoHandlerYUV::setSrcPixelFormat(PixelFormatYUV format, bool emitSignal)
Expand Down Expand Up @@ -4116,28 +4097,24 @@ void videoHandlerYUV::setPixelFormatYUV(const PixelFormatYUV &newFormat, bool em
if (!newFormat.isValid())
return;

if (newFormat != srcPixelFormat)
if (newFormat != this->srcPixelFormat)
{
if (ui.created())
if (this->ui.created())
{
// Check if the custom format is in the presets list. If not, add it.
int idx = presetList.indexOf(newFormat);
if (idx == -1)
const auto isInPresetList = vectorContains(videoHandlerYUV::formatPresetList, newFormat);
if (!isInPresetList)
{
// Valid pixel format with is not in the list. Add it...
presetList.append(newFormat);
int nrItems = ui.yuvFormatComboBox->count();
videoHandlerYUV::formatPresetList.push_back(newFormat);
const auto insertPositionBeforeCustom = (ui.yuvFormatComboBox->count() - 1);
const QSignalBlocker blocker(ui.yuvFormatComboBox);
ui.yuvFormatComboBox->insertItem(nrItems - 1, QString::fromStdString(newFormat.getName()));
// Select the added format
idx = presetList.indexOf(newFormat);
ui.yuvFormatComboBox->setCurrentIndex(idx);
ui.yuvFormatComboBox->insertItem(insertPositionBeforeCustom,
QString::fromStdString(newFormat.getName()));
}
else

if (const auto presetIndex = vectorIndexOf(videoHandlerYUV::formatPresetList, newFormat))
{
// Just select the format in the combo box
const QSignalBlocker blocker(ui.yuvFormatComboBox);
ui.yuvFormatComboBox->setCurrentIndex(idx);
ui.yuvFormatComboBox->setCurrentIndex(static_cast<int>(*presetIndex));
}
}

Expand Down
4 changes: 2 additions & 2 deletions YUViewLib/src/video/yuv/videoHandlerYUV.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ class videoHandlerYUV : public videoHandler
// Create the YUV controls and return a pointer to the layout.
// yuvFormatFixed: For example a YUV file does not have a fixed format (the user can change this),
// other sources might provide a fixed format which the user cannot change (HEVC file, ...)
virtual QLayout *createVideoHandlerControls(bool isSizeFixed = false) override;
virtual QLayout *createVideoHandlerControls(bool isSizeAndFormatFixed = false) override;

// Get the name of the currently selected YUV pixel format
virtual QString getRawPixelFormatYUVName() const
Expand Down Expand Up @@ -245,7 +245,7 @@ class videoHandlerYUV : public videoHandler
QByteArray diffYUV;
PixelFormatYUV diffYUVFormat{};

QList<PixelFormatYUV> presetList;
static std::vector<PixelFormatYUV> formatPresetList;

private slots:

Expand Down

0 comments on commit 01edae3

Please sign in to comment.