Fix bug with the sps-pps-idr-in-keyframe fmtp parameter.

RtpVideoStreamReceiver was forked to RtpVideoStreamReceiver2
recently, so the code that checks for this parameter needs to
be present in the forked location, but it wasn't.

This also enables RtpVideoStreamReceiver2TestH264.InBandSpsPps test
on MSAN, which was another already fixed bug that wasn't ported over
to the recently forked RtpVideoStreamReceiver2.

See webrtc:11595 for information about the fork.
See webrtc:11769 for information about this fmtp parameter.
See webrtc:11376 for the original MSAN issue.

Bug: webrtc:11957, webrtc:11595, webrtc:11769, webrtc:8423
Change-Id: I3734d077b2883c2f747ad35a0189b83c1915c3ef
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184524
Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Artem Titov <titovartem@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#32144}
This commit is contained in:
Andrew Johnson
2020-09-18 22:35:59 -07:00
committed by Commit Bot
parent 14dbf82961
commit f288f5b2d4
3 changed files with 79 additions and 9 deletions

View File

@ -18,6 +18,7 @@ Alexandre Gouaillard <agouaillard@gmail.com>
Alex Henrie <alexhenrie24@gmail.com>
Andrew MacDonald <andrew@webrtc.org>
Andrey Efremov <yoklmnprst@ya.ru>
Andrew Johnson <ajohnson@draster.com>
Anil Kumar <an1kumar@gmail.com>
Ben Strong <bstrong@gmail.com>
Bob Withers <bwit@pobox.com>

View File

