This source file includes following definitions.
- read_depth_rep_info_element
- read_depth_representation_info
- decode_hevc_aux_sei_messages
- remove_start_code_emulation
- parse_sps_for_hvcC_configuration
#include <assert.h>
#include <math.h>
#include "heif_hevc.h"
#include "bitstream.h"
using namespace heif;
static double read_depth_rep_info_element(BitReader& reader)
{
int sign_flag = reader.get_bits(1);
int exponent = reader.get_bits(7);
int mantissa_len = reader.get_bits(5)+1;
if (mantissa_len<1 || mantissa_len>32) {
}
if (exponent==127) {
}
int mantissa = reader.get_bits(mantissa_len);
double value;
if (exponent > 0) {
value = pow(2, exponent-31) * (1.0 + mantissa / pow(2,mantissa_len));
}
else {
value = pow(2, -(30+mantissa_len)) * mantissa;
}
if (sign_flag) {
value = -value;
}
return value;
}
static std::shared_ptr<SEIMessage> read_depth_representation_info(BitReader& reader)
{
auto msg = std::make_shared<SEIMessage_depth_representation_info>();
msg->version = 1;
msg->disparity_reference_view = 0;
msg->depth_nonlinear_representation_model_size = 0;
msg->depth_nonlinear_representation_model = nullptr;
msg->has_z_near = (uint8_t)reader.get_bits(1);
msg->has_z_far = (uint8_t)reader.get_bits(1);
msg->has_d_min = (uint8_t)reader.get_bits(1);
msg->has_d_max = (uint8_t)reader.get_bits(1);
int rep_type;
if (!reader.get_uvlc(&rep_type)) {
}
msg->depth_representation_type = (enum heif_depth_representation_type)rep_type;
if (msg->has_d_min || msg->has_d_max) {
int ref_view;
if (!reader.get_uvlc(&ref_view)) {
}
msg->disparity_reference_view = ref_view;
}
if (msg->has_z_near) msg->z_near = read_depth_rep_info_element(reader);
if (msg->has_z_far ) msg->z_far = read_depth_rep_info_element(reader);
if (msg->has_d_min ) msg->d_min = read_depth_rep_info_element(reader);
if (msg->has_d_max ) msg->d_max = read_depth_rep_info_element(reader);
if (msg->depth_representation_type == heif_depth_representation_type_nonuniform_disparity) {
}
return msg;
}
Error heif::decode_hevc_aux_sei_messages(const std::vector<uint8_t>& data,
std::vector<std::shared_ptr<SEIMessage>>& msgs)
{
BitReader reader(data.data(), (int)data.size());
uint32_t len = (uint32_t)reader.get_bits(32);
if (len > data.size()-4) {
}
while (reader.get_current_byte_index() < (int)len) {
int currPos = reader.get_current_byte_index();
BitReader sei_reader(data.data() + currPos, (int)data.size()-currPos);
uint32_t nal_size = (uint32_t)sei_reader.get_bits(32);
(void)nal_size;
uint8_t nal_type = (uint8_t)(sei_reader.get_bits(8) >> 1);
sei_reader.skip_bits(8);
if (nal_type == 39 ||
nal_type == 40) {
uint8_t payload_id = (uint8_t)(sei_reader.get_bits(8));
uint8_t payload_size = (uint8_t)(sei_reader.get_bits(8));
(void)payload_size;
switch (payload_id) {
case 177:
std::shared_ptr<SEIMessage> sei = read_depth_representation_info(sei_reader);
msgs.push_back(sei);
break;
}
}
break;
}
return Error::Ok;
}
static std::vector<uint8_t> remove_start_code_emulation(const uint8_t* sps, size_t size)
{
std::vector<uint8_t> out_data;
for (size_t i=0;i<size;i++) {
if (i+2<size &&
sps[i ] == 0 &&
sps[i+1] == 0 &&
sps[i+2] == 3) {
out_data.push_back(0);
out_data.push_back(0);
i+=2;
}
else {
out_data.push_back(sps[i]);
}
}
return out_data;
}
Error heif::parse_sps_for_hvcC_configuration(const uint8_t* sps, size_t size,
Box_hvcC::configuration* config,
int* width, int* height)
{
std::vector<uint8_t> sps_no_emul = remove_start_code_emulation(sps, size);
sps = sps_no_emul.data();
size = sps_no_emul.size();
BitReader reader(sps, (int)size);
reader.skip_bits(2*8);
reader.skip_bits(4);
int nMaxSubLayersMinus1 = reader.get_bits(3);
config->temporal_id_nested = (uint8_t)reader.get_bits(1);
config->general_profile_space = (uint8_t)reader.get_bits(2);
config->general_tier_flag = (uint8_t)reader.get_bits(1);
config->general_profile_idc = (uint8_t)reader.get_bits(5);
config->general_profile_compatibility_flags = reader.get_bits(32);
reader.skip_bits(16);
reader.skip_bits(16);
reader.skip_bits(16);
config->general_level_idc = (uint8_t)reader.get_bits(8);
std::vector<bool> layer_profile_present(nMaxSubLayersMinus1);
std::vector<bool> layer_level_present(nMaxSubLayersMinus1);
for (int i=0 ; i<nMaxSubLayersMinus1 ; i++) {
layer_profile_present[i] = reader.get_bits(1);
layer_level_present[i] = reader.get_bits(1);
}
for (int i=0 ; i<nMaxSubLayersMinus1 ; i++) {
if (layer_profile_present[i]) {
reader.skip_bits(2+1+5);
reader.skip_bits(32);
reader.skip_bits(16);
}
if (layer_level_present[i]) {
reader.skip_bits(8);
}
}
int dummy, value;
reader.get_uvlc(&dummy);
reader.get_uvlc(&value);
config->chroma_format = (uint8_t)value;
if (config->chroma_format==3) {
reader.skip_bits(1);
}
reader.get_uvlc(width);
reader.get_uvlc(height);
bool conformance_window = reader.get_bits(1);
if (conformance_window) {
int left,right,top,bottom;
reader.get_uvlc(&left);
reader.get_uvlc(&right);
reader.get_uvlc(&top);
reader.get_uvlc(&bottom);
*width -= 2*(left+right);
*height -= 2*(top+bottom);
}
reader.get_uvlc(&value);
config->bit_depth_luma = (uint8_t)(value + 8);
reader.get_uvlc(&value);
config->bit_depth_chroma = (uint8_t)(value + 8);
config->configuration_version = 1;
config->min_spatial_segmentation_idc = 0;
config->parallelism_type = 0;
config->avg_frame_rate = 0;
config->constant_frame_rate = 0;
config->num_temporal_layers = 1;
return Error::Ok;
}