diff --git a/src/media/resolution_adapter/resolution_adapter.h b/src/media/resolution_adapter/resolution_adapter.h index 1bff174..5d21b7c 100644 --- a/src/media/resolution_adapter/resolution_adapter.h +++ b/src/media/resolution_adapter/resolution_adapter.h @@ -31,7 +31,8 @@ class ResolutionAdapter { {640, 360, 500000, 30000, 800000}, {960, 540, 800000, 30000, 1500000}, {1280, 720, 1500000, 30000, 2500000}, - {1920, 1080, 2500000, 30000, 4000000}}; + {1920, 1080, 2500000, 30000, 4000000}, + {2560, 1440, 4000000, 30000, 10000000}}; } int SetTargetBitrate(int bitrate); diff --git a/src/rtp/rtp_packet/rtp_defines.h b/src/rtp/rtp_packet/rtp_defines.h index 19fbc23..c24c205 100644 --- a/src/rtp/rtp_packet/rtp_defines.h +++ b/src/rtp/rtp_packet/rtp_defines.h @@ -22,7 +22,8 @@ typedef enum { H264_FEC_REPAIR = 98, AV1 = 99, OPUS = 111, - DATA = 127 + RTX = 127, + DATA = 120 } PAYLOAD_TYPE; typedef struct { diff --git a/src/transport/channel/audio_channel_send.cpp b/src/transport/channel/audio_channel_send.cpp index 06c8033..542c46e 100644 --- a/src/transport/channel/audio_channel_send.cpp +++ b/src/transport/channel/audio_channel_send.cpp @@ -49,7 +49,7 @@ int AudioChannelSend::SendAudio(char *data, size_t size) { if (rtp_audio_sender_ && rtp_packetizer_) { std::vector> rtp_packets = rtp_packetizer_->Build((uint8_t *)data, (uint32_t)size, 0, true); - // packet_sender_->EnqueueRtpPacket(rtp_packets, 0); + // packet_sender_->EnqueueRtpPackets(rtp_packets, 0); rtp_audio_sender_->Enqueue(rtp_packets); } diff --git a/src/transport/channel/data_channel_send.cpp b/src/transport/channel/data_channel_send.cpp index 66b245e..1211607 100644 --- a/src/transport/channel/data_channel_send.cpp +++ b/src/transport/channel/data_channel_send.cpp @@ -49,7 +49,7 @@ int DataChannelSend::SendData(const char *data, size_t size) { if (rtp_data_sender_ && rtp_packetizer_) { std::vector> rtp_packets = rtp_packetizer_->Build((uint8_t *)data, (uint32_t)size, 0, true); - // packet_sender_->EnqueueRtpPacket(rtp_packets, 0); + // packet_sender_->EnqueueRtpPackets(rtp_packets, 0); rtp_data_sender_->Enqueue(rtp_packets); } diff --git a/src/transport/channel/rtp_video_receiver.cpp b/src/transport/channel/rtp_video_receiver.cpp index 5023250..0b89662 100644 --- a/src/transport/channel/rtp_video_receiver.cpp +++ b/src/transport/channel/rtp_video_receiver.cpp @@ -194,12 +194,37 @@ void RtpVideoReceiver::InsertRtpPacket(RtpPacket& rtp_packet) { rtp_packet_av1.GetFrameHeaderInfo(); ProcessAv1RtpPacket(rtp_packet_av1); } else if (rtp_packet.PayloadType() == rtp::PAYLOAD_TYPE::H264 || - rtp_packet.PayloadType() == rtp::PAYLOAD_TYPE::H264 - 1) { + rtp_packet.PayloadType() == rtp::PAYLOAD_TYPE::H264 - 1 || + rtp_packet.PayloadType() == rtp::PAYLOAD_TYPE::RTX) { + // RtpPacketH264 rtp_packet_h264; + // if (rtp_packet_h264.Build(rtp_packet.Buffer().data(), rtp_packet.Size())) + // { + // rtp_packet_h264.GetFrameHeaderInfo(); + + // ProcessH264RtpPacket(rtp_packet_h264); + // if (rtp_packet.PayloadType() != rtp::PAYLOAD_TYPE::RTX) { + // receive_side_congestion_controller_.OnReceivedPacket( + // rtp_packet_received, MediaType::VIDEO); + // nack_->OnReceivedPacket(rtp_packet.SequenceNumber(), true); + // } else { + // nack_->OnReceivedPacket(rtp_packet.SequenceNumber(), false); + // } + // } + std::unique_ptr rtp_packet_h264 = std::make_unique(); if (rtp_packet.Buffer().data() != nullptr && rtp_packet.Size() > 0 && rtp_packet_h264->Build(rtp_packet.Buffer().data(), rtp_packet.Size())) { rtp_packet_h264->GetFrameHeaderInfo(); + + if (rtp_packet.PayloadType() != rtp::PAYLOAD_TYPE::RTX) { + receive_side_congestion_controller_.OnReceivedPacket( + rtp_packet_received, MediaType::VIDEO); + nack_->OnReceivedPacket(rtp_packet.SequenceNumber(), true); + } else { + nack_->OnReceivedPacket(rtp_packet.SequenceNumber(), false); + } + rtp::NAL_UNIT_TYPE nalu_type = rtp_packet_h264->NalUnitType(); if (rtp::NAL_UNIT_TYPE::NALU == nalu_type) { ReceivedFrame received_frame(rtp_packet_h264->Payload(), @@ -237,25 +262,16 @@ void RtpVideoReceiver::InsertRtpPacket(RtpPacket& rtp_packet) { } } } - - // RtpPacketH264 rtp_packet_h264; - // if (rtp_packet_h264.Build(rtp_packet.Buffer().data(), rtp_packet.Size())) - // { - // rtp_packet_h264.GetFrameHeaderInfo(); - // bool is_missing_packet = ProcessH264RtpPacket(rtp_packet_h264); - // if (!is_missing_packet) { - // receive_side_congestion_controller_.OnReceivedPacket( - // rtp_packet_received, MediaType::VIDEO); - // nack_->OnReceivedPacket(rtp_packet.SequenceNumber(), true); - // } else { - // nack_->OnReceivedPacket(rtp_packet.SequenceNumber(), false); - // } - // } } } bool RtpVideoReceiver::ProcessH264RtpPacket(RtpPacketH264& rtp_packet_h264) { bool is_missing_packet = false; + + if (rtp_packet_h264.PayloadType() == rtp::PAYLOAD_TYPE::RTX) { + is_missing_packet = true; + } + if (!fec_enable_) { if (rtp::PAYLOAD_TYPE::H264 == rtp_packet_h264.PayloadType()) { rtp::NAL_UNIT_TYPE nalu_type = rtp_packet_h264.NalUnitType(); @@ -280,23 +296,18 @@ bool RtpVideoReceiver::ProcessH264RtpPacket(RtpPacketH264& rtp_packet_h264) { auto missing_seqs_wait_ts_iter = missing_sequence_numbers_wait_time_.find( rtp_packet_h264.Timestamp()); - if (missing_seqs_iter != missing_sequence_numbers_.end()) { - if (missing_seqs_wait_ts_iter != - missing_sequence_numbers_wait_time_.end()) { - if (clock_->CurrentTime().ms() - - missing_seqs_wait_ts_iter->second <= - MAX_WAIT_TIME_MS) { - auto missing_seqs = missing_seqs_iter->second; - if (missing_seqs.find(rtp_packet_h264.SequenceNumber()) != - missing_seqs.end()) { - CheckIsH264FrameCompletedMissSeqReceived(rtp_packet_h264); - is_missing_packet = true; - } - } else { - missing_sequence_numbers_wait_time_.erase( - missing_seqs_wait_ts_iter); - missing_sequence_numbers_.erase(missing_seqs_iter); - } + if (missing_seqs_wait_ts_iter != + missing_sequence_numbers_wait_time_.end()) { + if (clock_->CurrentTime().ms() - + missing_seqs_wait_ts_iter->second <= + MAX_WAIT_TIME_MS) { + CheckIsH264FrameCompletedMissSeqReceived(rtp_packet_h264); + is_missing_packet = true; + + } else { + missing_sequence_numbers_wait_time_.erase( + missing_seqs_wait_ts_iter); + missing_sequence_numbers_.erase(missing_seqs_iter); } } } @@ -312,7 +323,8 @@ bool RtpVideoReceiver::ProcessH264RtpPacket(RtpPacketH264& rtp_packet_h264) { // 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 + // rtp_packet; bool complete = CheckIsH264FrameCompleted(rtp_packet); + // if // (!complete) { // } // } @@ -325,7 +337,8 @@ bool RtpVideoReceiver::ProcessH264RtpPacket(RtpPacketH264& rtp_packet_h264) { // } // incomplete_fec_packet_list_[rtp_packet.Timestamp()] - // [rtp_packet.SequenceNumber()] = rtp_packet; + // [rtp_packet.SequenceNumber()] = + // rtp_packet; // uint8_t** complete_frame = fec_decoder_.DecodeWithNewSymbol( // (const char*)incomplete_fec_packet_list_[rtp_packet.Timestamp()] @@ -339,7 +352,8 @@ bool RtpVideoReceiver::ProcessH264RtpPacket(RtpPacketH264& rtp_packet_h264) { // } // size_t complete_frame_size = 0; - // for (int index = 0; index < rtp_packet.FecSourceSymbolNum(); index++) + // for (int index = 0; index < rtp_packet.FecSourceSymbolNum(); + // index++) // { // if (nullptr == complete_frame[index]) { // LOG_ERROR("Invalid complete_frame[{}]", index); @@ -377,7 +391,8 @@ bool RtpVideoReceiver::ProcessH264RtpPacket(RtpPacketH264& rtp_packet_h264) { // } // incomplete_fec_packet_list_[rtp_packet.Timestamp()] - // [rtp_packet.SequenceNumber()] = rtp_packet; + // [rtp_packet.SequenceNumber()] = + // rtp_packet; // uint8_t** complete_frame = fec_decoder_.DecodeWithNewSymbol( // (const char*)incomplete_fec_packet_list_[rtp_packet.Timestamp()] @@ -391,7 +406,8 @@ bool RtpVideoReceiver::ProcessH264RtpPacket(RtpPacketH264& rtp_packet_h264) { // } // size_t complete_frame_size = 0; - // for (int index = 0; index < rtp_packet.FecSourceSymbolNum(); index++) + // for (int index = 0; index < rtp_packet.FecSourceSymbolNum(); + // index++) // { // if (nullptr == complete_frame[index]) { // LOG_ERROR("Invalid complete_frame[{}]", index); @@ -775,8 +791,8 @@ void RtpVideoReceiver::SendRR() { cumulative_lost_ = cumulative_loss_ + cumulative_loss_rtcp_offset_; if (cumulative_lost_ < 0) { - // Clamp to zero. Work around to accommodate for senders that misbehave with - // negative cumulative loss. + // Clamp to zero. Work around to accommodate for senders that misbehave + // with negative cumulative loss. cumulative_lost_ = 0; cumulative_loss_rtcp_offset_ = -cumulative_loss_; } diff --git a/src/transport/channel/video_channel_send.cpp b/src/transport/channel/video_channel_send.cpp index 5a64eef..ce7507d 100644 --- a/src/transport/channel/video_channel_send.cpp +++ b/src/transport/channel/video_channel_send.cpp @@ -1,5 +1,6 @@ #include "video_channel_send.h" +#include "common.h" #include "log.h" #include "rtc_base/network/sent_packet.h" @@ -13,6 +14,8 @@ VideoChannelSend::VideoChannelSend( on_sent_packet_func) : ice_agent_(ice_agent), packet_sender_(packet_sender), + ssrc_(GenerateUniqueSsrc()), + rtx_ssrc_(GenerateUniqueSsrc()), ice_io_statistics_(ice_io_statistics), on_sent_packet_func_(on_sent_packet_func), delta_ntp_internal_ms_(clock->CurrentNtpInMilliseconds() - @@ -38,40 +41,7 @@ VideoChannelSend::~VideoChannelSend() { } void VideoChannelSend::Initialize(rtp::PAYLOAD_TYPE payload_type) { - rtp_video_sender_ = - std::make_unique(clock_, ice_io_statistics_); - rtp_packetizer_ = - RtpPacketizer::Create(payload_type, rtp_video_sender_->GetSsrc()); - rtp_video_sender_->SetSendDataFunc( - [this](const char* data, size_t size) -> int { - if (!ice_agent_) { - LOG_ERROR("ice_agent_ is nullptr"); - return -1; - } - - auto ice_state = ice_agent_->GetIceState(); - - if (ICE_STATE_DESTROYED == ice_state) { - return -2; - } - - ice_io_statistics_->UpdateVideoOutboundBytes((uint32_t)size); - - return ice_agent_->Send(data, size); - }); - - rtp_video_sender_->SetOnSentPacketFunc( - [this](const webrtc::RtpPacketToSend& packet) -> void { - on_sent_packet_func_(packet); - }); - - rtp_video_sender_->Start(); -} - -void VideoChannelSend::SetEnqueuePacketsFunc( - std::function>&)> - enqueue_packets_func) { - rtp_video_sender_->SetEnqueuePacketsFunc(enqueue_packets_func); + rtp_packetizer_ = RtpPacketizer::Create(payload_type, ssrc_); } void VideoChannelSend::OnSentRtpPacket( @@ -116,14 +86,10 @@ std::vector> VideoChannelSend::GeneratePadding( return std::vector>{}; } -void VideoChannelSend::Destroy() { - if (rtp_video_sender_) { - rtp_video_sender_->Stop(); - } -} +void VideoChannelSend::Destroy() {} int VideoChannelSend::SendVideo(const EncodedFrame& encoded_frame) { - if (rtp_video_sender_ && rtp_packetizer_ && packet_sender_) { + if (rtp_packetizer_ && packet_sender_) { int32_t rtp_timestamp = delta_ntp_internal_ms_ + static_cast(encoded_frame.CapturedTimestamp() / 1000); @@ -137,7 +103,7 @@ int VideoChannelSend::SendVideo(const EncodedFrame& encoded_frame) { file_rtp_sent_); #endif - packet_sender_->EnqueueRtpPacket(std::move(rtp_packets), rtp_timestamp); + packet_sender_->EnqueueRtpPackets(std::move(rtp_packets), rtp_timestamp); } return 0; @@ -176,13 +142,13 @@ int32_t VideoChannelSend::ReSendPacket(uint16_t packet_id) { return -1; } + packet->SetSsrc(rtx_ssrc_); + packet->SetPayloadType(rtp::PAYLOAD_TYPE::RTX); packet->set_packet_type(webrtc::RtpPacketMediaType::kRetransmission); packet->set_fec_protect_packet(false); - std::vector> packets; - packets.emplace_back(std::move(packet)); if (packet_sender_) { - packet_sender_->EnqueueRtpPacket(std::move(packets)); + packet_sender_->EnqueueRtpPacket(std::move(packet)); } return packet_size; diff --git a/src/transport/channel/video_channel_send.h b/src/transport/channel/video_channel_send.h index 5ca3ae2..a6b8154 100644 --- a/src/transport/channel/video_channel_send.h +++ b/src/transport/channel/video_channel_send.h @@ -30,11 +30,6 @@ class VideoChannelSend { on_sent_packet_func_); ~VideoChannelSend(); - void SetEnqueuePacketsFunc( - std::function< - void(std::vector>&)> - enqueue_packets_func); - void OnSentRtpPacket(std::unique_ptr packet); void OnReceiveNack(const std::vector& nack_sequence_numbers); @@ -46,18 +41,20 @@ class VideoChannelSend { void Initialize(rtp::PAYLOAD_TYPE payload_type); void Destroy(); - uint32_t GetSsrc() { - if (rtp_video_sender_) { - return rtp_video_sender_->GetSsrc(); - } - return 0; - } + uint32_t GetSsrc() { return ssrc_; } + + uint32_t GetRtxSsrc() { return rtx_ssrc_; } int SendVideo(const EncodedFrame& encoded_frame); void OnReceiverReport(const ReceiverReport& receiver_report) { - if (rtp_video_sender_) { - rtp_video_sender_->OnReceiverReport(receiver_report); + std::vector reports = receiver_report.GetReportBlocks(); + for (auto r : reports) { + LOG_WARN( + "r_ssrc [{}], f_lost [{}], c_lost [{}], h_seq [{}], jitter [{}], " + "lsr [{}], dlsr [{}] ", + r.SourceSsrc(), r.FractionLost() / 255.0, r.CumulativeLost(), + r.ExtendedHighSeqNum(), r.Jitter(), r.LastSr(), r.DelaySinceLastSr()); } } @@ -69,12 +66,13 @@ class VideoChannelSend { std::shared_ptr ice_agent_ = nullptr; std::shared_ptr ice_io_statistics_ = nullptr; std::unique_ptr rtp_packetizer_ = nullptr; - std::unique_ptr rtp_video_sender_ = nullptr; std::function on_sent_packet_func_ = nullptr; private: + uint32_t ssrc_ = 0; + uint32_t rtx_ssrc_ = 0; std::shared_ptr clock_; RtpPacketHistory rtp_packet_history_; int64_t delta_ntp_internal_ms_; diff --git a/src/transport/ice_transport.cpp b/src/transport/ice_transport.cpp index a795396..4a93764 100644 --- a/src/transport/ice_transport.cpp +++ b/src/transport/ice_transport.cpp @@ -206,7 +206,8 @@ void IceTransport::OnReceiveBuffer(NiceAgent *agent, guint stream_id, RtcpPacketInfo rtcp_packet_info; ParseRtcpPacket((const uint8_t *)buffer, size, &rtcp_packet_info); } else { - LOG_ERROR("Unknown packet"); + uint8_t payload_type = buffer[1] & 0x7F; + LOG_ERROR("Unknown packet [{} {}]", payload_type, size); } } } @@ -519,7 +520,7 @@ int IceTransport::AppendLocalCapabilitiesToOffer( std::string to_replace = "ICE/SDP"; std::string video_capabilities = "UDP/TLS/RTP/SAVPF "; std::string audio_capabilities = "UDP/TLS/RTP/SAVPF 111"; - std::string data_capabilities = "UDP/TLS/RTP/SAVPF 127"; + std::string data_capabilities = "UDP/TLS/RTP/SAVPF 120"; switch (video_codec_payload_type_) { case rtp::PAYLOAD_TYPE::H264: { @@ -919,11 +920,15 @@ uint8_t IceTransport::CheckIsRtpPacket(const char *buffer, size_t size) { } uint8_t payload_type = buffer[1] & 0x7F; - if (payload_type == 96 || payload_type == 99 || payload_type == 111 || - payload_type == 127) { + if (payload_type == rtp::PAYLOAD_TYPE::H264 || + payload_type == rtp::PAYLOAD_TYPE::AV1 || + payload_type == rtp::PAYLOAD_TYPE::OPUS || + payload_type == rtp::PAYLOAD_TYPE::RTX || + payload_type == rtp::PAYLOAD_TYPE::DATA) { return payload_type; - } else if (payload_type == 95 || payload_type == 98 || payload_type == 110 || - payload_type == 126) { + } else if (payload_type == rtp::PAYLOAD_TYPE::H264 - 1 || + payload_type == rtp::PAYLOAD_TYPE::AV1 - 1 || + payload_type == rtp::PAYLOAD_TYPE::OPUS - 1) { return payload_type; } else { return 0; @@ -960,7 +965,8 @@ uint8_t IceTransport::CheckIsVideoPacket(const char *buffer, size_t size) { (rtp::PAYLOAD_TYPE::H264_FEC_SOURCE - 1) == pt || rtp::PAYLOAD_TYPE::H264_FEC_REPAIR == pt || (rtp::PAYLOAD_TYPE::H264_FEC_REPAIR - 1) == pt || - rtp::PAYLOAD_TYPE::AV1 == pt || (rtp::PAYLOAD_TYPE::AV1 - 1) == pt) { + rtp::PAYLOAD_TYPE::AV1 == pt || (rtp::PAYLOAD_TYPE::AV1 - 1) == pt || + rtp::PAYLOAD_TYPE::RTX == pt) { return pt; } else { return 0; diff --git a/src/transport/ice_transport.h b/src/transport/ice_transport.h index 658b6db..668759d 100644 --- a/src/transport/ice_transport.h +++ b/src/transport/ice_transport.h @@ -20,7 +20,7 @@ class IceTransport { public: - typedef enum { VIDEO = 96, AUDIO = 97, DATA = 127 } DATA_TYPE; + typedef enum { VIDEO = 96, AUDIO = 97, DATA = 120 } DATA_TYPE; typedef enum { H264 = 96, AV1 = 99 } VIDEO_TYPE; enum VideoFrameType { kEmptyFrame = 0, diff --git a/src/transport/ice_transport_controller.cpp b/src/transport/ice_transport_controller.cpp index 47ba241..7add7b2 100644 --- a/src/transport/ice_transport_controller.cpp +++ b/src/transport/ice_transport_controller.cpp @@ -123,13 +123,6 @@ void IceTransportController::Create( if (video_channel_send_) { video_channel_send_->Initialize(video_codec_payload_type); - video_channel_send_->SetEnqueuePacketsFunc( - [this](std::vector>& packets) - -> void { - if (packet_sender_) { - packet_sender_->EnqueuePackets(std::move(packets)); - } - }); } if (audio_channel_send_) { diff --git a/src/transport/packet_sender/packet_sender.h b/src/transport/packet_sender/packet_sender.h index a780971..91ad1dd 100644 --- a/src/transport/packet_sender/packet_sender.h +++ b/src/transport/packet_sender/packet_sender.h @@ -19,13 +19,15 @@ class PacketSender { virtual ~PacketSender() {} virtual int Send() = 0; - virtual int EnqueueRtpPacket( + virtual int EnqueueRtpPackets( std::vector>& rtp_packets, int64_t captured_timestamp_us) = 0; - virtual int EnqueueRtpPacket( + virtual int EnqueueRtpPackets( std::vector>& rtp_packets) = 0; - ; + + virtual int EnqueueRtpPacket( + std::unique_ptr rtp_packet) = 0; }; #endif \ No newline at end of file diff --git a/src/transport/packet_sender/packet_sender_imp.cpp b/src/transport/packet_sender/packet_sender_imp.cpp index 86df7a3..97c11b5 100644 --- a/src/transport/packet_sender/packet_sender_imp.cpp +++ b/src/transport/packet_sender/packet_sender_imp.cpp @@ -95,6 +95,20 @@ void PacketSenderImp::EnqueuePackets( }); } +void PacketSenderImp::EnqueuePacket( + std::unique_ptr packet) { + task_queue_->PostTask([this, packet = std::move(packet)]() mutable { + size_t packet_size = packet->payload_size() + packet->padding_size(); + if (include_overhead_) { + packet_size += packet->headers_size(); + } + packet_size_.Apply(1, packet_size); + pacing_controller_.EnqueuePacket(std::move(packet)); + + MaybeProcessPackets(webrtc::Timestamp::MinusInfinity()); + }); +} + void PacketSenderImp::RemovePacketsForSsrc(uint32_t ssrc) { task_queue_->PostTask([this, ssrc] { pacing_controller_.RemovePacketsForSsrc(ssrc); @@ -164,7 +178,6 @@ void PacketSenderImp::MaybeScheduleProcessPackets() { void PacketSenderImp::MaybeProcessPackets( webrtc::Timestamp scheduled_process_time) { if (is_shutdown_ || !is_started_) { - LOG_ERROR("shutdown {}, started {}", is_shutdown_, is_started_); return; } @@ -251,7 +264,7 @@ PacketSenderImp::Stats PacketSenderImp::GetStats() const { /*----------------------------------------------------------------------------*/ -int PacketSenderImp::EnqueueRtpPacket( +int PacketSenderImp::EnqueueRtpPackets( std::vector> &rtp_packets, int64_t captured_timestamp_us) { std::vector> to_send_rtp_packets; @@ -293,8 +306,14 @@ int PacketSenderImp::EnqueueRtpPacket( return 0; } -int PacketSenderImp::EnqueueRtpPacket( +int PacketSenderImp::EnqueueRtpPackets( std::vector> &rtp_packets) { EnqueuePackets(std::move(rtp_packets)); return 0; +} + +int PacketSenderImp::EnqueueRtpPacket( + std::unique_ptr rtp_packet) { + EnqueuePacket(std::move(rtp_packet)); + return 0; } \ No newline at end of file diff --git a/src/transport/packet_sender/packet_sender_imp.h b/src/transport/packet_sender/packet_sender_imp.h index 3ef57e0..867007e 100644 --- a/src/transport/packet_sender/packet_sender_imp.h +++ b/src/transport/packet_sender/packet_sender_imp.h @@ -38,11 +38,14 @@ class PacketSenderImp : public PacketSender, public: int Send() override { return 0; } - int EnqueueRtpPacket(std::vector>& rtp_packets, - int64_t captured_timestamp_us) override; + int EnqueueRtpPackets(std::vector>& rtp_packets, + int64_t captured_timestamp_us) override; - int EnqueueRtpPacket(std::vector>& - rtp_packets) override; + int EnqueueRtpPackets(std::vector>& + rtp_packets) override; + + int EnqueueRtpPacket( + std::unique_ptr rtp_packet) override; public: void SetOnSentPacketFunc( @@ -109,6 +112,7 @@ class PacketSenderImp : public PacketSender, // PacingController::PacketSenderImp::SendPacket() when it's time to send. void EnqueuePackets( std::vector> packets); + void EnqueuePacket(std::unique_ptr packet); // Remove any pending packets matching this SSRC from the packet queue. void RemovePacketsForSsrc(uint32_t ssrc);