mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-27 04:35:34 +08:00
[fix] fix h264 rtp packet packetization and depacketization
This commit is contained in:
@@ -14,10 +14,8 @@ AudioChannelReceive::AudioChannelReceive(
|
|||||||
|
|
||||||
AudioChannelReceive::~AudioChannelReceive() {}
|
AudioChannelReceive::~AudioChannelReceive() {}
|
||||||
|
|
||||||
void AudioChannelReceive::Initialize(RtpPacket::PAYLOAD_TYPE payload_type) {
|
void AudioChannelReceive::Initialize(rtp::PAYLOAD_TYPE payload_type) {
|
||||||
audio_rtp_codec_ = std::make_unique<RtpCodec>(payload_type);
|
|
||||||
rtp_audio_receiver_ = std::make_unique<RtpAudioReceiver>(ice_io_statistics_);
|
rtp_audio_receiver_ = std::make_unique<RtpAudioReceiver>(ice_io_statistics_);
|
||||||
|
|
||||||
rtp_audio_receiver_->SetOnReceiveData(
|
rtp_audio_receiver_->SetOnReceiveData(
|
||||||
[this](const char *data, size_t size) -> void {
|
[this](const char *data, size_t size) -> void {
|
||||||
if (on_receive_audio_) {
|
if (on_receive_audio_) {
|
||||||
@@ -54,7 +52,9 @@ int AudioChannelReceive::OnReceiveRtpPacket(const char *data, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rtp_audio_receiver_) {
|
if (rtp_audio_receiver_) {
|
||||||
rtp_audio_receiver_->InsertRtpPacket(RtpPacket((uint8_t *)data, size));
|
RtpPacket rtp_packet;
|
||||||
|
rtp_packet.Build((uint8_t *)data, (uint32_t)size);
|
||||||
|
rtp_audio_receiver_->InsertRtpPacket(rtp_packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
#include "ice_agent.h"
|
#include "ice_agent.h"
|
||||||
#include "rtp_audio_receiver.h"
|
#include "rtp_audio_receiver.h"
|
||||||
#include "rtp_codec.h"
|
|
||||||
|
|
||||||
class AudioChannelReceive {
|
class AudioChannelReceive {
|
||||||
public:
|
public:
|
||||||
@@ -21,14 +20,13 @@ class AudioChannelReceive {
|
|||||||
~AudioChannelReceive();
|
~AudioChannelReceive();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Initialize(RtpPacket::PAYLOAD_TYPE payload_type);
|
void Initialize(rtp::PAYLOAD_TYPE payload_type);
|
||||||
void Destroy();
|
void Destroy();
|
||||||
int OnReceiveRtpPacket(const char *data, size_t size);
|
int OnReceiveRtpPacket(const char *data, size_t size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<IceAgent> ice_agent_ = nullptr;
|
std::shared_ptr<IceAgent> ice_agent_ = nullptr;
|
||||||
std::shared_ptr<IOStatistics> ice_io_statistics_ = nullptr;
|
std::shared_ptr<IOStatistics> ice_io_statistics_ = nullptr;
|
||||||
std::unique_ptr<RtpCodec> audio_rtp_codec_ = nullptr;
|
|
||||||
std::unique_ptr<RtpAudioReceiver> rtp_audio_receiver_ = nullptr;
|
std::unique_ptr<RtpAudioReceiver> rtp_audio_receiver_ = nullptr;
|
||||||
std::function<void(const char *, size_t)> on_receive_audio_ = nullptr;
|
std::function<void(const char *, size_t)> on_receive_audio_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,9 +11,8 @@ AudioChannelSend::AudioChannelSend(
|
|||||||
std::shared_ptr<IOStatistics> ice_io_statistics)
|
std::shared_ptr<IOStatistics> ice_io_statistics)
|
||||||
: ice_agent_(ice_agent), ice_io_statistics_(ice_io_statistics) {}
|
: ice_agent_(ice_agent), ice_io_statistics_(ice_io_statistics) {}
|
||||||
|
|
||||||
void AudioChannelSend::Initialize(RtpPacket::PAYLOAD_TYPE payload_type) {
|
void AudioChannelSend::Initialize(rtp::PAYLOAD_TYPE payload_type) {
|
||||||
audio_rtp_codec_ = std::make_unique<RtpCodec>(payload_type);
|
rtp_packetizer_ = RtpPacketizer::Create(payload_type);
|
||||||
|
|
||||||
rtp_audio_sender_ = std::make_unique<RtpAudioSender>(ice_io_statistics_);
|
rtp_audio_sender_ = std::make_unique<RtpAudioSender>(ice_io_statistics_);
|
||||||
rtp_audio_sender_->SetSendDataFunc(
|
rtp_audio_sender_->SetSendDataFunc(
|
||||||
[this](const char *data, size_t size) -> int {
|
[this](const char *data, size_t size) -> int {
|
||||||
@@ -45,10 +44,10 @@ void AudioChannelSend::Destroy() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int AudioChannelSend::SendAudio(char *data, size_t size) {
|
int AudioChannelSend::SendAudio(char *data, size_t size) {
|
||||||
if (audio_rtp_codec_) {
|
if (rtp_audio_sender_ && rtp_packetizer_) {
|
||||||
std::vector<RtpPacket> packets;
|
std::vector<RtpPacket> rtp_packets =
|
||||||
audio_rtp_codec_->Encode((uint8_t *)data, (uint32_t)size, packets);
|
rtp_packetizer_->Build((uint8_t *)data, (uint32_t)size);
|
||||||
rtp_audio_sender_->Enqueue(packets);
|
rtp_audio_sender_->Enqueue(rtp_packets);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
#include "ice_agent.h"
|
#include "ice_agent.h"
|
||||||
#include "rtp_audio_sender.h"
|
#include "rtp_audio_sender.h"
|
||||||
#include "rtp_codec.h"
|
#include "rtp_packetizer.h"
|
||||||
|
|
||||||
class AudioChannelSend {
|
class AudioChannelSend {
|
||||||
public:
|
public:
|
||||||
@@ -19,14 +19,14 @@ class AudioChannelSend {
|
|||||||
~AudioChannelSend();
|
~AudioChannelSend();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Initialize(RtpPacket::PAYLOAD_TYPE payload_type);
|
void Initialize(rtp::PAYLOAD_TYPE payload_type);
|
||||||
void Destroy();
|
void Destroy();
|
||||||
int SendAudio(char *data, size_t size);
|
int SendAudio(char *data, size_t size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<IceAgent> ice_agent_ = nullptr;
|
std::shared_ptr<IceAgent> ice_agent_ = nullptr;
|
||||||
std::shared_ptr<IOStatistics> ice_io_statistics_ = nullptr;
|
std::shared_ptr<IOStatistics> ice_io_statistics_ = nullptr;
|
||||||
std::unique_ptr<RtpCodec> audio_rtp_codec_ = nullptr;
|
std::unique_ptr<RtpPacketizer> rtp_packetizer_ = nullptr;
|
||||||
std::unique_ptr<RtpAudioSender> rtp_audio_sender_ = nullptr;
|
std::unique_ptr<RtpAudioSender> rtp_audio_sender_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -14,11 +14,8 @@ DataChannelReceive::DataChannelReceive(
|
|||||||
|
|
||||||
DataChannelReceive::~DataChannelReceive() {}
|
DataChannelReceive::~DataChannelReceive() {}
|
||||||
|
|
||||||
void DataChannelReceive::Initialize(RtpPacket::PAYLOAD_TYPE payload_type) {
|
void DataChannelReceive::Initialize(rtp::PAYLOAD_TYPE payload_type) {
|
||||||
data_rtp_codec_ = std::make_unique<RtpCodec>(payload_type);
|
|
||||||
|
|
||||||
rtp_data_receiver_ = std::make_unique<RtpDataReceiver>(ice_io_statistics_);
|
rtp_data_receiver_ = std::make_unique<RtpDataReceiver>(ice_io_statistics_);
|
||||||
|
|
||||||
rtp_data_receiver_->SetOnReceiveData(
|
rtp_data_receiver_->SetOnReceiveData(
|
||||||
[this](const char *data, size_t size) -> void {
|
[this](const char *data, size_t size) -> void {
|
||||||
if (on_receive_data_) {
|
if (on_receive_data_) {
|
||||||
@@ -55,7 +52,9 @@ int DataChannelReceive::OnReceiveRtpPacket(const char *data, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rtp_data_receiver_) {
|
if (rtp_data_receiver_) {
|
||||||
rtp_data_receiver_->InsertRtpPacket(RtpPacket((uint8_t *)data, size));
|
RtpPacket rtp_packet;
|
||||||
|
rtp_packet.Build((uint8_t *)data, (uint32_t)size);
|
||||||
|
rtp_data_receiver_->InsertRtpPacket(rtp_packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
#define _DATA_CHANNEL_RECEIVE_H_
|
#define _DATA_CHANNEL_RECEIVE_H_
|
||||||
|
|
||||||
#include "ice_agent.h"
|
#include "ice_agent.h"
|
||||||
#include "rtp_codec.h"
|
|
||||||
#include "rtp_data_receiver.h"
|
#include "rtp_data_receiver.h"
|
||||||
|
|
||||||
class DataChannelReceive {
|
class DataChannelReceive {
|
||||||
@@ -20,14 +19,13 @@ class DataChannelReceive {
|
|||||||
~DataChannelReceive();
|
~DataChannelReceive();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Initialize(RtpPacket::PAYLOAD_TYPE payload_type);
|
void Initialize(rtp::PAYLOAD_TYPE payload_type);
|
||||||
void Destroy();
|
void Destroy();
|
||||||
int OnReceiveRtpPacket(const char *data, size_t size);
|
int OnReceiveRtpPacket(const char *data, size_t size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<IceAgent> ice_agent_ = nullptr;
|
std::shared_ptr<IceAgent> ice_agent_ = nullptr;
|
||||||
std::shared_ptr<IOStatistics> ice_io_statistics_ = nullptr;
|
std::shared_ptr<IOStatistics> ice_io_statistics_ = nullptr;
|
||||||
std::unique_ptr<RtpCodec> data_rtp_codec_ = nullptr;
|
|
||||||
std::unique_ptr<RtpDataReceiver> rtp_data_receiver_ = nullptr;
|
std::unique_ptr<RtpDataReceiver> rtp_data_receiver_ = nullptr;
|
||||||
std::function<void(const char *, size_t)> on_receive_data_ = nullptr;
|
std::function<void(const char *, size_t)> on_receive_data_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,9 +11,8 @@ DataChannelSend::DataChannelSend(
|
|||||||
std::shared_ptr<IOStatistics> ice_io_statistics)
|
std::shared_ptr<IOStatistics> ice_io_statistics)
|
||||||
: ice_agent_(ice_agent), ice_io_statistics_(ice_io_statistics) {}
|
: ice_agent_(ice_agent), ice_io_statistics_(ice_io_statistics) {}
|
||||||
|
|
||||||
void DataChannelSend::Initialize(RtpPacket::PAYLOAD_TYPE payload_type) {
|
void DataChannelSend::Initialize(rtp::PAYLOAD_TYPE payload_type) {
|
||||||
data_rtp_codec_ = std::make_unique<RtpCodec>(payload_type);
|
rtp_packetizer_ = RtpPacketizer::Create(payload_type);
|
||||||
|
|
||||||
rtp_data_sender_ = std::make_unique<RtpDataSender>(ice_io_statistics_);
|
rtp_data_sender_ = std::make_unique<RtpDataSender>(ice_io_statistics_);
|
||||||
rtp_data_sender_->SetSendDataFunc(
|
rtp_data_sender_->SetSendDataFunc(
|
||||||
[this](const char *data, size_t size) -> int {
|
[this](const char *data, size_t size) -> int {
|
||||||
@@ -45,13 +44,10 @@ void DataChannelSend::Destroy() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int DataChannelSend::SendData(const char *data, size_t size) {
|
int DataChannelSend::SendData(const char *data, size_t size) {
|
||||||
std::vector<RtpPacket> packets;
|
if (rtp_data_sender_ && rtp_packetizer_) {
|
||||||
|
std::vector<RtpPacket> rtp_packets =
|
||||||
if (rtp_data_sender_) {
|
rtp_packetizer_->Build((uint8_t *)data, (uint32_t)size);
|
||||||
if (data_rtp_codec_) {
|
rtp_data_sender_->Enqueue(rtp_packets);
|
||||||
data_rtp_codec_->Encode((uint8_t *)data, (uint32_t)size, packets);
|
|
||||||
rtp_data_sender_->Enqueue(packets);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
#define _DATA_CHANNEL_SEND_H_
|
#define _DATA_CHANNEL_SEND_H_
|
||||||
|
|
||||||
#include "ice_agent.h"
|
#include "ice_agent.h"
|
||||||
#include "rtp_codec.h"
|
|
||||||
#include "rtp_data_sender.h"
|
#include "rtp_data_sender.h"
|
||||||
|
#include "rtp_packetizer.h"
|
||||||
|
|
||||||
class DataChannelSend {
|
class DataChannelSend {
|
||||||
public:
|
public:
|
||||||
@@ -19,14 +19,14 @@ class DataChannelSend {
|
|||||||
~DataChannelSend();
|
~DataChannelSend();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Initialize(RtpPacket::PAYLOAD_TYPE payload_type);
|
void Initialize(rtp::PAYLOAD_TYPE payload_type);
|
||||||
void Destroy();
|
void Destroy();
|
||||||
int SendData(const char *data, size_t size);
|
int SendData(const char *data, size_t size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<IceAgent> ice_agent_ = nullptr;
|
std::shared_ptr<IceAgent> ice_agent_ = nullptr;
|
||||||
std::shared_ptr<IOStatistics> ice_io_statistics_ = nullptr;
|
std::shared_ptr<IOStatistics> ice_io_statistics_ = nullptr;
|
||||||
std::unique_ptr<RtpCodec> data_rtp_codec_ = nullptr;
|
std::unique_ptr<RtpPacketizer> rtp_packetizer_ = nullptr;
|
||||||
std::unique_ptr<RtpDataSender> rtp_data_sender_ = nullptr;
|
std::unique_ptr<RtpDataSender> rtp_data_sender_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
#include "io_statistics.h"
|
#include "io_statistics.h"
|
||||||
#include "rtcp_receiver_report.h"
|
#include "rtcp_receiver_report.h"
|
||||||
#include "rtp_codec.h"
|
#include "rtp_packet.h"
|
||||||
#include "rtp_statistics.h"
|
#include "rtp_statistics.h"
|
||||||
|
|
||||||
class RtpAudioReceiver {
|
class RtpAudioReceiver {
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ int RtpAudioSender::SendRtpPacket(RtpPacket& rtp_packet) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 !=
|
if (0 != data_send_func_((const char*)rtp_packet.Buffer().data(),
|
||||||
data_send_func_((const char*)rtp_packet.Buffer(), rtp_packet.Size())) {
|
rtp_packet.Size())) {
|
||||||
LOG_ERROR("Send rtp packet failed");
|
LOG_ERROR("Send rtp packet failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#include "io_statistics.h"
|
#include "io_statistics.h"
|
||||||
#include "rtcp_receiver_report.h"
|
#include "rtcp_receiver_report.h"
|
||||||
#include "rtp_codec.h"
|
#include "rtp_packet.h"
|
||||||
#include "rtp_statistics.h"
|
#include "rtp_statistics.h"
|
||||||
|
|
||||||
class RtpDataReceiver {
|
class RtpDataReceiver {
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ int RtpDataSender::SendRtpPacket(RtpPacket& rtp_packet) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 !=
|
if (0 != data_send_func_((const char*)rtp_packet.Buffer().data(),
|
||||||
data_send_func_((const char*)rtp_packet.Buffer(), rtp_packet.Size())) {
|
rtp_packet.Size())) {
|
||||||
LOG_ERROR("Send rtp packet failed");
|
LOG_ERROR("Send rtp packet failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ void RtpVideoReceiver::InsertRtpPacket(RtpPacket& rtp_packet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
webrtc::RtpPacketReceived rtp_packet_received;
|
webrtc::RtpPacketReceived rtp_packet_received;
|
||||||
rtp_packet_received.Build(rtp_packet.Buffer(), rtp_packet.Size());
|
rtp_packet_received.Build(rtp_packet.Buffer().data(), rtp_packet.Size());
|
||||||
|
|
||||||
rtp_packet_received.set_arrival_time(clock_->CurrentTime());
|
rtp_packet_received.set_arrival_time(clock_->CurrentTime());
|
||||||
rtp_packet_received.set_ecn(EcnMarking::kEct0);
|
rtp_packet_received.set_ecn(EcnMarking::kEct0);
|
||||||
@@ -109,137 +109,152 @@ void RtpVideoReceiver::InsertRtpPacket(RtpPacket& rtp_packet) {
|
|||||||
|
|
||||||
// SendRtcpRR(rtcp_rr);
|
// SendRtcpRR(rtcp_rr);
|
||||||
}
|
}
|
||||||
if (rtp_packet.PayloadType() == RtpPacket::PAYLOAD_TYPE::AV1) {
|
if (rtp_packet.PayloadType() == rtp::PAYLOAD_TYPE::AV1) {
|
||||||
ProcessAv1RtpPacket(rtp_packet);
|
RtpPacketAv1 rtp_packet_av1;
|
||||||
|
rtp_packet_av1.Build(rtp_packet.Buffer().data(), rtp_packet.Size());
|
||||||
|
rtp_packet_av1.GetFrameHeaderInfo();
|
||||||
|
ProcessAv1RtpPacket(rtp_packet_av1);
|
||||||
} else {
|
} else {
|
||||||
ProcessH264RtpPacket(rtp_packet);
|
RtpPacketH264 rtp_packet_h264;
|
||||||
|
if (rtp_packet_h264.Build(rtp_packet.Buffer().data(), rtp_packet.Size())) {
|
||||||
|
rtp_packet_h264.GetFrameHeaderInfo();
|
||||||
|
ProcessH264RtpPacket(rtp_packet_h264);
|
||||||
|
} else {
|
||||||
|
LOG_ERROR("Invalid h264 rtp packet");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtpVideoReceiver::ProcessH264RtpPacket(RtpPacket& rtp_packet) {
|
void RtpVideoReceiver::ProcessH264RtpPacket(RtpPacketH264& rtp_packet_h264) {
|
||||||
if (!fec_enable_) {
|
if (!fec_enable_) {
|
||||||
if (RtpPacket::PAYLOAD_TYPE::H264 == rtp_packet.PayloadType()) {
|
if (rtp::PAYLOAD_TYPE::H264 == rtp_packet_h264.PayloadType()) {
|
||||||
if (RtpPacket::NAL_UNIT_TYPE::NALU == rtp_packet.NalUnitType()) {
|
rtp::NAL_UNIT_TYPE nalu_type = rtp_packet_h264.NalUnitType();
|
||||||
compelete_video_frame_queue_.push(
|
if (rtp::NAL_UNIT_TYPE::NALU == nalu_type) {
|
||||||
VideoFrame(rtp_packet.Payload(), rtp_packet.PayloadSize()));
|
compelete_video_frame_queue_.push(VideoFrame(
|
||||||
} else if (RtpPacket::NAL_UNIT_TYPE::FU_A == rtp_packet.NalUnitType()) {
|
rtp_packet_h264.Payload(), rtp_packet_h264.PayloadSize()));
|
||||||
incomplete_frame_list_[rtp_packet.SequenceNumber()] = rtp_packet;
|
} else if (rtp::NAL_UNIT_TYPE::FU_A == nalu_type) {
|
||||||
bool complete = CheckIsH264FrameCompleted(rtp_packet);
|
incomplete_h264_frame_list_[rtp_packet_h264.SequenceNumber()] =
|
||||||
|
rtp_packet_h264;
|
||||||
|
bool complete = CheckIsH264FrameCompleted(rtp_packet_h264);
|
||||||
if (!complete) {
|
if (!complete) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (RtpPacket::PAYLOAD_TYPE::H264 == rtp_packet.PayloadType()) {
|
|
||||||
if (RtpPacket::NAL_UNIT_TYPE::NALU == rtp_packet.NalUnitType()) {
|
|
||||||
compelete_video_frame_queue_.push(
|
|
||||||
VideoFrame(rtp_packet.Payload(), rtp_packet.PayloadSize()));
|
|
||||||
} else if (RtpPacket::NAL_UNIT_TYPE::FU_A == rtp_packet.NalUnitType()) {
|
|
||||||
incomplete_frame_list_[rtp_packet.SequenceNumber()] = rtp_packet;
|
|
||||||
bool complete = CheckIsH264FrameCompleted(rtp_packet);
|
|
||||||
if (!complete) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (RtpPacket::PAYLOAD_TYPE::H264_FEC_SOURCE ==
|
|
||||||
rtp_packet.PayloadType()) {
|
|
||||||
if (last_packet_ts_ != rtp_packet.Timestamp()) {
|
|
||||||
fec_decoder_.Init();
|
|
||||||
fec_decoder_.ResetParams(rtp_packet.FecSourceSymbolNum());
|
|
||||||
last_packet_ts_ = rtp_packet.Timestamp();
|
|
||||||
}
|
|
||||||
|
|
||||||
incomplete_fec_packet_list_[rtp_packet.Timestamp()]
|
|
||||||
[rtp_packet.SequenceNumber()] = rtp_packet;
|
|
||||||
|
|
||||||
uint8_t** complete_frame = fec_decoder_.DecodeWithNewSymbol(
|
|
||||||
(const char*)incomplete_fec_packet_list_[rtp_packet.Timestamp()]
|
|
||||||
[rtp_packet.SequenceNumber()]
|
|
||||||
.Payload(),
|
|
||||||
rtp_packet.FecSymbolId());
|
|
||||||
|
|
||||||
if (nullptr != complete_frame) {
|
|
||||||
if (!nv12_data_) {
|
|
||||||
nv12_data_ = new uint8_t[NV12_BUFFER_SIZE];
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t complete_frame_size = 0;
|
|
||||||
for (int index = 0; index < rtp_packet.FecSourceSymbolNum(); index++) {
|
|
||||||
if (nullptr == complete_frame[index]) {
|
|
||||||
LOG_ERROR("Invalid complete_frame[{}]", index);
|
|
||||||
}
|
|
||||||
memcpy(nv12_data_ + complete_frame_size, complete_frame[index], 1400);
|
|
||||||
complete_frame_size += 1400;
|
|
||||||
}
|
|
||||||
|
|
||||||
fec_decoder_.ReleaseSourcePackets(complete_frame);
|
|
||||||
fec_decoder_.Release();
|
|
||||||
LOG_ERROR("Release incomplete_fec_packet_list_");
|
|
||||||
incomplete_fec_packet_list_.erase(rtp_packet.Timestamp());
|
|
||||||
|
|
||||||
if (incomplete_fec_frame_list_.end() !=
|
|
||||||
incomplete_fec_frame_list_.find(rtp_packet.Timestamp())) {
|
|
||||||
incomplete_fec_frame_list_.erase(rtp_packet.Timestamp());
|
|
||||||
}
|
|
||||||
|
|
||||||
compelete_video_frame_queue_.push(
|
|
||||||
VideoFrame(nv12_data_, complete_frame_size));
|
|
||||||
} else {
|
|
||||||
incomplete_fec_frame_list_.insert(rtp_packet.Timestamp());
|
|
||||||
}
|
|
||||||
} else if (RtpPacket::PAYLOAD_TYPE::H264_FEC_REPAIR ==
|
|
||||||
rtp_packet.PayloadType()) {
|
|
||||||
if (incomplete_fec_frame_list_.end() ==
|
|
||||||
incomplete_fec_frame_list_.find(rtp_packet.Timestamp())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (last_packet_ts_ != rtp_packet.Timestamp()) {
|
|
||||||
fec_decoder_.Init();
|
|
||||||
fec_decoder_.ResetParams(rtp_packet.FecSourceSymbolNum());
|
|
||||||
last_packet_ts_ = rtp_packet.Timestamp();
|
|
||||||
}
|
|
||||||
|
|
||||||
incomplete_fec_packet_list_[rtp_packet.Timestamp()]
|
|
||||||
[rtp_packet.SequenceNumber()] = rtp_packet;
|
|
||||||
|
|
||||||
uint8_t** complete_frame = fec_decoder_.DecodeWithNewSymbol(
|
|
||||||
(const char*)incomplete_fec_packet_list_[rtp_packet.Timestamp()]
|
|
||||||
[rtp_packet.SequenceNumber()]
|
|
||||||
.Payload(),
|
|
||||||
rtp_packet.FecSymbolId());
|
|
||||||
|
|
||||||
if (nullptr != complete_frame) {
|
|
||||||
if (!nv12_data_) {
|
|
||||||
nv12_data_ = new uint8_t[NV12_BUFFER_SIZE];
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t complete_frame_size = 0;
|
|
||||||
for (int index = 0; index < rtp_packet.FecSourceSymbolNum(); index++) {
|
|
||||||
if (nullptr == complete_frame[index]) {
|
|
||||||
LOG_ERROR("Invalid complete_frame[{}]", index);
|
|
||||||
}
|
|
||||||
memcpy(nv12_data_ + complete_frame_size, complete_frame[index], 1400);
|
|
||||||
complete_frame_size += 1400;
|
|
||||||
}
|
|
||||||
|
|
||||||
fec_decoder_.ReleaseSourcePackets(complete_frame);
|
|
||||||
fec_decoder_.Release();
|
|
||||||
incomplete_fec_packet_list_.erase(rtp_packet.Timestamp());
|
|
||||||
|
|
||||||
compelete_video_frame_queue_.push(
|
|
||||||
VideoFrame(nv12_data_, complete_frame_size));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// else {
|
||||||
|
// if (rtp::PAYLOAD_TYPE::H264 == rtp_packet.PayloadType()) {
|
||||||
|
// if (rtp::NAL_UNIT_TYPE::NALU == rtp_packet.NalUnitType()) {
|
||||||
|
// compelete_video_frame_queue_.push(
|
||||||
|
// VideoFrame(rtp_packet.Payload(), rtp_packet.PayloadSize()));
|
||||||
|
// } else if (rtp::NAL_UNIT_TYPE::FU_A == rtp_packet.NalUnitType()) {
|
||||||
|
// incomplete_h264_frame_list_[rtp_packet.SequenceNumber()] =
|
||||||
|
// rtp_packet; bool complete = CheckIsH264FrameCompleted(rtp_packet); if
|
||||||
|
// (!complete) {
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } else if (rtp::PAYLOAD_TYPE::H264_FEC_SOURCE ==
|
||||||
|
// rtp_packet.PayloadType()) {
|
||||||
|
// if (last_packet_ts_ != rtp_packet.Timestamp()) {
|
||||||
|
// fec_decoder_.Init();
|
||||||
|
// fec_decoder_.ResetParams(rtp_packet.FecSourceSymbolNum());
|
||||||
|
// last_packet_ts_ = rtp_packet.Timestamp();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// incomplete_fec_packet_list_[rtp_packet.Timestamp()]
|
||||||
|
// [rtp_packet.SequenceNumber()] = rtp_packet;
|
||||||
|
|
||||||
|
// uint8_t** complete_frame = fec_decoder_.DecodeWithNewSymbol(
|
||||||
|
// (const char*)incomplete_fec_packet_list_[rtp_packet.Timestamp()]
|
||||||
|
// [rtp_packet.SequenceNumber()]
|
||||||
|
// .Payload(),
|
||||||
|
// rtp_packet.FecSymbolId());
|
||||||
|
|
||||||
|
// if (nullptr != complete_frame) {
|
||||||
|
// if (!nv12_data_) {
|
||||||
|
// nv12_data_ = new uint8_t[NV12_BUFFER_SIZE];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// size_t complete_frame_size = 0;
|
||||||
|
// for (int index = 0; index < rtp_packet.FecSourceSymbolNum(); index++)
|
||||||
|
// {
|
||||||
|
// if (nullptr == complete_frame[index]) {
|
||||||
|
// LOG_ERROR("Invalid complete_frame[{}]", index);
|
||||||
|
// }
|
||||||
|
// memcpy(nv12_data_ + complete_frame_size, complete_frame[index],
|
||||||
|
// 1400); complete_frame_size += 1400;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fec_decoder_.ReleaseSourcePackets(complete_frame);
|
||||||
|
// fec_decoder_.Release();
|
||||||
|
// LOG_ERROR("Release incomplete_fec_packet_list_");
|
||||||
|
// incomplete_fec_packet_list_.erase(rtp_packet.Timestamp());
|
||||||
|
|
||||||
|
// if (incomplete_fec_frame_list_.end() !=
|
||||||
|
// incomplete_fec_frame_list_.find(rtp_packet.Timestamp())) {
|
||||||
|
// incomplete_fec_frame_list_.erase(rtp_packet.Timestamp());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// compelete_video_frame_queue_.push(
|
||||||
|
// VideoFrame(nv12_data_, complete_frame_size));
|
||||||
|
// } else {
|
||||||
|
// incomplete_fec_frame_list_.insert(rtp_packet.Timestamp());
|
||||||
|
// }
|
||||||
|
// } else if (rtp::PAYLOAD_TYPE::H264_FEC_REPAIR ==
|
||||||
|
// rtp_packet.PayloadType()) {
|
||||||
|
// if (incomplete_fec_frame_list_.end() ==
|
||||||
|
// incomplete_fec_frame_list_.find(rtp_packet.Timestamp())) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (last_packet_ts_ != rtp_packet.Timestamp()) {
|
||||||
|
// fec_decoder_.Init();
|
||||||
|
// fec_decoder_.ResetParams(rtp_packet.FecSourceSymbolNum());
|
||||||
|
// last_packet_ts_ = rtp_packet.Timestamp();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// incomplete_fec_packet_list_[rtp_packet.Timestamp()]
|
||||||
|
// [rtp_packet.SequenceNumber()] = rtp_packet;
|
||||||
|
|
||||||
|
// uint8_t** complete_frame = fec_decoder_.DecodeWithNewSymbol(
|
||||||
|
// (const char*)incomplete_fec_packet_list_[rtp_packet.Timestamp()]
|
||||||
|
// [rtp_packet.SequenceNumber()]
|
||||||
|
// .Payload(),
|
||||||
|
// rtp_packet.FecSymbolId());
|
||||||
|
|
||||||
|
// if (nullptr != complete_frame) {
|
||||||
|
// if (!nv12_data_) {
|
||||||
|
// nv12_data_ = new uint8_t[NV12_BUFFER_SIZE];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// size_t complete_frame_size = 0;
|
||||||
|
// for (int index = 0; index < rtp_packet.FecSourceSymbolNum(); index++)
|
||||||
|
// {
|
||||||
|
// if (nullptr == complete_frame[index]) {
|
||||||
|
// LOG_ERROR("Invalid complete_frame[{}]", index);
|
||||||
|
// }
|
||||||
|
// memcpy(nv12_data_ + complete_frame_size, complete_frame[index],
|
||||||
|
// 1400); complete_frame_size += 1400;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fec_decoder_.ReleaseSourcePackets(complete_frame);
|
||||||
|
// fec_decoder_.Release();
|
||||||
|
// incomplete_fec_packet_list_.erase(rtp_packet.Timestamp());
|
||||||
|
|
||||||
|
// compelete_video_frame_queue_.push(
|
||||||
|
// VideoFrame(nv12_data_, complete_frame_size));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtpVideoReceiver::ProcessAv1RtpPacket(RtpPacket& rtp_packet) {
|
void RtpVideoReceiver::ProcessAv1RtpPacket(RtpPacketAv1& rtp_packet_av1) {
|
||||||
// LOG_ERROR("recv payload size = {}, sequence_number_ = {}",
|
// LOG_ERROR("recv payload size = {}, sequence_number_ = {}",
|
||||||
// rtp_packet.PayloadSize(), rtp_packet.SequenceNumber());
|
// rtp_packet.PayloadSize(), rtp_packet.SequenceNumber());
|
||||||
|
|
||||||
if (RtpPacket::PAYLOAD_TYPE::AV1 == rtp_packet.PayloadType()) {
|
if (rtp::PAYLOAD_TYPE::AV1 == rtp_packet_av1.PayloadType()) {
|
||||||
incomplete_frame_list_[rtp_packet.SequenceNumber()] = rtp_packet;
|
incomplete_av1_frame_list_[rtp_packet_av1.SequenceNumber()] =
|
||||||
bool complete = CheckIsAv1FrameCompleted(rtp_packet);
|
rtp_packet_av1;
|
||||||
|
bool complete = CheckIsAv1FrameCompleted(rtp_packet_av1);
|
||||||
if (!complete) {
|
if (!complete) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -253,13 +268,13 @@ void RtpVideoReceiver::ProcessAv1RtpPacket(RtpPacket& rtp_packet) {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RtpVideoReceiver::CheckIsH264FrameCompleted(RtpPacket& rtp_packet) {
|
bool RtpVideoReceiver::CheckIsH264FrameCompleted(
|
||||||
if (rtp_packet.FuAEnd()) {
|
RtpPacketH264& rtp_packet_h264) {
|
||||||
uint16_t end_seq = rtp_packet.SequenceNumber();
|
if (rtp_packet_h264.FuAEnd()) {
|
||||||
|
uint16_t end_seq = rtp_packet_h264.SequenceNumber();
|
||||||
while (end_seq--) {
|
while (end_seq--) {
|
||||||
auto it = incomplete_frame_list_.find(end_seq);
|
auto it = incomplete_h264_frame_list_.find(end_seq);
|
||||||
if (it == incomplete_frame_list_.end()) {
|
if (it == incomplete_h264_frame_list_.end()) {
|
||||||
// The last fragment has already received. If all fragments are in
|
// The last fragment has already received. If all fragments are in
|
||||||
// order, then some fragments lost in tranmission and need to be
|
// order, then some fragments lost in tranmission and need to be
|
||||||
// repaired using FEC
|
// repaired using FEC
|
||||||
@@ -272,16 +287,16 @@ bool RtpVideoReceiver::CheckIsH264FrameCompleted(RtpPacket& rtp_packet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t complete_frame_size = 0;
|
size_t complete_frame_size = 0;
|
||||||
for (uint16_t start = it->first; start <= rtp_packet.SequenceNumber();
|
for (uint16_t start = it->first;
|
||||||
start++) {
|
start <= rtp_packet_h264.SequenceNumber(); start++) {
|
||||||
memcpy(nv12_data_ + complete_frame_size,
|
memcpy(nv12_data_ + complete_frame_size,
|
||||||
incomplete_frame_list_[start].Payload(),
|
incomplete_h264_frame_list_[start].Payload(),
|
||||||
incomplete_frame_list_[start].PayloadSize());
|
incomplete_h264_frame_list_[start].PayloadSize());
|
||||||
|
|
||||||
complete_frame_size += incomplete_frame_list_[start].PayloadSize();
|
complete_frame_size +=
|
||||||
incomplete_frame_list_.erase(start);
|
incomplete_h264_frame_list_[start].PayloadSize();
|
||||||
|
incomplete_h264_frame_list_.erase(start);
|
||||||
}
|
}
|
||||||
|
|
||||||
compelete_video_frame_queue_.push(
|
compelete_video_frame_queue_.push(
|
||||||
VideoFrame(nv12_data_, complete_frame_size));
|
VideoFrame(nv12_data_, complete_frame_size));
|
||||||
|
|
||||||
@@ -297,13 +312,13 @@ bool RtpVideoReceiver::CheckIsH264FrameCompleted(RtpPacket& rtp_packet) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RtpVideoReceiver::CheckIsAv1FrameCompleted(RtpPacket& rtp_packet) {
|
bool RtpVideoReceiver::CheckIsAv1FrameCompleted(RtpPacketAv1& rtp_packet_av1) {
|
||||||
if (rtp_packet.Av1FrameEnd()) {
|
if (rtp_packet_av1.Av1FrameEnd()) {
|
||||||
uint16_t end_seq = rtp_packet.SequenceNumber();
|
uint16_t end_seq = rtp_packet_av1.SequenceNumber();
|
||||||
uint16_t start = end_seq;
|
uint16_t start = end_seq;
|
||||||
while (end_seq--) {
|
while (end_seq--) {
|
||||||
auto it = incomplete_frame_list_.find(end_seq);
|
auto it = incomplete_av1_frame_list_.find(end_seq);
|
||||||
if (it == incomplete_frame_list_.end()) {
|
if (it == incomplete_av1_frame_list_.end()) {
|
||||||
// The last fragment has already received. If all fragments are in
|
// The last fragment has already received. If all fragments are in
|
||||||
// order, then some fragments lost in tranmission and need to be
|
// order, then some fragments lost in tranmission and need to be
|
||||||
// repaired using FEC
|
// repaired using FEC
|
||||||
@@ -319,19 +334,19 @@ bool RtpVideoReceiver::CheckIsAv1FrameCompleted(RtpPacket& rtp_packet) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (start <= rtp_packet.SequenceNumber()) {
|
if (start <= rtp_packet_av1.SequenceNumber()) {
|
||||||
if (!nv12_data_) {
|
if (!nv12_data_) {
|
||||||
nv12_data_ = new uint8_t[NV12_BUFFER_SIZE];
|
nv12_data_ = new uint8_t[NV12_BUFFER_SIZE];
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t complete_frame_size = 0;
|
size_t complete_frame_size = 0;
|
||||||
for (; start <= rtp_packet.SequenceNumber(); start++) {
|
for (; start <= rtp_packet_av1.SequenceNumber(); start++) {
|
||||||
const uint8_t* obu_frame = incomplete_frame_list_[start].Payload();
|
const uint8_t* obu_frame = incomplete_av1_frame_list_[start].Payload();
|
||||||
size_t obu_frame_size = incomplete_frame_list_[start].PayloadSize();
|
size_t obu_frame_size = incomplete_av1_frame_list_[start].PayloadSize();
|
||||||
memcpy(nv12_data_ + complete_frame_size, obu_frame, obu_frame_size);
|
memcpy(nv12_data_ + complete_frame_size, obu_frame, obu_frame_size);
|
||||||
|
|
||||||
complete_frame_size += obu_frame_size;
|
complete_frame_size += obu_frame_size;
|
||||||
incomplete_frame_list_.erase(start);
|
incomplete_av1_frame_list_.erase(start);
|
||||||
}
|
}
|
||||||
|
|
||||||
compelete_video_frame_queue_.push(
|
compelete_video_frame_queue_.push(
|
||||||
|
|||||||
@@ -12,7 +12,8 @@
|
|||||||
#include "receive_side_congestion_controller.h"
|
#include "receive_side_congestion_controller.h"
|
||||||
#include "ringbuffer.h"
|
#include "ringbuffer.h"
|
||||||
#include "rtcp_receiver_report.h"
|
#include "rtcp_receiver_report.h"
|
||||||
#include "rtp_codec.h"
|
#include "rtp_packet_av1.h"
|
||||||
|
#include "rtp_packet_h264.h"
|
||||||
#include "rtp_rtcp_defines.h "
|
#include "rtp_rtcp_defines.h "
|
||||||
#include "rtp_statistics.h"
|
#include "rtp_statistics.h"
|
||||||
#include "thread_base.h"
|
#include "thread_base.h"
|
||||||
@@ -37,12 +38,12 @@ class RtpVideoReceiver : public ThreadBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ProcessAv1RtpPacket(RtpPacket& rtp_packet);
|
void ProcessAv1RtpPacket(RtpPacketAv1& rtp_packet_av1);
|
||||||
bool CheckIsAv1FrameCompleted(RtpPacket& rtp_packet);
|
bool CheckIsAv1FrameCompleted(RtpPacketAv1& rtp_packet_av1);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ProcessH264RtpPacket(RtpPacket& rtp_packet);
|
void ProcessH264RtpPacket(RtpPacketH264& rtp_packet_h264);
|
||||||
bool CheckIsH264FrameCompleted(RtpPacket& rtp_packet);
|
bool CheckIsH264FrameCompleted(RtpPacketH264& rtp_packet_h264);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool CheckIsTimeSendRR();
|
bool CheckIsTimeSendRR();
|
||||||
@@ -58,6 +59,8 @@ class RtpVideoReceiver : public ThreadBase {
|
|||||||
void RtcpThread();
|
void RtcpThread();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::map<uint16_t, RtpPacketH264> incomplete_h264_frame_list_;
|
||||||
|
std::map<uint16_t, RtpPacketAv1> incomplete_av1_frame_list_;
|
||||||
std::map<uint16_t, RtpPacket> incomplete_frame_list_;
|
std::map<uint16_t, RtpPacket> incomplete_frame_list_;
|
||||||
uint8_t* nv12_data_ = nullptr;
|
uint8_t* nv12_data_ = nullptr;
|
||||||
std::function<void(VideoFrame&)> on_receive_complete_frame_ = nullptr;
|
std::function<void(VideoFrame&)> on_receive_complete_frame_ = nullptr;
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ int RtpVideoSender::SendRtpPacket(RtpPacket& rtp_packet) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 !=
|
if (0 != data_send_func_((const char*)rtp_packet.Buffer().data(),
|
||||||
data_send_func_((const char*)rtp_packet.Buffer(), rtp_packet.Size())) {
|
rtp_packet.Size())) {
|
||||||
LOG_ERROR("Send rtp packet failed");
|
LOG_ERROR("Send rtp packet failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,10 +14,8 @@ VideoChannelReceive::VideoChannelReceive(
|
|||||||
|
|
||||||
VideoChannelReceive::~VideoChannelReceive() {}
|
VideoChannelReceive::~VideoChannelReceive() {}
|
||||||
|
|
||||||
void VideoChannelReceive::Initialize(RtpPacket::PAYLOAD_TYPE payload_type) {
|
void VideoChannelReceive::Initialize(rtp::PAYLOAD_TYPE payload_type) {
|
||||||
video_rtp_codec_ = std::make_unique<RtpCodec>(payload_type);
|
|
||||||
rtp_video_receiver_ = std::make_unique<RtpVideoReceiver>(ice_io_statistics_);
|
rtp_video_receiver_ = std::make_unique<RtpVideoReceiver>(ice_io_statistics_);
|
||||||
|
|
||||||
rtp_video_receiver_->SetOnReceiveCompleteFrame(
|
rtp_video_receiver_->SetOnReceiveCompleteFrame(
|
||||||
[this](VideoFrame &video_frame) -> void {
|
[this](VideoFrame &video_frame) -> void {
|
||||||
on_receive_complete_frame_(video_frame);
|
on_receive_complete_frame_(video_frame);
|
||||||
@@ -54,7 +52,9 @@ int VideoChannelReceive::OnReceiveRtpPacket(const char *data, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rtp_video_receiver_) {
|
if (rtp_video_receiver_) {
|
||||||
rtp_video_receiver_->InsertRtpPacket(RtpPacket((uint8_t *)data, size));
|
RtpPacket rtp_packet;
|
||||||
|
rtp_packet.Build((uint8_t *)data, (uint32_t)size);
|
||||||
|
rtp_video_receiver_->InsertRtpPacket(rtp_packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
#define _VIDEO_CHANNEL_RECEIVE_H_
|
#define _VIDEO_CHANNEL_RECEIVE_H_
|
||||||
|
|
||||||
#include "ice_agent.h"
|
#include "ice_agent.h"
|
||||||
#include "rtp_codec.h"
|
|
||||||
#include "rtp_video_receiver.h"
|
#include "rtp_video_receiver.h"
|
||||||
|
|
||||||
class VideoChannelReceive {
|
class VideoChannelReceive {
|
||||||
@@ -22,7 +21,7 @@ class VideoChannelReceive {
|
|||||||
~VideoChannelReceive();
|
~VideoChannelReceive();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Initialize(RtpPacket::PAYLOAD_TYPE payload_type);
|
void Initialize(rtp::PAYLOAD_TYPE payload_type);
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
||||||
int OnReceiveRtpPacket(const char *data, size_t size);
|
int OnReceiveRtpPacket(const char *data, size_t size);
|
||||||
@@ -30,7 +29,6 @@ class VideoChannelReceive {
|
|||||||
private:
|
private:
|
||||||
std::shared_ptr<IceAgent> ice_agent_ = nullptr;
|
std::shared_ptr<IceAgent> ice_agent_ = nullptr;
|
||||||
std::shared_ptr<IOStatistics> ice_io_statistics_ = nullptr;
|
std::shared_ptr<IOStatistics> ice_io_statistics_ = nullptr;
|
||||||
std::unique_ptr<RtpCodec> video_rtp_codec_ = nullptr;
|
|
||||||
std::unique_ptr<RtpVideoReceiver> rtp_video_receiver_ = nullptr;
|
std::unique_ptr<RtpVideoReceiver> rtp_video_receiver_ = nullptr;
|
||||||
std::function<void(VideoFrame &)> on_receive_complete_frame_ = nullptr;
|
std::function<void(VideoFrame &)> on_receive_complete_frame_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,9 +11,8 @@ VideoChannelSend::VideoChannelSend(
|
|||||||
std::shared_ptr<IOStatistics> ice_io_statistics)
|
std::shared_ptr<IOStatistics> ice_io_statistics)
|
||||||
: ice_agent_(ice_agent), ice_io_statistics_(ice_io_statistics){};
|
: ice_agent_(ice_agent), ice_io_statistics_(ice_io_statistics){};
|
||||||
|
|
||||||
void VideoChannelSend::Initialize(RtpPacket::PAYLOAD_TYPE payload_type) {
|
void VideoChannelSend::Initialize(rtp::PAYLOAD_TYPE payload_type) {
|
||||||
video_rtp_codec_ = std::make_unique<RtpCodec>(payload_type);
|
rtp_packetizer_ = RtpPacketizer::Create(payload_type);
|
||||||
|
|
||||||
rtp_video_sender_ = std::make_unique<RtpVideoSender>(ice_io_statistics_);
|
rtp_video_sender_ = std::make_unique<RtpVideoSender>(ice_io_statistics_);
|
||||||
rtp_video_sender_->SetSendDataFunc(
|
rtp_video_sender_->SetSendDataFunc(
|
||||||
[this](const char* data, size_t size) -> int {
|
[this](const char* data, size_t size) -> int {
|
||||||
@@ -45,12 +44,10 @@ void VideoChannelSend::Destroy() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int VideoChannelSend::SendVideo(char* data, size_t size) {
|
int VideoChannelSend::SendVideo(char* data, size_t size) {
|
||||||
std::vector<RtpPacket> packets;
|
if (rtp_video_sender_ && rtp_packetizer_) {
|
||||||
if (rtp_video_sender_) {
|
std::vector<RtpPacket> rtp_packets =
|
||||||
if (video_rtp_codec_) {
|
rtp_packetizer_->Build((uint8_t*)data, (uint32_t)size);
|
||||||
video_rtp_codec_->Encode((uint8_t*)data, (uint32_t)size, packets);
|
rtp_video_sender_->Enqueue(rtp_packets);
|
||||||
}
|
|
||||||
rtp_video_sender_->Enqueue(packets);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
#include "congestion_control_feedback.h"
|
#include "congestion_control_feedback.h"
|
||||||
#include "ice_agent.h"
|
#include "ice_agent.h"
|
||||||
#include "rtp_codec.h"
|
#include "rtp_packetizer.h"
|
||||||
#include "rtp_video_sender.h"
|
#include "rtp_video_sender.h"
|
||||||
#include "transport_feedback.h"
|
#include "transport_feedback.h"
|
||||||
#include "transport_feedback_adapter.h"
|
#include "transport_feedback_adapter.h"
|
||||||
@@ -22,7 +22,7 @@ class VideoChannelSend {
|
|||||||
~VideoChannelSend();
|
~VideoChannelSend();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Initialize(RtpPacket::PAYLOAD_TYPE payload_type);
|
void Initialize(rtp::PAYLOAD_TYPE payload_type);
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
||||||
int SendVideo(char* data, size_t size);
|
int SendVideo(char* data, size_t size);
|
||||||
@@ -36,7 +36,7 @@ class VideoChannelSend {
|
|||||||
private:
|
private:
|
||||||
std::shared_ptr<IceAgent> ice_agent_ = nullptr;
|
std::shared_ptr<IceAgent> ice_agent_ = nullptr;
|
||||||
std::shared_ptr<IOStatistics> ice_io_statistics_ = nullptr;
|
std::shared_ptr<IOStatistics> ice_io_statistics_ = nullptr;
|
||||||
std::unique_ptr<RtpCodec> video_rtp_codec_ = nullptr;
|
std::unique_ptr<RtpPacketizer> rtp_packetizer_ = nullptr;
|
||||||
std::unique_ptr<RtpVideoSender> rtp_video_sender_ = nullptr;
|
std::unique_ptr<RtpVideoSender> rtp_video_sender_ = nullptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -13,6 +13,9 @@
|
|||||||
class CopyOnWriteBuffer {
|
class CopyOnWriteBuffer {
|
||||||
public:
|
public:
|
||||||
CopyOnWriteBuffer() = default;
|
CopyOnWriteBuffer() = default;
|
||||||
|
CopyOnWriteBuffer(size_t size) {
|
||||||
|
buffer_ = std::make_shared<std::vector<uint8_t>>(size);
|
||||||
|
}
|
||||||
CopyOnWriteBuffer(const CopyOnWriteBuffer& other) = default;
|
CopyOnWriteBuffer(const CopyOnWriteBuffer& other) = default;
|
||||||
CopyOnWriteBuffer(CopyOnWriteBuffer&& other) noexcept = default;
|
CopyOnWriteBuffer(CopyOnWriteBuffer&& other) noexcept = default;
|
||||||
CopyOnWriteBuffer& operator=(const CopyOnWriteBuffer& other) = default;
|
CopyOnWriteBuffer& operator=(const CopyOnWriteBuffer& other) = default;
|
||||||
|
|||||||
@@ -66,11 +66,9 @@ int NvidiaVideoDecoder::Init() {
|
|||||||
int NvidiaVideoDecoder::Decode(
|
int NvidiaVideoDecoder::Decode(
|
||||||
const uint8_t *data, size_t size,
|
const uint8_t *data, size_t size,
|
||||||
std::function<void(VideoFrame)> on_receive_decoded_frame) {
|
std::function<void(VideoFrame)> on_receive_decoded_frame) {
|
||||||
LOG_ERROR("1");
|
|
||||||
if (!decoder) {
|
if (!decoder) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
LOG_ERROR("2");
|
|
||||||
#ifdef SAVE_RECEIVED_H264_STREAM
|
#ifdef SAVE_RECEIVED_H264_STREAM
|
||||||
fwrite((unsigned char *)data, 1, size, file_h264_);
|
fwrite((unsigned char *)data, 1, size, file_h264_);
|
||||||
#endif
|
#endif
|
||||||
@@ -80,14 +78,11 @@ int NvidiaVideoDecoder::Decode(
|
|||||||
}
|
}
|
||||||
|
|
||||||
int num_frame_returned = decoder->Decode(data, (int)size);
|
int num_frame_returned = decoder->Decode(data, (int)size);
|
||||||
LOG_ERROR("???? {}", num_frame_returned);
|
|
||||||
for (size_t i = 0; i < num_frame_returned; ++i) {
|
for (size_t i = 0; i < num_frame_returned; ++i) {
|
||||||
cudaVideoSurfaceFormat format = decoder->GetOutputFormat();
|
cudaVideoSurfaceFormat format = decoder->GetOutputFormat();
|
||||||
LOG_ERROR("3");
|
|
||||||
if (format == cudaVideoSurfaceFormat_NV12) {
|
if (format == cudaVideoSurfaceFormat_NV12) {
|
||||||
uint8_t *decoded_frame_buffer = nullptr;
|
uint8_t *decoded_frame_buffer = nullptr;
|
||||||
decoded_frame_buffer = decoder->GetFrame();
|
decoded_frame_buffer = decoder->GetFrame();
|
||||||
LOG_ERROR("4");
|
|
||||||
if (decoded_frame_buffer) {
|
if (decoded_frame_buffer) {
|
||||||
if (on_receive_decoded_frame) {
|
if (on_receive_decoded_frame) {
|
||||||
VideoFrame decoded_frame(
|
VideoFrame decoded_frame(
|
||||||
|
|||||||
@@ -616,7 +616,7 @@ void PeerConnection::ProcessIceWorkMsg(const IceWorkMsg &msg) {
|
|||||||
cfg_stun_server_ip_, stun_server_port_, cfg_turn_server_ip_,
|
cfg_stun_server_ip_, stun_server_port_, cfg_turn_server_ip_,
|
||||||
turn_server_port_, cfg_turn_server_username_,
|
turn_server_port_, cfg_turn_server_username_,
|
||||||
cfg_turn_server_password_,
|
cfg_turn_server_password_,
|
||||||
av1_encoding_ ? RtpPacket::AV1 : RtpPacket::H264);
|
av1_encoding_ ? rtp::PAYLOAD_TYPE::AV1 : rtp::PAYLOAD_TYPE::H264);
|
||||||
ice_transport_list_[remote_user_id]->JoinTransmission();
|
ice_transport_list_[remote_user_id]->JoinTransmission();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -663,7 +663,7 @@ void PeerConnection::ProcessIceWorkMsg(const IceWorkMsg &msg) {
|
|||||||
cfg_stun_server_ip_, stun_server_port_, cfg_turn_server_ip_,
|
cfg_stun_server_ip_, stun_server_port_, cfg_turn_server_ip_,
|
||||||
turn_server_port_, cfg_turn_server_username_,
|
turn_server_port_, cfg_turn_server_username_,
|
||||||
cfg_turn_server_password_,
|
cfg_turn_server_password_,
|
||||||
av1_encoding_ ? RtpPacket::AV1 : RtpPacket::H264);
|
av1_encoding_ ? rtp::PAYLOAD_TYPE::AV1 : rtp::PAYLOAD_TYPE::H264);
|
||||||
ice_transport_list_[remote_user_id]->SetTransmissionId(transmission_id);
|
ice_transport_list_[remote_user_id]->SetTransmissionId(transmission_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -147,9 +147,9 @@ class PeerConnection {
|
|||||||
bool try_rejoin_with_turn_ = false;
|
bool try_rejoin_with_turn_ = false;
|
||||||
TraversalMode mode_ = TraversalMode::P2P;
|
TraversalMode mode_ = TraversalMode::P2P;
|
||||||
|
|
||||||
std::vector<int> video_payload_types_ = {RtpPacket::PAYLOAD_TYPE::H264,
|
std::vector<int> video_payload_types_ = {rtp::PAYLOAD_TYPE::H264,
|
||||||
RtpPacket::PAYLOAD_TYPE::AV1};
|
rtp::PAYLOAD_TYPE::AV1};
|
||||||
std::vector<int> audio_payload_types_ = {RtpPacket::PAYLOAD_TYPE::OPUS};
|
std::vector<int> audio_payload_types_ = {rtp::PAYLOAD_TYPE::OPUS};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<WsClient> ws_transport_ = nullptr;
|
std::shared_ptr<WsClient> ws_transport_ = nullptr;
|
||||||
|
|||||||
11
src/rtp/rtp_depacketizer/rtp_depacketizer.cpp
Normal file
11
src/rtp/rtp_depacketizer/rtp_depacketizer.cpp
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#include "rtp_depacketizer.h"
|
||||||
|
|
||||||
|
std::shared_ptr<RtpDepacketizer> Create(uint32_t payload_type, uint8_t* payload,
|
||||||
|
size_t payload_size) {
|
||||||
|
switch (payload_type) {
|
||||||
|
case rtp::PAYLOAD_TYPE::H264:
|
||||||
|
return std::make_shared<RtpDepacketizerH264>(payload, payload_size);
|
||||||
|
case rtp::PAYLOAD_TYPE::AV1:
|
||||||
|
return std::make_shared<RtpDepacketizerAv1>(payload, payload_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
25
src/rtp/rtp_depacketizer/rtp_depacketizer.h
Normal file
25
src/rtp/rtp_depacketizer/rtp_depacketizer.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* @Author: DI JUNKUN
|
||||||
|
* @Date: 2025-01-23
|
||||||
|
* Copyright (c) 2025 by DI JUNKUN, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RTP_DEPACKETIZER_H_
|
||||||
|
#define _RTP_DEPACKETIZER_H_
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "rtp_packet.h"
|
||||||
|
|
||||||
|
class RtpDepacketizer {
|
||||||
|
public:
|
||||||
|
static std::shared_ptr<RtpDepacketizer> Create(uint32_t payload_type);
|
||||||
|
|
||||||
|
virtual ~RtpDepacketizer() = default;
|
||||||
|
|
||||||
|
bool Build(uint8_t* payload, uint32_t payload_size) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
9
src/rtp/rtp_depacketizer/rtp_depacketizer_h264.cpp
Normal file
9
src/rtp/rtp_depacketizer/rtp_depacketizer_h264.cpp
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#include "rtp_depacketizer_h264.h"
|
||||||
|
|
||||||
|
RtpDepacketizerH264::RtpDepacketizerH264() {}
|
||||||
|
|
||||||
|
RtpDepacketizerH264::~RtpDepacketizerH264() {}
|
||||||
|
|
||||||
|
bool RtpDepacketizerH264::Parse(uint8_t* payload, uint32_t payload_size) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
25
src/rtp/rtp_depacketizer/rtp_depacketizer_h264.h
Normal file
25
src/rtp/rtp_depacketizer/rtp_depacketizer_h264.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* @Author: DI JUNKUN
|
||||||
|
* @Date: 2025-01-23
|
||||||
|
* Copyright (c) 2025 by DI JUNKUN, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RTP_DEPACKETIZER_H_
|
||||||
|
#define _RTP_DEPACKETIZER_H_
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "rtp_packet.h"
|
||||||
|
|
||||||
|
class RtpDepacketizerH264 {
|
||||||
|
public:
|
||||||
|
RtpDepacketizerH264();
|
||||||
|
|
||||||
|
virtual ~RtpDepacketizerH264() = default;
|
||||||
|
|
||||||
|
bool Parse(uint8_t* payload, uint32_t payload_size);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -15,7 +15,7 @@ constexpr int kObuTypeSequenceHeader = 1;
|
|||||||
|
|
||||||
using namespace obu;
|
using namespace obu;
|
||||||
|
|
||||||
RtpCodec::RtpCodec(RtpPacket::PAYLOAD_TYPE payload_type)
|
RtpCodec::RtpCodec(rtp::PAYLOAD_TYPE payload_type)
|
||||||
: version_(RTP_VERSION),
|
: version_(RTP_VERSION),
|
||||||
has_padding_(false),
|
has_padding_(false),
|
||||||
has_extension_(false),
|
has_extension_(false),
|
||||||
@@ -41,7 +41,7 @@ RtpCodec::~RtpCodec() {
|
|||||||
|
|
||||||
// void RtpCodec::Encode(uint8_t* buffer, uint32_t size,
|
// void RtpCodec::Encode(uint8_t* buffer, uint32_t size,
|
||||||
// std::vector<RtpPacket>& packets) {
|
// std::vector<RtpPacket>& packets) {
|
||||||
// if (RtpPacket::PAYLOAD_TYPE::H264 == payload_type_) {
|
// if (rtp::PAYLOAD_TYPE::H264 == payload_type_) {
|
||||||
// if (fec_enable_ && IsKeyFrame((const uint8_t*)buffer, size)) {
|
// if (fec_enable_ && IsKeyFrame((const uint8_t*)buffer, size)) {
|
||||||
// uint8_t** fec_packets = fec_encoder_.Encode((const char*)buffer, size);
|
// uint8_t** fec_packets = fec_encoder_.Encode((const char*)buffer, size);
|
||||||
// if (nullptr == fec_packets) {
|
// if (nullptr == fec_packets) {
|
||||||
@@ -67,7 +67,7 @@ RtpCodec::~RtpCodec() {
|
|||||||
// rtp_packet.SetHasExtension(has_extension_);
|
// rtp_packet.SetHasExtension(has_extension_);
|
||||||
// rtp_packet.SetMarker((index == (num_of_source_packets - 1)) ? 1 :
|
// rtp_packet.SetMarker((index == (num_of_source_packets - 1)) ? 1 :
|
||||||
// 0);
|
// 0);
|
||||||
// rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE::H264_FEC_SOURCE);
|
// rtp_packet.SetPayloadType(rtp::PAYLOAD_TYPE::H264_FEC_SOURCE);
|
||||||
// rtp_packet.SetSequenceNumber(sequence_number_++);
|
// rtp_packet.SetSequenceNumber(sequence_number_++);
|
||||||
// rtp_packet.SetTimestamp(timestamp_);
|
// rtp_packet.SetTimestamp(timestamp_);
|
||||||
// rtp_packet.SetSsrc(ssrc_);
|
// rtp_packet.SetSsrc(ssrc_);
|
||||||
@@ -116,7 +116,7 @@ RtpCodec::~RtpCodec() {
|
|||||||
// rtp_packet.SetHasPadding(has_padding_);
|
// rtp_packet.SetHasPadding(has_padding_);
|
||||||
// rtp_packet.SetHasExtension(has_extension_);
|
// rtp_packet.SetHasExtension(has_extension_);
|
||||||
// rtp_packet.SetMarker(index == num_of_total_packets - 1 ? 1 : 0);
|
// rtp_packet.SetMarker(index == num_of_total_packets - 1 ? 1 : 0);
|
||||||
// rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE::H264_FEC_REPAIR);
|
// rtp_packet.SetPayloadType(rtp::PAYLOAD_TYPE::H264_FEC_REPAIR);
|
||||||
// rtp_packet.SetSequenceNumber(sequence_number_++);
|
// rtp_packet.SetSequenceNumber(sequence_number_++);
|
||||||
// rtp_packet.SetTimestamp(timestamp_);
|
// rtp_packet.SetTimestamp(timestamp_);
|
||||||
// rtp_packet.SetSsrc(ssrc_);
|
// rtp_packet.SetSsrc(ssrc_);
|
||||||
@@ -149,7 +149,7 @@ RtpCodec::~RtpCodec() {
|
|||||||
// rtp_packet.SetHasPadding(has_padding_);
|
// rtp_packet.SetHasPadding(has_padding_);
|
||||||
// rtp_packet.SetHasExtension(has_extension_);
|
// rtp_packet.SetHasExtension(has_extension_);
|
||||||
// rtp_packet.SetMarker(1);
|
// rtp_packet.SetMarker(1);
|
||||||
// rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_));
|
// rtp_packet.SetPayloadType(rtp::PAYLOAD_TYPE(payload_type_));
|
||||||
// rtp_packet.SetSequenceNumber(sequence_number_++);
|
// rtp_packet.SetSequenceNumber(sequence_number_++);
|
||||||
|
|
||||||
// timestamp_ = std::chrono::duration_cast<std::chrono::microseconds>(
|
// timestamp_ = std::chrono::duration_cast<std::chrono::microseconds>(
|
||||||
@@ -189,7 +189,7 @@ RtpCodec::~RtpCodec() {
|
|||||||
// rtp_packet.SetHasPadding(has_padding_);
|
// rtp_packet.SetHasPadding(has_padding_);
|
||||||
// rtp_packet.SetHasExtension(has_extension_);
|
// rtp_packet.SetHasExtension(has_extension_);
|
||||||
// rtp_packet.SetMarker(index == packet_num - 1 ? 1 : 0);
|
// rtp_packet.SetMarker(index == packet_num - 1 ? 1 : 0);
|
||||||
// rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_));
|
// rtp_packet.SetPayloadType(rtp::PAYLOAD_TYPE(payload_type_));
|
||||||
// rtp_packet.SetSequenceNumber(sequence_number_++);
|
// rtp_packet.SetSequenceNumber(sequence_number_++);
|
||||||
// rtp_packet.SetTimestamp(timestamp_);
|
// rtp_packet.SetTimestamp(timestamp_);
|
||||||
// rtp_packet.SetSsrc(ssrc_);
|
// rtp_packet.SetSsrc(ssrc_);
|
||||||
@@ -227,7 +227,7 @@ RtpCodec::~RtpCodec() {
|
|||||||
// packets.emplace_back(rtp_packet);
|
// packets.emplace_back(rtp_packet);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// } else if (RtpPacket::PAYLOAD_TYPE::AV1 == payload_type_) {
|
// } else if (rtp::PAYLOAD_TYPE::AV1 == payload_type_) {
|
||||||
// std::vector<Obu> obus = ParseObus(buffer, size);
|
// std::vector<Obu> obus = ParseObus(buffer, size);
|
||||||
// LOG_ERROR("Total size = [{}]", size);
|
// LOG_ERROR("Total size = [{}]", size);
|
||||||
// for (int i = 0; i < obus.size(); i++) {
|
// for (int i = 0; i < obus.size(); i++) {
|
||||||
@@ -239,7 +239,7 @@ RtpCodec::~RtpCodec() {
|
|||||||
// rtp_packet.SetHasPadding(has_padding_);
|
// rtp_packet.SetHasPadding(has_padding_);
|
||||||
// rtp_packet.SetHasExtension(has_extension_);
|
// rtp_packet.SetHasExtension(has_extension_);
|
||||||
// rtp_packet.SetMarker(1);
|
// rtp_packet.SetMarker(1);
|
||||||
// rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_));
|
// rtp_packet.SetPayloadType(rtp::PAYLOAD_TYPE(payload_type_));
|
||||||
// rtp_packet.SetSequenceNumber(sequence_number_++);
|
// rtp_packet.SetSequenceNumber(sequence_number_++);
|
||||||
|
|
||||||
// timestamp_ = std::chrono::duration_cast<std::chrono::microseconds>(
|
// timestamp_ = std::chrono::duration_cast<std::chrono::microseconds>(
|
||||||
@@ -275,7 +275,7 @@ RtpCodec::~RtpCodec() {
|
|||||||
// rtp_packet.SetHasPadding(has_padding_);
|
// rtp_packet.SetHasPadding(has_padding_);
|
||||||
// rtp_packet.SetHasExtension(has_extension_);
|
// rtp_packet.SetHasExtension(has_extension_);
|
||||||
// rtp_packet.SetMarker(index == packet_num - 1 ? 1 : 0);
|
// rtp_packet.SetMarker(index == packet_num - 1 ? 1 : 0);
|
||||||
// rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_));
|
// rtp_packet.SetPayloadType(rtp::PAYLOAD_TYPE(payload_type_));
|
||||||
// rtp_packet.SetSequenceNumber(sequence_number_++);
|
// rtp_packet.SetSequenceNumber(sequence_number_++);
|
||||||
// rtp_packet.SetTimestamp(timestamp_);
|
// rtp_packet.SetTimestamp(timestamp_);
|
||||||
// rtp_packet.SetSsrc(ssrc_);
|
// rtp_packet.SetSsrc(ssrc_);
|
||||||
@@ -306,13 +306,13 @@ RtpCodec::~RtpCodec() {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// } else if (RtpPacket::PAYLOAD_TYPE::OPUS == payload_type_) {
|
// } else if (rtp::PAYLOAD_TYPE::OPUS == payload_type_) {
|
||||||
// RtpPacket rtp_packet;
|
// RtpPacket rtp_packet;
|
||||||
// rtp_packet.SetVerion(version_);
|
// rtp_packet.SetVerion(version_);
|
||||||
// rtp_packet.SetHasPadding(has_padding_);
|
// rtp_packet.SetHasPadding(has_padding_);
|
||||||
// rtp_packet.SetHasExtension(has_extension_);
|
// rtp_packet.SetHasExtension(has_extension_);
|
||||||
// rtp_packet.SetMarker(1);
|
// rtp_packet.SetMarker(1);
|
||||||
// rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_));
|
// rtp_packet.SetPayloadType(rtp::PAYLOAD_TYPE(payload_type_));
|
||||||
// rtp_packet.SetSequenceNumber(sequence_number_++);
|
// rtp_packet.SetSequenceNumber(sequence_number_++);
|
||||||
|
|
||||||
// timestamp_ = std::chrono::duration_cast<std::chrono::microseconds>(
|
// timestamp_ = std::chrono::duration_cast<std::chrono::microseconds>(
|
||||||
@@ -323,13 +323,13 @@ RtpCodec::~RtpCodec() {
|
|||||||
|
|
||||||
// rtp_packet.Encode(buffer, size);
|
// rtp_packet.Encode(buffer, size);
|
||||||
// packets.emplace_back(rtp_packet);
|
// packets.emplace_back(rtp_packet);
|
||||||
// } else if (RtpPacket::PAYLOAD_TYPE::DATA == payload_type_) {
|
// } else if (rtp::PAYLOAD_TYPE::DATA == payload_type_) {
|
||||||
// RtpPacket rtp_packet;
|
// RtpPacket rtp_packet;
|
||||||
// rtp_packet.SetVerion(version_);
|
// rtp_packet.SetVerion(version_);
|
||||||
// rtp_packet.SetHasPadding(has_padding_);
|
// rtp_packet.SetHasPadding(has_padding_);
|
||||||
// rtp_packet.SetHasExtension(has_extension_);
|
// rtp_packet.SetHasExtension(has_extension_);
|
||||||
// rtp_packet.SetMarker(1);
|
// rtp_packet.SetMarker(1);
|
||||||
// rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_));
|
// rtp_packet.SetPayloadType(rtp::PAYLOAD_TYPE(payload_type_));
|
||||||
// rtp_packet.SetSequenceNumber(sequence_number_++);
|
// rtp_packet.SetSequenceNumber(sequence_number_++);
|
||||||
|
|
||||||
// timestamp_ = std::chrono::duration_cast<std::chrono::microseconds>(
|
// timestamp_ = std::chrono::duration_cast<std::chrono::microseconds>(
|
||||||
@@ -345,7 +345,7 @@ RtpCodec::~RtpCodec() {
|
|||||||
|
|
||||||
void RtpCodec::Encode(uint8_t* buffer, uint32_t size,
|
void RtpCodec::Encode(uint8_t* buffer, uint32_t size,
|
||||||
std::vector<RtpPacket>& packets) {
|
std::vector<RtpPacket>& packets) {
|
||||||
if (RtpPacket::PAYLOAD_TYPE::H264 == payload_type_) {
|
if (rtp::PAYLOAD_TYPE::H264 == payload_type_) {
|
||||||
if (fec_enable_ && IsKeyFrame((const uint8_t*)buffer, size)) {
|
if (fec_enable_ && IsKeyFrame((const uint8_t*)buffer, size)) {
|
||||||
uint8_t** fec_packets = fec_encoder_.Encode((const char*)buffer, size);
|
uint8_t** fec_packets = fec_encoder_.Encode((const char*)buffer, size);
|
||||||
if (nullptr == fec_packets) {
|
if (nullptr == fec_packets) {
|
||||||
@@ -369,7 +369,7 @@ void RtpCodec::Encode(uint8_t* buffer, uint32_t size,
|
|||||||
rtp_packet.SetHasPadding(has_padding_);
|
rtp_packet.SetHasPadding(has_padding_);
|
||||||
rtp_packet.SetHasExtension(has_extension_);
|
rtp_packet.SetHasExtension(has_extension_);
|
||||||
rtp_packet.SetMarker(index == num_of_source_packets - 1 ? 1 : 0);
|
rtp_packet.SetMarker(index == num_of_source_packets - 1 ? 1 : 0);
|
||||||
rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE::H264_FEC_SOURCE);
|
rtp_packet.SetPayloadType(rtp::PAYLOAD_TYPE::H264_FEC_SOURCE);
|
||||||
rtp_packet.SetSequenceNumber(sequence_number_++);
|
rtp_packet.SetSequenceNumber(sequence_number_++);
|
||||||
rtp_packet.SetTimestamp(timestamp_);
|
rtp_packet.SetTimestamp(timestamp_);
|
||||||
rtp_packet.SetSsrc(ssrc_);
|
rtp_packet.SetSsrc(ssrc_);
|
||||||
@@ -383,12 +383,12 @@ void RtpCodec::Encode(uint8_t* buffer, uint32_t size,
|
|||||||
rtp_packet.SetExtensionData(extension_data_, extension_len_);
|
rtp_packet.SetExtensionData(extension_data_, extension_len_);
|
||||||
}
|
}
|
||||||
|
|
||||||
RtpPacket::FU_INDICATOR fu_indicator;
|
rtp::FU_INDICATOR fu_indicator;
|
||||||
fu_indicator.forbidden_bit = 0;
|
fu_indicator.forbidden_bit = 0;
|
||||||
fu_indicator.nal_reference_idc = 0;
|
fu_indicator.nal_reference_idc = 0;
|
||||||
fu_indicator.nal_unit_type = FU_A;
|
fu_indicator.nal_unit_type = FU_A;
|
||||||
|
|
||||||
RtpPacket::FU_HEADER fu_header;
|
rtp::FU_HEADER fu_header;
|
||||||
fu_header.start = index == 0 ? 1 : 0;
|
fu_header.start = index == 0 ? 1 : 0;
|
||||||
fu_header.end = index == num_of_source_packets - 1 ? 1 : 0;
|
fu_header.end = index == num_of_source_packets - 1 ? 1 : 0;
|
||||||
fu_header.remain_bit = 0;
|
fu_header.remain_bit = 0;
|
||||||
@@ -417,7 +417,7 @@ void RtpCodec::Encode(uint8_t* buffer, uint32_t size,
|
|||||||
rtp_packet.SetHasPadding(has_padding_);
|
rtp_packet.SetHasPadding(has_padding_);
|
||||||
rtp_packet.SetHasExtension(has_extension_);
|
rtp_packet.SetHasExtension(has_extension_);
|
||||||
rtp_packet.SetMarker(index == num_of_total_packets - 1 ? 1 : 0);
|
rtp_packet.SetMarker(index == num_of_total_packets - 1 ? 1 : 0);
|
||||||
rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE::H264_FEC_REPAIR);
|
rtp_packet.SetPayloadType(rtp::PAYLOAD_TYPE::H264_FEC_REPAIR);
|
||||||
rtp_packet.SetSequenceNumber(sequence_number_++);
|
rtp_packet.SetSequenceNumber(sequence_number_++);
|
||||||
rtp_packet.SetTimestamp(timestamp_);
|
rtp_packet.SetTimestamp(timestamp_);
|
||||||
rtp_packet.SetSsrc(ssrc_);
|
rtp_packet.SetSsrc(ssrc_);
|
||||||
@@ -459,7 +459,7 @@ void RtpCodec::Encode(uint8_t* buffer, uint32_t size,
|
|||||||
|
|
||||||
rtp_packet.SetHasExtension(has_extension_);
|
rtp_packet.SetHasExtension(has_extension_);
|
||||||
rtp_packet.SetMarker(1);
|
rtp_packet.SetMarker(1);
|
||||||
rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_));
|
rtp_packet.SetPayloadType(rtp::PAYLOAD_TYPE(payload_type_));
|
||||||
rtp_packet.SetSequenceNumber(sequence_number_++);
|
rtp_packet.SetSequenceNumber(sequence_number_++);
|
||||||
|
|
||||||
timestamp_ = std::chrono::duration_cast<std::chrono::microseconds>(
|
timestamp_ = std::chrono::duration_cast<std::chrono::microseconds>(
|
||||||
@@ -478,7 +478,7 @@ void RtpCodec::Encode(uint8_t* buffer, uint32_t size,
|
|||||||
rtp_packet.SetExtensionData(extension_data_, extension_len_);
|
rtp_packet.SetExtensionData(extension_data_, extension_len_);
|
||||||
}
|
}
|
||||||
|
|
||||||
RtpPacket::FU_INDICATOR fu_indicator;
|
rtp::FU_INDICATOR fu_indicator;
|
||||||
fu_indicator.forbidden_bit = 0;
|
fu_indicator.forbidden_bit = 0;
|
||||||
fu_indicator.nal_reference_idc = 1;
|
fu_indicator.nal_reference_idc = 1;
|
||||||
fu_indicator.nal_unit_type = NALU;
|
fu_indicator.nal_unit_type = NALU;
|
||||||
@@ -508,7 +508,7 @@ void RtpCodec::Encode(uint8_t* buffer, uint32_t size,
|
|||||||
|
|
||||||
rtp_packet.SetHasExtension(has_extension_);
|
rtp_packet.SetHasExtension(has_extension_);
|
||||||
rtp_packet.SetMarker(index == packet_num - 1 ? 1 : 0);
|
rtp_packet.SetMarker(index == packet_num - 1 ? 1 : 0);
|
||||||
rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_));
|
rtp_packet.SetPayloadType(rtp::PAYLOAD_TYPE(payload_type_));
|
||||||
rtp_packet.SetSequenceNumber(sequence_number_++);
|
rtp_packet.SetSequenceNumber(sequence_number_++);
|
||||||
rtp_packet.SetTimestamp(timestamp_);
|
rtp_packet.SetTimestamp(timestamp_);
|
||||||
rtp_packet.SetSsrc(ssrc_);
|
rtp_packet.SetSsrc(ssrc_);
|
||||||
@@ -522,12 +522,12 @@ void RtpCodec::Encode(uint8_t* buffer, uint32_t size,
|
|||||||
rtp_packet.SetExtensionData(extension_data_, extension_len_);
|
rtp_packet.SetExtensionData(extension_data_, extension_len_);
|
||||||
}
|
}
|
||||||
|
|
||||||
RtpPacket::FU_INDICATOR fu_indicator;
|
rtp::FU_INDICATOR fu_indicator;
|
||||||
fu_indicator.forbidden_bit = 0;
|
fu_indicator.forbidden_bit = 0;
|
||||||
fu_indicator.nal_reference_idc = 0;
|
fu_indicator.nal_reference_idc = 0;
|
||||||
fu_indicator.nal_unit_type = FU_A;
|
fu_indicator.nal_unit_type = FU_A;
|
||||||
|
|
||||||
RtpPacket::FU_HEADER fu_header;
|
rtp::FU_HEADER fu_header;
|
||||||
fu_header.start = index == 0 ? 1 : 0;
|
fu_header.start = index == 0 ? 1 : 0;
|
||||||
fu_header.end = index == packet_num - 1 ? 1 : 0;
|
fu_header.end = index == packet_num - 1 ? 1 : 0;
|
||||||
fu_header.remain_bit = 0;
|
fu_header.remain_bit = 0;
|
||||||
@@ -545,7 +545,7 @@ void RtpCodec::Encode(uint8_t* buffer, uint32_t size,
|
|||||||
packets.emplace_back(rtp_packet);
|
packets.emplace_back(rtp_packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (RtpPacket::PAYLOAD_TYPE::AV1 == payload_type_) {
|
} else if (rtp::PAYLOAD_TYPE::AV1 == payload_type_) {
|
||||||
std::vector<Obu> obus = ParseObus(buffer, size);
|
std::vector<Obu> obus = ParseObus(buffer, size);
|
||||||
uint64_t timestamp =
|
uint64_t timestamp =
|
||||||
std::chrono::duration_cast<std::chrono::microseconds>(
|
std::chrono::duration_cast<std::chrono::microseconds>(
|
||||||
@@ -567,7 +567,7 @@ void RtpCodec::Encode(uint8_t* buffer, uint32_t size,
|
|||||||
|
|
||||||
rtp_packet.SetHasExtension(has_extension_);
|
rtp_packet.SetHasExtension(has_extension_);
|
||||||
rtp_packet.SetMarker(1);
|
rtp_packet.SetMarker(1);
|
||||||
rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_));
|
rtp_packet.SetPayloadType(rtp::PAYLOAD_TYPE(payload_type_));
|
||||||
rtp_packet.SetSequenceNumber(sequence_number_++);
|
rtp_packet.SetSequenceNumber(sequence_number_++);
|
||||||
rtp_packet.SetTimestamp(timestamp);
|
rtp_packet.SetTimestamp(timestamp);
|
||||||
rtp_packet.SetSsrc(ssrc_);
|
rtp_packet.SetSsrc(ssrc_);
|
||||||
@@ -603,7 +603,7 @@ void RtpCodec::Encode(uint8_t* buffer, uint32_t size,
|
|||||||
|
|
||||||
rtp_packet.SetHasExtension(has_extension_);
|
rtp_packet.SetHasExtension(has_extension_);
|
||||||
rtp_packet.SetMarker(index == packet_num - 1 ? 1 : 0);
|
rtp_packet.SetMarker(index == packet_num - 1 ? 1 : 0);
|
||||||
rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_));
|
rtp_packet.SetPayloadType(rtp::PAYLOAD_TYPE(payload_type_));
|
||||||
rtp_packet.SetSequenceNumber(sequence_number_++);
|
rtp_packet.SetSequenceNumber(sequence_number_++);
|
||||||
rtp_packet.SetTimestamp(timestamp);
|
rtp_packet.SetTimestamp(timestamp);
|
||||||
rtp_packet.SetSsrc(ssrc_);
|
rtp_packet.SetSsrc(ssrc_);
|
||||||
@@ -17,7 +17,7 @@ class RtpCodec {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RtpCodec(RtpPacket::PAYLOAD_TYPE payload_type);
|
RtpCodec(rtp::PAYLOAD_TYPE payload_type);
|
||||||
~RtpCodec();
|
~RtpCodec();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
// rtp_packet.SetHasPadding(has_padding_);
|
// rtp_packet.SetHasPadding(has_padding_);
|
||||||
// rtp_packet.SetHasExtension(has_extension_);
|
// rtp_packet.SetHasExtension(has_extension_);
|
||||||
// rtp_packet.SetMarker(1);
|
// rtp_packet.SetMarker(1);
|
||||||
// rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_));
|
// rtp_packet.SetPayloadType(rtp::PAYLOAD_TYPE(payload_type_));
|
||||||
// rtp_packet.SetSequenceNumber(sequence_number_++);
|
// rtp_packet.SetSequenceNumber(sequence_number_++);
|
||||||
// rtp_packet.SetTimestamp(timestamp);
|
// rtp_packet.SetTimestamp(timestamp);
|
||||||
// rtp_packet.SetSsrc(ssrc_);
|
// rtp_packet.SetSsrc(ssrc_);
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
// rtp_packet.SetHasPadding(has_padding_);
|
// rtp_packet.SetHasPadding(has_padding_);
|
||||||
// rtp_packet.SetHasExtension(has_extension_);
|
// rtp_packet.SetHasExtension(has_extension_);
|
||||||
// rtp_packet.SetMarker(index == packet_num - 1 ? 1 : 0);
|
// rtp_packet.SetMarker(index == packet_num - 1 ? 1 : 0);
|
||||||
// rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_));
|
// rtp_packet.SetPayloadType(rtp::PAYLOAD_TYPE(payload_type_));
|
||||||
// rtp_packet.SetSequenceNumber(sequence_number_++);
|
// rtp_packet.SetSequenceNumber(sequence_number_++);
|
||||||
// rtp_packet.SetTimestamp(timestamp);
|
// rtp_packet.SetTimestamp(timestamp);
|
||||||
// rtp_packet.SetSsrc(ssrc_);
|
// rtp_packet.SetSsrc(ssrc_);
|
||||||
43
src/rtp/rtp_packet/rtp_defines.h
Normal file
43
src/rtp/rtp_packet/rtp_defines.h
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* @Author: DI JUNKUN
|
||||||
|
* @Date: 2025-01-23
|
||||||
|
* Copyright (c) 2025 by DI JUNKUN, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RTP_DEFINES_H_
|
||||||
|
#define _RTP_DEFINES_H_
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#define DEFAULT_MTU 1500
|
||||||
|
#define MAX_NALU_LEN 1400
|
||||||
|
|
||||||
|
namespace rtp {
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
UNDEFINED = 0,
|
||||||
|
H264 = 96,
|
||||||
|
H264_FEC_SOURCE = 97,
|
||||||
|
H264_FEC_REPAIR = 98,
|
||||||
|
AV1 = 99,
|
||||||
|
OPUS = 111,
|
||||||
|
DATA = 127
|
||||||
|
} PAYLOAD_TYPE;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t forbidden_bit : 1;
|
||||||
|
uint8_t nal_reference_idc : 2;
|
||||||
|
uint8_t nal_unit_type : 5;
|
||||||
|
} FU_INDICATOR;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t start : 1;
|
||||||
|
uint8_t end : 1;
|
||||||
|
uint8_t remain_bit : 1;
|
||||||
|
uint8_t nal_unit_type : 5;
|
||||||
|
} FU_HEADER;
|
||||||
|
|
||||||
|
typedef enum { UNKNOWN = 0, NALU = 1, FU_A = 28, FU_B = 29 } NAL_UNIT_TYPE;
|
||||||
|
} // namespace rtp
|
||||||
|
#endif
|
||||||
@@ -54,7 +54,7 @@ struct RTPHeader {
|
|||||||
uint16_t sequence_number_ = 1;
|
uint16_t sequence_number_ = 1;
|
||||||
uint64_t timestamp_ = 0;
|
uint64_t timestamp_ = 0;
|
||||||
uint32_t ssrc_ = 0;
|
uint32_t ssrc_ = 0;
|
||||||
uint32_t csrcs_[kRtpCsrcSize];
|
uint32_t csrcs_[kMaxRtpCsrcSize];
|
||||||
size_t padding_len;
|
size_t padding_len;
|
||||||
size_t header_len;
|
size_t header_len;
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
RtpPacket::RtpPacket() {}
|
RtpPacket::RtpPacket() {}
|
||||||
|
|
||||||
|
RtpPacket::RtpPacket(size_t size) : buffer_(size) {}
|
||||||
|
|
||||||
RtpPacket::RtpPacket(const RtpPacket &rtp_packet) = default;
|
RtpPacket::RtpPacket(const RtpPacket &rtp_packet) = default;
|
||||||
|
|
||||||
RtpPacket::RtpPacket(RtpPacket &&rtp_packet) = default;
|
RtpPacket::RtpPacket(RtpPacket &&rtp_packet) = default;
|
||||||
@@ -15,12 +17,13 @@ RtpPacket &RtpPacket::operator=(RtpPacket &&rtp_packet) = default;
|
|||||||
RtpPacket::~RtpPacket() = default;
|
RtpPacket::~RtpPacket() = default;
|
||||||
|
|
||||||
bool RtpPacket::Build(const uint8_t *buffer, uint32_t size) {
|
bool RtpPacket::Build(const uint8_t *buffer, uint32_t size) {
|
||||||
if (size > 0) {
|
if (!Parse(buffer, size)) {
|
||||||
buffer_.SetData(buffer, size);
|
LOG_WARN("RtpPacket::Build: parse failed");
|
||||||
size_ = size;
|
return false;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
buffer_.SetData(buffer, size);
|
||||||
|
size_ = size;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RtpPacket::Parse(const uint8_t *buffer, uint32_t size) {
|
bool RtpPacket::Parse(const uint8_t *buffer, uint32_t size) {
|
||||||
@@ -30,36 +33,40 @@ bool RtpPacket::Parse(const uint8_t *buffer, uint32_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 1st byte
|
// 1st byte
|
||||||
version_ = (buffer_[payload_offset_] >> 6) & 0x03;
|
version_ = (buffer[payload_offset_] >> 6) & 0x03;
|
||||||
if (version_ != kRtpVersion) {
|
if (version_ != kRtpVersion) {
|
||||||
LOG_WARN("RtpPacket::Parse: version is not qual to kRtpVersion");
|
LOG_WARN("RtpPacket::Parse: version is not qual to kRtpVersion");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
has_padding_ = (buffer_[payload_offset_] >> 5) & 0x01;
|
has_padding_ = (buffer[payload_offset_] >> 5) & 0x01;
|
||||||
has_extension_ = (buffer_[payload_offset_] >> 4) & 0x01;
|
has_extension_ = (buffer[payload_offset_] >> 4) & 0x01;
|
||||||
csrc_count_ = buffer_[payload_offset_] & 0x0f;
|
csrc_count_ = buffer[payload_offset_] & 0x0f;
|
||||||
if (csrc_count_ > kMaxRtpCsrcSize) {
|
if (csrc_count_ > kMaxRtpCsrcSize) {
|
||||||
LOG_WARN("RtpPacket::Parse: csrc count is too large");
|
LOG_WARN("RtpPacket::Parse: csrc count is too large");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
payload_offset_++;
|
||||||
|
|
||||||
// 2nd byte
|
// 2nd byte
|
||||||
marker_ = (buffer_[payload_offset_] >> 7) & 0x01;
|
marker_ = (buffer[payload_offset_] >> 7) & 0x01;
|
||||||
payload_type_ = buffer_[payload_offset_] & 0x7f;
|
payload_type_ = buffer[payload_offset_] & 0x7f;
|
||||||
|
payload_offset_ += 1;
|
||||||
|
|
||||||
// 3rd byte and 4th byte
|
// 3rd byte and 4th byte
|
||||||
sequence_number_ =
|
sequence_number_ =
|
||||||
(buffer_[payload_offset_] << 8) | buffer_[payload_offset_ + 1];
|
(buffer[payload_offset_] << 8) | buffer[payload_offset_ + 1];
|
||||||
|
payload_offset_ += 2;
|
||||||
|
|
||||||
// 5th byte to 8th byte
|
// 5th byte to 8th byte
|
||||||
timestamp_ =
|
timestamp_ = (buffer[payload_offset_] << 24) |
|
||||||
(buffer_[payload_offset_] << 24) | (buffer_[payload_offset_ + 1] << 16) |
|
(buffer[payload_offset_ + 1] << 16) |
|
||||||
(buffer_[payload_offset_ + 2] << 8) | buffer_[payload_offset_ + 3];
|
(buffer[payload_offset_ + 2] << 8) | buffer[payload_offset_ + 3];
|
||||||
|
payload_offset_ += 4;
|
||||||
|
|
||||||
// 9th byte to 12th byte
|
// 9th byte to 12th byte
|
||||||
ssrc_ = (buffer_[payload_offset_] << 24) |
|
ssrc_ = (buffer[payload_offset_] << 24) |
|
||||||
(buffer_[payload_offset_ + 1] << 16) |
|
(buffer[payload_offset_ + 1] << 16) |
|
||||||
(buffer_[payload_offset_ + 2] << 8) | buffer_[payload_offset_ + 3];
|
(buffer[payload_offset_ + 2] << 8) | buffer[payload_offset_ + 3];
|
||||||
|
|
||||||
payload_offset_ = kFixedHeaderSize;
|
payload_offset_ = kFixedHeaderSize;
|
||||||
|
|
||||||
@@ -68,11 +75,11 @@ bool RtpPacket::Parse(const uint8_t *buffer, uint32_t size) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// csrc
|
// csrc
|
||||||
for (uint32_t csrc_index = 0; i < csrc_count_; i++) {
|
for (uint32_t csrc_index = 0; csrc_index < csrc_count_; csrc_index++) {
|
||||||
uint32_t csrc = (buffer_[payload_offset_ + csrc_index * 4] << 24) |
|
uint32_t csrc = (buffer[payload_offset_ + csrc_index * 4] << 24) |
|
||||||
(buffer_[payload_offset_ + 1 + csrc_index * 4] << 16) |
|
(buffer[payload_offset_ + 1 + csrc_index * 4] << 16) |
|
||||||
(buffer_[payload_offset_ + 2 + csrc_index * 4] << 8) |
|
(buffer[payload_offset_ + 2 + csrc_index * 4] << 8) |
|
||||||
buffer_[payload_offset_ + 3 + csrc_index * 4];
|
buffer[payload_offset_ + 3 + csrc_index * 4];
|
||||||
csrcs_.push_back(csrc);
|
csrcs_.push_back(csrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,28 +96,30 @@ bool RtpPacket::Parse(const uint8_t *buffer, uint32_t size) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
extension_profile_ =
|
extension_profile_ =
|
||||||
(buffer_[payload_offset_] << 8) | buffer_[payload_offset_ + 1];
|
(buffer[payload_offset_] << 8) | buffer[payload_offset_ + 1];
|
||||||
extension_len_ =
|
extension_len_ =
|
||||||
(buffer_[payload_offset_ + 2] << 8) | buffer_[payload_offset_ + 3];
|
(buffer[payload_offset_ + 2] << 8) | buffer[payload_offset_ + 3];
|
||||||
|
|
||||||
if (payload_offset_ + 4 + extension_len_ > size) {
|
if (payload_offset_ + extension_len_ > size) {
|
||||||
LOG_WARN("RtpPacket::Parse: extension len is too large");
|
LOG_WARN("RtpPacket::Parse: extension len is too large");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t offset = payload_offset_ + 4;
|
size_t offset = payload_offset_ + 4;
|
||||||
while (offset < size && extension_len_ > 0) {
|
while (offset < size && extension_len_ > 0) {
|
||||||
uint8_t id = buffer_[offset] >> 4;
|
uint8_t id = buffer[offset] >> 4;
|
||||||
uint8_t len = (buffer_[offset] & 0x0F) + 1;
|
uint8_t len = (buffer[offset] & 0x0F) + 1;
|
||||||
if (offset + 1 + len > size) {
|
if (offset + 1 + len > size) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
extensions_.push_back(
|
Extension extension;
|
||||||
{id, std::vector<uint8_t>(buffer_ + offset + 1,
|
extension.id = id;
|
||||||
buffer_ + offset + 1 + len)});
|
extension.data =
|
||||||
|
std::vector<uint8_t>(buffer + offset + 1, buffer + offset + 1 + len);
|
||||||
|
extensions_.push_back(extension);
|
||||||
offset += 1 + len;
|
offset += 1 + len;
|
||||||
}
|
}
|
||||||
payload_offset_ += (4 + extension_len_);
|
payload_offset_ += extension_len_;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_padding_ && payload_offset_ < size) {
|
if (has_padding_ && payload_offset_ < size) {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "copy_on_write_buffer.h"
|
#include "copy_on_write_buffer.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "rtp_defines.h"
|
||||||
#include "rtp_header.h"
|
#include "rtp_header.h"
|
||||||
|
|
||||||
// Common
|
// Common
|
||||||
@@ -170,25 +171,14 @@
|
|||||||
#define DEFAULT_MTU 1500
|
#define DEFAULT_MTU 1500
|
||||||
#define MAX_NALU_LEN 1400
|
#define MAX_NALU_LEN 1400
|
||||||
|
|
||||||
|
constexpr uint16_t kOneByteExtensionProfileId = 0xBEDE;
|
||||||
|
constexpr uint16_t kTwoByteExtensionProfileId = 0x1000;
|
||||||
|
constexpr size_t kFixedHeaderSize = 12;
|
||||||
|
|
||||||
class RtpPacket {
|
class RtpPacket {
|
||||||
public:
|
|
||||||
typedef enum {
|
|
||||||
UNDEFINED = 0,
|
|
||||||
H264 = 96,
|
|
||||||
H264_FEC_SOURCE = 97,
|
|
||||||
H264_FEC_REPAIR = 98,
|
|
||||||
AV1 = 99,
|
|
||||||
OPUS = 111,
|
|
||||||
DATA = 127
|
|
||||||
} PAYLOAD_TYPE;
|
|
||||||
|
|
||||||
constexpr uint16_t kOneByteExtensionProfileId = 0xBEDE;
|
|
||||||
constexpr uint16_t kTwoByteExtensionProfileId = 0x1000;
|
|
||||||
|
|
||||||
constexpr size_t kFixedHeaderSize = 12;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RtpPacket();
|
RtpPacket();
|
||||||
|
RtpPacket(size_t size);
|
||||||
RtpPacket(const RtpPacket &rtp_packet);
|
RtpPacket(const RtpPacket &rtp_packet);
|
||||||
RtpPacket(RtpPacket &&rtp_packet);
|
RtpPacket(RtpPacket &&rtp_packet);
|
||||||
RtpPacket &operator=(const RtpPacket &rtp_packet);
|
RtpPacket &operator=(const RtpPacket &rtp_packet);
|
||||||
@@ -199,13 +189,16 @@ class RtpPacket {
|
|||||||
public:
|
public:
|
||||||
bool Build(const uint8_t *buffer, uint32_t size);
|
bool Build(const uint8_t *buffer, uint32_t size);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool Parse(const uint8_t *buffer, uint32_t size);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Set Header
|
// Set Header
|
||||||
void SetVerion(uint8_t version) { version_ = version; }
|
void SetVerion(uint8_t version) { version_ = version; }
|
||||||
void SetHasPadding(bool has_padding) { has_padding_ = has_padding; }
|
void SetHasPadding(bool has_padding) { has_padding_ = has_padding; }
|
||||||
void SetHasExtension(bool has_extension) { has_extension_ = has_extension; }
|
void SetHasExtension(bool has_extension) { has_extension_ = has_extension; }
|
||||||
void SetMarker(bool marker) { marker_ = marker; }
|
void SetMarker(bool marker) { marker_ = marker; }
|
||||||
void SetPayloadType(PAYLOAD_TYPE payload_type) {
|
void SetPayloadType(rtp::PAYLOAD_TYPE payload_type) {
|
||||||
payload_type_ = (uint8_t)payload_type;
|
payload_type_ = (uint8_t)payload_type;
|
||||||
}
|
}
|
||||||
void SetSequenceNumber(uint16_t sequence_number) {
|
void SetSequenceNumber(uint16_t sequence_number) {
|
||||||
@@ -220,47 +213,54 @@ class RtpPacket {
|
|||||||
// bits
|
// bits
|
||||||
abs_send_time &= 0x00FFFFFF;
|
abs_send_time &= 0x00FFFFFF;
|
||||||
|
|
||||||
// Allocate memory for the extension data if not already allocated
|
|
||||||
if (extension_data_ == nullptr) {
|
|
||||||
extension_data_ =
|
|
||||||
(uint8_t *)malloc(5); // 2 bytes for profile, 2 bytes for length, 3
|
|
||||||
// bytes for abs_send_time
|
|
||||||
extension_len_ = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the extension profile to 0xBEDE (one-byte header)
|
// Set the extension profile to 0xBEDE (one-byte header)
|
||||||
extension_profile_ = kOneByteExtensionProfileId;
|
extension_profile_ = kOneByteExtensionProfileId;
|
||||||
|
extension_len_ = 5; // 2 bytes for profile, 2 bytes for length, 3 bytes for
|
||||||
|
// abs_send_time
|
||||||
|
|
||||||
// Set the length of the extension data (in 32-bit words minus one)
|
Extension extension;
|
||||||
extension_data_[0] = 0x00;
|
extension.id = 0;
|
||||||
extension_data_[1] = 0x02; // 2 words (8 bytes)
|
extension.len = 2;
|
||||||
|
extension.data.push_back(extension.id << 4 | extension.len);
|
||||||
// Set the absolute send time in the extension data
|
extension.data.push_back((abs_send_time >> 16) & 0xFF);
|
||||||
extension_data_[2] = (abs_send_time >> 16) & 0xFF;
|
extension.data.push_back((abs_send_time >> 8) & 0xFF);
|
||||||
extension_data_[3] = (abs_send_time >> 8) & 0xFF;
|
extension.data.push_back(abs_send_time & 0xFF);
|
||||||
extension_data_[4] = abs_send_time & 0xFF;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Get Header
|
// Get Header
|
||||||
uint32_t Verion() const { return version_; }
|
uint32_t Version() const { return version_; }
|
||||||
bool HasPadding() const { return has_padding_; }
|
bool HasPadding() const { return has_padding_; }
|
||||||
bool HasExtension() const { return has_extension_; }
|
bool HasExtension() const { return has_extension_; }
|
||||||
bool Marker() const { return marker_; }
|
bool Marker() const { return marker_; }
|
||||||
PAYLOAD_TYPE PayloadType() const { return PAYLOAD_TYPE(payload_type_); }
|
rtp::PAYLOAD_TYPE PayloadType() const {
|
||||||
|
return rtp::PAYLOAD_TYPE(payload_type_);
|
||||||
|
}
|
||||||
uint16_t SequenceNumber() const { return sequence_number_; }
|
uint16_t SequenceNumber() const { return sequence_number_; }
|
||||||
uint64_t Timestamp() const { return timestamp_; }
|
uint64_t Timestamp() const { return timestamp_; }
|
||||||
uint32_t Ssrc() const { return ssrc_; }
|
uint32_t Ssrc() const { return ssrc_; }
|
||||||
std::vector<uint32_t> Csrcs() const { return csrcs_; };
|
std::vector<uint32_t> Csrcs() const { return csrcs_; };
|
||||||
uint16_t ExtensionProfile() const { return extension_profile_; }
|
uint16_t ExtensionProfile() const { return extension_profile_; }
|
||||||
const uint8_t *ExtensionData() { return extension_data_; }
|
|
||||||
|
uint32_t GetAbsoluteSendTimestamp(uint32_t *abs_send_time) const {
|
||||||
|
if (!extensions_.empty()) {
|
||||||
|
for (auto &ext : extensions_) {
|
||||||
|
if (ext.id == 1) {
|
||||||
|
*abs_send_time = (ext.data[0] << 16) | (ext.data[1] << 8) |
|
||||||
|
ext.data[2]; // 24-bit value
|
||||||
|
return *abs_send_time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Payload
|
// Payload
|
||||||
const uint8_t *Payload() { return Buffer() + payload_offset_; };
|
const uint8_t *Payload() { return Buffer().data() + payload_offset_; };
|
||||||
size_t PayloadSize() { return payload_size_; }
|
size_t PayloadSize() { return payload_size_; }
|
||||||
|
|
||||||
// Entire RTP buffer
|
// Entire RTP buffer
|
||||||
const uint8_t *Buffer() const { return buffer_; }
|
CopyOnWriteBuffer Buffer() const { return buffer_; }
|
||||||
size_t Size() const { return size_; }
|
size_t Size() const { return size_; }
|
||||||
|
|
||||||
// For webrtc module use
|
// For webrtc module use
|
||||||
@@ -288,6 +288,7 @@ class RtpPacket {
|
|||||||
uint16_t extension_len_ = 0;
|
uint16_t extension_len_ = 0;
|
||||||
struct Extension {
|
struct Extension {
|
||||||
uint8_t id;
|
uint8_t id;
|
||||||
|
uint8_t len;
|
||||||
std::vector<uint8_t> data;
|
std::vector<uint8_t> data;
|
||||||
};
|
};
|
||||||
std::vector<Extension> extensions_;
|
std::vector<Extension> extensions_;
|
||||||
@@ -300,15 +301,8 @@ class RtpPacket {
|
|||||||
size_t padding_size_ = 0;
|
size_t padding_size_ = 0;
|
||||||
|
|
||||||
// Entire rtp buffer
|
// Entire rtp buffer
|
||||||
CopyOnWriteBuffer buffer_ = nullptr;
|
CopyOnWriteBuffer buffer_;
|
||||||
size_t size_ = 0;
|
size_t size_ = 0;
|
||||||
|
|
||||||
// H.264 header
|
|
||||||
FU_INDICATOR fu_indicator_;
|
|
||||||
FU_HEADER fu_header_;
|
|
||||||
uint8_t fec_symbol_id_ = 0;
|
|
||||||
uint8_t fec_source_symbol_num_ = 0;
|
|
||||||
uint8_t av1_aggr_header_ = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
16
src/rtp/rtp_packet/rtp_packet_av1.cpp
Normal file
16
src/rtp/rtp_packet/rtp_packet_av1.cpp
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#include "rtp_packet_av1.h"
|
||||||
|
|
||||||
|
RtpPacketAv1::RtpPacketAv1() {}
|
||||||
|
|
||||||
|
RtpPacketAv1::~RtpPacketAv1() {}
|
||||||
|
|
||||||
|
bool RtpPacketAv1::GetFrameHeaderInfo() {
|
||||||
|
const uint8_t* frame_buffer = Payload();
|
||||||
|
av1_aggr_header_ = frame_buffer[0];
|
||||||
|
z_ = av1_aggr_header_ >> 7;
|
||||||
|
y_ = av1_aggr_header_ >> 6 & 0x01;
|
||||||
|
w_ = av1_aggr_header_ >> 4 & 0x03;
|
||||||
|
n_ = av1_aggr_header_ >> 3 & 0x01;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
52
src/rtp/rtp_packet/rtp_packet_av1.h
Normal file
52
src/rtp/rtp_packet/rtp_packet_av1.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* @Author: DI JUNKUN
|
||||||
|
* @Date: 2025-01-23
|
||||||
|
* Copyright (c) 2025 by DI JUNKUN, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RTP_PACKET_AV1_H_
|
||||||
|
#define _RTP_PACKET_AV1_H_
|
||||||
|
|
||||||
|
#include "rtp_packet.h"
|
||||||
|
|
||||||
|
class RtpPacketAv1 : public RtpPacket {
|
||||||
|
public:
|
||||||
|
RtpPacketAv1();
|
||||||
|
virtual ~RtpPacketAv1();
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool GetFrameHeaderInfo();
|
||||||
|
|
||||||
|
bool Av1FrameStart() {
|
||||||
|
// return !z_ && !y_;
|
||||||
|
|
||||||
|
if (z_ == 0 && y_ == 0 && w_ == 1) {
|
||||||
|
return true;
|
||||||
|
} else if (z_ == 0 && y_ == 1 && w_ == 1) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Av1FrameEnd() {
|
||||||
|
// return z_ && !y_;
|
||||||
|
|
||||||
|
if (z_ == 0 && y_ == 0 && w_ == 1) {
|
||||||
|
return true;
|
||||||
|
} else if (z_ == 1 && y_ == 0 && w_ == 1) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t av1_aggr_header_ = 0;
|
||||||
|
uint8_t z_ = 0;
|
||||||
|
uint8_t y_ = 0;
|
||||||
|
uint8_t w_ = 0;
|
||||||
|
uint8_t n_ = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
20
src/rtp/rtp_packet/rtp_packet_h264.cpp
Normal file
20
src/rtp/rtp_packet/rtp_packet_h264.cpp
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#include "rtp_packet_h264.h"
|
||||||
|
|
||||||
|
RtpPacketH264::RtpPacketH264() {}
|
||||||
|
|
||||||
|
RtpPacketH264::~RtpPacketH264() {}
|
||||||
|
|
||||||
|
bool RtpPacketH264::GetFrameHeaderInfo() {
|
||||||
|
const uint8_t* frame_buffer = Payload();
|
||||||
|
|
||||||
|
fu_indicator_.forbidden_bit = (frame_buffer[0] >> 7) & 0x01;
|
||||||
|
fu_indicator_.nal_reference_idc = (frame_buffer[0] >> 5) & 0x03;
|
||||||
|
fu_indicator_.nal_unit_type = frame_buffer[0] & 0x1F;
|
||||||
|
|
||||||
|
fu_header_.start = (frame_buffer[1] >> 7) & 0x01;
|
||||||
|
fu_header_.end = (frame_buffer[1] >> 6) & 0x01;
|
||||||
|
fu_header_.remain_bit = (frame_buffer[1] >> 5) & 0x01;
|
||||||
|
fu_header_.nal_unit_type = frame_buffer[1] & 0x1F;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
31
src/rtp/rtp_packet/rtp_packet_h264.h
Normal file
31
src/rtp/rtp_packet/rtp_packet_h264.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* @Author: DI JUNKUN
|
||||||
|
* @Date: 2025-01-23
|
||||||
|
* Copyright (c) 2025 by DI JUNKUN, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RTP_PACKET_H264_H_
|
||||||
|
#define _RTP_PACKET_H264_H_
|
||||||
|
|
||||||
|
#include "rtp_packet.h"
|
||||||
|
|
||||||
|
class RtpPacketH264 : public RtpPacket {
|
||||||
|
public:
|
||||||
|
RtpPacketH264();
|
||||||
|
virtual ~RtpPacketH264();
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool GetFrameHeaderInfo();
|
||||||
|
// NAL
|
||||||
|
rtp::NAL_UNIT_TYPE NalUnitType() {
|
||||||
|
return rtp::NAL_UNIT_TYPE(fu_indicator_.nal_unit_type);
|
||||||
|
}
|
||||||
|
bool FuAStart() { return fu_header_.start; }
|
||||||
|
bool FuAEnd() { return fu_header_.end; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
rtp::FU_INDICATOR fu_indicator_;
|
||||||
|
rtp::FU_HEADER fu_header_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -33,7 +33,7 @@ RtpPacketReceived& RtpPacketReceived::operator=(RtpPacketReceived&& packet) =
|
|||||||
RtpPacketReceived::~RtpPacketReceived() {}
|
RtpPacketReceived::~RtpPacketReceived() {}
|
||||||
|
|
||||||
void RtpPacketReceived::GetHeader(RTPHeader* header) const {
|
void RtpPacketReceived::GetHeader(RTPHeader* header) const {
|
||||||
header->version = Version();
|
header->version_ = Version();
|
||||||
header->has_padding_ = HasPadding();
|
header->has_padding_ = HasPadding();
|
||||||
header->has_extension_ = HasExtension();
|
header->has_extension_ = HasExtension();
|
||||||
header->csrc_count_ = Csrcs().size();
|
header->csrc_count_ = Csrcs().size();
|
||||||
@@ -44,7 +44,7 @@ void RtpPacketReceived::GetHeader(RTPHeader* header) const {
|
|||||||
header->ssrc_ = Ssrc();
|
header->ssrc_ = Ssrc();
|
||||||
std::vector<uint32_t> csrcs = Csrcs();
|
std::vector<uint32_t> csrcs = Csrcs();
|
||||||
for (size_t i = 0; i < csrcs.size(); ++i) {
|
for (size_t i = 0; i < csrcs.size(); ++i) {
|
||||||
header->csrc_[i] = csrcs[i];
|
header->csrcs_[i] = csrcs[i];
|
||||||
}
|
}
|
||||||
header->padding_len = padding_size();
|
header->padding_len = padding_size();
|
||||||
header->header_len = headers_size();
|
header->header_len = headers_size();
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
#include "rtp_packetizer.h"
|
#include "rtp_packetizer.h"
|
||||||
|
|
||||||
std::unique_ptr<RtpPacketizer> Create(uint32_t payload_type, uint8_t* payload,
|
#include "rtp_packetizer_av1.h"
|
||||||
size_t payload_size) {
|
#include "rtp_packetizer_generic.h"
|
||||||
|
#include "rtp_packetizer_h264.h"
|
||||||
|
|
||||||
|
std::unique_ptr<RtpPacketizer> RtpPacketizer::Create(uint32_t payload_type) {
|
||||||
switch (payload_type) {
|
switch (payload_type) {
|
||||||
case RtpPacket::PAYLOAD_TYPE::H264:
|
case rtp::PAYLOAD_TYPE::H264:
|
||||||
return std::make_unique<RtpPacketizerH264>(payload, payload_size);
|
return std::make_unique<RtpPacketizerH264>();
|
||||||
case RtpPacket::PAYLOAD_TYPE::AV1:
|
case rtp::PAYLOAD_TYPE::AV1:
|
||||||
return std::make_unique<RtpPacketizerAv1>(payload, payload_size);
|
return std::make_unique<RtpPacketizerAv1>();
|
||||||
|
default:
|
||||||
|
return std::make_unique<RtpPacketizerGeneric>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,8 @@ class RtpPacketizer {
|
|||||||
|
|
||||||
virtual ~RtpPacketizer() = default;
|
virtual ~RtpPacketizer() = default;
|
||||||
|
|
||||||
bool Build(uint8_t* payload, uint32_t payload_size) = 0;
|
virtual std::vector<RtpPacket> Build(uint8_t* payload,
|
||||||
|
uint32_t payload_size) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#include "rtp_packetizer_av1.h"
|
||||||
|
|
||||||
|
RtpPacketizerAv1::RtpPacketizerAv1() {}
|
||||||
|
|
||||||
|
RtpPacketizerAv1::~RtpPacketizerAv1() {}
|
||||||
|
|
||||||
|
std::vector<RtpPacket> RtpPacketizerAv1::Build(uint8_t* payload,
|
||||||
|
uint32_t payload_size) {
|
||||||
|
std::vector<RtpPacket> rtp_packets;
|
||||||
|
return rtp_packets;
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* @Author: DI JUNKUN
|
||||||
|
* @Date: 2025-01-23
|
||||||
|
* Copyright (c) 2025 by DI JUNKUN, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RTP_PACKETIZER_AV1_H_
|
||||||
|
#define _RTP_PACKETIZER_AV1_H_
|
||||||
|
|
||||||
|
#include "rtp_packetizer.h"
|
||||||
|
|
||||||
|
class RtpPacketizerAv1 : public RtpPacketizer {
|
||||||
|
public:
|
||||||
|
RtpPacketizerAv1();
|
||||||
|
|
||||||
|
virtual ~RtpPacketizerAv1();
|
||||||
|
|
||||||
|
std::vector<RtpPacket> Build(uint8_t* payload,
|
||||||
|
uint32_t payload_size) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t version_;
|
||||||
|
bool has_padding_;
|
||||||
|
bool has_extension_;
|
||||||
|
uint32_t csrc_count_;
|
||||||
|
bool marker_;
|
||||||
|
uint32_t payload_type_;
|
||||||
|
uint16_t sequence_number_;
|
||||||
|
uint64_t timestamp_;
|
||||||
|
uint32_t ssrc_;
|
||||||
|
std::vector<uint32_t> csrcs_;
|
||||||
|
uint16_t profile_;
|
||||||
|
uint16_t extension_profile_;
|
||||||
|
uint16_t extension_len_;
|
||||||
|
uint8_t* extension_data_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<uint8_t> rtp_packet_frame_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
#include "rtp_packetizer_generic.h"
|
||||||
|
|
||||||
|
RtpPacketizerGeneric::RtpPacketizerGeneric()
|
||||||
|
: version_(kRtpVersion),
|
||||||
|
has_padding_(false),
|
||||||
|
has_extension_(true),
|
||||||
|
csrc_count_(0),
|
||||||
|
marker_(false),
|
||||||
|
payload_type_(rtp::PAYLOAD_TYPE::DATA),
|
||||||
|
sequence_number_(1),
|
||||||
|
timestamp_(0),
|
||||||
|
ssrc_(0),
|
||||||
|
profile_(0),
|
||||||
|
extension_profile_(0),
|
||||||
|
extension_len_(0),
|
||||||
|
extension_data_(nullptr) {}
|
||||||
|
|
||||||
|
RtpPacketizerGeneric::~RtpPacketizerGeneric() {}
|
||||||
|
|
||||||
|
std::vector<RtpPacket> RtpPacketizerGeneric::Build(uint8_t* payload,
|
||||||
|
uint32_t payload_size) {
|
||||||
|
uint32_t last_packet_size = payload_size % MAX_NALU_LEN;
|
||||||
|
uint32_t packet_num =
|
||||||
|
payload_size / MAX_NALU_LEN + (last_packet_size ? 1 : 0);
|
||||||
|
|
||||||
|
// TODO: use frame timestamp
|
||||||
|
timestamp_ = std::chrono::duration_cast<std::chrono::microseconds>(
|
||||||
|
std::chrono::system_clock::now().time_since_epoch())
|
||||||
|
.count();
|
||||||
|
|
||||||
|
std::vector<RtpPacket> rtp_packets;
|
||||||
|
for (uint32_t index = 0; index < packet_num; index++) {
|
||||||
|
version_ = kRtpVersion;
|
||||||
|
has_padding_ = false;
|
||||||
|
has_extension_ = true;
|
||||||
|
csrc_count_ = 0;
|
||||||
|
marker_ = index == packet_num - 1 ? 1 : 0;
|
||||||
|
payload_type_ = rtp::PAYLOAD_TYPE(payload_type_);
|
||||||
|
sequence_number_++;
|
||||||
|
timestamp_ = timestamp_;
|
||||||
|
ssrc_ = ssrc_;
|
||||||
|
|
||||||
|
if (!csrc_count_) {
|
||||||
|
csrcs_ = csrcs_;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtp_packet_frame_.clear();
|
||||||
|
rtp_packet_frame_.push_back((version_ << 6) | (has_padding_ << 5) |
|
||||||
|
(has_extension_ << 4) | csrc_count_);
|
||||||
|
rtp_packet_frame_.push_back((marker_ << 7) | payload_type_);
|
||||||
|
rtp_packet_frame_.push_back((sequence_number_ >> 8) & 0xFF);
|
||||||
|
rtp_packet_frame_.push_back(sequence_number_ & 0xFF);
|
||||||
|
rtp_packet_frame_.push_back((timestamp_ >> 24) & 0xFF);
|
||||||
|
rtp_packet_frame_.push_back((timestamp_ >> 16) & 0xFF);
|
||||||
|
rtp_packet_frame_.push_back((timestamp_ >> 8) & 0xFF);
|
||||||
|
rtp_packet_frame_.push_back(timestamp_ & 0xFF);
|
||||||
|
rtp_packet_frame_.push_back((ssrc_ >> 24) & 0xFF);
|
||||||
|
rtp_packet_frame_.push_back((ssrc_ >> 16) & 0xFF);
|
||||||
|
rtp_packet_frame_.push_back((ssrc_ >> 8) & 0xFF);
|
||||||
|
rtp_packet_frame_.push_back(ssrc_ & 0xFF);
|
||||||
|
|
||||||
|
for (uint32_t index = 0; index < csrc_count_ && !csrcs_.empty(); index++) {
|
||||||
|
rtp_packet_frame_.push_back((csrcs_[index] >> 24) & 0xFF);
|
||||||
|
rtp_packet_frame_.push_back((csrcs_[index] >> 16) & 0xFF);
|
||||||
|
rtp_packet_frame_.push_back((csrcs_[index] >> 8) & 0xFF);
|
||||||
|
rtp_packet_frame_.push_back(csrcs_[index] & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_extension_) {
|
||||||
|
extension_profile_ = kOneByteExtensionProfileId;
|
||||||
|
extension_len_ = 5; // 2 bytes for profile, 2 bytes for length, 3 bytes
|
||||||
|
// for abs_send_time
|
||||||
|
|
||||||
|
uint32_t abs_send_time =
|
||||||
|
std::chrono::duration_cast<std::chrono::microseconds>(
|
||||||
|
std::chrono::system_clock::now().time_since_epoch())
|
||||||
|
.count();
|
||||||
|
|
||||||
|
abs_send_time &= 0x00FFFFFF;
|
||||||
|
|
||||||
|
uint8_t sub_extension_id = 0;
|
||||||
|
uint8_t sub_extension_len = 2;
|
||||||
|
|
||||||
|
rtp_packet_frame_.push_back(extension_profile_ >> 8);
|
||||||
|
rtp_packet_frame_.push_back(extension_profile_ & 0xff);
|
||||||
|
rtp_packet_frame_.push_back((extension_len_ >> 8) & 0xFF);
|
||||||
|
rtp_packet_frame_.push_back(extension_len_ & 0xFF);
|
||||||
|
rtp_packet_frame_.push_back(sub_extension_id << 4 | sub_extension_len);
|
||||||
|
rtp_packet_frame_.push_back((abs_send_time >> 16) & 0xFF);
|
||||||
|
rtp_packet_frame_.push_back((abs_send_time >> 8) & 0xFF);
|
||||||
|
rtp_packet_frame_.push_back(abs_send_time & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index == packet_num - 1 && last_packet_size > 0) {
|
||||||
|
rtp_packet_frame_.insert(rtp_packet_frame_.end(), payload,
|
||||||
|
payload + last_packet_size);
|
||||||
|
} else {
|
||||||
|
rtp_packet_frame_.insert(rtp_packet_frame_.end(), payload,
|
||||||
|
payload + MAX_NALU_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
RtpPacket rtp_packet;
|
||||||
|
rtp_packet.Build(rtp_packet_frame_.data(), rtp_packet_frame_.size());
|
||||||
|
|
||||||
|
rtp_packets.emplace_back(rtp_packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rtp_packets;
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* @Author: DI JUNKUN
|
||||||
|
* @Date: 2025-01-23
|
||||||
|
* Copyright (c) 2025 by DI JUNKUN, All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RTP_PACKETIZER_GENERIC_H_
|
||||||
|
#define _RTP_PACKETIZER_GENERIC_H_
|
||||||
|
|
||||||
|
#include "rtp_packetizer.h"
|
||||||
|
|
||||||
|
class RtpPacketizerGeneric : public RtpPacketizer {
|
||||||
|
public:
|
||||||
|
RtpPacketizerGeneric();
|
||||||
|
|
||||||
|
virtual ~RtpPacketizerGeneric();
|
||||||
|
|
||||||
|
std::vector<RtpPacket> Build(uint8_t* payload,
|
||||||
|
uint32_t payload_size) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t version_;
|
||||||
|
bool has_padding_;
|
||||||
|
bool has_extension_;
|
||||||
|
uint32_t csrc_count_;
|
||||||
|
bool marker_;
|
||||||
|
uint32_t payload_type_;
|
||||||
|
uint16_t sequence_number_;
|
||||||
|
uint64_t timestamp_;
|
||||||
|
uint32_t ssrc_;
|
||||||
|
std::vector<uint32_t> csrcs_;
|
||||||
|
uint16_t profile_;
|
||||||
|
uint16_t extension_profile_;
|
||||||
|
uint16_t extension_len_;
|
||||||
|
uint8_t* extension_data_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
private:
|
||||||
|
std::vector<uint8_t> rtp_packet_frame_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -6,7 +6,7 @@ RtpPacketizerH264::RtpPacketizerH264()
|
|||||||
has_extension_(true),
|
has_extension_(true),
|
||||||
csrc_count_(0),
|
csrc_count_(0),
|
||||||
marker_(false),
|
marker_(false),
|
||||||
payload_type_(RtpPacket::PAYLOAD_TYPE::H264),
|
payload_type_(rtp::PAYLOAD_TYPE::H264),
|
||||||
sequence_number_(1),
|
sequence_number_(1),
|
||||||
timestamp_(0),
|
timestamp_(0),
|
||||||
ssrc_(0),
|
ssrc_(0),
|
||||||
@@ -28,13 +28,14 @@ std::vector<RtpPacket> RtpPacketizerH264::Build(uint8_t* payload,
|
|||||||
std::chrono::system_clock::now().time_since_epoch())
|
std::chrono::system_clock::now().time_since_epoch())
|
||||||
.count();
|
.count();
|
||||||
|
|
||||||
|
std::vector<RtpPacket> rtp_packets;
|
||||||
for (uint32_t index = 0; index < packet_num; index++) {
|
for (uint32_t index = 0; index < packet_num; index++) {
|
||||||
version_ = kRtpVersion;
|
version_ = kRtpVersion;
|
||||||
has_padding_ = false;
|
has_padding_ = false;
|
||||||
has_extension_ = true;
|
has_extension_ = true;
|
||||||
csrc_count_ = 0;
|
csrc_count_ = 0;
|
||||||
marker_ = index == packet_num - 1 ? 1 : 0;
|
marker_ = index == packet_num - 1 ? 1 : 0;
|
||||||
payload_type_ = RtpPacket::PAYLOAD_TYPE(payload_type_);
|
payload_type_ = rtp::PAYLOAD_TYPE(payload_type_);
|
||||||
sequence_number_++;
|
sequence_number_++;
|
||||||
timestamp_ = timestamp_;
|
timestamp_ = timestamp_;
|
||||||
ssrc_ = ssrc_;
|
ssrc_ = ssrc_;
|
||||||
@@ -43,16 +44,16 @@ std::vector<RtpPacket> RtpPacketizerH264::Build(uint8_t* payload,
|
|||||||
csrcs_ = csrcs_;
|
csrcs_ = csrcs_;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtpPacket::FU_INDICATOR fu_indicator;
|
rtp::FU_INDICATOR fu_indicator;
|
||||||
fu_indicator.forbidden_bit = 0;
|
fu_indicator.forbidden_bit = 0;
|
||||||
fu_indicator.nal_reference_idc = 0;
|
fu_indicator.nal_reference_idc = 0;
|
||||||
fu_indicator.nal_unit_type = FU_A;
|
fu_indicator.nal_unit_type = rtp::NAL_UNIT_TYPE::FU_A;
|
||||||
|
|
||||||
RtpPacket::FU_HEADER fu_header;
|
rtp::FU_HEADER fu_header;
|
||||||
fu_header.start = index == 0 ? 1 : 0;
|
fu_header.start = index == 0 ? 1 : 0;
|
||||||
fu_header.end = index == packet_num - 1 ? 1 : 0;
|
fu_header.end = index == packet_num - 1 ? 1 : 0;
|
||||||
fu_header.remain_bit = 0;
|
fu_header.remain_bit = 0;
|
||||||
fu_header.nal_unit_type = FU_A;
|
fu_header.nal_unit_type = rtp::NAL_UNIT_TYPE::FU_A;
|
||||||
|
|
||||||
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) |
|
||||||
@@ -77,20 +78,38 @@ std::vector<RtpPacket> RtpPacketizerH264::Build(uint8_t* payload,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (has_extension_) {
|
if (has_extension_) {
|
||||||
|
// 0 1 2 3
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | ID | L=2 | Absolute Send Time |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// ID (4 bits): The identifier of the extension header field. In WebRTC,
|
||||||
|
// the ID for Absolute Send Time is typically 3.
|
||||||
|
// L (4 bits): The length of the extension data in bytes minus 1. For
|
||||||
|
// Absolute Send Time: the length is 2 (indicating 3 bytes of data).
|
||||||
|
// Absolute Send Time (24 bits): The absolute send time, with a unit of
|
||||||
|
// 1/65536 seconds (approximately 15.258 microseconds).
|
||||||
|
|
||||||
extension_profile_ = kOneByteExtensionProfileId;
|
extension_profile_ = kOneByteExtensionProfileId;
|
||||||
extension_len_ = 5;
|
// 2 bytes for profile, 2 bytes for length, 3 bytes for abs_send_time, 1
|
||||||
|
// byte for id and sub extension length
|
||||||
|
extension_len_ = 8;
|
||||||
|
|
||||||
uint32_t abs_send_time =
|
uint32_t abs_send_time =
|
||||||
std::chrono::duration_cast<std::chrono::microseconds>(
|
std::chrono::duration_cast<std::chrono::microseconds>(
|
||||||
std::chrono::system_clock::now().time_since_epoch())
|
std::chrono::system_clock::now().time_since_epoch())
|
||||||
.count();
|
.count();
|
||||||
|
|
||||||
|
abs_send_time &= 0x00FFFFFF;
|
||||||
|
|
||||||
|
uint8_t sub_extension_id = 0;
|
||||||
|
uint8_t sub_extension_len = 2;
|
||||||
|
|
||||||
rtp_packet_frame_.push_back(extension_profile_ >> 8);
|
rtp_packet_frame_.push_back(extension_profile_ >> 8);
|
||||||
rtp_packet_frame_.push_back(extension_profile_ & 0xff);
|
rtp_packet_frame_.push_back(extension_profile_ & 0xff);
|
||||||
rtp_packet_frame_.push_back((extension_len_ >> 8) & 0xFF);
|
rtp_packet_frame_.push_back((extension_len_ >> 8) & 0xFF);
|
||||||
rtp_packet_frame_.push_back(extension_len_ & 0xFF);
|
rtp_packet_frame_.push_back(extension_len_ & 0xFF);
|
||||||
rtp_packet_frame_.push_back(0x00);
|
rtp_packet_frame_.push_back(sub_extension_id << 4 | sub_extension_len);
|
||||||
rtp_packet_frame_.push_back(0x02);
|
|
||||||
rtp_packet_frame_.push_back((abs_send_time >> 16) & 0xFF);
|
rtp_packet_frame_.push_back((abs_send_time >> 16) & 0xFF);
|
||||||
rtp_packet_frame_.push_back((abs_send_time >> 8) & 0xFF);
|
rtp_packet_frame_.push_back((abs_send_time >> 8) & 0xFF);
|
||||||
rtp_packet_frame_.push_back(abs_send_time & 0xFF);
|
rtp_packet_frame_.push_back(abs_send_time & 0xFF);
|
||||||
@@ -115,8 +134,9 @@ std::vector<RtpPacket> RtpPacketizerH264::Build(uint8_t* payload,
|
|||||||
RtpPacket rtp_packet;
|
RtpPacket rtp_packet;
|
||||||
rtp_packet.Build(rtp_packet_frame_.data(), rtp_packet_frame_.size());
|
rtp_packet.Build(rtp_packet_frame_.data(), rtp_packet_frame_.size());
|
||||||
|
|
||||||
packets.emplace_back(rtp_packet);
|
rtp_packets.emplace_back(rtp_packet);
|
||||||
}
|
}
|
||||||
|
return rtp_packets;
|
||||||
}
|
}
|
||||||
|
|
||||||
// bool BuildFec(uint8_t* payload, uint32_t payload_size) {
|
// bool BuildFec(uint8_t* payload, uint32_t payload_size) {
|
||||||
@@ -143,7 +163,7 @@ std::vector<RtpPacket> RtpPacketizerH264::Build(uint8_t* payload,
|
|||||||
// rtp_packet.SetHasPadding(false);
|
// rtp_packet.SetHasPadding(false);
|
||||||
// rtp_packet.SetHasExtension(has_extension_);
|
// rtp_packet.SetHasExtension(has_extension_);
|
||||||
// rtp_packet.SetMarker(index == num_of_source_packets - 1 ? 1 : 0);
|
// rtp_packet.SetMarker(index == num_of_source_packets - 1 ? 1 : 0);
|
||||||
// rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE::H264_FEC_SOURCE);
|
// rtp_packet.SetPayloadType(rtp::PAYLOAD_TYPE::H264_FEC_SOURCE);
|
||||||
// rtp_packet.SetSequenceNumber(sequence_number_++);
|
// rtp_packet.SetSequenceNumber(sequence_number_++);
|
||||||
// rtp_packet.SetTimestamp(timestamp_);
|
// rtp_packet.SetTimestamp(timestamp_);
|
||||||
// rtp_packet.SetSsrc(ssrc_);
|
// rtp_packet.SetSsrc(ssrc_);
|
||||||
@@ -192,7 +212,7 @@ std::vector<RtpPacket> RtpPacketizerH264::Build(uint8_t* payload,
|
|||||||
// rtp_packet.SetHasPadding(false);
|
// rtp_packet.SetHasPadding(false);
|
||||||
// rtp_packet.SetHasExtension(has_extension_);
|
// rtp_packet.SetHasExtension(has_extension_);
|
||||||
// rtp_packet.SetMarker(index == num_of_total_packets - 1 ? 1 : 0);
|
// rtp_packet.SetMarker(index == num_of_total_packets - 1 ? 1 : 0);
|
||||||
// rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE::H264_FEC_REPAIR);
|
// rtp_packet.SetPayloadType(rtp::PAYLOAD_TYPE::H264_FEC_REPAIR);
|
||||||
// rtp_packet.SetSequenceNumber(sequence_number_++);
|
// rtp_packet.SetSequenceNumber(sequence_number_++);
|
||||||
// rtp_packet.SetTimestamp(timestamp_);
|
// rtp_packet.SetTimestamp(timestamp_);
|
||||||
// rtp_packet.SetSsrc(ssrc_);
|
// rtp_packet.SetSsrc(ssrc_);
|
||||||
@@ -234,7 +254,7 @@ std::vector<RtpPacket> RtpPacketizerH264::Build(uint8_t* payload,
|
|||||||
|
|
||||||
// rtp_packet.SetHasExtension(has_extension_);
|
// rtp_packet.SetHasExtension(has_extension_);
|
||||||
// rtp_packet.SetMarker(1);
|
// rtp_packet.SetMarker(1);
|
||||||
// rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_));
|
// rtp_packet.SetPayloadType(rtp::PAYLOAD_TYPE(payload_type_));
|
||||||
// rtp_packet.SetSequenceNumber(sequence_number_++);
|
// rtp_packet.SetSequenceNumber(sequence_number_++);
|
||||||
|
|
||||||
// timestamp_ = std::chrono::duration_cast<std::chrono::microseconds>(
|
// timestamp_ = std::chrono::duration_cast<std::chrono::microseconds>(
|
||||||
|
|||||||
@@ -38,6 +38,14 @@ class RtpPacketizerH264 : public RtpPacketizer {
|
|||||||
uint16_t extension_len_;
|
uint16_t extension_len_;
|
||||||
uint8_t* extension_data_;
|
uint8_t* extension_data_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// H.264 header
|
||||||
|
rtp::FU_INDICATOR fu_indicator_;
|
||||||
|
rtp::FU_HEADER fu_header_;
|
||||||
|
uint8_t fec_symbol_id_ = 0;
|
||||||
|
uint8_t fec_source_symbol_num_ = 0;
|
||||||
|
uint8_t av1_aggr_header_ = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<uint8_t> rtp_packet_frame_;
|
std::vector<uint8_t> rtp_packet_frame_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -54,14 +54,14 @@ int IceTransport::SetLocalCapabilities(bool hardware_acceleration,
|
|||||||
force_turn_ = force_turn;
|
force_turn_ = force_turn;
|
||||||
support_video_payload_types_ = video_payload_types;
|
support_video_payload_types_ = video_payload_types;
|
||||||
support_audio_payload_types_ = audio_payload_types;
|
support_audio_payload_types_ = audio_payload_types;
|
||||||
support_data_payload_types_ = {RtpPacket::PAYLOAD_TYPE::DATA};
|
support_data_payload_types_ = {rtp::PAYLOAD_TYPE::DATA};
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int IceTransport::InitIceTransmission(
|
int IceTransport::InitIceTransmission(
|
||||||
std::string &stun_ip, int stun_port, std::string &turn_ip, int turn_port,
|
std::string &stun_ip, int stun_port, std::string &turn_ip, int turn_port,
|
||||||
std::string &turn_username, std::string &turn_password,
|
std::string &turn_username, std::string &turn_password,
|
||||||
RtpPacket::PAYLOAD_TYPE video_codec_payload_type) {
|
rtp::PAYLOAD_TYPE video_codec_payload_type) {
|
||||||
ice_agent_ = std::make_unique<IceAgent>(
|
ice_agent_ = std::make_unique<IceAgent>(
|
||||||
offer_peer_, use_trickle_ice_, use_reliable_ice_, enable_turn_,
|
offer_peer_, use_trickle_ice_, use_reliable_ice_, enable_turn_,
|
||||||
force_turn_, stun_ip, stun_port, turn_ip, turn_port, turn_username,
|
force_turn_, stun_ip, stun_port, turn_ip, turn_port, turn_username,
|
||||||
@@ -116,7 +116,7 @@ void IceTransport::InitializeIOStatistics() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void IceTransport::InitializeChannels(
|
void IceTransport::InitializeChannels(
|
||||||
RtpPacket::PAYLOAD_TYPE video_codec_payload_type) {
|
rtp::PAYLOAD_TYPE video_codec_payload_type) {
|
||||||
video_codec_payload_type_ = video_codec_payload_type;
|
video_codec_payload_type_ = video_codec_payload_type;
|
||||||
|
|
||||||
video_channel_send_ =
|
video_channel_send_ =
|
||||||
@@ -127,14 +127,12 @@ void IceTransport::InitializeChannels(
|
|||||||
std::make_unique<DataChannelSend>(ice_agent_, ice_io_statistics_);
|
std::make_unique<DataChannelSend>(ice_agent_, ice_io_statistics_);
|
||||||
|
|
||||||
video_channel_send_->Initialize(video_codec_payload_type_);
|
video_channel_send_->Initialize(video_codec_payload_type_);
|
||||||
audio_channel_send_->Initialize(RtpPacket::PAYLOAD_TYPE::OPUS);
|
audio_channel_send_->Initialize(rtp::PAYLOAD_TYPE::OPUS);
|
||||||
data_channel_send_->Initialize(RtpPacket::PAYLOAD_TYPE::DATA);
|
data_channel_send_->Initialize(rtp::PAYLOAD_TYPE::DATA);
|
||||||
|
|
||||||
video_channel_receive_ = std::make_unique<VideoChannelReceive>(
|
video_channel_receive_ = std::make_unique<VideoChannelReceive>(
|
||||||
ice_agent_, ice_io_statistics_, [this](VideoFrame &video_frame) {
|
ice_agent_, ice_io_statistics_,
|
||||||
LOG_ERROR("ccccccc");
|
[this](VideoFrame &video_frame) { OnReceiveCompleteFrame(video_frame); });
|
||||||
OnReceiveCompleteFrame(video_frame);
|
|
||||||
});
|
|
||||||
|
|
||||||
audio_channel_receive_ = std::make_unique<AudioChannelReceive>(
|
audio_channel_receive_ = std::make_unique<AudioChannelReceive>(
|
||||||
ice_agent_, ice_io_statistics_, [this](const char *data, size_t size) {
|
ice_agent_, ice_io_statistics_, [this](const char *data, size_t size) {
|
||||||
@@ -147,8 +145,8 @@ void IceTransport::InitializeChannels(
|
|||||||
});
|
});
|
||||||
|
|
||||||
video_channel_receive_->Initialize(video_codec_payload_type_);
|
video_channel_receive_->Initialize(video_codec_payload_type_);
|
||||||
audio_channel_receive_->Initialize(RtpPacket::PAYLOAD_TYPE::OPUS);
|
audio_channel_receive_->Initialize(rtp::PAYLOAD_TYPE::OPUS);
|
||||||
data_channel_receive_->Initialize(RtpPacket::PAYLOAD_TYPE::DATA);
|
data_channel_receive_->Initialize(rtp::PAYLOAD_TYPE::DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IceTransport::OnIceStateChange(NiceAgent *agent, guint stream_id,
|
void IceTransport::OnIceStateChange(NiceAgent *agent, guint stream_id,
|
||||||
@@ -379,7 +377,6 @@ void IceTransport::OnReceiveCompleteFrame(VideoFrame &video_frame) {
|
|||||||
x_video_frame.width = video_frame.Width();
|
x_video_frame.width = video_frame.Width();
|
||||||
x_video_frame.height = video_frame.Height();
|
x_video_frame.height = video_frame.Height();
|
||||||
x_video_frame.size = video_frame.Size();
|
x_video_frame.size = video_frame.Size();
|
||||||
LOG_ERROR("ccccccc 2222222");
|
|
||||||
on_receive_video_(&x_video_frame, remote_user_id_.data(),
|
on_receive_video_(&x_video_frame, remote_user_id_.data(),
|
||||||
remote_user_id_.size(), user_data_);
|
remote_user_id_.size(), user_data_);
|
||||||
}
|
}
|
||||||
@@ -434,14 +431,7 @@ int IceTransport::DestroyIceTransmission() {
|
|||||||
return ice_agent_->DestroyIceAgent();
|
return ice_agent_->DestroyIceAgent();
|
||||||
}
|
}
|
||||||
|
|
||||||
int IceTransport::CreateMediaCodec() {
|
int IceTransport::CreateVideoCodec(rtp::PAYLOAD_TYPE video_pt,
|
||||||
video_rtp_codec_ = std::make_unique<RtpCodec>(negotiated_video_pt_);
|
|
||||||
audio_rtp_codec_ = std::make_unique<RtpCodec>(negotiated_audio_pt_);
|
|
||||||
data_rtp_codec_ = std::make_unique<RtpCodec>(negotiated_data_pt_);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int IceTransport::CreateVideoCodec(RtpPacket::PAYLOAD_TYPE video_pt,
|
|
||||||
bool hardware_acceleration) {
|
bool hardware_acceleration) {
|
||||||
if (video_codec_inited_) {
|
if (video_codec_inited_) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -449,14 +439,14 @@ int IceTransport::CreateVideoCodec(RtpPacket::PAYLOAD_TYPE video_pt,
|
|||||||
|
|
||||||
hardware_acceleration_ = hardware_acceleration;
|
hardware_acceleration_ = hardware_acceleration;
|
||||||
|
|
||||||
if (RtpPacket::PAYLOAD_TYPE::AV1 == video_pt) {
|
if (rtp::PAYLOAD_TYPE::AV1 == video_pt) {
|
||||||
if (hardware_acceleration_) {
|
if (hardware_acceleration_) {
|
||||||
hardware_acceleration_ = false;
|
hardware_acceleration_ = false;
|
||||||
LOG_WARN("Only support software codec for AV1");
|
LOG_WARN("Only support software codec for AV1");
|
||||||
}
|
}
|
||||||
video_encoder_ = VideoEncoderFactory::CreateVideoEncoder(false, true);
|
video_encoder_ = VideoEncoderFactory::CreateVideoEncoder(false, true);
|
||||||
video_decoder_ = VideoDecoderFactory::CreateVideoDecoder(false, true);
|
video_decoder_ = VideoDecoderFactory::CreateVideoDecoder(false, true);
|
||||||
} else if (RtpPacket::PAYLOAD_TYPE::H264 == video_pt) {
|
} else if (rtp::PAYLOAD_TYPE::H264 == video_pt) {
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
if (hardware_acceleration_) {
|
if (hardware_acceleration_) {
|
||||||
hardware_acceleration_ = false;
|
hardware_acceleration_ = false;
|
||||||
@@ -619,18 +609,18 @@ int IceTransport::AppendLocalCapabilitiesToOffer(
|
|||||||
std::string data_capabilities = "UDP/TLS/RTP/SAVPF 127";
|
std::string data_capabilities = "UDP/TLS/RTP/SAVPF 127";
|
||||||
|
|
||||||
switch (video_codec_payload_type_) {
|
switch (video_codec_payload_type_) {
|
||||||
case RtpPacket::PAYLOAD_TYPE::H264: {
|
case rtp::PAYLOAD_TYPE::H264: {
|
||||||
preferred_video_pt = std::to_string(RtpPacket::PAYLOAD_TYPE::H264);
|
preferred_video_pt = std::to_string(rtp::PAYLOAD_TYPE::H264);
|
||||||
video_capabilities += preferred_video_pt + " 97 98 99";
|
video_capabilities += preferred_video_pt + " 97 98 99";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RtpPacket::PAYLOAD_TYPE::AV1: {
|
case rtp::PAYLOAD_TYPE::AV1: {
|
||||||
preferred_video_pt = std::to_string(RtpPacket::PAYLOAD_TYPE::AV1);
|
preferred_video_pt = std::to_string(rtp::PAYLOAD_TYPE::AV1);
|
||||||
video_capabilities += preferred_video_pt + " 96 97 98";
|
video_capabilities += preferred_video_pt + " 96 97 98";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
preferred_video_pt = std::to_string(RtpPacket::PAYLOAD_TYPE::H264);
|
preferred_video_pt = std::to_string(rtp::PAYLOAD_TYPE::H264);
|
||||||
video_capabilities += preferred_video_pt + " 97 98 99";
|
video_capabilities += preferred_video_pt + " 97 98 99";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -734,7 +724,6 @@ std::string IceTransport::GetRemoteCapabilities(const std::string &remote_sdp) {
|
|||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateMediaCodec();
|
|
||||||
CreateVideoCodec(negotiated_video_pt_, hardware_acceleration_);
|
CreateVideoCodec(negotiated_video_pt_, hardware_acceleration_);
|
||||||
CreateAudioCodec();
|
CreateAudioCodec();
|
||||||
|
|
||||||
@@ -808,7 +797,7 @@ bool IceTransport::NegotiateVideoPayloadType(const std::string &remote_sdp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
remote_prefered_video_pt_ =
|
remote_prefered_video_pt_ =
|
||||||
(RtpPacket::PAYLOAD_TYPE)(atoi(remote_prefered_video_pt.c_str()));
|
(rtp::PAYLOAD_TYPE)(atoi(remote_prefered_video_pt.c_str()));
|
||||||
|
|
||||||
bool is_support_this_video_pt =
|
bool is_support_this_video_pt =
|
||||||
std::find(support_video_payload_types_.begin(),
|
std::find(support_video_payload_types_.begin(),
|
||||||
@@ -817,7 +806,7 @@ bool IceTransport::NegotiateVideoPayloadType(const std::string &remote_sdp) {
|
|||||||
support_video_payload_types_.end();
|
support_video_payload_types_.end();
|
||||||
|
|
||||||
if (is_support_this_video_pt) {
|
if (is_support_this_video_pt) {
|
||||||
negotiated_video_pt_ = (RtpPacket::PAYLOAD_TYPE)remote_prefered_video_pt_;
|
negotiated_video_pt_ = (rtp::PAYLOAD_TYPE)remote_prefered_video_pt_;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
if (prefered_pt_end != std::string::npos) {
|
if (prefered_pt_end != std::string::npos) {
|
||||||
@@ -828,7 +817,7 @@ bool IceTransport::NegotiateVideoPayloadType(const std::string &remote_sdp) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (negotiated_video_pt_ == RtpPacket::PAYLOAD_TYPE::UNDEFINED) {
|
if (negotiated_video_pt_ == rtp::PAYLOAD_TYPE::UNDEFINED) {
|
||||||
LOG_ERROR("Negotiate video pt failed");
|
LOG_ERROR("Negotiate video pt failed");
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
@@ -868,7 +857,7 @@ bool IceTransport::NegotiateAudioPayloadType(const std::string &remote_sdp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
remote_prefered_audio_pt_ =
|
remote_prefered_audio_pt_ =
|
||||||
(RtpPacket::PAYLOAD_TYPE)(atoi(remote_prefered_audio_pt.c_str()));
|
(rtp::PAYLOAD_TYPE)(atoi(remote_prefered_audio_pt.c_str()));
|
||||||
|
|
||||||
bool is_support_this_audio_pt =
|
bool is_support_this_audio_pt =
|
||||||
std::find(support_audio_payload_types_.begin(),
|
std::find(support_audio_payload_types_.begin(),
|
||||||
@@ -877,7 +866,7 @@ bool IceTransport::NegotiateAudioPayloadType(const std::string &remote_sdp) {
|
|||||||
support_audio_payload_types_.end();
|
support_audio_payload_types_.end();
|
||||||
|
|
||||||
if (is_support_this_audio_pt) {
|
if (is_support_this_audio_pt) {
|
||||||
negotiated_audio_pt_ = (RtpPacket::PAYLOAD_TYPE)remote_prefered_audio_pt_;
|
negotiated_audio_pt_ = (rtp::PAYLOAD_TYPE)remote_prefered_audio_pt_;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
if (prefered_pt_end != std::string::npos) {
|
if (prefered_pt_end != std::string::npos) {
|
||||||
@@ -888,7 +877,7 @@ bool IceTransport::NegotiateAudioPayloadType(const std::string &remote_sdp) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (negotiated_audio_pt_ == RtpPacket::PAYLOAD_TYPE::UNDEFINED) {
|
if (negotiated_audio_pt_ == rtp::PAYLOAD_TYPE::UNDEFINED) {
|
||||||
LOG_ERROR("Negotiate audio pt failed");
|
LOG_ERROR("Negotiate audio pt failed");
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
@@ -928,7 +917,7 @@ bool IceTransport::NegotiateDataPayloadType(const std::string &remote_sdp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
remote_prefered_data_pt_ =
|
remote_prefered_data_pt_ =
|
||||||
(RtpPacket::PAYLOAD_TYPE)(atoi(remote_prefered_data_pt.c_str()));
|
(rtp::PAYLOAD_TYPE)(atoi(remote_prefered_data_pt.c_str()));
|
||||||
|
|
||||||
bool is_support_this_data_pt =
|
bool is_support_this_data_pt =
|
||||||
std::find(support_data_payload_types_.begin(),
|
std::find(support_data_payload_types_.begin(),
|
||||||
@@ -937,7 +926,7 @@ bool IceTransport::NegotiateDataPayloadType(const std::string &remote_sdp) {
|
|||||||
support_data_payload_types_.end();
|
support_data_payload_types_.end();
|
||||||
|
|
||||||
if (is_support_this_data_pt) {
|
if (is_support_this_data_pt) {
|
||||||
negotiated_data_pt_ = (RtpPacket::PAYLOAD_TYPE)remote_prefered_data_pt_;
|
negotiated_data_pt_ = (rtp::PAYLOAD_TYPE)remote_prefered_data_pt_;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
if (prefered_pt_end != std::string::npos) {
|
if (prefered_pt_end != std::string::npos) {
|
||||||
@@ -948,7 +937,7 @@ bool IceTransport::NegotiateDataPayloadType(const std::string &remote_sdp) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (negotiated_data_pt_ == RtpPacket::PAYLOAD_TYPE::UNDEFINED) {
|
if (negotiated_data_pt_ == rtp::PAYLOAD_TYPE::UNDEFINED) {
|
||||||
LOG_ERROR("Negotiate data pt failed");
|
LOG_ERROR("Negotiate data pt failed");
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
@@ -957,7 +946,7 @@ bool IceTransport::NegotiateDataPayloadType(const std::string &remote_sdp) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<RtpPacket::PAYLOAD_TYPE> IceTransport::GetNegotiatedCapabilities() {
|
std::vector<rtp::PAYLOAD_TYPE> IceTransport::GetNegotiatedCapabilities() {
|
||||||
return {negotiated_video_pt_, negotiated_audio_pt_, negotiated_data_pt_};
|
return {negotiated_video_pt_, negotiated_audio_pt_, negotiated_data_pt_};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1068,10 +1057,10 @@ uint8_t IceTransport::CheckIsVideoPacket(const char *buffer, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t pt = buffer[1] & 0x7F;
|
uint8_t pt = buffer[1] & 0x7F;
|
||||||
if (RtpPacket::PAYLOAD_TYPE::H264 == pt ||
|
if (rtp::PAYLOAD_TYPE::H264 == pt ||
|
||||||
RtpPacket::PAYLOAD_TYPE::H264_FEC_SOURCE == pt ||
|
rtp::PAYLOAD_TYPE::H264_FEC_SOURCE == pt ||
|
||||||
RtpPacket::PAYLOAD_TYPE::H264_FEC_REPAIR == pt ||
|
rtp::PAYLOAD_TYPE::H264_FEC_REPAIR == pt ||
|
||||||
RtpPacket::PAYLOAD_TYPE::AV1 == pt) {
|
rtp::PAYLOAD_TYPE::AV1 == pt) {
|
||||||
return pt;
|
return pt;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1089,7 +1078,7 @@ uint8_t IceTransport::CheckIsAudioPacket(const char *buffer, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t pt = buffer[1] & 0x7F;
|
uint8_t pt = buffer[1] & 0x7F;
|
||||||
if (RtpPacket::PAYLOAD_TYPE::OPUS == pt) {
|
if (rtp::PAYLOAD_TYPE::OPUS == pt) {
|
||||||
return pt;
|
return pt;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1107,7 +1096,7 @@ uint8_t IceTransport::CheckIsDataPacket(const char *buffer, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t pt = buffer[1] & 0x7F;
|
uint8_t pt = buffer[1] & 0x7F;
|
||||||
if (RtpPacket::PAYLOAD_TYPE::DATA == pt) {
|
if (rtp::PAYLOAD_TYPE::DATA == pt) {
|
||||||
return pt;
|
return pt;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
#include "rtcp_packet_info.h"
|
#include "rtcp_packet_info.h"
|
||||||
#include "rtp_audio_receiver.h"
|
#include "rtp_audio_receiver.h"
|
||||||
#include "rtp_audio_sender.h"
|
#include "rtp_audio_sender.h"
|
||||||
#include "rtp_codec.h"
|
|
||||||
#include "rtp_data_receiver.h"
|
#include "rtp_data_receiver.h"
|
||||||
#include "rtp_data_sender.h"
|
#include "rtp_data_sender.h"
|
||||||
#include "rtp_packet.h"
|
#include "rtp_packet.h"
|
||||||
@@ -66,7 +65,7 @@ class IceTransport {
|
|||||||
std::string &turn_ip, int turn_port,
|
std::string &turn_ip, int turn_port,
|
||||||
std::string &turn_username,
|
std::string &turn_username,
|
||||||
std::string &turn_password,
|
std::string &turn_password,
|
||||||
RtpPacket::PAYLOAD_TYPE video_codec_payload_type);
|
rtp::PAYLOAD_TYPE video_codec_payload_type);
|
||||||
|
|
||||||
int DestroyIceTransmission();
|
int DestroyIceTransmission();
|
||||||
|
|
||||||
@@ -74,7 +73,6 @@ class IceTransport {
|
|||||||
std::function<void(const XVideoFrame *, const char *, const size_t,
|
std::function<void(const XVideoFrame *, const char *, const size_t,
|
||||||
void *)>
|
void *)>
|
||||||
on_receive_video) {
|
on_receive_video) {
|
||||||
LOG_ERROR("!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
|
||||||
on_receive_video_ = on_receive_video;
|
on_receive_video_ = on_receive_video;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +119,7 @@ class IceTransport {
|
|||||||
|
|
||||||
int SendAnswer();
|
int SendAnswer();
|
||||||
|
|
||||||
std::vector<RtpPacket::PAYLOAD_TYPE> GetNegotiatedCapabilities();
|
std::vector<rtp::PAYLOAD_TYPE> GetNegotiatedCapabilities();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int AppendLocalCapabilitiesToOffer(const std::string &remote_sdp);
|
int AppendLocalCapabilitiesToOffer(const std::string &remote_sdp);
|
||||||
@@ -132,10 +130,7 @@ class IceTransport {
|
|||||||
bool NegotiateAudioPayloadType(const std::string &remote_sdp);
|
bool NegotiateAudioPayloadType(const std::string &remote_sdp);
|
||||||
bool NegotiateDataPayloadType(const std::string &remote_sdp);
|
bool NegotiateDataPayloadType(const std::string &remote_sdp);
|
||||||
|
|
||||||
int CreateMediaCodec();
|
int CreateVideoCodec(rtp::PAYLOAD_TYPE video_pt, bool hardware_acceleration);
|
||||||
|
|
||||||
int CreateVideoCodec(RtpPacket::PAYLOAD_TYPE video_pt,
|
|
||||||
bool hardware_acceleration);
|
|
||||||
int CreateAudioCodec();
|
int CreateAudioCodec();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -148,7 +143,7 @@ class IceTransport {
|
|||||||
private:
|
private:
|
||||||
void InitializeIOStatistics();
|
void InitializeIOStatistics();
|
||||||
|
|
||||||
void InitializeChannels(RtpPacket::PAYLOAD_TYPE video_codec_payload_type);
|
void InitializeChannels(rtp::PAYLOAD_TYPE video_codec_payload_type);
|
||||||
|
|
||||||
void OnIceStateChange(NiceAgent *agent, guint stream_id, guint component_id,
|
void OnIceStateChange(NiceAgent *agent, guint stream_id, guint component_id,
|
||||||
NiceComponentState state, gpointer user_ptr);
|
NiceComponentState state, gpointer user_ptr);
|
||||||
@@ -231,10 +226,6 @@ class IceTransport {
|
|||||||
std::unique_ptr<DataChannelSend> data_channel_send_ = nullptr;
|
std::unique_ptr<DataChannelSend> data_channel_send_ = nullptr;
|
||||||
std::unique_ptr<DataChannelReceive> data_channel_receive_ = nullptr;
|
std::unique_ptr<DataChannelReceive> data_channel_receive_ = nullptr;
|
||||||
|
|
||||||
std::unique_ptr<RtpCodec> video_rtp_codec_ = nullptr;
|
|
||||||
std::unique_ptr<RtpCodec> audio_rtp_codec_ = nullptr;
|
|
||||||
std::unique_ptr<RtpCodec> data_rtp_codec_ = nullptr;
|
|
||||||
|
|
||||||
std::unique_ptr<RtpVideoReceiver> rtp_video_receiver_ = nullptr;
|
std::unique_ptr<RtpVideoReceiver> rtp_video_receiver_ = nullptr;
|
||||||
std::unique_ptr<RtpVideoSender> rtp_video_sender_ = nullptr;
|
std::unique_ptr<RtpVideoSender> rtp_video_sender_ = nullptr;
|
||||||
std::unique_ptr<RtpAudioReceiver> rtp_audio_receiver_ = nullptr;
|
std::unique_ptr<RtpAudioReceiver> rtp_audio_receiver_ = nullptr;
|
||||||
@@ -249,20 +240,14 @@ class IceTransport {
|
|||||||
std::shared_ptr<IOStatistics> ice_io_statistics_ = nullptr;
|
std::shared_ptr<IOStatistics> ice_io_statistics_ = nullptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RtpPacket::PAYLOAD_TYPE video_codec_payload_type_;
|
rtp::PAYLOAD_TYPE video_codec_payload_type_;
|
||||||
bool remote_capabilities_got_ = false;
|
bool remote_capabilities_got_ = false;
|
||||||
RtpPacket::PAYLOAD_TYPE remote_prefered_video_pt_ =
|
rtp::PAYLOAD_TYPE remote_prefered_video_pt_ = rtp::PAYLOAD_TYPE::UNDEFINED;
|
||||||
RtpPacket::PAYLOAD_TYPE::UNDEFINED;
|
rtp::PAYLOAD_TYPE remote_prefered_audio_pt_ = rtp::PAYLOAD_TYPE::UNDEFINED;
|
||||||
RtpPacket::PAYLOAD_TYPE remote_prefered_audio_pt_ =
|
rtp::PAYLOAD_TYPE remote_prefered_data_pt_ = rtp::PAYLOAD_TYPE::UNDEFINED;
|
||||||
RtpPacket::PAYLOAD_TYPE::UNDEFINED;
|
rtp::PAYLOAD_TYPE negotiated_video_pt_ = rtp::PAYLOAD_TYPE::UNDEFINED;
|
||||||
RtpPacket::PAYLOAD_TYPE remote_prefered_data_pt_ =
|
rtp::PAYLOAD_TYPE negotiated_audio_pt_ = rtp::PAYLOAD_TYPE::UNDEFINED;
|
||||||
RtpPacket::PAYLOAD_TYPE::UNDEFINED;
|
rtp::PAYLOAD_TYPE negotiated_data_pt_ = rtp::PAYLOAD_TYPE::UNDEFINED;
|
||||||
RtpPacket::PAYLOAD_TYPE negotiated_video_pt_ =
|
|
||||||
RtpPacket::PAYLOAD_TYPE::UNDEFINED;
|
|
||||||
RtpPacket::PAYLOAD_TYPE negotiated_audio_pt_ =
|
|
||||||
RtpPacket::PAYLOAD_TYPE::UNDEFINED;
|
|
||||||
RtpPacket::PAYLOAD_TYPE negotiated_data_pt_ =
|
|
||||||
RtpPacket::PAYLOAD_TYPE::UNDEFINED;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<VideoEncoder> video_encoder_ = nullptr;
|
std::unique_ptr<VideoEncoder> video_encoder_ = nullptr;
|
||||||
|
|||||||
@@ -107,9 +107,11 @@ target("rtp")
|
|||||||
set_kind("object")
|
set_kind("object")
|
||||||
add_deps("log", "common", "frame", "ringbuffer", "thread", "rtcp", "fec", "statistics")
|
add_deps("log", "common", "frame", "ringbuffer", "thread", "rtcp", "fec", "statistics")
|
||||||
add_files("src/rtp/*.cpp",
|
add_files("src/rtp/*.cpp",
|
||||||
"src/rtp/rtp_packet/*.cpp")
|
"src/rtp/rtp_packet/*.cpp",
|
||||||
|
"src/rtp/rtp_packetizer/*.cpp")
|
||||||
add_includedirs("src/rtp",
|
add_includedirs("src/rtp",
|
||||||
"src/rtp/rtp_packet", {public = true})
|
"src/rtp/rtp_packet",
|
||||||
|
"src/rtp/rtp_packetizer", {public = true})
|
||||||
|
|
||||||
target("rtcp")
|
target("rtcp")
|
||||||
set_kind("object")
|
set_kind("object")
|
||||||
|
|||||||
Reference in New Issue
Block a user