Add option to configure raw RTP packetization per payload type.
Bug: webrtc:10625
Change-Id: I699f61af29656827eccb3c4ed507b4229dee972a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/137803
Commit-Queue: Mirta Dvornicic <mirtad@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Reviewed-by: Åsa Persson <asapersson@webrtc.org>
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28036}
diff --git a/call/rtp_config.cc b/call/rtp_config.cc
index cce78ad..f11d69c 100644
--- a/call/rtp_config.cc
+++ b/call/rtp_config.cc
@@ -76,6 +76,7 @@
ss << ", ulpfec: " << ulpfec.ToString();
ss << ", payload_name: " << payload_name;
ss << ", payload_type: " << payload_type;
+ ss << ", raw_payload: " << (raw_payload ? "true" : "false");
ss << ", flexfec: {payload_type: " << flexfec.payload_type;
ss << ", ssrc: " << flexfec.ssrc;
diff --git a/call/rtp_config.h b/call/rtp_config.h
index b6155c0..adffc89 100644
--- a/call/rtp_config.h
+++ b/call/rtp_config.h
@@ -99,6 +99,10 @@
// images to the right payload type.
std::string payload_name;
int payload_type = -1;
+ // Payload should be packetized using raw packetizer (payload header will
+ // not be added, additional meta data is expected to be present in generic
+ // frame descriptor RTP header extension).
+ bool raw_payload = false;
// See NackConfig for description.
NackConfig nack;
diff --git a/call/rtp_video_sender.cc b/call/rtp_video_sender.cc
index 796575b..332fc95 100644
--- a/call/rtp_video_sender.cc
+++ b/call/rtp_video_sender.cc
@@ -312,7 +312,8 @@
stream.rtp_rtcp->RegisterSendPayloadFrequency(rtp_config.payload_type,
kVideoPayloadTypeFrequency);
stream.sender_video->RegisterPayloadType(rtp_config.payload_type,
- rtp_config.payload_name);
+ rtp_config.payload_name,
+ rtp_config.raw_payload);
}
// Currently, both ULPFEC and FlexFEC use the same FEC rate calculation logic,
// so enable that logic if either of those FEC schemes are enabled.
diff --git a/call/video_receive_stream.cc b/call/video_receive_stream.cc
index 92787cc..e825956 100644
--- a/call/video_receive_stream.cc
+++ b/call/video_receive_stream.cc
@@ -125,6 +125,11 @@
ss << kv.first << " (pt) -> " << kv.second << " (apt), ";
}
ss << '}';
+ ss << ", raw_payload_types: {";
+ for (const auto& pt : raw_payload_types) {
+ ss << pt << ", ";
+ }
+ ss << '}';
ss << ", extensions: [";
for (size_t i = 0; i < extensions.size(); ++i) {
ss << extensions[i].ToString();
diff --git a/call/video_receive_stream.h b/call/video_receive_stream.h
index a1fa86d..5a819f9 100644
--- a/call/video_receive_stream.h
+++ b/call/video_receive_stream.h
@@ -13,6 +13,7 @@
#include <limits>
#include <map>
+#include <set>
#include <string>
#include <vector>
@@ -195,6 +196,12 @@
// For RTX to be enabled, both an SSRC and this mapping are needed.
std::map<int, int> rtx_associated_payload_types;
+ // Payload types that should be depacketized using raw depacketizer
+ // (payload header will not be parsed and must not be present, additional
+ // meta data is expected to be present in generic frame descriptor
+ // RTP header extension).
+ std::set<int> raw_payload_types;
+
// RTP header extensions used for the received stream.
std::vector<RtpExtension> extensions;
} rtp;
diff --git a/modules/rtp_rtcp/source/nack_rtx_unittest.cc b/modules/rtp_rtcp/source/nack_rtx_unittest.cc
index 2ae324c..f8fd39a 100644
--- a/modules/rtp_rtcp/source/nack_rtx_unittest.cc
+++ b/modules/rtp_rtcp/source/nack_rtx_unittest.cc
@@ -151,7 +151,8 @@
// single rtp_rtcp module for both send and receive side.
rtp_rtcp_module_->SetRemoteSSRC(kTestSsrc);
- rtp_sender_video_->RegisterPayloadType(kPayloadType, "video");
+ rtp_sender_video_->RegisterPayloadType(kPayloadType, "video",
+ /*raw_payload=*/false);
rtp_rtcp_module_->SetRtxSendPayloadType(kRtxPayloadType, kPayloadType);
transport_.SetSendModule(rtp_rtcp_module_.get());
media_receiver_ = transport_.stream_receiver_controller_.CreateReceiver(
diff --git a/modules/rtp_rtcp/source/rtp_format.cc b/modules/rtp_rtcp/source/rtp_format.cc
index 843cbb8..e870232 100644
--- a/modules/rtp_rtcp/source/rtp_format.cc
+++ b/modules/rtp_rtcp/source/rtp_format.cc
@@ -24,14 +24,19 @@
namespace webrtc {
std::unique_ptr<RtpPacketizer> RtpPacketizer::Create(
- VideoCodecType type,
+ absl::optional<VideoCodecType> type,
rtc::ArrayView<const uint8_t> payload,
PayloadSizeLimits limits,
// Codec-specific details.
const RTPVideoHeader& rtp_video_header,
VideoFrameType frame_type,
const RTPFragmentationHeader* fragmentation) {
- switch (type) {
+ if (!type) {
+ // Use raw packetizer.
+ return absl::make_unique<RtpPacketizerGeneric>(payload, limits);
+ }
+
+ switch (*type) {
case kVideoCodecH264: {
RTC_CHECK(fragmentation);
const auto& h264 =
@@ -133,8 +138,13 @@
return result;
}
-RtpDepacketizer* RtpDepacketizer::Create(VideoCodecType type) {
- switch (type) {
+RtpDepacketizer* RtpDepacketizer::Create(absl::optional<VideoCodecType> type) {
+ if (!type) {
+ // Use raw depacketizer.
+ return new RtpDepacketizerGeneric(/*generic_header_enabled=*/false);
+ }
+
+ switch (*type) {
case kVideoCodecH264:
return new RtpDepacketizerH264();
case kVideoCodecVP8:
@@ -145,4 +155,5 @@
return new RtpDepacketizerGeneric(/*generic_header_enabled=*/true);
}
}
+
} // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtp_format.h b/modules/rtp_rtcp/source/rtp_format.h
index f9c1e76..b28e9a6 100644
--- a/modules/rtp_rtcp/source/rtp_format.h
+++ b/modules/rtp_rtcp/source/rtp_format.h
@@ -15,6 +15,7 @@
#include <memory>
#include <vector>
+#include "absl/types/optional.h"
#include "api/array_view.h"
#include "modules/include/module_common_types.h"
#include "modules/rtp_rtcp/source/rtp_video_header.h"
@@ -32,8 +33,10 @@
// Reduction len for packet that is first & last at the same time.
int single_packet_reduction_len = 0;
};
+
+ // If type is not set, returns a raw packetizer.
static std::unique_ptr<RtpPacketizer> Create(
- VideoCodecType type,
+ absl::optional<VideoCodecType> type,
rtc::ArrayView<const uint8_t> payload,
PayloadSizeLimits limits,
// Codec-specific details.
@@ -79,7 +82,8 @@
size_t payload_length;
};
- static RtpDepacketizer* Create(VideoCodecType type);
+ // If type is not set, returns a raw depacketizer.
+ static RtpDepacketizer* Create(absl::optional<VideoCodecType> type);
virtual ~RtpDepacketizer() {}
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc
index 28712c5..09f8dbd 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc
@@ -193,7 +193,8 @@
codec_.plType = 100;
codec_.width = 320;
codec_.height = 180;
- sender_video_->RegisterPayloadType(codec_.plType, "VP8");
+ sender_video_->RegisterPayloadType(codec_.plType, "VP8",
+ /*raw_payload=*/false);
// Receive module.
EXPECT_EQ(0, receiver_.impl_->SetSendingStatus(false));
diff --git a/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_unittest.cc
index 9ac23fc..3d1bed4 100644
--- a/modules/rtp_rtcp/source/rtp_sender_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_unittest.cc
@@ -521,7 +521,8 @@
const uint8_t kPayloadType = 127;
const char payload_name[] = "GENERIC";
- rtp_sender_video.RegisterPayloadType(kPayloadType, payload_name);
+ rtp_sender_video.RegisterPayloadType(kPayloadType, payload_name,
+ /*raw_payload=*/false);
const uint32_t kCaptureTimeMsToRtpTimestamp = 90; // 90 kHz clock
RTPVideoHeader video_header;
@@ -1099,7 +1100,8 @@
RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
&playout_delay_oracle, nullptr, false,
FieldTrialBasedConfig());
- rtp_sender_video.RegisterPayloadType(payload_type, payload_name);
+ rtp_sender_video.RegisterPayloadType(payload_type, payload_name,
+ /*raw_payload=*/false);
uint8_t payload[] = {47, 11, 32, 93, 89};
// Send keyframe
@@ -1132,6 +1134,29 @@
EXPECT_THAT(sent_payload.subview(1), ElementsAreArray(payload));
}
+TEST_P(RtpSenderTestWithoutPacer, SendRawVideo) {
+ const char payload_name[] = "VP8";
+ const uint8_t payload_type = 111;
+ const uint8_t payload[] = {11, 22, 33, 44, 55};
+
+ PlayoutDelayOracle playout_delay_oracle;
+ RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
+ &playout_delay_oracle, nullptr, false,
+ FieldTrialBasedConfig());
+ rtp_sender_video.RegisterPayloadType(payload_type, payload_name,
+ /*raw_payload=*/true);
+
+ // Send a frame.
+ RTPVideoHeader video_header;
+ ASSERT_TRUE(rtp_sender_video.SendVideo(
+ VideoFrameType::kVideoFrameKey, payload_type, 1234, 4321, payload,
+ sizeof(payload), nullptr, &video_header,
+ kDefaultExpectedRetransmissionTimeMs));
+
+ auto sent_payload = transport_.last_sent_packet().payload();
+ EXPECT_THAT(sent_payload, ElementsAreArray(payload));
+}
+
TEST_P(RtpSenderTest, SendFlexfecPackets) {
constexpr uint32_t kTimestamp = 1234;
constexpr int kMediaPayloadType = 127;
@@ -1158,7 +1183,8 @@
RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(),
&flexfec_sender, &playout_delay_oracle,
nullptr, false, FieldTrialBasedConfig());
- rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC");
+ rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC",
+ /*raw_payload=*/false);
// Parameters selected to generate a single FEC packet per media packet.
FecProtectionParams params;
@@ -1234,7 +1260,8 @@
RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(),
&flexfec_sender, &playout_delay_oracle,
nullptr, false, FieldTrialBasedConfig());
- rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC");
+ rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC",
+ /*raw_payload=*/false);
// Need extension to be registered for timing frames to be sent.
ASSERT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
@@ -1335,7 +1362,8 @@
RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(),
&flexfec_sender, &playout_delay_oracle,
nullptr, false, FieldTrialBasedConfig());
- rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC");
+ rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC",
+ /*raw_payload=*/false);
// Parameters selected to generate a single FEC packet per media packet.
FecProtectionParams params;
@@ -1465,7 +1493,8 @@
RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(),
&flexfec_sender, &playout_delay_oracle,
nullptr, false, FieldTrialBasedConfig());
- rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC");
+ rtp_sender_video.RegisterPayloadType(kMediaPayloadType, "GENERIC",
+ /*raw_payload=*/false);
// Parameters selected to generate a single FEC packet per media packet.
FecProtectionParams params;
params.fec_rate = 15;
@@ -1537,7 +1566,8 @@
FieldTrialBasedConfig());
const char payload_name[] = "GENERIC";
const uint8_t payload_type = 127;
- rtp_sender_video.RegisterPayloadType(payload_type, payload_name);
+ rtp_sender_video.RegisterPayloadType(payload_type, payload_name,
+ /*raw_payload=*/false);
// Simulate kNumPackets sent with kPacketInterval ms intervals, with the
// number of packets selected so that we fill (but don't overflow) the one
@@ -1623,7 +1653,8 @@
RTPSenderVideo rtp_sender_video(&fake_clock_, rtp_sender_.get(), nullptr,
&playout_delay_oracle, nullptr, false,
FieldTrialBasedConfig());
- rtp_sender_video.RegisterPayloadType(payload_type, payload_name);
+ rtp_sender_video.RegisterPayloadType(payload_type, payload_name,
+ /*raw_payload=*/false);
uint8_t payload[] = {47, 11, 32, 93, 89};
rtp_sender_->SetStorePacketsStatus(true, 1);
uint32_t ssrc = rtp_sender_->SSRC();
diff --git a/modules/rtp_rtcp/source/rtp_sender_video.cc b/modules/rtp_rtcp/source/rtp_sender_video.cc
index a71a6e5..8d12ff4 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_video.cc
@@ -24,9 +24,7 @@
#include "modules/remote_bitrate_estimator/test/bwe_test_logging.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/byte_io.h"
-#include "modules/rtp_rtcp/source/rtp_format_video_generic.h"
-#include "modules/rtp_rtcp/source/rtp_format_vp8.h"
-#include "modules/rtp_rtcp/source/rtp_format_vp9.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"
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
@@ -224,28 +222,28 @@
RTPSenderVideo::~RTPSenderVideo() {}
void RTPSenderVideo::RegisterPayloadType(int8_t payload_type,
- absl::string_view payload_name) {
- VideoCodecType video_type;
-
- if (absl::EqualsIgnoreCase(payload_name, "VP8")) {
- video_type = kVideoCodecVP8;
- } else if (absl::EqualsIgnoreCase(payload_name, "VP9")) {
- video_type = kVideoCodecVP9;
- } else if (absl::EqualsIgnoreCase(payload_name, "H264")) {
- video_type = kVideoCodecH264;
- } else if (absl::EqualsIgnoreCase(payload_name, "I420")) {
- video_type = kVideoCodecGeneric;
- } else if (absl::EqualsIgnoreCase(payload_name, "stereo")) {
- video_type = kVideoCodecGeneric;
- } else {
- video_type = kVideoCodecGeneric;
+ absl::string_view payload_name,
+ bool raw_payload) {
+ absl::optional<VideoCodecType> video_type;
+ if (!raw_payload) {
+ if (absl::EqualsIgnoreCase(payload_name, "VP8")) {
+ video_type = kVideoCodecVP8;
+ } else if (absl::EqualsIgnoreCase(payload_name, "VP9")) {
+ video_type = kVideoCodecVP9;
+ } else if (absl::EqualsIgnoreCase(payload_name, "H264")) {
+ video_type = kVideoCodecH264;
+ } else {
+ video_type = kVideoCodecGeneric;
+ }
}
- rtc::CritScope cs(&payload_type_crit_);
- payload_type_map_[payload_type] = video_type;
+ {
+ rtc::CritScope cs(&payload_type_crit_);
+ payload_type_map_[payload_type] = video_type;
+ }
// Backward compatibility for older receivers without temporal layer logic
- if (video_type == kVideoCodecH264) {
+ if (absl::EqualsIgnoreCase(payload_name, "H264")) {
rtc::CritScope cs(&crit_);
retransmission_settings_ = kRetransmitBaseLayer | kRetransmitHigherLayers;
}
@@ -613,7 +611,7 @@
<< "one is required since require_frame_encryptor is set";
}
- VideoCodecType video_type;
+ absl::optional<VideoCodecType> type;
{
rtc::CritScope cs(&payload_type_crit_);
const auto it = payload_type_map_.find(payload_type);
@@ -622,10 +620,10 @@
<< " not registered.";
return false;
}
- video_type = it->second;
+ type = it->second;
}
std::unique_ptr<RtpPacketizer> packetizer = RtpPacketizer::Create(
- video_type, rtc::MakeArrayView(payload_data, payload_size), limits,
+ type, rtc::MakeArrayView(payload_data, payload_size), limits,
*packetize_video_header, frame_type, fragmentation);
const uint8_t temporal_id = GetTemporalId(*video_header);
diff --git a/modules/rtp_rtcp/source/rtp_sender_video.h b/modules/rtp_rtcp/source/rtp_sender_video.h
index cc7c1fa..bdbe90a 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video.h
+++ b/modules/rtp_rtcp/source/rtp_sender_video.h
@@ -71,7 +71,9 @@
const RTPVideoHeader* video_header,
int64_t expected_retransmission_time_ms);
- void RegisterPayloadType(int8_t payload_type, absl::string_view payload_name);
+ void RegisterPayloadType(int8_t payload_type,
+ absl::string_view payload_name,
+ bool raw_payload);
// Set RED and ULPFEC payload types. A payload type of -1 means that the
// corresponding feature is turned off. Note that we DO NOT support enabling
@@ -162,7 +164,7 @@
// Maps payload type to codec type, for packetization.
// TODO(nisse): Set on construction, to avoid lock.
rtc::CriticalSection payload_type_crit_;
- std::map<int8_t, VideoCodecType> payload_type_map_
+ std::map<int8_t, absl::optional<VideoCodecType>> payload_type_map_
RTC_GUARDED_BY(payload_type_crit_);
// Should never be held when calling out of this class.
diff --git a/modules/rtp_rtcp/source/rtp_sender_video_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_video_unittest.cc
index b54934c..9864ecb 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_video_unittest.cc
@@ -163,7 +163,8 @@
rtp_sender_.SetTimestampOffset(0);
rtp_sender_.SetSSRC(kSsrc);
- rtp_sender_video_.RegisterPayloadType(kPayload, "generic");
+ rtp_sender_video_.RegisterPayloadType(kPayload, "generic",
+ /*raw_payload=*/false);
}
void PopulateGenericFrameDescriptor(int version);
@@ -618,7 +619,7 @@
vp8.keyIdx = 2;
RTPVideoHeader::GenericDescriptorInfo& generic = hdr.generic.emplace();
generic.frame_id = kFrameId;
- rtp_sender_video_.RegisterPayloadType(kPayload, "vp8");
+ rtp_sender_video_.RegisterPayloadType(kPayload, "vp8", /*raw_payload=*/false);
rtp_sender_video_.SendVideo(VideoFrameType::kVideoFrameDelta, kPayload,
kTimestamp, 0, kFrame, sizeof(kFrame), nullptr,
&hdr, kDefaultExpectedRetransmissionTimeMs);
diff --git a/video/rtp_video_stream_receiver.cc b/video/rtp_video_stream_receiver.cc
index edced5d..e12bd5c 100644
--- a/video/rtp_video_stream_receiver.cc
+++ b/video/rtp_video_stream_receiver.cc
@@ -193,8 +193,13 @@
void RtpVideoStreamReceiver::AddReceiveCodec(
const VideoCodec& video_codec,
- const std::map<std::string, std::string>& codec_params) {
- pt_codec_type_.emplace(video_codec.plType, video_codec.codecType);
+ const std::map<std::string, std::string>& codec_params,
+ bool raw_payload) {
+ absl::optional<VideoCodecType> video_type;
+ if (!raw_payload) {
+ video_type = video_codec.codecType;
+ }
+ payload_type_map_.emplace(video_codec.plType, video_type);
pt_codec_params_.emplace(video_codec.plType, codec_params);
}
@@ -503,12 +508,12 @@
return;
}
- const auto codec_type_it = pt_codec_type_.find(packet.PayloadType());
- if (codec_type_it == pt_codec_type_.end()) {
+ const auto type_it = payload_type_map_.find(packet.PayloadType());
+ if (type_it == payload_type_map_.end()) {
return;
}
auto depacketizer =
- absl::WrapUnique(RtpDepacketizer::Create(codec_type_it->second));
+ absl::WrapUnique(RtpDepacketizer::Create(type_it->second));
if (!depacketizer) {
RTC_LOG(LS_ERROR) << "Failed to create depacketizer.";
diff --git a/video/rtp_video_stream_receiver.h b/video/rtp_video_stream_receiver.h
index fdacca9..237a514 100644
--- a/video/rtp_video_stream_receiver.h
+++ b/video/rtp_video_stream_receiver.h
@@ -82,7 +82,8 @@
~RtpVideoStreamReceiver() override;
void AddReceiveCodec(const VideoCodec& video_codec,
- const std::map<std::string, std::string>& codec_params);
+ const std::map<std::string, std::string>& codec_params,
+ bool raw_payload);
void StartReceive();
void StopReceive();
@@ -214,7 +215,9 @@
RTC_GUARDED_BY(last_seq_num_cs_);
video_coding::H264SpsPpsTracker tracker_;
- std::map<uint8_t, VideoCodecType> pt_codec_type_;
+ // Maps payload type to codec type, for packetization.
+ std::map<uint8_t, absl::optional<VideoCodecType>> payload_type_map_;
+
// TODO(johan): Remove pt_codec_params_ once
// https://bugs.chromium.org/p/webrtc/issues/detail?id=6883 is resolved.
// Maps a payload type to a map of out-of-band supplied codec parameters.
diff --git a/video/rtp_video_stream_receiver_unittest.cc b/video/rtp_video_stream_receiver_unittest.cc
index 1133560..d9c1071 100644
--- a/video/rtp_video_stream_receiver_unittest.cc
+++ b/video/rtp_video_stream_receiver_unittest.cc
@@ -278,7 +278,8 @@
codec.plType = kPayloadType;
codec.codecType = kVideoCodecVP9;
std::map<std::string, std::string> codec_params;
- rtp_video_stream_receiver_->AddReceiveCodec(codec, codec_params);
+ rtp_video_stream_receiver_->AddReceiveCodec(codec, codec_params,
+ /*raw_payload=*/false);
// Generate key frame packets.
received_packet_generator.SetPayload(kKeyFramePayload,
@@ -345,7 +346,7 @@
const uint8_t kRedPayloadType = 125;
VideoCodec codec;
codec.plType = kRedPayloadType;
- rtp_video_stream_receiver_->AddReceiveCodec(codec, {});
+ rtp_video_stream_receiver_->AddReceiveCodec(codec, {}, /*raw_payload=*/false);
const std::vector<uint8_t> data({
0x80, // RTP version.
kRedPayloadType, // Payload type.
@@ -469,7 +470,8 @@
// .
codec_params.insert(
{cricket::kH264FmtpSpropParameterSets, "Z0IACpZTBYmI,aMljiA=="});
- rtp_video_stream_receiver_->AddReceiveCodec(codec, codec_params);
+ rtp_video_stream_receiver_->AddReceiveCodec(codec, codec_params,
+ /*raw_payload=*/false);
const uint8_t binary_sps[] = {0x67, 0x42, 0x00, 0x0a, 0x96,
0x53, 0x05, 0x89, 0x88};
mock_on_complete_frame_callback_.AppendExpectedBitstream(
@@ -683,7 +685,7 @@
VideoCodec codec;
codec.plType = kPayloadType;
- rtp_video_stream_receiver_->AddReceiveCodec(codec, {});
+ rtp_video_stream_receiver_->AddReceiveCodec(codec, {}, /*raw_payload=*/false);
rtp_video_stream_receiver_->StartReceive();
RtpHeaderExtensionMap extension_map;
@@ -731,7 +733,7 @@
VideoCodec codec;
codec.plType = kPayloadType;
- rtp_video_stream_receiver_->AddReceiveCodec(codec, {});
+ rtp_video_stream_receiver_->AddReceiveCodec(codec, {}, /*raw_payload=*/false);
rtp_video_stream_receiver_->StartReceive();
RtpHeaderExtensionMap extension_map;
@@ -792,7 +794,7 @@
VideoCodec codec;
codec.plType = kPayloadType;
- rtp_video_stream_receiver_->AddReceiveCodec(codec, {});
+ rtp_video_stream_receiver_->AddReceiveCodec(codec, {}, /*raw_payload=*/false);
rtp_video_stream_receiver_->StartReceive();
RtpHeaderExtensionMap extension_map;
@@ -824,6 +826,41 @@
rtp_video_stream_receiver_->OnRtpPacket(rtp_packet);
}
+TEST_P(RtpVideoStreamReceiverGenericDescriptorTest,
+ ParseGenericDescriptorRawPayload) {
+ const int version = GetParam();
+
+ const std::vector<uint8_t> data = {0, 1, 2, 3, 4};
+ const int kPayloadType = 123;
+
+ VideoCodec codec;
+ codec.plType = kPayloadType;
+ rtp_video_stream_receiver_->AddReceiveCodec(codec, {}, /*raw_payload=*/true);
+ rtp_video_stream_receiver_->StartReceive();
+
+ RtpHeaderExtensionMap extension_map;
+ RegisterRtpGenericFrameDescriptorExtension(&extension_map, version);
+ RtpPacketReceived rtp_packet(&extension_map);
+
+ RtpGenericFrameDescriptor generic_descriptor;
+ generic_descriptor.SetFirstPacketInSubFrame(true);
+ generic_descriptor.SetLastPacketInSubFrame(true);
+ ASSERT_TRUE(SetExtensionRtpGenericFrameDescriptorExtension(
+ generic_descriptor, &rtp_packet, version));
+
+ uint8_t* payload = rtp_packet.SetPayloadSize(data.size());
+ memcpy(payload, data.data(), data.size());
+ mock_on_complete_frame_callback_.AppendExpectedBitstream(data.data(),
+ data.size());
+
+ rtp_packet.SetMarker(true);
+ rtp_packet.SetPayloadType(kPayloadType);
+ rtp_packet.SetSequenceNumber(1);
+
+ EXPECT_CALL(mock_on_complete_frame_callback_, DoOnCompleteFrame);
+ rtp_video_stream_receiver_->OnRtpPacket(rtp_packet);
+}
+
#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
TEST_F(RtpVideoStreamReceiverTest, RepeatedSecondarySinkDisallowed) {
MockRtpPacketSink secondary_sink;
diff --git a/video/video_receive_stream.cc b/video/video_receive_stream.cc
index 20a1967..176b682 100644
--- a/video/video_receive_stream.cc
+++ b/video/video_receive_stream.cc
@@ -367,8 +367,11 @@
video_receiver_.RegisterExternalDecoder(video_decoders_.back().get(),
decoder.payload_type);
VideoCodec codec = CreateDecoderVideoCodec(decoder);
- rtp_video_stream_receiver_.AddReceiveCodec(codec,
- decoder.video_format.parameters);
+
+ const bool raw_payload =
+ config_.rtp.raw_payload_types.count(codec.plType) > 0;
+ rtp_video_stream_receiver_.AddReceiveCodec(
+ codec, decoder.video_format.parameters, raw_payload);
RTC_CHECK_EQ(VCM_OK, video_receiver_.RegisterReceiveCodec(
&codec, num_cpu_cores_, false));
}