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}
This commit is contained in:

committed by
Commit Bot

parent
a352248c43
commit
fe68daab97
@ -76,6 +76,7 @@ std::string RtpConfig::ToString() const {
|
||||
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;
|
||||
|
@ -99,6 +99,10 @@ struct RtpConfig {
|
||||
// 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;
|
||||
|
@ -312,7 +312,8 @@ RtpVideoSender::RtpVideoSender(
|
||||
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.
|
||||
|
@ -125,6 +125,11 @@ std::string VideoReceiveStream::Config::Rtp::ToString() const {
|
||||
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();
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@ -195,6 +196,12 @@ class VideoReceiveStream {
|
||||
// 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;
|
||||
|
@ -151,7 +151,8 @@ class RtpRtcpRtxNackTest : public ::testing::Test {
|
||||
// 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(
|
||||
|
@ -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 @@ std::vector<int> RtpPacketizer::SplitAboutEqually(
|
||||
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 @@ RtpDepacketizer* RtpDepacketizer::Create(VideoCodecType type) {
|
||||
return new RtpDepacketizerGeneric(/*generic_header_enabled=*/true);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
@ -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 @@ class RtpPacketizer {
|
||||
// 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 @@ class RtpDepacketizer {
|
||||
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() {}
|
||||
|
||||
|
@ -193,7 +193,8 @@ class RtpRtcpImplTest : public ::testing::Test {
|
||||
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));
|
||||
|
@ -521,7 +521,8 @@ TEST_P(RtpSenderTestWithoutPacer, OnSendSideDelayUpdated) {
|
||||
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 @@ TEST_P(RtpSenderTestWithoutPacer, SendGenericVideo) {
|
||||
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 @@ TEST_P(RtpSenderTestWithoutPacer, SendGenericVideo) {
|
||||
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 @@ TEST_P(RtpSenderTest, SendFlexfecPackets) {
|
||||
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 @@ TEST_P(RtpSenderTest, NoFlexfecForTimingFrames) {
|
||||
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 @@ TEST_P(RtpSenderTestWithoutPacer, SendFlexfecPackets) {
|
||||
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 @@ TEST_P(RtpSenderTest, FecOverheadRate) {
|
||||
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 @@ TEST_P(RtpSenderTest, BitrateCallbacks) {
|
||||
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 @@ TEST_P(RtpSenderTestWithoutPacer, StreamDataCountersCallbacks) {
|
||||
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();
|
||||
|
@ -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(Clock* clock,
|
||||
RTPSenderVideo::~RTPSenderVideo() {}
|
||||
|
||||
void RTPSenderVideo::RegisterPayloadType(int8_t payload_type,
|
||||
absl::string_view payload_name) {
|
||||
VideoCodecType video_type;
|
||||
|
||||
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 if (absl::EqualsIgnoreCase(payload_name, "I420")) {
|
||||
video_type = kVideoCodecGeneric;
|
||||
} else if (absl::EqualsIgnoreCase(payload_name, "stereo")) {
|
||||
video_type = kVideoCodecGeneric;
|
||||
} else {
|
||||
video_type = kVideoCodecGeneric;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
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 @@ bool RTPSenderVideo::SendVideo(VideoFrameType frame_type,
|
||||
<< "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 @@ bool RTPSenderVideo::SendVideo(VideoFrameType frame_type,
|
||||
<< " 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);
|
||||
|
@ -71,7 +71,9 @@ class RTPSenderVideo {
|
||||
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 @@ class RTPSenderVideo {
|
||||
// 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.
|
||||
|
@ -163,7 +163,8 @@ class RtpSenderVideoTest : public ::testing::TestWithParam<bool> {
|
||||
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 @@ void RtpSenderVideoTest::
|
||||
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);
|
||||
|
@ -193,8 +193,13 @@ RtpVideoStreamReceiver::~RtpVideoStreamReceiver() {
|
||||
|
||||
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 @@ void RtpVideoStreamReceiver::ReceivePacket(const RtpPacketReceived& packet) {
|
||||
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.";
|
||||
|
@ -82,7 +82,8 @@ class RtpVideoStreamReceiver : public LossNotificationSender,
|
||||
~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 @@ class RtpVideoStreamReceiver : public LossNotificationSender,
|
||||
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.
|
||||
|
@ -278,7 +278,8 @@ TEST_F(RtpVideoStreamReceiverTest, CacheColorSpaceFromLastPacketOfKeyframe) {
|
||||
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 @@ TEST_F(RtpVideoStreamReceiverTest, NoInfiniteRecursionOnEncapsulatedRedPacket) {
|
||||
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 @@ TEST_P(RtpVideoStreamReceiverTestH264, OutOfBandFmtpSpsPps) {
|
||||
// .
|
||||
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 @@ TEST_P(RtpVideoStreamReceiverGenericDescriptorTest,
|
||||
|
||||
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 @@ TEST_P(RtpVideoStreamReceiverGenericDescriptorTest,
|
||||
|
||||
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 @@ TEST_F(RtpVideoStreamReceiverGenericDescriptorTest,
|
||||
|
||||
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 @@ TEST_F(RtpVideoStreamReceiverGenericDescriptorTest,
|
||||
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;
|
||||
|
@ -367,8 +367,11 @@ void VideoReceiveStream::Start() {
|
||||
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));
|
||||
}
|
||||
|
Reference in New Issue
Block a user