@ -331,6 +331,10 @@ void RtpVideoStreamReceiver2::AddReceiveCodec(
const std::map<std::string, std::string>& codec_params,
bool raw_payload) {
RTC_DCHECK_RUN_ON(&worker_task_checker_);
if (codec_params.count(cricket::kH264FmtpSpsPpsIdrInKeyframe) ||
field_trial::IsEnabled("WebRTC-SpsPpsIdrIsH264Keyframe")) {
packet_buffer_.ForceSpsPpsIdrIsH264Keyframe();
}
payload_type_map_.emplace(
payload_type, raw_payload
? std::make_unique<VideoRtpDepacketizerRaw>()

View File

@ -201,7 +201,7 @@ class RtpVideoStreamReceiver2Test : public ::testing::Test {
info.type = H264::NaluType::kSps;
info.sps_id = sps_id;
info.pps_id = -1;
data->AppendData({H264::NaluType::kSps, sps_id});
data->AppendData<uint8_t, 2>({H264::NaluType::kSps, sps_id});
auto& h264 = absl::get<RTPVideoHeaderH264>(video_header->video_type_header);
h264.nalus[h264.nalus_length++] = info;
}
@ -214,7 +214,7 @@ class RtpVideoStreamReceiver2Test : public ::testing::Test {
info.type = H264::NaluType::kPps;
info.sps_id = sps_id;
info.pps_id = pps_id;
data->AppendData({H264::NaluType::kPps, pps_id});
data->AppendData<uint8_t, 2>({H264::NaluType::kPps, pps_id});
auto& h264 = absl::get<RTPVideoHeaderH264>(video_header->video_type_header);
h264.nalus[h264.nalus_length++] = info;
}
@ -523,13 +523,7 @@ INSTANTIATE_TEST_SUITE_P(SpsPpsIdrIsKeyframe,
RtpVideoStreamReceiver2TestH264,
Values("", "WebRTC-SpsPpsIdrIsH264Keyframe/Enabled/"));
// Fails on MSAN: https://bugs.chromium.org/p/webrtc/issues/detail?id=11376.
#if defined(MEMORY_SANITIZER)
#define MAYBE_InBandSpsPps DISABLED_InBandSpsPps
#else
#define MAYBE_InBandSpsPps InBandSpsPps
#endif
TEST_P(RtpVideoStreamReceiver2TestH264, MAYBE_InBandSpsPps) {
TEST_P(RtpVideoStreamReceiver2TestH264, InBandSpsPps) {
rtc::CopyOnWriteBuffer sps_data;
RtpPacketReceived rtp_packet;
RTPVideoHeader sps_video_header = GetDefaultH264VideoHeader();
@ -617,6 +611,77 @@ TEST_P(RtpVideoStreamReceiver2TestH264, OutOfBandFmtpSpsPps) {
video_header);
}
TEST_P(RtpVideoStreamReceiver2TestH264, ForceSpsPpsIdrIsKeyframe) {
constexpr int kPayloadType = 99;
VideoCodec codec;
std::map<std::string, std::string> codec_params;
if (GetParam() ==
"") { // Forcing can be done either with field trial or codec_params.
codec_params.insert({cricket::kH264FmtpSpsPpsIdrInKeyframe, ""});
}
rtp_video_stream_receiver_->AddReceiveCodec(kPayloadType, codec, codec_params,
/*raw_payload=*/false);
rtc::CopyOnWriteBuffer sps_data;
RtpPacketReceived rtp_packet;
RTPVideoHeader sps_video_header = GetDefaultH264VideoHeader();
AddSps(&sps_video_header, 0, &sps_data);
rtp_packet.SetSequenceNumber(0);
rtp_packet.SetPayloadType(kPayloadType);
sps_video_header.is_first_packet_in_frame = true;
sps_video_header.frame_type = VideoFrameType::kEmptyFrame;
mock_on_complete_frame_callback_.AppendExpectedBitstream(
kH264StartCode, sizeof(kH264StartCode));
mock_on_complete_frame_callback_.AppendExpectedBitstream(sps_data.data(),
sps_data.size());
rtp_video_stream_receiver_->OnReceivedPayloadData(sps_data, rtp_packet,
sps_video_header);
rtc::CopyOnWriteBuffer pps_data;
RTPVideoHeader pps_video_header = GetDefaultH264VideoHeader();
AddPps(&pps_video_header, 0, 1, &pps_data);
rtp_packet.SetSequenceNumber(1);
pps_video_header.is_first_packet_in_frame = true;
pps_video_header.frame_type = VideoFrameType::kEmptyFrame;
mock_on_complete_frame_callback_.AppendExpectedBitstream(
kH264StartCode, sizeof(kH264StartCode));
mock_on_complete_frame_callback_.AppendExpectedBitstream(pps_data.data(),
pps_data.size());
rtp_video_stream_receiver_->OnReceivedPayloadData(pps_data, rtp_packet,
pps_video_header);
rtc::CopyOnWriteBuffer idr_data;
RTPVideoHeader idr_video_header = GetDefaultH264VideoHeader();
AddIdr(&idr_video_header, 1);
rtp_packet.SetSequenceNumber(2);
idr_video_header.is_first_packet_in_frame = true;
idr_video_header.is_last_packet_in_frame = true;
idr_video_header.frame_type = VideoFrameType::kVideoFrameKey;
const uint8_t idr[] = {0x65, 1, 2, 3};
idr_data.AppendData(idr);
mock_on_complete_frame_callback_.AppendExpectedBitstream(
kH264StartCode, sizeof(kH264StartCode));
mock_on_complete_frame_callback_.AppendExpectedBitstream(idr_data.data(),
idr_data.size());
EXPECT_CALL(mock_on_complete_frame_callback_, DoOnCompleteFrame)
.WillOnce([&](video_coding::EncodedFrame* frame) {
EXPECT_TRUE(frame->is_keyframe());
});
rtp_video_stream_receiver_->OnReceivedPayloadData(idr_data, rtp_packet,
idr_video_header);
mock_on_complete_frame_callback_.ClearExpectedBitstream();
mock_on_complete_frame_callback_.AppendExpectedBitstream(
kH264StartCode, sizeof(kH264StartCode));
mock_on_complete_frame_callback_.AppendExpectedBitstream(idr_data.data(),
idr_data.size());
rtp_packet.SetSequenceNumber(3);
EXPECT_CALL(mock_on_complete_frame_callback_, DoOnCompleteFrame)
.WillOnce([&](video_coding::EncodedFrame* frame) {
EXPECT_FALSE(frame->is_keyframe());
});
rtp_video_stream_receiver_->OnReceivedPayloadData(idr_data, rtp_packet,
idr_video_header);
}
TEST_F(RtpVideoStreamReceiver2Test, PaddingInMediaStream) {
RtpPacketReceived rtp_packet;
RTPVideoHeader video_header = GetDefaultH264VideoHeader();