mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-15 06:40:43 +01:00

This metric was always supposed to be the spec's answer to googBucketDelay, and is defined as "The total number of seconds that packets have spent buffered locally before being transmitted onto the network." But our implementation measured the time between capture and send, including encode time. This is incorrect and yields a much larger value than expected. This CL updated the metric to do what the spec says. Implementation-wise we measure the time between pushing and popping each packet from the queue (in modules/pacing/prioritized_packet_queue.cc). The spec says to increment the delay counter at the same time as we increment the packet counter in order for the app to be able to do "delta totalPacketSendDelay / delta packetSent". For this reason, `total_packet_delay` is added to RtpPacketCounter. (Previously, the two counters were incremented on different threads and observers.) Running Google Meet on a good network, I could observe a 2-3 ms average send delay per packet with this implementation compared to 20-30 ms with the old implementation. See b/137014977#comment170 for comparison with googBucketDelay which is a little bit different by design - totalPacketSendDelay is clearly better than googBucketDelay. Since none of this depend on the media kind, we can wire up this metric for audio as well in a follow-up: https://webrtc-review.googlesource.com/c/src/+/280523 Bug: webrtc:14593 Change-Id: If8fcd82fee74030d0923ee5df2c2aea2264600d4 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/280443 Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/main@{#38480}
147 lines
5.7 KiB
C++
147 lines
5.7 KiB
C++
/*
|
|
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
#ifndef MODULES_RTP_RTCP_SOURCE_RTP_PACKET_TO_SEND_H_
|
|
#define MODULES_RTP_RTCP_SOURCE_RTP_PACKET_TO_SEND_H_
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#include <utility>
|
|
|
|
#include "absl/types/optional.h"
|
|
#include "api/array_view.h"
|
|
#include "api/ref_counted_base.h"
|
|
#include "api/scoped_refptr.h"
|
|
#include "api/units/time_delta.h"
|
|
#include "api/units/timestamp.h"
|
|
#include "api/video/video_timing.h"
|
|
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
|
#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
|
|
#include "modules/rtp_rtcp/source/rtp_packet.h"
|
|
|
|
namespace webrtc {
|
|
// Class to hold rtp packet with metadata for sender side.
|
|
// The metadata is not send over the wire, but packet sender may use it to
|
|
// create rtp header extensions or other data that is sent over the wire.
|
|
class RtpPacketToSend : public RtpPacket {
|
|
public:
|
|
// RtpPacketToSend::Type is deprecated. Use RtpPacketMediaType directly.
|
|
using Type = RtpPacketMediaType;
|
|
|
|
explicit RtpPacketToSend(const ExtensionManager* extensions);
|
|
RtpPacketToSend(const ExtensionManager* extensions, size_t capacity);
|
|
RtpPacketToSend(const RtpPacketToSend& packet);
|
|
RtpPacketToSend(RtpPacketToSend&& packet);
|
|
|
|
RtpPacketToSend& operator=(const RtpPacketToSend& packet);
|
|
RtpPacketToSend& operator=(RtpPacketToSend&& packet);
|
|
|
|
~RtpPacketToSend();
|
|
|
|
// Time in local time base as close as it can to frame capture time.
|
|
webrtc::Timestamp capture_time() const { return capture_time_; }
|
|
void set_capture_time(webrtc::Timestamp time) { capture_time_ = time; }
|
|
|
|
void set_packet_type(RtpPacketMediaType type) { packet_type_ = type; }
|
|
absl::optional<RtpPacketMediaType> packet_type() const {
|
|
return packet_type_;
|
|
}
|
|
|
|
// If this is a retransmission, indicates the sequence number of the original
|
|
// media packet that this packet represents. If RTX is used this will likely
|
|
// be different from SequenceNumber().
|
|
void set_retransmitted_sequence_number(uint16_t sequence_number) {
|
|
retransmitted_sequence_number_ = sequence_number;
|
|
}
|
|
absl::optional<uint16_t> retransmitted_sequence_number() const {
|
|
return retransmitted_sequence_number_;
|
|
}
|
|
|
|
void set_allow_retransmission(bool allow_retransmission) {
|
|
allow_retransmission_ = allow_retransmission;
|
|
}
|
|
bool allow_retransmission() const { return allow_retransmission_; }
|
|
|
|
// An application can attach arbitrary data to an RTP packet using
|
|
// `additional_data`. The additional data does not affect WebRTC processing.
|
|
rtc::scoped_refptr<rtc::RefCountedBase> additional_data() const {
|
|
return additional_data_;
|
|
}
|
|
void set_additional_data(rtc::scoped_refptr<rtc::RefCountedBase> data) {
|
|
additional_data_ = std::move(data);
|
|
}
|
|
|
|
void set_packetization_finish_time(webrtc::Timestamp time) {
|
|
SetExtension<VideoTimingExtension>(
|
|
VideoSendTiming::GetDeltaCappedMs(time - capture_time_),
|
|
VideoTimingExtension::kPacketizationFinishDeltaOffset);
|
|
}
|
|
|
|
void set_pacer_exit_time(webrtc::Timestamp time) {
|
|
SetExtension<VideoTimingExtension>(
|
|
VideoSendTiming::GetDeltaCappedMs(time - capture_time_),
|
|
VideoTimingExtension::kPacerExitDeltaOffset);
|
|
}
|
|
|
|
void set_network_time(webrtc::Timestamp time) {
|
|
SetExtension<VideoTimingExtension>(
|
|
VideoSendTiming::GetDeltaCappedMs(time - capture_time_),
|
|
VideoTimingExtension::kNetworkTimestampDeltaOffset);
|
|
}
|
|
|
|
void set_network2_time(webrtc::Timestamp time) {
|
|
SetExtension<VideoTimingExtension>(
|
|
VideoSendTiming::GetDeltaCappedMs(time - capture_time_),
|
|
VideoTimingExtension::kNetwork2TimestampDeltaOffset);
|
|
}
|
|
|
|
// Indicates if packet is the first packet of a video frame.
|
|
void set_first_packet_of_frame(bool is_first_packet) {
|
|
is_first_packet_of_frame_ = is_first_packet;
|
|
}
|
|
bool is_first_packet_of_frame() const { return is_first_packet_of_frame_; }
|
|
|
|
// Indicates if packet contains payload for a video key-frame.
|
|
void set_is_key_frame(bool is_key_frame) { is_key_frame_ = is_key_frame; }
|
|
bool is_key_frame() const { return is_key_frame_; }
|
|
|
|
// Indicates if packets should be protected by FEC (Forward Error Correction).
|
|
void set_fec_protect_packet(bool protect) { fec_protect_packet_ = protect; }
|
|
bool fec_protect_packet() const { return fec_protect_packet_; }
|
|
|
|
// Indicates if packet is using RED encapsulation, in accordance with
|
|
// https://tools.ietf.org/html/rfc2198
|
|
void set_is_red(bool is_red) { is_red_ = is_red; }
|
|
bool is_red() const { return is_red_; }
|
|
|
|
// The amount of time spent in the send queue, used for totalPacketSendDelay.
|
|
// https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-totalpacketsenddelay
|
|
void set_time_in_send_queue(TimeDelta time_in_send_queue) {
|
|
time_in_send_queue_ = time_in_send_queue;
|
|
}
|
|
absl::optional<TimeDelta> time_in_send_queue() const {
|
|
return time_in_send_queue_;
|
|
}
|
|
|
|
private:
|
|
webrtc::Timestamp capture_time_ = webrtc::Timestamp::Zero();
|
|
absl::optional<RtpPacketMediaType> packet_type_;
|
|
bool allow_retransmission_ = false;
|
|
absl::optional<uint16_t> retransmitted_sequence_number_;
|
|
rtc::scoped_refptr<rtc::RefCountedBase> additional_data_;
|
|
bool is_first_packet_of_frame_ = false;
|
|
bool is_key_frame_ = false;
|
|
bool fec_protect_packet_ = false;
|
|
bool is_red_ = false;
|
|
absl::optional<TimeDelta> time_in_send_queue_;
|
|
};
|
|
|
|
} // namespace webrtc
|
|
#endif // MODULES_RTP_RTCP_SOURCE_RTP_PACKET_TO_SEND_H_
|