Authenticate video header when dependency descriptor is sent
same way as generic frame descriptor is authenticated. Bug: webrtc:10342 Change-Id: I50bb3ab343d66f1f628083183444da6e338f7db9 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168681 Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Reviewed-by: Markus Handell <handellm@webrtc.org> Cr-Commit-Position: refs/heads/master@{#30578}
This commit is contained in:
parent
f5c1909b54
commit
95800f6298
@ -502,6 +502,7 @@ if (rtc_include_tests) {
|
||||
"../..:webrtc_common",
|
||||
"../../api:array_view",
|
||||
"../../api:libjingle_peerconnection_api",
|
||||
"../../api:mock_frame_encryptor",
|
||||
"../../api:rtp_headers",
|
||||
"../../api:rtp_packet_info",
|
||||
"../../api:rtp_parameters",
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#include "modules/rtp_rtcp/source/absolute_capture_time_sender.h"
|
||||
#include "modules/rtp_rtcp/source/byte_io.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_dependency_descriptor_extension.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_descriptor_authentication.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_format.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
|
||||
@ -613,23 +614,24 @@ bool RTPSenderVideo::SendVideo(
|
||||
limits.last_packet_reduction_len =
|
||||
last_packet->headers_size() - middle_packet->headers_size();
|
||||
|
||||
rtc::ArrayView<const uint8_t> generic_descriptor_raw_00 =
|
||||
first_packet->GetRawExtension<RtpGenericFrameDescriptorExtension00>();
|
||||
rtc::ArrayView<const uint8_t> generic_descriptor_raw_01 =
|
||||
first_packet->GetRawExtension<RtpGenericFrameDescriptorExtension01>();
|
||||
bool has_generic_descriptor_00 =
|
||||
first_packet->HasExtension<RtpGenericFrameDescriptorExtension00>();
|
||||
bool has_generic_descriptor_01 =
|
||||
first_packet->HasExtension<RtpGenericFrameDescriptorExtension01>();
|
||||
bool has_dependency_descriptor =
|
||||
first_packet->HasExtension<RtpDependencyDescriptorExtension>();
|
||||
|
||||
if (!generic_descriptor_raw_00.empty() &&
|
||||
!generic_descriptor_raw_01.empty()) {
|
||||
if (has_generic_descriptor_00 && has_generic_descriptor_01) {
|
||||
RTC_LOG(LS_WARNING) << "Two versions of GFD extension used.";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Minimiazation of the vp8 descriptor may erase temporal_id, so save it.
|
||||
// Minimization of the vp8 descriptor may erase temporal_id, so save it.
|
||||
const uint8_t temporal_id = GetTemporalId(video_header);
|
||||
rtc::ArrayView<const uint8_t> generic_descriptor_raw =
|
||||
!generic_descriptor_raw_01.empty() ? generic_descriptor_raw_01
|
||||
: generic_descriptor_raw_00;
|
||||
if (!generic_descriptor_raw.empty()) {
|
||||
bool has_generic_descriptor = has_generic_descriptor_00 ||
|
||||
has_generic_descriptor_01 ||
|
||||
has_dependency_descriptor;
|
||||
if (has_generic_descriptor) {
|
||||
MinimizeDescriptor(&video_header);
|
||||
}
|
||||
|
||||
@ -645,7 +647,7 @@ bool RTPSenderVideo::SendVideo(
|
||||
// TODO(benwright@webrtc.org) - Allocate enough to always encrypt inline.
|
||||
rtc::Buffer encrypted_video_payload;
|
||||
if (frame_encryptor_ != nullptr) {
|
||||
if (generic_descriptor_raw.empty()) {
|
||||
if (!has_generic_descriptor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -657,9 +659,9 @@ bool RTPSenderVideo::SendVideo(
|
||||
size_t bytes_written = 0;
|
||||
|
||||
// Enable header authentication if the field trial isn't disabled.
|
||||
rtc::ArrayView<const uint8_t> additional_data;
|
||||
std::vector<uint8_t> additional_data;
|
||||
if (generic_descriptor_auth_experiment_) {
|
||||
additional_data = generic_descriptor_raw;
|
||||
additional_data = RtpDescriptorAuthentication(video_header);
|
||||
}
|
||||
|
||||
if (frame_encryptor_->Encrypt(
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "api/test/mock_frame_encryptor.h"
|
||||
#include "api/transport/rtp/dependency_descriptor.h"
|
||||
#include "api/video/video_codec_constants.h"
|
||||
#include "api/video/video_timing.h"
|
||||
@ -39,16 +40,22 @@ namespace webrtc {
|
||||
|
||||
namespace {
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::ElementsAre;
|
||||
using ::testing::ElementsAreArray;
|
||||
using ::testing::IsEmpty;
|
||||
using ::testing::NiceMock;
|
||||
using ::testing::Return;
|
||||
using ::testing::ReturnArg;
|
||||
using ::testing::SizeIs;
|
||||
using ::testing::WithArgs;
|
||||
|
||||
enum : int { // The first valid value is 1.
|
||||
kAbsoluteSendTimeExtensionId = 1,
|
||||
kFrameMarkingExtensionId,
|
||||
kGenericDescriptorId00,
|
||||
kGenericDescriptorId01,
|
||||
kGenericDescriptorId02,
|
||||
kDependencyDescriptorId,
|
||||
kTransmissionTimeOffsetExtensionId,
|
||||
kTransportSequenceNumberExtensionId,
|
||||
kVideoRotationExtensionId,
|
||||
@ -83,7 +90,7 @@ class LoopbackTransportTest : public webrtc::Transport {
|
||||
receivers_extensions_.Register<RtpGenericFrameDescriptorExtension01>(
|
||||
kGenericDescriptorId01);
|
||||
receivers_extensions_.Register<RtpDependencyDescriptorExtension>(
|
||||
kGenericDescriptorId02);
|
||||
kDependencyDescriptorId);
|
||||
receivers_extensions_.Register<FrameMarkingExtension>(
|
||||
kFrameMarkingExtensionId);
|
||||
receivers_extensions_.Register<AbsoluteCaptureTimeExtension>(
|
||||
@ -537,7 +544,7 @@ TEST_P(RtpSenderVideoTest, SendsDependencyDescriptorWhenVideoStructureIsSet) {
|
||||
const int64_t kFrameId = 100000;
|
||||
uint8_t kFrame[100];
|
||||
rtp_module_->RegisterRtpHeaderExtension(
|
||||
RtpDependencyDescriptorExtension::kUri, kGenericDescriptorId02);
|
||||
RtpDependencyDescriptorExtension::kUri, kDependencyDescriptorId);
|
||||
FrameDependencyStructure video_structure;
|
||||
video_structure.num_decode_targets = 2;
|
||||
video_structure.templates = {
|
||||
@ -606,7 +613,7 @@ TEST_P(RtpSenderVideoTest,
|
||||
const int64_t kFrameId = 100000;
|
||||
uint8_t kFrame[100];
|
||||
rtp_module_->RegisterRtpHeaderExtension(
|
||||
RtpDependencyDescriptorExtension::kUri, kGenericDescriptorId02);
|
||||
RtpDependencyDescriptorExtension::kUri, kDependencyDescriptorId);
|
||||
FrameDependencyStructure video_structure1;
|
||||
video_structure1.num_decode_targets = 2;
|
||||
video_structure1.templates = {
|
||||
@ -675,6 +682,50 @@ TEST_P(RtpSenderVideoTest,
|
||||
descriptor_key2.attached_structure.get(), &descriptor_delta));
|
||||
}
|
||||
|
||||
TEST_P(RtpSenderVideoTest,
|
||||
AuthenticateVideoHeaderWhenDependencyDescriptorExtensionIsUsed) {
|
||||
static constexpr size_t kFrameSize = 100;
|
||||
uint8_t kFrame[kFrameSize] = {1, 2, 3, 4};
|
||||
|
||||
rtp_module_->RegisterRtpHeaderExtension(
|
||||
RtpDependencyDescriptorExtension::kUri, kDependencyDescriptorId);
|
||||
rtc::scoped_refptr<MockFrameEncryptor> encryptor(
|
||||
new rtc::RefCountedObject<NiceMock<MockFrameEncryptor>>);
|
||||
ON_CALL(*encryptor, GetMaxCiphertextByteSize).WillByDefault(ReturnArg<1>());
|
||||
ON_CALL(*encryptor, Encrypt)
|
||||
.WillByDefault(WithArgs<3, 5>(
|
||||
[](rtc::ArrayView<const uint8_t> frame, size_t* bytes_written) {
|
||||
*bytes_written = frame.size();
|
||||
return 0;
|
||||
}));
|
||||
RTPSenderVideo::Config config;
|
||||
config.clock = &fake_clock_;
|
||||
config.rtp_sender = rtp_module_->RtpSender();
|
||||
config.field_trials = &field_trials_;
|
||||
config.frame_encryptor = encryptor;
|
||||
RTPSenderVideo rtp_sender_video(config);
|
||||
|
||||
FrameDependencyStructure video_structure;
|
||||
video_structure.num_decode_targets = 1;
|
||||
video_structure.templates = {GenericFrameInfo::Builder().Dtis("S").Build()};
|
||||
rtp_sender_video.SetVideoStructure(&video_structure);
|
||||
|
||||
// Send key frame.
|
||||
RTPVideoHeader hdr;
|
||||
hdr.frame_type = VideoFrameType::kVideoFrameKey;
|
||||
hdr.generic.emplace().decode_target_indications =
|
||||
video_structure.templates[0].decode_target_indications;
|
||||
|
||||
EXPECT_CALL(*encryptor,
|
||||
Encrypt(_, _, Not(IsEmpty()), ElementsAreArray(kFrame), _, _));
|
||||
rtp_sender_video.SendVideo(kPayload, kType, kTimestamp, 0, kFrame, nullptr,
|
||||
hdr, kDefaultExpectedRetransmissionTimeMs);
|
||||
// Double check packet with the dependency descriptor is sent.
|
||||
ASSERT_EQ(transport_.packets_sent(), 1);
|
||||
EXPECT_TRUE(transport_.last_sent_packet()
|
||||
.HasExtension<RtpDependencyDescriptorExtension>());
|
||||
}
|
||||
|
||||
void RtpSenderVideoTest::PopulateGenericFrameDescriptor(int version) {
|
||||
const absl::string_view ext_uri =
|
||||
(version == 0) ? RtpGenericFrameDescriptorExtension00::kUri
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user