diff --git a/src/channel/audio_channel_receive.cpp b/src/channel/audio_channel_receive.cpp index 13d082c..bc2080d 100644 --- a/src/channel/audio_channel_receive.cpp +++ b/src/channel/audio_channel_receive.cpp @@ -14,10 +14,8 @@ AudioChannelReceive::AudioChannelReceive( AudioChannelReceive::~AudioChannelReceive() {} -void AudioChannelReceive::Initialize(RtpPacket::PAYLOAD_TYPE payload_type) { - audio_rtp_codec_ = std::make_unique(payload_type); +void AudioChannelReceive::Initialize(rtp::PAYLOAD_TYPE payload_type) { rtp_audio_receiver_ = std::make_unique(ice_io_statistics_); - rtp_audio_receiver_->SetOnReceiveData( [this](const char *data, size_t size) -> void { if (on_receive_audio_) { @@ -54,7 +52,9 @@ int AudioChannelReceive::OnReceiveRtpPacket(const char *data, size_t size) { } 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; diff --git a/src/channel/audio_channel_receive.h b/src/channel/audio_channel_receive.h index 4e1579d..074ba45 100644 --- a/src/channel/audio_channel_receive.h +++ b/src/channel/audio_channel_receive.h @@ -9,7 +9,6 @@ #include "ice_agent.h" #include "rtp_audio_receiver.h" -#include "rtp_codec.h" class AudioChannelReceive { public: @@ -21,14 +20,13 @@ class AudioChannelReceive { ~AudioChannelReceive(); public: - void Initialize(RtpPacket::PAYLOAD_TYPE payload_type); + void Initialize(rtp::PAYLOAD_TYPE payload_type); void Destroy(); int OnReceiveRtpPacket(const char *data, size_t size); private: std::shared_ptr ice_agent_ = nullptr; std::shared_ptr ice_io_statistics_ = nullptr; - std::unique_ptr audio_rtp_codec_ = nullptr; std::unique_ptr rtp_audio_receiver_ = nullptr; std::function on_receive_audio_ = nullptr; }; diff --git a/src/channel/audio_channel_send.cpp b/src/channel/audio_channel_send.cpp index fed7728..a7c66b1 100644 --- a/src/channel/audio_channel_send.cpp +++ b/src/channel/audio_channel_send.cpp @@ -11,9 +11,8 @@ AudioChannelSend::AudioChannelSend( std::shared_ptr ice_io_statistics) : ice_agent_(ice_agent), ice_io_statistics_(ice_io_statistics) {} -void AudioChannelSend::Initialize(RtpPacket::PAYLOAD_TYPE payload_type) { - audio_rtp_codec_ = std::make_unique(payload_type); - +void AudioChannelSend::Initialize(rtp::PAYLOAD_TYPE payload_type) { + rtp_packetizer_ = RtpPacketizer::Create(payload_type); rtp_audio_sender_ = std::make_unique(ice_io_statistics_); rtp_audio_sender_->SetSendDataFunc( [this](const char *data, size_t size) -> int { @@ -45,10 +44,10 @@ void AudioChannelSend::Destroy() { } int AudioChannelSend::SendAudio(char *data, size_t size) { - if (audio_rtp_codec_) { - std::vector packets; - audio_rtp_codec_->Encode((uint8_t *)data, (uint32_t)size, packets); - rtp_audio_sender_->Enqueue(packets); + if (rtp_audio_sender_ && rtp_packetizer_) { + std::vector rtp_packets = + rtp_packetizer_->Build((uint8_t *)data, (uint32_t)size); + rtp_audio_sender_->Enqueue(rtp_packets); } return 0; diff --git a/src/channel/audio_channel_send.h b/src/channel/audio_channel_send.h index 2824f3b..6bb3477 100644 --- a/src/channel/audio_channel_send.h +++ b/src/channel/audio_channel_send.h @@ -9,7 +9,7 @@ #include "ice_agent.h" #include "rtp_audio_sender.h" -#include "rtp_codec.h" +#include "rtp_packetizer.h" class AudioChannelSend { public: @@ -19,14 +19,14 @@ class AudioChannelSend { ~AudioChannelSend(); public: - void Initialize(RtpPacket::PAYLOAD_TYPE payload_type); + void Initialize(rtp::PAYLOAD_TYPE payload_type); void Destroy(); int SendAudio(char *data, size_t size); private: std::shared_ptr ice_agent_ = nullptr; std::shared_ptr ice_io_statistics_ = nullptr; - std::unique_ptr audio_rtp_codec_ = nullptr; + std::unique_ptr rtp_packetizer_ = nullptr; std::unique_ptr rtp_audio_sender_ = nullptr; }; diff --git a/src/channel/data_channel_receive.cpp b/src/channel/data_channel_receive.cpp index 9edfa07..4cb1fb1 100644 --- a/src/channel/data_channel_receive.cpp +++ b/src/channel/data_channel_receive.cpp @@ -14,11 +14,8 @@ DataChannelReceive::DataChannelReceive( DataChannelReceive::~DataChannelReceive() {} -void DataChannelReceive::Initialize(RtpPacket::PAYLOAD_TYPE payload_type) { - data_rtp_codec_ = std::make_unique(payload_type); - +void DataChannelReceive::Initialize(rtp::PAYLOAD_TYPE payload_type) { rtp_data_receiver_ = std::make_unique(ice_io_statistics_); - rtp_data_receiver_->SetOnReceiveData( [this](const char *data, size_t size) -> void { if (on_receive_data_) { @@ -55,7 +52,9 @@ int DataChannelReceive::OnReceiveRtpPacket(const char *data, size_t size) { } 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; diff --git a/src/channel/data_channel_receive.h b/src/channel/data_channel_receive.h index 4dc7485..a887ec2 100644 --- a/src/channel/data_channel_receive.h +++ b/src/channel/data_channel_receive.h @@ -8,7 +8,6 @@ #define _DATA_CHANNEL_RECEIVE_H_ #include "ice_agent.h" -#include "rtp_codec.h" #include "rtp_data_receiver.h" class DataChannelReceive { @@ -20,14 +19,13 @@ class DataChannelReceive { ~DataChannelReceive(); public: - void Initialize(RtpPacket::PAYLOAD_TYPE payload_type); + void Initialize(rtp::PAYLOAD_TYPE payload_type); void Destroy(); int OnReceiveRtpPacket(const char *data, size_t size); private: std::shared_ptr ice_agent_ = nullptr; std::shared_ptr ice_io_statistics_ = nullptr; - std::unique_ptr data_rtp_codec_ = nullptr; std::unique_ptr rtp_data_receiver_ = nullptr; std::function on_receive_data_ = nullptr; }; diff --git a/src/channel/data_channel_send.cpp b/src/channel/data_channel_send.cpp index 1be5abe..c79cc6a 100644 --- a/src/channel/data_channel_send.cpp +++ b/src/channel/data_channel_send.cpp @@ -11,9 +11,8 @@ DataChannelSend::DataChannelSend( std::shared_ptr ice_io_statistics) : ice_agent_(ice_agent), ice_io_statistics_(ice_io_statistics) {} -void DataChannelSend::Initialize(RtpPacket::PAYLOAD_TYPE payload_type) { - data_rtp_codec_ = std::make_unique(payload_type); - +void DataChannelSend::Initialize(rtp::PAYLOAD_TYPE payload_type) { + rtp_packetizer_ = RtpPacketizer::Create(payload_type); rtp_data_sender_ = std::make_unique(ice_io_statistics_); rtp_data_sender_->SetSendDataFunc( [this](const char *data, size_t size) -> int { @@ -45,13 +44,10 @@ void DataChannelSend::Destroy() { } int DataChannelSend::SendData(const char *data, size_t size) { - std::vector packets; - - if (rtp_data_sender_) { - if (data_rtp_codec_) { - data_rtp_codec_->Encode((uint8_t *)data, (uint32_t)size, packets); - rtp_data_sender_->Enqueue(packets); - } + if (rtp_data_sender_ && rtp_packetizer_) { + std::vector rtp_packets = + rtp_packetizer_->Build((uint8_t *)data, (uint32_t)size); + rtp_data_sender_->Enqueue(rtp_packets); } return 0; diff --git a/src/channel/data_channel_send.h b/src/channel/data_channel_send.h index 076c9e1..9022037 100644 --- a/src/channel/data_channel_send.h +++ b/src/channel/data_channel_send.h @@ -8,8 +8,8 @@ #define _DATA_CHANNEL_SEND_H_ #include "ice_agent.h" -#include "rtp_codec.h" #include "rtp_data_sender.h" +#include "rtp_packetizer.h" class DataChannelSend { public: @@ -19,14 +19,14 @@ class DataChannelSend { ~DataChannelSend(); public: - void Initialize(RtpPacket::PAYLOAD_TYPE payload_type); + void Initialize(rtp::PAYLOAD_TYPE payload_type); void Destroy(); int SendData(const char *data, size_t size); private: std::shared_ptr ice_agent_ = nullptr; std::shared_ptr ice_io_statistics_ = nullptr; - std::unique_ptr data_rtp_codec_ = nullptr; + std::unique_ptr rtp_packetizer_ = nullptr; std::unique_ptr rtp_data_sender_ = nullptr; }; diff --git a/src/channel/rtp_channel/rtp_audio_receiver.h b/src/channel/rtp_channel/rtp_audio_receiver.h index 3167f6a..32f9d3f 100644 --- a/src/channel/rtp_channel/rtp_audio_receiver.h +++ b/src/channel/rtp_channel/rtp_audio_receiver.h @@ -11,7 +11,7 @@ #include "io_statistics.h" #include "rtcp_receiver_report.h" -#include "rtp_codec.h" +#include "rtp_packet.h" #include "rtp_statistics.h" class RtpAudioReceiver { diff --git a/src/channel/rtp_channel/rtp_audio_sender.cpp b/src/channel/rtp_channel/rtp_audio_sender.cpp index b24ba38..b9fc7e2 100644 --- a/src/channel/rtp_channel/rtp_audio_sender.cpp +++ b/src/channel/rtp_channel/rtp_audio_sender.cpp @@ -39,8 +39,8 @@ int RtpAudioSender::SendRtpPacket(RtpPacket& rtp_packet) { return -1; } - if (0 != - data_send_func_((const char*)rtp_packet.Buffer(), rtp_packet.Size())) { + if (0 != data_send_func_((const char*)rtp_packet.Buffer().data(), + rtp_packet.Size())) { LOG_ERROR("Send rtp packet failed"); return -1; } diff --git a/src/channel/rtp_channel/rtp_data_receiver.h b/src/channel/rtp_channel/rtp_data_receiver.h index f9ed875..d635ebc 100644 --- a/src/channel/rtp_channel/rtp_data_receiver.h +++ b/src/channel/rtp_channel/rtp_data_receiver.h @@ -5,7 +5,7 @@ #include "io_statistics.h" #include "rtcp_receiver_report.h" -#include "rtp_codec.h" +#include "rtp_packet.h" #include "rtp_statistics.h" class RtpDataReceiver { diff --git a/src/channel/rtp_channel/rtp_data_sender.cpp b/src/channel/rtp_channel/rtp_data_sender.cpp index 15bea07..4f52ee1 100644 --- a/src/channel/rtp_channel/rtp_data_sender.cpp +++ b/src/channel/rtp_channel/rtp_data_sender.cpp @@ -39,8 +39,8 @@ int RtpDataSender::SendRtpPacket(RtpPacket& rtp_packet) { return -1; } - if (0 != - data_send_func_((const char*)rtp_packet.Buffer(), rtp_packet.Size())) { + if (0 != data_send_func_((const char*)rtp_packet.Buffer().data(), + rtp_packet.Size())) { LOG_ERROR("Send rtp packet failed"); return -1; } diff --git a/src/channel/rtp_channel/rtp_video_receiver.cpp b/src/channel/rtp_channel/rtp_video_receiver.cpp index fa625be..e6d326a 100644 --- a/src/channel/rtp_channel/rtp_video_receiver.cpp +++ b/src/channel/rtp_channel/rtp_video_receiver.cpp @@ -57,7 +57,7 @@ void RtpVideoReceiver::InsertRtpPacket(RtpPacket& rtp_packet) { } 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_ecn(EcnMarking::kEct0); @@ -109,137 +109,152 @@ void RtpVideoReceiver::InsertRtpPacket(RtpPacket& rtp_packet) { // SendRtcpRR(rtcp_rr); } - if (rtp_packet.PayloadType() == RtpPacket::PAYLOAD_TYPE::AV1) { - ProcessAv1RtpPacket(rtp_packet); + if (rtp_packet.PayloadType() == rtp::PAYLOAD_TYPE::AV1) { + RtpPacketAv1 rtp_packet_av1; + rtp_packet_av1.Build(rtp_packet.Buffer().data(), rtp_packet.Size()); + rtp_packet_av1.GetFrameHeaderInfo(); + ProcessAv1RtpPacket(rtp_packet_av1); } 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 (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 (rtp::PAYLOAD_TYPE::H264 == rtp_packet_h264.PayloadType()) { + rtp::NAL_UNIT_TYPE nalu_type = rtp_packet_h264.NalUnitType(); + if (rtp::NAL_UNIT_TYPE::NALU == nalu_type) { + compelete_video_frame_queue_.push(VideoFrame( + rtp_packet_h264.Payload(), rtp_packet_h264.PayloadSize())); + } else if (rtp::NAL_UNIT_TYPE::FU_A == nalu_type) { + incomplete_h264_frame_list_[rtp_packet_h264.SequenceNumber()] = + rtp_packet_h264; + bool complete = CheckIsH264FrameCompleted(rtp_packet_h264); 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_ = {}", // rtp_packet.PayloadSize(), rtp_packet.SequenceNumber()); - if (RtpPacket::PAYLOAD_TYPE::AV1 == rtp_packet.PayloadType()) { - incomplete_frame_list_[rtp_packet.SequenceNumber()] = rtp_packet; - bool complete = CheckIsAv1FrameCompleted(rtp_packet); + if (rtp::PAYLOAD_TYPE::AV1 == rtp_packet_av1.PayloadType()) { + incomplete_av1_frame_list_[rtp_packet_av1.SequenceNumber()] = + rtp_packet_av1; + bool complete = CheckIsAv1FrameCompleted(rtp_packet_av1); if (!complete) { } } @@ -253,13 +268,13 @@ void RtpVideoReceiver::ProcessAv1RtpPacket(RtpPacket& rtp_packet) { // } } -bool RtpVideoReceiver::CheckIsH264FrameCompleted(RtpPacket& rtp_packet) { - if (rtp_packet.FuAEnd()) { - uint16_t end_seq = rtp_packet.SequenceNumber(); - +bool RtpVideoReceiver::CheckIsH264FrameCompleted( + RtpPacketH264& rtp_packet_h264) { + if (rtp_packet_h264.FuAEnd()) { + uint16_t end_seq = rtp_packet_h264.SequenceNumber(); while (end_seq--) { - auto it = incomplete_frame_list_.find(end_seq); - if (it == incomplete_frame_list_.end()) { + auto it = incomplete_h264_frame_list_.find(end_seq); + if (it == incomplete_h264_frame_list_.end()) { // The last fragment has already received. If all fragments are in // order, then some fragments lost in tranmission and need to be // repaired using FEC @@ -272,16 +287,16 @@ bool RtpVideoReceiver::CheckIsH264FrameCompleted(RtpPacket& rtp_packet) { } size_t complete_frame_size = 0; - for (uint16_t start = it->first; start <= rtp_packet.SequenceNumber(); - start++) { + for (uint16_t start = it->first; + start <= rtp_packet_h264.SequenceNumber(); start++) { memcpy(nv12_data_ + complete_frame_size, - incomplete_frame_list_[start].Payload(), - incomplete_frame_list_[start].PayloadSize()); + incomplete_h264_frame_list_[start].Payload(), + incomplete_h264_frame_list_[start].PayloadSize()); - complete_frame_size += incomplete_frame_list_[start].PayloadSize(); - incomplete_frame_list_.erase(start); + complete_frame_size += + incomplete_h264_frame_list_[start].PayloadSize(); + incomplete_h264_frame_list_.erase(start); } - compelete_video_frame_queue_.push( VideoFrame(nv12_data_, complete_frame_size)); @@ -297,13 +312,13 @@ bool RtpVideoReceiver::CheckIsH264FrameCompleted(RtpPacket& rtp_packet) { return false; } -bool RtpVideoReceiver::CheckIsAv1FrameCompleted(RtpPacket& rtp_packet) { - if (rtp_packet.Av1FrameEnd()) { - uint16_t end_seq = rtp_packet.SequenceNumber(); +bool RtpVideoReceiver::CheckIsAv1FrameCompleted(RtpPacketAv1& rtp_packet_av1) { + if (rtp_packet_av1.Av1FrameEnd()) { + uint16_t end_seq = rtp_packet_av1.SequenceNumber(); uint16_t start = end_seq; while (end_seq--) { - auto it = incomplete_frame_list_.find(end_seq); - if (it == incomplete_frame_list_.end()) { + auto it = incomplete_av1_frame_list_.find(end_seq); + if (it == incomplete_av1_frame_list_.end()) { // The last fragment has already received. If all fragments are in // order, then some fragments lost in tranmission and need to be // 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_) { nv12_data_ = new uint8_t[NV12_BUFFER_SIZE]; } size_t complete_frame_size = 0; - for (; start <= rtp_packet.SequenceNumber(); start++) { - const uint8_t* obu_frame = incomplete_frame_list_[start].Payload(); - size_t obu_frame_size = incomplete_frame_list_[start].PayloadSize(); + for (; start <= rtp_packet_av1.SequenceNumber(); start++) { + const uint8_t* obu_frame = incomplete_av1_frame_list_[start].Payload(); + size_t obu_frame_size = incomplete_av1_frame_list_[start].PayloadSize(); memcpy(nv12_data_ + complete_frame_size, obu_frame, 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( diff --git a/src/channel/rtp_channel/rtp_video_receiver.h b/src/channel/rtp_channel/rtp_video_receiver.h index 610c60c..05237f5 100644 --- a/src/channel/rtp_channel/rtp_video_receiver.h +++ b/src/channel/rtp_channel/rtp_video_receiver.h @@ -12,7 +12,8 @@ #include "receive_side_congestion_controller.h" #include "ringbuffer.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_statistics.h" #include "thread_base.h" @@ -37,12 +38,12 @@ class RtpVideoReceiver : public ThreadBase { } private: - void ProcessAv1RtpPacket(RtpPacket& rtp_packet); - bool CheckIsAv1FrameCompleted(RtpPacket& rtp_packet); + void ProcessAv1RtpPacket(RtpPacketAv1& rtp_packet_av1); + bool CheckIsAv1FrameCompleted(RtpPacketAv1& rtp_packet_av1); private: - void ProcessH264RtpPacket(RtpPacket& rtp_packet); - bool CheckIsH264FrameCompleted(RtpPacket& rtp_packet); + void ProcessH264RtpPacket(RtpPacketH264& rtp_packet_h264); + bool CheckIsH264FrameCompleted(RtpPacketH264& rtp_packet_h264); private: bool CheckIsTimeSendRR(); @@ -58,6 +59,8 @@ class RtpVideoReceiver : public ThreadBase { void RtcpThread(); private: + std::map incomplete_h264_frame_list_; + std::map incomplete_av1_frame_list_; std::map incomplete_frame_list_; uint8_t* nv12_data_ = nullptr; std::function on_receive_complete_frame_ = nullptr; diff --git a/src/channel/rtp_channel/rtp_video_sender.cpp b/src/channel/rtp_channel/rtp_video_sender.cpp index 487b333..9cad148 100644 --- a/src/channel/rtp_channel/rtp_video_sender.cpp +++ b/src/channel/rtp_channel/rtp_video_sender.cpp @@ -39,8 +39,8 @@ int RtpVideoSender::SendRtpPacket(RtpPacket& rtp_packet) { return -1; } - if (0 != - data_send_func_((const char*)rtp_packet.Buffer(), rtp_packet.Size())) { + if (0 != data_send_func_((const char*)rtp_packet.Buffer().data(), + rtp_packet.Size())) { LOG_ERROR("Send rtp packet failed"); return -1; } diff --git a/src/channel/video_channel_receive.cpp b/src/channel/video_channel_receive.cpp index 82e4e0c..bce4875 100644 --- a/src/channel/video_channel_receive.cpp +++ b/src/channel/video_channel_receive.cpp @@ -14,10 +14,8 @@ VideoChannelReceive::VideoChannelReceive( VideoChannelReceive::~VideoChannelReceive() {} -void VideoChannelReceive::Initialize(RtpPacket::PAYLOAD_TYPE payload_type) { - video_rtp_codec_ = std::make_unique(payload_type); +void VideoChannelReceive::Initialize(rtp::PAYLOAD_TYPE payload_type) { rtp_video_receiver_ = std::make_unique(ice_io_statistics_); - rtp_video_receiver_->SetOnReceiveCompleteFrame( [this](VideoFrame &video_frame) -> void { on_receive_complete_frame_(video_frame); @@ -54,7 +52,9 @@ int VideoChannelReceive::OnReceiveRtpPacket(const char *data, size_t size) { } 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; diff --git a/src/channel/video_channel_receive.h b/src/channel/video_channel_receive.h index 93e4520..8b9c5fd 100644 --- a/src/channel/video_channel_receive.h +++ b/src/channel/video_channel_receive.h @@ -8,7 +8,6 @@ #define _VIDEO_CHANNEL_RECEIVE_H_ #include "ice_agent.h" -#include "rtp_codec.h" #include "rtp_video_receiver.h" class VideoChannelReceive { @@ -22,7 +21,7 @@ class VideoChannelReceive { ~VideoChannelReceive(); public: - void Initialize(RtpPacket::PAYLOAD_TYPE payload_type); + void Initialize(rtp::PAYLOAD_TYPE payload_type); void Destroy(); int OnReceiveRtpPacket(const char *data, size_t size); @@ -30,7 +29,6 @@ class VideoChannelReceive { private: std::shared_ptr ice_agent_ = nullptr; std::shared_ptr ice_io_statistics_ = nullptr; - std::unique_ptr video_rtp_codec_ = nullptr; std::unique_ptr rtp_video_receiver_ = nullptr; std::function on_receive_complete_frame_ = nullptr; }; diff --git a/src/channel/video_channel_send.cpp b/src/channel/video_channel_send.cpp index 55e0eef..2bda4ba 100644 --- a/src/channel/video_channel_send.cpp +++ b/src/channel/video_channel_send.cpp @@ -11,9 +11,8 @@ VideoChannelSend::VideoChannelSend( std::shared_ptr ice_io_statistics) : ice_agent_(ice_agent), ice_io_statistics_(ice_io_statistics){}; -void VideoChannelSend::Initialize(RtpPacket::PAYLOAD_TYPE payload_type) { - video_rtp_codec_ = std::make_unique(payload_type); - +void VideoChannelSend::Initialize(rtp::PAYLOAD_TYPE payload_type) { + rtp_packetizer_ = RtpPacketizer::Create(payload_type); rtp_video_sender_ = std::make_unique(ice_io_statistics_); rtp_video_sender_->SetSendDataFunc( [this](const char* data, size_t size) -> int { @@ -45,12 +44,10 @@ void VideoChannelSend::Destroy() { } int VideoChannelSend::SendVideo(char* data, size_t size) { - std::vector packets; - if (rtp_video_sender_) { - if (video_rtp_codec_) { - video_rtp_codec_->Encode((uint8_t*)data, (uint32_t)size, packets); - } - rtp_video_sender_->Enqueue(packets); + if (rtp_video_sender_ && rtp_packetizer_) { + std::vector rtp_packets = + rtp_packetizer_->Build((uint8_t*)data, (uint32_t)size); + rtp_video_sender_->Enqueue(rtp_packets); } return 0; diff --git a/src/channel/video_channel_send.h b/src/channel/video_channel_send.h index 225fae7..8989590 100644 --- a/src/channel/video_channel_send.h +++ b/src/channel/video_channel_send.h @@ -9,7 +9,7 @@ #include "congestion_control_feedback.h" #include "ice_agent.h" -#include "rtp_codec.h" +#include "rtp_packetizer.h" #include "rtp_video_sender.h" #include "transport_feedback.h" #include "transport_feedback_adapter.h" @@ -22,7 +22,7 @@ class VideoChannelSend { ~VideoChannelSend(); public: - void Initialize(RtpPacket::PAYLOAD_TYPE payload_type); + void Initialize(rtp::PAYLOAD_TYPE payload_type); void Destroy(); int SendVideo(char* data, size_t size); @@ -36,7 +36,7 @@ class VideoChannelSend { private: std::shared_ptr ice_agent_ = nullptr; std::shared_ptr ice_io_statistics_ = nullptr; - std::unique_ptr video_rtp_codec_ = nullptr; + std::unique_ptr rtp_packetizer_ = nullptr; std::unique_ptr rtp_video_sender_ = nullptr; private: diff --git a/src/common/copy_on_write_buffer.h b/src/common/copy_on_write_buffer.h index fb3b69b..16aacfb 100644 --- a/src/common/copy_on_write_buffer.h +++ b/src/common/copy_on_write_buffer.h @@ -13,6 +13,9 @@ class CopyOnWriteBuffer { public: CopyOnWriteBuffer() = default; + CopyOnWriteBuffer(size_t size) { + buffer_ = std::make_shared>(size); + } CopyOnWriteBuffer(const CopyOnWriteBuffer& other) = default; CopyOnWriteBuffer(CopyOnWriteBuffer&& other) noexcept = default; CopyOnWriteBuffer& operator=(const CopyOnWriteBuffer& other) = default; diff --git a/src/media/video/decode/nvcodec/nvidia_video_decoder.cpp b/src/media/video/decode/nvcodec/nvidia_video_decoder.cpp index 860e9a5..3b672e2 100644 --- a/src/media/video/decode/nvcodec/nvidia_video_decoder.cpp +++ b/src/media/video/decode/nvcodec/nvidia_video_decoder.cpp @@ -66,11 +66,9 @@ int NvidiaVideoDecoder::Init() { int NvidiaVideoDecoder::Decode( const uint8_t *data, size_t size, std::function on_receive_decoded_frame) { - LOG_ERROR("1"); if (!decoder) { return -1; } - LOG_ERROR("2"); #ifdef SAVE_RECEIVED_H264_STREAM fwrite((unsigned char *)data, 1, size, file_h264_); #endif @@ -80,14 +78,11 @@ int NvidiaVideoDecoder::Decode( } int num_frame_returned = decoder->Decode(data, (int)size); - LOG_ERROR("???? {}", num_frame_returned); for (size_t i = 0; i < num_frame_returned; ++i) { cudaVideoSurfaceFormat format = decoder->GetOutputFormat(); - LOG_ERROR("3"); if (format == cudaVideoSurfaceFormat_NV12) { uint8_t *decoded_frame_buffer = nullptr; decoded_frame_buffer = decoder->GetFrame(); - LOG_ERROR("4"); if (decoded_frame_buffer) { if (on_receive_decoded_frame) { VideoFrame decoded_frame( diff --git a/src/pc/peer_connection.cpp b/src/pc/peer_connection.cpp index 62ff042..3b5a8c0 100644 --- a/src/pc/peer_connection.cpp +++ b/src/pc/peer_connection.cpp @@ -616,7 +616,7 @@ void PeerConnection::ProcessIceWorkMsg(const IceWorkMsg &msg) { cfg_stun_server_ip_, stun_server_port_, cfg_turn_server_ip_, turn_server_port_, cfg_turn_server_username_, 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(); } @@ -663,7 +663,7 @@ void PeerConnection::ProcessIceWorkMsg(const IceWorkMsg &msg) { cfg_stun_server_ip_, stun_server_port_, cfg_turn_server_ip_, turn_server_port_, cfg_turn_server_username_, 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); } diff --git a/src/pc/peer_connection.h b/src/pc/peer_connection.h index 0c1c733..ad81bf4 100644 --- a/src/pc/peer_connection.h +++ b/src/pc/peer_connection.h @@ -147,9 +147,9 @@ class PeerConnection { bool try_rejoin_with_turn_ = false; TraversalMode mode_ = TraversalMode::P2P; - std::vector video_payload_types_ = {RtpPacket::PAYLOAD_TYPE::H264, - RtpPacket::PAYLOAD_TYPE::AV1}; - std::vector audio_payload_types_ = {RtpPacket::PAYLOAD_TYPE::OPUS}; + std::vector video_payload_types_ = {rtp::PAYLOAD_TYPE::H264, + rtp::PAYLOAD_TYPE::AV1}; + std::vector audio_payload_types_ = {rtp::PAYLOAD_TYPE::OPUS}; private: std::shared_ptr ws_transport_ = nullptr; diff --git a/src/rtp/rtp_depacketizer/rtp_depacketizer.cpp b/src/rtp/rtp_depacketizer/rtp_depacketizer.cpp new file mode 100644 index 0000000..a7a2966 --- /dev/null +++ b/src/rtp/rtp_depacketizer/rtp_depacketizer.cpp @@ -0,0 +1,11 @@ +#include "rtp_depacketizer.h" + +std::shared_ptr Create(uint32_t payload_type, uint8_t* payload, + size_t payload_size) { + switch (payload_type) { + case rtp::PAYLOAD_TYPE::H264: + return std::make_shared(payload, payload_size); + case rtp::PAYLOAD_TYPE::AV1: + return std::make_shared(payload, payload_size); + } +} \ No newline at end of file diff --git a/src/rtp/rtp_depacketizer/rtp_depacketizer.h b/src/rtp/rtp_depacketizer/rtp_depacketizer.h new file mode 100644 index 0000000..2176448 --- /dev/null +++ b/src/rtp/rtp_depacketizer/rtp_depacketizer.h @@ -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 +#include +#include + +#include "rtp_packet.h" + +class RtpDepacketizer { + public: + static std::shared_ptr Create(uint32_t payload_type); + + virtual ~RtpDepacketizer() = default; + + bool Build(uint8_t* payload, uint32_t payload_size) = 0; +}; + +#endif \ No newline at end of file diff --git a/src/rtp/rtp_depacketizer/rtp_depacketizer_h264.cpp b/src/rtp/rtp_depacketizer/rtp_depacketizer_h264.cpp new file mode 100644 index 0000000..1e675ea --- /dev/null +++ b/src/rtp/rtp_depacketizer/rtp_depacketizer_h264.cpp @@ -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; +} \ No newline at end of file diff --git a/src/rtp/rtp_depacketizer/rtp_depacketizer_h264.h b/src/rtp/rtp_depacketizer/rtp_depacketizer_h264.h new file mode 100644 index 0000000..90b1b4a --- /dev/null +++ b/src/rtp/rtp_depacketizer/rtp_depacketizer_h264.h @@ -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 +#include +#include + +#include "rtp_packet.h" + +class RtpDepacketizerH264 { + public: + RtpDepacketizerH264(); + + virtual ~RtpDepacketizerH264() = default; + + bool Parse(uint8_t* payload, uint32_t payload_size); +}; + +#endif \ No newline at end of file diff --git a/src/rtp/rtp_packet/rtp_codec.cpp b/src/rtp/rtp_packet/rtp_codec.cc similarity index 93% rename from src/rtp/rtp_packet/rtp_codec.cpp rename to src/rtp/rtp_packet/rtp_codec.cc index 957dca0..e24c922 100644 --- a/src/rtp/rtp_packet/rtp_codec.cpp +++ b/src/rtp/rtp_packet/rtp_codec.cc @@ -15,7 +15,7 @@ constexpr int kObuTypeSequenceHeader = 1; using namespace obu; -RtpCodec::RtpCodec(RtpPacket::PAYLOAD_TYPE payload_type) +RtpCodec::RtpCodec(rtp::PAYLOAD_TYPE payload_type) : version_(RTP_VERSION), has_padding_(false), has_extension_(false), @@ -41,7 +41,7 @@ RtpCodec::~RtpCodec() { // void RtpCodec::Encode(uint8_t* buffer, uint32_t size, // std::vector& packets) { -// if (RtpPacket::PAYLOAD_TYPE::H264 == payload_type_) { +// if (rtp::PAYLOAD_TYPE::H264 == payload_type_) { // if (fec_enable_ && IsKeyFrame((const uint8_t*)buffer, size)) { // uint8_t** fec_packets = fec_encoder_.Encode((const char*)buffer, size); // if (nullptr == fec_packets) { @@ -67,7 +67,7 @@ RtpCodec::~RtpCodec() { // rtp_packet.SetHasExtension(has_extension_); // 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.SetTimestamp(timestamp_); // rtp_packet.SetSsrc(ssrc_); @@ -116,7 +116,7 @@ RtpCodec::~RtpCodec() { // rtp_packet.SetHasPadding(has_padding_); // rtp_packet.SetHasExtension(has_extension_); // 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.SetTimestamp(timestamp_); // rtp_packet.SetSsrc(ssrc_); @@ -149,7 +149,7 @@ RtpCodec::~RtpCodec() { // rtp_packet.SetHasPadding(has_padding_); // rtp_packet.SetHasExtension(has_extension_); // 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_++); // timestamp_ = std::chrono::duration_cast( @@ -189,7 +189,7 @@ RtpCodec::~RtpCodec() { // rtp_packet.SetHasPadding(has_padding_); // rtp_packet.SetHasExtension(has_extension_); // 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.SetTimestamp(timestamp_); // rtp_packet.SetSsrc(ssrc_); @@ -227,7 +227,7 @@ RtpCodec::~RtpCodec() { // packets.emplace_back(rtp_packet); // } // } -// } else if (RtpPacket::PAYLOAD_TYPE::AV1 == payload_type_) { +// } else if (rtp::PAYLOAD_TYPE::AV1 == payload_type_) { // std::vector obus = ParseObus(buffer, size); // LOG_ERROR("Total size = [{}]", size); // for (int i = 0; i < obus.size(); i++) { @@ -239,7 +239,7 @@ RtpCodec::~RtpCodec() { // rtp_packet.SetHasPadding(has_padding_); // rtp_packet.SetHasExtension(has_extension_); // 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_++); // timestamp_ = std::chrono::duration_cast( @@ -275,7 +275,7 @@ RtpCodec::~RtpCodec() { // rtp_packet.SetHasPadding(has_padding_); // rtp_packet.SetHasExtension(has_extension_); // 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.SetTimestamp(timestamp_); // 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; // rtp_packet.SetVerion(version_); // rtp_packet.SetHasPadding(has_padding_); // rtp_packet.SetHasExtension(has_extension_); // 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_++); // timestamp_ = std::chrono::duration_cast( @@ -323,13 +323,13 @@ RtpCodec::~RtpCodec() { // rtp_packet.Encode(buffer, size); // packets.emplace_back(rtp_packet); -// } else if (RtpPacket::PAYLOAD_TYPE::DATA == payload_type_) { +// } else if (rtp::PAYLOAD_TYPE::DATA == payload_type_) { // RtpPacket rtp_packet; // rtp_packet.SetVerion(version_); // rtp_packet.SetHasPadding(has_padding_); // rtp_packet.SetHasExtension(has_extension_); // 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_++); // timestamp_ = std::chrono::duration_cast( @@ -345,7 +345,7 @@ RtpCodec::~RtpCodec() { void RtpCodec::Encode(uint8_t* buffer, uint32_t size, std::vector& packets) { - if (RtpPacket::PAYLOAD_TYPE::H264 == payload_type_) { + if (rtp::PAYLOAD_TYPE::H264 == payload_type_) { if (fec_enable_ && IsKeyFrame((const uint8_t*)buffer, size)) { uint8_t** fec_packets = fec_encoder_.Encode((const char*)buffer, size); if (nullptr == fec_packets) { @@ -369,7 +369,7 @@ void RtpCodec::Encode(uint8_t* buffer, uint32_t size, rtp_packet.SetHasPadding(has_padding_); rtp_packet.SetHasExtension(has_extension_); 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.SetTimestamp(timestamp_); rtp_packet.SetSsrc(ssrc_); @@ -383,12 +383,12 @@ void RtpCodec::Encode(uint8_t* buffer, uint32_t size, rtp_packet.SetExtensionData(extension_data_, extension_len_); } - RtpPacket::FU_INDICATOR fu_indicator; + rtp::FU_INDICATOR fu_indicator; fu_indicator.forbidden_bit = 0; fu_indicator.nal_reference_idc = 0; 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.end = index == num_of_source_packets - 1 ? 1 : 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.SetHasExtension(has_extension_); 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.SetTimestamp(timestamp_); rtp_packet.SetSsrc(ssrc_); @@ -459,7 +459,7 @@ void RtpCodec::Encode(uint8_t* buffer, uint32_t size, rtp_packet.SetHasExtension(has_extension_); 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_++); timestamp_ = std::chrono::duration_cast( @@ -478,7 +478,7 @@ void RtpCodec::Encode(uint8_t* buffer, uint32_t size, rtp_packet.SetExtensionData(extension_data_, extension_len_); } - RtpPacket::FU_INDICATOR fu_indicator; + rtp::FU_INDICATOR fu_indicator; fu_indicator.forbidden_bit = 0; fu_indicator.nal_reference_idc = 1; 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.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.SetTimestamp(timestamp_); rtp_packet.SetSsrc(ssrc_); @@ -522,12 +522,12 @@ void RtpCodec::Encode(uint8_t* buffer, uint32_t size, rtp_packet.SetExtensionData(extension_data_, extension_len_); } - RtpPacket::FU_INDICATOR fu_indicator; + rtp::FU_INDICATOR fu_indicator; fu_indicator.forbidden_bit = 0; fu_indicator.nal_reference_idc = 0; 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.end = index == packet_num - 1 ? 1 : 0; fu_header.remain_bit = 0; @@ -545,7 +545,7 @@ void RtpCodec::Encode(uint8_t* buffer, uint32_t size, packets.emplace_back(rtp_packet); } } - } else if (RtpPacket::PAYLOAD_TYPE::AV1 == payload_type_) { + } else if (rtp::PAYLOAD_TYPE::AV1 == payload_type_) { std::vector obus = ParseObus(buffer, size); uint64_t timestamp = std::chrono::duration_cast( @@ -567,7 +567,7 @@ void RtpCodec::Encode(uint8_t* buffer, uint32_t size, rtp_packet.SetHasExtension(has_extension_); 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.SetTimestamp(timestamp); rtp_packet.SetSsrc(ssrc_); @@ -603,7 +603,7 @@ void RtpCodec::Encode(uint8_t* buffer, uint32_t size, rtp_packet.SetHasExtension(has_extension_); 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.SetTimestamp(timestamp); rtp_packet.SetSsrc(ssrc_); diff --git a/src/rtp/rtp_packet/rtp_codec.h b/src/rtp/rtp_packet/rtp_codec.hxx similarity index 95% rename from src/rtp/rtp_packet/rtp_codec.h rename to src/rtp/rtp_packet/rtp_codec.hxx index d014f63..755d94a 100644 --- a/src/rtp/rtp_packet/rtp_codec.h +++ b/src/rtp/rtp_packet/rtp_codec.hxx @@ -17,7 +17,7 @@ class RtpCodec { }; public: - RtpCodec(RtpPacket::PAYLOAD_TYPE payload_type); + RtpCodec(rtp::PAYLOAD_TYPE payload_type); ~RtpCodec(); public: diff --git a/src/rtp/rtp_packet/rtp_codec_av1.cpp b/src/rtp/rtp_packet/rtp_codec_av1.cc similarity index 95% rename from src/rtp/rtp_packet/rtp_codec_av1.cpp rename to src/rtp/rtp_packet/rtp_codec_av1.cc index 3b02353..9df3365 100644 --- a/src/rtp/rtp_packet/rtp_codec_av1.cpp +++ b/src/rtp/rtp_packet/rtp_codec_av1.cc @@ -29,7 +29,7 @@ // rtp_packet.SetHasPadding(has_padding_); // rtp_packet.SetHasExtension(has_extension_); // 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.SetTimestamp(timestamp); // rtp_packet.SetSsrc(ssrc_); @@ -58,7 +58,7 @@ // rtp_packet.SetHasPadding(has_padding_); // rtp_packet.SetHasExtension(has_extension_); // 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.SetTimestamp(timestamp); // rtp_packet.SetSsrc(ssrc_); diff --git a/src/rtp/rtp_packet/rtp_defines.h b/src/rtp/rtp_packet/rtp_defines.h new file mode 100644 index 0000000..3f141b4 --- /dev/null +++ b/src/rtp/rtp_packet/rtp_defines.h @@ -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 +#include + +#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 \ No newline at end of file diff --git a/src/rtp/rtp_packet/rtp_header.h b/src/rtp/rtp_packet/rtp_header.h index a0efc4d..1837be6 100644 --- a/src/rtp/rtp_packet/rtp_header.h +++ b/src/rtp/rtp_packet/rtp_header.h @@ -54,7 +54,7 @@ struct RTPHeader { uint16_t sequence_number_ = 1; uint64_t timestamp_ = 0; uint32_t ssrc_ = 0; - uint32_t csrcs_[kRtpCsrcSize]; + uint32_t csrcs_[kMaxRtpCsrcSize]; size_t padding_len; size_t header_len; diff --git a/src/rtp/rtp_packet/rtp_packet.cpp b/src/rtp/rtp_packet/rtp_packet.cpp index 3f109c4..f9d311c 100644 --- a/src/rtp/rtp_packet/rtp_packet.cpp +++ b/src/rtp/rtp_packet/rtp_packet.cpp @@ -4,6 +4,8 @@ RtpPacket::RtpPacket() {} +RtpPacket::RtpPacket(size_t size) : buffer_(size) {} + RtpPacket::RtpPacket(const RtpPacket &rtp_packet) = default; RtpPacket::RtpPacket(RtpPacket &&rtp_packet) = default; @@ -15,12 +17,13 @@ RtpPacket &RtpPacket::operator=(RtpPacket &&rtp_packet) = default; RtpPacket::~RtpPacket() = default; bool RtpPacket::Build(const uint8_t *buffer, uint32_t size) { - if (size > 0) { - buffer_.SetData(buffer, size); - size_ = size; - return true; + if (!Parse(buffer, size)) { + LOG_WARN("RtpPacket::Build: parse failed"); + return false; } - return false; + buffer_.SetData(buffer, size); + size_ = size; + return true; } 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 - version_ = (buffer_[payload_offset_] >> 6) & 0x03; + version_ = (buffer[payload_offset_] >> 6) & 0x03; if (version_ != kRtpVersion) { LOG_WARN("RtpPacket::Parse: version is not qual to kRtpVersion"); return false; } - has_padding_ = (buffer_[payload_offset_] >> 5) & 0x01; - has_extension_ = (buffer_[payload_offset_] >> 4) & 0x01; - csrc_count_ = buffer_[payload_offset_] & 0x0f; + has_padding_ = (buffer[payload_offset_] >> 5) & 0x01; + has_extension_ = (buffer[payload_offset_] >> 4) & 0x01; + csrc_count_ = buffer[payload_offset_] & 0x0f; if (csrc_count_ > kMaxRtpCsrcSize) { LOG_WARN("RtpPacket::Parse: csrc count is too large"); return false; } + payload_offset_++; // 2nd byte - marker_ = (buffer_[payload_offset_] >> 7) & 0x01; - payload_type_ = buffer_[payload_offset_] & 0x7f; + marker_ = (buffer[payload_offset_] >> 7) & 0x01; + payload_type_ = buffer[payload_offset_] & 0x7f; + payload_offset_ += 1; // 3rd byte and 4th byte 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 - timestamp_ = - (buffer_[payload_offset_] << 24) | (buffer_[payload_offset_ + 1] << 16) | - (buffer_[payload_offset_ + 2] << 8) | buffer_[payload_offset_ + 3]; + timestamp_ = (buffer[payload_offset_] << 24) | + (buffer[payload_offset_ + 1] << 16) | + (buffer[payload_offset_ + 2] << 8) | buffer[payload_offset_ + 3]; + payload_offset_ += 4; // 9th byte to 12th byte - ssrc_ = (buffer_[payload_offset_] << 24) | - (buffer_[payload_offset_ + 1] << 16) | - (buffer_[payload_offset_ + 2] << 8) | buffer_[payload_offset_ + 3]; + ssrc_ = (buffer[payload_offset_] << 24) | + (buffer[payload_offset_ + 1] << 16) | + (buffer[payload_offset_ + 2] << 8) | buffer[payload_offset_ + 3]; payload_offset_ = kFixedHeaderSize; @@ -68,11 +75,11 @@ bool RtpPacket::Parse(const uint8_t *buffer, uint32_t size) { return false; } // csrc - for (uint32_t csrc_index = 0; i < csrc_count_; i++) { - uint32_t csrc = (buffer_[payload_offset_ + csrc_index * 4] << 24) | - (buffer_[payload_offset_ + 1 + csrc_index * 4] << 16) | - (buffer_[payload_offset_ + 2 + csrc_index * 4] << 8) | - buffer_[payload_offset_ + 3 + csrc_index * 4]; + for (uint32_t csrc_index = 0; csrc_index < csrc_count_; csrc_index++) { + uint32_t csrc = (buffer[payload_offset_ + csrc_index * 4] << 24) | + (buffer[payload_offset_ + 1 + csrc_index * 4] << 16) | + (buffer[payload_offset_ + 2 + csrc_index * 4] << 8) | + buffer[payload_offset_ + 3 + csrc_index * 4]; csrcs_.push_back(csrc); } @@ -89,28 +96,30 @@ bool RtpPacket::Parse(const uint8_t *buffer, uint32_t size) { return false; } extension_profile_ = - (buffer_[payload_offset_] << 8) | buffer_[payload_offset_ + 1]; + (buffer[payload_offset_] << 8) | buffer[payload_offset_ + 1]; 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"); return false; } size_t offset = payload_offset_ + 4; while (offset < size && extension_len_ > 0) { - uint8_t id = buffer_[offset] >> 4; - uint8_t len = (buffer_[offset] & 0x0F) + 1; + uint8_t id = buffer[offset] >> 4; + uint8_t len = (buffer[offset] & 0x0F) + 1; if (offset + 1 + len > size) { break; } - extensions_.push_back( - {id, std::vector(buffer_ + offset + 1, - buffer_ + offset + 1 + len)}); + Extension extension; + extension.id = id; + extension.data = + std::vector(buffer + offset + 1, buffer + offset + 1 + len); + extensions_.push_back(extension); offset += 1 + len; } - payload_offset_ += (4 + extension_len_); + payload_offset_ += extension_len_; } if (has_padding_ && payload_offset_ < size) { diff --git a/src/rtp/rtp_packet/rtp_packet.h b/src/rtp/rtp_packet/rtp_packet.h index 40e2bd1..785accb 100644 --- a/src/rtp/rtp_packet/rtp_packet.h +++ b/src/rtp/rtp_packet/rtp_packet.h @@ -8,6 +8,7 @@ #include "copy_on_write_buffer.h" #include "log.h" +#include "rtp_defines.h" #include "rtp_header.h" // Common @@ -170,25 +171,14 @@ #define DEFAULT_MTU 1500 #define MAX_NALU_LEN 1400 +constexpr uint16_t kOneByteExtensionProfileId = 0xBEDE; +constexpr uint16_t kTwoByteExtensionProfileId = 0x1000; +constexpr size_t kFixedHeaderSize = 12; + 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: RtpPacket(); + RtpPacket(size_t size); RtpPacket(const RtpPacket &rtp_packet); RtpPacket(RtpPacket &&rtp_packet); RtpPacket &operator=(const RtpPacket &rtp_packet); @@ -199,13 +189,16 @@ class RtpPacket { public: bool Build(const uint8_t *buffer, uint32_t size); + private: + bool Parse(const uint8_t *buffer, uint32_t size); + public: // Set Header void SetVerion(uint8_t version) { version_ = version; } void SetHasPadding(bool has_padding) { has_padding_ = has_padding; } void SetHasExtension(bool has_extension) { has_extension_ = has_extension; } 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; } void SetSequenceNumber(uint16_t sequence_number) { @@ -220,47 +213,54 @@ class RtpPacket { // bits 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) 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_data_[0] = 0x00; - extension_data_[1] = 0x02; // 2 words (8 bytes) - - // Set the absolute send time in the extension data - extension_data_[2] = (abs_send_time >> 16) & 0xFF; - extension_data_[3] = (abs_send_time >> 8) & 0xFF; - extension_data_[4] = abs_send_time & 0xFF; + Extension extension; + extension.id = 0; + extension.len = 2; + extension.data.push_back(extension.id << 4 | extension.len); + extension.data.push_back((abs_send_time >> 16) & 0xFF); + extension.data.push_back((abs_send_time >> 8) & 0xFF); + extension.data.push_back(abs_send_time & 0xFF); } public: // Get Header - uint32_t Verion() const { return version_; } + uint32_t Version() const { return version_; } bool HasPadding() const { return has_padding_; } bool HasExtension() const { return has_extension_; } bool Marker() const { return marker_; } - PAYLOAD_TYPE PayloadType() const { return PAYLOAD_TYPE(payload_type_); } + rtp::PAYLOAD_TYPE PayloadType() const { + return rtp::PAYLOAD_TYPE(payload_type_); + } uint16_t SequenceNumber() const { return sequence_number_; } uint64_t Timestamp() const { return timestamp_; } uint32_t Ssrc() const { return ssrc_; } std::vector Csrcs() const { return csrcs_; }; 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 - const uint8_t *Payload() { return Buffer() + payload_offset_; }; + const uint8_t *Payload() { return Buffer().data() + payload_offset_; }; size_t PayloadSize() { return payload_size_; } // Entire RTP buffer - const uint8_t *Buffer() const { return buffer_; } + CopyOnWriteBuffer Buffer() const { return buffer_; } size_t Size() const { return size_; } // For webrtc module use @@ -288,6 +288,7 @@ class RtpPacket { uint16_t extension_len_ = 0; struct Extension { uint8_t id; + uint8_t len; std::vector data; }; std::vector extensions_; @@ -300,15 +301,8 @@ class RtpPacket { size_t padding_size_ = 0; // Entire rtp buffer - CopyOnWriteBuffer buffer_ = nullptr; + CopyOnWriteBuffer buffer_; 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 \ No newline at end of file diff --git a/src/rtp/rtp_packet/rtp_packet_av1.cpp b/src/rtp/rtp_packet/rtp_packet_av1.cpp new file mode 100644 index 0000000..6929c32 --- /dev/null +++ b/src/rtp/rtp_packet/rtp_packet_av1.cpp @@ -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; +} \ No newline at end of file diff --git a/src/rtp/rtp_packet/rtp_packet_av1.h b/src/rtp/rtp_packet/rtp_packet_av1.h new file mode 100644 index 0000000..f62d8fe --- /dev/null +++ b/src/rtp/rtp_packet/rtp_packet_av1.h @@ -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 \ No newline at end of file diff --git a/src/rtp/rtp_packet/rtp_packet_h264.cpp b/src/rtp/rtp_packet/rtp_packet_h264.cpp new file mode 100644 index 0000000..92408a0 --- /dev/null +++ b/src/rtp/rtp_packet/rtp_packet_h264.cpp @@ -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; +} \ No newline at end of file diff --git a/src/rtp/rtp_packet/rtp_packet_h264.h b/src/rtp/rtp_packet/rtp_packet_h264.h new file mode 100644 index 0000000..ff1a67e --- /dev/null +++ b/src/rtp/rtp_packet/rtp_packet_h264.h @@ -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 \ No newline at end of file diff --git a/src/rtp/rtp_packet/rtp_packet_received.cpp b/src/rtp/rtp_packet/rtp_packet_received.cpp index eaa89c9..8c51d21 100644 --- a/src/rtp/rtp_packet/rtp_packet_received.cpp +++ b/src/rtp/rtp_packet/rtp_packet_received.cpp @@ -33,7 +33,7 @@ RtpPacketReceived& RtpPacketReceived::operator=(RtpPacketReceived&& packet) = RtpPacketReceived::~RtpPacketReceived() {} void RtpPacketReceived::GetHeader(RTPHeader* header) const { - header->version = Version(); + header->version_ = Version(); header->has_padding_ = HasPadding(); header->has_extension_ = HasExtension(); header->csrc_count_ = Csrcs().size(); @@ -44,7 +44,7 @@ void RtpPacketReceived::GetHeader(RTPHeader* header) const { header->ssrc_ = Ssrc(); std::vector csrcs = Csrcs(); 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->header_len = headers_size(); diff --git a/src/rtp/rtp_packetizer/rtp_packetizer.cpp b/src/rtp/rtp_packetizer/rtp_packetizer.cpp index dbeea34..86cc341 100644 --- a/src/rtp/rtp_packetizer/rtp_packetizer.cpp +++ b/src/rtp/rtp_packetizer/rtp_packetizer.cpp @@ -1,11 +1,16 @@ #include "rtp_packetizer.h" -std::unique_ptr Create(uint32_t payload_type, uint8_t* payload, - size_t payload_size) { +#include "rtp_packetizer_av1.h" +#include "rtp_packetizer_generic.h" +#include "rtp_packetizer_h264.h" + +std::unique_ptr RtpPacketizer::Create(uint32_t payload_type) { switch (payload_type) { - case RtpPacket::PAYLOAD_TYPE::H264: - return std::make_unique(payload, payload_size); - case RtpPacket::PAYLOAD_TYPE::AV1: - return std::make_unique(payload, payload_size); + case rtp::PAYLOAD_TYPE::H264: + return std::make_unique(); + case rtp::PAYLOAD_TYPE::AV1: + return std::make_unique(); + default: + return std::make_unique(); } } \ No newline at end of file diff --git a/src/rtp/rtp_packetizer/rtp_packetizer.h b/src/rtp/rtp_packetizer/rtp_packetizer.h index 95ef409..a8ced94 100644 --- a/src/rtp/rtp_packetizer/rtp_packetizer.h +++ b/src/rtp/rtp_packetizer/rtp_packetizer.h @@ -19,7 +19,8 @@ class RtpPacketizer { virtual ~RtpPacketizer() = default; - bool Build(uint8_t* payload, uint32_t payload_size) = 0; + virtual std::vector Build(uint8_t* payload, + uint32_t payload_size) = 0; }; #endif \ No newline at end of file diff --git a/src/rtp/rtp_packetizer/rtp_packetizer_av1.cpp b/src/rtp/rtp_packetizer/rtp_packetizer_av1.cpp index e69de29..01f2a45 100644 --- a/src/rtp/rtp_packetizer/rtp_packetizer_av1.cpp +++ b/src/rtp/rtp_packetizer/rtp_packetizer_av1.cpp @@ -0,0 +1,11 @@ +#include "rtp_packetizer_av1.h" + +RtpPacketizerAv1::RtpPacketizerAv1() {} + +RtpPacketizerAv1::~RtpPacketizerAv1() {} + +std::vector RtpPacketizerAv1::Build(uint8_t* payload, + uint32_t payload_size) { + std::vector rtp_packets; + return rtp_packets; +} \ No newline at end of file diff --git a/src/rtp/rtp_packetizer/rtp_packetizer_av1.h b/src/rtp/rtp_packetizer/rtp_packetizer_av1.h index e69de29..eeaf693 100644 --- a/src/rtp/rtp_packetizer/rtp_packetizer_av1.h +++ b/src/rtp/rtp_packetizer/rtp_packetizer_av1.h @@ -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 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 csrcs_; + uint16_t profile_; + uint16_t extension_profile_; + uint16_t extension_len_; + uint8_t* extension_data_; + + private: + std::vector rtp_packet_frame_; +}; + +#endif \ No newline at end of file diff --git a/src/rtp/rtp_packetizer/rtp_packetizer_generic.cpp b/src/rtp/rtp_packetizer/rtp_packetizer_generic.cpp index e69de29..2364f99 100644 --- a/src/rtp/rtp_packetizer/rtp_packetizer_generic.cpp +++ b/src/rtp/rtp_packetizer/rtp_packetizer_generic.cpp @@ -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 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::system_clock::now().time_since_epoch()) + .count(); + + std::vector 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::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; +} diff --git a/src/rtp/rtp_packetizer/rtp_packetizer_generic.h b/src/rtp/rtp_packetizer/rtp_packetizer_generic.h index e69de29..57c10c3 100644 --- a/src/rtp/rtp_packetizer/rtp_packetizer_generic.h +++ b/src/rtp/rtp_packetizer/rtp_packetizer_generic.h @@ -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 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 csrcs_; + uint16_t profile_; + uint16_t extension_profile_; + uint16_t extension_len_; + uint8_t* extension_data_; + + private: + private: + std::vector rtp_packet_frame_; +}; + +#endif \ No newline at end of file diff --git a/src/rtp/rtp_packetizer/rtp_packetizer_h264.cpp b/src/rtp/rtp_packetizer/rtp_packetizer_h264.cpp index 2881b7b..9ea67b3 100644 --- a/src/rtp/rtp_packetizer/rtp_packetizer_h264.cpp +++ b/src/rtp/rtp_packetizer/rtp_packetizer_h264.cpp @@ -6,7 +6,7 @@ RtpPacketizerH264::RtpPacketizerH264() has_extension_(true), csrc_count_(0), marker_(false), - payload_type_(RtpPacket::PAYLOAD_TYPE::H264), + payload_type_(rtp::PAYLOAD_TYPE::H264), sequence_number_(1), timestamp_(0), ssrc_(0), @@ -28,13 +28,14 @@ std::vector RtpPacketizerH264::Build(uint8_t* payload, std::chrono::system_clock::now().time_since_epoch()) .count(); + std::vector 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_ = RtpPacket::PAYLOAD_TYPE(payload_type_); + payload_type_ = rtp::PAYLOAD_TYPE(payload_type_); sequence_number_++; timestamp_ = timestamp_; ssrc_ = ssrc_; @@ -43,16 +44,16 @@ std::vector RtpPacketizerH264::Build(uint8_t* payload, csrcs_ = csrcs_; } - RtpPacket::FU_INDICATOR fu_indicator; + rtp::FU_INDICATOR fu_indicator; fu_indicator.forbidden_bit = 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.end = index == packet_num - 1 ? 1 : 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_.push_back((version_ << 6) | (has_padding_ << 5) | @@ -77,20 +78,38 @@ std::vector RtpPacketizerH264::Build(uint8_t* payload, } 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_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 = std::chrono::duration_cast( 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(0x00); - rtp_packet_frame_.push_back(0x02); + 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); @@ -115,8 +134,9 @@ std::vector RtpPacketizerH264::Build(uint8_t* payload, RtpPacket rtp_packet; 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) { @@ -143,7 +163,7 @@ std::vector RtpPacketizerH264::Build(uint8_t* payload, // rtp_packet.SetHasPadding(false); // rtp_packet.SetHasExtension(has_extension_); // 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.SetTimestamp(timestamp_); // rtp_packet.SetSsrc(ssrc_); @@ -192,7 +212,7 @@ std::vector RtpPacketizerH264::Build(uint8_t* payload, // rtp_packet.SetHasPadding(false); // rtp_packet.SetHasExtension(has_extension_); // 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.SetTimestamp(timestamp_); // rtp_packet.SetSsrc(ssrc_); @@ -234,7 +254,7 @@ std::vector RtpPacketizerH264::Build(uint8_t* payload, // rtp_packet.SetHasExtension(has_extension_); // 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_++); // timestamp_ = std::chrono::duration_cast( diff --git a/src/rtp/rtp_packetizer/rtp_packetizer_h264.h b/src/rtp/rtp_packetizer/rtp_packetizer_h264.h index 8b49226..8076731 100644 --- a/src/rtp/rtp_packetizer/rtp_packetizer_h264.h +++ b/src/rtp/rtp_packetizer/rtp_packetizer_h264.h @@ -38,6 +38,14 @@ class RtpPacketizerH264 : public RtpPacketizer { uint16_t extension_len_; 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: std::vector rtp_packet_frame_; }; diff --git a/src/transport/ice_transport.cpp b/src/transport/ice_transport.cpp index d52f9d2..ba2c38f 100644 --- a/src/transport/ice_transport.cpp +++ b/src/transport/ice_transport.cpp @@ -54,14 +54,14 @@ int IceTransport::SetLocalCapabilities(bool hardware_acceleration, force_turn_ = force_turn; support_video_payload_types_ = video_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; } int IceTransport::InitIceTransmission( std::string &stun_ip, int stun_port, std::string &turn_ip, int turn_port, 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( offer_peer_, use_trickle_ice_, use_reliable_ice_, enable_turn_, force_turn_, stun_ip, stun_port, turn_ip, turn_port, turn_username, @@ -116,7 +116,7 @@ void IceTransport::InitializeIOStatistics() { } 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_channel_send_ = @@ -127,14 +127,12 @@ void IceTransport::InitializeChannels( std::make_unique(ice_agent_, ice_io_statistics_); video_channel_send_->Initialize(video_codec_payload_type_); - audio_channel_send_->Initialize(RtpPacket::PAYLOAD_TYPE::OPUS); - data_channel_send_->Initialize(RtpPacket::PAYLOAD_TYPE::DATA); + audio_channel_send_->Initialize(rtp::PAYLOAD_TYPE::OPUS); + data_channel_send_->Initialize(rtp::PAYLOAD_TYPE::DATA); video_channel_receive_ = std::make_unique( - ice_agent_, ice_io_statistics_, [this](VideoFrame &video_frame) { - LOG_ERROR("ccccccc"); - OnReceiveCompleteFrame(video_frame); - }); + ice_agent_, ice_io_statistics_, + [this](VideoFrame &video_frame) { OnReceiveCompleteFrame(video_frame); }); audio_channel_receive_ = std::make_unique( 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_); - audio_channel_receive_->Initialize(RtpPacket::PAYLOAD_TYPE::OPUS); - data_channel_receive_->Initialize(RtpPacket::PAYLOAD_TYPE::DATA); + audio_channel_receive_->Initialize(rtp::PAYLOAD_TYPE::OPUS); + data_channel_receive_->Initialize(rtp::PAYLOAD_TYPE::DATA); } 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.height = video_frame.Height(); x_video_frame.size = video_frame.Size(); - LOG_ERROR("ccccccc 2222222"); on_receive_video_(&x_video_frame, remote_user_id_.data(), remote_user_id_.size(), user_data_); } @@ -434,14 +431,7 @@ int IceTransport::DestroyIceTransmission() { return ice_agent_->DestroyIceAgent(); } -int IceTransport::CreateMediaCodec() { - video_rtp_codec_ = std::make_unique(negotiated_video_pt_); - audio_rtp_codec_ = std::make_unique(negotiated_audio_pt_); - data_rtp_codec_ = std::make_unique(negotiated_data_pt_); - return 0; -} - -int IceTransport::CreateVideoCodec(RtpPacket::PAYLOAD_TYPE video_pt, +int IceTransport::CreateVideoCodec(rtp::PAYLOAD_TYPE video_pt, bool hardware_acceleration) { if (video_codec_inited_) { return 0; @@ -449,14 +439,14 @@ int IceTransport::CreateVideoCodec(RtpPacket::PAYLOAD_TYPE video_pt, hardware_acceleration_ = hardware_acceleration; - if (RtpPacket::PAYLOAD_TYPE::AV1 == video_pt) { + if (rtp::PAYLOAD_TYPE::AV1 == video_pt) { if (hardware_acceleration_) { hardware_acceleration_ = false; LOG_WARN("Only support software codec for AV1"); } video_encoder_ = VideoEncoderFactory::CreateVideoEncoder(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__ if (hardware_acceleration_) { hardware_acceleration_ = false; @@ -619,18 +609,18 @@ int IceTransport::AppendLocalCapabilitiesToOffer( std::string data_capabilities = "UDP/TLS/RTP/SAVPF 127"; switch (video_codec_payload_type_) { - case RtpPacket::PAYLOAD_TYPE::H264: { - preferred_video_pt = std::to_string(RtpPacket::PAYLOAD_TYPE::H264); + case rtp::PAYLOAD_TYPE::H264: { + preferred_video_pt = std::to_string(rtp::PAYLOAD_TYPE::H264); video_capabilities += preferred_video_pt + " 97 98 99"; break; } - case RtpPacket::PAYLOAD_TYPE::AV1: { - preferred_video_pt = std::to_string(RtpPacket::PAYLOAD_TYPE::AV1); + case rtp::PAYLOAD_TYPE::AV1: { + preferred_video_pt = std::to_string(rtp::PAYLOAD_TYPE::AV1); video_capabilities += preferred_video_pt + " 96 97 98"; break; } 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"; break; } @@ -734,7 +724,6 @@ std::string IceTransport::GetRemoteCapabilities(const std::string &remote_sdp) { return std::string(); } - CreateMediaCodec(); CreateVideoCodec(negotiated_video_pt_, hardware_acceleration_); CreateAudioCodec(); @@ -808,7 +797,7 @@ bool IceTransport::NegotiateVideoPayloadType(const std::string &remote_sdp) { } 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 = std::find(support_video_payload_types_.begin(), @@ -817,7 +806,7 @@ bool IceTransport::NegotiateVideoPayloadType(const std::string &remote_sdp) { support_video_payload_types_.end(); 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; } else { 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"); return false; } else { @@ -868,7 +857,7 @@ bool IceTransport::NegotiateAudioPayloadType(const std::string &remote_sdp) { } 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 = std::find(support_audio_payload_types_.begin(), @@ -877,7 +866,7 @@ bool IceTransport::NegotiateAudioPayloadType(const std::string &remote_sdp) { support_audio_payload_types_.end(); 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; } else { 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"); return false; } else { @@ -928,7 +917,7 @@ bool IceTransport::NegotiateDataPayloadType(const std::string &remote_sdp) { } 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 = std::find(support_data_payload_types_.begin(), @@ -937,7 +926,7 @@ bool IceTransport::NegotiateDataPayloadType(const std::string &remote_sdp) { support_data_payload_types_.end(); 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; } else { 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"); return false; } else { @@ -957,7 +946,7 @@ bool IceTransport::NegotiateDataPayloadType(const std::string &remote_sdp) { } } -std::vector IceTransport::GetNegotiatedCapabilities() { +std::vector IceTransport::GetNegotiatedCapabilities() { 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; - if (RtpPacket::PAYLOAD_TYPE::H264 == pt || - RtpPacket::PAYLOAD_TYPE::H264_FEC_SOURCE == pt || - RtpPacket::PAYLOAD_TYPE::H264_FEC_REPAIR == pt || - RtpPacket::PAYLOAD_TYPE::AV1 == pt) { + if (rtp::PAYLOAD_TYPE::H264 == pt || + rtp::PAYLOAD_TYPE::H264_FEC_SOURCE == pt || + rtp::PAYLOAD_TYPE::H264_FEC_REPAIR == pt || + rtp::PAYLOAD_TYPE::AV1 == pt) { return pt; } else { return 0; @@ -1089,7 +1078,7 @@ uint8_t IceTransport::CheckIsAudioPacket(const char *buffer, size_t size) { } uint8_t pt = buffer[1] & 0x7F; - if (RtpPacket::PAYLOAD_TYPE::OPUS == pt) { + if (rtp::PAYLOAD_TYPE::OPUS == pt) { return pt; } else { return 0; @@ -1107,7 +1096,7 @@ uint8_t IceTransport::CheckIsDataPacket(const char *buffer, size_t size) { } uint8_t pt = buffer[1] & 0x7F; - if (RtpPacket::PAYLOAD_TYPE::DATA == pt) { + if (rtp::PAYLOAD_TYPE::DATA == pt) { return pt; } else { return 0; diff --git a/src/transport/ice_transport.h b/src/transport/ice_transport.h index 40db78a..4680285 100644 --- a/src/transport/ice_transport.h +++ b/src/transport/ice_transport.h @@ -22,7 +22,6 @@ #include "rtcp_packet_info.h" #include "rtp_audio_receiver.h" #include "rtp_audio_sender.h" -#include "rtp_codec.h" #include "rtp_data_receiver.h" #include "rtp_data_sender.h" #include "rtp_packet.h" @@ -66,7 +65,7 @@ class IceTransport { std::string &turn_ip, int turn_port, std::string &turn_username, std::string &turn_password, - RtpPacket::PAYLOAD_TYPE video_codec_payload_type); + rtp::PAYLOAD_TYPE video_codec_payload_type); int DestroyIceTransmission(); @@ -74,7 +73,6 @@ class IceTransport { std::function on_receive_video) { - LOG_ERROR("!!!!!!!!!!!!!!!!!!!!!!!!!!!"); on_receive_video_ = on_receive_video; } @@ -121,7 +119,7 @@ class IceTransport { int SendAnswer(); - std::vector GetNegotiatedCapabilities(); + std::vector GetNegotiatedCapabilities(); private: int AppendLocalCapabilitiesToOffer(const std::string &remote_sdp); @@ -132,10 +130,7 @@ class IceTransport { bool NegotiateAudioPayloadType(const std::string &remote_sdp); bool NegotiateDataPayloadType(const std::string &remote_sdp); - int CreateMediaCodec(); - - int CreateVideoCodec(RtpPacket::PAYLOAD_TYPE video_pt, - bool hardware_acceleration); + int CreateVideoCodec(rtp::PAYLOAD_TYPE video_pt, bool hardware_acceleration); int CreateAudioCodec(); private: @@ -148,7 +143,7 @@ class IceTransport { private: 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, NiceComponentState state, gpointer user_ptr); @@ -231,10 +226,6 @@ class IceTransport { std::unique_ptr data_channel_send_ = nullptr; std::unique_ptr data_channel_receive_ = nullptr; - std::unique_ptr video_rtp_codec_ = nullptr; - std::unique_ptr audio_rtp_codec_ = nullptr; - std::unique_ptr data_rtp_codec_ = nullptr; - std::unique_ptr rtp_video_receiver_ = nullptr; std::unique_ptr rtp_video_sender_ = nullptr; std::unique_ptr rtp_audio_receiver_ = nullptr; @@ -249,20 +240,14 @@ class IceTransport { std::shared_ptr ice_io_statistics_ = nullptr; private: - RtpPacket::PAYLOAD_TYPE video_codec_payload_type_; + rtp::PAYLOAD_TYPE video_codec_payload_type_; bool remote_capabilities_got_ = false; - RtpPacket::PAYLOAD_TYPE remote_prefered_video_pt_ = - RtpPacket::PAYLOAD_TYPE::UNDEFINED; - RtpPacket::PAYLOAD_TYPE remote_prefered_audio_pt_ = - RtpPacket::PAYLOAD_TYPE::UNDEFINED; - RtpPacket::PAYLOAD_TYPE remote_prefered_data_pt_ = - RtpPacket::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; + rtp::PAYLOAD_TYPE remote_prefered_video_pt_ = rtp::PAYLOAD_TYPE::UNDEFINED; + rtp::PAYLOAD_TYPE remote_prefered_audio_pt_ = rtp::PAYLOAD_TYPE::UNDEFINED; + rtp::PAYLOAD_TYPE remote_prefered_data_pt_ = rtp::PAYLOAD_TYPE::UNDEFINED; + rtp::PAYLOAD_TYPE negotiated_video_pt_ = rtp::PAYLOAD_TYPE::UNDEFINED; + rtp::PAYLOAD_TYPE negotiated_audio_pt_ = rtp::PAYLOAD_TYPE::UNDEFINED; + rtp::PAYLOAD_TYPE negotiated_data_pt_ = rtp::PAYLOAD_TYPE::UNDEFINED; private: std::unique_ptr video_encoder_ = nullptr; diff --git a/xmake.lua b/xmake.lua index 750415b..ec7c0eb 100644 --- a/xmake.lua +++ b/xmake.lua @@ -107,9 +107,11 @@ target("rtp") set_kind("object") add_deps("log", "common", "frame", "ringbuffer", "thread", "rtcp", "fec", "statistics") add_files("src/rtp/*.cpp", - "src/rtp/rtp_packet/*.cpp") + "src/rtp/rtp_packet/*.cpp", + "src/rtp/rtp_packetizer/*.cpp") add_includedirs("src/rtp", - "src/rtp/rtp_packet", {public = true}) + "src/rtp/rtp_packet", + "src/rtp/rtp_packetizer", {public = true}) target("rtcp") set_kind("object")