From f85de2e108521cee33768be30aa5051786d8139c Mon Sep 17 00:00:00 2001 From: ziyue <1213642868@qq.com> Date: Fri, 5 Aug 2022 17:36:51 +0800 Subject: [PATCH] =?UTF-8?q?=E7=B2=BE=E7=AE=80=E5=A4=8D=E7=94=A8rtp=20encod?= =?UTF-8?q?er=E5=88=9B=E5=BB=BA=E7=9B=B8=E5=85=B3=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Extension/Factory.cpp | 101 +++++++++++++++++++------------------- src/Extension/Factory.h | 9 ++++ src/Rtp/RawEncoder.cpp | 80 ++++++++++-------------------- src/Rtp/RawEncoder.h | 23 ++++----- src/Rtp/RtpCache.h | 1 - 5 files changed, 98 insertions(+), 116 deletions(-) diff --git a/src/Extension/Factory.cpp b/src/Extension/Factory.cpp index fae8dd8b..a2cdcd80 100644 --- a/src/Extension/Factory.cpp +++ b/src/Extension/Factory.cpp @@ -95,71 +95,72 @@ Track::Ptr Factory::getTrackBySdp(const SdpTrack::Ptr &track) { } } - Track::Ptr Factory::getTrackByAbstractTrack(const Track::Ptr& track) { auto codec = track->getCodecId(); switch (codec) { - case CodecG711A: - case CodecG711U: { - auto audio_track = dynamic_pointer_cast(track); - return std::make_shared(codec, audio_track->getAudioSampleRate(), audio_track->getAudioChannel(), 16); - } - case CodecL16: { - auto audio_track = dynamic_pointer_cast(track); - return std::make_shared(audio_track->getAudioSampleRate(), audio_track->getAudioChannel()); - } - case CodecAAC : return std::make_shared(); - case CodecOpus : return std::make_shared(); - case CodecH265 : return std::make_shared(); - case CodecH264 : return std::make_shared(); + case CodecG711A: + case CodecG711U: { + auto audio_track = dynamic_pointer_cast(track); + return std::make_shared(codec, audio_track->getAudioSampleRate(), audio_track->getAudioChannel(), 16); + } + case CodecL16: { + auto audio_track = dynamic_pointer_cast(track); + return std::make_shared(audio_track->getAudioSampleRate(), audio_track->getAudioChannel()); + } + case CodecAAC: return std::make_shared(); + case CodecOpus: return std::make_shared(); + case CodecH265: return std::make_shared(); + case CodecH264: return std::make_shared(); - default: { - //其他codec不支持 - WarnL << "暂不支持该该编码类型创建Track:" << track->getCodecName(); - return nullptr; - } + default: { + //其他codec不支持 + WarnL << "暂不支持该该编码类型创建Track:" << track->getCodecName(); + return nullptr; + } } } -RtpCodec::Ptr Factory::getRtpEncoderBySdp(const Sdp::Ptr &sdp) { - GET_CONFIG(uint32_t,audio_mtu,Rtp::kAudioMtuSize); - GET_CONFIG(uint32_t,video_mtu,Rtp::kVideoMtuSize); - // ssrc不冲突即可,可以为任意的32位整形 - static atomic 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; - } - 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(ssrc, mtu, sample_rate, pt, interleaved); - case CodecH265 : return std::make_shared(ssrc, mtu, sample_rate, pt, interleaved); - case CodecAAC : return std::make_shared(ssrc, mtu, sample_rate, pt, interleaved); - case CodecL16 : - case CodecOpus : return std::make_shared(codec_id, ssrc, mtu, sample_rate, pt, interleaved); - case CodecG711A : - case CodecG711U : { +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, video_mtu, Rtp::kVideoMtuSize); + auto type = getTrackType(codec_id); + auto mtu = type == TrackVideo ? video_mtu : audio_mtu; + auto interleaved = type * 2; + switch (codec_id) { + case CodecH264: return std::make_shared(ssrc, mtu, sample_rate, pt, interleaved); + case CodecH265: return std::make_shared(ssrc, mtu, sample_rate, pt, interleaved); + case CodecAAC: return std::make_shared(ssrc, mtu, sample_rate, pt, interleaved); + case CodecL16: + case CodecOpus: return std::make_shared(codec_id, ssrc, mtu, sample_rate, pt, interleaved); + case CodecG711A: + case CodecG711U: { if (pt == Rtsp::PT_PCMA || pt == Rtsp::PT_PCMU) { return std::make_shared(codec_id, ssrc, mtu, sample_rate, pt, interleaved, 1); } return std::make_shared(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 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) { switch (track->getCodecId()){ case CodecH264 : return std::make_shared(); diff --git a/src/Extension/Factory.h b/src/Extension/Factory.h index 75c968ce..6b0c3c0a 100644 --- a/src/Extension/Factory.h +++ b/src/Extension/Factory.h @@ -38,6 +38,15 @@ public: */ 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解包器 */ diff --git a/src/Rtp/RawEncoder.cpp b/src/Rtp/RawEncoder.cpp index f97b5b38..b1b75c12 100644 --- a/src/Rtp/RawEncoder.cpp +++ b/src/Rtp/RawEncoder.cpp @@ -11,92 +11,64 @@ #if defined(ENABLE_RTPPROXY) #include "RawEncoder.h" -#include "Extension/H264Rtp.h" -#include "Extension/AACRtp.h" -#include "Extension/H265Rtp.h" -#include "Extension/CommonRtp.h" -#include "Extension/G711Rtp.h" +#include "Extension/Factory.h" #include "Rtsp/RtspMuxer.h" 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() { InfoL << this << " " << printSSRC(_ssrc); } -bool RawEncoderImp::addTrack(const Track::Ptr &track){ - if(_sendAudio && track->getTrackType() == TrackType::TrackAudio && !_rtp_encoder){// audio +bool RawEncoderImp::addTrack(const Track::Ptr &track) { + if (_send_audio && track->getTrackType() == TrackType::TrackAudio && !_rtp_encoder) { // audio _rtp_encoder = createRtpEncoder(track); _rtp_encoder->setRtpRing(std::make_shared()); - _rtp_encoder->getRtpRing()->setDelegate(std::make_shared([this](RtpPacket::Ptr rtp, bool is_key){ - onRTP(std::move(rtp),true); - })); + _rtp_encoder->getRtpRing()->setDelegate(std::make_shared( + [this](RtpPacket::Ptr rtp, bool is_key) { onRTP(std::move(rtp), true); })); return true; } - if(!_sendAudio && track->getTrackType()==TrackType::TrackVideo && !_rtp_encoder){ - _rtp_encoder = createRtpEncoder(track); - _rtp_encoder->setRtpRing(std::make_shared()); - _rtp_encoder->getRtpRing()->setDelegate(std::make_shared([this](RtpPacket::Ptr rtp, bool is_key){ - onRTP(std::move(rtp),is_key); - })); + if (!_send_audio && track->getTrackType() == TrackType::TrackVideo && !_rtp_encoder) { + _rtp_encoder = createRtpEncoder(track); + _rtp_encoder->setRtpRing(std::make_shared()); + _rtp_encoder->getRtpRing()->setDelegate(std::make_shared( + [this](RtpPacket::Ptr rtp, bool is_key) { onRTP(std::move(rtp), is_key); })); return true; } return true; } - -void RawEncoderImp::resetTracks(){ +void RawEncoderImp::resetTracks() { return; } - -bool RawEncoderImp::inputFrame(const Frame::Ptr &frame){ - if(frame->getTrackType() == TrackType::TrackAudio && _sendAudio && _rtp_encoder){ +bool RawEncoderImp::inputFrame(const Frame::Ptr &frame) { + if (frame->getTrackType() == TrackType::TrackAudio && _send_audio && _rtp_encoder) { _rtp_encoder->inputFrame(frame); } - if(frame->getTrackType() == TrackType::TrackVideo && !_sendAudio && _rtp_encoder){ - _rtp_encoder->inputFrame(frame); + if (frame->getTrackType() == TrackType::TrackVideo && !_send_audio && _rtp_encoder) { + _rtp_encoder->inputFrame(frame); } return true; } -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(); +RtpCodec::Ptr RawEncoderImp::createRtpEncoder(const Track::Ptr &track) { uint32_t sample_rate = 90000; - int channels = 1; - auto mtu = (track->getTrackType() == TrackVideo ? video_mtu : audio_mtu); - if(track->getTrackType() == TrackType::TrackAudio){ - AudioTrack::Ptr audioTrack = std::dynamic_pointer_cast(track); - sample_rate = audioTrack->getAudioSampleRate(); - channels = audioTrack->getAudioChannel(); - } - switch (codec_id){ - case CodecH264 : return std::make_shared(_ssrc, mtu, sample_rate, _payload_type, 0); - case CodecH265 : return std::make_shared(_ssrc, mtu, sample_rate, _payload_type, 0); - case CodecAAC : return std::make_shared(_ssrc, mtu, sample_rate, _payload_type, 0); - case CodecL16 : - case CodecOpus : return std::make_shared(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(codec_id, _ssrc, mtu, sample_rate, _payload_type, 0, channels); - } - return std::make_shared(codec_id, _ssrc, mtu, sample_rate, _payload_type, 0); - } - default : WarnL << "暂不支持该CodecId:" << codec_id; return nullptr; + if (track->getTrackType() == TrackType::TrackAudio) { + sample_rate = std::static_pointer_cast(track)->getAudioSampleRate(); } + return Factory::getRtpEncoderByCodecId(track->getCodecId(), sample_rate, _payload_type, _ssrc); } -}//namespace mediakit +} // namespace mediakit -#endif//defined(ENABLE_RTPPROXY) +#endif // defined(ENABLE_RTPPROXY) diff --git a/src/Rtp/RawEncoder.h b/src/Rtp/RawEncoder.h index 6a18f450..d6c9620d 100644 --- a/src/Rtp/RawEncoder.h +++ b/src/Rtp/RawEncoder.h @@ -13,16 +13,15 @@ #if defined(ENABLE_RTPPROXY) - #include "Common/MediaSink.h" #include "Common/Stamp.h" #include "Extension/CommonRtp.h" -namespace mediakit{ +namespace mediakit { -class RawEncoderImp : public MediaSinkInterface{ +class RawEncoderImp : public MediaSinkInterface { 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; /** @@ -30,7 +29,6 @@ public: */ bool addTrack(const Track::Ptr &track) override; - /** * 重置音视频轨道 */ @@ -42,17 +40,20 @@ public: bool inputFrame(const Frame::Ptr &frame) override; protected: - //rtp打包后回调 + // rtp打包后回调 virtual void onRTP(toolkit::Buffer::Ptr rtp, bool is_key = false) = 0; + private: RtpCodec::Ptr createRtpEncoder(const Track::Ptr &track); - uint32_t _ssrc; + +private: + bool _send_audio; uint8_t _payload_type; - bool _sendAudio; + uint32_t _ssrc; RtpCodec::Ptr _rtp_encoder; }; -}//namespace mediakit +} // namespace mediakit -#endif //ENABLE_RTPPROXY -#endif //ZLMEDIAKIT_RAWENCODER_H +#endif // ENABLE_RTPPROXY +#endif // ZLMEDIAKIT_RAWENCODER_H diff --git a/src/Rtp/RtpCache.h b/src/Rtp/RtpCache.h index 4144b345..b83c8282 100644 --- a/src/Rtp/RtpCache.h +++ b/src/Rtp/RtpCache.h @@ -50,7 +50,6 @@ protected: void onRTP(toolkit::Buffer::Ptr rtp,bool is_key = false) override; }; - class RtpCacheRaw : public RtpCache, public RawEncoderImp{ public: RtpCacheRaw(onFlushed cb, uint32_t ssrc, uint8_t payload_type = 96, bool sendAudio = true) : RtpCache(std::move(cb)), RawEncoderImp(ssrc, payload_type,sendAudio) {};