Sanity check parsed QP values from H264 bitstream
BUG=chromium:663610 Review-Url: https://codereview.webrtc.org/2532973002 Cr-Commit-Position: refs/heads/master@{#15377}
This commit is contained in:
parent
864f58b751
commit
b336392562
@ -19,6 +19,12 @@
|
||||
#include "webrtc/common_video/h264/h264_common.h"
|
||||
#include "webrtc/base/logging.h"
|
||||
|
||||
namespace {
|
||||
const int kMaxAbsQpDeltaValue = 51;
|
||||
const int kMinQpValue = 0;
|
||||
const int kMaxQpValue = 51;
|
||||
}
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
#define RETURN_ON_FAIL(x, res) \
|
||||
@ -251,6 +257,12 @@ H264BitstreamParser::Result H264BitstreamParser::ParseNonParameterSetNalu(
|
||||
int32_t last_slice_qp_delta;
|
||||
RETURN_INV_ON_FAIL(
|
||||
slice_reader.ReadSignedExponentialGolomb(&last_slice_qp_delta));
|
||||
if (abs(last_slice_qp_delta) > kMaxAbsQpDeltaValue) {
|
||||
// Something has gone wrong, and the parsed value is invalid.
|
||||
LOG(LS_WARNING) << "Parsed QP value out of range.";
|
||||
return kInvalidStream;
|
||||
}
|
||||
|
||||
last_slice_qp_delta_ = rtc::Optional<int32_t>(last_slice_qp_delta);
|
||||
return kOk;
|
||||
}
|
||||
@ -291,7 +303,12 @@ void H264BitstreamParser::ParseBitstream(const uint8_t* bitstream,
|
||||
bool H264BitstreamParser::GetLastSliceQp(int* qp) const {
|
||||
if (!last_slice_qp_delta_ || !pps_)
|
||||
return false;
|
||||
*qp = 26 + pps_->pic_init_qp_minus26 + *last_slice_qp_delta_;
|
||||
const int parsed_qp = 26 + pps_->pic_init_qp_minus26 + *last_slice_qp_delta_;
|
||||
if (parsed_qp < kMinQpValue || parsed_qp > kMaxQpValue) {
|
||||
LOG(LS_ERROR) << "Parsed invalid QP from bitstream.";
|
||||
return false;
|
||||
}
|
||||
*qp = parsed_qp;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -22,6 +22,11 @@
|
||||
return rtc::Optional<PpsParser::PpsState>(); \
|
||||
}
|
||||
|
||||
namespace {
|
||||
const int kMaxPicInitQpDeltaValue = 25;
|
||||
const int kMinPicInitQpDeltaValue = -26;
|
||||
}
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// General note: this is based off the 02/2014 version of the H.264 standard.
|
||||
@ -162,6 +167,11 @@ rtc::Optional<PpsParser::PpsState> PpsParser::ParseInternal(
|
||||
// pic_init_qp_minus26: se(v)
|
||||
RETURN_EMPTY_ON_FAIL(
|
||||
bit_buffer->ReadSignedExponentialGolomb(&pps.pic_init_qp_minus26));
|
||||
// Sanity-check parsed value
|
||||
if (pps.pic_init_qp_minus26 > kMaxPicInitQpDeltaValue ||
|
||||
pps.pic_init_qp_minus26 < kMinPicInitQpDeltaValue) {
|
||||
RETURN_EMPTY_ON_FAIL(false);
|
||||
}
|
||||
// pic_init_qs_minus26: se(v)
|
||||
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadExponentialGolomb(&golomb_ignored));
|
||||
// chroma_qp_index_offset: se(v)
|
||||
|
||||
@ -201,7 +201,7 @@ TEST_F(PpsParserTest, ZeroPps) {
|
||||
|
||||
TEST_F(PpsParserTest, MaxPps) {
|
||||
generated_pps_.bottom_field_pic_order_in_frame_present_flag = true;
|
||||
generated_pps_.pic_init_qp_minus26 = std::numeric_limits<int32_t>::max();
|
||||
generated_pps_.pic_init_qp_minus26 = 25;
|
||||
generated_pps_.redundant_pic_cnt_present_flag = 1; // 1 bit value.
|
||||
generated_pps_.weighted_bipred_idc = (1 << 2) - 1; // 2 bit value.
|
||||
generated_pps_.weighted_pred_flag = true;
|
||||
@ -210,7 +210,7 @@ TEST_F(PpsParserTest, MaxPps) {
|
||||
generated_pps_.sps_id = 1;
|
||||
RunTest();
|
||||
|
||||
generated_pps_.pic_init_qp_minus26 = std::numeric_limits<int32_t>::min() + 1;
|
||||
generated_pps_.pic_init_qp_minus26 = -25;
|
||||
RunTest();
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user