diff options
author | Hendrik Leppkes <h.leppkes@gmail.com> | 2017-05-08 23:49:27 +0300 |
---|---|---|
committer | Hendrik Leppkes <h.leppkes@gmail.com> | 2017-05-09 00:12:55 +0300 |
commit | 377f6f1d2b29958a7d106d964f74e3b0dc20fd71 (patch) | |
tree | a038708c577452e40e07e571d253e0f07ff077cb /decoder | |
parent | 2675937efa5fd57146c473d4af29e509e28e7ed2 (diff) |
Parse more bitstream properties from the HEVC SPS
Diffstat (limited to 'decoder')
-rw-r--r-- | decoder/LAVVideo/parsers/HEVCSequenceParser.cpp | 76 | ||||
-rw-r--r-- | decoder/LAVVideo/parsers/HEVCSequenceParser.h | 2 |
2 files changed, 63 insertions, 15 deletions
diff --git a/decoder/LAVVideo/parsers/HEVCSequenceParser.cpp b/decoder/LAVVideo/parsers/HEVCSequenceParser.cpp index 785bf1e2..790aa8f8 100644 --- a/decoder/LAVVideo/parsers/HEVCSequenceParser.cpp +++ b/decoder/LAVVideo/parsers/HEVCSequenceParser.cpp @@ -29,6 +29,7 @@ CHEVCSequenceParser::CHEVCSequenceParser() { ZeroMemory(&sps, sizeof(sps)); + sps.bitdepth = 8; } CHEVCSequenceParser::~CHEVCSequenceParser() @@ -45,7 +46,8 @@ HRESULT CHEVCSequenceParser::ParseNALs(const BYTE *buffer, size_t buflen, int na const BYTE *data = nalu.GetDataBuffer() + 2; const size_t len = nalu.GetDataLength() - 2; if (nalu.GetType() == HEVC_NAL_SPS) { - ParseSPS(data, len); + CH264NALUnescape unescapedNAL(data, len); + ParseSPS(unescapedNAL.GetBuffer(), unescapedNAL.GetSize()); break; } } @@ -61,33 +63,77 @@ HRESULT CHEVCSequenceParser::ParseSPS(const BYTE *buffer, size_t buflen) ZeroMemory(&sps, sizeof(sps)); sps.valid = 1; - parser.BitRead(4); // sps_video_parameter_set_id + struct { + int profile_present; + int level_present; + } Sublayers[7]; + + parser.BitSkip(4); // sps_video_parameter_set_id int max_sub_layers = parser.BitRead(3); // sps_max_sub_layers_minus1 - parser.BitRead(1); // sps_temporal_id_nesting_flag + parser.BitSkip(1); // sps_temporal_id_nesting_flag // profile tier level - parser.BitRead(2); // general_profile_space - parser.BitRead(1); // general_tier_flag + parser.BitSkip(2); // general_profile_space + parser.BitSkip(1); // general_tier_flag sps.profile = parser.BitRead(5); // general_profile_idc - parser.BitRead(32); // general_profile_compatibility_flag[32] - parser.BitRead(1); // general_progressive_source_flag - parser.BitRead(1); // general_interlaced_source_flag - parser.BitRead(1); // general_non_packed_constraint_flag - parser.BitRead(1); // general_frame_only_constraint_flag - parser.BitRead(22); // general_reserved_zero_44bits - parser.BitRead(22); // general_reserved_zero_44bits + parser.BitSkip(32); // general_profile_compatibility_flag[32] + parser.BitSkip(1); // general_progressive_source_flag + parser.BitSkip(1); // general_interlaced_source_flag + parser.BitSkip(1); // general_non_packed_constraint_flag + parser.BitSkip(1); // general_frame_only_constraint_flag + parser.BitSkip(22); // general_reserved_zero_44bits + parser.BitSkip(22); // general_reserved_zero_44bits sps.level = parser.BitRead(8); // general_level_idc + if (max_sub_layers > 7) + return E_FAIL; + for (i = 0; i < max_sub_layers; i++) { - parser.BitRead(1); // sub_layer_profile_present_flag - parser.BitRead(1); // sub_layer_level_present_flag + Sublayers[i].profile_present = parser.BitRead(1); // sub_layer_profile_present_flag + Sublayers[i].level_present = parser.BitRead(1); // sub_layer_level_present_flag } if (max_sub_layers > 0) { for (i = max_sub_layers; i < 8; i++) - parser.BitRead(2); // reserved_zero_2bits + parser.BitSkip(2); // reserved_zero_2bits + } + + for (i = 0; i < max_sub_layers; i++) { + if (Sublayers[i].profile_present) { + parser.BitSkip(2); // general_profile_space + parser.BitSkip(1); // general_tier_flag + parser.BitSkip(5); // general_profile_idc + + parser.BitSkip(32); // profile_compatibility_flag[32] + parser.BitSkip(1); // progressive_source_flag + parser.BitSkip(1); // interlaced_source_flag + parser.BitSkip(1); // non_packed_constraint_flag + parser.BitSkip(1); // frame_only_constraint_flag + parser.BitSkip(22); // reserved_zero_44bits + parser.BitSkip(22); // reserved_zero_44bits + } + if (Sublayers[i].level_present) { + parser.BitSkip(8); // level_idc + } + } + + parser.UExpGolombRead(); // sps_id + sps.chroma = parser.UExpGolombRead(); // chroma_format_idc + if (sps.chroma == 3) + parser.BitRead(1); // separate_color_plane_flag + + parser.UExpGolombRead(); // width + parser.UExpGolombRead(); // height + + if (parser.BitRead(1)) { // conformance_window_flag + parser.UExpGolombRead(); // left offset + parser.UExpGolombRead(); // right offset + parser.UExpGolombRead(); // top offset + parser.UExpGolombRead(); // bottom offset } + sps.bitdepth = parser.UExpGolombRead() + 8; // bit_depth_luma_minus8 + return S_OK; } diff --git a/decoder/LAVVideo/parsers/HEVCSequenceParser.h b/decoder/LAVVideo/parsers/HEVCSequenceParser.h index eddda8c8..af7748cf 100644 --- a/decoder/LAVVideo/parsers/HEVCSequenceParser.h +++ b/decoder/LAVVideo/parsers/HEVCSequenceParser.h @@ -35,6 +35,8 @@ public: int profile; int level; + int chroma; + int bitdepth; } sps; private: |