Skip to content

Commit

Permalink
Merge pull request IENT#487 from IENT/feature/fixAVCParsing
Browse files Browse the repository at this point in the history
Fix parsing of AVC. The POC detection was not really correct
  • Loading branch information
ChristianFeldmann authored Sep 20, 2022
2 parents 065ff67 + d15d097 commit a7be0ed
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 32 deletions.
2 changes: 1 addition & 1 deletion YUViewLib/src/filesource/FileSourceAnnexBFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ bool FileSourceAnnexBFile::seek(int64_t pos)
if (!isFileOpened)
return false;

DEBUG_ANNEXBFILE("FileSourceAnnexBFile::seek ot " << pos);
DEBUG_ANNEXBFILE("FileSourceAnnexBFile::seek to " << pos);
// Seek the file and update the buffer
srcFile.seek(pos);
this->fileBufferSize = srcFile.read(this->fileBuffer.data(), BUFFERSIZE);
Expand Down
7 changes: 4 additions & 3 deletions YUViewLib/src/parser/AVC/AUDelimiterDetector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
namespace parser::avc
{

bool AUDelimiterDetector::isStartOfNewAU(std::shared_ptr<NalUnitAVC> nal, int curFramePOC)
bool AUDelimiterDetector::isStartOfNewAU(std::shared_ptr<NalUnitAVC> nal,
std::optional<int> curFramePOC)
{
const auto isSlice = (nal->header.nal_unit_type == NalType::CODED_SLICE_NON_IDR ||
nal->header.nal_unit_type == NalType::CODED_SLICE_IDR);
Expand Down Expand Up @@ -65,10 +66,10 @@ bool AUDelimiterDetector::isStartOfNewAU(std::shared_ptr<NalUnitAVC> nal, int cu
if (fourteenToEigtheen)
isStart = true;

if (isSlice && curFramePOC != this->lastSlicePoc)
if (isSlice && curFramePOC && *curFramePOC != this->lastSlicePoc)
{
isStart = true;
this->lastSlicePoc = curFramePOC;
this->lastSlicePoc = *curFramePOC;
}
}

Expand Down
3 changes: 2 additions & 1 deletion YUViewLib/src/parser/AVC/AUDelimiterDetector.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#pragma once

#include <memory>
#include <optional>

namespace parser::avc
{
Expand All @@ -44,7 +45,7 @@ class AUDelimiterDetector
public:
AUDelimiterDetector() = default;

bool isStartOfNewAU(std::shared_ptr<NalUnitAVC> nal, int curFramePOC);
bool isStartOfNewAU(std::shared_ptr<NalUnitAVC> nal, std::optional<int> curFramePOC);
int lastSlicePoc{-1};
bool primaryCodedPictureInAuEncountered{};
};
Expand Down
57 changes: 34 additions & 23 deletions YUViewLib/src/parser/AVC/AnnexBAVC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,16 @@ using namespace avc;
namespace
{

struct CurrentSliceData
{
int poc{};
bool isRandomAccess{};
};

std::optional<FrameParsingData>
getFrameDataWithUpdatedPosition(std::optional<FrameParsingData> data,
std::optional<pairUint64> nalStartEndPosFile)
std::optional<pairUint64> nalStartEndPosFile,
std::optional<CurrentSliceData> currentSliceData)
{
auto newData = data.value_or(FrameParsingData());
if (nalStartEndPosFile)
Expand All @@ -75,6 +82,11 @@ getFrameDataWithUpdatedPosition(std::optional<FrameParsingData> data,
else
newData.fileStartEndPos->second = nalStartEndPosFile->second;
}
if (currentSliceData)
{
newData.poc = currentSliceData->poc;
newData.isRandomAccess = currentSliceData->isRandomAccess;
}
return newData;
}

Expand Down Expand Up @@ -176,27 +188,27 @@ AnnexBAVC::parseAndAddNALUnit(int nalI

if (nalID == -1 && data.empty())
{
if (this->curFrameData)
if (this->curFrameData && this->curFrameData->poc)
{
// Save the info of the last frame
if (!this->addFrameToList(this->curFrameData->poc,
if (!this->addFrameToList(*this->curFrameData->poc,
this->curFrameData->fileStartEndPos,
this->curFrameData->isRandomAccess))
{
if (parent)
parent->createChildItem("Error - POC " + std::to_string(this->curFrameData->poc) +
parent->createChildItem("Error - POC " + std::to_string(*this->curFrameData->poc) +
"alread in the POC list.");
return parseResult;
}
if (this->curFrameData->fileStartEndPos)
DEBUG_AVC("AnnexBAVC::parseAndAddNALUnit Adding start/end "
<< this->curFrameData->fileStartEndPos->first << "/"
<< this->curFrameData->fileStartEndPos->second << " - POC "
<< this->curFrameData->poc
<< *this->curFrameData->poc
<< (this->curFrameData->isRandomAccess ? " - ra" : ""));
else
DEBUG_AVC("AnnexBAVC::parseAndAddNALUnit Adding start/end NA/NA - POC "
<< this->curFrameData->poc
<< *this->curFrameData->poc
<< (this->curFrameData->isRandomAccess ? " - ra" : ""));
}
// The file ended
Expand All @@ -221,6 +233,8 @@ AnnexBAVC::parseAndAddNALUnit(int nalI
std::string specificDescription;
auto nalAVC = std::make_shared<NalUnitAVC>(nalID, nalStartEndPosFile);

std::optional<CurrentSliceData> currentSliceData;

bool currentSliceIntra = false;
std::string currentSliceType;
try
Expand Down Expand Up @@ -249,8 +263,6 @@ AnnexBAVC::parseAndAddNALUnit(int nalI
newSPS->seqParameterSetData.vuiParameters.nalHrdParameters.CpbSize[0]);
}

this->curFrameData = getFrameDataWithUpdatedPosition(this->curFrameData, nalStartEndPosFile);

DEBUG_AVC("AnnexBAVC::parseAndAddNALUnit Parse SPS ID "
<< newSPS->seqParameterSetData.seq_parameter_set_id);

Expand All @@ -270,8 +282,6 @@ AnnexBAVC::parseAndAddNALUnit(int nalI

specificDescription += " ID " + std::to_string(newPPS->pic_parameter_set_id);

this->curFrameData = getFrameDataWithUpdatedPosition(this->curFrameData, nalStartEndPosFile);

DEBUG_AVC("AnnexBAVC::parseAndAddNALUnit Parse PPS ID " << newPPS->pic_parameter_set_id);

nalAVC->rbsp = newPPS;
Expand Down Expand Up @@ -341,13 +351,9 @@ AnnexBAVC::parseAndAddNALUnit(int nalI

specificDescription += " POC " + std::to_string(newSliceHeader->globalPOC);

this->curFrameData = getFrameDataWithUpdatedPosition(this->curFrameData, nalStartEndPosFile);

if (isFirstSlice)
{
this->curFrameData->poc = newSliceHeader->globalPOC;
this->curFrameData->isRandomAccess = isRandomAccess;

currentSliceData = CurrentSliceData({newSliceHeader->globalPOC, isRandomAccess});
this->currentAUAssociatedSPS = refSPS;
}

Expand Down Expand Up @@ -457,25 +463,27 @@ AnnexBAVC::parseAndAddNALUnit(int nalI
parseResult.success = false;
}

if (this->curFrameData &&
this->auDelimiterDetector.isStartOfNewAU(nalAVC, this->curFrameData->poc))
std::optional<int> curSlicePoc;
if (currentSliceData)
curSlicePoc = currentSliceData->poc;
if (this->curFrameData && this->auDelimiterDetector.isStartOfNewAU(nalAVC, curSlicePoc))
{
// Save the info of the last frame
if (!this->addFrameToList(this->curFrameData->poc,
if (!this->addFrameToList(*this->curFrameData->poc,
this->curFrameData->fileStartEndPos,
this->curFrameData->isRandomAccess))
{
throw std::logic_error("Error - POC " + std::to_string(this->curFrameData->poc) +
throw std::logic_error("Error - POC " + std::to_string(*this->curFrameData->poc) +
" already in the POC list");
}
if (this->curFrameData->fileStartEndPos)
DEBUG_AVC("AnnexBAVC::parseAndAddNALUnit Adding start/end "
<< this->curFrameData->fileStartEndPos->first << "/"
<< this->curFrameData->fileStartEndPos->second << " - POC "
<< this->curFrameData->poc << (this->curFrameData->isRandomAccess ? " - ra" : ""));
<< *this->curFrameData->poc << (this->curFrameData->isRandomAccess ? " - ra" : ""));
else
DEBUG_AVC("AnnexBAVC::parseAndAddNALUnit Adding start/end NA/NA - POC "
<< this->curFrameData->poc << (this->curFrameData->isRandomAccess ? " - ra" : ""));
<< *this->curFrameData->poc << (this->curFrameData->isRandomAccess ? " - ra" : ""));

if (this->sizeCurrentAU > 0)
{
Expand All @@ -494,7 +502,7 @@ AnnexBAVC::parseAndAddNALUnit(int nalI
entry.pts = this->lastFramePOC;
entry.dts = this->counterAU;
entry.duration = 1;
this->lastFramePOC = this->curFrameData->poc;
this->lastFramePOC = *this->curFrameData->poc;
}
entry.bitrate = this->sizeCurrentAU;
entry.keyframe = this->currentAUAllSlicesIntra;
Expand All @@ -508,7 +516,7 @@ AnnexBAVC::parseAndAddNALUnit(int nalI
{
if (this->activeParameterSets.spsMap.size() > 0)
this->hrd.addAU(this->sizeCurrentAU * 8,
this->curFrameData->poc,
*this->curFrameData->poc,
this->activeParameterSets.spsMap[0],
this->lastBufferingPeriodSEI,
this->lastPicTimingSEI,
Expand All @@ -528,6 +536,9 @@ AnnexBAVC::parseAndAddNALUnit(int nalI
this->currentAUPartitionASPS.reset();
this->curFrameData.reset();
}
curFrameData =
getFrameDataWithUpdatedPosition(curFrameData, nalStartEndPosFile, currentSliceData);

if (this->newBufferingPeriodSEI)
this->lastBufferingPeriodSEI = this->newBufferingPeriodSEI;
if (this->newPicTimingSEI)
Expand Down
2 changes: 1 addition & 1 deletion YUViewLib/src/parser/AVC/AnnexBAVC.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ struct FrameParsingData
// and where the NAL of the last slice ends (if known). This is used by getNextFrameNALUnits to
// return all information (NAL units) for a specific frame (AU). This includes SPS/PPS.
std::optional<pairUint64> fileStartEndPos{};
int poc{-1};
std::optional<int> poc{};
bool isRandomAccess{};
};
} // namespace avc
Expand Down
7 changes: 4 additions & 3 deletions YUViewLib/src/parser/AnnexB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,9 @@ bool AnnexB::parseAnnexBFile(std::unique_ptr<FileSourceAnnexBFile> &file, QWidge
this->bitratePlotModel->addBitratePoint(0, *parsingResult.bitrateEntry);
}
}
catch (const std::exception &)
catch (const std::exception &exc)
{
(void)exc;
// Reading a NAL unit failed at some point.
// This is not too bad. Just don't use this NAL unit and continue with the next one.
DEBUG_ANNEXB("AnnexB::parseAndAddNALUnit Exception thrown parsing NAL " << nalID << " - "
Expand Down Expand Up @@ -258,8 +259,8 @@ bool AnnexB::parseAnnexBFile(std::unique_ptr<FileSourceAnnexBFile> &file, QWidge
DEBUG_ANNEXB("AnnexB::parseAndAddNALUnit Error finalizing parsing. This should not happen.");
}

DEBUG_ANNEXB("AnnexB::parseAndAddNALUnit Parsing done. Found " << this->frameList.size()
<< " POCs");
DEBUG_ANNEXB("AnnexB::parseAndAddNALUnit Parsing done. Found "
<< this->frameListCodingOrder.size() << " POCs");

if (packetModel)
emit modelDataUpdated();
Expand Down

0 comments on commit a7be0ed

Please sign in to comment.