Avoid treating VP8 key frame in simulcast as delta frame
Bug: None Change-Id: Ief3c759571f02af6cd9517acb2851861e190ceaf Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/203891 Reviewed-by: Åsa Persson <asapersson@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/master@{#33088}
This commit is contained in:
parent
075fd4b7f9
commit
37dfddd5e8
@ -314,14 +314,24 @@ bool IsFirstFrameOfACodedVideoSequence(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (codec_specific_info != nullptr &&
|
||||
codec_specific_info->generic_frame_info.has_value()) {
|
||||
// This function is used before
|
||||
// `codec_specific_info->generic_frame_info->frame_diffs` are calculated, so
|
||||
// need to use more complicated way to check for presence of dependencies.
|
||||
return absl::c_none_of(
|
||||
codec_specific_info->generic_frame_info->encoder_buffers,
|
||||
[](const CodecBufferUsage& buffer) { return buffer.referenced; });
|
||||
if (codec_specific_info != nullptr) {
|
||||
if (codec_specific_info->generic_frame_info.has_value()) {
|
||||
// This function is used before
|
||||
// `codec_specific_info->generic_frame_info->frame_diffs` are calculated,
|
||||
// so need to use a more complicated way to check for presence of the
|
||||
// dependencies.
|
||||
return absl::c_none_of(
|
||||
codec_specific_info->generic_frame_info->encoder_buffers,
|
||||
[](const CodecBufferUsage& buffer) { return buffer.referenced; });
|
||||
}
|
||||
|
||||
if (codec_specific_info->codecType == VideoCodecType::kVideoCodecVP8 ||
|
||||
codec_specific_info->codecType == VideoCodecType::kVideoCodecH264 ||
|
||||
codec_specific_info->codecType == VideoCodecType::kVideoCodecGeneric) {
|
||||
// These codecs do not support intra picture dependencies, so a frame
|
||||
// marked as a key frame should be a key frame.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Without depenedencies described in generic format do an educated guess.
|
||||
|
||||
@ -825,6 +825,64 @@ TEST(RtpVideoSenderTest, SupportsStoppingUsingDependencyDescriptor) {
|
||||
sent_packets.back().HasExtension<RtpDependencyDescriptorExtension>());
|
||||
}
|
||||
|
||||
TEST(RtpVideoSenderTest,
|
||||
SupportsStoppingUsingDependencyDescriptorForVp8Simulcast) {
|
||||
RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {}, kPayloadType, {});
|
||||
test.router()->SetActive(true);
|
||||
|
||||
RtpHeaderExtensionMap extensions;
|
||||
extensions.Register<RtpDependencyDescriptorExtension>(
|
||||
kDependencyDescriptorExtensionId);
|
||||
std::vector<RtpPacket> sent_packets;
|
||||
ON_CALL(test.transport(), SendRtp)
|
||||
.WillByDefault([&](const uint8_t* packet, size_t length,
|
||||
const PacketOptions& options) {
|
||||
sent_packets.emplace_back(&extensions);
|
||||
EXPECT_TRUE(sent_packets.back().Parse(packet, length));
|
||||
return true;
|
||||
});
|
||||
|
||||
const uint8_t kPayload[1] = {'a'};
|
||||
EncodedImage encoded_image;
|
||||
encoded_image.SetTimestamp(1);
|
||||
encoded_image.capture_time_ms_ = 2;
|
||||
encoded_image.SetEncodedData(
|
||||
EncodedImageBuffer::Create(kPayload, sizeof(kPayload)));
|
||||
// VP8 simulcast uses spatial index to communicate simulcast stream.
|
||||
encoded_image.SetSpatialIndex(1);
|
||||
|
||||
CodecSpecificInfo codec_specific;
|
||||
codec_specific.codecType = VideoCodecType::kVideoCodecVP8;
|
||||
codec_specific.template_structure.emplace();
|
||||
codec_specific.template_structure->num_decode_targets = 1;
|
||||
codec_specific.template_structure->templates = {
|
||||
FrameDependencyTemplate().T(0).Dtis("S")};
|
||||
|
||||
// Send two tiny images, mapping to single RTP packets.
|
||||
// Send in a key frame.
|
||||
encoded_image._frameType = VideoFrameType::kVideoFrameKey;
|
||||
codec_specific.generic_frame_info =
|
||||
GenericFrameInfo::Builder().T(0).Dtis("S").Build();
|
||||
codec_specific.generic_frame_info->encoder_buffers = {{0, false, true}};
|
||||
EXPECT_EQ(test.router()->OnEncodedImage(encoded_image, &codec_specific).error,
|
||||
EncodedImageCallback::Result::OK);
|
||||
test.AdvanceTime(TimeDelta::Millis(33));
|
||||
ASSERT_THAT(sent_packets, SizeIs(1));
|
||||
EXPECT_TRUE(
|
||||
sent_packets.back().HasExtension<RtpDependencyDescriptorExtension>());
|
||||
|
||||
// Send in a new key frame without the support for the dependency descriptor.
|
||||
encoded_image._frameType = VideoFrameType::kVideoFrameKey;
|
||||
codec_specific.template_structure = absl::nullopt;
|
||||
codec_specific.generic_frame_info = absl::nullopt;
|
||||
EXPECT_EQ(test.router()->OnEncodedImage(encoded_image, &codec_specific).error,
|
||||
EncodedImageCallback::Result::OK);
|
||||
test.AdvanceTime(TimeDelta::Millis(33));
|
||||
ASSERT_THAT(sent_packets, SizeIs(2));
|
||||
EXPECT_FALSE(
|
||||
sent_packets.back().HasExtension<RtpDependencyDescriptorExtension>());
|
||||
}
|
||||
|
||||
TEST(RtpVideoSenderTest, CanSetZeroBitrate) {
|
||||
RtpVideoSenderTestFixture test({kSsrc1}, {kRtxSsrc1}, kPayloadType, {});
|
||||
test.router()->OnBitrateUpdated(CreateBitrateAllocationUpdate(0),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user