Skip to content
This repository was archived by the owner on Oct 25, 2024. It is now read-only.

Commit 846553f

Browse files
taste1981jianjunz
authored andcommitted
Enable TCAE information population on client stack. (#160)
1 parent 81cfb7d commit 846553f

File tree

7 files changed

+136
-22
lines changed

7 files changed

+136
-22
lines changed

api/task_queue/test/ptp_clock_sync.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright (C) <2021> Intel Corporation
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
#ifndef RTC_BASE_TIME_PTP_CLOCK_SYNC_H_
6+
#define RTC_BASE_TIME_PTP_CLOCK_SYNC_H_
7+
8+
#include <windows.h>
9+
#include <cstdint>
10+
11+
#define MICROSECONDS_FACTOR 1000000.0
12+
#define OFFSET_FACTOR 200000
13+
#define SERVER_FREQUENCY 0.09 // RTP/NTP timestamp runs at 90KHz clock
14+
15+
// A Windows implementation for PTP using timestamp from RTP and local
16+
// timestamp. We may need to implement something like QueryPerformanceFrequency
17+
// for this to work on Linux platforms.
18+
namespace webrtc {
19+
class PTPClockSync {
20+
public:
21+
PTPClockSync()
22+
: m_server_point(0), m_server_freq(0), m_client_point(0), m_last_ts(0) {
23+
uint64_t freq; // Performance counter frequency in a second.
24+
QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
25+
m_client_freq = (double)freq / MICROSECONDS_FACTOR;
26+
m_server_freq = SERVER_FREQUENCY;
27+
}
28+
~PTPClockSync() {}
29+
30+
void Sync(uint32_t ts, uint64_t tc) {
31+
if (GetDuration(ts, tc) < 0 ||
32+
(ts - m_last_ts) > OFFSET_FACTOR * m_server_freq) {
33+
UpdateSync(ts, tc);
34+
}
35+
m_last_ts = ts;
36+
}
37+
38+
double GetDuration(uint32_t ts, uint64_t tc) {
39+
int ds = (int)(ts - m_server_point);
40+
int dc = (int)(tc - m_client_point);
41+
return (double)dc / m_client_freq - (double)ds / m_server_freq;
42+
}
43+
44+
protected:
45+
uint32_t m_server_point;
46+
double m_server_freq; // count per us
47+
uint64_t m_client_point;
48+
double m_client_freq; // count per us
49+
uint32_t m_last_ts;
50+
51+
void UpdateSync(uint32_t ts, uint64_t tc) {
52+
m_client_point = tc;
53+
m_server_point = ts;
54+
}
55+
};
56+
} // namespace webrtc
57+
#endif

api/video/encoded_image.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,14 @@ class RTC_EXPORT EncodedImage {
198198
int64_t receive_finish_ms = 0;
199199
} timing_;
200200

201+
#if defined(WEBRTC_WIN)
202+
struct BWEStats {
203+
double start_duration_ = 0;
204+
double last_duration_ = 0;
205+
int32_t packets_lost_ = 0;
206+
}bwe_stats_;
207+
#endif
208+
201209
private:
202210
size_t capacity() const { return encoded_data_ ? encoded_data_->size() : 0; }
203211

modules/video_coding/frame_object.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,17 @@ class RtpFrameObject : public EncodedFrame {
4646
int64_t RenderTime() const override;
4747
bool delayed_by_retransmission() const override;
4848
const RTPVideoHeader& GetRtpVideoHeader() const;
49-
50-
uint8_t* mutable_data() { return image_buffer_->data(); }
51-
49+
const FrameMarking& GetFrameMarking() const;
50+
#if defined(WEBRTC_WIN)
51+
void SetBWETiming(double start_duration,
52+
double last_duration,
53+
int32_t packets_lost) {
54+
bwe_stats_.start_duration_ = start_duration;
55+
bwe_stats_.last_duration_ = last_duration;
56+
bwe_stats_.packets_lost_ = packets_lost;
57+
}
58+
#endif
5259
private:
53-
// Reference for mutable access.
54-
rtc::scoped_refptr<EncodedImageBuffer> image_buffer_;
5560
RTPVideoHeader rtp_video_header_;
5661
VideoCodecType codec_type_;
5762
uint16_t first_seq_num_;

modules/video_coding/packet_buffer.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ PacketBuffer::InsertResult PacketBuffer::InsertPacket(
8686
first_seq_num_ = seq_num;
8787
}
8888

89+
#if defined(WEBRTC_WIN)
90+
QueryPerformanceCounter((LARGE_INTEGER*)&packet->time_ticks);
91+
#endif
92+
8993
if (buffer_[index] != nullptr) {
9094
// Duplicate packet, just delete the payload.
9195
if (buffer_[index]->seq_num == packet->seq_num) {

modules/video_coding/packet_buffer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ class PacketBuffer {
6363

6464
rtc::CopyOnWriteBuffer video_payload;
6565
RTPVideoHeader video_header;
66+
#if defined(WEBRTC_WIN)
67+
int64_t time_ticks;
68+
#endif
6669
};
6770
struct InsertResult {
6871
std::vector<std::unique_ptr<Packet>> packets;

video/rtp_video_stream_receiver.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@
4747
#include "rtc_base/constructor_magic.h"
4848
#include "rtc_base/critical_section.h"
4949
#include "rtc_base/numerics/sequence_number_util.h"
50+
#if defined(WEBRTC_WIN)
51+
#include "rtc_base/time/ptp_clock_sync.h"
52+
#endif
5053
#include "rtc_base/synchronization/sequence_checker.h"
5154
#include "rtc_base/thread_annotations.h"
5255
#include "rtc_base/thread_checker.h"
@@ -272,6 +275,9 @@ class RtpVideoStreamReceiver : public LossNotificationSender,
272275
void OnAssembledFrame(std::unique_ptr<video_coding::RtpFrameObject> frame);
273276

274277
Clock* const clock_;
278+
#if defined(WEBRTC_WIN)
279+
PTPClockSync clock_sync_;
280+
#endif
275281
// Ownership of this object lies with VideoReceiveStream, which owns |this|.
276282
const VideoReceiveStream::Config& config_;
277283
PacketRouter* const packet_router_;

video/rtp_video_stream_receiver2.cc

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -623,8 +623,11 @@ void RtpVideoStreamReceiver2::OnReceivedPayloadData(
623623
RTC_LOG(LS_INFO)
624624
<< "LossNotificationController does not support reordering.";
625625
} else if (generic_descriptor_state == kNoGenericDescriptor) {
626+
#if 0
627+
// Johny(TODO): check cause of no generic descriptor.
626628
RTC_LOG(LS_WARNING) << "LossNotificationController requires generic "
627629
"frame descriptor, but it is missing.";
630+
#endif
628631
} else {
629632
if (video_header.is_first_packet_in_frame) {
630633
RTC_DCHECK(video_header.generic);
@@ -810,6 +813,11 @@ void RtpVideoStreamReceiver2::OnInsertedPacket(
810813
std::vector<rtc::ArrayView<const uint8_t>> payloads;
811814
RtpPacketInfos::vector_type packet_infos;
812815

816+
// Add timing information required by sender-side BWE.
817+
#if defined(WEBRTC_WIN)
818+
int64_t max_tc = 0, min_tc = 0;
819+
double start_duration = 0, last_duration = 0;
820+
#endif
813821
bool frame_boundary = true;
814822
for (auto& packet : result.packets) {
815823
// PacketBuffer promisses frame boundaries are correctly set on each
@@ -824,16 +832,28 @@ void RtpVideoStreamReceiver2::OnInsertedPacket(
824832
max_nack_count = packet->times_nacked;
825833
min_recv_time = packet_info.receive_time().ms();
826834
max_recv_time = packet_info.receive_time().ms();
835+
#if defined(WEBRTC_WIN)
836+
max_tc = min_tc = packet->time_ticks;
837+
#endif
827838
} else {
828839
max_nack_count = std::max(max_nack_count, packet->times_nacked);
829840
min_recv_time = std::min(min_recv_time, packet_info.receive_time().ms());
830841
max_recv_time = std::max(max_recv_time, packet_info.receive_time().ms());
842+
#if defined(WEBRTC_WIN)
843+
max_tc = std::max(max_tc, packet->time_ticks);
844+
min_tc = std::min(min_tc, packet->time_ticks);
845+
#endif
831846
}
832847
payloads.emplace_back(packet->video_payload);
833848
packet_infos.push_back(packet_info);
834849

835850
frame_boundary = packet->is_last_packet_in_frame();
836851
if (packet->is_last_packet_in_frame()) {
852+
#if defined(WEBRTC_WIN)
853+
clock_sync_.Sync(packet->timestamp, min_tc);
854+
start_duration = clock_sync_.GetDuration(packet->timestamp, min_tc);
855+
last_duration = clock_sync_.GetDuration(packet->timestamp, max_tc);
856+
#endif
837857
auto depacketizer_it = payload_type_map_.find(first_packet->payload_type);
838858
RTC_CHECK(depacketizer_it != payload_type_map_.end());
839859

@@ -845,24 +865,35 @@ void RtpVideoStreamReceiver2::OnInsertedPacket(
845865
}
846866

847867
const video_coding::PacketBuffer::Packet& last_packet = *packet;
848-
OnAssembledFrame(std::make_unique<RtpFrameObject>(
849-
first_packet->seq_num, //
850-
last_packet.seq_num, //
851-
last_packet.marker_bit, //
852-
max_nack_count, //
853-
min_recv_time, //
854-
max_recv_time, //
855-
first_packet->timestamp, //
868+
std::unique_ptr<video_coding::RtpFrameObject> frame =
869+
std::make_unique<video_coding::RtpFrameObject>(
870+
first_packet->seq_num, //
871+
last_packet.seq_num, //
872+
last_packet.marker_bit, //
873+
max_nack_count, //
874+
min_recv_time, //
875+
max_recv_time, //
876+
first_packet->timestamp, //
856877
ntp_estimator_.Estimate(first_packet->timestamp), //
857-
last_packet.video_header.video_timing, //
858-
first_packet->payload_type, //
859-
first_packet->codec(), //
860-
last_packet.video_header.rotation, //
861-
last_packet.video_header.content_type, //
862-
first_packet->video_header, //
863-
last_packet.video_header.color_space, //
864-
RtpPacketInfos(std::move(packet_infos)), //
865-
std::move(bitstream)));
878+
last_packet.video_header.video_timing, //
879+
first_packet->payload_type, //
880+
first_packet->codec(), //
881+
last_packet.video_header.rotation, //
882+
last_packet.video_header.content_type, //
883+
first_packet->video_header, //
884+
last_packet.video_header.color_space, //
885+
RtpPacketInfos(std::move(packet_infos)), //
886+
std::move(bitstream));
887+
#if defined(WEBRTC_WIN)
888+
StreamStatistician* ss =
889+
rtp_receive_statistics_->GetStatistician(config_.rtp.remote_ssrc);
890+
int32_t packets_lost = 0;
891+
if (ss != nullptr) {
892+
packets_lost = ss->GetStats().packets_lost;
893+
frame->SetBWETiming(start_duration, last_duration, packets_lost);
894+
}
895+
#endif
896+
OnAssembledFrame(std::move(frame));
866897
payloads.clear();
867898
packet_infos.clear();
868899
}

0 commit comments

Comments
 (0)