Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/LAVFilters.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHendrik Leppkes <h.leppkes@gmail.com>2017-05-08 23:49:27 +0300
committerHendrik Leppkes <h.leppkes@gmail.com>2017-05-09 00:12:55 +0300
commit377f6f1d2b29958a7d106d964f74e3b0dc20fd71 (patch)
treea038708c577452e40e07e571d253e0f07ff077cb /decoder
parent2675937efa5fd57146c473d4af29e509e28e7ed2 (diff)
Parse more bitstream properties from the HEVC SPS
Diffstat (limited to 'decoder')
-rw-r--r--decoder/LAVVideo/parsers/HEVCSequenceParser.cpp76
-rw-r--r--decoder/LAVVideo/parsers/HEVCSequenceParser.h2
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: