[fix] fix video frame capture timestamp

This commit is contained in:
dijunkun
2025-03-19 14:35:48 +08:00
parent 257581e5e9
commit 1cd9ea1b0e
22 changed files with 45 additions and 50 deletions

View File

@@ -68,12 +68,12 @@ int64_t SystemClock::CurrentTimeNs() {
return ticks; return ticks;
} }
int64_t SystemClock::CurrentTime() { return CurrentTimeNs() / 1000LL; }
int64_t SystemClock::CurrentTimeUs() { return CurrentTimeNs() / 1000LL; } int64_t SystemClock::CurrentTimeUs() { return CurrentTimeNs() / 1000LL; }
int64_t SystemClock::CurrentTimeMs() { return CurrentTimeNs() / 1000000LL; } int64_t SystemClock::CurrentTimeMs() { return CurrentTimeNs() / 1000000LL; }
int64_t SystemClock::CurrentTime() { return CurrentTimeNs() / 1000000000LL; }
int64_t SystemClock::CurrentNtpTime() { int64_t SystemClock::CurrentNtpTime() {
return ConvertToNtpTime(CurrentTimeNs()); return ConvertToNtpTime(CurrentTimeNs());
} }

View File

@@ -18,8 +18,8 @@ class SystemClock {
~SystemClock() = default; ~SystemClock() = default;
int64_t CurrentTime(); int64_t CurrentTime();
int64_t CurrentTimeMs();
int64_t CurrentTimeUs(); int64_t CurrentTimeUs();
int64_t CurrentTimeMs();
int64_t CurrentTimeNs(); int64_t CurrentTimeNs();
int64_t CurrentNtpTime(); int64_t CurrentNtpTime();

View File

@@ -23,10 +23,10 @@ class VideoFrameWrapper : public VideoFrame {
VideoFrameWrapper() = delete; VideoFrameWrapper() = delete;
~VideoFrameWrapper() = default; ~VideoFrameWrapper() = default;
int64_t CaptureTimestamp() { return capture_timestamp_ms_; } int64_t CaptureTimestamp() { return capture_timestamp_us_; }
void SetCaptureTimestamp(int64_t capture_timestamp_ms) { void SetCaptureTimestamp(int64_t capture_timestamp_us) {
capture_timestamp_ms_ = capture_timestamp_ms; capture_timestamp_us_ = capture_timestamp_us;
} }
VideoFrameType FrameType() { return frame_type_; } VideoFrameType FrameType() { return frame_type_; }
@@ -46,7 +46,7 @@ class VideoFrameWrapper : public VideoFrame {
} }
private: private:
int64_t capture_timestamp_ms_ = 0; int64_t capture_timestamp_us_ = 0;
VideoFrameType frame_type_ = VideoFrameType::kVideoFrameDelta; VideoFrameType frame_type_ = VideoFrameType::kVideoFrameDelta;
uint32_t encoded_width_ = 0; uint32_t encoded_width_ = 0;
uint32_t encoded_height_ = 0; uint32_t encoded_height_ = 0;

View File

@@ -134,7 +134,7 @@ DLLAPI int SendAudioFrame(PeerPtr* peer_ptr, const char* data, size_t size);
DLLAPI int SendDataFrame(PeerPtr* peer_ptr, const char* data, size_t size); DLLAPI int SendDataFrame(PeerPtr* peer_ptr, const char* data, size_t size);
DLLAPI int64_t CurrentNtpTimeMs(PeerPtr* peer_ptr); DLLAPI int64_t GetSystemTimeMicros(PeerPtr* peer_ptr);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -390,9 +390,9 @@ int PeerConnection::SendDataFrame(const char *data, size_t size) {
return 0; return 0;
} }
int64_t PeerConnection::CurrentNtpTimeMs() { int64_t PeerConnection::GetSystemTimeMicros() {
if (clock_) { if (clock_) {
return clock_->CurrentNtpTimeMs(); return clock_->CurrentTimeUs();
} }
return 0; return 0;
} }

View File

