Give VideoSendStreamImpl access to RTP timestamps
When a LossNotification RTCP message is received, the sequence numbers it refers to must be converted to timestamps before passing the message down to the encoder. This CL gives VideoSendStreamImpl access to that information via VideoSendStreamImpl::rtp_video_sender_. TBR=sprang@webrtc.org Bug: webrtc:10501 Change-Id: If207f0b6d2fb344da35b525cc104e8ba5cc614ec Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131323 Commit-Queue: Elad Alon <eladalon@webrtc.org> Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/master@{#27489}
This commit is contained in:
@ -15,6 +15,7 @@
|
||||
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@ -38,6 +39,7 @@ namespace webrtc {
|
||||
|
||||
namespace {
|
||||
constexpr size_t kRedForFecHeaderLength = 1;
|
||||
constexpr size_t kRtpSequenceNumberMapMaxEntries = 1 << 13;
|
||||
constexpr int64_t kMaxUnretransmittableFrameIntervalMs = 33 * 4;
|
||||
|
||||
void BuildRedPayload(const RtpPacketToSend& media_packet,
|
||||
@ -196,6 +198,14 @@ RTPSenderVideo::RTPSenderVideo(Clock* clock,
|
||||
last_rotation_(kVideoRotation_0),
|
||||
transmit_color_space_next_frame_(false),
|
||||
playout_delay_oracle_(playout_delay_oracle),
|
||||
// TODO(eladalon): Choose whether to instantiate rtp_sequence_number_map_
|
||||
// according to the negotiation of the RTCP message.
|
||||
rtp_sequence_number_map_(
|
||||
field_trials.Lookup("WebRTC-RtcpLossNotification").find("Enabled") !=
|
||||
std::string::npos
|
||||
? absl::make_unique<RtpSequenceNumberMap>(
|
||||
kRtpSequenceNumberMapMaxEntries)
|
||||
: nullptr),
|
||||
red_payload_type_(-1),
|
||||
ulpfec_payload_type_(-1),
|
||||
flexfec_sender_(flexfec_sender),
|
||||
@ -622,7 +632,7 @@ bool RTPSenderVideo::SendVideo(VideoFrameType frame_type,
|
||||
const uint8_t temporal_id = GetTemporalId(*video_header);
|
||||
StorageType storage = GetStorageType(temporal_id, retransmission_settings,
|
||||
expected_retransmission_time_ms);
|
||||
size_t num_packets = packetizer->NumPackets();
|
||||
const size_t num_packets = packetizer->NumPackets();
|
||||
|
||||
size_t unpacketized_payload_size;
|
||||
if (fragmentation && fragmentation->fragmentationVectorSize > 0) {
|
||||
@ -638,6 +648,7 @@ bool RTPSenderVideo::SendVideo(VideoFrameType frame_type,
|
||||
if (num_packets == 0)
|
||||
return false;
|
||||
|
||||
uint16_t first_sequence_number;
|
||||
bool first_frame = first_frame_sent_();
|
||||
for (size_t i = 0; i < num_packets; ++i) {
|
||||
std::unique_ptr<RtpPacketToSend> packet;
|
||||
@ -667,6 +678,10 @@ bool RTPSenderVideo::SendVideo(VideoFrameType frame_type,
|
||||
return false;
|
||||
packetized_payload_size += packet->payload_size();
|
||||
|
||||
if (rtp_sequence_number_map_ && i == 0) {
|
||||
first_sequence_number = packet->SequenceNumber();
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
playout_delay_oracle_->OnSentPacket(packet->SequenceNumber(),
|
||||
playout_delay);
|
||||
@ -709,6 +724,13 @@ bool RTPSenderVideo::SendVideo(VideoFrameType frame_type,
|
||||
}
|
||||
}
|
||||
|
||||
if (rtp_sequence_number_map_) {
|
||||
const uint32_t timestamp = rtp_timestamp - rtp_sender_->TimestampOffset();
|
||||
rtc::CritScope cs(&crit_);
|
||||
rtp_sequence_number_map_->InsertFrame(first_sequence_number, num_packets,
|
||||
timestamp);
|
||||
}
|
||||
|
||||
rtc::CritScope cs(&stats_crit_);
|
||||
RTC_DCHECK_GE(packetized_payload_size, unpacketized_payload_size);
|
||||
packetization_overhead_bitrate_.Update(
|
||||
@ -736,6 +758,15 @@ uint32_t RTPSenderVideo::PacketizationOverheadBps() const {
|
||||
.value_or(0);
|
||||
}
|
||||
|
||||
absl::optional<RtpSequenceNumberMap::Info> RTPSenderVideo::GetSentRtpPacketInfo(
|
||||
uint16_t sequence_number) const {
|
||||
if (!rtp_sequence_number_map_) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
rtc::CritScope cs(&crit_);
|
||||
return rtp_sequence_number_map_->Get(sequence_number);
|
||||
}
|
||||
|
||||
StorageType RTPSenderVideo::GetStorageType(
|
||||
uint8_t temporal_id,
|
||||
int32_t retransmission_settings,
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include "modules/rtp_rtcp/source/playout_delay_oracle.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_rtcp_config.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_sender.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_sequence_number_map.h"
|
||||
#include "modules/rtp_rtcp/source/ulpfec_generator.h"
|
||||
#include "rtc_base/critical_section.h"
|
||||
#include "rtc_base/one_time_event.h"
|
||||
@ -93,6 +94,14 @@ class RTPSenderVideo {
|
||||
// or extension/
|
||||
uint32_t PacketizationOverheadBps() const;
|
||||
|
||||
// Recall the last RTP packet whose sequence number was |sequence_number|.
|
||||
// Return the timestamp of the video frame that packet belonged too, as well
|
||||
// as whether the packet was the first and/or last packet in the frame.
|
||||
// absl::nullopt returned if no such packet can be recalled (e.g. it happened
|
||||
// too long ago).
|
||||
absl::optional<RtpSequenceNumberMap::Info> GetSentRtpPacketInfo(
|
||||
uint16_t sequence_number) const;
|
||||
|
||||
protected:
|
||||
static uint8_t GetTemporalId(const RTPVideoHeader& header);
|
||||
StorageType GetStorageType(uint8_t temporal_id,
|
||||
@ -166,6 +175,13 @@ class RTPSenderVideo {
|
||||
// delay extension on header.
|
||||
PlayoutDelayOracle* const playout_delay_oracle_;
|
||||
|
||||
// Maps sent packets' sequence numbers to a tuple consisting of:
|
||||
// 1. The timestamp, without the randomizing offset mandated by the RFC.
|
||||
// 2. Whether the packet was the first in its frame.
|
||||
// 3. Whether the packet was the last in its frame.
|
||||
const std::unique_ptr<RtpSequenceNumberMap> rtp_sequence_number_map_
|
||||
RTC_PT_GUARDED_BY(crit_);
|
||||
|
||||
// RED/ULPFEC.
|
||||
int red_payload_type_ RTC_GUARDED_BY(crit_);
|
||||
int ulpfec_payload_type_ RTC_GUARDED_BY(crit_);
|
||||
|
||||
Reference in New Issue
Block a user