Always add/rewrite VUI and set max_num_reorder_frames to 0.
Bug: webrtc:10256 Change-Id: I5c28e69973cc5666deba4a1d7d660dc91f82c9f6 Reviewed-on: https://webrtc-review.googlesource.com/c/120349 Commit-Queue: Sergey Silkin <ssilkin@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26521}
This commit is contained in:
parent
a1fae4b475
commit
88fa2ab966
@ -84,11 +84,6 @@ SpsVuiRewriter::ParseResult SpsVuiRewriter::ParseAndRewriteSps(
|
||||
|
||||
*sps = sps_state;
|
||||
|
||||
if (sps_state->pic_order_cnt_type >= 2) {
|
||||
// No need to rewrite VUI in this case.
|
||||
return ParseResult::kPocOk;
|
||||
}
|
||||
|
||||
// We're going to completely muck up alignment, so we need a BitBuffer to
|
||||
// write with.
|
||||
rtc::Buffer out_buffer(length + kMaxVuiSpsIncrease);
|
||||
|
||||
@ -31,7 +31,7 @@ namespace webrtc {
|
||||
// decoding.
|
||||
class SpsVuiRewriter : private SpsParser {
|
||||
public:
|
||||
enum class ParseResult { kFailure, kPocOk, kVuiOk, kVuiRewritten };
|
||||
enum class ParseResult { kFailure, kVuiOk, kVuiRewritten };
|
||||
|
||||
// Parses an SPS block and if necessary copies it and rewrites the VUI.
|
||||
// Returns kFailure on failure, kParseOk if parsing succeeded and no update
|
||||
|
||||
@ -21,7 +21,6 @@
|
||||
namespace webrtc {
|
||||
|
||||
enum SpsMode {
|
||||
kNoRewriteRequired_PocCorrect,
|
||||
kNoRewriteRequired_VuiOptimal,
|
||||
kRewriteRequired_NoVui,
|
||||
kRewriteRequired_NoBitstreamRestriction,
|
||||
@ -55,14 +54,10 @@ void GenerateFakeSps(SpsMode mode, rtc::Buffer* out_buffer) {
|
||||
// log2_max_frame_num_minus4: ue(v). 0 is fine.
|
||||
writer.WriteExponentialGolomb(0);
|
||||
// pic_order_cnt_type: ue(v).
|
||||
// POC type 2 is the one that doesn't need to be rewritten.
|
||||
if (mode == kNoRewriteRequired_PocCorrect) {
|
||||
writer.WriteExponentialGolomb(2);
|
||||
} else {
|
||||
writer.WriteExponentialGolomb(0);
|
||||
// log2_max_pic_order_cnt_lsb_minus4: ue(v). 0 is fine.
|
||||
writer.WriteExponentialGolomb(0);
|
||||
}
|
||||
writer.WriteExponentialGolomb(0);
|
||||
// log2_max_pic_order_cnt_lsb_minus4: ue(v). 0 is fine.
|
||||
writer.WriteExponentialGolomb(0);
|
||||
|
||||
// max_num_ref_frames: ue(v). Use 1, to make optimal/suboptimal more obvious.
|
||||
writer.WriteExponentialGolomb(1);
|
||||
// gaps_in_frame_num_value_allowed_flag: u(1).
|
||||
@ -96,7 +91,7 @@ void GenerateFakeSps(SpsMode mode, rtc::Buffer* out_buffer) {
|
||||
|
||||
// Finally! The VUI.
|
||||
// vui_parameters_present_flag: u(1)
|
||||
if (mode == kNoRewriteRequired_PocCorrect || mode == kRewriteRequired_NoVui) {
|
||||
if (mode == kRewriteRequired_NoVui) {
|
||||
writer.WriteBits(0, 1);
|
||||
} else {
|
||||
writer.WriteBits(1, 1);
|
||||
@ -124,7 +119,7 @@ void GenerateFakeSps(SpsMode mode, rtc::Buffer* out_buffer) {
|
||||
if (mode == kRewriteRequired_VuiSuboptimal) {
|
||||
writer.WriteExponentialGolomb(4);
|
||||
writer.WriteExponentialGolomb(4);
|
||||
} else if (kNoRewriteRequired_VuiOptimal) {
|
||||
} else {
|
||||
writer.WriteExponentialGolomb(0);
|
||||
writer.WriteExponentialGolomb(1);
|
||||
}
|
||||
@ -138,42 +133,42 @@ void GenerateFakeSps(SpsMode mode, rtc::Buffer* out_buffer) {
|
||||
byte_count++;
|
||||
}
|
||||
|
||||
// Write the NALU header and type; {0 0 0 1} and 7 for the SPS header type.
|
||||
uint8_t header[] = {0, 0, 0, 1, 7};
|
||||
out_buffer->AppendData(header, sizeof(header));
|
||||
|
||||
H264::WriteRbsp(rbsp, byte_count, out_buffer);
|
||||
}
|
||||
|
||||
void TestSps(SpsMode mode, SpsVuiRewriter::ParseResult expected_parse_result) {
|
||||
rtc::LogMessage::LogToDebug(rtc::LS_VERBOSE);
|
||||
rtc::Buffer buffer;
|
||||
GenerateFakeSps(mode, &buffer);
|
||||
std::vector<H264::NaluIndex> start_offsets =
|
||||
H264::FindNaluIndices(buffer.data(), buffer.size());
|
||||
EXPECT_EQ(1u, start_offsets.size());
|
||||
H264::NaluIndex index = start_offsets[0];
|
||||
|
||||
H264::NaluType nal_type =
|
||||
H264::ParseNaluType(buffer[index.payload_start_offset]);
|
||||
EXPECT_EQ(H264::kSps, nal_type);
|
||||
index.payload_start_offset += H264::kNaluTypeSize;
|
||||
index.payload_size -= H264::kNaluTypeSize;
|
||||
rtc::Buffer original_sps;
|
||||
GenerateFakeSps(mode, &original_sps);
|
||||
|
||||
absl::optional<SpsParser::SpsState> sps;
|
||||
rtc::Buffer out_buffer;
|
||||
SpsVuiRewriter::ParseResult result =
|
||||
SpsVuiRewriter::ParseAndRewriteSps(&buffer[index.payload_start_offset],
|
||||
index.payload_size, &sps, &out_buffer);
|
||||
rtc::Buffer rewritten_sps;
|
||||
SpsVuiRewriter::ParseResult result = SpsVuiRewriter::ParseAndRewriteSps(
|
||||
original_sps.data(), original_sps.size(), &sps, &rewritten_sps);
|
||||
EXPECT_EQ(expected_parse_result, result);
|
||||
ASSERT_TRUE(sps);
|
||||
EXPECT_EQ(sps->width, kWidth);
|
||||
EXPECT_EQ(sps->height, kHeight);
|
||||
if (mode != kRewriteRequired_NoVui) {
|
||||
EXPECT_EQ(sps->vui_params_present, 1u);
|
||||
}
|
||||
|
||||
if (result == SpsVuiRewriter::ParseResult::kVuiRewritten) {
|
||||
// Ensure that added/rewritten SPS is parsable.
|
||||
rtc::Buffer tmp;
|
||||
result = SpsVuiRewriter::ParseAndRewriteSps(
|
||||
rewritten_sps.data(), rewritten_sps.size(), &sps, &tmp);
|
||||
EXPECT_EQ(SpsVuiRewriter::ParseResult::kVuiOk, result);
|
||||
ASSERT_TRUE(sps);
|
||||
EXPECT_EQ(sps->width, kWidth);
|
||||
EXPECT_EQ(sps->height, kHeight);
|
||||
EXPECT_EQ(sps->vui_params_present, 1u);
|
||||
}
|
||||
}
|
||||
|
||||
#define REWRITE_TEST(test_name, mode, expected_parse_result) \
|
||||
TEST(SpsVuiRewriterTest, test_name) { TestSps(mode, expected_parse_result); }
|
||||
|
||||
REWRITE_TEST(PocCorrect,
|
||||
kNoRewriteRequired_PocCorrect,
|
||||
SpsVuiRewriter::ParseResult::kPocOk);
|
||||
REWRITE_TEST(VuiAlreadyOptimal,
|
||||
kNoRewriteRequired_VuiOptimal,
|
||||
SpsVuiRewriter::ParseResult::kVuiOk);
|
||||
@ -186,5 +181,4 @@ REWRITE_TEST(AddBitstreamRestriction,
|
||||
REWRITE_TEST(RewriteSuboptimalVui,
|
||||
kRewriteRequired_VuiSuboptimal,
|
||||
SpsVuiRewriter::ParseResult::kVuiRewritten);
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -43,7 +43,6 @@ static const size_t kStapAHeaderSize = kNalHeaderSize + kLengthFieldSize;
|
||||
|
||||
static const char* kSpsValidHistogramName = "WebRTC.Video.H264.SpsValid";
|
||||
enum SpsValidEvent {
|
||||
kReceivedSpsPocOk = 0,
|
||||
kReceivedSpsVuiOk = 1,
|
||||
kReceivedSpsRewritten = 2,
|
||||
kReceivedSpsParseFailure = 3,
|
||||
@ -135,11 +134,6 @@ RtpPacketizerH264::RtpPacketizerH264(
|
||||
SpsValidEvent::kSentSpsRewritten,
|
||||
SpsValidEvent::kSpsRewrittenMax);
|
||||
break;
|
||||
case SpsVuiRewriter::ParseResult::kPocOk:
|
||||
RTC_HISTOGRAM_ENUMERATION(kSpsValidHistogramName,
|
||||
SpsValidEvent::kSentSpsPocOk,
|
||||
SpsValidEvent::kSpsRewrittenMax);
|
||||
break;
|
||||
case SpsVuiRewriter::ParseResult::kVuiOk:
|
||||
RTC_HISTOGRAM_ENUMERATION(kSpsValidHistogramName,
|
||||
SpsValidEvent::kSentSpsVuiOk,
|
||||
@ -559,11 +553,6 @@ bool RtpDepacketizerH264::ProcessStapAOrSingleNalu(
|
||||
SpsValidEvent::kReceivedSpsRewritten,
|
||||
SpsValidEvent::kSpsRewrittenMax);
|
||||
break;
|
||||
case SpsVuiRewriter::ParseResult::kPocOk:
|
||||
RTC_HISTOGRAM_ENUMERATION(kSpsValidHistogramName,
|
||||
SpsValidEvent::kReceivedSpsPocOk,
|
||||
SpsValidEvent::kSpsRewrittenMax);
|
||||
break;
|
||||
case SpsVuiRewriter::ParseResult::kVuiOk:
|
||||
RTC_HISTOGRAM_ENUMERATION(kSpsValidHistogramName,
|
||||
SpsValidEvent::kReceivedSpsVuiOk,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user