Bug 1952339 - Vendor libwebrtc from a152ada304
Upstream commit: https://webrtc.googlesource.com/src/+/a152ada304a19769bfbd1e6e19c626dc5c66dc67 Support h265 streams with weighted prediction tables. Some H265 encoders may encode with weighted prediction turned on. Allow such streams to be parsed. Bug: chromium:41480904 Change-Id: I25e7ca7b8151f264eeb9a4eae3cd49719dfeef9c Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/378703 Reviewed-by: Henrik Boström <hbos@webrtc.org> Reviewed-by: Sergey Silkin <ssilkin@webrtc.org> Commit-Queue: Jianlin Qiu <jianlin.qiu@intel.com> Cr-Commit-Position: refs/heads/main@{#43991} Differential Revision: https://phabricator.services.mozilla.com/D243999
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc
|
||||
libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-03-07T22:41:33.244180+00:00.
|
||||
libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-03-07T22:42:22.082859+00:00.
|
||||
# base of lastest vendoring
|
||||
4b67f8d3f7
|
||||
a152ada304
|
||||
|
||||
@@ -364,13 +364,109 @@ H265BitstreamParser::Result H265BitstreamParser::ParseNonParameterSetNalu(
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!slice_reader.Ok() ||
|
||||
((pps->weighted_pred_flag && slice_type == H265::SliceType::kP) ||
|
||||
(pps->weighted_bipred_flag && slice_type == H265::SliceType::kB))) {
|
||||
// pred_weight_table()
|
||||
RTC_LOG(LS_ERROR) << "Streams with pred_weight_table unsupported.";
|
||||
return kUnsupportedStream;
|
||||
|
||||
// pred_weight_table()
|
||||
if ((pps->weighted_pred_flag && slice_type == H265::SliceType::kP) ||
|
||||
(pps->weighted_bipred_flag && slice_type == H265::SliceType::kB)) {
|
||||
uint32_t luma_log2_weight_denom = slice_reader.ReadExponentialGolomb();
|
||||
IN_RANGE_OR_RETURN(luma_log2_weight_denom, 0, 7);
|
||||
uint32_t chroma_array_type =
|
||||
sps->separate_colour_plane_flag == 0 ? sps->chroma_format_idc : 0;
|
||||
int32_t chroma_log2_weight_denom = luma_log2_weight_denom;
|
||||
// wp_offset_half_range_c and wp_offset_half_range_y depends on
|
||||
// sps.high_precision_offsets_enable_flag. Since range extension is not
|
||||
// supported, so for now below two are fixed to 128 instead of 1 <<
|
||||
// (sps.bit_depth_luma|chroma_minus8 + 7).
|
||||
int32_t wp_offset_half_range_c = (1 << 7);
|
||||
int32_t wp_offset_half_range_y = (1 << 7);
|
||||
if (chroma_array_type != 0) {
|
||||
// delta_chroma_log2_weight_denom: se(v)
|
||||
chroma_log2_weight_denom +=
|
||||
slice_reader.ReadSignedExponentialGolomb();
|
||||
}
|
||||
IN_RANGE_OR_RETURN(chroma_log2_weight_denom, 0, 7);
|
||||
|
||||
bool luma_weight_flag_l0[kMaxRefIdxActive] = {};
|
||||
bool chroma_weight_flag_l0[kMaxRefIdxActive] = {};
|
||||
int32_t delta_chroma_weight_l0[kMaxRefIdxActive][2] = {};
|
||||
int32_t luma_offset_l0[kMaxRefIdxActive] = {};
|
||||
int32_t delta_chroma_offset_l0[kMaxRefIdxActive][2] = {};
|
||||
for (uint32_t i = 0; i <= num_ref_idx_l0_active_minus1; i++) {
|
||||
// luma_weight_l0_flag: u(1). By syntax this should conditionally
|
||||
// check if the POC or layer ID of the reference picture is different,
|
||||
// but we don't support encoding referencing different layers in the
|
||||
// same AU. Skip the check for now.
|
||||
luma_weight_flag_l0[i] = slice_reader.Read<bool>();
|
||||
}
|
||||
if (chroma_array_type != 0) {
|
||||
for (uint32_t i = 0; i <= num_ref_idx_l0_active_minus1; i++) {
|
||||
// chroma_weight_l0_flag: u(1)
|
||||
chroma_weight_flag_l0[i] = slice_reader.Read<bool>();
|
||||
}
|
||||
}
|
||||
for (uint32_t i = 0; i <= num_ref_idx_l0_active_minus1; i++) {
|
||||
if (luma_weight_flag_l0[i]) {
|
||||
int32_t delta_luma_weight_l0[kMaxRefIdxActive] = {};
|
||||
delta_luma_weight_l0[i] =
|
||||
slice_reader.ReadSignedExponentialGolomb();
|
||||
IN_RANGE_OR_RETURN(delta_luma_weight_l0[i], -128, 127);
|
||||
luma_offset_l0[i] = slice_reader.ReadSignedExponentialGolomb();
|
||||
IN_RANGE_OR_RETURN(luma_offset_l0[i], -wp_offset_half_range_y,
|
||||
wp_offset_half_range_y - 1);
|
||||
}
|
||||
if (chroma_weight_flag_l0[i]) {
|
||||
for (uint32_t j = 0; j < 2; j++) {
|
||||
delta_chroma_weight_l0[i][j] =
|
||||
slice_reader.ReadSignedExponentialGolomb();
|
||||
IN_RANGE_OR_RETURN(delta_chroma_weight_l0[i][j], -128, 127);
|
||||
delta_chroma_offset_l0[i][j] =
|
||||
slice_reader.ReadSignedExponentialGolomb();
|
||||
IN_RANGE_OR_RETURN(delta_chroma_offset_l0[i][j],
|
||||
-4 * wp_offset_half_range_c,
|
||||
4 * wp_offset_half_range_c - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (slice_type == H265::SliceType::kB) {
|
||||
bool luma_weight_flag_l1[kMaxRefIdxActive] = {};
|
||||
bool chroma_weight_flag_l1[kMaxRefIdxActive] = {};
|
||||
int32_t delta_chroma_weight_l1[kMaxRefIdxActive][2] = {};
|
||||
int32_t luma_offset_l1[kMaxRefIdxActive] = {};
|
||||
int32_t delta_chroma_offset_l1[kMaxRefIdxActive][2] = {};
|
||||
for (uint32_t i = 0; i < num_ref_idx_l1_active_minus1; i++) {
|
||||
luma_weight_flag_l1[i] = slice_reader.Read<bool>();
|
||||
}
|
||||
if (chroma_array_type != 0) {
|
||||
for (uint32_t i = 0; i <= num_ref_idx_l1_active_minus1; i++) {
|
||||
chroma_weight_flag_l1[i] = slice_reader.Read<bool>();
|
||||
}
|
||||
}
|
||||
for (uint32_t i = 0; i <= num_ref_idx_l1_active_minus1; i++) {
|
||||
if (luma_weight_flag_l1[i]) {
|
||||
int32_t delta_luma_weight_l1[kMaxRefIdxActive] = {};
|
||||
delta_luma_weight_l1[i] =
|
||||
slice_reader.ReadSignedExponentialGolomb();
|
||||
IN_RANGE_OR_RETURN(delta_luma_weight_l1[i], -128, 127);
|
||||
luma_offset_l1[i] = slice_reader.ReadSignedExponentialGolomb();
|
||||
IN_RANGE_OR_RETURN(luma_offset_l1[i], -wp_offset_half_range_y,
|
||||
wp_offset_half_range_y - 1);
|
||||
}
|
||||
if (chroma_weight_flag_l1[i]) {
|
||||
for (uint32_t j = 0; j < 2; j++) {
|
||||
delta_chroma_weight_l1[i][j] =
|
||||
slice_reader.ReadSignedExponentialGolomb();
|
||||
IN_RANGE_OR_RETURN(delta_chroma_weight_l1[i][j], -128, 127);
|
||||
delta_chroma_offset_l1[i][j] =
|
||||
slice_reader.ReadSignedExponentialGolomb();
|
||||
IN_RANGE_OR_RETURN(delta_chroma_offset_l1[i][j],
|
||||
-4 * wp_offset_half_range_c,
|
||||
4 * wp_offset_half_range_c - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// five_minus_max_num_merge_cand: ue(v)
|
||||
uint32_t five_minus_max_num_merge_cand =
|
||||
slice_reader.ReadExponentialGolomb();
|
||||
|
||||
@@ -101,6 +101,24 @@ const uint8_t kH265BitstreamInvalidQPChunk52[] = {
|
||||
0x00, 0x01, 0x26, 0x01, 0xaf, 0x03, 0x44,
|
||||
};
|
||||
|
||||
// Bitstream that contains pred_weight_table. Contains enough data to parse
|
||||
// over pred_weight_table for slice QP. This is bear.hevc from Chromium source,
|
||||
// used for H265 hardware decoder's parser test, with some slices truncated.
|
||||
const uint8_t kH265BitstreamWithPredWeightTable[] = {
|
||||
0x00, 0x00, 0x00, 0x01, 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x01, 0x60,
|
||||
0x00, 0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00,
|
||||
0x3c, 0x95, 0xc0, 0x90, 0x00, 0x00, 0x00, 0x01, 0x42, 0x01, 0x01, 0x01,
|
||||
0x60, 0x00, 0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03,
|
||||
0x00, 0x3c, 0xa0, 0x0a, 0x08, 0x0b, 0x9f, 0x79, 0x65, 0x79, 0x24, 0xca,
|
||||
0xe0, 0x10, 0x00, 0x00, 0x06, 0x40, 0x00, 0x00, 0xbb, 0x50, 0x80, 0x00,
|
||||
0x00, 0x00, 0x01, 0x44, 0x01, 0xc1, 0x73, 0xd1, 0x89, 0x00, 0x00, 0x00,
|
||||
0x01, 0x02, 0x01, 0xd0, 0x21, 0x49, 0xe8, 0xee, 0x50, 0x9c, 0x27, 0x20,
|
||||
0x42, 0xc4, 0xcd, 0x33, 0xf0, 0xb1, 0x23, 0x7b, 0xfe, 0x4d, 0xcf, 0x40,
|
||||
0xeb, 0x17, 0x37, 0x91, 0x1c, 0xb6, 0xba, 0x21, 0x42, 0xf7, 0xef, 0x01,
|
||||
0x08, 0x90, 0x49, 0xdc, 0xfc, 0x10, 0x1f, 0x5e, 0x02, 0xd9, 0xaa, 0xe8,
|
||||
0x32, 0xeb, 0x74, 0xbc, 0xdb, 0x2c, 0xa3, 0xec,
|
||||
};
|
||||
|
||||
TEST(H265BitstreamParserTest, ReportsNoQpWithoutParsedSlices) {
|
||||
H265BitstreamParser h265_parser;
|
||||
EXPECT_FALSE(h265_parser.GetLastSliceQp().has_value());
|
||||
@@ -112,6 +130,14 @@ TEST(H265BitstreamParserTest, ReportsNoQpWithOnlyParsedPpsAndSpsSlices) {
|
||||
EXPECT_FALSE(h265_parser.GetLastSliceQp().has_value());
|
||||
}
|
||||
|
||||
TEST(H265BitstreamParserTest, ReportQpWithPredWeightTable) {
|
||||
H265BitstreamParser h265_parser;
|
||||
h265_parser.ParseBitstream(kH265BitstreamWithPredWeightTable);
|
||||
std::optional<int> qp = h265_parser.GetLastSliceQp();
|
||||
ASSERT_TRUE(qp.has_value());
|
||||
EXPECT_EQ(34, *qp);
|
||||
}
|
||||
|
||||
TEST(H265BitstreamParserTest, ReportsLastSliceQpForImageSlices) {
|
||||
H265BitstreamParser h265_parser;
|
||||
h265_parser.ParseBitstream(kH265BitstreamChunk);
|
||||
|
||||
Reference in New Issue
Block a user