Skip to content

Commit

Permalink
VPS extensions finished
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristianFeldmann committed Feb 22, 2024
1 parent 298ed36 commit d1b78b9
Show file tree
Hide file tree
Showing 9 changed files with 459 additions and 6 deletions.
51 changes: 51 additions & 0 deletions YUViewLib/src/parser/HEVC/Extensions/video_signal_info.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/* This file is part of YUView - The YUV player with advanced analytics toolset
* <https://github.com/IENT/YUView>
* 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 <http:https://www.gnu.org/licenses/>.
*/

#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
55 changes: 55 additions & 0 deletions YUViewLib/src/parser/HEVC/Extensions/video_signal_info.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/* This file is part of YUView - The YUV player with advanced analytics toolset
* <https://github.com/IENT/YUView>
* 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 <http:https://www.gnu.org/licenses/>.
*/

#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
18 changes: 16 additions & 2 deletions YUViewLib/src/parser/HEVC/Extensions/vps_extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ 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_layer_sets_minus1,
const unsigned vps_num_hrd_parameters)
{
SubByteReaderLoggingSubLevel subLevel(reader, "vps_extension()");

Expand Down Expand Up @@ -270,7 +271,20 @@ void vps_extension::parse(SubByteReaderLogging &reader,
{
while (!reader.byte_aligned())
reader.readFlag("vps_vui_alignment_bit_equal_to_one", Options().withCheckEqualTo(0));
vpsVui.parse(reader, this->vps_vui_present_flag);
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);
}
}

Expand Down
3 changes: 2 additions & 1 deletion YUViewLib/src/parser/HEVC/Extensions/vps_extension.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ class vps_extension
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_layer_sets_minus1,
const unsigned vps_num_hrd_parameters);

profile_tier_level profileTierLevel;
bool splitting_flag{};
Expand Down
118 changes: 117 additions & 1 deletion YUViewLib/src/parser/HEVC/Extensions/vps_vui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,27 @@

#include "vps_vui.h"

#include <parser/common/Functions.h>

namespace parser::hevc
{

using namespace reader;

void vps_vui::parse(SubByteReaderLogging &reader, const bool vps_vui_present_flag)
void vps_vui::parse(SubByteReaderLogging & reader,
const bool vps_vui_present_flag,
const bool vps_base_layer_internal_flag,
const unsigned NumLayerSets,
const vector<unsigned> & MaxSubLayersInLayerSetMinus1,
const unsigned MaxLayersMinus1,
const umap_1d<unsigned> &NumDirectRefLayers,
const vector<unsigned> & layer_id_in_nuh,
const umap_1d<unsigned> &LayerIdxInVps,
const umap_2d<unsigned> &IdDirectRefLayer,
const unsigned vps_num_hrd_parameters,
const unsigned NumOutputLayerSets,
const umap_1d<unsigned> &NumLayersInIdList,
const umap_1d<unsigned> &OlsIdxToLsIdx)
{
SubByteReaderLoggingSubLevel subLevel(reader, "vps_vui()");

Expand All @@ -53,7 +68,108 @@ void vps_vui::parse(SubByteReaderLogging &reader, const bool vps_vui_present_fla

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[i]); j++)
{
const auto layerIdx = LayerIdxInVps.at(IdDirectRefLayer.at(layer_id_in_nuh[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[i]); j++)
{
if (vps_base_layer_internal_flag || IdDirectRefLayer.at(layer_id_in_nuh[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[i]) == 0)
this->base_layer_parameter_set_compatibility_flag[i] =
reader.readFlag(formatArray("base_layer_parameter_set_compatibility_flag", i));
}

} // namespace parser::hevc
50 changes: 49 additions & 1 deletion YUViewLib/src/parser/HEVC/Extensions/vps_vui.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
#pragma once

#include "parser/common/SubByteReaderLogging.h"
#include "video_signal_info.h"
#include "vps_vui_bsp_hrd_params.h"

namespace parser::hevc
{
Expand All @@ -43,13 +45,59 @@ class vps_vui
public:
vps_vui() {}

void parse(reader::SubByteReaderLogging &reader, const bool vps_vui_present_flag);
void parse(reader::SubByteReaderLogging &reader,
const bool vps_vui_present_flag,
const bool vps_base_layer_internal_flag,
const unsigned NumLayerSets,
const vector<unsigned> & MaxSubLayersInLayerSetMinus1,
const unsigned MaxLayersMinus1,
const umap_1d<unsigned> & NumDirectRefLayers,
const vector<unsigned> & layer_id_in_nuh,
const umap_1d<unsigned> & LayerIdxInVps,
const umap_2d<unsigned> & IdDirectRefLayer,
const unsigned vps_num_hrd_parameters,
const unsigned NumOutputLayerSets,
const umap_1d<unsigned> & NumLayersInIdList,
const umap_1d<unsigned> & 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<bool> bit_rate_present_flag;
umap_2d<bool> pic_rate_present_flag;
umap_2d<unsigned> avg_bit_rate;
umap_2d<unsigned> max_bit_rate;
umap_2d<unsigned> constant_pic_rate_idc;
umap_2d<unsigned> avg_pic_rate;

bool video_signal_info_idx_present_flag{};
unsigned vps_num_video_signal_info_minus1{};
vector<video_signal_info> videoSignalInfoList;

umap_1d<unsigned> vps_video_signal_info_idx;

bool tiles_not_in_use_flag{};
umap_1d<bool> tiles_in_use_flag;
umap_1d<bool> loop_filter_not_across_tiles_flag;
umap_2d<bool> tile_boundaries_aligned_flag;

bool wpp_not_in_use_flag{};
umap_1d<bool> 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<unsigned> min_spatial_segment_offset_plus1;
umap_2d<bool> ctu_based_offset_enabled_flag;
umap_2d<unsigned> min_horizontal_ctu_offset_plus1;

bool vps_vui_bsp_hrd_present_flag{};
vps_vui_bsp_hrd_params vpsVuiBspHrdParams{};

umap_1d<bool> base_layer_parameter_set_compatibility_flag;
};

} // namespace parser::hevc
Loading

0 comments on commit d1b78b9

Please sign in to comment.