精简复用rtp encoder创建相关代码

This commit is contained in:
ziyue 2022-08-05 17:36:51 +08:00
parent d3ac296228
commit f85de2e108
5 changed files with 98 additions and 116 deletions

View File

@ -95,71 +95,72 @@ Track::Ptr Factory::getTrackBySdp(const SdpTrack::Ptr &track) {
} }
} }
Track::Ptr Factory::getTrackByAbstractTrack(const Track::Ptr& track) { Track::Ptr Factory::getTrackByAbstractTrack(const Track::Ptr& track) {
auto codec = track->getCodecId(); auto codec = track->getCodecId();
switch (codec) { switch (codec) {
case CodecG711A: case CodecG711A:
case CodecG711U: { case CodecG711U: {
auto audio_track = dynamic_pointer_cast<AudioTrackImp>(track); auto audio_track = dynamic_pointer_cast<AudioTrackImp>(track);
return std::make_shared<G711Track>(codec, audio_track->getAudioSampleRate(), audio_track->getAudioChannel(), 16); return std::make_shared<G711Track>(codec, audio_track->getAudioSampleRate(), audio_track->getAudioChannel(), 16);
} }
case CodecL16: { case CodecL16: {
auto audio_track = dynamic_pointer_cast<AudioTrackImp>(track); auto audio_track = dynamic_pointer_cast<AudioTrackImp>(track);
return std::make_shared<L16Track>(audio_track->getAudioSampleRate(), audio_track->getAudioChannel()); return std::make_shared<L16Track>(audio_track->getAudioSampleRate(), audio_track->getAudioChannel());
} }
case CodecAAC : return std::make_shared<AACTrack>(); case CodecAAC: return std::make_shared<AACTrack>();
case CodecOpus : return std::make_shared<OpusTrack>(); case CodecOpus: return std::make_shared<OpusTrack>();
case CodecH265 : return std::make_shared<H265Track>(); case CodecH265: return std::make_shared<H265Track>();
case CodecH264 : return std::make_shared<H264Track>(); case CodecH264: return std::make_shared<H264Track>();
default: { default: {
//其他codec不支持 //其他codec不支持
WarnL << "暂不支持该该编码类型创建Track:" << track->getCodecName(); WarnL << "暂不支持该该编码类型创建Track:" << track->getCodecName();
return nullptr; return nullptr;
} }
} }
} }
RtpCodec::Ptr Factory::getRtpEncoderBySdp(const Sdp::Ptr &sdp) { RtpCodec::Ptr Factory::getRtpEncoderByCodecId(CodecId codec_id, uint32_t sample_rate, uint8_t pt, uint32_t ssrc) {
GET_CONFIG(uint32_t,audio_mtu,Rtp::kAudioMtuSize); GET_CONFIG(uint32_t, audio_mtu, Rtp::kAudioMtuSize);
GET_CONFIG(uint32_t,video_mtu,Rtp::kVideoMtuSize); GET_CONFIG(uint32_t, video_mtu, Rtp::kVideoMtuSize);
// ssrc不冲突即可,可以为任意的32位整形 auto type = getTrackType(codec_id);
static atomic<uint32_t> s_ssrc(0); auto mtu = type == TrackVideo ? video_mtu : audio_mtu;
uint32_t ssrc = s_ssrc++; auto interleaved = type * 2;
if(!ssrc){ switch (codec_id) {
//ssrc不能为0 case CodecH264: return std::make_shared<H264RtpEncoder>(ssrc, mtu, sample_rate, pt, interleaved);
ssrc = 1; case CodecH265: return std::make_shared<H265RtpEncoder>(ssrc, mtu, sample_rate, pt, interleaved);
} case CodecAAC: return std::make_shared<AACRtpEncoder>(ssrc, mtu, sample_rate, pt, interleaved);
if(sdp->getTrackType() == TrackVideo){ case CodecL16:
//视频的ssrc是偶数方便调试 case CodecOpus: return std::make_shared<CommonRtpEncoder>(codec_id, ssrc, mtu, sample_rate, pt, interleaved);
ssrc = 2 * ssrc; case CodecG711A:
}else{ case CodecG711U: {
//音频ssrc是奇数
ssrc = 2 * ssrc + 1;
}
auto mtu = (sdp->getTrackType() == TrackVideo ? video_mtu : audio_mtu);
auto sample_rate = sdp->getSampleRate();
auto pt = sdp->getPayloadType();
auto interleaved = sdp->getTrackType() * 2;
auto codec_id = sdp->getCodecId();
switch (codec_id){
case CodecH264 : return std::make_shared<H264RtpEncoder>(ssrc, mtu, sample_rate, pt, interleaved);
case CodecH265 : return std::make_shared<H265RtpEncoder>(ssrc, mtu, sample_rate, pt, interleaved);
case CodecAAC : return std::make_shared<AACRtpEncoder>(ssrc, mtu, sample_rate, pt, interleaved);
case CodecL16 :
case CodecOpus : return std::make_shared<CommonRtpEncoder>(codec_id, ssrc, mtu, sample_rate, pt, interleaved);
case CodecG711A :
case CodecG711U : {
if (pt == Rtsp::PT_PCMA || pt == Rtsp::PT_PCMU) { if (pt == Rtsp::PT_PCMA || pt == Rtsp::PT_PCMU) {
return std::make_shared<G711RtpEncoder>(codec_id, ssrc, mtu, sample_rate, pt, interleaved, 1); return std::make_shared<G711RtpEncoder>(codec_id, ssrc, mtu, sample_rate, pt, interleaved, 1);
} }
return std::make_shared<CommonRtpEncoder>(codec_id, ssrc, mtu, sample_rate, pt, interleaved); return std::make_shared<CommonRtpEncoder>(codec_id, ssrc, mtu, sample_rate, pt, interleaved);
} }
default : WarnL << "暂不支持该CodecId:" << codec_id; return nullptr; default: WarnL << "暂不支持该CodecId:" << codec_id; return nullptr;
} }
} }
RtpCodec::Ptr Factory::getRtpEncoderBySdp(const Sdp::Ptr &sdp) {
// ssrc不冲突即可,可以为任意的32位整形
static atomic<uint32_t> s_ssrc(0);
uint32_t ssrc = s_ssrc++;
if (!ssrc) {
// ssrc不能为0
ssrc = 1;
}
if (sdp->getTrackType() == TrackVideo) {
//视频的ssrc是偶数方便调试
ssrc = 2 * ssrc;
} else {
//音频ssrc是奇数
ssrc = 2 * ssrc + 1;
}
return getRtpEncoderByCodecId(sdp->getCodecId(), sdp->getSampleRate(), sdp->getPayloadType(), ssrc);
}
RtpCodec::Ptr Factory::getRtpDecoderByTrack(const Track::Ptr &track) { RtpCodec::Ptr Factory::getRtpDecoderByTrack(const Track::Ptr &track) {
switch (track->getCodecId()){ switch (track->getCodecId()){
case CodecH264 : return std::make_shared<H264RtpDecoder>(); case CodecH264 : return std::make_shared<H264RtpDecoder>();

View File

@ -38,6 +38,15 @@ public:
*/ */
static RtpCodec::Ptr getRtpEncoderBySdp(const Sdp::Ptr &sdp); static RtpCodec::Ptr getRtpEncoderBySdp(const Sdp::Ptr &sdp);
/**
* codec id生成rtp编码器
* @param codec_id id
* @param sample_rate 90000
* @param pt rtp payload type
* @param ssrc rtp ssrc
*/
static RtpCodec::Ptr getRtpEncoderByCodecId(CodecId codec_id, uint32_t sample_rate, uint8_t pt, uint32_t ssrc);
/** /**
* Track生成Rtp解包器 * Track生成Rtp解包器
*/ */

View File

@ -11,92 +11,64 @@
#if defined(ENABLE_RTPPROXY) #if defined(ENABLE_RTPPROXY)
#include "RawEncoder.h" #include "RawEncoder.h"
#include "Extension/H264Rtp.h" #include "Extension/Factory.h"
#include "Extension/AACRtp.h"
#include "Extension/H265Rtp.h"
#include "Extension/CommonRtp.h"
#include "Extension/G711Rtp.h"
#include "Rtsp/RtspMuxer.h" #include "Rtsp/RtspMuxer.h"
using namespace toolkit; using namespace toolkit;
namespace mediakit{ namespace mediakit {
RawEncoderImp::RawEncoderImp(uint32_t ssrc, uint8_t payload_type,bool sendAudio):_ssrc(ssrc),_payload_type(payload_type),_sendAudio(sendAudio) { RawEncoderImp::RawEncoderImp(uint32_t ssrc, uint8_t payload_type, bool send_audio)
: _ssrc(ssrc)
} , _payload_type(payload_type)
, _send_audio(send_audio) {}
RawEncoderImp::~RawEncoderImp() { RawEncoderImp::~RawEncoderImp() {
InfoL << this << " " << printSSRC(_ssrc); InfoL << this << " " << printSSRC(_ssrc);
} }
bool RawEncoderImp::addTrack(const Track::Ptr &track){ bool RawEncoderImp::addTrack(const Track::Ptr &track) {
if(_sendAudio && track->getTrackType() == TrackType::TrackAudio && !_rtp_encoder){// audio if (_send_audio && track->getTrackType() == TrackType::TrackAudio && !_rtp_encoder) { // audio
_rtp_encoder = createRtpEncoder(track); _rtp_encoder = createRtpEncoder(track);
_rtp_encoder->setRtpRing(std::make_shared<RtpRing::RingType>()); _rtp_encoder->setRtpRing(std::make_shared<RtpRing::RingType>());
_rtp_encoder->getRtpRing()->setDelegate(std::make_shared<RingDelegateHelper>([this](RtpPacket::Ptr rtp, bool is_key){ _rtp_encoder->getRtpRing()->setDelegate(std::make_shared<RingDelegateHelper>(
onRTP(std::move(rtp),true); [this](RtpPacket::Ptr rtp, bool is_key) { onRTP(std::move(rtp), true); }));
}));
return true; return true;
} }
if(!_sendAudio && track->getTrackType()==TrackType::TrackVideo && !_rtp_encoder){ if (!_send_audio && track->getTrackType() == TrackType::TrackVideo && !_rtp_encoder) {
_rtp_encoder = createRtpEncoder(track); _rtp_encoder = createRtpEncoder(track);
_rtp_encoder->setRtpRing(std::make_shared<RtpRing::RingType>()); _rtp_encoder->setRtpRing(std::make_shared<RtpRing::RingType>());
_rtp_encoder->getRtpRing()->setDelegate(std::make_shared<RingDelegateHelper>([this](RtpPacket::Ptr rtp, bool is_key){ _rtp_encoder->getRtpRing()->setDelegate(std::make_shared<RingDelegateHelper>(
onRTP(std::move(rtp),is_key); [this](RtpPacket::Ptr rtp, bool is_key) { onRTP(std::move(rtp), is_key); }));
}));
return true; return true;
} }
return true; return true;
} }
void RawEncoderImp::resetTracks() {
void RawEncoderImp::resetTracks(){
return; return;
} }
bool RawEncoderImp::inputFrame(const Frame::Ptr &frame) {
bool RawEncoderImp::inputFrame(const Frame::Ptr &frame){ if (frame->getTrackType() == TrackType::TrackAudio && _send_audio && _rtp_encoder) {
if(frame->getTrackType() == TrackType::TrackAudio && _sendAudio && _rtp_encoder){
_rtp_encoder->inputFrame(frame); _rtp_encoder->inputFrame(frame);
} }
if(frame->getTrackType() == TrackType::TrackVideo && !_sendAudio && _rtp_encoder){ if (frame->getTrackType() == TrackType::TrackVideo && !_send_audio && _rtp_encoder) {
_rtp_encoder->inputFrame(frame); _rtp_encoder->inputFrame(frame);
} }
return true; return true;
} }
RtpCodec::Ptr RawEncoderImp::createRtpEncoder(const Track::Ptr &track){ RtpCodec::Ptr RawEncoderImp::createRtpEncoder(const Track::Ptr &track) {
GET_CONFIG(uint32_t,audio_mtu,Rtp::kAudioMtuSize);
GET_CONFIG(uint32_t,video_mtu,Rtp::kVideoMtuSize);
auto codec_id = track->getCodecId();
uint32_t sample_rate = 90000; uint32_t sample_rate = 90000;
int channels = 1; if (track->getTrackType() == TrackType::TrackAudio) {
auto mtu = (track->getTrackType() == TrackVideo ? video_mtu : audio_mtu); sample_rate = std::static_pointer_cast<AudioTrack>(track)->getAudioSampleRate();
if(track->getTrackType() == TrackType::TrackAudio){
AudioTrack::Ptr audioTrack = std::dynamic_pointer_cast<AudioTrack>(track);
sample_rate = audioTrack->getAudioSampleRate();
channels = audioTrack->getAudioChannel();
}
switch (codec_id){
case CodecH264 : return std::make_shared<H264RtpEncoder>(_ssrc, mtu, sample_rate, _payload_type, 0);
case CodecH265 : return std::make_shared<H265RtpEncoder>(_ssrc, mtu, sample_rate, _payload_type, 0);
case CodecAAC : return std::make_shared<AACRtpEncoder>(_ssrc, mtu, sample_rate, _payload_type, 0);
case CodecL16 :
case CodecOpus : return std::make_shared<CommonRtpEncoder>(codec_id, _ssrc, mtu, sample_rate, _payload_type, 0);
case CodecG711A :
case CodecG711U : {
if (_payload_type == Rtsp::PT_PCMA || _payload_type == Rtsp::PT_PCMU) {
return std::make_shared<G711RtpEncoder>(codec_id, _ssrc, mtu, sample_rate, _payload_type, 0, channels);
}
return std::make_shared<CommonRtpEncoder>(codec_id, _ssrc, mtu, sample_rate, _payload_type, 0);
}
default : WarnL << "暂不支持该CodecId:" << codec_id; return nullptr;
} }
return Factory::getRtpEncoderByCodecId(track->getCodecId(), sample_rate, _payload_type, _ssrc);
} }
}//namespace mediakit } // namespace mediakit
#endif//defined(ENABLE_RTPPROXY) #endif // defined(ENABLE_RTPPROXY)

View File

@ -13,16 +13,15 @@
#if defined(ENABLE_RTPPROXY) #if defined(ENABLE_RTPPROXY)
#include "Common/MediaSink.h" #include "Common/MediaSink.h"
#include "Common/Stamp.h" #include "Common/Stamp.h"
#include "Extension/CommonRtp.h" #include "Extension/CommonRtp.h"
namespace mediakit{ namespace mediakit {
class RawEncoderImp : public MediaSinkInterface{ class RawEncoderImp : public MediaSinkInterface {
public: public:
RawEncoderImp(uint32_t ssrc, uint8_t payload_type = 96, bool sendAudio = true); RawEncoderImp(uint32_t ssrc, uint8_t payload_type = 96, bool send_audio = true);
~RawEncoderImp() override; ~RawEncoderImp() override;
/** /**
@ -30,7 +29,6 @@ public:
*/ */
bool addTrack(const Track::Ptr &track) override; bool addTrack(const Track::Ptr &track) override;
/** /**
* *
*/ */
@ -42,17 +40,20 @@ public:
bool inputFrame(const Frame::Ptr &frame) override; bool inputFrame(const Frame::Ptr &frame) override;
protected: protected:
//rtp打包后回调 // rtp打包后回调
virtual void onRTP(toolkit::Buffer::Ptr rtp, bool is_key = false) = 0; virtual void onRTP(toolkit::Buffer::Ptr rtp, bool is_key = false) = 0;
private: private:
RtpCodec::Ptr createRtpEncoder(const Track::Ptr &track); RtpCodec::Ptr createRtpEncoder(const Track::Ptr &track);
uint32_t _ssrc;
private:
bool _send_audio;
uint8_t _payload_type; uint8_t _payload_type;
bool _sendAudio; uint32_t _ssrc;
RtpCodec::Ptr _rtp_encoder; RtpCodec::Ptr _rtp_encoder;
}; };
}//namespace mediakit } // namespace mediakit
#endif //ENABLE_RTPPROXY #endif // ENABLE_RTPPROXY
#endif //ZLMEDIAKIT_RAWENCODER_H #endif // ZLMEDIAKIT_RAWENCODER_H

View File

@ -50,7 +50,6 @@ protected:
void onRTP(toolkit::Buffer::Ptr rtp,bool is_key = false) override; void onRTP(toolkit::Buffer::Ptr rtp,bool is_key = false) override;
}; };
class RtpCacheRaw : public RtpCache, public RawEncoderImp{ class RtpCacheRaw : public RtpCache, public RawEncoderImp{
public: public:
RtpCacheRaw(onFlushed cb, uint32_t ssrc, uint8_t payload_type = 96, bool sendAudio = true) : RtpCache(std::move(cb)), RawEncoderImp(ssrc, payload_type,sendAudio) {}; RtpCacheRaw(onFlushed cb, uint32_t ssrc, uint8_t payload_type = 96, bool sendAudio = true) : RtpCache(std::move(cb)), RawEncoderImp(ssrc, payload_type,sendAudio) {};