Add extended header containing frame ID to the generic packetizer.

Also changes default value of frame ID in RTPVideoHeader to
kNoPictureId. Special care should be take so that picture ID will not
be set in RTPVideoHeader unless the client on the end supports
deserializing extended generic header.

Bug: webrtc:9582
Change-Id: Ib096373ed187f31e51d481193a2bda56de68f167
Reviewed-on: https://webrtc-review.googlesource.com/92084
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Commit-Queue: Sami Kalliomäki <sakal@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24250}
This commit is contained in:
Sami Kalliomäki
2018-08-08 11:37:59 +02:00
committed by Commit Bot
parent 9489c3a2ea
commit 426a80ce08
8 changed files with 185 additions and 46 deletions

View File

@ -202,9 +202,10 @@ class RtpRtcpRtxNackTest : public ::testing::Test {
uint32_t timestamp = 3000; uint32_t timestamp = 3000;
uint16_t nack_list[kVideoNackListSize]; uint16_t nack_list[kVideoNackListSize];
for (int frame = 0; frame < kNumFrames; ++frame) { for (int frame = 0; frame < kNumFrames; ++frame) {
RTPVideoHeader video_header;
EXPECT_TRUE(rtp_rtcp_module_->SendOutgoingData( EXPECT_TRUE(rtp_rtcp_module_->SendOutgoingData(
webrtc::kVideoFrameDelta, kPayloadType, timestamp, timestamp / 90, webrtc::kVideoFrameDelta, kPayloadType, timestamp, timestamp / 90,
payload_data, payload_data_length, nullptr, nullptr, nullptr)); payload_data, payload_data_length, nullptr, &video_header, nullptr));
// Min required delay until retransmit = 5 + RTT ms (RTT = 0). // Min required delay until retransmit = 5 + RTT ms (RTT = 0).
fake_clock.AdvanceTimeMilliseconds(5); fake_clock.AdvanceTimeMilliseconds(5);
int length = BuildNackList(nack_list); int length = BuildNackList(nack_list);
@ -250,9 +251,10 @@ TEST_F(RtpRtcpRtxNackTest, LongNackList) {
// Send 30 frames which at the default size is roughly what we need to get // Send 30 frames which at the default size is roughly what we need to get
// enough packets. // enough packets.
for (int frame = 0; frame < kNumFrames; ++frame) { for (int frame = 0; frame < kNumFrames; ++frame) {
RTPVideoHeader video_header;
EXPECT_TRUE(rtp_rtcp_module_->SendOutgoingData( EXPECT_TRUE(rtp_rtcp_module_->SendOutgoingData(
webrtc::kVideoFrameDelta, kPayloadType, timestamp, timestamp / 90, webrtc::kVideoFrameDelta, kPayloadType, timestamp, timestamp / 90,
payload_data, payload_data_length, nullptr, nullptr, nullptr)); payload_data, payload_data_length, nullptr, &video_header, nullptr));
// Prepare next frame. // Prepare next frame.
timestamp += 3000; timestamp += 3000;
fake_clock.AdvanceTimeMilliseconds(33); fake_clock.AdvanceTimeMilliseconds(33);

View File

@ -41,7 +41,9 @@ RtpPacketizer* RtpPacketizer::Create(VideoCodecType type,
last_packet_reduction_len); last_packet_reduction_len);
} }
case kVideoCodecGeneric: case kVideoCodecGeneric:
return new RtpPacketizerGeneric(frame_type, max_payload_len, RTC_CHECK(rtp_video_header);
return new RtpPacketizerGeneric(*rtp_video_header, frame_type,
max_payload_len,
last_packet_reduction_len); last_packet_reduction_len);
default: default:
RTC_NOTREACHED(); RTC_NOTREACHED();

View File

@ -18,13 +18,21 @@
namespace webrtc { namespace webrtc {
static const size_t kGenericHeaderLength = 1; static const size_t kGenericHeaderLength = 1;
static const size_t kExtendedHeaderLength = 2;
RtpPacketizerGeneric::RtpPacketizerGeneric(FrameType frame_type, RtpPacketizerGeneric::RtpPacketizerGeneric(
size_t max_payload_len, const RTPVideoHeader& rtp_video_header,
size_t last_packet_reduction_len) FrameType frame_type,
: payload_data_(NULL), size_t max_payload_len,
size_t last_packet_reduction_len)
: picture_id_(
rtp_video_header.frame_id != kNoPictureId
? absl::optional<uint16_t>(rtp_video_header.frame_id & 0x7FFF)
: absl::nullopt),
payload_data_(nullptr),
payload_size_(0), payload_size_(0),
max_payload_len_(max_payload_len - kGenericHeaderLength), max_payload_len_(max_payload_len - kGenericHeaderLength -
(picture_id_.has_value() ? kExtendedHeaderLength : 0)),
last_packet_reduction_len_(last_packet_reduction_len), last_packet_reduction_len_(last_packet_reduction_len),
frame_type_(frame_type), frame_type_(frame_type),
num_packets_left_(0), num_packets_left_(0),
@ -62,6 +70,10 @@ size_t RtpPacketizerGeneric::SetPayloadData(
if (frame_type_ == kVideoFrameKey) { if (frame_type_ == kVideoFrameKey) {
generic_header_ |= RtpFormatVideoGeneric::kKeyFrameBit; generic_header_ |= RtpFormatVideoGeneric::kKeyFrameBit;
} }
if (picture_id_.has_value()) {
generic_header_ |= RtpFormatVideoGeneric::kExtendedHeaderBit;
}
return num_packets_left_; return num_packets_left_;
} }
@ -86,16 +98,24 @@ bool RtpPacketizerGeneric::NextPacket(RtpPacketToSend* packet) {
} }
RTC_DCHECK_LE(next_packet_payload_len, max_payload_len_); RTC_DCHECK_LE(next_packet_payload_len, max_payload_len_);
uint8_t* out_ptr = size_t total_length = next_packet_payload_len + kGenericHeaderLength +
packet->AllocatePayload(kGenericHeaderLength + next_packet_payload_len); (picture_id_.has_value() ? kExtendedHeaderLength : 0);
uint8_t* out_ptr = packet->AllocatePayload(total_length);
// Put generic header in packet. // Put generic header in packet.
out_ptr[0] = generic_header_; out_ptr[0] = generic_header_;
out_ptr += kGenericHeaderLength;
if (picture_id_.has_value()) {
WriteExtendedHeader(out_ptr);
out_ptr += kExtendedHeaderLength;
}
// Remove first-packet bit, following packets are intermediate. // Remove first-packet bit, following packets are intermediate.
generic_header_ &= ~RtpFormatVideoGeneric::kFirstPacketBit; generic_header_ &= ~RtpFormatVideoGeneric::kFirstPacketBit;
// Put payload in packet. // Put payload in packet.
memcpy(out_ptr + kGenericHeaderLength, payload_data_, memcpy(out_ptr, payload_data_, next_packet_payload_len);
next_packet_payload_len);
payload_data_ += next_packet_payload_len; payload_data_ += next_packet_payload_len;
payload_size_ -= next_packet_payload_len; payload_size_ -= next_packet_payload_len;
--num_packets_left_; --num_packets_left_;
@ -111,6 +131,13 @@ std::string RtpPacketizerGeneric::ToString() {
return "RtpPacketizerGeneric"; return "RtpPacketizerGeneric";
} }
void RtpPacketizerGeneric::WriteExtendedHeader(uint8_t* out_ptr) {
// Store bottom 15 bits of the the sequence number. Only 15 bits are used for
// compatibility with other packetizer implemenetations that also use 15 bits.
out_ptr[0] = (*picture_id_ >> 8) & 0x7F;
out_ptr[1] = *picture_id_ & 0xFF;
}
RtpDepacketizerGeneric::~RtpDepacketizerGeneric() = default; RtpDepacketizerGeneric::~RtpDepacketizerGeneric() = default;
bool RtpDepacketizerGeneric::Parse(ParsedPayload* parsed_payload, bool RtpDepacketizerGeneric::Parse(ParsedPayload* parsed_payload,
@ -118,7 +145,7 @@ bool RtpDepacketizerGeneric::Parse(ParsedPayload* parsed_payload,
size_t payload_data_length) { size_t payload_data_length) {
assert(parsed_payload != NULL); assert(parsed_payload != NULL);
if (payload_data_length == 0) { if (payload_data_length == 0) {
RTC_LOG(LS_ERROR) << "Empty payload."; RTC_LOG(LS_WARNING) << "Empty payload.";
return false; return false;
} }
@ -135,6 +162,17 @@ bool RtpDepacketizerGeneric::Parse(ParsedPayload* parsed_payload,
parsed_payload->video_header().width = 0; parsed_payload->video_header().width = 0;
parsed_payload->video_header().height = 0; parsed_payload->video_header().height = 0;
if (generic_header & RtpFormatVideoGeneric::kExtendedHeaderBit) {
if (payload_data_length < kExtendedHeaderLength) {
RTC_LOG(LS_WARNING) << "Too short payload for generic header.";
return false;
}
parsed_payload->video_header().frame_id =
((payload_data[0] & 0x7F) << 8) | payload_data[1];
payload_data += kExtendedHeaderLength;
payload_data_length -= kExtendedHeaderLength;
}
parsed_payload->payload = payload_data; parsed_payload->payload = payload_data;
parsed_payload->payload_length = payload_data_length; parsed_payload->payload_length = payload_data_length;
return true; return true;

View File

@ -20,13 +20,17 @@ namespace webrtc {
namespace RtpFormatVideoGeneric { namespace RtpFormatVideoGeneric {
static const uint8_t kKeyFrameBit = 0x01; static const uint8_t kKeyFrameBit = 0x01;
static const uint8_t kFirstPacketBit = 0x02; static const uint8_t kFirstPacketBit = 0x02;
// If this bit is set, there will be an extended header contained in this
// packet. This was added later so old clients will not send this.
static const uint8_t kExtendedHeaderBit = 0x04;
} // namespace RtpFormatVideoGeneric } // namespace RtpFormatVideoGeneric
class RtpPacketizerGeneric : public RtpPacketizer { class RtpPacketizerGeneric : public RtpPacketizer {
public: public:
// Initialize with payload from encoder. // Initialize with payload from encoder.
// The payload_data must be exactly one encoded generic frame. // The payload_data must be exactly one encoded generic frame.
RtpPacketizerGeneric(FrameType frametype, RtpPacketizerGeneric(const RTPVideoHeader& rtp_video_header,
FrameType frametype,
size_t max_payload_len, size_t max_payload_len,
size_t last_packet_reduction_len); size_t last_packet_reduction_len);
@ -45,6 +49,7 @@ class RtpPacketizerGeneric : public RtpPacketizer {
std::string ToString() override; std::string ToString() override;
private: private:
const absl::optional<uint16_t> picture_id_;
const uint8_t* payload_data_; const uint8_t* payload_data_;
size_t payload_size_; size_t payload_size_;
const size_t max_payload_len_; const size_t max_payload_len_;
@ -57,6 +62,8 @@ class RtpPacketizerGeneric : public RtpPacketizer {
// Number of packets, which will be 1 byte more than the rest. // Number of packets, which will be 1 byte more than the rest.
size_t num_larger_packets_; size_t num_larger_packets_;
void WriteExtendedHeader(uint8_t* out_ptr);
RTC_DISALLOW_COPY_AND_ASSIGN(RtpPacketizerGeneric); RTC_DISALLOW_COPY_AND_ASSIGN(RtpPacketizerGeneric);
}; };

View File

@ -63,8 +63,8 @@ TEST(RtpPacketizerVideoGeneric, AllPacketsMayBeEqualAndRespectMaxPayloadSize) {
const size_t kMaxPayloadLen = 6; const size_t kMaxPayloadLen = 6;
const size_t kLastPacketReductionLen = 2; const size_t kLastPacketReductionLen = 2;
const size_t kPayloadSize = 13; const size_t kPayloadSize = 13;
RtpPacketizerGeneric packetizer(kVideoFrameKey, kMaxPayloadLen, RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
kLastPacketReductionLen); kMaxPayloadLen, kLastPacketReductionLen);
size_t num_packets = size_t num_packets =
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr); packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer); std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
@ -78,8 +78,8 @@ TEST(RtpPacketizerVideoGeneric,
const size_t kMaxPayloadLen = 6; const size_t kMaxPayloadLen = 6;
const size_t kLastPacketReductionLen = 2; const size_t kLastPacketReductionLen = 2;
const size_t kPayloadSize = 13; const size_t kPayloadSize = 13;
RtpPacketizerGeneric packetizer(kVideoFrameKey, kMaxPayloadLen, RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
kLastPacketReductionLen); kMaxPayloadLen, kLastPacketReductionLen);
size_t num_packets = size_t num_packets =
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr); packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer); std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
@ -93,8 +93,8 @@ TEST(RtpPacketizerVideoGeneric,
const size_t kMaxPayloadLen = 6; const size_t kMaxPayloadLen = 6;
const size_t kLastPacketReductionLen = 2; const size_t kLastPacketReductionLen = 2;
const size_t kPayloadSize = 13; const size_t kPayloadSize = 13;
RtpPacketizerGeneric packetizer(kVideoFrameKey, kMaxPayloadLen, RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
kLastPacketReductionLen); kMaxPayloadLen, kLastPacketReductionLen);
size_t num_packets = size_t num_packets =
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr); packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer); std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
@ -114,8 +114,8 @@ TEST(RtpPacketizerVideoGeneric,
// generic header lengh for each packet minus last packet reduction). // generic header lengh for each packet minus last packet reduction).
// 4 packets is enough for kPayloadSize. // 4 packets is enough for kPayloadSize.
const size_t kMinNumPackets = 4; const size_t kMinNumPackets = 4;
RtpPacketizerGeneric packetizer(kVideoFrameKey, kMaxPayloadLen, RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
kLastPacketReductionLen); kMaxPayloadLen, kLastPacketReductionLen);
size_t num_packets = size_t num_packets =
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr); packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer); std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
@ -128,8 +128,8 @@ TEST(RtpPacketizerVideoGeneric, SomePacketsAreSmaller_RespectsMaxPayloadSize) {
const size_t kMaxPayloadLen = 8; const size_t kMaxPayloadLen = 8;
const size_t kLastPacketReductionLen = 5; const size_t kLastPacketReductionLen = 5;
const size_t kPayloadSize = 28; const size_t kPayloadSize = 28;
RtpPacketizerGeneric packetizer(kVideoFrameKey, kMaxPayloadLen, RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
kLastPacketReductionLen); kMaxPayloadLen, kLastPacketReductionLen);
size_t num_packets = size_t num_packets =
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr); packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer); std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
@ -143,8 +143,8 @@ TEST(RtpPacketizerVideoGeneric,
const size_t kMaxPayloadLen = 8; const size_t kMaxPayloadLen = 8;
const size_t kLastPacketReductionLen = 5; const size_t kLastPacketReductionLen = 5;
const size_t kPayloadSize = 28; const size_t kPayloadSize = 28;
RtpPacketizerGeneric packetizer(kVideoFrameKey, kMaxPayloadLen, RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
kLastPacketReductionLen); kMaxPayloadLen, kLastPacketReductionLen);
size_t num_packets = size_t num_packets =
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr); packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer); std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
@ -158,8 +158,8 @@ TEST(RtpPacketizerVideoGeneric,
const size_t kMaxPayloadLen = 8; const size_t kMaxPayloadLen = 8;
const size_t kLastPacketReductionLen = 5; const size_t kLastPacketReductionLen = 5;
const size_t kPayloadSize = 28; const size_t kPayloadSize = 28;
RtpPacketizerGeneric packetizer(kVideoFrameKey, kMaxPayloadLen, RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
kLastPacketReductionLen); kMaxPayloadLen, kLastPacketReductionLen);
size_t num_packets = size_t num_packets =
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr); packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer); std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
@ -179,8 +179,8 @@ TEST(RtpPacketizerVideoGeneric,
// generic header lengh for each packet minus last packet reduction). // generic header lengh for each packet minus last packet reduction).
// 5 packets is enough for kPayloadSize. // 5 packets is enough for kPayloadSize.
const size_t kMinNumPackets = 5; const size_t kMinNumPackets = 5;
RtpPacketizerGeneric packetizer(kVideoFrameKey, kMaxPayloadLen, RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
kLastPacketReductionLen); kMaxPayloadLen, kLastPacketReductionLen);
size_t num_packets = size_t num_packets =
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr); packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer); std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
@ -189,4 +189,84 @@ TEST(RtpPacketizerVideoGeneric,
EXPECT_EQ(num_packets, kMinNumPackets); EXPECT_EQ(num_packets, kMinNumPackets);
} }
TEST(RtpPacketizerVideoGeneric, HasFrameIdWritesExtendedHeader) {
const size_t kMaxPayloadLen = 6;
const size_t kLastPacketReductionLen = 2;
const size_t kPayloadSize = 13;
RTPVideoHeader rtp_video_header;
rtp_video_header.frame_id = 37;
RtpPacketizerGeneric packetizer(rtp_video_header, kVideoFrameKey,
kMaxPayloadLen, kLastPacketReductionLen);
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
RtpPacketToSend packet(nullptr);
packetizer.NextPacket(&packet);
rtc::ArrayView<const uint8_t> payload = packet.payload();
EXPECT_TRUE(payload[0] & 0x04); // Extended header bit is set.
// Frame id is 37.
EXPECT_EQ(0u, payload[1]);
EXPECT_EQ(37u, payload[2]);
}
TEST(RtpPacketizerVideoGeneric, FrameIdOver15bitsWrapsAround) {
const size_t kMaxPayloadLen = 6;
const size_t kLastPacketReductionLen = 2;
const size_t kPayloadSize = 13;
RTPVideoHeader rtp_video_header;
rtp_video_header.frame_id = 0x8137;
RtpPacketizerGeneric packetizer(rtp_video_header, kVideoFrameKey,
kMaxPayloadLen, kLastPacketReductionLen);
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
RtpPacketToSend packet(nullptr);
packetizer.NextPacket(&packet);
rtc::ArrayView<const uint8_t> payload = packet.payload();
EXPECT_TRUE(payload[0] & 0x04); // Extended header bit is set.
// Frame id is 0x137.
EXPECT_EQ(0x01u, payload[1]);
EXPECT_EQ(0x37u, payload[2]);
}
TEST(RtpPacketizerVideoGeneric, NoFrameIdDoesNotWriteExtendedHeader) {
const size_t kMaxPayloadLen = 6;
const size_t kLastPacketReductionLen = 2;
const size_t kPayloadSize = 13;
RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
kMaxPayloadLen, kLastPacketReductionLen);
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
RtpPacketToSend packet(nullptr);
packetizer.NextPacket(&packet);
rtc::ArrayView<const uint8_t> payload = packet.payload();
EXPECT_FALSE(payload[0] & 0x04);
}
TEST(RtpDepacketizerVideoGeneric, NonExtendedHeaderNoFrameId) {
const size_t kPayloadLen = 1;
uint8_t payload[kPayloadLen] = {0x01};
RtpDepacketizerGeneric depacketizer;
RtpDepacketizer::ParsedPayload parsed_payload;
depacketizer.Parse(&parsed_payload, payload, kPayloadLen);
EXPECT_EQ(kNoPictureId, parsed_payload.video_header().frame_id);
}
TEST(RtpDepacketizerVideoGeneric, ExtendedHeaderParsesFrameId) {
const size_t kPayloadLen = 3;
uint8_t payload[kPayloadLen] = {0x05, 0x13, 0x37};
RtpDepacketizerGeneric depacketizer;
RtpDepacketizer::ParsedPayload parsed_payload;
depacketizer.Parse(&parsed_payload, payload, kPayloadLen);
EXPECT_EQ(0x1337, parsed_payload.video_header().frame_id);
}
} // namespace webrtc } // namespace webrtc

