Commit 28a9ff14 authored by Karl Sharman's avatar Karl Sharman
Browse files

Annotated Regions SEI message - rebased.

Original version by Palanivel Guruvareddiar, 2019-06-18 13:50:25.
parent d52e938d
......@@ -86,6 +86,9 @@ Bool TAppDecCfg::parseCfg( Int argc, TChar* argv[] )
("TarDecLayerIdSetFile,l", cfg_TargetDecLayerIdSetFile, string(""), "targetDecLayerIdSet file name. The file should include white space separated LayerId values to be decoded. Omitting the option or a value of -1 in the file decodes all layers.")
("RespectDefDispWindow,w", m_respectDefDispWindow, 0, "Only output content inside the default display window\n")
("SEIColourRemappingInfoFilename", m_colourRemapSEIFileName, string(""), "Colour Remapping YUV output file name. If empty, no remapping is applied (ignore SEI message)\n")
#if AR_SEI_MESSAGE
("SEIAnnotatedRegionsInfoFilename", m_annotatedRegionsSEIFileName, string(""), "Annotated regions output file name. If empty, no object information will be saved (ignore SEI message)\n")
#endif
#if O0043_BEST_EFFORT_DECODING
("ForceDecodeBitDepth", m_forceDecodeBitDepth, 0U, "Force the decoder to operate at a particular bit-depth (best effort decoding)")
#endif
......
......@@ -66,6 +66,9 @@ protected:
Int m_decodedPictureHashSEIEnabled; ///< Checksum(3)/CRC(2)/MD5(1)/disable(0) acting on decoded picture hash SEI message
Bool m_decodedNoDisplaySEIEnabled; ///< Enable(true)/disable(false) writing only pictures that get displayed based on the no display SEI message
std::string m_colourRemapSEIFileName; ///< output Colour Remapping file name
#if AR_SEI_MESSAGE
std::string m_annotatedRegionsSEIFileName; ///< annotated regions file name
#endif
std::vector<Int> m_targetDecLayerIdSet; ///< set of LayerIds to be included in the sub-bitstream extraction process.
Int m_respectDefDispWindow; ///< Only output content inside the default display window
#if O0043_BEST_EFFORT_DECODING
......@@ -88,6 +91,9 @@ public:
, m_decodedPictureHashSEIEnabled(0)
, m_decodedNoDisplaySEIEnabled(false)
, m_colourRemapSEIFileName()
#if AR_SEI_MESSAGE
, m_annotatedRegionsSEIFileName()
#endif
, m_targetDecLayerIdSet()
, m_respectDefDispWindow(0)
#if O0043_BEST_EFFORT_DECODING
......
......@@ -58,6 +58,9 @@
TAppDecTop::TAppDecTop()
: m_iPOCLastDisplay(-MAX_INT)
,m_pcSeiColourRemappingInfoPrevious(NULL)
#if AR_SEI_MESSAGE
,m_pcSeiAnnotatedRegions(NULL)
#endif
{
}
......@@ -123,6 +126,19 @@ Void TAppDecTop::decode()
}
}
#if AR_SEI_MESSAGE
// clear contents of annotated-Regions-SEI output file
if (!m_annotatedRegionsSEIFileName.empty())
{
std::ofstream ofile(m_annotatedRegionsSEIFileName.c_str());
if (!ofile.good() || !ofile.is_open())
{
fprintf(stderr, "\nUnable to open file '%s' for writing annotated-Regions-SEI\n", m_annotatedRegionsSEIFileName.c_str());
exit(EXIT_FAILURE);
}
}
#endif
// main decoder loop
Bool openedReconFile = false; // reconstruction file not yet opened. (must be performed after SPS is seen)
Bool loopFiltered = false;
......@@ -284,6 +300,13 @@ Void TAppDecTop::xDestroyDecLib()
delete m_pcSeiColourRemappingInfoPrevious;
m_pcSeiColourRemappingInfoPrevious = NULL;
}
#if AR_SEI_MESSAGE
if (m_pcSeiAnnotatedRegions != NULL)
{
delete m_pcSeiAnnotatedRegions;
m_pcSeiAnnotatedRegions = NULL;
}
#endif
}
Void TAppDecTop::xInitDecLib()
......@@ -307,6 +330,13 @@ Void TAppDecTop::xInitDecLib()
delete m_pcSeiColourRemappingInfoPrevious;
m_pcSeiColourRemappingInfoPrevious = NULL;
}
#if AR_SEI_MESSAGE
if (m_pcSeiAnnotatedRegions != NULL)
{
delete m_pcSeiAnnotatedRegions;
m_pcSeiAnnotatedRegions = NULL;
}
#endif
}
/** \param pcListPic list of pictures to be written to file
......@@ -462,6 +492,13 @@ Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, UInt tId )
NUM_CHROMA_FORMAT, m_bClipOutputVideoToRec709Range );
}
#if AR_SEI_MESSAGE
if (!m_annotatedRegionsSEIFileName.empty())
{
xOutputAnnotatedRegions(pcPic);
}
#endif
if (!m_colourRemapSEIFileName.empty())
{
xOutputColourRemapPic(pcPic);
......@@ -590,6 +627,13 @@ Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic )
xOutputColourRemapPic(pcPic);
}
#if AR_SEI_MESSAGE
if (!m_annotatedRegionsSEIFileName.empty())
{
xOutputAnnotatedRegions(pcPic);
}
#endif
// update POC of display order
m_iPOCLastDisplay = pcPic->getPOC();
......@@ -669,6 +713,151 @@ Void TAppDecTop::xOutputColourRemapPic(TComPic* pcPic)
}
}
#if AR_SEI_MESSAGE
Void TAppDecTop::xOutputAnnotatedRegions(TComPic* pcPic)
{
// Check if any annotated region SEI has arrived
std::map<UInt, SEIAnnotatedRegions::AnnotatedLabel>::iterator labIt;
std::map<UInt, SEIAnnotatedRegions::AnnotatedRegion>::iterator objIt;
SEIMessages annotatedRegionSEIs = getSeisByType(pcPic->getSEIs(), SEI::ANNOTATED_REGIONS);
SEIAnnotatedRegions *seiAnnotatedRegions = ( annotatedRegionSEIs.size() > 0 ) ? (SEIAnnotatedRegions*) *(annotatedRegionSEIs.begin()) : NULL;
if (seiAnnotatedRegions)
{
if (annotatedRegionSEIs.size() > 1)
{
printf ("Warning: Got multiple Annotated Regions SEI messages. Using first.");
}
if (m_pcSeiAnnotatedRegions == NULL)
{
m_pcSeiAnnotatedRegions = new SEIAnnotatedRegions();
m_pcSeiAnnotatedRegions->copyFrom(*seiAnnotatedRegions);
}
else
{
if (seiAnnotatedRegions->m_annotatedRegionsCancelFlag)
{
m_pcSeiAnnotatedRegions->m_annotatedRegions.clear();
m_pcSeiAnnotatedRegions->m_annotatedLabels.clear();
}
else
{
// Label pool updates
if (seiAnnotatedRegions->m_annotatedRegionsObjLabelPresentFlag)
{
int numLabelUpdates = seiAnnotatedRegions->m_annotatedRegionsNumLabelUpdates;
for (UInt i = 0; i < numLabelUpdates; i++)
{
UInt labIdx = seiAnnotatedRegions->m_annotatedLabels[i].labelIdx;
labIt = m_pcSeiAnnotatedRegions->m_annotatedLabels.find(labIdx);
//New label, needs to be appended to the existing pool
if (labIt == m_pcSeiAnnotatedRegions->m_annotatedLabels.end())
{
m_pcSeiAnnotatedRegions->m_annotatedLabels[labIdx] = seiAnnotatedRegions->m_annotatedLabels[i];
}
//Existing label, modifications to be done
else
{
//Modify the existing label
if (!m_pcSeiAnnotatedRegions->m_annotatedLabels.at(labIdx).bLabelCancelFlag)
{
m_pcSeiAnnotatedRegions->m_annotatedLabels.at(labIdx).label = seiAnnotatedRegions->m_annotatedLabels[i].label;
}
//Label is removed from the pool
else
{
m_pcSeiAnnotatedRegions->m_annotatedLabels.erase(labIdx);
}
}
}
}
//Object updates
for (UInt i = 0; i < seiAnnotatedRegions->m_annotatedRegionsNumObjUpdates; i++)
{
UInt objIdx = seiAnnotatedRegions->m_annotatedRegions[i].objIdx;
objIt = m_pcSeiAnnotatedRegions->m_annotatedRegions.find(objIdx);
//New object arrived, needs to be appended to the list
if (objIt == m_pcSeiAnnotatedRegions->m_annotatedRegions.end())
{
m_pcSeiAnnotatedRegions->m_annotatedRegions[objIdx] = seiAnnotatedRegions->m_annotatedRegions[i];
}
//Existing object, modifications to be done
else
{
SEIAnnotatedRegions::AnnotatedRegion &annObjInfo = m_pcSeiAnnotatedRegions->m_annotatedRegions[objIdx];
if (!seiAnnotatedRegions->m_annotatedRegions[i].bObjCancelFlag)
{
if (seiAnnotatedRegions->m_annotatedRegionsObjLabelPresentFlag)
{
if (seiAnnotatedRegions->m_annotatedRegions[i].bObjLabelUpdateFlag)
{
annObjInfo.objLabelIdc = seiAnnotatedRegions->m_annotatedRegions[i].objLabelIdc;
}
}
if (seiAnnotatedRegions->m_annotatedRegions[i].bObjBoundBoxUpdateFlag)
{
annObjInfo.boundingBoxTop = seiAnnotatedRegions->m_annotatedRegions[i].boundingBoxTop;
annObjInfo.boundingBoxLeft = seiAnnotatedRegions->m_annotatedRegions[i].boundingBoxLeft;
annObjInfo.boundingBoxWidth = seiAnnotatedRegions->m_annotatedRegions[i].boundingBoxWidth;
annObjInfo.boundingBoxHeight = seiAnnotatedRegions->m_annotatedRegions[i].boundingBoxHeight;
if (seiAnnotatedRegions->m_annotatedRegionsPartialObjsFlagPresentFlag)
{
annObjInfo.bPartObjFlag = seiAnnotatedRegions->m_annotatedRegions[i].bPartObjFlag;
}
if (seiAnnotatedRegions->m_annotatedRegionsObjDetConfInfoPresentFlag)
{
annObjInfo.objConf = seiAnnotatedRegions->m_annotatedRegions[i].objConf;
}
}
}
//Object no longer needs to be tracked
else
{
m_pcSeiAnnotatedRegions->m_annotatedRegions.erase(objIdx);
}
}
}
}
}
}
UInt numObjs = (UInt)m_pcSeiAnnotatedRegions->m_annotatedRegions.size();
if (numObjs > 0)
{
FILE *fp_persist = fopen(m_annotatedRegionsSEIFileName.c_str(), "ab");
if (fp_persist == NULL)
{
std::cout << "Not able to open file for writing persist SEI messages" << std::endl;
}
else
{
fprintf(fp_persist, "\n");
fprintf(fp_persist, "Number of objects = %d\n", numObjs);
for (auto it = m_pcSeiAnnotatedRegions->m_annotatedRegions.begin(); it != m_pcSeiAnnotatedRegions->m_annotatedRegions.end(); ++it)
{
fprintf(fp_persist, "Object Idx = %d\n", it->first);
fprintf(fp_persist, "Object Top = %d\n", it->second.boundingBoxTop);
fprintf(fp_persist, "Object Left = %d\n", it->second.boundingBoxLeft);
fprintf(fp_persist, "Object Width = %d\n", it->second.boundingBoxWidth);
fprintf(fp_persist, "Object Height = %d\n", it->second.boundingBoxHeight);
if (m_pcSeiAnnotatedRegions->m_annotatedRegionsObjLabelPresentFlag)
{
fprintf(fp_persist, "Object Label = %s\n", m_pcSeiAnnotatedRegions->m_annotatedLabels[it->second.objLabelIdc].label.c_str());
}
if (m_pcSeiAnnotatedRegions->m_annotatedRegionsObjDetConfInfoPresentFlag)
{
fprintf(fp_persist, "Object Conf = %d\n", it->second.objConf);
}
}
fclose(fp_persist);
}
}
}
#endif
// compute lut from SEI
// use at lutPoints points aligned on a power of 2 value
// SEI Lut must be in ascending values of coded Values
......
......@@ -69,6 +69,10 @@ private:
SEIColourRemappingInfo* m_pcSeiColourRemappingInfoPrevious;
#if AR_SEI_MESSAGE
SEIAnnotatedRegions* m_pcSeiAnnotatedRegions; ///< Annotated regions SEI message
#endif
public:
TAppDecTop();
virtual ~TAppDecTop() {}
......@@ -90,6 +94,9 @@ protected:
private:
Void applyColourRemapping(const TComPicYuv& pic, SEIColourRemappingInfo& pCriSEI, const TComSPS &activeSPS);
Void xOutputColourRemapPic(TComPic* pcPic);
#if AR_SEI_MESSAGE
Void xOutputAnnotatedRegions(TComPic* pcPic);
#endif
};
//! \}
......
......@@ -1250,6 +1250,9 @@ Bool TAppEncCfg::parseCfg( Int argc, TChar* argv[] )
#endif
#if RNSEI
("SEIRegionalNestingFileRoot,-rns", m_regionalNestingSEIFileRoot, string(""), "Regional nesting SEI parameters root file name (wo num ext); only the file name base is to be added. Underscore and POC would be automatically addded to . E.g. \"-rns rns\" will search for files rns_0.txt, rns_1.txt, ...")
#endif
#if AR_SEI_MESSAGE
("SEIAnnotatedRegionsFileRoot,-ar", m_arSEIFileRoot, string(""), "Annotated region SEI parameters root file name (wo num ext); only the file name base is to be added. Underscore and POC would be automatically addded to . E.g. \"-ar ar\" will search for files ar_0.txt, ar_1.txt, ...")
#endif
;
......
......@@ -436,6 +436,9 @@ protected:
Bool m_gopBasedTemporalFilterFutureReference; ///< Enable/disable future frame references in the GOP-based Temporal Filter
std::map<Int, Double> m_gopBasedTemporalFilterStrengths; ///< Filter strength per frame for the GOP-based Temporal Filter
#if AR_SEI_MESSAGE
std::string m_arSEIFileRoot;
#endif
// weighted prediction
Bool m_useWeightedPred; ///< Use of weighted prediction in P slices
Bool m_useWeightedBiPred; ///< Use of bi-directional weighted prediction in B slices
......
......@@ -449,6 +449,9 @@ Void TAppEncTop::xInitLibCfg()
m_cTEncTop.setSEIXSDMetricType ( UChar(m_xsdMetricType) );
#if RNSEI
m_cTEncTop.setRegionalNestingSEIFileRoot ( m_regionalNestingSEIFileRoot );
#endif
#if AR_SEI_MESSAGE
m_cTEncTop.setARSEIFileRoot (m_arSEIFileRoot);
#endif
m_cTEncTop.setTileUniformSpacingFlag ( m_tileUniformSpacingFlag );
m_cTEncTop.setNumColumnsMinus1 ( m_numTileColumnsMinus1 );
......
......@@ -323,6 +323,9 @@ const TChar *SEI::getSEIMessageString(SEI::PayloadType payloadType)
#endif
#if MCTS_EXTRACTION
case SEI::MCTS_EXTRACTION_INFO_SET: return "MCTS extraction information";
#endif
#if AR_SEI_MESSAGE
case SEI::ANNOTATED_REGIONS: return "Annotated Region";
#endif
default: return "Unknown";
}
......
......@@ -38,6 +38,7 @@
#include <list>
#include <vector>
#include <cstring>
#include <map>
#include "CommonDef.h"
#include "libmd5/MD5.h"
......@@ -111,6 +112,9 @@ public:
#endif
#if MCTS_EXTRACTION
MCTS_EXTRACTION_INFO_SET = 158,
#endif
#if AR_SEI_MESSAGE
ANNOTATED_REGIONS = 202,
#endif
};
......@@ -845,6 +849,57 @@ public:
};
#endif
#if AR_SEI_MESSAGE
class SEIAnnotatedRegions : public SEI
{
public:
PayloadType payloadType() const { return ANNOTATED_REGIONS; }
SEIAnnotatedRegions() {}
virtual ~SEIAnnotatedRegions() {}
Void copyFrom(const SEIAnnotatedRegions &seiAnnotaedRegions)
{
(*this) = seiAnnotaedRegions;
}
struct AnnotatedRegion
{
Bool bObjCancelFlag;
Bool bObjLabelUpdateFlag;
UInt objIdx;
UInt objLabelIdc; // only valid if !bNewObjFlag && m_annotatedRegionsObjLabelPresentFlag
Bool bObjBoundBoxUpdateFlag; // only valid if !bNewObjFlag. (not required when not valid)
UInt boundingBoxTop; // only valid if bObjBoundBoxUpdateFlag or bNewObjFlag
UInt boundingBoxLeft;
UInt boundingBoxWidth;
UInt boundingBoxHeight;
Bool bPartObjFlag;
UInt objConf; // only valid if m_annotatedRegionsObjDetConfLength
};
struct AnnotatedLabel
{
UInt labelIdx;
Bool bLabelCancelFlag;
std::string label;
};
Bool m_annotatedRegionsSEIEnabled;
Bool m_annotatedRegionsCancelFlag;
Bool m_annotatedRegionsNotOptimizedForViewFlag;
Bool m_annotatedRegionsTrueMotionFlag;
Bool m_annotatedRegionsOccludedObjsFlag;
Bool m_annotatedRegionsPartialObjsFlagPresentFlag;
Bool m_annotatedRegionsObjLabelPresentFlag;
Bool m_annotatedRegionsObjDetConfInfoPresentFlag;
UInt m_annotatedRegionsObjDetConfLength; //Only valid if m_annotatedRegionsObjDetConfInfoPresentFlag is present
Bool m_annotatedRegionsObjLabelLangPresentFlag; //Only valid if m_annotatedRegionsObjLabelPresentFlag is present
std::string m_annotatedRegionsObjLabelLang;
UInt m_annotatedRegionsNumLabelUpdates;
UInt m_annotatedRegionsNumObjUpdates;
std::map<UInt, AnnotatedRegion> m_annotatedRegions;
std::map<UInt, AnnotatedLabel> m_annotatedLabels;
};
#endif
#if CMP_SEI_MESSAGE
class SEICubemapProjection : public SEI
{
......
......@@ -104,6 +104,8 @@
#define RNSEI 1 ///< Support for signalling regional nesting SEI message
#define AR_SEI_MESSAGE 1 ///< Annotated Region SEI message
#define FIXSAORESETAFTERIRAP 1 // Fix the reset mechanism for SAO after an IRAP for the case of IRAP period equal to gop size.
#define ADD_RESET_ENCODER_DECISIONS_AFTER_IRAP 1 // Add support to reseting encoder decisions after IRAP, to enable independent/parallel coding of randomaccess configuration intra-periods.
......
......@@ -378,6 +378,13 @@ Void SEIReader::xReadSEIPayloadData(Int const payloadType, Int const payloadSize
xParseSEIRegionWisePacking((SEIRegionWisePacking&) *sei, payloadSize, pDecodedMessageOutputStream);
break;
#endif
#if AR_SEI_MESSAGE
case SEI::ANNOTATED_REGIONS:
sei = new SEIAnnotatedRegions;
xParseSEIAnnotatedRegions((SEIAnnotatedRegions&)*sei, payloadSize, pDecodedMessageOutputStream);
break;
#endif
#if RNSEI
case SEI::REGIONAL_NESTING:
sei = new SEIRegionalNesting;
......@@ -1628,6 +1635,121 @@ Void SEIReader::xParseSEIOmniViewport(SEIOmniViewport& sei, UInt payloadSize, st
}
#endif
#if AR_SEI_MESSAGE
Void SEIReader::xParseSEIAnnotatedRegions(SEIAnnotatedRegions& sei, UInt payloadSize, std::ostream *pDecodedMessageOutputStream)
{
output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
UInt val;
sei_read_flag(pDecodedMessageOutputStream, val, "annotated_regions_cancel_flag"); sei.m_annotatedRegionsCancelFlag = val;
if (!sei.m_annotatedRegionsCancelFlag)
{
sei_read_flag(pDecodedMessageOutputStream, val, "annotated_regions_not_opt_for_view_flag"); sei.m_annotatedRegionsNotOptimizedForViewFlag = val;
sei_read_flag(pDecodedMessageOutputStream, val, "annotated_regions_true_motion_flag"); sei.m_annotatedRegionsTrueMotionFlag = val;
sei_read_flag(pDecodedMessageOutputStream, val, "annotated_regions_occluded_objects_flag"); sei.m_annotatedRegionsOccludedObjsFlag = val;
sei_read_flag(pDecodedMessageOutputStream, val, "annotated_regions_partial_objects_flag_present_flag"); sei.m_annotatedRegionsPartialObjsFlagPresentFlag = val;
sei_read_flag(pDecodedMessageOutputStream, val, "annotated_regions_object_label_present_flag"); sei.m_annotatedRegionsObjLabelPresentFlag = val;
sei_read_flag(pDecodedMessageOutputStream, val, "annotated_regions_object_conf_info_present_flag"); sei.m_annotatedRegionsObjDetConfInfoPresentFlag = val;
if (sei.m_annotatedRegionsObjDetConfInfoPresentFlag)
{
sei_read_code(pDecodedMessageOutputStream, 4, val, "annotated_regions_object_detection_conf_length_minus_1"); sei.m_annotatedRegionsObjDetConfLength = (val + 1);
}
if (sei.m_annotatedRegionsObjLabelPresentFlag)
{
sei_read_flag(pDecodedMessageOutputStream, val, "annotated_regions_object_label_language_present_flag"); sei.m_annotatedRegionsObjLabelLangPresentFlag = val;
if (sei.m_annotatedRegionsObjLabelLangPresentFlag)
{
// byte alignment
while (m_pcBitstream->getNumBitsRead() % 8 != 0)
{
UInt code;
sei_read_flag(pDecodedMessageOutputStream, code, "ar_zero_bit");
}
do
{
sei_read_code(pDecodedMessageOutputStream, 8, val, "annotated_regions_label_language");
if (val)
{
sei.m_annotatedRegionsObjLabelLang.push_back((char)val);
}
} while (val != '\0');
}
}
UInt numLabelUpdates;
sei_read_uvlc(pDecodedMessageOutputStream, numLabelUpdates, "annotated_regions_num_label_updates"); sei.m_annotatedRegionsNumLabelUpdates = numLabelUpdates;
sei.m_annotatedLabels.clear();
for (Int i = 0; i < numLabelUpdates; i++)
{
SEIAnnotatedRegions::AnnotatedLabel &ar = sei.m_annotatedLabels[i];
sei_read_uvlc(pDecodedMessageOutputStream, val, "annotated_regions_label_idx"); ar.labelIdx = val;
sei_read_flag(pDecodedMessageOutputStream, val, "annotated_regions_label_cancel_flag"); ar.bLabelCancelFlag = val;
if (!ar.bLabelCancelFlag)
{
// byte alignment
while (m_pcBitstream->getNumBitsRead() % 8 != 0)
{
UInt code;
sei_read_flag(pDecodedMessageOutputStream, code, "ar_zero_bit");
}
do
{
sei_read_code(pDecodedMessageOutputStream, 8, val, "annotated_regions_label");
if (val)
{
ar.label.push_back((char)val);
}
} while (val != '\0');
}
}
UInt numObjUpdates;
sei_read_uvlc(pDecodedMessageOutputStream, numObjUpdates, "annotated_regions_num_object_updates"); sei.m_annotatedRegionsNumObjUpdates = numObjUpdates;
sei.m_annotatedRegions.clear();
for (UInt i = 0; i < numObjUpdates; i++)
{
UInt objIdx;
sei_read_uvlc(pDecodedMessageOutputStream, objIdx, "annotated_regions_obj_idx");
SEIAnnotatedRegions::AnnotatedRegion &ar = sei.m_annotatedRegions[i]; ar.objIdx = objIdx;
sei_read_flag(pDecodedMessageOutputStream, val, "annotated_regions_obj_cancel_flag"); ar.bObjCancelFlag = val;
if (!ar.bObjCancelFlag)
{
if (sei.m_annotatedRegionsObjLabelPresentFlag)
{
sei_read_flag(pDecodedMessageOutputStream, val, "annotated_regions_obj_label_update_flag"); ar.bObjLabelUpdateFlag = val;
if (ar.bObjLabelUpdateFlag)
{
sei_read_uvlc(pDecodedMessageOutputStream, val, "annotated_regions_label_idc"); ar.objLabelIdc = val;
}
}
sei_read_flag(pDecodedMessageOutputStream, val, "annotated_regions_bounding_box_update_flag"); ar.bObjBoundBoxUpdateFlag = val;
if (ar.bObjBoundBoxUpdateFlag)
{
// byte alignment
while (m_pcBitstream->getNumBitsRead() % 8 != 0)
{
UInt code;
sei_read_flag(pDecodedMessageOutputStream, code, "ar_zero_bit");
}
sei_read_code(pDecodedMessageOutputStream, 16, val, "annotated_regions_object_top"); ar.boundingBoxTop = val;
sei_read_code(pDecodedMessageOutputStream, 16, val, "annotated_regions_object_left"); ar.boundingBoxLeft = val;
sei_read_code(pDecodedMessageOutputStream, 16, val, "annotated_regions_object_width"); ar.boundingBoxWidth = val;
sei_read_code(pDecodedMessageOutputStream, 16, val, "annotated_regions_object_height"); ar.boundingBoxHeight = val;
if (sei.m_annotatedRegionsPartialObjsFlagPresentFlag)
{
sei_read_flag(pDecodedMessageOutputStream, val, "annotated_regions_partial_obj_flag"); ar.bPartObjFlag = val;
}
if (sei.m_annotatedRegionsObjDetConfInfoPresentFlag)
{
sei_read_code(pDecodedMessageOutputStream, sei.m_annotatedRegionsObjDetConfLength, val, "annotated_regions_object_conf"); ar.objConf = val;
}
}
}
}
}
}
#endif
#if CMP_SEI_MESSAGE
Void SEIReader::xParseSEICubemapProjection(SEICubemapProjection& sei, UInt payloadSize, std::ostream *pDecodedMessageOutputStream)
{
......
......@@ -105,6 +105,9 @@ protected:
#if CMP_SEI_MESSAGE
Void xParseSEICubemapProjection (SEICubemapProjection& sei, UInt payloadSize, std::ostream *pDecodedMessageOutputStream);
#endif
#if AR_SEI_MESSAGE
Void xParseSEIAnnotatedRegions (SEIAnnotatedRegions& sei, UInt payloadSize, std::ostream *pDecodedMessageOutputStream);
#endif
#if RWP_SEI_MESSAGE
Void xParseSEIRegionWisePacking (SEIRegionWisePacking& sei, UInt payloadSize, std::ostream *pDecodedMessageOutputStream);
#endif
......
......@@ -759,6 +759,61 @@ static Void readTokenValueAndValidate(Bool &returnedValue, /// value ret
readTokenValue(returnedValue, failed, is, pToken);
}
#if AR_SEI_MESSAGE
template <typename T>
static void readTokenValueString(std::vector<T> &returnedValue,
Bool & failed,
std::istream &is,
const TChar *pToken)
{
if (failed)
{
return;
}
Int c;
// Ignore any whitespace
while ((c = is.get()) != EOF && isspace(c));
// test for comment mark
while (c == '#')
{
// Ignore to the end of the line
while ((c = is.get()) != EOF && (c != 10 && c != 13));
// Ignore any white space at the start of the next line
while ((c = is.get()) != EOF && isspace(c));
}
// test first character of token
failed = (c != pToken[0]);
// test remaining characters of token
Int pos;
for (pos = 1; !failed && pToken[pos] != 0 && is.get() == pToken[pos]; pos++);
failed |= (pToken[pos] != 0);
// Ignore any whitespace before the ':'
while (!failed && (c = is.get()) != EOF && isspace(c));
failed |= (c != ':');
// Now read the values till end of line