diff --git a/YUViewLib/src/common/Typedef.h b/YUViewLib/src/common/Typedef.h index 23fbf0334..3abac89ed 100644 --- a/YUViewLib/src/common/Typedef.h +++ b/YUViewLib/src/common/Typedef.h @@ -218,6 +218,8 @@ typedef QPair QUIntPair; template using umap_1d = std::map; template using umap_2d = std::map>; template using umap_3d = std::map>; +template using umap_4d = std::map>; +template using umap_5d = std::map>; template using vector = std::vector; template using vector2d = std::vector>; @@ -226,6 +228,8 @@ template using vector4d = std::vector>; template using array = std::array; template using array2d = std::array, N1>; +template +using array3d = std::array, N2>, N1>; template int indexInVec(const std::vector &vec, const T &item) { diff --git a/YUViewLib/src/parser/AVC/ParserAnnexBAVC.cpp b/YUViewLib/src/parser/AVC/ParserAnnexBAVC.cpp index e7f2ed178..b7e9fd392 100644 --- a/YUViewLib/src/parser/AVC/ParserAnnexBAVC.cpp +++ b/YUViewLib/src/parser/AVC/ParserAnnexBAVC.cpp @@ -193,7 +193,8 @@ ParserAnnexBAVC::parseAndAddNALUnit(int // Save the info of the last frame if (!this->addFrameToList(*this->curFrameData->poc, this->curFrameData->fileStartEndPos, - this->curFrameData->isRandomAccess)) + this->curFrameData->isRandomAccess, + 0)) { if (parent) parent->createChildItem("Error - POC " + std::to_string(*this->curFrameData->poc) + @@ -481,7 +482,8 @@ ParserAnnexBAVC::parseAndAddNALUnit(int // Save the info of the last frame if (!this->addFrameToList(*this->curFrameData->poc, this->curFrameData->fileStartEndPos, - this->curFrameData->isRandomAccess)) + this->curFrameData->isRandomAccess, + 0)) { throw std::logic_error("Error - POC " + std::to_string(*this->curFrameData->poc) + " already in the POC list"); diff --git a/YUViewLib/src/parser/HEVC/Extensions/colour_mapping_octants.cpp b/YUViewLib/src/parser/HEVC/Extensions/colour_mapping_octants.cpp new file mode 100644 index 000000000..bd2b6bb9d --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/colour_mapping_octants.cpp @@ -0,0 +1,120 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "colour_mapping_octants.h" + +#include + +namespace parser::hevc +{ + +using namespace reader; + +void colour_mapping_octants::parse(SubByteReaderLogging &reader, + const unsigned cm_octant_depth, + const unsigned cm_y_part_num_log2, + const unsigned CMResLSBits, + const unsigned inpDepth, + const unsigned idxY, + const unsigned idxCb, + const unsigned idxCr, + const unsigned inpLength) +{ + std::string subLevelName = "colour_mapping_octants("; + subLevelName += "inpDepth=" + std::to_string(inpDepth); + subLevelName += ", idxY=" + std::to_string(idxY); + subLevelName += ", idxCb=" + std::to_string(idxCb); + subLevelName += ", idxCr=" + std::to_string(idxCr); + subLevelName += ", inpLength=" + std::to_string(inpLength); + subLevelName += ")"; + + SubByteReaderLoggingSubLevel subLevel(reader, subLevelName); + + // F.7.4.3.3.5 (F-43) + const auto PartNumY = 1u << cm_y_part_num_log2; + + if (inpDepth < cm_octant_depth) + this->split_octant_flag = reader.readFlag("split_octant_flag"); + if (this->split_octant_flag) + { + for (int k = 0; k < 2; k++) + { + for (int m = 0; m < 2; m++) + { + for (int n = 0; n < 2; n++) + { + this->colourMappingOctants = std::make_unique>(); + (*this->colourMappingOctants)[k][m][n].parse(reader, + cm_octant_depth, + cm_y_part_num_log2, + CMResLSBits, + inpDepth + 1, + idxY + PartNumY * k * inpLength / 2, + idxCb + m * inpLength / 2, + idxCr + n * inpLength / 2, + inpLength / 2); + } + } + } + } + else + { + for (unsigned i = 0; i < PartNumY; i++) + { + const auto idxShiftY = idxY + (i << (cm_octant_depth - inpDepth)); + for (unsigned j = 0; j < 4; j++) + { + this->coded_res_flag[idxShiftY][idxCb][idxCr][j] = + reader.readFlag(formatArray("coded_res_flag", idxShiftY, idxCb, idxCr, j)); + if (this->coded_res_flag[idxShiftY][idxCb][idxCr][j]) + { + for (unsigned c = 0; c < 3; c++) + { + this->res_coeff_q[idxShiftY][idxCb][idxCr][j][c] = + reader.readUEV(formatArray("res_coeff_q", idxShiftY, idxCb, idxCr, j, c)); + if (CMResLSBits == 0) + this->res_coeff_r[idxShiftY][idxCb][idxCr][j][c] = 0; + else + this->res_coeff_r[idxShiftY][idxCb][idxCr][j][c] = reader.readBits( + formatArray("res_coeff_r", idxShiftY, idxCb, idxCr, j, c), CMResLSBits); + if (this->res_coeff_q[idxShiftY][idxCb][idxCr][j][c] || + this->res_coeff_r[idxShiftY][idxCb][idxCr][j][c]) + this->res_coeff_s[idxShiftY][idxCb][idxCr][j][c] = + reader.readFlag(formatArray("res_coeff_s", idxShiftY, idxCb, idxCr, j, c)); + } + } + } + } + } +} + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/colour_mapping_octants.h b/YUViewLib/src/parser/HEVC/Extensions/colour_mapping_octants.h new file mode 100644 index 000000000..215a275f7 --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/colour_mapping_octants.h @@ -0,0 +1,66 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "parser/common/SubByteReaderLogging.h" + +namespace parser::hevc +{ + +// F.7.3.2.3.6 Colour mapping octants syntax +class colour_mapping_octants +{ +public: + colour_mapping_octants() {} + + void parse(reader::SubByteReaderLogging &reader, + const unsigned cm_octant_depth, + const unsigned cm_y_part_num_log2, + const unsigned CMResLSBits, + const unsigned inpDepth, + const unsigned idxY, + const unsigned idxCb, + const unsigned idxCr, + const unsigned inpLength); + + bool split_octant_flag{}; + + std::unique_ptr> colourMappingOctants; + + umap_4d coded_res_flag; + umap_5d res_coeff_q; + umap_5d res_coeff_r; + umap_5d res_coeff_s; +}; + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/colour_mapping_table.cpp b/YUViewLib/src/parser/HEVC/Extensions/colour_mapping_table.cpp new file mode 100644 index 000000000..559042ae3 --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/colour_mapping_table.cpp @@ -0,0 +1,81 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "colour_mapping_table.h" + +#include + +namespace parser::hevc +{ + +using namespace reader; + +void colour_mapping_table::parse(SubByteReaderLogging &reader) +{ + SubByteReaderLoggingSubLevel subLevel(reader, "colour_mapping_table()"); + + this->num_cm_ref_layers_minus1 = reader.readUEV("num_cm_ref_layers_minus1"); + for (unsigned i = 0; i <= this->num_cm_ref_layers_minus1; i++) + this->cm_ref_layer_id.push_back(reader.readBits(formatArray("cm_ref_layer_id", i), 6)); + this->cm_octant_depth = reader.readBits("cm_octant_depth", 2); + this->cm_y_part_num_log2 = reader.readBits("cm_y_part_num_log2", 2); + this->luma_bit_depth_cm_input_minus8 = reader.readUEV("luma_bit_depth_cm_input_minus8"); + this->chroma_bit_depth_cm_input_minus8 = reader.readUEV("chroma_bit_depth_cm_input_minus8"); + this->luma_bit_depth_cm_output_minus8 = reader.readUEV("luma_bit_depth_cm_output_minus8"); + this->chroma_bit_depth_cm_output_minus8 = reader.readUEV("chroma_bit_depth_cm_output_minus8"); + this->cm_res_quant_bits = reader.readBits("cm_res_quant_bits", 2); + this->cm_delta_flc_bits_minus1 = reader.readBits("cm_delta_flc_bits_minus1", 2); + if (this->cm_octant_depth == 1) + { + this->cm_adapt_threshold_u_delta = reader.readSEV("cm_adapt_threshold_u_delta"); + this->cm_adapt_threshold_v_delta = reader.readSEV("cm_adapt_threshold_v_delta"); + } + + const auto BitDepthCmInputY = 8 + this->luma_bit_depth_cm_input_minus8; + const auto BitDepthCmOutputY = 8 + luma_bit_depth_cm_output_minus8; + const auto CMResLSBits = + std::max(0u, + (10 + BitDepthCmInputY - BitDepthCmOutputY - this->cm_res_quant_bits - + (this->cm_delta_flc_bits_minus1 + 1))); + + this->colourMappingOctants.parse(reader, + this->cm_octant_depth, + cm_y_part_num_log2, + CMResLSBits, + 0, + 0, + 0, + 0, + 1 << this->cm_octant_depth); +} + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/colour_mapping_table.h b/YUViewLib/src/parser/HEVC/Extensions/colour_mapping_table.h new file mode 100644 index 000000000..1c67eb70a --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/colour_mapping_table.h @@ -0,0 +1,64 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "colour_mapping_octants.h" +#include "parser/common/SubByteReaderLogging.h" + +namespace parser::hevc +{ + +// F.7.3.2.3.5 General colour mapping table syntax +class colour_mapping_table +{ +public: + colour_mapping_table() {} + + void parse(reader::SubByteReaderLogging &reader); + + unsigned num_cm_ref_layers_minus1{}; + vector cm_ref_layer_id; + unsigned cm_octant_depth{}; + unsigned cm_y_part_num_log2{}; + unsigned luma_bit_depth_cm_input_minus8{}; + unsigned chroma_bit_depth_cm_input_minus8{}; + unsigned luma_bit_depth_cm_output_minus8{}; + unsigned chroma_bit_depth_cm_output_minus8{}; + unsigned cm_res_quant_bits{}; + unsigned cm_delta_flc_bits_minus1{}; + int cm_adapt_threshold_u_delta{}; + int cm_adapt_threshold_v_delta{}; + colour_mapping_octants colourMappingOctants{}; +}; + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/delta_dlt.cpp b/YUViewLib/src/parser/HEVC/Extensions/delta_dlt.cpp new file mode 100644 index 000000000..f4cc1efa1 --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/delta_dlt.cpp @@ -0,0 +1,72 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "delta_dlt.h" + +#include + +#include + +namespace parser::hevc +{ + +using namespace reader; + +void delta_dlt::parse(SubByteReaderLogging &reader, + const unsigned pps_bit_depth_for_depth_layers_minus8) +{ + SubByteReaderLoggingSubLevel subLevel(reader, "delta_dlt()"); + + const auto numBits = pps_bit_depth_for_depth_layers_minus8 + 8; + this->num_val_delta_dlt = reader.readBits("num_val_delta_dlt", numBits); + if (this->num_val_delta_dlt > 0) + { + if (num_val_delta_dlt > 1) + this->max_diff = reader.readBits("max_diff", numBits); + if (this->num_val_delta_dlt > 2 && this->max_diff > 0) + { + const auto numBitsDiff = std::ceil(std::log2(this->max_diff + 1)); + this->min_diff_minus1 = reader.readBits("min_diff_minus1", numBitsDiff); + } + this->delta_dlt_val0 = reader.readBits("delta_dlt_val0", numBits); + if (this->max_diff > (this->min_diff_minus1 + 1)) + { + const auto minDiff = (this->min_diff_minus1 + 1); + const auto numBitsDiff = std::ceil(std::log2(this->max_diff - minDiff + 1)); + for (unsigned k = 1; k < num_val_delta_dlt; k++) + this->delta_val_diff_minus_min.push_back( + reader.readBits(formatArray("delta_val_diff_minus_min", k), numBitsDiff)); + } + } +} + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/delta_dlt.h b/YUViewLib/src/parser/HEVC/Extensions/delta_dlt.h new file mode 100644 index 000000000..fbadfc124 --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/delta_dlt.h @@ -0,0 +1,56 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "parser/common/SubByteReaderLogging.h" + +namespace parser::hevc +{ + +// I.7.3.2.3.8 Delta depth look-up table syntax +class delta_dlt +{ +public: + delta_dlt() {} + + void parse(reader::SubByteReaderLogging &reader, + const unsigned pps_bit_depth_for_depth_layers_minus8); + + unsigned num_val_delta_dlt{}; + unsigned max_diff{}; + unsigned min_diff_minus1{}; + unsigned delta_dlt_val0{}; + vector delta_val_diff_minus_min; +}; + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/dpb_size.cpp b/YUViewLib/src/parser/HEVC/Extensions/dpb_size.cpp new file mode 100644 index 000000000..d524ecf54 --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/dpb_size.cpp @@ -0,0 +1,81 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "dpb_size.h" + +#include + +namespace parser::hevc +{ + +using namespace reader; + +void dpb_size::parse(SubByteReaderLogging & reader, + const unsigned NumOutputLayerSets, + const umap_1d &OlsIdxToLsIdx, + const vector & MaxSubLayersInLayerSetMinus1, + const umap_1d &NumLayersInIdList, + const umap_2d NecessaryLayerFlag, + const bool vps_base_layer_internal_flag, + const umap_2d &LayerSetLayerIdList) +{ + SubByteReaderLoggingSubLevel subLevel(reader, "dpb_size()"); + + for (unsigned i = 1; i < NumOutputLayerSets; i++) + { + const auto currLsIdx = OlsIdxToLsIdx.at(i); + this->sub_layer_flag_info_present_flag.push_back( + reader.readFlag(formatArray("sub_layer_flag_info_present_flag", i))); + for (unsigned j = 0; j <= MaxSubLayersInLayerSetMinus1.at(currLsIdx); j++) + { + if (j > 0 && this->sub_layer_flag_info_present_flag[i]) + this->sub_layer_dpb_info_present_flag[i][j] = + reader.readFlag(formatArray("sub_layer_dpb_info_present_flag", i, j)); + if (j == 0) + this->sub_layer_dpb_info_present_flag[i][j] = true; + if (this->sub_layer_dpb_info_present_flag[i][j]) + { + for (unsigned k = 0; k < NumLayersInIdList.at(currLsIdx); k++) + if (NecessaryLayerFlag.at(i).at(k) && + (vps_base_layer_internal_flag || (LayerSetLayerIdList.at(currLsIdx).at(k) != 0))) + this->max_vps_dec_pic_buffering_minus1[i][k][j] = + reader.readUEV(formatArray("max_vps_dec_pic_buffering_minus1", i, k, j)); + this->max_vps_num_reorder_pics[i][j] = + reader.readUEV(formatArray("max_vps_num_reorder_pics", i, j)); + this->max_vps_latency_increase_plus1[i][j] = + reader.readUEV(formatArray("max_vps_latency_increase_plus1", i, j)); + } + } + } +} + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/dpb_size.h b/YUViewLib/src/parser/HEVC/Extensions/dpb_size.h new file mode 100644 index 000000000..0a32aa6ae --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/dpb_size.h @@ -0,0 +1,62 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "parser/common/SubByteReaderLogging.h" + +namespace parser::hevc +{ + +// F.7.3.2.1.3 DPB size syntax +class dpb_size +{ +public: + dpb_size() {} + + void parse(reader::SubByteReaderLogging &reader, + const unsigned NumOutputLayerSets, + const umap_1d & OlsIdxToLsIdx, + const vector & MaxSubLayersInLayerSetMinus1, + const umap_1d & NumLayersInIdList, + const umap_2d NecessaryLayerFlag, + const bool vps_base_layer_internal_flag, + const umap_2d & LayerSetLayerIdList); + + vector sub_layer_flag_info_present_flag; + umap_2d sub_layer_dpb_info_present_flag; + umap_3d max_vps_dec_pic_buffering_minus1; + umap_2d max_vps_num_reorder_pics; + umap_2d max_vps_latency_increase_plus1; +}; + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/pps_3d_extension.cpp b/YUViewLib/src/parser/HEVC/Extensions/pps_3d_extension.cpp new file mode 100644 index 000000000..62e51399b --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/pps_3d_extension.cpp @@ -0,0 +1,80 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "pps_3d_extension.h" + +#include + +namespace parser::hevc +{ + +using namespace reader; + +void pps_3d_extension::parse(SubByteReaderLogging &reader) +{ + SubByteReaderLoggingSubLevel subLevel(reader, "pps_3d_extension()"); + + this->dlts_present_flag = reader.readFlag("dlts_present_flag"); + if (this->dlts_present_flag) + { + this->pps_depth_layers_minus1 = reader.readBits("pps_depth_layers_minus1", 6); + this->pps_bit_depth_for_depth_layers_minus8 = + reader.readBits("pps_bit_depth_for_depth_layers_minus8", 4); + + const auto depthMaxValue = (1u << (pps_bit_depth_for_depth_layers_minus8 + 8)) - 1; + + for (unsigned i = 0; i <= this->pps_depth_layers_minus1; i++) + { + this->dlt_flag.push_back(reader.readFlag(formatArray("dlt_flag", i))); + if (this->dlt_flag.at(i)) + { + this->dlt_pred_flag.push_back(reader.readFlag(formatArray("dlt_pred_flag", i))); + if (!this->dlt_pred_flag.at(i)) + this->dlt_val_flags_present_flag.push_back( + reader.readFlag(formatArray("dlt_val_flags_present_flag", i))); + else + this->dlt_val_flags_present_flag.push_back(false); + + if (this->dlt_val_flags_present_flag.at(i)) + { + dlt_value_flag.push_back({}); + for (unsigned j = 0; j <= depthMaxValue; j++) + dlt_value_flag[i].push_back(reader.readFlag(formatArray("dlt_value_flag", i, j))); + } + else + this->deltaDlt.parse(reader, this->pps_bit_depth_for_depth_layers_minus8); + } + } + } +} + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/pps_3d_extension.h b/YUViewLib/src/parser/HEVC/Extensions/pps_3d_extension.h new file mode 100644 index 000000000..fa962bf80 --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/pps_3d_extension.h @@ -0,0 +1,60 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "delta_dlt.h" +#include "parser/common/SubByteReaderLogging.h" + +namespace parser::hevc +{ + +// I.7.3.2.3.7 Picture parameter set 3D extension syntax +class pps_3d_extension +{ +public: + pps_3d_extension() {} + + void parse(reader::SubByteReaderLogging &reader); + + bool dlts_present_flag{}; + unsigned pps_depth_layers_minus1{}; + unsigned pps_bit_depth_for_depth_layers_minus8{}; + vector dlt_flag{}; + vector dlt_pred_flag{}; + vector dlt_val_flags_present_flag{}; + vector2d dlt_value_flag{}; + + delta_dlt deltaDlt; +}; + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/pps_multilayer_extension.cpp b/YUViewLib/src/parser/HEVC/Extensions/pps_multilayer_extension.cpp new file mode 100644 index 000000000..f9d582beb --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/pps_multilayer_extension.cpp @@ -0,0 +1,102 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "pps_multilayer_extension.h" + +#include + +namespace parser::hevc +{ + +using namespace reader; + +void pps_multilayer_extension::parse(SubByteReaderLogging &reader) +{ + SubByteReaderLoggingSubLevel subLevel(reader, "pps_multilayer_extension()"); + + this->poc_reset_info_present_flag = reader.readFlag("poc_reset_info_present_flag"); + this->pps_infer_scaling_list_flag = reader.readFlag("pps_infer_scaling_list_flag"); + if (this->pps_infer_scaling_list_flag) + this->pps_scaling_list_ref_layer_id = reader.readBits("pps_scaling_list_ref_layer_id", 6); + this->num_ref_loc_offsets = reader.readUEV("num_ref_loc_offsets"); + for (unsigned i = 0; i < this->num_ref_loc_offsets; i++) + { + this->ref_loc_offset_layer_id.push_back(reader.readBits("ref_loc_offset_layer_id", 6)); + const auto index = this->ref_loc_offset_layer_id.at(i); + + this->scaled_ref_layer_offset_present_flag.push_back( + reader.readFlag("scaled_ref_layer_offset_present_flag")); + if (this->scaled_ref_layer_offset_present_flag.at(i)) + { + this->scaled_ref_layer_left_offset[index] = + reader.readSEV(formatArray("scaled_ref_layer_left_offset", index)); + this->scaled_ref_layer_top_offset[index] = + reader.readSEV(formatArray("scaled_ref_layer_top_offset", index)); + this->scaled_ref_layer_right_offset[index] = + reader.readSEV(formatArray("scaled_ref_layer_right_offset", index)); + this->scaled_ref_layer_bottom_offset[index] = + reader.readSEV(formatArray("scaled_ref_layer_bottom_offset", index)); + } + + this->ref_region_offset_present_flag.push_back( + reader.readFlag("ref_region_offset_present_flag")); + if (this->ref_region_offset_present_flag.at(i)) + { + this->ref_region_left_offset[index] = + reader.readSEV(formatArray("ref_region_left_offset", index)); + this->ref_region_top_offset[index] = + reader.readSEV(formatArray("ref_region_top_offset", index)); + this->ref_region_right_offset[index] = + reader.readSEV(formatArray("ref_region_right_offset", index)); + this->ref_region_bottom_offset[index] = + reader.readSEV(formatArray("ref_region_bottom_offset", index)); + } + + this->resample_phase_set_present_flag.push_back( + reader.readFlag("resample_phase_set_present_flag")); + if (this->resample_phase_set_present_flag.at(i)) + { + this->phase_hor_luma[index] = reader.readUEV(formatArray("phase_hor_luma", index)); + this->phase_ver_luma[index] = reader.readUEV(formatArray("phase_ver_luma", index)); + this->phase_hor_chroma_plus8[index] = + reader.readUEV(formatArray("phase_hor_chroma_plus8", index)); + this->phase_ver_chroma_plus8[index] = + reader.readUEV(formatArray("phase_ver_chroma_plus8", index)); + } + } + + this->colour_mapping_enabled_flag = reader.readFlag("colour_mapping_enabled_flag"); + if (this->colour_mapping_enabled_flag) + this->colourMappingTable.parse(reader); +} + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/pps_multilayer_extension.h b/YUViewLib/src/parser/HEVC/Extensions/pps_multilayer_extension.h new file mode 100644 index 000000000..87143e683 --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/pps_multilayer_extension.h @@ -0,0 +1,78 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "colour_mapping_table.h" +#include "parser/common/SubByteReaderLogging.h" + + +namespace parser::hevc +{ + +// F.7.3.2.3.4 Picture parameter set multilayer extension syntax +class pps_multilayer_extension +{ +public: + pps_multilayer_extension() {} + + void parse(reader::SubByteReaderLogging &reader); + + bool poc_reset_info_present_flag{}; + bool pps_infer_scaling_list_flag{}; + unsigned pps_scaling_list_ref_layer_id{}; + unsigned num_ref_loc_offsets{}; + vector ref_loc_offset_layer_id; + + vector scaled_ref_layer_offset_present_flag; + umap_1d scaled_ref_layer_left_offset; + umap_1d scaled_ref_layer_top_offset; + umap_1d scaled_ref_layer_right_offset; + umap_1d scaled_ref_layer_bottom_offset; + + vector ref_region_offset_present_flag; + umap_1d ref_region_left_offset; + umap_1d ref_region_top_offset; + umap_1d ref_region_right_offset; + umap_1d ref_region_bottom_offset; + + vector resample_phase_set_present_flag; + umap_1d phase_hor_luma; + umap_1d phase_ver_luma; + umap_1d phase_hor_chroma_plus8; + umap_1d phase_ver_chroma_plus8; + + bool colour_mapping_enabled_flag{}; + colour_mapping_table colourMappingTable; +}; + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/pps_range_extension.cpp b/YUViewLib/src/parser/HEVC/Extensions/pps_range_extension.cpp similarity index 100% rename from YUViewLib/src/parser/HEVC/pps_range_extension.cpp rename to YUViewLib/src/parser/HEVC/Extensions/pps_range_extension.cpp diff --git a/YUViewLib/src/parser/HEVC/pps_range_extension.h b/YUViewLib/src/parser/HEVC/Extensions/pps_range_extension.h similarity index 100% rename from YUViewLib/src/parser/HEVC/pps_range_extension.h rename to YUViewLib/src/parser/HEVC/Extensions/pps_range_extension.h diff --git a/YUViewLib/src/parser/HEVC/Extensions/pps_scc_extension.cpp b/YUViewLib/src/parser/HEVC/Extensions/pps_scc_extension.cpp new file mode 100644 index 000000000..f9c7562aa --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/pps_scc_extension.cpp @@ -0,0 +1,85 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "pps_scc_extension.h" + +#include + +namespace parser::hevc +{ + +using namespace reader; + +void pps_scc_extension::parse(SubByteReaderLogging &reader) +{ + SubByteReaderLoggingSubLevel subLevel(reader, "pps_scc_extension()"); + + this->pps_curr_pic_ref_enabled_flag = reader.readFlag("pps_curr_pic_ref_enabled_flag"); + this->residual_adaptive_colour_transform_enabled_flag = + reader.readFlag("residual_adaptive_colour_transform_enabled_flag"); + if (this->residual_adaptive_colour_transform_enabled_flag) + { + this->pps_slice_act_qp_offsets_present_flag = + reader.readFlag("pps_slice_act_qp_offsets_present_flag"); + this->pps_act_y_qp_offset_plus5 = reader.readSEV("pps_act_y_qp_offset_plus5"); + this->pps_act_cb_qp_offset_plus5 = reader.readSEV("pps_act_cb_qp_offset_plus5"); + this->pps_act_cr_qp_offset_plus3 = reader.readSEV("pps_act_cr_qp_offset_plus3"); + } + this->pps_palette_predictor_initializers_present_flag = + reader.readFlag("pps_palette_predictor_initializers_present_flag"); + if (this->pps_palette_predictor_initializers_present_flag) + { + this->pps_num_palette_predictor_initializers = + reader.readUEV("pps_num_palette_predictor_initializers"); + if (pps_num_palette_predictor_initializers > 0) + { + this->monochrome_palette_flag = reader.readFlag("monochrome_palette_flag"); + this->luma_bit_depth_entry_minus8 = reader.readUEV("luma_bit_depth_entry_minus8"); + if (!this->monochrome_palette_flag) + this->chroma_bit_depth_entry_minus8 = reader.readUEV("chroma_bit_depth_entry_minus8"); + const auto numComps = this->monochrome_palette_flag ? 1u : 3u; + for (unsigned comp = 0; comp < numComps; comp++) + { + this->pps_palette_predictor_initializer.push_back({}); + const auto numBits = (comp == 0) ? this->luma_bit_depth_entry_minus8 + 8 + : this->chroma_bit_depth_entry_minus8 + 8; + for (unsigned i = 0; i < this->pps_num_palette_predictor_initializers; i++) + { + pps_palette_predictor_initializer[comp].push_back( + reader.readBits(formatArray("pps_palette_predictor_initializer", comp, i), numBits)); + } + } + } + } +} + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/pps_scc_extension.h b/YUViewLib/src/parser/HEVC/Extensions/pps_scc_extension.h new file mode 100644 index 000000000..b216d99be --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/pps_scc_extension.h @@ -0,0 +1,62 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "parser/common/SubByteReaderLogging.h" + +namespace parser::hevc +{ + +// 7.3.2.3.3 Picture parameter set screen content coding extension syntax +class pps_scc_extension +{ +public: + pps_scc_extension() {} + + void parse(reader::SubByteReaderLogging &reader); + + bool pps_curr_pic_ref_enabled_flag{}; + bool residual_adaptive_colour_transform_enabled_flag{}; + bool pps_slice_act_qp_offsets_present_flag{}; + int pps_act_y_qp_offset_plus5{}; + int pps_act_cb_qp_offset_plus5{}; + int pps_act_cr_qp_offset_plus3{}; + bool pps_palette_predictor_initializers_present_flag{}; + unsigned pps_num_palette_predictor_initializers{}; + bool monochrome_palette_flag{}; + unsigned luma_bit_depth_entry_minus8{}; + unsigned chroma_bit_depth_entry_minus8{}; + vector2d pps_palette_predictor_initializer; +}; + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/rep_format.cpp b/YUViewLib/src/parser/HEVC/Extensions/rep_format.cpp new file mode 100644 index 000000000..004f62e4d --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/rep_format.cpp @@ -0,0 +1,66 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "rep_format.h" + +namespace parser::hevc +{ + +using namespace reader; + +void rep_format::parse(SubByteReaderLogging &reader) +{ + SubByteReaderLoggingSubLevel subLevel(reader, "rep_format()"); + + this->pic_width_vps_in_luma_samples = reader.readBits("pic_width_vps_in_luma_samples", 16); + this->pic_height_vps_in_luma_samples = reader.readBits("pic_height_vps_in_luma_samples", 16); + this->chroma_and_bit_depth_vps_present_flag = + reader.readFlag("chroma_and_bit_depth_vps_present_flag"); + if (this->chroma_and_bit_depth_vps_present_flag) + { + chroma_format_vps_idc = reader.readBits("chroma_format_vps_idc", 2); + if (this->chroma_format_vps_idc == 3) + this->separate_colour_plane_vps_flag = reader.readFlag("separate_colour_plane_vps_flag"); + this->bit_depth_vps_luma_minus8 = reader.readBits("bit_depth_vps_luma_minus8", 4); + this->bit_depth_vps_chroma_minus8 = reader.readBits("bit_depth_vps_chroma_minus8", 4); + } + this->conformance_window_vps_flag = reader.readFlag("conformance_window_vps_flag"); + if (this->conformance_window_vps_flag) + { + conf_win_vps_left_offset = reader.readUEV("conf_win_vps_left_offset"); + conf_win_vps_right_offset = reader.readUEV("conf_win_vps_right_offset"); + conf_win_vps_top_offset = reader.readUEV("conf_win_vps_top_offset"); + conf_win_vps_bottom_offset = reader.readUEV("conf_win_vps_bottom_offset"); + } +} + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/rep_format.h b/YUViewLib/src/parser/HEVC/Extensions/rep_format.h new file mode 100644 index 000000000..508966b6f --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/rep_format.h @@ -0,0 +1,62 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "parser/common/SubByteReaderLogging.h" + +namespace parser::hevc +{ + +// F.7.3.2.1.2 Representation format syntax +class rep_format +{ +public: + rep_format() {} + + void parse(reader::SubByteReaderLogging &reader); + + unsigned pic_width_vps_in_luma_samples{}; + unsigned pic_height_vps_in_luma_samples{}; + bool chroma_and_bit_depth_vps_present_flag{}; + unsigned chroma_format_vps_idc{}; + bool separate_colour_plane_vps_flag{}; + unsigned bit_depth_vps_luma_minus8{}; + unsigned bit_depth_vps_chroma_minus8{}; + bool conformance_window_vps_flag{}; + unsigned conf_win_vps_left_offset{}; + unsigned conf_win_vps_right_offset{}; + unsigned conf_win_vps_top_offset{}; + unsigned conf_win_vps_bottom_offset{}; +}; + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/sps_3d_extension.cpp b/YUViewLib/src/parser/HEVC/Extensions/sps_3d_extension.cpp new file mode 100644 index 000000000..376c33268 --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/sps_3d_extension.cpp @@ -0,0 +1,78 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "sps_3d_extension.h" + +#include + +namespace parser::hevc +{ + +using namespace reader; + +void sps_3d_extension::parse(SubByteReaderLogging &reader) +{ + SubByteReaderLoggingSubLevel subLevel(reader, "sps_3d_extension()"); + + for (int d = 0; d <= 1; d++) + { + this->iv_di_mc_enabled_flag[d] = reader.readFlag(formatArray("iv_di_mc_enabled_flag", d)); + this->iv_mv_scal_enabled_flag[d] = reader.readFlag(formatArray("iv_mv_scal_enabled_flag", d)); + if (d == 0) + { + this->log2_ivmc_sub_pb_size_minus3[d] = + reader.readUEV(formatArray("log2_ivmc_sub_pb_size_minus3", d)); + this->iv_res_pred_enabled_flag[d] = + reader.readFlag(formatArray("iv_res_pred_enabled_flag", d)); + this->depth_ref_enabled_flag[d] = reader.readFlag(formatArray("depth_ref_enabled_flag", d)); + this->vsp_mc_enabled_flag[d] = reader.readFlag(formatArray("vsp_mc_enabled_flag", d)); + this->dbbp_enabled_flag[d] = reader.readFlag(formatArray("dbbp_enabled_flag", d)); + } + else + { + this->tex_mc_enabled_flag[d] = reader.readFlag(formatArray("tex_mc_enabled_flag", d)); + this->log2_texmc_sub_pb_size_minus3[d] = + reader.readUEV(formatArray("log2_texmc_sub_pb_size_minus3", d)); + this->intra_contour_enabled_flag[d] = + reader.readFlag(formatArray("intra_contour_enabled_flag", d)); + this->intra_dc_only_wedge_enabled_flag[d] = + reader.readFlag(formatArray("intra_dc_only_wedge_enabled_flag", d)); + this->cqt_cu_part_pred_enabled_flag[d] = + reader.readFlag(formatArray("cqt_cu_part_pred_enabled_flag", d)); + this->inter_dc_only_enabled_flag[d] = + reader.readFlag(formatArray("inter_dc_only_enabled_flag", d)); + this->skip_intra_enabled_flag[d] = reader.readFlag(formatArray("skip_intra_enabled_flag", d)); + } + } +} + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/sps_3d_extension.h b/YUViewLib/src/parser/HEVC/Extensions/sps_3d_extension.h new file mode 100644 index 000000000..9ca49bba9 --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/sps_3d_extension.h @@ -0,0 +1,65 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "parser/common/SubByteReaderLogging.h" + +namespace parser::hevc +{ + +// I.7.3.2.2.5 Sequence parameter set 3D extension syntax +class sps_3d_extension +{ +public: + sps_3d_extension() {} + + void parse(reader::SubByteReaderLogging &reader); + + bool iv_di_mc_enabled_flag[2]{}; + bool iv_mv_scal_enabled_flag[2]{}; + unsigned log2_ivmc_sub_pb_size_minus3[2]{}; + bool iv_res_pred_enabled_flag[2]{}; + bool depth_ref_enabled_flag[2]{}; + bool vsp_mc_enabled_flag[2]{}; + bool dbbp_enabled_flag[2]{}; + + bool tex_mc_enabled_flag[2]{}; + unsigned log2_texmc_sub_pb_size_minus3[2]{}; + bool intra_contour_enabled_flag[2]{}; + bool intra_dc_only_wedge_enabled_flag[2]{}; + bool cqt_cu_part_pred_enabled_flag[2]{}; + bool inter_dc_only_enabled_flag[2]{}; + bool skip_intra_enabled_flag[2]{}; +}; + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/sps_multilayer_extension.cpp b/YUViewLib/src/parser/HEVC/Extensions/sps_multilayer_extension.cpp new file mode 100644 index 000000000..f7269c08b --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/sps_multilayer_extension.cpp @@ -0,0 +1,47 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "sps_multilayer_extension.h" + +namespace parser::hevc +{ + +using namespace reader; + +void sps_multilayer_extension::parse(SubByteReaderLogging &reader) +{ + SubByteReaderLoggingSubLevel subLevel(reader, "sps_multilayer_extension()"); + + this->inter_view_mv_vert_constraint_flag = reader.readFlag("inter_view_mv_vert_constraint_flag"); +} + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/sps_multilayer_extension.h b/YUViewLib/src/parser/HEVC/Extensions/sps_multilayer_extension.h new file mode 100644 index 000000000..8a8a2dda8 --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/sps_multilayer_extension.h @@ -0,0 +1,51 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "parser/common/SubByteReaderLogging.h" + +namespace parser::hevc +{ + +// F.7.3.2.2.4 Sequence parameter set multilayer extension syntax +class sps_multilayer_extension +{ +public: + sps_multilayer_extension() {} + + void parse(reader::SubByteReaderLogging &reader); + + bool inter_view_mv_vert_constraint_flag{}; +}; + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/sps_range_extension.cpp b/YUViewLib/src/parser/HEVC/Extensions/sps_range_extension.cpp new file mode 100644 index 000000000..eda25c13c --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/sps_range_extension.cpp @@ -0,0 +1,60 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "sps_range_extension.h" + +namespace parser::hevc +{ + +using namespace reader; + +void sps_range_extension::parse(SubByteReaderLogging &reader) +{ + SubByteReaderLoggingSubLevel subLevel(reader, "sps_range_extension()"); + + this->transform_skip_rotation_enabled_flag = + reader.readFlag("transform_skip_rotation_enabled_flag"); + this->transform_skip_context_enabled_flag = + reader.readFlag("transform_skip_context_enabled_flag"); + this->implicit_rdpcm_enabled_flag = reader.readFlag("implicit_rdpcm_enabled_flag"); + this->explicit_rdpcm_enabled_flag = reader.readFlag("explicit_rdpcm_enabled_flag"); + this->extended_precision_processing_flag = reader.readFlag("extended_precision_processing_flag"); + this->intra_smoothing_disabled_flag = reader.readFlag("intra_smoothing_disabled_flag"); + this->high_precision_offsets_enabled_flag = + reader.readFlag("high_precision_offsets_enabled_flag"); + this->persistent_rice_adaptation_enabled_flag = + reader.readFlag("persistent_rice_adaptation_enabled_flag"); + this->cabac_bypass_alignment_enabled_flag = + reader.readFlag("cabac_bypass_alignment_enabled_flag"); +} + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/sps_range_extension.h b/YUViewLib/src/parser/HEVC/Extensions/sps_range_extension.h new file mode 100644 index 000000000..853f407e7 --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/sps_range_extension.h @@ -0,0 +1,59 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "parser/common/SubByteReaderLogging.h" + +namespace parser::hevc +{ + +// 7.3.2.2.2 Sequence parameter set range extension syntax +class sps_range_extension +{ +public: + sps_range_extension() {} + + void parse(reader::SubByteReaderLogging &reader); + + bool transform_skip_rotation_enabled_flag{}; + bool transform_skip_context_enabled_flag{}; + bool implicit_rdpcm_enabled_flag{}; + bool explicit_rdpcm_enabled_flag{}; + bool extended_precision_processing_flag{}; + bool intra_smoothing_disabled_flag{}; + bool high_precision_offsets_enabled_flag{}; + bool persistent_rice_adaptation_enabled_flag{}; + bool cabac_bypass_alignment_enabled_flag{}; +}; + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/sps_scc_extension.cpp b/YUViewLib/src/parser/HEVC/Extensions/sps_scc_extension.cpp new file mode 100644 index 000000000..6569a623e --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/sps_scc_extension.cpp @@ -0,0 +1,83 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "sps_scc_extension.h" + +#include + +namespace parser::hevc +{ + +using namespace reader; + +void sps_scc_extension::parse(SubByteReaderLogging &reader, + const unsigned chroma_format_idc, + const unsigned bitDepthLuma, + const unsigned bitDepthChroma) +{ + SubByteReaderLoggingSubLevel subLevel(reader, "sps_scc_extension()"); + + this->sps_curr_pic_ref_enabled_flag = reader.readFlag("sps_curr_pic_ref_enabled_flag"); + this->palette_mode_enabled_flag = reader.readFlag("palette_mode_enabled_flag"); + if (this->palette_mode_enabled_flag) + { + this->palette_max_size = reader.readUEV("palette_max_size"); + this->delta_palette_max_predictor_size = reader.readUEV("delta_palette_max_predictor_size"); + this->sps_palette_predictor_initializers_present_flag = + reader.readFlag("sps_palette_predictor_initializers_present_flag"); + if (this->sps_palette_predictor_initializers_present_flag) + { + this->sps_num_palette_predictor_initializers_minus1 = + reader.readUEV("sps_num_palette_predictor_initializers_minus1"); + const auto numComps = (chroma_format_idc == 0) ? 1 : 3; + for (int comp = 0; comp < numComps; comp++) + { + for (int i = 0; i <= this->sps_num_palette_predictor_initializers_minus1; i++) + { + // There is an issue in the HEVC spec here. It is missing the number of bits that are used + // to code this symbol. From the SCC reference software I was able to deduce that it + // should be equal to the number for bit_depth signaled in the SPS for the component. + const int numBits = (comp == 0) ? bitDepthLuma : bitDepthChroma; + + sps_palette_predictor_initializer[comp][i] = + reader.readBits(formatArray("sps_palette_predictor_initializer", comp, i), numBits); + } + } + } + } + this->motion_vector_resolution_control_idc = + reader.readBits("motion_vector_resolution_control_idc", 2); + this->intra_boundary_filtering_disabled_flag = + reader.readFlag("intra_boundary_filtering_disabled_flag"); +} + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/sps_scc_extension.h b/YUViewLib/src/parser/HEVC/Extensions/sps_scc_extension.h new file mode 100644 index 000000000..ea839b30b --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/sps_scc_extension.h @@ -0,0 +1,62 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "parser/common/SubByteReaderLogging.h" + +namespace parser::hevc +{ + +// 7.3.2.2.3 Sequence parameter set screen content coding extension syntax +class sps_scc_extension +{ +public: + sps_scc_extension() {} + + void parse(reader::SubByteReaderLogging &reader, + const unsigned chroma_format_idc, + const unsigned bitDepthLuma, + const unsigned bitDepthChroma); + + bool sps_curr_pic_ref_enabled_flag{}; + bool palette_mode_enabled_flag{}; + unsigned palette_max_size{}; + unsigned delta_palette_max_predictor_size{}; + bool sps_palette_predictor_initializers_present_flag{}; + unsigned sps_num_palette_predictor_initializers_minus1{}; + umap_2d sps_palette_predictor_initializer; + unsigned motion_vector_resolution_control_idc{}; + bool intra_boundary_filtering_disabled_flag{}; +}; + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/video_signal_info.cpp b/YUViewLib/src/parser/HEVC/Extensions/video_signal_info.cpp new file mode 100644 index 000000000..814e657f9 --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/video_signal_info.cpp @@ -0,0 +1,51 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "video_signal_info.h" + +namespace parser::hevc +{ + +using namespace reader; + +void video_signal_info::parse(SubByteReaderLogging &reader) +{ + SubByteReaderLoggingSubLevel subLevel(reader, "video_signal_info()"); + + this->video_vps_format = reader.readBits("video_vps_format", 3); + this->video_full_range_vps_flag = reader.readFlag("video_full_range_vps_flag"); + this->colour_primaries_vps = reader.readBits("colour_primaries_vps", 8); + this->transfer_characteristics_vps = reader.readBits("transfer_characteristics_vps", 8); + this->matrix_coeffs_vps = reader.readBits("matrix_coeffs_vps", 8); +} + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/video_signal_info.h b/YUViewLib/src/parser/HEVC/Extensions/video_signal_info.h new file mode 100644 index 000000000..52dd4fd11 --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/video_signal_info.h @@ -0,0 +1,55 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "parser/common/SubByteReaderLogging.h" + +namespace parser::hevc +{ + +// F.7.3.2.2.4 Sequence parameter set multilayer extension syntax +class video_signal_info +{ +public: + video_signal_info() {} + + void parse(reader::SubByteReaderLogging &reader); + + unsigned video_vps_format{}; + bool video_full_range_vps_flag{}; + unsigned colour_primaries_vps{}; + unsigned transfer_characteristics_vps{}; + unsigned matrix_coeffs_vps{}; +}; + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/vps_extension.cpp b/YUViewLib/src/parser/HEVC/Extensions/vps_extension.cpp new file mode 100644 index 000000000..03e14c187 --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/vps_extension.cpp @@ -0,0 +1,464 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "vps_extension.h" + +#include + +#include + +namespace parser::hevc +{ + +using namespace reader; + +void vps_extension::parse(SubByteReaderLogging & reader, + const unsigned vps_max_layers_minus1, + const bool vps_base_layer_internal_flag, + const unsigned vps_max_sub_layers_minus1, + const unsigned vps_num_layer_sets_minus1, + const unsigned vps_num_hrd_parameters, + const umap_1d &NumLayersInIdListVPS, + const umap_2d &LayerSetLayerIdListVPS) +{ + SubByteReaderLoggingSubLevel subLevel(reader, "vps_extension()"); + + this->NumLayersInIdList = NumLayersInIdListVPS; + this->LayerSetLayerIdList = LayerSetLayerIdListVPS; + + if (vps_max_layers_minus1 > 0 && vps_base_layer_internal_flag) + profileTierLevel.parse(reader, false, vps_max_sub_layers_minus1); + this->splitting_flag = reader.readFlag("splitting_flag"); + + unsigned NumScalabilityTypes = 0; + for (unsigned i = 0; i < 16; i++) + { + this->scalability_mask_flag.push_back(reader.readFlag(formatArray("scalability_mask_flag", i))); + if (this->scalability_mask_flag.at(i)) + NumScalabilityTypes++; + } + + for (unsigned j = 0; j < (NumScalabilityTypes - (this->splitting_flag) ? 1u : 0u); j++) + this->dimension_id_len_minus1.push_back( + reader.readBits(formatArray("dimension_id_len_minus1", j), 3)); + + this->vps_nuh_layer_id_present_flag = reader.readFlag("vps_nuh_layer_id_present_flag"); + this->MaxLayersMinus1 = std::min(62u, vps_max_layers_minus1); + reader.logCalculatedValue("MaxLayersMinus1", this->MaxLayersMinus1); + + for (unsigned i = 1; i <= this->MaxLayersMinus1; i++) + { + if (this->vps_nuh_layer_id_present_flag) + this->layer_id_in_nuh[i] = reader.readBits(formatArray("layer_id_in_nuh", i), 6); + else + this->layer_id_in_nuh[i] = i; + this->LayerIdxInVps[this->layer_id_in_nuh[i]] = i; + + if (!this->splitting_flag) + { + for (unsigned j = 0; j < NumScalabilityTypes; j++) + { + const auto nrBits = this->dimension_id_len_minus1[j] + 1; + this->dimension_id[i][j] = reader.readBits(formatArray("dimension_id", i, j), nrBits); + } + } + } + + this->calcualteValuesF3(); + + this->view_id_len = reader.readBits("view_id_len", 4); + if (this->view_id_len > 0) + { + for (unsigned i = 0; i < NumViews; i++) + this->view_id_val.push_back( + reader.readBits(formatArray("view_id_val", i), this->view_id_len)); + } + + for (unsigned i = 1; i <= MaxLayersMinus1; i++) + for (unsigned j = 0; j < i; j++) + this->direct_dependency_flag[i][j] = + reader.readFlag(formatArray("direct_dependency_flag", i, j)); + this->calcualteValuesF4(); + this->calcualteValuesF5(); + this->calcualteValuesF6(); + + if (this->NumIndependentLayers > 1) + this->num_add_layer_sets = reader.readUEV("num_add_layer_sets"); + this->NumLayerSets = vps_num_layer_sets_minus1 + 1 + num_add_layer_sets; + + for (unsigned i = 0; i < this->num_add_layer_sets; i++) + { + for (unsigned j = 1; j < this->NumIndependentLayers; j++) + { + const auto nrBits = std::ceil(std::log2(this->NumLayersInTreePartition[j] + 1)); + this->highest_layer_idx_plus1[i][j] = + reader.readBits(formatArray("highest_layer_idx_plus1", i, j), nrBits); + } + this->calculateValuesF9(vps_num_layer_sets_minus1, i); + } + + this->vps_sub_layers_max_minus1_present_flag = + reader.readFlag("vps_sub_layers_max_minus1_present_flag"); + if (this->vps_sub_layers_max_minus1_present_flag) + for (unsigned i = 0; i <= this->MaxLayersMinus1; i++) + sub_layers_vps_max_minus1.push_back( + reader.readBits(formatArray("sub_layers_vps_max_minus1", i), 3)); + else + for (unsigned i = 0; i <= this->MaxLayersMinus1; i++) + sub_layers_vps_max_minus1.push_back(vps_max_sub_layers_minus1); + this->calcualteValuesF10(); + + this->max_tid_ref_present_flag = reader.readFlag("max_tid_ref_present_flag"); + if (this->max_tid_ref_present_flag) + { + for (unsigned i = 0; i < this->MaxLayersMinus1; i++) + for (unsigned j = i + 1; j <= this->MaxLayersMinus1; j++) + if (this->direct_dependency_flag[j][i]) + this->max_tid_il_ref_pics_plus1[i][j] = + reader.readBits(formatArray("max_tid_il_ref_pics_plus1", i, j), 3); + } + + this->default_ref_layers_active_flag = reader.readFlag("default_ref_layers_active_flag"); + this->vps_num_profile_tier_level_minus1 = reader.readUEV("vps_num_profile_tier_level_minus1"); + for (unsigned i = vps_base_layer_internal_flag ? 2 : 1; + i <= this->vps_num_profile_tier_level_minus1; + i++) + { + this->vps_profile_present_flag[i] = reader.readFlag(formatArray("vps_profile_present_flag", i)); + profileTierLevelSubLayers[i].parse( + reader, this->vps_profile_present_flag[i], vps_max_sub_layers_minus1); + } + + if (this->NumLayerSets > 1) + { + this->num_add_olss = reader.readUEV("num_add_olss"); + this->default_output_layer_idc = reader.readBits("default_output_layer_idc", 2); + } + this->defaultOutputLayerIdc = std::min(this->default_output_layer_idc, 2u); + + this->NumOutputLayerSets = this->num_add_olss + this->NumLayerSets; + for (unsigned i = 1; i < this->NumOutputLayerSets; i++) + { + if (this->NumLayerSets > 2 && i >= this->NumLayerSets) + { + const auto nrBits = std::ceil(std::log2(this->NumLayerSets - 1)); + this->layer_set_idx_for_ols_minus1[i] = + reader.readBits(formatArray("layer_set_idx_for_ols_minus1", i), nrBits); + } + this->calculateValuesF11(i); + + if (i > vps_num_layer_sets_minus1 || this->defaultOutputLayerIdc == 2) + { + for (unsigned j = 0; j < NumLayersInIdList[this->OlsIdxToLsIdx[i]]; j++) + { + this->output_layer_flag[i][j] = reader.readFlag(formatArray("output_layer_flag", i, j)); + this->OutputLayerFlag[i][j] = this->output_layer_flag[i][j]; + } + } + else if ((this->defaultOutputLayerIdc == 0 || this->defaultOutputLayerIdc == 1) && + i <= vps_num_layer_sets_minus1) + { + for (int j = 0; j <= int(NumLayersInIdList[OlsIdxToLsIdx[i]]) - 1; j++) + { + const auto layerIdAList = this->LayerSetLayerIdList[this->OlsIdxToLsIdx[i]]; + const auto nuhLayerIdA = std::max_element(layerIdAList.begin(), layerIdAList.end()); + if (this->defaultOutputLayerIdc == 0 || layerIdAList.at(j) == nuhLayerIdA->second) + this->OutputLayerFlag[i][j] = true; + else + this->OutputLayerFlag[i][j] = false; + } + } + + this->calcualteValuesF12(i); + this->calculateValuesF13(i); + + for (unsigned j = 0; j < this->NumLayersInIdList[this->OlsIdxToLsIdx[i]]; j++) + { + if (this->NecessaryLayerFlag[i][j] && this->vps_num_profile_tier_level_minus1 > 0) + { + const auto nrBits = std::ceil(std::log2(this->vps_num_profile_tier_level_minus1 + 1)); + this->profile_tier_level_idx[i][j] = + reader.readBits(formatArray("profile_tier_level_idx", i, j), nrBits); + } + } + + if (this->NumOutputLayersInOutputLayerSet[i] == 1 && + this->NumDirectRefLayers[OlsHighestOutputLayerId[i]] > 0) + this->alt_output_layer_flag[i] = reader.readFlag(formatArray("alt_output_layer_flag", i)); + } + + this->vps_num_rep_formats_minus1 = reader.readUEV("vps_num_rep_formats_minus1"); + for (unsigned i = 0; i <= this->vps_num_rep_formats_minus1; i++) + { + rep_format repFormat; + repFormat.parse(reader); + repFormats.push_back(repFormat); + } + + if (this->vps_num_rep_formats_minus1 > 0) + this->rep_format_idx_present_flag = reader.readFlag("rep_format_idx_present_flag"); + + if (this->rep_format_idx_present_flag) + { + for (unsigned i = vps_base_layer_internal_flag ? 1 : 0; i <= MaxLayersMinus1; i++) + { + const auto nrBits = std::ceil(std::log2(this->vps_num_rep_formats_minus1 + 1)); + this->vps_rep_format_idx.push_back( + reader.readBits(formatArray("vps_rep_format_idx", i), nrBits)); + } + } + + this->max_one_active_ref_layer_flag = reader.readFlag("max_one_active_ref_layer_flag"); + this->vps_poc_lsb_aligned_flag = reader.readFlag("vps_poc_lsb_aligned_flag"); + for (unsigned i = 1; i <= this->MaxLayersMinus1; i++) + if (this->NumDirectRefLayers[this->layer_id_in_nuh[i]] == 0) + this->poc_lsb_not_present_flag[i] = + reader.readFlag(formatArray("poc_lsb_not_present_flag", i)); + + this->dpbSize.parse(reader, + this->NumOutputLayerSets, + this->OlsIdxToLsIdx, + this->MaxSubLayersInLayerSetMinus1, + this->NumLayersInIdList, + this->NecessaryLayerFlag, + vps_base_layer_internal_flag, + this->LayerSetLayerIdList); + + this->direct_dep_type_len_minus2 = reader.readUEV("direct_dep_type_len_minus2"); + this->direct_dependency_all_layers_flag = reader.readFlag("direct_dependency_all_layers_flag"); + if (this->direct_dependency_all_layers_flag) + { + const auto nrBits = this->direct_dep_type_len_minus2 + 2; + this->direct_dependency_all_layers_type = + reader.readBits("direct_dependency_all_layers_type", nrBits); + } + else + { + for (unsigned i = vps_base_layer_internal_flag ? 1 : 2; i <= MaxLayersMinus1; i++) + for (unsigned j = vps_base_layer_internal_flag ? 0 : 1; j < i; j++) + if (this->direct_dependency_flag[i][j]) + { + const auto nrBits = this->direct_dep_type_len_minus2 + 2; + direct_dependency_type[i][j] = + reader.readBits(formatArray("direct_dependency_type", i, j), nrBits); + } + } + + this->vps_non_vui_extension_length = reader.readUEV("vps_non_vui_extension_length"); + for (unsigned i = 1; i <= this->vps_non_vui_extension_length; i++) + this->vps_non_vui_extension_data_byte = reader.readBits("vps_non_vui_extension_data_byte", 8); + this->vps_vui_present_flag = reader.readFlag("vps_vui_present_flag"); + if (this->vps_vui_present_flag) + { + while (!reader.byte_aligned()) + reader.readFlag("vps_vui_alignment_bit_equal_to_one", Options().withCheckEqualTo(0)); + vpsVui.parse(reader, + this->vps_vui_present_flag, + vps_base_layer_internal_flag, + this->NumLayerSets, + this->MaxSubLayersInLayerSetMinus1, + this->MaxLayersMinus1, + this->NumDirectRefLayers, + this->layer_id_in_nuh, + this->LayerIdxInVps, + this->IdDirectRefLayer, + vps_num_hrd_parameters, + this->NumOutputLayerSets, + this->NumLayersInIdList, + this->OlsIdxToLsIdx); + } +} + +void vps_extension::calcualteValuesF3() +{ + // F.7.4.3.1.1 (F-3) + this->NumViews = 1; + for (unsigned i = 0; i <= this->MaxLayersMinus1; i++) + { + const auto lId = this->layer_id_in_nuh[i]; + ScalabilityId.emplace_back(); + unsigned j = 0; + for (unsigned smIdx = 0; smIdx < 16; smIdx++) + { + if (this->scalability_mask_flag[smIdx]) + this->ScalabilityId[i].push_back(this->dimension_id[i][j++]); + else + this->ScalabilityId[i].push_back(0); + } + this->DepthLayerFlag[lId] = this->ScalabilityId[i][0]; + this->ViewOrderIdx[lId] = this->ScalabilityId[i][1]; + this->DependencyId[lId] = this->ScalabilityId[i][2]; + this->AuxId[lId] = this->ScalabilityId[i][3]; + + if (i > 0) + { + + bool newViewFlag = true; + for (unsigned j = 0; j < i; j++) + if (this->ViewOrderIdx[lId] == this->ViewOrderIdx[layer_id_in_nuh[j]]) + newViewFlag = false; + if (newViewFlag) + this->NumViews++; + } + } +} + +void vps_extension::calcualteValuesF4() +{ + for (unsigned i = 0; i <= MaxLayersMinus1; i++) + for (unsigned j = 0; j <= MaxLayersMinus1; j++) + { + this->DependencyFlag[i][j] = this->direct_dependency_flag[i][j]; + for (unsigned k = 0; k < i; k++) + if (this->direct_dependency_flag[i][k] && this->DependencyFlag[k][j]) + this->DependencyFlag[i][j] = true; + } +} + +void vps_extension::calcualteValuesF5() +{ + for (unsigned i = 0; i <= this->MaxLayersMinus1; i++) + { + const auto iNuhLId = this->layer_id_in_nuh[i]; + unsigned d = 0; + unsigned r = 0; + unsigned p = 0; + for (unsigned j = 0; j <= this->MaxLayersMinus1; j++) + { + const auto jNuhLid = this->layer_id_in_nuh[j]; + if (this->direct_dependency_flag[i][j]) + this->IdDirectRefLayer[iNuhLId][d++] = jNuhLid; + if (this->DependencyFlag[i][j]) + this->IdRefLayer[iNuhLId][r++] = jNuhLid; + if (this->DependencyFlag[j][i]) + this->IdPredictedLayer[iNuhLId][p++] = jNuhLid; + } + this->NumDirectRefLayers[iNuhLId] = d; + this->NumRefLayers[iNuhLId] = r; + this->NumPredictedLayers[iNuhLId] = p; + } +} + +void vps_extension::calcualteValuesF6() +{ + for (unsigned i = 0; i <= 63; i++) + this->layerIdInListFlag[i] = 0; + + unsigned k = 0; + for (unsigned i = 0; i <= this->MaxLayersMinus1; i++) + { + const auto iNuhLId = this->layer_id_in_nuh[i]; + if (this->NumDirectRefLayers[iNuhLId] == 0) + { + this->TreePartitionLayerIdList[k][0] = iNuhLId; + unsigned h = 1; + for (unsigned j = 0; j < this->NumPredictedLayers[iNuhLId]; j++) + { + const auto predLId = this->IdPredictedLayer[iNuhLId][j]; + if (!this->layerIdInListFlag[predLId]) + { + this->TreePartitionLayerIdList[k][h++] = predLId; + this->layerIdInListFlag[predLId] = 1; + } + } + this->NumLayersInTreePartition.push_back(h); + k++; + } + } + this->NumIndependentLayers = k; +} + +void vps_extension::calculateValuesF9(const unsigned vps_num_layer_sets_minus1, const unsigned i) +{ + auto layerNum = 0u; + const auto lsIdx = vps_num_layer_sets_minus1 + 1 + i; + for (unsigned treeIdx = 1; treeIdx < this->NumIndependentLayers; treeIdx++) + for (unsigned layerCnt = 0; layerCnt < this->highest_layer_idx_plus1[i][treeIdx]; layerCnt++) + this->LayerSetLayerIdList[lsIdx][layerNum++] = + this->TreePartitionLayerIdList[treeIdx][layerCnt]; + this->NumLayersInIdList[lsIdx] = layerNum; +} + +void vps_extension::calcualteValuesF10() +{ + for (unsigned i = 0; i < this->NumLayerSets; i++) + { + auto maxSlMinus1 = 0u; + for (unsigned k = 0; k < this->NumLayersInIdList[i]; k++) + { + auto lId = this->LayerSetLayerIdList[i][k]; + maxSlMinus1 = std::max(maxSlMinus1, this->sub_layers_vps_max_minus1[LayerIdxInVps[lId]]); + } + MaxSubLayersInLayerSetMinus1.push_back(maxSlMinus1); + } +} + +void vps_extension::calculateValuesF11(const unsigned i) +{ + this->OlsIdxToLsIdx[i] = + (i < this->NumLayerSets) ? i : (this->layer_set_idx_for_ols_minus1[i] + 1); +} + +void vps_extension::calcualteValuesF12(const unsigned i) +{ + this->NumOutputLayersInOutputLayerSet[i] = 0; + for (unsigned j = 0; j < this->NumLayersInIdList[OlsIdxToLsIdx[i]]; j++) + { + this->NumOutputLayersInOutputLayerSet[i] += this->OutputLayerFlag[i][j]; + if (this->OutputLayerFlag[i][j]) + this->OlsHighestOutputLayerId[i] = this->LayerSetLayerIdList[OlsIdxToLsIdx[i]][j]; + } +} + +void vps_extension::calculateValuesF13(const unsigned olsIdx) +{ + const auto lsIdx = OlsIdxToLsIdx[olsIdx]; + for (unsigned lsLayerIdx = 0; lsLayerIdx < this->NumLayersInIdList[lsIdx]; lsLayerIdx++) + this->NecessaryLayerFlag[olsIdx][lsLayerIdx] = false; + for (unsigned lsLayerIdx = 0; lsLayerIdx < this->NumLayersInIdList[lsIdx]; lsLayerIdx++) + if (this->OutputLayerFlag[olsIdx][lsLayerIdx]) + { + this->NecessaryLayerFlag[olsIdx][lsLayerIdx] = true; + const auto currLayerId = this->LayerSetLayerIdList[lsIdx][lsLayerIdx]; + for (unsigned rLsLayerIdx = 0; rLsLayerIdx < lsLayerIdx; rLsLayerIdx++) + { + const auto refLayerId = this->LayerSetLayerIdList[lsIdx][rLsLayerIdx]; + if (this->DependencyFlag[LayerIdxInVps[currLayerId]][LayerIdxInVps[refLayerId]]) + this->NecessaryLayerFlag[olsIdx][rLsLayerIdx] = 1; + } + } + this->NumNecessaryLayers[olsIdx] = 0; + for (unsigned lsLayerIdx = 0; lsLayerIdx < this->NumLayersInIdList[lsIdx]; lsLayerIdx++) + this->NumNecessaryLayers[olsIdx] += this->NecessaryLayerFlag[olsIdx][lsLayerIdx]; +} + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/vps_extension.h b/YUViewLib/src/parser/HEVC/Extensions/vps_extension.h new file mode 100644 index 000000000..0804b86f1 --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/vps_extension.h @@ -0,0 +1,161 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "../profile_tier_level.h" +#include "dpb_size.h" +#include "parser/common/SubByteReaderLogging.h" +#include "rep_format.h" +#include "vps_vui.h" + +namespace parser::hevc +{ + +// F.7.3.2.1.1 Video parameter set extension syntax +class vps_extension +{ +public: + vps_extension() {} + + void parse(reader::SubByteReaderLogging &reader, + const unsigned vps_max_layers_minus1, + const bool vps_base_layer_internal_flag, + const unsigned vps_max_sub_layers_minus1, + const unsigned vps_num_layer_sets_minus1, + const unsigned vps_num_hrd_parameters, + const umap_1d & NumLayersInIdListVPS, + const umap_2d & LayerSetLayerIdListVPS); + + profile_tier_level profileTierLevel; + bool splitting_flag{}; + vector scalability_mask_flag{}; + vector dimension_id_len_minus1{}; + bool vps_nuh_layer_id_present_flag{}; + umap_1d layer_id_in_nuh{}; + umap_1d LayerIdxInVps{}; + umap_2d dimension_id{}; + unsigned view_id_len{}; + vector view_id_val{}; + + void calcualteValuesF3(); + unsigned MaxLayersMinus1{}; + vector2d ScalabilityId; + umap_1d ViewOrderIdx; + umap_1d DepthLayerFlag; + umap_1d DependencyId; + umap_1d AuxId; + unsigned NumViews{}; + + umap_2d direct_dependency_flag; + unsigned num_add_layer_sets{}; + + void calcualteValuesF4(); + umap_2d DependencyFlag; + + void calcualteValuesF5(); + umap_2d IdDirectRefLayer; + umap_2d IdRefLayer; + umap_2d IdPredictedLayer; + umap_1d NumDirectRefLayers; + umap_1d NumRefLayers; + umap_1d NumPredictedLayers; + + void calcualteValuesF6(); + std::array layerIdInListFlag{}; + umap_2d TreePartitionLayerIdList; + vector NumLayersInTreePartition; + unsigned NumIndependentLayers{}; + + umap_2d highest_layer_idx_plus1; + void calculateValuesF9(const unsigned vps_num_layer_sets_minus1, const unsigned i); + umap_2d LayerSetLayerIdList; + umap_1d NumLayersInIdList; + + bool vps_sub_layers_max_minus1_present_flag{}; + vector sub_layers_vps_max_minus1; + void calcualteValuesF10(); + vector MaxSubLayersInLayerSetMinus1; + bool max_tid_ref_present_flag{}; + umap_2d max_tid_il_ref_pics_plus1; + bool default_ref_layers_active_flag{}; + unsigned vps_num_profile_tier_level_minus1{}; + umap_1d vps_profile_present_flag{}; + umap_1d profileTierLevelSubLayers; + + unsigned NumLayerSets{}; + unsigned num_add_olss{}; + unsigned default_output_layer_idc{}; + unsigned defaultOutputLayerIdc{}; + + unsigned NumOutputLayerSets{}; + umap_1d layer_set_idx_for_ols_minus1; + void calculateValuesF11(const unsigned i); + umap_1d OlsIdxToLsIdx; + + umap_2d output_layer_flag; + umap_2d OutputLayerFlag; + void calcualteValuesF12(const unsigned i); + umap_1d NumOutputLayersInOutputLayerSet; + umap_1d OlsHighestOutputLayerId; + umap_2d profile_tier_level_idx; + + void calculateValuesF13(const unsigned olsIdx); + umap_2d NecessaryLayerFlag; + umap_1d NumNecessaryLayers; + + umap_1d alt_output_layer_flag; + + unsigned vps_num_rep_formats_minus1{}; + vector repFormats; + + bool rep_format_idx_present_flag{}; + vector vps_rep_format_idx; + bool max_one_active_ref_layer_flag{}; + bool vps_poc_lsb_aligned_flag{}; + umap_1d poc_lsb_not_present_flag; + + dpb_size dpbSize{}; + + unsigned direct_dep_type_len_minus2{}; + bool direct_dependency_all_layers_flag{}; + unsigned direct_dependency_all_layers_type{}; + umap_2d direct_dependency_type; + + unsigned vps_non_vui_extension_length{}; + unsigned vps_non_vui_extension_data_byte{}; + bool vps_vui_present_flag{}; + + vps_vui vpsVui; +}; + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/vps_vui.cpp b/YUViewLib/src/parser/HEVC/Extensions/vps_vui.cpp new file mode 100644 index 000000000..d8270e1ce --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/vps_vui.cpp @@ -0,0 +1,175 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "vps_vui.h" + +#include + +namespace parser::hevc +{ + +using namespace reader; + +void vps_vui::parse(SubByteReaderLogging & reader, + const bool vps_vui_present_flag, + const bool vps_base_layer_internal_flag, + const unsigned NumLayerSets, + const vector & MaxSubLayersInLayerSetMinus1, + const unsigned MaxLayersMinus1, + const umap_1d &NumDirectRefLayers, + const umap_1d &layer_id_in_nuh, + const umap_1d &LayerIdxInVps, + const umap_2d &IdDirectRefLayer, + const unsigned vps_num_hrd_parameters, + const unsigned NumOutputLayerSets, + const umap_1d &NumLayersInIdList, + const umap_1d &OlsIdxToLsIdx) +{ + SubByteReaderLoggingSubLevel subLevel(reader, "vps_vui()"); + + this->cross_layer_pic_type_aligned_flag = reader.readFlag("cross_layer_pic_type_aligned_flag"); + if (!this->cross_layer_pic_type_aligned_flag) + this->cross_layer_irap_aligned_flag = reader.readFlag("cross_layer_irap_aligned_flag"); + else + this->cross_layer_irap_aligned_flag = vps_vui_present_flag; + if (this->cross_layer_irap_aligned_flag) + this->all_layers_idr_aligned_flag = reader.readFlag("all_layers_idr_aligned_flag"); + this->bit_rate_present_vps_flag = reader.readFlag("bit_rate_present_vps_flag"); + this->pic_rate_present_vps_flag = reader.readFlag("pic_rate_present_vps_flag"); + + if (this->bit_rate_present_vps_flag || this->pic_rate_present_vps_flag) + { + for (unsigned i = vps_base_layer_internal_flag ? 0 : 1; i < NumLayerSets; i++) + { + for (unsigned j = 0; j <= MaxSubLayersInLayerSetMinus1[i]; j++) + { + if (this->bit_rate_present_vps_flag) + this->bit_rate_present_flag[i][j] = + reader.readFlag(formatArray("all_layers_idr_aligned_flag", i, j)); + if (this->pic_rate_present_vps_flag) + this->pic_rate_present_flag[i][j] = + reader.readFlag(formatArray("pic_rate_present_flag", i, j)); + if (this->bit_rate_present_flag[i][j]) + { + this->avg_bit_rate[i][j] = reader.readBits(formatArray("avg_bit_rate", i, j), 16); + this->max_bit_rate[i][j] = reader.readBits(formatArray("max_bit_rate", i, j), 16); + } + if (this->pic_rate_present_flag[i][j]) + { + this->constant_pic_rate_idc[i][j] = + reader.readBits(formatArray("constant_pic_rate_idc", i, j), 2); + this->avg_pic_rate[i][j] = reader.readBits(formatArray("avg_pic_rate", i, j), 16); + } + } + } + } + + this->video_signal_info_idx_present_flag = reader.readFlag("video_signal_info_idx_present_flag"); + if (this->video_signal_info_idx_present_flag) + this->vps_num_video_signal_info_minus1 = reader.readBits("vps_num_video_signal_info_minus1", 4); + + for (unsigned i = 0; i <= this->vps_num_video_signal_info_minus1; i++) + { + video_signal_info videoSignalInfo; + videoSignalInfo.parse(reader); + this->videoSignalInfoList.push_back(videoSignalInfo); + } + + if (this->video_signal_info_idx_present_flag && this->vps_num_video_signal_info_minus1 > 0) + for (unsigned i = vps_base_layer_internal_flag ? 0 : 1; i <= MaxLayersMinus1; i++) + this->vps_video_signal_info_idx[i] = reader.readBits("vps_video_signal_info_idx", 4); + + this->tiles_not_in_use_flag = reader.readFlag("tiles_not_in_use_flag"); + + if (!this->tiles_not_in_use_flag) + { + for (unsigned i = vps_base_layer_internal_flag ? 0 : 1; i <= MaxLayersMinus1; i++) + { + this->tiles_in_use_flag[i] = reader.readFlag("tiles_in_use_flag"); + if (this->tiles_in_use_flag[i]) + this->loop_filter_not_across_tiles_flag[i] = reader.readFlag("tiles_in_use_flag"); + } + for (unsigned i = vps_base_layer_internal_flag ? 1 : 2; i <= MaxLayersMinus1; i++) + for (unsigned j = 0; j < NumDirectRefLayers.at(layer_id_in_nuh.at(i)); j++) + { + const auto layerIdx = LayerIdxInVps.at(IdDirectRefLayer.at(layer_id_in_nuh.at(i)).at(j)); + if (tiles_in_use_flag[i] && tiles_in_use_flag[layerIdx]) + this->tile_boundaries_aligned_flag[i][j] = + reader.readFlag(formatArray("tile_boundaries_aligned_flag", i, j)); + } + } + + this->wpp_not_in_use_flag = reader.readFlag("wpp_not_in_use_flag"); + if (!this->wpp_not_in_use_flag) + for (unsigned i = vps_base_layer_internal_flag ? 0 : 1; i <= MaxLayersMinus1; i++) + this->wpp_in_use_flag[i] = reader.readFlag(formatArray("wpp_in_use_flag", i)); + + this->single_layer_for_non_irap_flag = reader.readFlag("single_layer_for_non_irap_flag"); + this->higher_layer_irap_skip_flag = reader.readFlag("higher_layer_irap_skip_flag"); + this->ilp_restricted_ref_layers_flag = reader.readFlag("ilp_restricted_ref_layers_flag"); + if (this->ilp_restricted_ref_layers_flag) + { + for (unsigned i = 1; i <= MaxLayersMinus1; i++) + for (unsigned j = 0; j < NumDirectRefLayers.at(layer_id_in_nuh.at(i)); j++) + { + if (vps_base_layer_internal_flag || IdDirectRefLayer.at(layer_id_in_nuh.at(i)).at(j) > 0) + { + this->min_spatial_segment_offset_plus1[i][j] = + reader.readUEV(formatArray("min_spatial_segment_offset_plus1", i, j)); + if (this->min_spatial_segment_offset_plus1[i][j] > 0) + { + this->ctu_based_offset_enabled_flag[i][j] = + reader.readFlag(formatArray("ctu_based_offset_enabled_flag", i, j)); + if (this->ctu_based_offset_enabled_flag[i][j]) + this->min_horizontal_ctu_offset_plus1[i][j] = + reader.readUEV(formatArray("min_horizontal_ctu_offset_plus1", i, j)); + } + } + } + } + + this->vps_vui_bsp_hrd_present_flag = reader.readFlag("vps_vui_bsp_hrd_present_flag"); + if (this->vps_vui_bsp_hrd_present_flag) + vpsVuiBspHrdParams.parse(reader, + vps_num_hrd_parameters, + NumOutputLayerSets, + NumLayersInIdList, + OlsIdxToLsIdx, + MaxSubLayersInLayerSetMinus1); + + for (unsigned i = 1; i <= MaxLayersMinus1; i++) + if (NumDirectRefLayers.at(layer_id_in_nuh.at(i)) == 0) + this->base_layer_parameter_set_compatibility_flag[i] = + reader.readFlag(formatArray("base_layer_parameter_set_compatibility_flag", i)); +} + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/vps_vui.h b/YUViewLib/src/parser/HEVC/Extensions/vps_vui.h new file mode 100644 index 000000000..4411d5fc3 --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/vps_vui.h @@ -0,0 +1,103 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "parser/common/SubByteReaderLogging.h" +#include "video_signal_info.h" +#include "vps_vui_bsp_hrd_params.h" + +namespace parser::hevc +{ + +// F.7.3.2.1.4 VPS VUI syntax +class vps_vui +{ +public: + vps_vui() {} + + void parse(reader::SubByteReaderLogging &reader, + const bool vps_vui_present_flag, + const bool vps_base_layer_internal_flag, + const unsigned NumLayerSets, + const vector & MaxSubLayersInLayerSetMinus1, + const unsigned MaxLayersMinus1, + const umap_1d & NumDirectRefLayers, + const umap_1d & layer_id_in_nuh, + const umap_1d & LayerIdxInVps, + const umap_2d & IdDirectRefLayer, + const unsigned vps_num_hrd_parameters, + const unsigned NumOutputLayerSets, + const umap_1d & NumLayersInIdList, + const umap_1d & OlsIdxToLsIdx); + + bool cross_layer_pic_type_aligned_flag{}; + bool cross_layer_irap_aligned_flag{}; + bool all_layers_idr_aligned_flag{}; + bool bit_rate_present_vps_flag{}; + bool pic_rate_present_vps_flag{}; + + umap_2d bit_rate_present_flag; + umap_2d pic_rate_present_flag; + umap_2d avg_bit_rate; + umap_2d max_bit_rate; + umap_2d constant_pic_rate_idc; + umap_2d avg_pic_rate; + + bool video_signal_info_idx_present_flag{}; + unsigned vps_num_video_signal_info_minus1{}; + vector videoSignalInfoList; + + umap_1d vps_video_signal_info_idx; + + bool tiles_not_in_use_flag{}; + umap_1d tiles_in_use_flag; + umap_1d loop_filter_not_across_tiles_flag; + umap_2d tile_boundaries_aligned_flag; + + bool wpp_not_in_use_flag{}; + umap_1d wpp_in_use_flag; + + bool single_layer_for_non_irap_flag{}; + bool higher_layer_irap_skip_flag{}; + bool ilp_restricted_ref_layers_flag{}; + umap_2d min_spatial_segment_offset_plus1; + umap_2d ctu_based_offset_enabled_flag; + umap_2d min_horizontal_ctu_offset_plus1; + + bool vps_vui_bsp_hrd_present_flag{}; + vps_vui_bsp_hrd_params vpsVuiBspHrdParams{}; + + umap_1d base_layer_parameter_set_compatibility_flag; +}; + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/vps_vui_bsp_hrd_params.cpp b/YUViewLib/src/parser/HEVC/Extensions/vps_vui_bsp_hrd_params.cpp new file mode 100644 index 000000000..ff6a2bf39 --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/vps_vui_bsp_hrd_params.cpp @@ -0,0 +1,101 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "vps_vui_bsp_hrd_params.h" + +#include + +#include + +namespace parser::hevc +{ + +using namespace reader; + +void vps_vui_bsp_hrd_params::parse(SubByteReaderLogging & reader, + const unsigned vps_num_hrd_parameters, + const unsigned NumOutputLayerSets, + const umap_1d &NumLayersInIdList, + const umap_1d &OlsIdxToLsIdx, + const vector & MaxSubLayersInLayerSetMinus1) +{ + SubByteReaderLoggingSubLevel subLevel(reader, "vps_vui_bsp_hrd_params()"); + + this->vps_num_add_hrd_params = reader.readUEV("vps_num_add_hrd_params"); + for (unsigned i = vps_num_hrd_parameters; + i < vps_num_hrd_parameters + this->vps_num_add_hrd_params; + i++) + { + if (i > 0) + this->cprms_add_present_flag[i] = reader.readFlag(formatArray("cprms_add_present_flag", i)); + this->num_sub_layer_hrd_minus1[i] = reader.readUEV(formatArray("cprms_add_present_flag", i)); + hrdParameters[i].parse( + reader, this->cprms_add_present_flag[i], this->num_sub_layer_hrd_minus1[i]); + } + + if (vps_num_hrd_parameters + this->vps_num_add_hrd_params > 0) + for (unsigned h = 1; h < NumOutputLayerSets; h++) + { + this->num_signalled_partitioning_schemes[h] = + reader.readUEV(formatArray("cprms_add_present_flag", h)); + for (unsigned j = 1; j < num_signalled_partitioning_schemes[h] + 1; j++) + { + this->num_partitions_in_scheme_minus1[h][j] = + reader.readUEV(formatArray("num_partitions_in_scheme_minus1", h, j)); + for (unsigned k = 0; k <= this->num_partitions_in_scheme_minus1[h][j]; k++) + for (unsigned r = 0; r < NumLayersInIdList.at(OlsIdxToLsIdx.at(h)); r++) + layer_included_in_partition_flag[h][j][k][r] = + reader.readFlag(formatArray("layer_included_in_partition_flag", h, j, k, r)); + } + for (unsigned i = 0; i < this->num_signalled_partitioning_schemes[h] + 1; i++) + for (unsigned t = 0; t <= MaxSubLayersInLayerSetMinus1[OlsIdxToLsIdx.at(h)]; t++) + { + this->num_bsp_schedules_minus1[h][i][t] = + reader.readUEV(formatArray("num_bsp_schedules_minus1", h, i, t)); + for (unsigned j = 0; j <= this->num_bsp_schedules_minus1[h][i][t]; j++) + for (unsigned k = 0; k <= this->num_partitions_in_scheme_minus1[h][i]; k++) + { + if (vps_num_hrd_parameters + this->vps_num_add_hrd_params > 1) + { + const auto nrBits = + std::ceil(std::log2(vps_num_hrd_parameters + this->vps_num_add_hrd_params)); + this->bsp_hrd_idx[h][i][t][j][k] = + reader.readBits(formatArray("bsp_sched_idx", h, i, t, j, k), nrBits); + } + this->bsp_sched_idx[h][i][t][j][k] = + reader.readUEV(formatArray("bsp_sched_idx", h, i, t, j, k)); + } + } + } +} + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/Extensions/vps_vui_bsp_hrd_params.h b/YUViewLib/src/parser/HEVC/Extensions/vps_vui_bsp_hrd_params.h new file mode 100644 index 000000000..364f729f9 --- /dev/null +++ b/YUViewLib/src/parser/HEVC/Extensions/vps_vui_bsp_hrd_params.h @@ -0,0 +1,68 @@ +/* This file is part of YUView - The YUV player with advanced analytics toolset + * + * Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations including + * the two. + * + * You must obey the GNU General Public License in all respects for all + * of the code used other than OpenSSL. If you modify file(s) with this + * exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. If you delete + * this exception statement from all source files in the program, then + * also delete it here. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "parser/common/SubByteReaderLogging.h" + +#include "../hrd_parameters.h" + +namespace parser::hevc +{ + +// F.7.3.2.2.4 Sequence parameter set multilayer extension syntax +class vps_vui_bsp_hrd_params +{ +public: + vps_vui_bsp_hrd_params() {} + + void parse(reader::SubByteReaderLogging &reader, + const unsigned vps_num_hrd_parameters, + const unsigned NumOutputLayerSets, + const umap_1d & NumLayersInIdList, + const umap_1d & OlsIdxToLsIdx, + const vector & MaxSubLayersInLayerSetMinus1); + + unsigned vps_num_add_hrd_params{}; + umap_1d cprms_add_present_flag; + umap_1d num_sub_layer_hrd_minus1; + + umap_1d hrdParameters; + umap_1d num_signalled_partitioning_schemes; + umap_2d num_partitions_in_scheme_minus1; + umap_4d layer_included_in_partition_flag; + umap_3d num_bsp_schedules_minus1; + umap_5d bsp_hrd_idx; + umap_5d bsp_sched_idx; +}; + +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/ParserAnnexBHEVC.cpp b/YUViewLib/src/parser/HEVC/ParserAnnexBHEVC.cpp index 7ea034f02..40dacae80 100644 --- a/YUViewLib/src/parser/HEVC/ParserAnnexBHEVC.cpp +++ b/YUViewLib/src/parser/HEVC/ParserAnnexBHEVC.cpp @@ -283,7 +283,8 @@ ParserAnnexBHEVC::parseAndAddNALUnit(int if (curFramePOC != -1) { // Save the info of the last frame - if (!this->addFrameToList(curFramePOC, curFrameFileStartEndPos, curFrameIsRandomAccess)) + if (!this->addFrameToList( + curFramePOC, curFrameFileStartEndPos, curFrameIsRandomAccess, curFrameLayerID)) { throw std::logic_error("Error - POC " + std::to_string(curFramePOC) + " alread in the POC list."); @@ -291,10 +292,12 @@ ParserAnnexBHEVC::parseAndAddNALUnit(int if (curFrameFileStartEndPos) DEBUG_HEVC("ParserAnnexBHEVC::parseAndAddNALUnit Adding start/end " << curFrameFileStartEndPos->first << "/" << curFrameFileStartEndPos->second - << " - POC " << curFramePOC << (curFrameIsRandomAccess ? " - ra" : "")); + << " - POC " << curFramePOC << " layer " << curFrameLayerID + << (curFrameIsRandomAccess ? " - ra" : "")); else DEBUG_HEVC("ParserAnnexBHEVC::parseAndAddNALUnit Adding start/end NA/NA - POC " - << curFramePOC << (curFrameIsRandomAccess ? " - ra" : "")); + << curFramePOC << " layer " << curFrameLayerID + << (curFrameIsRandomAccess ? " - ra" : "")); } // The file ended return parseResult; @@ -345,7 +348,7 @@ ParserAnnexBHEVC::parseAndAddNALUnit(int else if (nalHEVC->header.nal_unit_type == hevc::NalType::SPS_NUT) { auto newSPS = std::make_shared(); - newSPS->parse(reader); + newSPS->parse(reader, nalHEVC->header); this->activeParameterSets.spsMap[newSPS->sps_seq_parameter_set_id] = newSPS; @@ -445,7 +448,8 @@ ParserAnnexBHEVC::parseAndAddNALUnit(int if (curFramePOC != -1) { // Save the info of the last frame - if (!this->addFrameToList(curFramePOC, curFrameFileStartEndPos, curFrameIsRandomAccess)) + if (!this->addFrameToList( + curFramePOC, curFrameFileStartEndPos, curFrameIsRandomAccess, curFrameLayerID)) { throw std::logic_error("Error - POC " + std::to_string(curFramePOC) + " alread in the POC list."); @@ -453,14 +457,17 @@ ParserAnnexBHEVC::parseAndAddNALUnit(int if (curFrameFileStartEndPos) DEBUG_HEVC("ParserAnnexBHEVC::parseAndAddNALUnit Adding start/end " << curFrameFileStartEndPos->first << "/" << curFrameFileStartEndPos->second - << " - POC " << curFramePOC << (curFrameIsRandomAccess ? " - ra" : "")); + << " - POC " << curFramePOC << curFramePOC << " layer " + << (curFrameIsRandomAccess ? " - ra" : "")); else DEBUG_HEVC("ParserAnnexBHEVC::parseAndAddNALUnit Adding start/end NA/NA - POC " - << curFramePOC << (curFrameIsRandomAccess ? " - ra" : "")); + << curFramePOC << curFramePOC << " layer " + << (curFrameIsRandomAccess ? " - ra" : "")); } curFrameFileStartEndPos = nalStartEndPosFile; curFramePOC = newSlice->sliceSegmentHeader.globalPOC; curFrameIsRandomAccess = nalHEVC->header.isIRAP(); + curFrameLayerID = nalHEVC->header.nuh_layer_id; { std::shared_ptr refSPS; diff --git a/YUViewLib/src/parser/HEVC/ParserAnnexBHEVC.h b/YUViewLib/src/parser/HEVC/ParserAnnexBHEVC.h index 9206e592a..0c72dac73 100644 --- a/YUViewLib/src/parser/HEVC/ParserAnnexBHEVC.h +++ b/YUViewLib/src/parser/HEVC/ParserAnnexBHEVC.h @@ -138,8 +138,9 @@ class ParserAnnexBHEVC : public ParserAnnexB // in case the frame has multiple NAL units // The POC of the current frame. We save this we encounter a NAL from the next POC; then we add // it. - int curFramePOC{-1}; - bool curFrameIsRandomAccess{false}; + int curFramePOC{-1}; + bool curFrameIsRandomAccess{false}; + unsigned curFrameLayerID{0}; hevc::AUDelimiterDetector auDelimiterDetector; diff --git a/YUViewLib/src/parser/HEVC/pic_parameter_set_rbsp.cpp b/YUViewLib/src/parser/HEVC/pic_parameter_set_rbsp.cpp index 094c3e720..3e3e0ebf5 100644 --- a/YUViewLib/src/parser/HEVC/pic_parameter_set_rbsp.cpp +++ b/YUViewLib/src/parser/HEVC/pic_parameter_set_rbsp.cpp @@ -115,7 +115,8 @@ void pic_parameter_set_rbsp::parse(SubByteReaderLogging &reader) this->pps_range_extension_flag = reader.readFlag("pps_range_extension_flag"); this->pps_multilayer_extension_flag = reader.readFlag("pps_multilayer_extension_flag"); this->pps_3d_extension_flag = reader.readFlag("pps_3d_extension_flag"); - this->pps_extension_5bits = reader.readBits("pps_extension_5bits", 5); + this->pps_scc_extension_flag = reader.readFlag("pps_scc_extension_flag"); + this->pps_extension_4bits = reader.readBits("pps_extension_4bits", 4); } // Now the extensions follow ... @@ -125,13 +126,16 @@ void pic_parameter_set_rbsp::parse(SubByteReaderLogging &reader) // This would also be interesting but later. if (this->pps_multilayer_extension_flag) - reader.logArbitrary("pps_multilayer_extension()", 0, "", "", "Not implemented yet..."); + this->ppsMultilayerExtension.parse(reader); if (this->pps_3d_extension_flag) - reader.logArbitrary("pps_3d_extension()", 0, "", "", "Not implemented yet..."); + this->pps3DExtension.parse(reader); - if (this->pps_extension_5bits != 0) - reader.logArbitrary("pps_extension_data_flag()", 0, "", "", "Not implemented yet..."); + if (this->pps_scc_extension_flag) + this->ppsSCCExtension.parse(reader); + + if (this->pps_extension_4bits != 0) + reader.logArbitrary("pps_extension_data_flag()", "", "", "", "Not implemented yet..."); // There is more to parse but we are not interested in this information (for now) // this->rbspTrailingBits.parse(reader); diff --git a/YUViewLib/src/parser/HEVC/pic_parameter_set_rbsp.h b/YUViewLib/src/parser/HEVC/pic_parameter_set_rbsp.h index 79062c71b..9abc0e962 100644 --- a/YUViewLib/src/parser/HEVC/pic_parameter_set_rbsp.h +++ b/YUViewLib/src/parser/HEVC/pic_parameter_set_rbsp.h @@ -32,11 +32,14 @@ #pragma once +#include "Extensions/pps_3d_extension.h" +#include "Extensions/pps_multilayer_extension.h" +#include "Extensions/pps_range_extension.h" +#include "Extensions/pps_scc_extension.h" #include "NalUnitHEVC.h" #include "parser/common/SubByteReaderLogging.h" -#include "pps_range_extension.h" -#include "scaling_list_data.h" #include "rbsp_trailing_bits.h" +#include "scaling_list_data.h" namespace parser::hevc { @@ -91,9 +94,13 @@ class pic_parameter_set_rbsp : public NalRBSP bool pps_range_extension_flag{}; bool pps_multilayer_extension_flag{}; bool pps_3d_extension_flag{}; - unsigned pps_extension_5bits{}; + bool pps_scc_extension_flag{}; + unsigned pps_extension_4bits{}; - pps_range_extension ppsRangeExtension; + pps_range_extension ppsRangeExtension{}; + pps_multilayer_extension ppsMultilayerExtension{}; + pps_3d_extension pps3DExtension{}; + pps_scc_extension ppsSCCExtension{}; rbsp_trailing_bits rbspTrailingBits; }; diff --git a/YUViewLib/src/parser/HEVC/seq_parameter_set_rbsp.cpp b/YUViewLib/src/parser/HEVC/seq_parameter_set_rbsp.cpp index 154b482b8..e9ffcb82a 100644 --- a/YUViewLib/src/parser/HEVC/seq_parameter_set_rbsp.cpp +++ b/YUViewLib/src/parser/HEVC/seq_parameter_set_rbsp.cpp @@ -41,62 +41,83 @@ namespace parser::hevc using namespace reader; -void seq_parameter_set_rbsp::parse(SubByteReaderLogging &reader) +void seq_parameter_set_rbsp::parse(SubByteReaderLogging & reader, + const nal_unit_header &nalUnitHeader) { SubByteReaderLoggingSubLevel subLevel(reader, "seq_parameter_set_rbsp()"); - this->sps_video_parameter_set_id = reader.readBits("sps_video_parameter_set_id", 4); - this->sps_max_sub_layers_minus1 = reader.readBits("sps_max_sub_layers_minus1", 3); - this->sps_temporal_id_nesting_flag = reader.readFlag("sps_temporal_id_nesting_flag"); + this->sps_video_parameter_set_id = reader.readBits("sps_video_parameter_set_id", 4); + if (nalUnitHeader.nuh_layer_id == 0) + this->sps_max_sub_layers_minus1 = reader.readBits("sps_max_sub_layers_minus1", 3); + else + this->sps_ext_or_max_sub_layers_minus1 = reader.readBits("sps_ext_or_max_sub_layers_minus1", 3); - // parse profile tier level - this->profileTierLevel.parse(reader, true, sps_max_sub_layers_minus1); + const auto MultiLayerExtSpsFlag = + (nalUnitHeader.nuh_layer_id != 0 && this->sps_ext_or_max_sub_layers_minus1 == 7); + if (!MultiLayerExtSpsFlag) + { + this->sps_temporal_id_nesting_flag = reader.readFlag("sps_temporal_id_nesting_flag"); + this->profileTierLevel.parse(reader, true, sps_max_sub_layers_minus1); + } - /// Back to the seq_parameter_set_rbsp this->sps_seq_parameter_set_id = reader.readUEV("sps_seq_parameter_set_id"); - this->chroma_format_idc = reader.readUEV( - "chroma_format_idc", - Options().withMeaningVector({"moochrome", "4:2:0", "4:2:2", "4:4:4", "4:4:4"})); - if (this->chroma_format_idc == 3) - this->separate_colour_plane_flag = reader.readFlag("separate_colour_plane_flag"); - this->ChromaArrayType = (this->separate_colour_plane_flag) ? 0 : this->chroma_format_idc; - reader.logCalculatedValue("ChromaArrayType", this->ChromaArrayType); - - // Rec. ITU-T H.265 v3 (04/2015) - 6.2 - Table 6-1 - this->SubWidthC = (this->chroma_format_idc == 1 || this->chroma_format_idc == 2) ? 2 : 1; - this->SubHeightC = (this->chroma_format_idc == 1) ? 2 : 1; - reader.logCalculatedValue("SubWidthC", this->SubWidthC); - reader.logCalculatedValue("SubHeightC", this->SubHeightC); - - this->pic_width_in_luma_samples = reader.readUEV("pic_width_in_luma_samples"); - this->pic_height_in_luma_samples = reader.readUEV("pic_height_in_luma_samples"); - this->conformance_window_flag = reader.readFlag("conformance_window_flag"); - - if (this->conformance_window_flag) + + if (MultiLayerExtSpsFlag) { - this->conf_win_left_offset = reader.readUEV("conf_win_left_offset"); - this->conf_win_right_offset = reader.readUEV("conf_win_right_offset"); - this->conf_win_top_offset = reader.readUEV("conf_win_top_offset"); - this->conf_win_bottom_offset = reader.readUEV("conf_win_bottom_offset"); + this->update_rep_format_flag = reader.readFlag("update_rep_format_flag"); + if (this->update_rep_format_flag) + this->sps_rep_format_idx = reader.readBits("sps_rep_format_idx", 8); + } + else + { + this->chroma_format_idc = reader.readUEV( + "chroma_format_idc", + Options().withMeaningVector({"moochrome", "4:2:0", "4:2:2", "4:4:4", "4:4:4"})); + if (this->chroma_format_idc == 3) + this->separate_colour_plane_flag = reader.readFlag("separate_colour_plane_flag"); + this->ChromaArrayType = (this->separate_colour_plane_flag) ? 0 : this->chroma_format_idc; + reader.logCalculatedValue("ChromaArrayType", this->ChromaArrayType); + + // Rec. ITU-T H.265 v3 (04/2015) - 6.2 - Table 6-1 + this->SubWidthC = (this->chroma_format_idc == 1 || this->chroma_format_idc == 2) ? 2 : 1; + this->SubHeightC = (this->chroma_format_idc == 1) ? 2 : 1; + reader.logCalculatedValue("SubWidthC", this->SubWidthC); + reader.logCalculatedValue("SubHeightC", this->SubHeightC); + + this->pic_width_in_luma_samples = reader.readUEV("pic_width_in_luma_samples"); + this->pic_height_in_luma_samples = reader.readUEV("pic_height_in_luma_samples"); + this->conformance_window_flag = reader.readFlag("conformance_window_flag"); + + if (this->conformance_window_flag) + { + this->conf_win_left_offset = reader.readUEV("conf_win_left_offset"); + this->conf_win_right_offset = reader.readUEV("conf_win_right_offset"); + this->conf_win_top_offset = reader.readUEV("conf_win_top_offset"); + this->conf_win_bottom_offset = reader.readUEV("conf_win_bottom_offset"); + } + + this->bit_depth_luma_minus8 = reader.readUEV("bit_depth_luma_minus8"); + this->bit_depth_chroma_minus8 = reader.readUEV("bit_depth_chroma_minus8"); } - this->bit_depth_luma_minus8 = reader.readUEV("bit_depth_luma_minus8"); - this->bit_depth_chroma_minus8 = reader.readUEV("bit_depth_chroma_minus8"); this->log2_max_pic_order_cnt_lsb_minus4 = reader.readUEV("log2_max_pic_order_cnt_lsb_minus4"); - this->sps_sub_layer_ordering_info_present_flag = - reader.readFlag("sps_sub_layer_ordering_info_present_flag"); - for (unsigned i = - (this->sps_sub_layer_ordering_info_present_flag ? 0 : this->sps_max_sub_layers_minus1); - i <= this->sps_max_sub_layers_minus1; - i++) + if (!MultiLayerExtSpsFlag) { - this->sps_max_dec_pic_buffering_minus1.push_back( - reader.readUEV(formatArray("sps_max_dec_pic_buffering_minus1", i))); - this->sps_max_num_reorder_pics.push_back( - reader.readUEV(formatArray("sps_max_num_reorder_pics", i))); - this->sps_max_latency_increase_plus1.push_back( - reader.readUEV(formatArray("sps_max_latency_increase_plus1", i))); + this->sps_sub_layer_ordering_info_present_flag = + reader.readFlag("sps_sub_layer_ordering_info_present_flag"); + for (unsigned i = + (this->sps_sub_layer_ordering_info_present_flag ? 0 : this->sps_max_sub_layers_minus1); + i <= this->sps_max_sub_layers_minus1; + i++) + { + this->sps_max_dec_pic_buffering_minus1.push_back( + reader.readUEV(formatArray("sps_max_dec_pic_buffering_minus1", i))); + this->sps_max_num_reorder_pics.push_back( + reader.readUEV(formatArray("sps_max_num_reorder_pics", i))); + this->sps_max_latency_increase_plus1.push_back( + reader.readUEV(formatArray("sps_max_latency_increase_plus1", i))); + } } this->log2_min_luma_coding_block_size_minus3 = @@ -171,22 +192,40 @@ void seq_parameter_set_rbsp::parse(SubByteReaderLogging &reader) this->sps_range_extension_flag = reader.readFlag("sps_range_extension_flag"); this->sps_multilayer_extension_flag = reader.readFlag("sps_multilayer_extension_flag"); this->sps_3d_extension_flag = reader.readFlag("sps_3d_extension_flag"); - this->sps_extension_5bits = reader.readBits("sps_extension_5bits", 5); + this->sps_scc_extension_flag = reader.readFlag("sps_scc_extension_flag"); + this->sps_extension_4bits = reader.readBits("sps_extension_4bits", 4); } // Now the extensions follow ... // This would also be interesting but later. if (this->sps_range_extension_flag) - reader.logArbitrary("sps_range_extension()", 0, "", "", "Not implemented yet..."); + this->rangeExtension.parse(reader); if (this->sps_multilayer_extension_flag) - reader.logArbitrary("sps_multilayer_extension()", 0, "", "", "Not implemented yet..."); + this->multilayerExtension.parse(reader); if (this->sps_3d_extension_flag) - reader.logArbitrary("sps_3d_extension()", 0, "", "", "Not implemented yet..."); + this->extension3D.parse(reader); + + if (this->sps_scc_extension_flag) + { + if (MultiLayerExtSpsFlag) + { + // For multiview, the bit depths would have to be obtained from the main SPS ... + // Is this even possible to combine SCC with Multiview? + reader.logArbitrary("sps_scc_extension()", "", "", "", "Not supported for Multiview..."); + } + else + { + this->sccExtension.parse(reader, + this->chroma_format_idc, + this->bit_depth_luma_minus8 + 8, + this->bit_depth_chroma_minus8 + 8); + } + } - if (this->sps_extension_5bits != 0) - reader.logArbitrary("sps_extension_data_flag()", 0, "", "", "Not implemented yet..."); + if (this->sps_extension_4bits != 0) + reader.logArbitrary("sps_extension_data_flag()", "", "", "", "Not implemented yet..."); // rbspTrailingBits.parse(reader); diff --git a/YUViewLib/src/parser/HEVC/seq_parameter_set_rbsp.h b/YUViewLib/src/parser/HEVC/seq_parameter_set_rbsp.h index b6058f792..63841fbd9 100644 --- a/YUViewLib/src/parser/HEVC/seq_parameter_set_rbsp.h +++ b/YUViewLib/src/parser/HEVC/seq_parameter_set_rbsp.h @@ -32,13 +32,17 @@ #pragma once +#include "Extensions/sps_3d_extension.h" +#include "Extensions/sps_multilayer_extension.h" +#include "Extensions/sps_range_extension.h" +#include "Extensions/sps_scc_extension.h" #include "NalUnitHEVC.h" #include "parser/common/SubByteReaderLogging.h" #include "profile_tier_level.h" +#include "rbsp_trailing_bits.h" #include "scaling_list_data.h" #include "st_ref_pic_set.h" #include "vui_parameters.h" -#include "rbsp_trailing_bits.h" namespace parser::hevc { @@ -48,7 +52,7 @@ class seq_parameter_set_rbsp : public NalRBSP public: seq_parameter_set_rbsp() {} - void parse(reader::SubByteReaderLogging &reader); + void parse(reader::SubByteReaderLogging &reader, const nal_unit_header &nalUnitHeader); unsigned sps_video_parameter_set_id{}; unsigned sps_max_sub_layers_minus1{}; @@ -110,7 +114,8 @@ class seq_parameter_set_rbsp : public NalRBSP bool sps_range_extension_flag{}; bool sps_multilayer_extension_flag{}; bool sps_3d_extension_flag{}; - unsigned sps_extension_5bits{}; + bool sps_scc_extension_flag{}; + unsigned sps_extension_4bits{}; rbsp_trailing_bits rbspTrailingBits; @@ -124,6 +129,16 @@ class seq_parameter_set_rbsp : public NalRBSP unsigned PicHeightInCtbsY{}; unsigned PicSizeInCtbsY{}; + // Annex F.7.3.2.2.1 + unsigned sps_ext_or_max_sub_layers_minus1{}; + bool update_rep_format_flag{}; + unsigned sps_rep_format_idx{}; + + sps_range_extension rangeExtension{}; + sps_multilayer_extension multilayerExtension{}; + sps_3d_extension extension3D{}; + sps_scc_extension sccExtension{}; + // Get the actual size of the image that will be returned. Internally the image might be bigger. unsigned get_conformance_cropping_width() const { diff --git a/YUViewLib/src/parser/HEVC/slice_segment_header.cpp b/YUViewLib/src/parser/HEVC/slice_segment_header.cpp index 216958004..d42219be7 100644 --- a/YUViewLib/src/parser/HEVC/slice_segment_header.cpp +++ b/YUViewLib/src/parser/HEVC/slice_segment_header.cpp @@ -33,11 +33,10 @@ #include "slice_segment_header.h" #include "parser/common/CodingEnum.h" -#include #include "pic_parameter_set_rbsp.h" #include "seq_parameter_set_rbsp.h" #include "slice_segment_layer_rbsp.h" - +#include #include @@ -56,7 +55,10 @@ static parser::CodingEnum sliceTypeCoding({{0, SliceType::B, "B", "B- using namespace reader; -std::string to_string(SliceType sliceType) { return sliceTypeCoding.getMeaning(sliceType); } +std::string to_string(SliceType sliceType) +{ + return sliceTypeCoding.getMeaning(sliceType); +} void slice_segment_header::parse(SubByteReaderLogging & reader, bool firstAUInDecodingOrder, @@ -95,7 +97,18 @@ void slice_segment_header::parse(SubByteReaderLogging & reader, if (!dependent_slice_segment_flag) { - for (unsigned int i = 0; i < pps->num_extra_slice_header_bits; i++) + unsigned i = 0; + if (pps->num_extra_slice_header_bits > i) + { + i++; + this->discardable_flag = reader.readFlag("discardable_flag"); + } + if (pps->num_extra_slice_header_bits > i) + { + i++; + this->cross_layer_bla_flag = reader.readFlag("cross_layer_bla_flag"); + } + for (; i < pps->num_extra_slice_header_bits; i++) this->slice_reserved_flag.push_back(reader.readFlag(formatArray("slice_reserved_flag", i))); auto sliceTypeIdx = reader.readUEV( @@ -148,7 +161,8 @@ void slice_segment_header::parse(SubByteReaderLogging & reader, this->lt_idx_sps[i] = reader.readBits(formatArray("lt_idx_sps", i), nrBits); } - this->UsedByCurrPicLt.push_back(sps->used_by_curr_pic_lt_sps_flag[this->lt_idx_sps[i]]); + this->UsedByCurrPicLt.push_back( + sps->used_by_curr_pic_lt_sps_flag.at(this->lt_idx_sps[i])); } else { @@ -171,6 +185,12 @@ void slice_segment_header::parse(SubByteReaderLogging & reader, this->slice_temporal_mvp_enabled_flag = reader.readFlag("slice_temporal_mvp_enabled_flag"); } + // This is not 100% done yet. + // if (nalUnitHeader.nuh_layer_id > 0 && !default_ref_layers_active_flag && + // NumDirectRefLayers[nuh_layer_id] > 0) + // { + // } + if (sps->sample_adaptive_offset_enabled_flag) { this->slice_sao_luma_flag = reader.readFlag("slice_sao_luma_flag"); diff --git a/YUViewLib/src/parser/HEVC/slice_segment_header.h b/YUViewLib/src/parser/HEVC/slice_segment_header.h index 438ed15b7..0b301af60 100644 --- a/YUViewLib/src/parser/HEVC/slice_segment_header.h +++ b/YUViewLib/src/parser/HEVC/slice_segment_header.h @@ -75,6 +75,8 @@ class slice_segment_header bool dependent_slice_segment_flag{}; unsigned slice_pic_parameter_set_id{}; unsigned slice_segment_address{}; + bool discardable_flag{}; + bool cross_layer_bla_flag{}; vector slice_reserved_flag; SliceType slice_type{}; bool pic_output_flag{true}; diff --git a/YUViewLib/src/parser/HEVC/video_parameter_set_rbsp.cpp b/YUViewLib/src/parser/HEVC/video_parameter_set_rbsp.cpp index 7ac4d9976..0730c70e7 100644 --- a/YUViewLib/src/parser/HEVC/video_parameter_set_rbsp.cpp +++ b/YUViewLib/src/parser/HEVC/video_parameter_set_rbsp.cpp @@ -68,13 +68,16 @@ void video_parameter_set_rbsp::parse(SubByteReaderLogging &reader) } this->vps_max_layer_id = reader.readBits("vps_max_layer_id", 6); + this->vps_num_layer_sets_minus1 = reader.readUEV("vps_num_layer_sets_minus1", Options().withCheckRange({0, 1023})); for (unsigned int i = 1; i <= this->vps_num_layer_sets_minus1; i++) for (unsigned int j = 0; j <= this->vps_max_layer_id; j++) - this->layer_id_included_flag->push_back( - reader.readFlag(formatArray("layer_id_included_flag", i))); + this->layer_id_included_flag[i][j] = + reader.readFlag(formatArray("layer_id_included_flag", i, j)); + + this->calculateValues7_3(); this->vps_timing_info_present_flag = reader.readFlag("vps_timing_info_present_flag"); if (this->vps_timing_info_present_flag) @@ -98,7 +101,6 @@ void video_parameter_set_rbsp::parse(SubByteReaderLogging &reader) else this->cprms_present_flag.push_back(reader.readFlag(formatArray("cprms_present_flag", i))); - // hrd_parameters... hrd_parameters hrdParameters; hrdParameters.parse(reader, cprms_present_flag[i], vps_max_sub_layers_minus1); this->vps_hrd_parameters.push_back(hrdParameters); @@ -110,15 +112,44 @@ void video_parameter_set_rbsp::parse(SubByteReaderLogging &reader) this->vps_extension_flag = reader.readFlag("vps_extension_flag"); if (vps_extension_flag) - reader.logArbitrary("vps_extension()", "", "", "", "Not implemented yet..."); + { + while (!reader.byte_aligned()) + reader.readFlag("vps_extension_alignment_bit_equal_to_one", Options().withCheckEqualTo(1)); + + vpsExtension.parse(reader, + this->vps_max_layers_minus1, + this->vps_base_layer_internal_flag, + this->vps_max_sub_layers_minus1, + this->vps_num_layer_sets_minus1, + this->vps_num_hrd_parameters, + this->NumLayersInIdList, + this->LayerSetLayerIdList); + + this->vps_extension2_flag = reader.readFlag("vps_extension2_flag"); + if (this->vps_extension2_flag) + { + while (reader.more_rbsp_data()) + reader.readFlag("vps_extension_data_flag"); + } + } - // TODO: - // Here comes the VPS extension. - // This is specified in the annex F, multilayer and stuff. - // This could be added and is definitely interesting. - // ... later + rbspTrailingBits.parse(reader); +} + +void video_parameter_set_rbsp::calculateValues7_3() +{ + this->NumLayersInIdList[0] = 1; + this->LayerSetLayerIdList[0][0] = 0; - // rbspTrailingBits.parse(reader); + for (unsigned i = 1; i <= this->vps_num_layer_sets_minus1; i++) + { + auto n = 0u; + for (unsigned m = 0; m <= this->vps_max_layer_id; m++) + if (this->layer_id_included_flag.count(i) == 1 && + this->layer_id_included_flag.at(i).count(m) == 1 && this->layer_id_included_flag[i][m]) + this->LayerSetLayerIdList[i][n++] = m; + this->NumLayersInIdList[i] = n; + } } -} // namespace parser::hevc \ No newline at end of file +} // namespace parser::hevc diff --git a/YUViewLib/src/parser/HEVC/video_parameter_set_rbsp.h b/YUViewLib/src/parser/HEVC/video_parameter_set_rbsp.h index bb379888c..b93f698a4 100644 --- a/YUViewLib/src/parser/HEVC/video_parameter_set_rbsp.h +++ b/YUViewLib/src/parser/HEVC/video_parameter_set_rbsp.h @@ -32,10 +32,11 @@ #pragma once +#include "Extensions/vps_extension.h" +#include "NalUnitHEVC.h" #include "hrd_parameters.h" #include "parser/common/SubByteReaderLogging.h" #include "profile_tier_level.h" -#include "NalUnitHEVC.h" #include "rbsp_trailing_bits.h" namespace parser::hevc @@ -59,13 +60,17 @@ class video_parameter_set_rbsp : public NalRBSP profile_tier_level profileTierLevel; - bool vps_sub_layer_ordering_info_present_flag{}; - unsigned vps_max_dec_pic_buffering_minus1[7]{}; - unsigned vps_max_num_reorder_pics[7]{}; - unsigned vps_max_latency_increase_plus1[7]{}; - unsigned vps_max_layer_id{}; - unsigned vps_num_layer_sets_minus1{}; - vector layer_id_included_flag[7]{}; + bool vps_sub_layer_ordering_info_present_flag{}; + unsigned vps_max_dec_pic_buffering_minus1[7]{}; + unsigned vps_max_num_reorder_pics[7]{}; + unsigned vps_max_latency_increase_plus1[7]{}; + unsigned vps_max_layer_id{}; + unsigned vps_num_layer_sets_minus1{}; + umap_2d layer_id_included_flag{}; + + void calculateValues7_3(); + umap_2d LayerSetLayerIdList; + umap_1d NumLayersInIdList; bool vps_timing_info_present_flag{}; unsigned vps_num_units_in_tick{}; @@ -78,6 +83,8 @@ class video_parameter_set_rbsp : public NalRBSP vector vps_hrd_parameters; bool vps_extension_flag{}; + vps_extension vpsExtension{}; + bool vps_extension2_flag{}; rbsp_trailing_bits rbspTrailingBits; diff --git a/YUViewLib/src/parser/ParserAnnexB.cpp b/YUViewLib/src/parser/ParserAnnexB.cpp index c02ebd74a..80b842dc7 100644 --- a/YUViewLib/src/parser/ParserAnnexB.cpp +++ b/YUViewLib/src/parser/ParserAnnexB.cpp @@ -62,10 +62,11 @@ std::string ParserAnnexB::getShortStreamDescription(const int) const bool ParserAnnexB::addFrameToList(int poc, std::optional fileStartEndPos, - bool randomAccessPoint) + bool randomAccessPoint, + unsigned layerID) { for (const auto &f : this->frameListCodingOrder) - if (f.poc == poc) + if (f.poc == poc && f.layerID == layerID) return false; if (!this->pocOfFirstRandomAccessFrame && randomAccessPoint) @@ -77,6 +78,7 @@ bool ParserAnnexB::addFrameToList(int poc, newFrame.poc = poc; newFrame.fileStartEndPos = fileStartEndPos; newFrame.randomAccessPoint = randomAccessPoint; + newFrame.layerID = layerID; this->frameListCodingOrder.push_back(newFrame); this->frameListDisplayOder.clear(); } diff --git a/YUViewLib/src/parser/ParserAnnexB.h b/YUViewLib/src/parser/ParserAnnexB.h index 8b0f092f5..2f0d45fbc 100644 --- a/YUViewLib/src/parser/ParserAnnexB.h +++ b/YUViewLib/src/parser/ParserAnnexB.h @@ -137,17 +137,20 @@ class ParserAnnexB : public Parser struct AnnexBFrame { AnnexBFrame() = default; - int poc{-1}; //< The poc of this frame - std::optional - fileStartEndPos; //< The start and end position of all slice NAL units (if known) - bool randomAccessPoint{false}; //< Can we start decoding here? + int poc{-1}; + std::optional fileStartEndPos; + bool randomAccessPoint{false}; + unsigned layerID{}; bool operator<(AnnexBFrame const &b) const { return (this->poc < b.poc); } bool operator==(AnnexBFrame const &b) const { return (this->poc == b.poc); } }; // Returns false if the POC was already present int the list - bool addFrameToList(int poc, std::optional fileStartEndPos, bool randomAccessPoint); + bool addFrameToList(int poc, + std::optional fileStartEndPos, + bool randomAccessPoint, + unsigned layerID); static void logNALSize(const ByteVector & data, std::shared_ptr root, diff --git a/YUViewLib/src/parser/VVC/ParserAnnexBVVC.cpp b/YUViewLib/src/parser/VVC/ParserAnnexBVVC.cpp index 5a10abec6..0a6b6a150 100644 --- a/YUViewLib/src/parser/VVC/ParserAnnexBVVC.cpp +++ b/YUViewLib/src/parser/VVC/ParserAnnexBVVC.cpp @@ -473,6 +473,7 @@ ParserAnnexBVVC::parseAndAddNALUnit(int nalVVC->rbsp = newSliceLayer; + updatedParsingState.currentAU.layerID = nalVVC->header.nuh_layer_id; updatedParsingState.currentAU.isKeyframe = (nalType == NalType::IDR_W_RADL || nalType == NalType::IDR_N_LP || nalType == NalType::CRA_NUT); @@ -596,22 +597,25 @@ int ParserAnnexBVVC::calculateAndUpdateGlobalPOC(bool isIRAP, unsigned PicOrderC bool ParserAnnexBVVC::handleNewAU(ParsingState &parsingState) { - DEBUG_VVC("Start of new AU. Adding bitrate " << parsingState.currentAU.sizeBytes << " POC " - << parsingState.currentAU.poc << " AU " - << parsingState.currentAU.counter); + DEBUG_VVC("Start of new AU. Adding bitrate " + << parsingState.currentAU.sizeBytes << " POC " << parsingState.currentAU.poc << " AU " + << parsingState.currentAU.counter << " Layer " << parsingState.currentAU.layerID); if (!this->addFrameToList(parsingState.currentAU.poc, parsingState.currentAU.fileStartEndPos, - parsingState.currentAU.isKeyframe)) + parsingState.currentAU.isKeyframe, + parsingState.currentAU.layerID)) return false; if (this->parsingState.currentAU.fileStartEndPos) DEBUG_VVC("Adding start/end " << parsingState.currentAU.fileStartEndPos->first << "/" << parsingState.currentAU.fileStartEndPos->second << " - AU " - << parsingState.currentAU.counter + << parsingState.currentAU.counter << " Layer " + << parsingState.currentAU.layerID << (parsingState.currentAU.isKeyframe ? " - ra" : "")); else - DEBUG_VVC("Adding start/end NA/NA - AU " << parsingState.currentAU.counter + DEBUG_VVC("Adding start/end NA/NA - AU " << parsingState.currentAU.counter << " Layer " + << parsingState.currentAU.layerID << (parsingState.currentAU.isKeyframe ? " - ra" : "")); return true; diff --git a/YUViewLib/src/parser/VVC/ParserAnnexBVVC.h b/YUViewLib/src/parser/VVC/ParserAnnexBVVC.h index 86eafe10a..43edf03ef 100644 --- a/YUViewLib/src/parser/VVC/ParserAnnexBVVC.h +++ b/YUViewLib/src/parser/VVC/ParserAnnexBVVC.h @@ -65,6 +65,7 @@ struct ParsingState size_t counter{}; size_t sizeBytes{}; int poc{-1}; + unsigned layerID{0}; bool isKeyframe{}; std::optional fileStartEndPos; }; diff --git a/YUViewLib/src/parser/common/Functions.h b/YUViewLib/src/parser/common/Functions.h index 1b96f11a7..eec0a0484 100644 --- a/YUViewLib/src/parser/common/Functions.h +++ b/YUViewLib/src/parser/common/Functions.h @@ -41,22 +41,24 @@ namespace parser { -template std::string formatArray(std::string variableName, T idx) +namespace { - return variableName + "[" + std::to_string(idx) + "]"; + +template std::string formatArrayArguments(T variable) +{ + return "[" + std::to_string(variable) + "]"; } -template -std::string formatArray(std::string variableName, T1 idx1, T2 idx2) +template std::string formatArrayArguments(T first, Args... args) { - return variableName + "[" + std::to_string(idx1) + "][" + std::to_string(idx2) + "]"; + return "[" + std::to_string(first) + "]" + formatArrayArguments(args...); } -template -std::string formatArray(std::string variableName, T1 idx1, T2 idx2, T3 idx3) +} // namespace + +template std::string formatArray(std::string variableName, Args... args) { - return variableName + "[" + std::to_string(idx1) + "][" + std::to_string(idx2) + "][" + - std::to_string(idx3) + "]"; + return variableName + formatArrayArguments(args...); } std::string convertSliceCountsToString(const std::map &sliceCounts);