mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-27 04:35:34 +08:00
[feat] introduce fraction lost into congestion control module
This commit is contained in:
61
src/channel/meida_channel/audio_channel_receive.cpp
Normal file
61
src/channel/meida_channel/audio_channel_receive.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#include "audio_channel_receive.h"
|
||||
|
||||
#include "log.h"
|
||||
|
||||
AudioChannelReceive::AudioChannelReceive() {}
|
||||
|
||||
AudioChannelReceive::AudioChannelReceive(
|
||||
std::shared_ptr<IceAgent> ice_agent,
|
||||
std::shared_ptr<IOStatistics> ice_io_statistics,
|
||||
std::function<void(const char *, size_t)> on_receive_audio)
|
||||
: ice_agent_(ice_agent),
|
||||
ice_io_statistics_(ice_io_statistics),
|
||||
on_receive_audio_(on_receive_audio) {}
|
||||
|
||||
AudioChannelReceive::~AudioChannelReceive() {}
|
||||
|
||||
void AudioChannelReceive::Initialize(rtp::PAYLOAD_TYPE payload_type) {
|
||||
rtp_audio_receiver_ = std::make_unique<RtpAudioReceiver>(ice_io_statistics_);
|
||||
rtp_audio_receiver_->SetOnReceiveData(
|
||||
[this](const char *data, size_t size) -> void {
|
||||
if (on_receive_audio_) {
|
||||
on_receive_audio_(data, size);
|
||||
}
|
||||
});
|
||||
|
||||
rtp_audio_receiver_->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 != NICE_COMPONENT_STATE_CONNECTED &&
|
||||
ice_state != NICE_COMPONENT_STATE_READY) {
|
||||
LOG_ERROR("Ice is not connected, state = [{}]",
|
||||
nice_component_state_to_string(ice_state));
|
||||
return -2;
|
||||
}
|
||||
|
||||
ice_io_statistics_->UpdateAudioOutboundBytes((uint32_t)size);
|
||||
return ice_agent_->Send(data, size);
|
||||
});
|
||||
}
|
||||
|
||||
void AudioChannelReceive::Destroy() {}
|
||||
|
||||
int AudioChannelReceive::OnReceiveRtpPacket(const char *data, size_t size) {
|
||||
if (ice_io_statistics_) {
|
||||
ice_io_statistics_->UpdateAudioInboundBytes((uint32_t)size);
|
||||
}
|
||||
|
||||
if (rtp_audio_receiver_) {
|
||||
RtpPacket rtp_packet;
|
||||
rtp_packet.Build((uint8_t *)data, (uint32_t)size);
|
||||
rtp_audio_receiver_->InsertRtpPacket(rtp_packet);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
55
src/channel/meida_channel/audio_channel_receive.h
Normal file
55
src/channel/meida_channel/audio_channel_receive.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* @Author: DI JUNKUN
|
||||
* @Date: 2025-01-03
|
||||
* Copyright (c) 2025 by DI JUNKUN, All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _AUDIO_CHANNEL_RECEIVE_H_
|
||||
#define _AUDIO_CHANNEL_RECEIVE_H_
|
||||
|
||||
#include "ice_agent.h"
|
||||
#include "rtp_audio_receiver.h"
|
||||
|
||||
class AudioChannelReceive {
|
||||
public:
|
||||
AudioChannelReceive();
|
||||
AudioChannelReceive(
|
||||
std::shared_ptr<IceAgent> ice_agent,
|
||||
std::shared_ptr<IOStatistics> ice_io_statistics,
|
||||
std::function<void(const char *, size_t)> on_receive_audio);
|
||||
~AudioChannelReceive();
|
||||
|
||||
public:
|
||||
void Initialize(rtp::PAYLOAD_TYPE payload_type);
|
||||
void Destroy();
|
||||
|
||||
uint32_t GetSsrc() {
|
||||
if (rtp_audio_receiver_) {
|
||||
return rtp_audio_receiver_->GetSsrc();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t GetRemoteSsrc() {
|
||||
if (rtp_audio_receiver_) {
|
||||
return rtp_audio_receiver_->GetRemoteSsrc();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int OnReceiveRtpPacket(const char *data, size_t size);
|
||||
|
||||
void OnSenderReport(const SenderReport &sender_report) {
|
||||
if (rtp_audio_receiver_) {
|
||||
rtp_audio_receiver_->OnSenderReport(sender_report);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<IceAgent> ice_agent_ = nullptr;
|
||||
std::shared_ptr<IOStatistics> ice_io_statistics_ = nullptr;
|
||||
std::unique_ptr<RtpAudioReceiver> rtp_audio_receiver_ = nullptr;
|
||||
std::function<void(const char *, size_t)> on_receive_audio_ = nullptr;
|
||||
};
|
||||
|
||||
#endif
|
||||
56
src/channel/meida_channel/audio_channel_send.cpp
Normal file
56
src/channel/meida_channel/audio_channel_send.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#include "audio_channel_send.h"
|
||||
|
||||
#include "log.h"
|
||||
|
||||
AudioChannelSend::AudioChannelSend() {}
|
||||
|
||||
AudioChannelSend::~AudioChannelSend() {}
|
||||
|
||||
AudioChannelSend::AudioChannelSend(
|
||||
std::shared_ptr<IceAgent> ice_agent,
|
||||
std::shared_ptr<IOStatistics> ice_io_statistics)
|
||||
: ice_agent_(ice_agent), ice_io_statistics_(ice_io_statistics) {}
|
||||
|
||||
void AudioChannelSend::Initialize(rtp::PAYLOAD_TYPE payload_type) {
|
||||
rtp_audio_sender_ = std::make_unique<RtpAudioSender>(ice_io_statistics_);
|
||||
rtp_packetizer_ =
|
||||
RtpPacketizer::Create(payload_type, rtp_audio_sender_->GetSsrc());
|
||||
|
||||
rtp_audio_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 != NICE_COMPONENT_STATE_CONNECTED &&
|
||||
ice_state != NICE_COMPONENT_STATE_READY) {
|
||||
LOG_ERROR("Ice is not connected, state = [{}]",
|
||||
nice_component_state_to_string(ice_state));
|
||||
return -2;
|
||||
}
|
||||
|
||||
ice_io_statistics_->UpdateAudioOutboundBytes((uint32_t)size);
|
||||
return ice_agent_->Send(data, size);
|
||||
});
|
||||
|
||||
rtp_audio_sender_->Start();
|
||||
}
|
||||
|
||||
void AudioChannelSend::Destroy() {
|
||||
if (rtp_audio_sender_) {
|
||||
rtp_audio_sender_->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
int AudioChannelSend::SendAudio(char *data, size_t size) {
|
||||
if (rtp_audio_sender_ && rtp_packetizer_) {
|
||||
std::vector<std::shared_ptr<RtpPacket>> rtp_packets =
|
||||
rtp_packetizer_->Build((uint8_t *)data, (uint32_t)size, 0, true);
|
||||
rtp_audio_sender_->Enqueue(rtp_packets);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
43
src/channel/meida_channel/audio_channel_send.h
Normal file
43
src/channel/meida_channel/audio_channel_send.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* @Author: DI JUNKUN
|
||||
* @Date: 2025-01-03
|
||||
* Copyright (c) 2025 by DI JUNKUN, All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _AUDIO_CHANNEL_SEND_H_
|
||||
#define _AUDIO_CHANNEL_SEND_H_
|
||||
|
||||
#include "ice_agent.h"
|
||||
#include "rtp_audio_sender.h"
|
||||
#include "rtp_packetizer.h"
|
||||
|
||||
class AudioChannelSend {
|
||||
public:
|
||||
AudioChannelSend();
|
||||
AudioChannelSend(std::shared_ptr<IceAgent> ice_agent,
|
||||
std::shared_ptr<IOStatistics> ice_io_statistics);
|
||||
~AudioChannelSend();
|
||||
|
||||
public:
|
||||
void Initialize(rtp::PAYLOAD_TYPE payload_type);
|
||||
void Destroy();
|
||||
|
||||
uint32_t GetSsrc() {
|
||||
if (rtp_audio_sender_) {
|
||||
return rtp_audio_sender_->GetSsrc();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SendAudio(char* data, size_t size);
|
||||
|
||||
void OnReceiverReport(const ReceiverReport& receiver_report) {}
|
||||
|
||||
private:
|
||||
std::shared_ptr<IceAgent> ice_agent_ = nullptr;
|
||||
std::shared_ptr<IOStatistics> ice_io_statistics_ = nullptr;
|
||||
std::unique_ptr<RtpPacketizer> rtp_packetizer_ = nullptr;
|
||||
std::unique_ptr<RtpAudioSender> rtp_audio_sender_ = nullptr;
|
||||
};
|
||||
|
||||
#endif
|
||||
61
src/channel/meida_channel/data_channel_receive.cpp
Normal file
61
src/channel/meida_channel/data_channel_receive.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#include "data_channel_receive.h"
|
||||
|
||||
#include "log.h"
|
||||
|
||||
DataChannelReceive::DataChannelReceive() {}
|
||||
|
||||
DataChannelReceive::DataChannelReceive(
|
||||
std::shared_ptr<IceAgent> ice_agent,
|
||||
std::shared_ptr<IOStatistics> ice_io_statistics,
|
||||
std::function<void(const char *, size_t)> on_receive_data)
|
||||
: ice_agent_(ice_agent),
|
||||
ice_io_statistics_(ice_io_statistics),
|
||||
on_receive_data_(on_receive_data) {}
|
||||
|
||||
DataChannelReceive::~DataChannelReceive() {}
|
||||
|
||||
void DataChannelReceive::Initialize(rtp::PAYLOAD_TYPE payload_type) {
|
||||
rtp_data_receiver_ = std::make_unique<RtpDataReceiver>(ice_io_statistics_);
|
||||
rtp_data_receiver_->SetOnReceiveData(
|
||||
[this](const char *data, size_t size) -> void {
|
||||
if (on_receive_data_) {
|
||||
on_receive_data_(data, size);
|
||||
}
|
||||
});
|
||||
|
||||
rtp_data_receiver_->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 != NICE_COMPONENT_STATE_CONNECTED &&
|
||||
ice_state != NICE_COMPONENT_STATE_READY) {
|
||||
LOG_ERROR("Ice is not connected, state = [{}]",
|
||||
nice_component_state_to_string(ice_state));
|
||||
return -2;
|
||||
}
|
||||
|
||||
ice_io_statistics_->UpdateDataOutboundBytes((uint32_t)size);
|
||||
return ice_agent_->Send(data, size);
|
||||
});
|
||||
}
|
||||
|
||||
void DataChannelReceive::Destroy() {}
|
||||
|
||||
int DataChannelReceive::OnReceiveRtpPacket(const char *data, size_t size) {
|
||||
if (ice_io_statistics_) {
|
||||
ice_io_statistics_->UpdateDataInboundBytes((uint32_t)size);
|
||||
}
|
||||
|
||||
if (rtp_data_receiver_) {
|
||||
RtpPacket rtp_packet;
|
||||
rtp_packet.Build((uint8_t *)data, (uint32_t)size);
|
||||
rtp_data_receiver_->InsertRtpPacket(rtp_packet);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
54
src/channel/meida_channel/data_channel_receive.h
Normal file
54
src/channel/meida_channel/data_channel_receive.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* @Author: DI JUNKUN
|
||||
* @Date: 2025-01-03
|
||||
* Copyright (c) 2025 by DI JUNKUN, All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DATA_CHANNEL_RECEIVE_H_
|
||||
#define _DATA_CHANNEL_RECEIVE_H_
|
||||
|
||||
#include "ice_agent.h"
|
||||
#include "rtp_data_receiver.h"
|
||||
|
||||
class DataChannelReceive {
|
||||
public:
|
||||
DataChannelReceive();
|
||||
DataChannelReceive(std::shared_ptr<IceAgent> ice_agent,
|
||||
std::shared_ptr<IOStatistics> ice_io_statistics,
|
||||
std::function<void(const char *, size_t)> on_receive_data);
|
||||
~DataChannelReceive();
|
||||
|
||||
public:
|
||||
void Initialize(rtp::PAYLOAD_TYPE payload_type);
|
||||
void Destroy();
|
||||
|
||||
uint32_t GetSsrc() {
|
||||
if (rtp_data_receiver_) {
|
||||
return rtp_data_receiver_->GetSsrc();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t GetRemoteSsrc() {
|
||||
if (rtp_data_receiver_) {
|
||||
return rtp_data_receiver_->GetRemoteSsrc();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int OnReceiveRtpPacket(const char *data, size_t size);
|
||||
|
||||
void OnSenderReport(const SenderReport &sender_report) {
|
||||
if (rtp_data_receiver_) {
|
||||
rtp_data_receiver_->OnSenderReport(sender_report);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<IceAgent> ice_agent_ = nullptr;
|
||||
std::shared_ptr<IOStatistics> ice_io_statistics_ = nullptr;
|
||||
std::unique_ptr<RtpDataReceiver> rtp_data_receiver_ = nullptr;
|
||||
std::function<void(const char *, size_t)> on_receive_data_ = nullptr;
|
||||
};
|
||||
|
||||
#endif
|
||||
56
src/channel/meida_channel/data_channel_send.cpp
Normal file
56
src/channel/meida_channel/data_channel_send.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#include "data_channel_send.h"
|
||||
|
||||
#include "log.h"
|
||||
|
||||
DataChannelSend::DataChannelSend() {}
|
||||
|
||||
DataChannelSend::~DataChannelSend() {}
|
||||
|
||||
DataChannelSend::DataChannelSend(
|
||||
std::shared_ptr<IceAgent> ice_agent,
|
||||
std::shared_ptr<IOStatistics> ice_io_statistics)
|
||||
: ice_agent_(ice_agent), ice_io_statistics_(ice_io_statistics) {}
|
||||
|
||||
void DataChannelSend::Initialize(rtp::PAYLOAD_TYPE payload_type) {
|
||||
rtp_data_sender_ = std::make_unique<RtpDataSender>(ice_io_statistics_);
|
||||
rtp_packetizer_ =
|
||||
RtpPacketizer::Create(payload_type, rtp_data_sender_->GetSsrc());
|
||||
|
||||
rtp_data_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 != NICE_COMPONENT_STATE_CONNECTED &&
|
||||
ice_state != NICE_COMPONENT_STATE_READY) {
|
||||
LOG_ERROR("Ice is not connected, state = [{}]",
|
||||
nice_component_state_to_string(ice_state));
|
||||
return -2;
|
||||
}
|
||||
|
||||
ice_io_statistics_->UpdateDataOutboundBytes((uint32_t)size);
|
||||
return ice_agent_->Send(data, size);
|
||||
});
|
||||
|
||||
rtp_data_sender_->Start();
|
||||
}
|
||||
|
||||
void DataChannelSend::Destroy() {
|
||||
if (rtp_data_sender_) {
|
||||
rtp_data_sender_->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
int DataChannelSend::SendData(const char *data, size_t size) {
|
||||
if (rtp_data_sender_ && rtp_packetizer_) {
|
||||
std::vector<std::shared_ptr<RtpPacket>> rtp_packets =
|
||||
rtp_packetizer_->Build((uint8_t *)data, (uint32_t)size, 0, true);
|
||||
rtp_data_sender_->Enqueue(rtp_packets);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
43
src/channel/meida_channel/data_channel_send.h
Normal file
43
src/channel/meida_channel/data_channel_send.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* @Author: DI JUNKUN
|
||||
* @Date: 2025-01-03
|
||||
* Copyright (c) 2025 by DI JUNKUN, All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DATA_CHANNEL_SEND_H_
|
||||
#define _DATA_CHANNEL_SEND_H_
|
||||
|
||||
#include "ice_agent.h"
|
||||
#include "rtp_data_sender.h"
|
||||
#include "rtp_packetizer.h"
|
||||
|
||||
class DataChannelSend {
|
||||
public:
|
||||
DataChannelSend();
|
||||
DataChannelSend(std::shared_ptr<IceAgent> ice_agent,
|
||||
std::shared_ptr<IOStatistics> ice_io_statistics);
|
||||
~DataChannelSend();
|
||||
|
||||
public:
|
||||
void Initialize(rtp::PAYLOAD_TYPE payload_type);
|
||||
void Destroy();
|
||||
|
||||
uint32_t GetSsrc() {
|
||||
if (rtp_data_sender_) {
|
||||
return rtp_data_sender_->GetSsrc();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SendData(const char* data, size_t size);
|
||||
|
||||
void OnReceiverReport(const ReceiverReport& receiver_report) {}
|
||||
|
||||
private:
|
||||
std::shared_ptr<IceAgent> ice_agent_ = nullptr;
|
||||
std::shared_ptr<IOStatistics> ice_io_statistics_ = nullptr;
|
||||
std::unique_ptr<RtpPacketizer> rtp_packetizer_ = nullptr;
|
||||
std::unique_ptr<RtpDataSender> rtp_data_sender_ = nullptr;
|
||||
};
|
||||
|
||||
#endif
|
||||
67
src/channel/meida_channel/video_channel_receive.cpp
Normal file
67
src/channel/meida_channel/video_channel_receive.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
#include "video_channel_receive.h"
|
||||
|
||||
#include "log.h"
|
||||
|
||||
VideoChannelReceive::VideoChannelReceive() {}
|
||||
|
||||
VideoChannelReceive::VideoChannelReceive(
|
||||
std::shared_ptr<SystemClock> clock, std::shared_ptr<IceAgent> ice_agent,
|
||||
std::shared_ptr<IOStatistics> ice_io_statistics,
|
||||
std::function<void(VideoFrame &)> on_receive_complete_frame)
|
||||
: ice_agent_(ice_agent),
|
||||
ice_io_statistics_(ice_io_statistics),
|
||||
on_receive_complete_frame_(on_receive_complete_frame),
|
||||
clock_(clock) {}
|
||||
|
||||
VideoChannelReceive::~VideoChannelReceive() {}
|
||||
|
||||
void VideoChannelReceive::Initialize(rtp::PAYLOAD_TYPE payload_type) {
|
||||
rtp_video_receiver_ =
|
||||
std::make_unique<RtpVideoReceiver>(clock_, ice_io_statistics_);
|
||||
rtp_video_receiver_->SetOnReceiveCompleteFrame(
|
||||
[this](VideoFrame &video_frame) -> void {
|
||||
on_receive_complete_frame_(video_frame);
|
||||
});
|
||||
|
||||
rtp_video_receiver_->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 != NICE_COMPONENT_STATE_CONNECTED &&
|
||||
ice_state != NICE_COMPONENT_STATE_READY) {
|
||||
LOG_ERROR("Ice is not connected, state = [{}]",
|
||||
nice_component_state_to_string(ice_state));
|
||||
return -2;
|
||||
}
|
||||
|
||||
ice_io_statistics_->UpdateVideoOutboundBytes((uint32_t)size);
|
||||
return ice_agent_->Send(data, size);
|
||||
});
|
||||
|
||||
rtp_video_receiver_->Start();
|
||||
}
|
||||
|
||||
void VideoChannelReceive::Destroy() {
|
||||
if (rtp_video_receiver_) {
|
||||
rtp_video_receiver_->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
int VideoChannelReceive::OnReceiveRtpPacket(const char *data, size_t size) {
|
||||
if (ice_io_statistics_) {
|
||||
ice_io_statistics_->UpdateVideoInboundBytes((uint32_t)size);
|
||||
}
|
||||
|
||||
if (rtp_video_receiver_) {
|
||||
RtpPacket rtp_packet;
|
||||
rtp_packet.Build((uint8_t *)data, (uint32_t)size);
|
||||
rtp_video_receiver_->InsertRtpPacket(rtp_packet);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
60
src/channel/meida_channel/video_channel_receive.h
Normal file
60
src/channel/meida_channel/video_channel_receive.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* @Author: DI JUNKUN
|
||||
* @Date: 2025-01-03
|
||||
* Copyright (c) 2025 by DI JUNKUN, All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _VIDEO_CHANNEL_RECEIVE_H_
|
||||
#define _VIDEO_CHANNEL_RECEIVE_H_
|
||||
|
||||
#include "clock/system_clock.h"
|
||||
#include "ice_agent.h"
|
||||
#include "rtp_video_receiver.h"
|
||||
|
||||
class VideoChannelReceive {
|
||||
public:
|
||||
VideoChannelReceive();
|
||||
VideoChannelReceive(
|
||||
std::shared_ptr<SystemClock> clock, std::shared_ptr<IceAgent> ice_agent,
|
||||
std::shared_ptr<IOStatistics> ice_io_statistics,
|
||||
std::function<void(VideoFrame &)> on_receive_complete_frame);
|
||||
|
||||
~VideoChannelReceive();
|
||||
|
||||
public:
|
||||
void Initialize(rtp::PAYLOAD_TYPE payload_type);
|
||||
void Destroy();
|
||||
|
||||
uint32_t GetSsrc() {
|
||||
if (rtp_video_receiver_) {
|
||||
return rtp_video_receiver_->GetSsrc();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t GetRemoteSsrc() {
|
||||
if (rtp_video_receiver_) {
|
||||
return rtp_video_receiver_->GetRemoteSsrc();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int OnReceiveRtpPacket(const char *data, size_t size);
|
||||
|
||||
void OnSenderReport(const SenderReport &sender_report) {
|
||||
if (rtp_video_receiver_) {
|
||||
rtp_video_receiver_->OnSenderReport(sender_report);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<IceAgent> ice_agent_ = nullptr;
|
||||
std::shared_ptr<IOStatistics> ice_io_statistics_ = nullptr;
|
||||
std::unique_ptr<RtpVideoReceiver> rtp_video_receiver_ = nullptr;
|
||||
std::function<void(VideoFrame &)> on_receive_complete_frame_ = nullptr;
|
||||
|
||||
private:
|
||||
std::shared_ptr<SystemClock> clock_;
|
||||
};
|
||||
|
||||
#endif
|
||||
71
src/channel/meida_channel/video_channel_send.cpp
Normal file
71
src/channel/meida_channel/video_channel_send.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
#include "video_channel_send.h"
|
||||
|
||||
#include "log.h"
|
||||
#include "rtc_base/network/sent_packet.h"
|
||||
|
||||
VideoChannelSend::VideoChannelSend() {}
|
||||
|
||||
VideoChannelSend::~VideoChannelSend() {}
|
||||
|
||||
VideoChannelSend::VideoChannelSend(
|
||||
std::shared_ptr<SystemClock> clock, std::shared_ptr<IceAgent> ice_agent,
|
||||
std::shared_ptr<IOStatistics> ice_io_statistics,
|
||||
std::function<void(const webrtc::RtpPacketToSend& packet)>
|
||||
on_sent_packet_func)
|
||||
: ice_agent_(ice_agent),
|
||||
ice_io_statistics_(ice_io_statistics),
|
||||
on_sent_packet_func_(on_sent_packet_func),
|
||||
clock_(clock){};
|
||||
|
||||
void VideoChannelSend::Initialize(rtp::PAYLOAD_TYPE payload_type) {
|
||||
rtp_video_sender_ =
|
||||
std::make_unique<RtpVideoSender>(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 != NICE_COMPONENT_STATE_CONNECTED &&
|
||||
ice_state != NICE_COMPONENT_STATE_READY) {
|
||||
// LOG_ERROR("Ice is not connected, state = [{}]",
|
||||
// nice_component_state_to_string(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::Destroy() {
|
||||
if (rtp_video_sender_) {
|
||||
rtp_video_sender_->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
int VideoChannelSend::SendVideo(
|
||||
std::shared_ptr<VideoFrameWrapper> encoded_frame) {
|
||||
if (rtp_video_sender_ && rtp_packetizer_) {
|
||||
std::vector<std::shared_ptr<RtpPacket>> rtp_packets =
|
||||
rtp_packetizer_->Build((uint8_t*)encoded_frame->Buffer(),
|
||||
(uint32_t)encoded_frame->Size(),
|
||||
encoded_frame->CaptureTimestamp(), true);
|
||||
rtp_video_sender_->Enqueue(rtp_packets, encoded_frame->CaptureTimestamp());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
72
src/channel/meida_channel/video_channel_send.h
Normal file
72
src/channel/meida_channel/video_channel_send.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* @Author: DI JUNKUN
|
||||
* @Date: 2025-01-03
|
||||
* Copyright (c) 2025 by DI JUNKUN, All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _VIDEO_CHANNEL_SEND_H_
|
||||
#define _VIDEO_CHANNEL_SEND_H_
|
||||
|
||||
#include "api/transport/network_types.h"
|
||||
#include "api/units/timestamp.h"
|
||||
#include "clock/system_clock.h"
|
||||
#include "congestion_control.h"
|
||||
#include "congestion_control_feedback.h"
|
||||
#include "ice_agent.h"
|
||||
#include "rtp_packetizer.h"
|
||||
#include "rtp_video_sender.h"
|
||||
#include "transport_feedback_adapter.h"
|
||||
#include "video_frame_wrapper.h"
|
||||
|
||||
class VideoChannelSend {
|
||||
public:
|
||||
VideoChannelSend();
|
||||
VideoChannelSend(std::shared_ptr<SystemClock> clock,
|
||||
std::shared_ptr<IceAgent> ice_agent,
|
||||
std::shared_ptr<IOStatistics> ice_io_statistics,
|
||||
std::function<void(const webrtc::RtpPacketToSend& packet)>
|
||||
on_sent_packet_func_);
|
||||
~VideoChannelSend();
|
||||
|
||||
public:
|
||||
void Initialize(rtp::PAYLOAD_TYPE payload_type);
|
||||
void Destroy();
|
||||
|
||||
uint32_t GetSsrc() {
|
||||
if (rtp_video_sender_) {
|
||||
return rtp_video_sender_->GetSsrc();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SendVideo(std::shared_ptr<VideoFrameWrapper> encoded_frame);
|
||||
|
||||
void OnCongestionControlFeedback(
|
||||
Timestamp recv_ts,
|
||||
const webrtc::rtcp::CongestionControlFeedback& feedback);
|
||||
|
||||
void OnReceiverReport(const ReceiverReport& receiver_report) {
|
||||
if (rtp_video_sender_) {
|
||||
rtp_video_sender_->OnReceiverReport(receiver_report);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void PostUpdates(webrtc::NetworkControlUpdate update);
|
||||
void UpdateControlState();
|
||||
void UpdateCongestedState();
|
||||
|
||||
private:
|
||||
std::shared_ptr<IceAgent> ice_agent_ = nullptr;
|
||||
std::shared_ptr<IOStatistics> ice_io_statistics_ = nullptr;
|
||||
std::unique_ptr<RtpPacketizer> rtp_packetizer_ = nullptr;
|
||||
std::unique_ptr<RtpVideoSender> rtp_video_sender_ = nullptr;
|
||||
|
||||
std::function<void(const webrtc::RtpPacketToSend& packet)>
|
||||
on_sent_packet_func_ = nullptr;
|
||||
|
||||
private:
|
||||
std::shared_ptr<SystemClock> clock_;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user