Implementation for rtcp sender report

This commit is contained in:
dijunkun
2023-09-12 17:30:08 +08:00
parent 8c545f7544
commit c1d31790d4
15 changed files with 470 additions and 204 deletions

View File

@@ -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);

View File

@@ -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>();

View File

@@ -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_) {

View File

@@ -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