Skip to content

Commit

Permalink
Merge pull request #542 from happycube/dropout-refactor
Browse files Browse the repository at this point in the history
Refactored dropout handling into its own class
  • Loading branch information
Simon Inns authored Aug 28, 2020
2 parents 34eda6e + ecac5b1 commit f081df4
Show file tree
Hide file tree
Showing 19 changed files with 297 additions and 115 deletions.
6 changes: 4 additions & 2 deletions tools/ld-analyse/ld-analyse.pro
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ SOURCES += \
../library/tbc/sourcevideo.cpp \
../library/tbc/vbidecoder.cpp \
../library/tbc/filters.cpp \
../library/tbc/logging.cpp
../library/tbc/logging.cpp \
../library/tbc/dropouts.cpp

HEADERS += \
busydialog.h \
Expand Down Expand Up @@ -78,7 +79,8 @@ HEADERS += \
../library/tbc/sourcevideo.h \
../library/tbc/vbidecoder.h \
../library/tbc/filters.h \
../library/tbc/logging.h
../library/tbc/logging.h \
../library/tbc/dropouts.h

FORMS += \
busydialog.ui \
Expand Down
34 changes: 17 additions & 17 deletions tools/ld-analyse/tbcsource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,20 +176,20 @@ QImage TbcSource::getFrameImage(qint32 frameNumber)

