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:
KongQun Yang 2018-01-05 20:57:51 -08:00
parent 5d5cb8678d
commit 858fcd8698
4 changed files with 28 additions and 20 deletions

View File

@ -51,9 +51,8 @@ bool H265ByteToUnitStreamConverter::GetDecoderConfigurationRecord(
// (4) general_profile_compatibility_flags
// (6) general_constraint_indicator_flags
// (1) general_level_idc
// Skip Nalu header (2) and the first byte of the SPS to get the
// profile_tier_level.
buffer.AppendArray(&last_sps_[2+1], 12);
for (int byte : sps->general_profile_tier_level_data)
buffer.AppendInt(static_cast<uint8_t>(byte));
// The default value for this field is 0, which is Unknown.
int min_spatial_segmentation_idc =

View File

@ -14,7 +14,7 @@
namespace {
const char kExpectedConfigRecord[] =
"01016000000300900000030000f000fcfdf8f800000303a00001001840010c01ffff01"
"0101600000009000000000005df000fcfdf8f800000303a00001001840010c01ffff01"
"600000030090000003000003005d999809a10001002e42010101600000030090000003"
"000003005da0028080241f265999a4932bffc0d5c0d64040000003004000000602a200"
"0100074401c172b46240";

View File

@ -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->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->chroma_format_idc));
@ -947,24 +948,27 @@ H265Parser::Result H265Parser::SkipPredictionWeightTable(
return kOk;
}
H265Parser::Result H265Parser::SkipProfileTierLevel(
H265Parser::Result H265Parser::ReadProfileTierLevel(
bool profile_present,
int max_num_sub_layers_minus1,
H26xBitReader* br) {
H26xBitReader* br,
H265Sps* sps) {
// Reads whole element, ignores it.
if (profile_present) {
// general_profile_space, general_tier_flag, general_profile_idc
// general_profile_compativility_flag
// general_progressive_source_flag
// general_interlaced_source_flag
// general_non_packed_constraint_flag
// general_frame_only_constraint_flag
// 44-bits of other flags
TRUE_OR_RETURN(br->SkipBits(2 + 1 + 5 + 32 + 4 + 44));
// 11 bytes of general_profile_tier flags:
// general_profile_space, general_tier_flag, general_profile_idc
// general_profile_compativility_flag
// general_progressive_source_flag
// general_interlaced_source_flag
// general_non_packed_constraint_flag
// general_frame_only_constraint_flag
// 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]));
}
TRUE_OR_RETURN(br->SkipBits(8)); // general_level_idc
// 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_level_present(max_num_sub_layers_minus1);

View File

@ -131,7 +131,11 @@ struct H265Sps {
int video_parameter_set_id = 0;
int max_sub_layers_minus1 = 0;
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;
@ -334,9 +338,10 @@ class H265Parser {
const H265SliceHeader& slice_header,
H26xBitReader* br);
Result SkipProfileTierLevel(bool profile_present,
Result ReadProfileTierLevel(bool profile_present,
int max_num_sub_layers_minus1,
H26xBitReader* br);
H26xBitReader* br,
H265Sps* sps);
Result SkipScalingListData(H26xBitReader* br);