View File

@ -244,9 +244,10 @@ class RtpSenderTest : public ::testing::TestWithParam<bool> {
EXPECT_EQ(0, rtp_sender_->RegisterPayload(payload_name, kPayloadType, 90000, EXPECT_EQ(0, rtp_sender_->RegisterPayload(payload_name, kPayloadType, 90000,
0, 1500)); 0, 1500));
RTPVideoHeader video_header;
EXPECT_TRUE(rtp_sender_->SendOutgoingData( EXPECT_TRUE(rtp_sender_->SendOutgoingData(
kVideoFrameKey, kPayloadType, kTimestamp, kCaptureTimeMs, kPayloadData, kVideoFrameKey, kPayloadType, kTimestamp, kCaptureTimeMs, kPayloadData,
sizeof(kPayloadData), nullptr, nullptr, nullptr, sizeof(kPayloadData), nullptr, &video_header, nullptr,
kDefaultExpectedRetransmissionTimeMs)); kDefaultExpectedRetransmissionTimeMs));
} }
}; };
@ -968,9 +969,10 @@ TEST_P(RtpSenderTestWithoutPacer, SendGenericVideo) {
uint8_t payload[] = {47, 11, 32, 93, 89}; uint8_t payload[] = {47, 11, 32, 93, 89};
// Send keyframe // Send keyframe
RTPVideoHeader video_header;
ASSERT_TRUE(rtp_sender_->SendOutgoingData( ASSERT_TRUE(rtp_sender_->SendOutgoingData(
kVideoFrameKey, payload_type, 1234, 4321, payload, sizeof(payload), kVideoFrameKey, payload_type, 1234, 4321, payload, sizeof(payload),
nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs)); nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
auto sent_payload = transport_.last_sent_packet().payload(); auto sent_payload = transport_.last_sent_packet().payload();
uint8_t generic_header = sent_payload[0]; uint8_t generic_header = sent_payload[0];
@ -985,7 +987,7 @@ TEST_P(RtpSenderTestWithoutPacer, SendGenericVideo) {
ASSERT_TRUE(rtp_sender_->SendOutgoingData( ASSERT_TRUE(rtp_sender_->SendOutgoingData(
kVideoFrameDelta, payload_type, 1234, 4321, payload, sizeof(payload), kVideoFrameDelta, payload_type, 1234, 4321, payload, sizeof(payload),
nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs)); nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
sent_payload = transport_.last_sent_packet().payload(); sent_payload = transport_.last_sent_packet().payload();
generic_header = sent_payload[0]; generic_header = sent_payload[0];
@ -1299,9 +1301,10 @@ TEST_P(RtpSenderTest, FrameCountCallbacks) {
EXPECT_CALL(mock_paced_sender_, InsertPacket(_, _, _, _, _, _)) EXPECT_CALL(mock_paced_sender_, InsertPacket(_, _, _, _, _, _))
.Times(::testing::AtLeast(2)); .Times(::testing::AtLeast(2));
RTPVideoHeader video_header;
ASSERT_TRUE(rtp_sender_->SendOutgoingData( ASSERT_TRUE(rtp_sender_->SendOutgoingData(
kVideoFrameKey, payload_type, 1234, 4321, payload, sizeof(payload), kVideoFrameKey, payload_type, 1234, 4321, payload, sizeof(payload),
nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs)); nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
EXPECT_EQ(1U, callback.num_calls_); EXPECT_EQ(1U, callback.num_calls_);
EXPECT_EQ(ssrc, callback.ssrc_); EXPECT_EQ(ssrc, callback.ssrc_);
@ -1310,7 +1313,7 @@ TEST_P(RtpSenderTest, FrameCountCallbacks) {
ASSERT_TRUE(rtp_sender_->SendOutgoingData( ASSERT_TRUE(rtp_sender_->SendOutgoingData(
kVideoFrameDelta, payload_type, 1234, 4321, payload, sizeof(payload), kVideoFrameDelta, payload_type, 1234, 4321, payload, sizeof(payload),
nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs)); nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
EXPECT_EQ(2U, callback.num_calls_); EXPECT_EQ(2U, callback.num_calls_);
EXPECT_EQ(ssrc, callback.ssrc_); EXPECT_EQ(ssrc, callback.ssrc_);
@ -1373,10 +1376,11 @@ TEST_P(RtpSenderTest, BitrateCallbacks) {
rtp_sender_->ProcessBitrate(); rtp_sender_->ProcessBitrate();
// Send a few frames. // Send a few frames.
RTPVideoHeader video_header;
for (uint32_t i = 0; i < kNumPackets; ++i) { for (uint32_t i = 0; i < kNumPackets; ++i) {
ASSERT_TRUE(rtp_sender_->SendOutgoingData( ASSERT_TRUE(rtp_sender_->SendOutgoingData(
kVideoFrameKey, payload_type, 1234, 4321, payload, sizeof(payload), kVideoFrameKey, payload_type, 1234, 4321, payload, sizeof(payload),
nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs)); nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
fake_clock_.AdvanceTimeMilliseconds(kPacketInterval); fake_clock_.AdvanceTimeMilliseconds(kPacketInterval);
} }
@ -1457,9 +1461,10 @@ TEST_P(RtpSenderTestWithoutPacer, StreamDataCountersCallbacks) {
rtp_sender_->RegisterRtpStatisticsCallback(&callback); rtp_sender_->RegisterRtpStatisticsCallback(&callback);
// Send a frame. // Send a frame.
RTPVideoHeader video_header;
ASSERT_TRUE(rtp_sender_->SendOutgoingData( ASSERT_TRUE(rtp_sender_->SendOutgoingData(
kVideoFrameKey, payload_type, 1234, 4321, payload, sizeof(payload), kVideoFrameKey, payload_type, 1234, 4321, payload, sizeof(payload),
nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs)); nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
StreamDataCounters expected; StreamDataCounters expected;
expected.transmitted.payload_bytes = 6; expected.transmitted.payload_bytes = 6;
expected.transmitted.header_bytes = 12; expected.transmitted.header_bytes = 12;
@ -1501,7 +1506,7 @@ TEST_P(RtpSenderTestWithoutPacer, StreamDataCountersCallbacks) {
rtp_sender_->SetFecParameters(fec_params, fec_params); rtp_sender_->SetFecParameters(fec_params, fec_params);
ASSERT_TRUE(rtp_sender_->SendOutgoingData( ASSERT_TRUE(rtp_sender_->SendOutgoingData(
kVideoFrameDelta, payload_type, 1234, 4321, payload, sizeof(payload), kVideoFrameDelta, payload_type, 1234, 4321, payload, sizeof(payload),
nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs)); nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
expected.transmitted.payload_bytes = 40; expected.transmitted.payload_bytes = 40;
expected.transmitted.header_bytes = 60; expected.transmitted.header_bytes = 60;
expected.transmitted.packets = 5; expected.transmitted.packets = 5;
@ -1518,9 +1523,10 @@ TEST_P(RtpSenderAudioTest, SendAudio) {
0, 1500)); 0, 1500));
uint8_t payload[] = {47, 11, 32, 93, 89}; uint8_t payload[] = {47, 11, 32, 93, 89};
RTPVideoHeader video_header;
ASSERT_TRUE(rtp_sender_->SendOutgoingData( ASSERT_TRUE(rtp_sender_->SendOutgoingData(
kAudioFrameCN, payload_type, 1234, 4321, payload, sizeof(payload), kAudioFrameCN, payload_type, 1234, 4321, payload, sizeof(payload),
nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs)); nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
auto sent_payload = transport_.last_sent_packet().payload(); auto sent_payload = transport_.last_sent_packet().payload();
EXPECT_THAT(sent_payload, ElementsAreArray(payload)); EXPECT_THAT(sent_payload, ElementsAreArray(payload));
@ -1537,9 +1543,10 @@ TEST_P(RtpSenderAudioTest, SendAudioWithAudioLevelExtension) {
0, 1500)); 0, 1500));
uint8_t payload[] = {47, 11, 32, 93, 89}; uint8_t payload[] = {47, 11, 32, 93, 89};
RTPVideoHeader video_header;
ASSERT_TRUE(rtp_sender_->SendOutgoingData( ASSERT_TRUE(rtp_sender_->SendOutgoingData(
kAudioFrameCN, payload_type, 1234, 4321, payload, sizeof(payload), kAudioFrameCN, payload_type, 1234, 4321, payload, sizeof(payload),
nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs)); nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
auto sent_payload = transport_.last_sent_packet().payload(); auto sent_payload = transport_.last_sent_packet().payload();
EXPECT_THAT(sent_payload, ElementsAreArray(payload)); EXPECT_THAT(sent_payload, ElementsAreArray(payload));
@ -1576,22 +1583,23 @@ TEST_P(RtpSenderAudioTest, CheckMarkerBitForTelephoneEvents) {
// During start, it takes the starting timestamp as last sent timestamp. // During start, it takes the starting timestamp as last sent timestamp.
// The duration is calculated as the difference of current and last sent // The duration is calculated as the difference of current and last sent
// timestamp. So for first call it will skip since the duration is zero. // timestamp. So for first call it will skip since the duration is zero.
RTPVideoHeader video_header;
ASSERT_TRUE(rtp_sender_->SendOutgoingData( ASSERT_TRUE(rtp_sender_->SendOutgoingData(
kEmptyFrame, kPayloadType, capture_time_ms, 0, nullptr, 0, nullptr, kEmptyFrame, kPayloadType, capture_time_ms, 0, nullptr, 0, nullptr,
nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs)); &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
// DTMF Sample Length is (Frequency/1000) * Duration. // DTMF Sample Length is (Frequency/1000) * Duration.
// So in this case, it is (8000/1000) * 500 = 4000. // So in this case, it is (8000/1000) * 500 = 4000.
// Sending it as two packets. // Sending it as two packets.
ASSERT_TRUE(rtp_sender_->SendOutgoingData( ASSERT_TRUE(rtp_sender_->SendOutgoingData(
kEmptyFrame, kPayloadType, capture_time_ms + 2000, 0, nullptr, 0, nullptr, kEmptyFrame, kPayloadType, capture_time_ms + 2000, 0, nullptr, 0, nullptr,
nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs)); &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
// Marker Bit should be set to 1 for first packet. // Marker Bit should be set to 1 for first packet.
EXPECT_TRUE(transport_.last_sent_packet().Marker()); EXPECT_TRUE(transport_.last_sent_packet().Marker());
ASSERT_TRUE(rtp_sender_->SendOutgoingData( ASSERT_TRUE(rtp_sender_->SendOutgoingData(
kEmptyFrame, kPayloadType, capture_time_ms + 4000, 0, nullptr, 0, nullptr, kEmptyFrame, kPayloadType, capture_time_ms + 4000, 0, nullptr, 0, nullptr,
nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs)); &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
// Marker Bit should be set to 0 for rest of the packets. // Marker Bit should be set to 0 for rest of the packets.
EXPECT_FALSE(transport_.last_sent_packet().Marker()); EXPECT_FALSE(transport_.last_sent_packet().Marker());
} }
@ -1608,9 +1616,10 @@ TEST_P(RtpSenderTestWithoutPacer, BytesReportedCorrectly) {
0, 1500)); 0, 1500));
uint8_t payload[] = {47, 11, 32, 93, 89}; uint8_t payload[] = {47, 11, 32, 93, 89};
RTPVideoHeader video_header;
ASSERT_TRUE(rtp_sender_->SendOutgoingData( ASSERT_TRUE(rtp_sender_->SendOutgoingData(
kVideoFrameKey, kPayloadType, 1234, 4321, payload, sizeof(payload), kVideoFrameKey, kPayloadType, 1234, 4321, payload, sizeof(payload),
nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs)); nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
// Will send 2 full-size padding packets. // Will send 2 full-size padding packets.
rtp_sender_->TimeToSendPadding(1, PacedPacketInfo()); rtp_sender_->TimeToSendPadding(1, PacedPacketInfo());

View File

@ -46,7 +46,7 @@ struct RTPVideoHeader {
} }
// Information for generic codec descriptor. // Information for generic codec descriptor.
int64_t frame_id = 0; int64_t frame_id = kNoPictureId;
int spatial_index = 0; int spatial_index = 0;
int temporal_index = 0; int temporal_index = 0;
absl::InlinedVector<int64_t, 5> dependencies; absl::InlinedVector<int64_t, 5> dependencies;

View File

@ -140,9 +140,10 @@ class RtpRtcpVideoTest : public ::testing::Test {
TEST_F(RtpRtcpVideoTest, BasicVideo) { TEST_F(RtpRtcpVideoTest, BasicVideo) {
uint32_t timestamp = 3000; uint32_t timestamp = 3000;
RTPVideoHeader video_header;
EXPECT_TRUE(video_module_->SendOutgoingData( EXPECT_TRUE(video_module_->SendOutgoingData(
kVideoFrameDelta, 123, timestamp, timestamp / 90, video_frame_, kVideoFrameDelta, 123, timestamp, timestamp / 90, video_frame_,
payload_data_length_, nullptr, nullptr, nullptr)); payload_data_length_, nullptr, &video_header, nullptr));
} }
TEST_F(RtpRtcpVideoTest, PaddingOnlyFrames) { TEST_F(RtpRtcpVideoTest, PaddingOnlyFrames) {