Skip to content

Commit

Permalink
Use more ByteVector
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristianFeldmann committed Dec 5, 2024
1 parent 6a682b1 commit 20b2d69
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 82 deletions.
84 changes: 58 additions & 26 deletions YUViewLib/src/playlistitem/playlistItemRawFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,18 @@ bool isInExtensions(const QString &testValue, const std::initializer_list<const
return it != extensions.end();
}

std::string extractStringFromByteVector(const ByteVector &data, const int offset, const int length)
{
const auto requiredDataLength = offset + length;
if (data.empty() || offset <= 0 || length <= 0 || data.size() < requiredDataLength)
return {};

std::string str;
for (auto i = offset; i < offset + length; ++i)
str.push_back(data.at(i));
return str;
}

} // namespace

playlistItemRawFile::playlistItemRawFile(const QString &rawFilePath,
Expand All @@ -81,11 +93,11 @@ playlistItemRawFile::playlistItemRawFile(const QString &rawFilePath,
this->prop.isFileSource = true;
this->prop.propertiesWidgetTitle = "Raw File Properties";

this->dataSource.openFile(std::filesystem::path(rawFilePath.toStdString()));
this->dataSource = std::make_unique<datasource::DataSourceLocalFile>(
std::filesystem::path(rawFilePath.toStdString()));

if (!this->dataSource.isOk())
if (!this->dataSource->isOk())
{
// Opening the file failed.
this->setError("Error opening the input file.");
return;
}
Expand Down Expand Up @@ -133,9 +145,9 @@ playlistItemRawFile::playlistItemRawFile(const QString &rawFilePath,
if (!this->video->isFormatValid())
{
// Load 24883200 bytes from the input and try to get the format from the correlation.
QByteArray rawData;
this->dataSource.readBytes(rawData, 0, 24883200);
this->video->setFormatFromCorrelation(rawData, this->dataSource.getFileSize().value_or(-1));
ByteVector rawData;
this->dataSource->read(rawData, 24883200);
this->video->setFormatFromCorrelation(rawData, this->dataSource->getFileSize().value_or(-1));
}
}
else
Expand Down Expand Up @@ -172,7 +184,7 @@ playlistItemRawFile::playlistItemRawFile(const QString &rawFilePath,

void playlistItemRawFile::updateStartEndRange()
{
if (!this->dataSource.isOk() || !this->video->isFormatValid())
if (!this->dataSource->isOk() || !this->video->isFormatValid())
{
this->prop.startEndRange = indexRange(-1, -1);
return;
Expand All @@ -189,7 +201,7 @@ void playlistItemRawFile::updateStartEndRange()
this->prop.startEndRange = indexRange(-1, -1);
return;
}
nrFrames = this->dataSource.getFileSize().value_or(0) / bpf;
nrFrames = this->dataSource->getFileSize().value_or(0) / bpf;
}

this->prop.startEndRange = indexRange(0, std::max(nrFrames - 1, 0));
Expand All @@ -200,22 +212,22 @@ InfoData playlistItemRawFile::getInfo() const
InfoData info((rawFormat == video::RawFormat::YUV) ? "YUV File Info" : "RGB File Info");

// At first append the file information part (path, date created, file size...)
for (const auto &infoItem : this->dataSource.getFileInfoList())
for (const auto &infoItem : this->dataSource->getInfoList())
info.items.append(infoItem);

const auto nrFrames =
(this->properties().startEndRange.second - this->properties().startEndRange.first + 1);
info.items.append(InfoItem("Num Frames", std::to_string(nrFrames)));
info.items.append(InfoItem("Bytes per Frame", std::to_string(this->video->getBytesPerFrame())));

if (this->dataSource.isOk() && this->video->isFormatValid() && !this->isY4MFile)
if (this->dataSource->isOk() && this->video->isFormatValid() && !this->isY4MFile)
{
// Check if the size of the file and the number of bytes per frame can be divided
// without any remainder. If not, then there is probably something wrong with the
// selected YUV format / width / height ...

auto bpf = this->video->getBytesPerFrame();
if (const auto fileSize = this->dataSource.getFileSize())
if (const auto fileSize = this->dataSource->getFileSize())
{
if ((*fileSize % bpf) != 0)
info.items.append(InfoItem(
Expand All @@ -232,13 +244,13 @@ bool playlistItemRawFile::parseY4MFile()
{
// Read a chunck of data from the file. Thecnically, the header can be arbitrarily long, but in
// practice, 512 bytes should cover the length of all headers
QByteArray rawData;
this->dataSource.readBytes(rawData, 0, 512);
ByteVector rawData;
this->dataSource->read(rawData, 512);

DEBUG_RAWFILE("playlistItemRawFile::parseY4MFile Read Y4M");

// A Y4M file must start with the signature string "YUV4MPEG2 ".
if (rawData.left(10) != "YUV4MPEG2 ")
if (extractStringFromByteVector(rawData, 0, 10) != "YUV4MPEG2 ")
return setError("Y4M File header does not start with YUV4MPEG2 header signature.");

DEBUG_RAWFILE("playlistItemRawFile::parseY4MFile Found signature YUV4MPEG2");
Expand Down Expand Up @@ -319,7 +331,7 @@ bool playlistItemRawFile::parseY4MFile()
else if (parameterIndicator == 'C')
{
// Get 3 bytes and check them
auto formatName = rawData.mid(offset, 3);
const auto formatName = extractStringFromByteVector(rawData, offset, 3);
offset += 3;

// The YUV format. By default, YUV420 is setup.
Expand Down Expand Up @@ -405,10 +417,13 @@ bool playlistItemRawFile::parseY4MFile()
while (true)
{
// Seek the file to 'offset' and read a few bytes
if (this->dataSource.readBytes(rawData, offset, 20) < 20)
if (!this->dataSource->seek(offset))
return setError(
QString("Error parsing the Y4M header: Unable to seek to position %1").arg(offset));
if (this->dataSource->read(rawData, 20) < 20)
return setError("Error parsing the Y4M header: The file ended unexpectedly.");

auto frameIndicator = rawData.mid(0, 5);
const auto frameIndicator = extractStringFromByteVector(rawData, 0, 5);
if (frameIndicator != "FRAME")
return setError("Error parsing the Y4M header: Could not locate the next 'FRAME' indicator.");

Expand All @@ -434,7 +449,7 @@ bool playlistItemRawFile::parseY4MFile()
DEBUG_RAWFILE("playlistItemRawFile::parseY4MFile Found FRAME at offset " << offset);

offset += stride;
if (offset >= this->dataSource.getFileSize())
if (offset >= this->dataSource->getFileSize())
break;
}

Expand All @@ -449,8 +464,8 @@ bool playlistItemRawFile::parseY4MFile()

void playlistItemRawFile::setFormatFromFileName()
{
const auto fileInfoForGuess = filesource::frameFormatGuess::getFileInfoForGuessFromPath(
this->dataSource.getAbsoluteFilePath());
const auto fileInfoForGuess =
filesource::frameFormatGuess::getFileInfoForGuessFromPath(this->dataSource->getFilePath());

const auto frameFormat = filesource::frameFormatGuess::guessFrameFormat(fileInfoForGuess);

Expand Down Expand Up @@ -491,10 +506,10 @@ void playlistItemRawFile::createPropertiesWidget()

void playlistItemRawFile::savePlaylist(QDomElement &root, const QDir &playlistDir) const
{
QUrl fileURL(QString::fromStdString(dataSource.getAbsoluteFilePath()));
QUrl fileURL(QString::fromStdString(dataSource->getFilePath()));
fileURL.setScheme("file");
auto relativePath =
playlistDir.relativeFilePath(QString::fromStdString(dataSource.getAbsoluteFilePath()));
playlistDir.relativeFilePath(QString::fromStdString(dataSource->getFilePath()));

auto d = YUViewDomElement(root.ownerDocument().createElement("playlistItemRawFile"));

Expand Down Expand Up @@ -550,7 +565,9 @@ void playlistItemRawFile::loadRawData(int frameIdx)

DEBUG_RAWFILE("playlistItemRawFile::loadRawData Start loading frame " << frameIdx << " bytes "
<< int(nrBytes));
if (this->dataSource.readBytes(this->video->rawData, fileStartPos, nrBytes) < nrBytes)
if (!this->dataSource->seek(fileStartPos))
return;
if (this->dataSource->read(this->video->rawData, nrBytes) < nrBytes)
return; // Error
this->video->rawData_frameIndex = frameIdx;

Expand Down Expand Up @@ -589,12 +606,18 @@ void playlistItemRawFile::getSupportedFileExtensions(QStringList &allExtensions,
filters.append("Raw CMYK File (*.cmyk)");
}

bool playlistItemRawFile::isSourceChanged()
{
if (!this->dataSource)
return false;
return this->dataSource->wasSourceModified();
}

void playlistItemRawFile::reloadItemSource()
{
// Reopen the file
this->dataSource.openFile(this->properties().name.toStdString());
if (!this->dataSource.isOk())
// Opening the file failed.
this->dataSource->reloadAndResetDataSource();
if (!this->dataSource->isOk())
return;

this->video->invalidateAllBuffers();
Expand All @@ -603,3 +626,12 @@ void playlistItemRawFile::reloadItemSource()
// Emit that the item needs redrawing and the cache changed.
emit SignalItemChanged(true, RECACHE_NONE);
}

void playlistItemRawFile::cacheFrame(int idx, bool testMode)
{
if (!this->dataSource)
return;
if (testMode)
this->dataSource->clearFileCache();
playlistItemWithVideo::cacheFrame(idx, testMode);
}
19 changes: 6 additions & 13 deletions YUViewLib/src/playlistitem/playlistItemRawFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
#pragma once

#include <common/Typedef.h>
#include <filesource/FileSource.h>
#include <dataSource/DataSourceLocalFile.h>
#include <dataSource/IDataSource.h>

#include <QFuture>
#include <QString>
Expand Down Expand Up @@ -64,7 +65,7 @@ class playlistItemRawFile : public playlistItemWithVideo
// Create a new playlistItemRawFile from the playlist file entry. Return nullptr if parsing
// failed.
static playlistItemRawFile *newplaylistItemRawFile(const YUViewDomElement &root,
const QString & playlistFilePath);
const QString &playlistFilePath);

virtual bool canBeUsedInProcessing() const override { return true; }

Expand All @@ -73,18 +74,10 @@ class playlistItemRawFile : public playlistItemWithVideo
// Add the file type filters and the extensions of files that we can load.
static void getSupportedFileExtensions(QStringList &allExtensions, QStringList &filters);

// ----- Detection of source/file change events -----
virtual bool isSourceChanged() override { return this->dataSource.getAndResetFileChangedFlag(); }
virtual bool isSourceChanged() override;
virtual void reloadItemSource() override;
virtual void updateSettings() override { this->dataSource.updateFileWatchSetting(); }

// Cache the given frame
virtual void cacheFrame(int idx, bool testMode) override
{
if (testMode)
dataSource.clearFileCache();
playlistItemWithVideo::cacheFrame(idx, testMode);
}
virtual void cacheFrame(int idx, bool testMode) override;

private slots:
// Load the raw data for the given frame index from file. This slot is called by the videoHandler
Expand All @@ -105,7 +98,7 @@ private slots:

int getNumberFrames() const;

FileSource dataSource;
std::unique_ptr<datasource::DataSourceLocalFile> dataSource;

void updateStartEndRange() override;

Expand Down
2 changes: 1 addition & 1 deletion YUViewLib/src/video/rgb/videoHandlerRGB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ QStringPairList videoHandlerRGB::getPixelValues(const QPoint &pixelPos,
return values;
}

void videoHandlerRGB::setFormatFromCorrelation(const QByteArray &, int64_t)
void videoHandlerRGB::setFormatFromCorrelation(const ByteVector &, int64_t)
{ /* TODO */
}

Expand Down
2 changes: 1 addition & 1 deletion YUViewLib/src/video/rgb/videoHandlerRGB.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class videoHandlerRGB : public videoHandler

// Try to guess and set the format (frameSize/srcPixelFormat) from the raw RGB data.
// If a file size is given, it is tested if the RGB format and the file size match.
virtual void setFormatFromCorrelation(const QByteArray &rawRGBData,
virtual void setFormatFromCorrelation(const ByteVector &rawRGBData,
int64_t fileSize = -1) override;

virtual QString getFormatAsString() const override
Expand Down
16 changes: 8 additions & 8 deletions YUViewLib/src/video/videoHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ void videoHandler::setFrameSize(Size size)
{
if (size != frameSize)
{
this->currentFrameRawData_frameIndex = -1;
this->currentImageIndex = -1;
this->rawData_frameIndex = -1;
this->currentFrameRawDataFrameIndex = -1;
this->currentImageIndex = -1;
this->rawData_frameIndex = -1;
}

FrameHandler::setFrameSize(size);
Expand Down Expand Up @@ -221,7 +221,7 @@ void videoHandler::drawFrame(QPainter *painter, int frameIdx, double zoomFactor,
}
}

QImage videoHandler::calculateDifference(FrameHandler * item2,
QImage videoHandler::calculateDifference(FrameHandler *item2,
const int frameIdxItem0,
const int frameIdxItem1,
QList<InfoItem> &differenceInfoList,
Expand Down Expand Up @@ -387,8 +387,8 @@ void videoHandler::loadFrameForCaching(int frameIndex, QImage &frameToCache)

void videoHandler::invalidateAllBuffers()
{
currentFrameRawData_frameIndex = -1;
rawData_frameIndex = -1;
currentFrameRawDataFrameIndex = -1;
rawData_frameIndex = -1;

// Set the current frame in the buffer to be invalid
currentImageIndex = -1;
Expand Down Expand Up @@ -419,8 +419,8 @@ QLayout *videoHandler::createVideoHandlerControls(bool)

ItemLoadingState videoHandler::needsLoadingRawValues(int frameIndex)
{
return (this->currentFrameRawData_frameIndex == frameIndex) ? ItemLoadingState::LoadingNotNeeded
: ItemLoadingState::LoadingNeeded;
return (this->currentFrameRawDataFrameIndex == frameIndex) ? ItemLoadingState::LoadingNotNeeded
: ItemLoadingState::LoadingNeeded;
}

} // namespace video
8 changes: 4 additions & 4 deletions YUViewLib/src/video/videoHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class videoHandler : public FrameHandler
// Try to guess and set the format (frameSize/srcPixelFormat) from the raw data in the right raw
// format. If a file size is given, it is tested if the guessed format and the file size match.
// You can overload this for any specific raw format. The default implementation does nothing.
virtual void setFormatFromCorrelation(const QByteArray &, int64_t fileSize = -1)
virtual void setFormatFromCorrelation(const ByteVector &, int64_t fileSize = -1)
{
(void)fileSize;
}
Expand Down Expand Up @@ -131,7 +131,7 @@ class videoHandler : public FrameHandler
// TODO: Explain better what the difference between these two is (currentFrameRawData and rawData)

// A buffer with the raw RGB data (this is filled if signalRequestRawData() is emitted)
QByteArray rawData;
ByteVector rawData;
int rawData_frameIndex{-1};

// Do we need to load the raw values (because they are drawn on screen?)
Expand Down Expand Up @@ -186,8 +186,8 @@ class videoHandler : public FrameHandler
// The buffer of the raw data (RGB or YUV) of the current frame (and its frame index)
// Before using the currentFrameRawData, you have to check if the currentFrameRawData_frameIndex
// is correct. If not, you have to call loadFrame() to load the frame and set it correctly.
QByteArray currentFrameRawData;
int currentFrameRawData_frameIndex{-1};
ByteVector currentFrameRawData;
int currentFrameRawDataFrameIndex{-1};

// Set the cache to be invalid until a call to removefromCache(-1) clears it.
void setCacheInvalid() { cacheValid = false; }
Expand Down
Loading

0 comments on commit 20b2d69

Please sign in to comment.