mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-27 04:35:34 +08:00
Implementation for rtcp sender report
This commit is contained in:
@@ -141,30 +141,30 @@ class RtpPacket {
|
||||
|
||||
public:
|
||||
// Get Header
|
||||
const uint32_t Verion() { return version_; }
|
||||
const bool HasPadding() { return has_padding_; }
|
||||
const bool HasExtension() { return has_extension_; }
|
||||
const bool Marker() { return marker_; }
|
||||
const PAYLOAD_TYPE PayloadType() { return PAYLOAD_TYPE(payload_type_); }
|
||||
const uint16_t SequenceNumber() { return sequence_number_; }
|
||||
const uint32_t Timestamp() { return timestamp_; }
|
||||
const uint32_t Ssrc() { return ssrc_; }
|
||||
const std::vector<uint32_t> Csrcs() { return csrcs_; };
|
||||
const uint16_t ExtensionProfile() { return extension_profile_; }
|
||||
const uint8_t *ExtensionData() { return extension_data_; }
|
||||
uint32_t Verion() const { return version_; }
|
||||
bool HasPadding() const { return has_padding_; }
|
||||
bool HasExtension() const { return has_extension_; }
|
||||
bool Marker() const { return marker_; }
|
||||
PAYLOAD_TYPE PayloadType() const { return PAYLOAD_TYPE(payload_type_); }
|
||||
uint16_t SequenceNumber() const { return sequence_number_; }
|
||||
uint32_t Timestamp() const { return timestamp_; }
|
||||
uint32_t Ssrc() const { return ssrc_; }
|
||||
std::vector<uint32_t> Csrcs() const { return csrcs_; };
|
||||
uint16_t ExtensionProfile() const { return extension_profile_; }
|
||||
const uint8_t *ExtensionData() const { return extension_data_; }
|
||||
|
||||
// Payload
|
||||
const uint8_t *Payload() { return payload_; };
|
||||
const size_t PayloadSize() { return payload_size_; }
|
||||
const uint8_t *Payload() const { return payload_; };
|
||||
size_t PayloadSize() const { return payload_size_; }
|
||||
|
||||
// Entire RTP buffer
|
||||
const uint8_t *Buffer() { return buffer_; }
|
||||
const size_t Size() { return size_; }
|
||||
const uint8_t *Buffer() const { return buffer_; }
|
||||
size_t Size() const { return size_; }
|
||||
|
||||
// NAL
|
||||
const NAL_UNIT_TYPE NalUnitType() { return nal_unit_type_; }
|
||||
const bool FuAStart() { return fu_header_.start; }
|
||||
const bool FuAEnd() { return fu_header_.end; }
|
||||
NAL_UNIT_TYPE NalUnitType() const { return nal_unit_type_; }
|
||||
bool FuAStart() const { return fu_header_.start; }
|
||||
bool FuAEnd() const { return fu_header_.end; }
|
||||
|
||||
private:
|
||||
inline void TryToDecodeH264RtpPacket(uint8_t *buffer);
|
||||
|
||||
@@ -9,6 +9,10 @@ RtpVideoReceiver::RtpVideoReceiver() {}
|
||||
RtpVideoReceiver::~RtpVideoReceiver() {}
|
||||
|
||||
void RtpVideoReceiver::InsertRtpPacket(RtpPacket& rtp_packet) {
|
||||
if (rtp_packet.PayloadType() == 200) {
|
||||
LOG_ERROR("!!!!!!!!!!!!!!!!!!");
|
||||
}
|
||||
|
||||
if (!rtp_video_receive_statistics_) {
|
||||
rtp_video_receive_statistics_ =
|
||||
std::make_unique<RtpVideoReceiveStatistics>();
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "log.h"
|
||||
|
||||
#define RTCP_INTERVAL 1000
|
||||
|
||||
RtpVideoSender::RtpVideoSender() {}
|
||||
|
||||
RtpVideoSender::~RtpVideoSender() { rtp_video_send_statistics_->Stop(); }
|
||||
@@ -19,6 +21,88 @@ void RtpVideoSender::Enqueue(std::vector<RtpPacket>& rtp_packets) {
|
||||
}
|
||||
}
|
||||
|
||||
void RtpVideoSender::SetUdpSender(
|
||||
std::function<int(const char*, size_t)> udp_sender) {
|
||||
udp_sender_ = udp_sender;
|
||||
}
|
||||
|
||||
int RtpVideoSender::SendRtpPacket(RtpPacket& rtp_packet) {
|
||||
if (!udp_sender_) {
|
||||
LOG_ERROR("udp_sender_ is nullptr");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
|
||||
if (0 != udp_sender_((const char*)rtp_packet.Buffer(), rtp_packet.Size())) {
|
||||
LOG_ERROR("Send rtp packet failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
last_send_bytes_ += rtp_packet.Size();
|
||||
total_rtp_packets_sent_++;
|
||||
total_rtp_payload_sent_ += rtp_packet.PayloadSize();
|
||||
|
||||
if (CheckIsTimeSendRtcpPacket()) {
|
||||
RtcpSenderReport rtcp_sr;
|
||||
RtcpSenderReport::SENDER_INFO sender_info;
|
||||
|
||||
auto duration = std::chrono::system_clock::now().time_since_epoch();
|
||||
auto seconds = std::chrono::duration_cast<std::chrono::seconds>(duration);
|
||||
uint32_t seconds_u32 = static_cast<uint32_t>(
|
||||
std::chrono::duration_cast<std::chrono::seconds>(duration).count());
|
||||
|
||||
uint32_t fraction_u32 = static_cast<uint32_t>(
|
||||
std::chrono::duration_cast<std::chrono::nanoseconds>(duration - seconds)
|
||||
.count());
|
||||
|
||||
sender_info.sender_ssrc = 0x00;
|
||||
sender_info.ntp_ts = (uint64_t)seconds_u32 << 32 | (uint64_t)fraction_u32;
|
||||
sender_info.rtp_ts =
|
||||
std::chrono::high_resolution_clock::now().time_since_epoch().count() *
|
||||
1000000;
|
||||
sender_info.sender_packet_count = total_rtp_packets_sent_;
|
||||
sender_info.sender_octet_count = total_rtp_payload_sent_;
|
||||
|
||||
rtcp_sr.SetSenderInfo(sender_info);
|
||||
|
||||
rtcp_sr.Encode();
|
||||
|
||||
SendRtcpSR(rtcp_sr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RtpVideoSender::SendRtcpSR(RtcpSenderReport& rtcp_sr) {
|
||||
if (!udp_sender_) {
|
||||
LOG_ERROR("udp_sender_ is nullptr");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (udp_sender_((const char*)rtcp_sr.Buffer(), rtcp_sr.Size())) {
|
||||
LOG_ERROR("Send SR failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
LOG_ERROR("Send SR");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool RtpVideoSender::CheckIsTimeSendRtcpPacket() {
|
||||
auto now_ts =
|
||||
std::chrono::high_resolution_clock::now().time_since_epoch().count() *
|
||||
1000000;
|
||||
|
||||
if (now_ts - last_send_rtcp_packet_ts_ >= RTCP_INTERVAL) {
|
||||
last_send_rtcp_packet_ts_ = now_ts;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool RtpVideoSender::Process() {
|
||||
last_send_bytes_ = 0;
|
||||
|
||||
@@ -26,10 +110,7 @@ bool RtpVideoSender::Process() {
|
||||
if (!rtp_packe_queue_.isEmpty()) {
|
||||
RtpPacket rtp_packet;
|
||||
rtp_packe_queue_.pop(rtp_packet);
|
||||
if (rtp_packet_send_func_) {
|
||||
rtp_packet_send_func_(rtp_packet);
|
||||
last_send_bytes_ += rtp_packet.Size();
|
||||
}
|
||||
SendRtpPacket(rtp_packet);
|
||||
}
|
||||
|
||||
if (rtp_video_send_statistics_) {
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <functional>
|
||||
|
||||
#include "ringbuffer.h"
|
||||
#include "rtcp_packet.h"
|
||||
#include "rtcp_sender_report.h"
|
||||
#include "rtp_packet.h"
|
||||
#include "rtp_video_send_statistics.h"
|
||||
#include "thread_base.h"
|
||||
@@ -17,21 +19,28 @@ class RtpVideoSender : public ThreadBase {
|
||||
void Enqueue(std::vector<RtpPacket> &rtp_packets);
|
||||
|
||||
public:
|
||||
void SetRtpPacketSendFunc(
|
||||
std::function<void(RtpPacket &)> rtp_packet_send_func) {
|
||||
rtp_packet_send_func_ = rtp_packet_send_func;
|
||||
}
|
||||
void SetUdpSender(
|
||||
std::function<int(const char *, size_t)> rtp_packet_send_func);
|
||||
|
||||
private:
|
||||
int SendRtpPacket(RtpPacket &rtp_packet);
|
||||
int SendRtcpSR(RtcpSenderReport &rtcp_sr);
|
||||
|
||||
bool CheckIsTimeSendRtcpPacket();
|
||||
|
||||
private:
|
||||
bool Process() override;
|
||||
|
||||
private:
|
||||
std::function<void(RtpPacket &)> rtp_packet_send_func_ = nullptr;
|
||||
std::function<int(const char *, size_t)> udp_sender_ = nullptr;
|
||||
RingBuffer<RtpPacket> rtp_packe_queue_;
|
||||
|
||||
private:
|
||||
std::unique_ptr<RtpVideoSendStatistics> rtp_video_send_statistics_ = nullptr;
|
||||
uint32_t last_send_bytes_ = 0;
|
||||
uint32_t last_send_rtcp_packet_ts_ = 0;
|
||||
uint32_t total_rtp_packets_sent_ = 0;
|
||||
uint32_t total_rtp_payload_sent_ = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user