// Draw the drop out data for the first field
imagePainter.setPen(Qt::red);
for (qint32 dropOutIndex = 0; dropOutIndex < firstField.dropOuts.startx.size(); dropOutIndex++) {
qint32 startx = firstField.dropOuts.startx[dropOutIndex];
qint32 endx = firstField.dropOuts.endx[dropOutIndex];
qint32 fieldLine = firstField.dropOuts.fieldLine[dropOutIndex];
for (qint32 dropOutIndex = 0; dropOutIndex < firstField.dropOuts.size(); dropOutIndex++) {
qint32 startx = firstField.dropOuts.startx(dropOutIndex);
qint32 endx = firstField.dropOuts.endx(dropOutIndex);
qint32 fieldLine = firstField.dropOuts.fieldLine(dropOutIndex);

imagePainter.drawLine(startx, ((fieldLine - 1) * 2), endx, ((fieldLine - 1) * 2));
}

// Draw the drop out data for the second field
imagePainter.setPen(Qt::blue);
for (qint32 dropOutIndex = 0; dropOutIndex < secondField.dropOuts.startx.size(); dropOutIndex++) {
qint32 startx = secondField.dropOuts.startx[dropOutIndex];
qint32 endx = secondField.dropOuts.endx[dropOutIndex];
qint32 fieldLine = secondField.dropOuts.fieldLine[dropOutIndex];
for (qint32 dropOutIndex = 0; dropOutIndex < secondField.dropOuts.size(); dropOutIndex++) {
qint32 startx = secondField.dropOuts.startx(dropOutIndex);
qint32 endx = secondField.dropOuts.endx(dropOutIndex);
qint32 fieldLine = secondField.dropOuts.fieldLine(dropOutIndex);

imagePainter.drawLine(startx, ((fieldLine - 1) * 2) + 1, endx, ((fieldLine - 1) * 2) + 1);
}
Expand Down Expand Up @@ -295,8 +295,8 @@ bool TbcSource::getIsDropoutPresent(qint32 frameNumber)
qint32 firstFieldNumber = ldDecodeMetaData.getFirstFieldNumber(frameNumber);
qint32 secondFieldNumber = ldDecodeMetaData.getSecondFieldNumber(frameNumber);

if (ldDecodeMetaData.getFieldDropOuts(firstFieldNumber).startx.size() > 0) dropOutsPresent = true;
if (ldDecodeMetaData.getFieldDropOuts(secondFieldNumber).startx.size() > 0) dropOutsPresent = true;
if (ldDecodeMetaData.getFieldDropOuts(firstFieldNumber).size() > 0) dropOutsPresent = true;
if (ldDecodeMetaData.getFieldDropOuts(secondFieldNumber).size() > 0) dropOutsPresent = true;

return dropOutsPresent;
}
Expand Down Expand Up @@ -337,7 +337,7 @@ TbcSource::ScanLineData TbcSource::getScanLineData(qint32 frameNumber, qint32 sc

// Get the field video and dropout data
SourceVideo::Data fieldData;
LdDecodeMetaData::DropOuts dropouts;
DropOuts dropouts;
if (isFieldTop) {
fieldData = sourceVideo.getVideoField(firstFieldNumber);
dropouts = ldDecodeMetaData.getFieldDropOuts(firstFieldNumber);
Expand All @@ -353,9 +353,9 @@ TbcSource::ScanLineData TbcSource::getScanLineData(qint32 frameNumber, qint32 sc
scanLineData.data[xPosition] = fieldData[((fieldLine - 1) * videoParameters.fieldWidth) + xPosition];

scanLineData.isDropout[xPosition] = false;
for (qint32 doCount = 0; doCount < dropouts.startx.size(); doCount++) {
if (dropouts.fieldLine[doCount] == fieldLine) {
if (xPosition >= dropouts.startx[doCount] && xPosition <= dropouts.endx[doCount]) scanLineData.isDropout[xPosition] = true;
for (qint32 doCount = 0; doCount < dropouts.size(); doCount++) {
if (dropouts.fieldLine(doCount) == fieldLine) {
if (xPosition >= dropouts.startx(doCount) && xPosition <= dropouts.endx(doCount)) scanLineData.isDropout[xPosition] = true;
}
}
}
Expand Down Expand Up @@ -641,10 +641,10 @@ void TbcSource::generateData(qint32 _targetDataPoints)
LdDecodeMetaData::Field field = ldDecodeMetaData.getField(fieldNumber);

// Get the DOs
if (field.dropOuts.startx.size() > 0) {
if (field.dropOuts.size() > 0) {
// Calculate the total length of the dropouts
for (qint32 i = 0; i < field.dropOuts.startx.size(); i++) {
doLength += field.dropOuts.endx[i] - field.dropOuts.startx[i];
for (qint32 i = 0; i < field.dropOuts.size(); i++) {
doLength += field.dropOuts.endx(i) - field.dropOuts.startx(i);
}
}

Expand Down
6 changes: 4 additions & 2 deletions tools/ld-chroma-decoder/encoder/encoder.pro
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@ SOURCES += \
palencoder.cpp \
../../library/tbc/lddecodemetadata.cpp \
../../library/tbc/logging.cpp \
../../library/tbc/vbidecoder.cpp
../../library/tbc/vbidecoder.cpp \
../../library/tbc/dropouts.cpp

HEADERS += \
palencoder.h \
../../library/filter/firfilter.h \
../../library/tbc/lddecodemetadata.h \
../../library/tbc/logging.h \
../../library/tbc/vbidecoder.h
../../library/tbc/vbidecoder.h \
../../library/tbc/dropouts.h

# Add external includes to the include path
INCLUDEPATH += ../../library/filter
Expand Down
6 changes: 4 additions & 2 deletions tools/ld-chroma-decoder/ld-chroma-decoder.pro
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ SOURCES += \
../library/tbc/lddecodemetadata.cpp \
../library/tbc/sourcevideo.cpp \
../library/tbc/vbidecoder.cpp \
../library/tbc/logging.cpp
../library/tbc/logging.cpp \
../library/tbc/dropouts.cpp

HEADERS += \
comb.h \
Expand All @@ -56,7 +57,8 @@ HEADERS += \
../library/tbc/lddecodemetadata.h \
../library/tbc/sourcevideo.h \
../library/tbc/vbidecoder.h \
../library/tbc/logging.h
../library/tbc/logging.h \
../library/tbc/dropouts.h

# Add external includes to the include path
INCLUDEPATH += ../library/filter
Expand Down
45 changes: 8 additions & 37 deletions tools/ld-diffdod/diffdod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ void DiffDod::run()
bool signalClip;

// Set up the output variables
QVector<LdDecodeMetaData::DropOuts> firstFieldDropouts;
QVector<LdDecodeMetaData::DropOuts> secondFieldDropouts;
QVector<DropOuts> firstFieldDropouts;
QVector<DropOuts> secondFieldDropouts;

// Process frames until there's nothing left to process
while(!m_abort) {
Expand Down Expand Up @@ -233,12 +233,12 @@ void DiffDod::getFieldErrorByMedian(QVector<SourceVideo::Data> &fields, QVector<
// Method to create the field drop-out metadata based on the differential map of the fields
// This method compares each available source against all other available sources to determine where the source differs.
// If any of the frame's contents do not match that of the other sources, the frame's pixels are marked as dropouts.
QVector<LdDecodeMetaData::DropOuts> DiffDod::getFieldDropouts(QVector<QByteArray> &fieldDiff,
QVector<DropOuts> DiffDod::getFieldDropouts(QVector<QByteArray> &fieldDiff,
LdDecodeMetaData::VideoParameters videoParameters,
QVector<qint32> availableSourcesForFrame)
{
// Create and resize the return data vector
QVector<LdDecodeMetaData::DropOuts> fieldDropouts;
QVector<DropOuts> fieldDropouts;
fieldDropouts.resize(fieldDiff.size());

// This method requires at least three source frames
Expand Down Expand Up @@ -275,9 +275,7 @@ QVector<LdDecodeMetaData::DropOuts> DiffDod::getFieldDropouts(QVector<QByteArray
doCounter--;
if (doCounter == 0) {
// Mark the previous x as the end of the dropout
fieldDropouts[sourceNo].startx.append(doStart);
fieldDropouts[sourceNo].endx.append(x - 1);
fieldDropouts[sourceNo].fieldLine.append(doFieldLine);
fieldDropouts[sourceNo].append(doStart, x - 1, doFieldLine);
}
}
} else {
Expand All @@ -294,9 +292,7 @@ QVector<LdDecodeMetaData::DropOuts> DiffDod::getFieldDropouts(QVector<QByteArray
if (doCounter > 0) {
doCounter = 0;

fieldDropouts[sourceNo].startx.append(doStart);
fieldDropouts[sourceNo].endx.append(areaEnd);
fieldDropouts[sourceNo].fieldLine.append(doFieldLine);
fieldDropouts[sourceNo].append(doStart, areaEnd, doFieldLine);
}

} // Next source
Expand All @@ -307,38 +303,13 @@ QVector<LdDecodeMetaData::DropOuts> DiffDod::getFieldDropouts(QVector<QByteArray

// Method to concatenate dropouts on the same line that are close together
// (to cut down on the amount of generated metadata with noisy/bad sources)
void DiffDod::concatenateFieldDropouts(QVector<LdDecodeMetaData::DropOuts> &dropouts,
void DiffDod::concatenateFieldDropouts(QVector<DropOuts> &dropouts,
QVector<qint32> availableSourcesForFrame)
{
// This variable controls the minimum allowed gap between dropouts
// if the gap between the end of the last dropout and the start of
// the next is less than minimumGap, the two dropouts will be
// concatenated together
qint32 minimumGap = 50;

for (qint32 sourcePointer = 0; sourcePointer < availableSourcesForFrame.size(); sourcePointer++) {
qint32 sourceNo = availableSourcesForFrame[sourcePointer]; // Get the actual source

// Start from 1 as 0 has no previous dropout
qint32 i = 1;

while (i < dropouts[sourceNo].startx.size()) {
// Is the current dropout on the same field line as the last?
if (dropouts[sourceNo].fieldLine[i - 1] == dropouts[sourceNo].fieldLine[i]) {
if ((dropouts[sourceNo].endx[i - 1] + minimumGap) > (dropouts[sourceNo].startx[i])) {
// Concatenate
dropouts[sourceNo].endx[i - 1] = dropouts[sourceNo].endx[i];

// Remove the current dropout
dropouts[sourceNo].startx.removeAt(i);
dropouts[sourceNo].endx.removeAt(i);
dropouts[sourceNo].fieldLine.removeAt(i);
}
}

// Next dropout
i++;
}
dropouts[sourceNo].concatenate();
}
}

Expand Down
4 changes: 2 additions & 2 deletions tools/ld-diffdod/diffdod.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ class DiffDod : public QThread
void getFieldErrorByMedian(QVector<SourceVideo::Data> &fields, QVector<QByteArray> &fieldDiff, qint32 dodThreshold,
LdDecodeMetaData::VideoParameters videoParameters,
QVector<qint32> availableSourcesForFrame);
QVector<LdDecodeMetaData::DropOuts> getFieldDropouts(QVector<QByteArray> &fieldDiff,
QVector<DropOuts> getFieldDropouts(QVector<QByteArray> &fieldDiff,
LdDecodeMetaData::VideoParameters videoParameters,
QVector<qint32> availableSourcesForFrame);

void concatenateFieldDropouts(QVector<LdDecodeMetaData::DropOuts> &dropouts, QVector<qint32> availableSourcesForFrame);
void concatenateFieldDropouts(QVector<DropOuts> &dropouts, QVector<qint32> availableSourcesForFrame);

qint32 median(QVector<qint32> v);
float convertLinearToBrightness(quint16 value, quint16 black16bIre, quint16 white16bIre, bool isSourcePal);
Expand Down
2 changes: 2 additions & 0 deletions tools/ld-diffdod/ld-diffdod.pro
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ SOURCES += \
../library/tbc/vbidecoder.cpp \
../library/tbc/filters.cpp \
../library/tbc/logging.cpp \
../library/tbc/dropouts.cpp \
diffdod.cpp \
main.cpp \
sources.cpp
Expand All @@ -31,6 +32,7 @@ HEADERS += \
../library/tbc/vbidecoder.h \
../library/tbc/filters.h \
../library/tbc/logging.h \
../library/tbc/dropouts.h \
diffdod.h \
sources.h

Expand Down
8 changes: 4 additions & 4 deletions tools/ld-diffdod/sources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ bool Sources::getInputFrame(qint32& targetVbiFrame,

// Receive a frame from the threaded processing
bool Sources::setOutputFrame(qint32 targetVbiFrame,
QVector<LdDecodeMetaData::DropOuts> firstFieldDropouts,
QVector<LdDecodeMetaData::DropOuts> secondFieldDropouts,
QVector<DropOuts> firstFieldDropouts,
QVector<DropOuts> secondFieldDropouts,
QVector<qint32> availableSourcesForFrame)
{
QMutexLocker locker(&outputMutex);
Expand All @@ -184,8 +184,8 @@ bool Sources::setOutputFrame(qint32 targetVbiFrame,
// Calculate the total number of dropouts detected for the frame
qint32 totalFirstDropouts = 0;
qint32 totalSecondDropouts = 0;
if (firstFieldDropouts.size() > 0) totalFirstDropouts = firstFieldDropouts[sourceNo].startx.size();
if (secondFieldDropouts.size() > 0) totalSecondDropouts = secondFieldDropouts[sourceNo].startx.size();
if (firstFieldDropouts.size() > 0) totalFirstDropouts = firstFieldDropouts[sourceNo].size();
if (secondFieldDropouts.size() > 0) totalSecondDropouts = secondFieldDropouts[sourceNo].size();

qDebug() << "Writing source" << sourceNo <<
"frame" << targetVbiFrame << "fields" << firstFieldNumber << "/" << secondFieldNumber <<
Expand Down
4 changes: 2 additions & 2 deletions tools/ld-diffdod/sources.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ class Sources : public QObject
qint32& dodThreshold, bool& signalClip);

bool setOutputFrame(qint32 targetVbiFrame,
QVector<LdDecodeMetaData::DropOuts> firstFieldDropouts,
QVector<LdDecodeMetaData::DropOuts> secondFieldDropouts,
QVector<DropOuts> firstFieldDropouts,
QVector<DropOuts> secondFieldDropouts,
QVector<qint32> availableSourcesForFrame);

private:
Expand Down
12 changes: 6 additions & 6 deletions tools/ld-discmap/discmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,16 +283,16 @@ DiscMap::DiscMap(const QFileInfo &metadataFileInfo, const bool &reverseFieldOrde

// Calculate the cumulative length of all the dropouts in the frame (by summing both fields)
qint32 totalDotsInFrame = (ldDecodeMetaData->getVideoParameters().fieldHeight * 2) + ldDecodeMetaData->getVideoParameters().fieldWidth;
LdDecodeMetaData::DropOuts dropOuts1 = ldDecodeMetaData->getFieldDropOuts(ldDecodeMetaData->getFirstFieldNumber(frameNumber + 1));
LdDecodeMetaData::DropOuts dropOuts2 = ldDecodeMetaData->getFieldDropOuts(ldDecodeMetaData->getSecondFieldNumber(frameNumber + 1));
DropOuts dropOuts1 = ldDecodeMetaData->getFieldDropOuts(ldDecodeMetaData->getFirstFieldNumber(frameNumber + 1));
DropOuts dropOuts2 = ldDecodeMetaData->getFieldDropOuts(ldDecodeMetaData->getSecondFieldNumber(frameNumber + 1));

qint32 frameDoLength = 0;
for (qint32 i = 0; i < dropOuts1.startx.size(); i++) {
frameDoLength += dropOuts1.endx[i] - dropOuts1.startx[i];
for (qint32 i = 0; i < dropOuts1.size(); i++) {
frameDoLength += dropOuts1.endx(i) - dropOuts1.startx(i);
}

for (qint32 i = 0; i < dropOuts2.startx.size(); i++) {
frameDoLength += dropOuts2.endx[i] - dropOuts2.startx[i];
for (qint32 i = 0; i < dropOuts2.size(); i++) {
frameDoLength += dropOuts2.endx(i) - dropOuts2.startx(i);
}

qreal frameDoPercent = 100.0 - (static_cast<qreal>(frameDoLength) / static_cast<qreal>(totalDotsInFrame));
Expand Down
2 changes: 2 additions & 0 deletions tools/ld-discmap/ld-discmap.pro
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ SOURCES += \
../library/tbc/sourcevideo.cpp \
../library/tbc/vbidecoder.cpp \
../library/tbc/logging.cpp \
../library/tbc/dropouts.cpp \
discmap.cpp \
discmapper.cpp \
frame.cpp \
Expand All @@ -29,6 +30,7 @@ HEADERS += \
../library/tbc/sourcevideo.h \
../library/tbc/vbidecoder.h \
../library/tbc/logging.h \
../library/tbc/dropouts.h \
discmap.h \
discmapper.h \
frame.h
Expand Down
16 changes: 8 additions & 8 deletions tools/ld-dropout-correct/dropoutcorrect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,30 +75,30 @@ void DropOutCorrect::run()
QVector<SourceVideo::Data> secondFieldData = secondSourceField;

// Check if the frame contains drop-outs
if (firstFieldMetadata[0].dropOuts.startx.empty() && secondFieldMetadata[0].dropOuts.startx.empty()) {
if (firstFieldMetadata[0].dropOuts.empty() && secondFieldMetadata[0].dropOuts.empty()) {
// No correction required...
qDebug() << "DropOutCorrect::process(): Skipping fields [" <<
firstFieldSeqNo[0] << "/" << secondFieldSeqNo[0] << "]";
} else {
// Perform correction...
qDebug().nospace() << "DropOutCorrect::process(): Correcting fields [" <<
firstFieldSeqNo[0] << "/" << secondFieldSeqNo[0] << "] containing " <<
firstFieldMetadata[0].dropOuts.startx.size() + secondFieldMetadata[0].dropOuts.startx.size() <<
firstFieldMetadata[0].dropOuts.size() + secondFieldMetadata[0].dropOuts.size() <<
" drop-outs";

// Analyse the drop out locations in the first field
QVector<QVector<DropOutLocation>> firstFieldDropouts(totalAvailableSources);
for (qint32 i = 0; i < availableSourcesForFrame.size(); i++) {
qint32 currentSource = availableSourcesForFrame[i];
if (firstFieldMetadata[currentSource].dropOuts.startx.size() > 0)
if (firstFieldMetadata[currentSource].dropOuts.size() > 0)
firstFieldDropouts[currentSource] = setDropOutLocations(populateDropoutsVector(firstFieldMetadata[currentSource], overCorrect));
}

// Analyse the drop out locations in the second field
QVector<QVector<DropOutLocation>> secondFieldDropouts(totalAvailableSources);
for (qint32 i = 0; i < availableSourcesForFrame.size(); i++) {
qint32 currentSource = availableSourcesForFrame[i];
if (secondFieldMetadata[currentSource].dropOuts.startx.size() > 0)
if (secondFieldMetadata[currentSource].dropOuts.size() > 0)
secondFieldDropouts[currentSource] = setDropOutLocations(populateDropoutsVector(secondFieldMetadata[currentSource], overCorrect));
}

Expand Down Expand Up @@ -158,11 +158,11 @@ QVector<DropOutCorrect::DropOutLocation> DropOutCorrect::populateDropoutsVector(
{
QVector<DropOutLocation> fieldDropOuts;

for (qint32 dropOutIndex = 0; dropOutIndex < field.dropOuts.startx.size(); dropOutIndex++) {
for (qint32 dropOutIndex = 0; dropOutIndex < field.dropOuts.size(); dropOutIndex++) {
DropOutLocation dropOutLocation;
dropOutLocation.startx = field.dropOuts.startx[dropOutIndex];
dropOutLocation.endx = field.dropOuts.endx[dropOutIndex];
dropOutLocation.fieldLine = field.dropOuts.fieldLine[dropOutIndex];
dropOutLocation.startx = field.dropOuts.startx(dropOutIndex);
dropOutLocation.endx = field.dropOuts.endx(dropOutIndex);
dropOutLocation.fieldLine = field.dropOuts.fieldLine(dropOutIndex);
dropOutLocation.location = DropOutCorrect::Location::unknown;

// Ignore dropouts outside the field's data
Expand Down
6 changes: 4 additions & 2 deletions tools/ld-dropout-correct/ld-dropout-correct.pro
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ SOURCES += \
../library/tbc/lddecodemetadata.cpp \
../library/tbc/sourcevideo.cpp \
../library/tbc/vbidecoder.cpp \
../library/tbc/logging.cpp
../library/tbc/logging.cpp \
../library/tbc/dropouts.cpp

HEADERS += \
correctorpool.h \
Expand All @@ -32,7 +33,8 @@ HEADERS += \
../library/tbc/lddecodemetadata.h \
../library/tbc/sourcevideo.h \
../library/tbc/vbidecoder.h \
../library/tbc/logging.h
../library/tbc/logging.h \
../library/tbc/dropouts.h

# Add external includes to the include path
INCLUDEPATH += ../library/filter
Expand Down
Loading

0 comments on commit f081df4

Please sign in to comment.