@@ -108,7 +108,7 @@ class PeerConnection {
int SendAudioFrame(const char *data, size_t size); int SendAudioFrame(const char *data, size_t size);
int SendDataFrame(const char *data, size_t size); int SendDataFrame(const char *data, size_t size);
int64_t CurrentNtpTimeMs(); int64_t GetSystemTimeMicros();
private: private:
int Login(); int Login();

View File

@@ -149,10 +149,10 @@ int SendDataFrame(PeerPtr *peer_ptr, const char *data, size_t size) {
return 0; return 0;
} }
int64_t CurrentNtpTimeMs(PeerPtr *peer_ptr) { int64_t GetSystemTimeMicros(PeerPtr *peer_ptr) {
if (!peer_ptr || !peer_ptr->peer_connection) { if (!peer_ptr || !peer_ptr->peer_connection) {
LOG_ERROR("Peer connection not created"); LOG_ERROR("Peer connection not created");
return -1; return -1;
} }
return peer_ptr->peer_connection->CurrentNtpTimeMs(); return peer_ptr->peer_connection->GetSystemTimeMicros();
} }

View File

@@ -22,11 +22,11 @@ class RtpPacketizer {
virtual ~RtpPacketizer() = default; virtual ~RtpPacketizer() = default;
virtual std::vector<std::unique_ptr<RtpPacket>> Build( virtual std::vector<std::unique_ptr<RtpPacket>> Build(
uint8_t* payload, uint32_t payload_size, int64_t capture_timestamp_ms, uint8_t* payload, uint32_t payload_size, int64_t capture_timestamp_us,
bool use_rtp_packet_to_send) = 0; bool use_rtp_packet_to_send) = 0;
virtual std::vector<std::unique_ptr<RtpPacket>> BuildPadding( virtual std::vector<std::unique_ptr<RtpPacket>> BuildPadding(
uint32_t payload_size, int64_t capture_timestamp_ms, uint32_t payload_size, int64_t capture_timestamp_us,
bool use_rtp_packet_to_send) = 0; bool use_rtp_packet_to_send) = 0;
}; };

View File

@@ -5,7 +5,7 @@ RtpPacketizerAv1::RtpPacketizerAv1(uint32_t ssrc) {}
RtpPacketizerAv1::~RtpPacketizerAv1() {} RtpPacketizerAv1::~RtpPacketizerAv1() {}
std::vector<std::unique_ptr<RtpPacket>> RtpPacketizerAv1::Build( std::vector<std::unique_ptr<RtpPacket>> RtpPacketizerAv1::Build(
uint8_t* payload, uint32_t payload_size, int64_t capture_timestamp_ms, uint8_t* payload, uint32_t payload_size, int64_t capture_timestamp_us,
bool use_rtp_packet_to_send) { bool use_rtp_packet_to_send) {
std::vector<std::unique_ptr<RtpPacket>> rtp_packets; std::vector<std::unique_ptr<RtpPacket>> rtp_packets;

View File

@@ -16,11 +16,11 @@ class RtpPacketizerAv1 : public RtpPacketizer {
virtual ~RtpPacketizerAv1(); virtual ~RtpPacketizerAv1();
std::vector<std::unique_ptr<RtpPacket>> Build( std::vector<std::unique_ptr<RtpPacket>> Build(
uint8_t* payload, uint32_t payload_size, int64_t capture_timestamp_ms, uint8_t* payload, uint32_t payload_size, int64_t capture_timestamp_us,
bool use_rtp_packet_to_send) override; bool use_rtp_packet_to_send) override;
std::vector<std::unique_ptr<RtpPacket>> BuildPadding( std::vector<std::unique_ptr<RtpPacket>> BuildPadding(
uint32_t payload_size, int64_t capture_timestamp_ms, uint32_t payload_size, int64_t capture_timestamp_us,
bool use_rtp_packet_to_send) override { bool use_rtp_packet_to_send) override {
return std::vector<std::unique_ptr<RtpPacket>>{}; return std::vector<std::unique_ptr<RtpPacket>>{};
}; };

View File

@@ -47,7 +47,7 @@ void RtpPacketizerGeneric::AddAbsSendTimeExtension(
} }
std::vector<std::unique_ptr<RtpPacket>> RtpPacketizerGeneric::Build( std::vector<std::unique_ptr<RtpPacket>> RtpPacketizerGeneric::Build(
uint8_t* payload, uint32_t payload_size, int64_t capture_timestamp_ms, uint8_t* payload, uint32_t payload_size, int64_t capture_timestamp_us,
bool use_rtp_packet_to_send) { bool use_rtp_packet_to_send) {
uint32_t last_packet_size = payload_size % MAX_NALU_LEN; uint32_t last_packet_size = payload_size % MAX_NALU_LEN;
uint32_t packet_num = uint32_t packet_num =

View File

@@ -16,11 +16,11 @@ class RtpPacketizerGeneric : public RtpPacketizer {
virtual ~RtpPacketizerGeneric(); virtual ~RtpPacketizerGeneric();
std::vector<std::unique_ptr<RtpPacket>> Build( std::vector<std::unique_ptr<RtpPacket>> Build(
uint8_t* payload, uint32_t payload_size, int64_t capture_timestamp_ms, uint8_t* payload, uint32_t payload_size, int64_t capture_timestamp_us,
bool use_rtp_packet_to_send) override; bool use_rtp_packet_to_send) override;
std::vector<std::unique_ptr<RtpPacket>> BuildPadding( std::vector<std::unique_ptr<RtpPacket>> BuildPadding(
uint32_t payload_size, int64_t capture_timestamp_ms, uint32_t payload_size, int64_t capture_timestamp_us,
bool use_rtp_packet_to_send) override { bool use_rtp_packet_to_send) override {
return std::vector<std::unique_ptr<RtpPacket>>{}; return std::vector<std::unique_ptr<RtpPacket>>{};
}; };

View File

@@ -61,19 +61,19 @@ void RtpPacketizerH264::AddAbsSendTimeExtension(
} }
std::vector<std::unique_ptr<RtpPacket>> RtpPacketizerH264::Build( std::vector<std::unique_ptr<RtpPacket>> RtpPacketizerH264::Build(
uint8_t* payload, uint32_t payload_size, int64_t capture_timestamp_ms, uint8_t* payload, uint32_t payload_size, int64_t capture_timestamp_us,
bool use_rtp_packet_to_send) { bool use_rtp_packet_to_send) {
if (payload_size <= MAX_NALU_LEN) { if (payload_size <= MAX_NALU_LEN) {
return BuildNalu(payload, payload_size, capture_timestamp_ms, return BuildNalu(payload, payload_size, capture_timestamp_us,
use_rtp_packet_to_send); use_rtp_packet_to_send);
} else { } else {
return BuildFua(payload, payload_size, capture_timestamp_ms, return BuildFua(payload, payload_size, capture_timestamp_us,
use_rtp_packet_to_send); use_rtp_packet_to_send);
} }
} }
std::vector<std::unique_ptr<RtpPacket>> RtpPacketizerH264::BuildNalu( std::vector<std::unique_ptr<RtpPacket>> RtpPacketizerH264::BuildNalu(
uint8_t* payload, uint32_t payload_size, int64_t capture_timestamp_ms, uint8_t* payload, uint32_t payload_size, int64_t capture_timestamp_us,
bool use_rtp_packet_to_send) { bool use_rtp_packet_to_send) {
std::vector<std::unique_ptr<RtpPacket>> rtp_packets; std::vector<std::unique_ptr<RtpPacket>> rtp_packets;
@@ -84,7 +84,7 @@ std::vector<std::unique_ptr<RtpPacket>> RtpPacketizerH264::BuildNalu(
marker_ = 1; marker_ = 1;
payload_type_ = rtp::PAYLOAD_TYPE(payload_type_); payload_type_ = rtp::PAYLOAD_TYPE(payload_type_);
sequence_number_++; sequence_number_++;
timestamp_ = kMsToRtpTimestamp * static_cast<uint32_t>(capture_timestamp_ms); timestamp_ = kMsToRtpTimestamp * static_cast<uint32_t>(capture_timestamp_us);
if (!csrc_count_) { if (!csrc_count_) {
} }
@@ -142,7 +142,7 @@ std::vector<std::unique_ptr<RtpPacket>> RtpPacketizerH264::BuildNalu(
} }
std::vector<std::unique_ptr<RtpPacket>> RtpPacketizerH264::BuildFua( std::vector<std::unique_ptr<RtpPacket>> RtpPacketizerH264::BuildFua(
uint8_t* payload, uint32_t payload_size, int64_t capture_timestamp_ms, uint8_t* payload, uint32_t payload_size, int64_t capture_timestamp_us,
bool use_rtp_packet_to_send) { bool use_rtp_packet_to_send) {
std::vector<std::unique_ptr<RtpPacket>> rtp_packets; std::vector<std::unique_ptr<RtpPacket>> rtp_packets;
@@ -242,7 +242,7 @@ std::vector<std::unique_ptr<RtpPacket>> RtpPacketizerH264::BuildFua(
} }
std::vector<std::unique_ptr<RtpPacket>> RtpPacketizerH264::BuildPadding( std::vector<std::unique_ptr<RtpPacket>> RtpPacketizerH264::BuildPadding(
uint32_t payload_size, int64_t capture_timestamp_ms, uint32_t payload_size, int64_t capture_timestamp_us,
bool use_rtp_packet_to_send) { bool use_rtp_packet_to_send) {
std::vector<std::unique_ptr<RtpPacket>> rtp_packets; std::vector<std::unique_ptr<RtpPacket>> rtp_packets;
@@ -259,7 +259,7 @@ std::vector<std::unique_ptr<RtpPacket>> RtpPacketizerH264::BuildPadding(
uint8_t payload_type = rtp::PAYLOAD_TYPE(payload_type_ - 1); uint8_t payload_type = rtp::PAYLOAD_TYPE(payload_type_ - 1);
sequence_number_++; sequence_number_++;
timestamp_ = timestamp_ =
kMsToRtpTimestamp * static_cast<uint32_t>(capture_timestamp_ms); kMsToRtpTimestamp * static_cast<uint32_t>(capture_timestamp_us);
rtp_packet_frame_.clear(); rtp_packet_frame_.clear();
rtp_packet_frame_.push_back((version_ << 6) | (has_padding_ << 5) | rtp_packet_frame_.push_back((version_ << 6) | (has_padding_ << 5) |

View File

@@ -16,20 +16,20 @@ class RtpPacketizerH264 : public RtpPacketizer {
virtual ~RtpPacketizerH264(); virtual ~RtpPacketizerH264();
std::vector<std::unique_ptr<RtpPacket>> Build( std::vector<std::unique_ptr<RtpPacket>> Build(
uint8_t* payload, uint32_t payload_size, int64_t capture_timestamp_ms, uint8_t* payload, uint32_t payload_size, int64_t capture_timestamp_us,
bool use_rtp_packet_to_send) override; bool use_rtp_packet_to_send) override;
std::vector<std::unique_ptr<RtpPacket>> BuildNalu( std::vector<std::unique_ptr<RtpPacket>> BuildNalu(
uint8_t* payload, uint32_t payload_size, int64_t capture_timestamp_ms, uint8_t* payload, uint32_t payload_size, int64_t capture_timestamp_us,
bool use_rtp_packet_to_send); bool use_rtp_packet_to_send);
std::vector<std::unique_ptr<RtpPacket>> BuildFua(uint8_t* payload, std::vector<std::unique_ptr<RtpPacket>> BuildFua(uint8_t* payload,
uint32_t payload_size, uint32_t payload_size,
int64_t capture_timestamp_ms, int64_t capture_timestamp_us,
bool use_rtp_packet_to_send); bool use_rtp_packet_to_send);
std::vector<std::unique_ptr<RtpPacket>> BuildPadding( std::vector<std::unique_ptr<RtpPacket>> BuildPadding(
uint32_t payload_size, int64_t capture_timestamp_ms, uint32_t payload_size, int64_t capture_timestamp_us,
bool use_rtp_packet_to_send) override; bool use_rtp_packet_to_send) override;
private: private:

View File

@@ -45,7 +45,7 @@ RtpVideoSender::~RtpVideoSender() {
void RtpVideoSender::Enqueue( void RtpVideoSender::Enqueue(
std::vector<std::unique_ptr<RtpPacket>>& rtp_packets, std::vector<std::unique_ptr<RtpPacket>>& rtp_packets,
int64_t capture_timestamp_ms) { int64_t capture_timestamp_us) {
if (!rtp_statistics_) { if (!rtp_statistics_) {
rtp_statistics_ = std::make_unique<RtpStatistics>(); rtp_statistics_ = std::make_unique<RtpStatistics>();
rtp_statistics_->Start(); rtp_statistics_->Start();

View File

@@ -24,7 +24,7 @@ class RtpVideoSender : public ThreadBase {
public: public:
void Enqueue(std::vector<std::unique_ptr<RtpPacket>> &rtp_packets, void Enqueue(std::vector<std::unique_ptr<RtpPacket>> &rtp_packets,
int64_t capture_timestamp_ms); int64_t capture_timestamp_us);
void SetSendDataFunc(std::function<int(const char *, size_t)> data_send_func); void SetSendDataFunc(std::function<int(const char *, size_t)> data_send_func);
void SetOnSentPacketFunc( void SetOnSentPacketFunc(
std::function<void(const webrtc::RtpPacketToSend &)> on_sent_packet_func); std::function<void(const webrtc::RtpPacketToSend &)> on_sent_packet_func);

View File

@@ -57,9 +57,9 @@ void VideoChannelSend::SetEnqueuePacketsFunc(
} }
std::vector<std::unique_ptr<RtpPacket>> VideoChannelSend::GeneratePadding( std::vector<std::unique_ptr<RtpPacket>> VideoChannelSend::GeneratePadding(
uint32_t payload_size, int64_t capture_timestamp_ms) { uint32_t payload_size, int64_t capture_timestamp_us) {
if (rtp_packetizer_) { if (rtp_packetizer_) {
return rtp_packetizer_->BuildPadding(payload_size, capture_timestamp_ms, return rtp_packetizer_->BuildPadding(payload_size, capture_timestamp_us,
true); true);
} }
return std::vector<std::unique_ptr<RtpPacket>>{}; return std::vector<std::unique_ptr<RtpPacket>>{};

View File

@@ -36,7 +36,7 @@ class VideoChannelSend {
enqueue_packets_func); enqueue_packets_func);
std::vector<std::unique_ptr<RtpPacket>> GeneratePadding( std::vector<std::unique_ptr<RtpPacket>> GeneratePadding(
uint32_t payload_size, int64_t capture_timestamp_ms); uint32_t payload_size, int64_t capture_timestamp_us);
int64_t GetTransportSeqAndIncrement() { int64_t GetTransportSeqAndIncrement() {
int64_t transport_seq = rtp_video_sender_->GetTransportSequenceNumber(); int64_t transport_seq = rtp_video_sender_->GetTransportSequenceNumber();

View File

@@ -75,9 +75,9 @@ void IceTransportController::Create(
}); });
packet_sender_->SetGeneratePaddingFunc( packet_sender_->SetGeneratePaddingFunc(
[this](uint32_t size, int64_t capture_timestamp_ms) [this](uint32_t size, int64_t capture_timestamp_us)
-> std::vector<std::unique_ptr<RtpPacket>> { -> std::vector<std::unique_ptr<RtpPacket>> {
return video_channel_send_->GeneratePadding(size, capture_timestamp_ms); return video_channel_send_->GeneratePadding(size, capture_timestamp_us);
}); });
audio_channel_send_ = std::make_unique<AudioChannelSend>( audio_channel_send_ = std::make_unique<AudioChannelSend>(
@@ -170,6 +170,7 @@ int IceTransportController::SendVideo(const XVideoFrame* video_frame) {
new_frame.width = video_frame->width; new_frame.width = video_frame->width;
new_frame.height = video_frame->height; new_frame.height = video_frame->height;
new_frame.size = video_frame->size; new_frame.size = video_frame->size;
new_frame.timestamp = video_frame->timestamp;
if (target_width_.has_value() && target_height_.has_value()) { if (target_width_.has_value() && target_height_.has_value()) {
if (target_width_.value() < video_frame->width && if (target_width_.value() < video_frame->width &&
target_height_.value() < video_frame->height) { target_height_.value() < video_frame->height) {

View File

@@ -20,7 +20,7 @@ class PacketSender {
virtual int Send() = 0; virtual int Send() = 0;
virtual int EnqueueRtpPacket( virtual int EnqueueRtpPacket(
std::vector<std::unique_ptr<RtpPacket>> &rtp_packets, std::vector<std::unique_ptr<RtpPacket>> &rtp_packets,
int64_t capture_timestamp_ms) = 0; int64_t capture_timestamp_us) = 0;
}; };
#endif #endif

View File

@@ -250,13 +250,13 @@ PacketSenderImp::Stats PacketSenderImp::GetStats() const {
int PacketSenderImp::EnqueueRtpPacket( int PacketSenderImp::EnqueueRtpPacket(
std::vector<std::unique_ptr<RtpPacket>> &rtp_packets, std::vector<std::unique_ptr<RtpPacket>> &rtp_packets,
int64_t capture_timestamp_ms) { int64_t capture_timestamp_us) {
std::vector<std::unique_ptr<webrtc::RtpPacketToSend>> to_send_rtp_packets; std::vector<std::unique_ptr<webrtc::RtpPacketToSend>> to_send_rtp_packets;
for (auto &rtp_packet : rtp_packets) { for (auto &rtp_packet : rtp_packets) {
std::unique_ptr<webrtc::RtpPacketToSend> rtp_packet_to_send( std::unique_ptr<webrtc::RtpPacketToSend> rtp_packet_to_send(
static_cast<webrtc::RtpPacketToSend *>(rtp_packet.release())); static_cast<webrtc::RtpPacketToSend *>(rtp_packet.release()));
rtp_packet_to_send->set_capture_time( rtp_packet_to_send->set_capture_time(
webrtc::Timestamp::Millis(capture_timestamp_ms)); webrtc::Timestamp::Micros(capture_timestamp_us));
rtp_packet_to_send->set_transport_sequence_number(transport_seq_++); rtp_packet_to_send->set_transport_sequence_number(transport_seq_++);
switch (rtp_packet_to_send->PayloadType()) { switch (rtp_packet_to_send->PayloadType()) {

View File

@@ -38,7 +38,7 @@ class PacketSenderImp : public PacketSender,
int Send() { return 0; } int Send() { return 0; }
int EnqueueRtpPacket(std::vector<std::unique_ptr<RtpPacket>>& rtp_packets, int EnqueueRtpPacket(std::vector<std::unique_ptr<RtpPacket>>& rtp_packets,
int64_t capture_timestamp_ms); int64_t capture_timestamp_us);
void SetOnSentPacketFunc( void SetOnSentPacketFunc(
std::function<void(const webrtc::RtpPacketToSend&)> on_sent_packet_func) { std::function<void(const webrtc::RtpPacketToSend&)> on_sent_packet_func) {
@@ -61,12 +61,6 @@ class PacketSenderImp : public PacketSender,
packet->UpdateSequenceNumber(ssrc_seq_[packet->Ssrc()]++); packet->UpdateSequenceNumber(ssrc_seq_[packet->Ssrc()]++);
webrtc::Timestamp now = clock_->CurrentTime();
webrtc::TimeDelta interval = now - last_send_time_;
webrtc::TimeDelta delay = now - packet->capture_time();
LOG_WARN("interval: {}, delay: {}", interval.ms(), delay.seconds());
last_send_time_ = now;
on_sent_packet_func_(*packet); on_sent_packet_func_(*packet);
} }
} }