Fix incorrect HEVC decoder configuration data
When transmuxing from TS to MP4 if there is emulation prevention bytes in general_profile_tier_level_data. Fixes #312 Change-Id: I48857046c1ea4bed4f455d03d060551e3ef4bec8
This commit is contained in:
parent
5d5cb8678d
commit
858fcd8698
|
@ -51,9 +51,8 @@ bool H265ByteToUnitStreamConverter::GetDecoderConfigurationRecord(
|
||||||
// (4) general_profile_compatibility_flags
|
// (4) general_profile_compatibility_flags
|
||||||
// (6) general_constraint_indicator_flags
|
// (6) general_constraint_indicator_flags
|
||||||
// (1) general_level_idc
|
// (1) general_level_idc
|
||||||
// Skip Nalu header (2) and the first byte of the SPS to get the
|
for (int byte : sps->general_profile_tier_level_data)
|
||||||
// profile_tier_level.
|
buffer.AppendInt(static_cast<uint8_t>(byte));
|
||||||
buffer.AppendArray(&last_sps_[2+1], 12);
|
|
||||||
|
|
||||||
// The default value for this field is 0, which is Unknown.
|
// The default value for this field is 0, which is Unknown.
|
||||||
int min_spatial_segmentation_idc =
|
int min_spatial_segmentation_idc =
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const char kExpectedConfigRecord[] =
|
const char kExpectedConfigRecord[] =
|
||||||
"01016000000300900000030000f000fcfdf8f800000303a00001001840010c01ffff01"
|
"0101600000009000000000005df000fcfdf8f800000303a00001001840010c01ffff01"
|
||||||
"600000030090000003000003005d999809a10001002e42010101600000030090000003"
|
"600000030090000003000003005d999809a10001002e42010101600000030090000003"
|
||||||
"000003005da0028080241f265999a4932bffc0d5c0d64040000003004000000602a200"
|
"000003005da0028080241f265999a4932bffc0d5c0d64040000003004000000602a200"
|
||||||
"0100074401c172b46240";
|
"0100074401c172b46240";
|
||||||
|
|
|
@ -518,7 +518,8 @@ H265Parser::Result H265Parser::ParseSps(const Nalu& nalu, int* sps_id) {
|
||||||
TRUE_OR_RETURN(br->ReadBits(3, &sps->max_sub_layers_minus1));
|
TRUE_OR_RETURN(br->ReadBits(3, &sps->max_sub_layers_minus1));
|
||||||
TRUE_OR_RETURN(br->ReadBool(&sps->temporal_id_nesting_flag));
|
TRUE_OR_RETURN(br->ReadBool(&sps->temporal_id_nesting_flag));
|
||||||
|
|
||||||
OK_OR_RETURN(SkipProfileTierLevel(true, sps->max_sub_layers_minus1, br));
|
OK_OR_RETURN(
|
||||||
|
ReadProfileTierLevel(true, sps->max_sub_layers_minus1, br, sps.get()));
|
||||||
|
|
||||||
TRUE_OR_RETURN(br->ReadUE(&sps->seq_parameter_set_id));
|
TRUE_OR_RETURN(br->ReadUE(&sps->seq_parameter_set_id));
|
||||||
TRUE_OR_RETURN(br->ReadUE(&sps->chroma_format_idc));
|
TRUE_OR_RETURN(br->ReadUE(&sps->chroma_format_idc));
|
||||||
|
@ -947,24 +948,27 @@ H265Parser::Result H265Parser::SkipPredictionWeightTable(
|
||||||
return kOk;
|
return kOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
H265Parser::Result H265Parser::SkipProfileTierLevel(
|
H265Parser::Result H265Parser::ReadProfileTierLevel(
|
||||||
bool profile_present,
|
bool profile_present,
|
||||||
int max_num_sub_layers_minus1,
|
int max_num_sub_layers_minus1,
|
||||||
H26xBitReader* br) {
|
H26xBitReader* br,
|
||||||
|
H265Sps* sps) {
|
||||||
// Reads whole element, ignores it.
|
// Reads whole element, ignores it.
|
||||||
|
|
||||||
if (profile_present) {
|
if (profile_present) {
|
||||||
// general_profile_space, general_tier_flag, general_profile_idc
|
// 11 bytes of general_profile_tier flags:
|
||||||
// general_profile_compativility_flag
|
// general_profile_space, general_tier_flag, general_profile_idc
|
||||||
// general_progressive_source_flag
|
// general_profile_compativility_flag
|
||||||
// general_interlaced_source_flag
|
// general_progressive_source_flag
|
||||||
// general_non_packed_constraint_flag
|
// general_interlaced_source_flag
|
||||||
// general_frame_only_constraint_flag
|
// general_non_packed_constraint_flag
|
||||||
// 44-bits of other flags
|
// general_frame_only_constraint_flag
|
||||||
TRUE_OR_RETURN(br->SkipBits(2 + 1 + 5 + 32 + 4 + 44));
|
// 44-bits of other flags
|
||||||
|
for (int i = 0; i < 11; i++)
|
||||||
|
TRUE_OR_RETURN(br->ReadBits(8, &sps->general_profile_tier_level_data[i]));
|
||||||
}
|
}
|
||||||
|
// general_level_idc
|
||||||
TRUE_OR_RETURN(br->SkipBits(8)); // general_level_idc
|
TRUE_OR_RETURN(br->ReadBits(8, &sps->general_profile_tier_level_data[11]));
|
||||||
|
|
||||||
std::vector<bool> sub_layer_profile_present(max_num_sub_layers_minus1);
|
std::vector<bool> sub_layer_profile_present(max_num_sub_layers_minus1);
|
||||||
std::vector<bool> sub_layer_level_present(max_num_sub_layers_minus1);
|
std::vector<bool> sub_layer_level_present(max_num_sub_layers_minus1);
|
||||||
|
|
|
@ -131,7 +131,11 @@ struct H265Sps {
|
||||||
int video_parameter_set_id = 0;
|
int video_parameter_set_id = 0;
|
||||||
int max_sub_layers_minus1 = 0;
|
int max_sub_layers_minus1 = 0;
|
||||||
bool temporal_id_nesting_flag = false;
|
bool temporal_id_nesting_flag = false;
|
||||||
// Ignored: profile_tier_level(...)
|
|
||||||
|
// general_profile_space (2), general_tier_flag (1), general_profile_idc (5),
|
||||||
|
// general_profile_compatibility_flags (32),
|
||||||
|
// general_constraint_indicator_flags (48), general_level_idc (8).
|
||||||
|
int general_profile_tier_level_data[12] = {};
|
||||||
|
|
||||||
int seq_parameter_set_id = 0;
|
int seq_parameter_set_id = 0;
|
||||||
|
|
||||||
|
@ -334,9 +338,10 @@ class H265Parser {
|
||||||
const H265SliceHeader& slice_header,
|
const H265SliceHeader& slice_header,
|
||||||
H26xBitReader* br);
|
H26xBitReader* br);
|
||||||
|
|
||||||
Result SkipProfileTierLevel(bool profile_present,
|
Result ReadProfileTierLevel(bool profile_present,
|
||||||
int max_num_sub_layers_minus1,
|
int max_num_sub_layers_minus1,
|
||||||
H26xBitReader* br);
|
H26xBitReader* br,
|
||||||
|
H265Sps* sps);
|
||||||
|
|
||||||
Result SkipScalingListData(H26xBitReader* br);
|
Result SkipScalingListData(H26xBitReader* br);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue