diff --git a/src/Common/Factory.cpp b/src/Common/Factory.cpp new file mode 100644 index 00000000..a5842f03 --- /dev/null +++ b/src/Common/Factory.cpp @@ -0,0 +1,103 @@ +// +// Created by xzl on 2018/10/24. +// + +#include "Factory.h" + +Sdp::Ptr Factory::getSdpByTrack(const Track::Ptr &track) { + switch (track->getCodecId()){ + case CodecH264:{ + H264Track::Ptr h264Track = dynamic_pointer_cast(track); + if(!h264Track){ + return nullptr; + } + return std::make_shared(h264Track->getSps(),h264Track->getPps()); + } + + case CodecAAC:{ + AACTrack::Ptr aacTrack = dynamic_pointer_cast(track); + if(!aacTrack){ + return nullptr; + } + return std::make_shared(aacTrack->getAacCfg(),aacTrack->getAudioSampleRate()); + } + + default: + return nullptr; + } +} + + +Track::Ptr Factory::getTrackBySdp(const string &sdp) { + if (strcasestr(sdp.data(), "mpeg4-generic") != nullptr) { + string aac_cfg_str = FindField(sdp.c_str(), "config=", "\r\n"); + if (aac_cfg_str.size() != 4) { + aac_cfg_str = FindField(sdp.c_str(), "config=", ";"); + } + if (aac_cfg_str.size() != 4) { + return nullptr; + } + string aac_cfg; + + unsigned int cfg1; + sscanf(aac_cfg_str.substr(0, 2).c_str(), "%02X", &cfg1); + cfg1 &= 0x00FF; + aac_cfg.push_back(cfg1); + + unsigned int cfg2; + sscanf(aac_cfg_str.substr(2, 2).c_str(), "%02X", &cfg2); + cfg2 &= 0x00FF; + aac_cfg.push_back(cfg2); + + return std::make_shared(aac_cfg); + } + + if (strcasestr(sdp.data(), "h264") != nullptr) { + string sps_pps = FindField(sdp.c_str(), "sprop-parameter-sets=", "\r\n"); + if(sps_pps.empty()){ + return std::make_shared(); + } + string base64_SPS = FindField(sps_pps.c_str(), NULL, ","); + string base64_PPS = FindField(sps_pps.c_str(), ",", NULL); + if(base64_PPS.back() == ';'){ + base64_PPS.pop_back(); + } + + auto sps = decodeBase64(base64_SPS); + auto pps = decodeBase64(base64_PPS); + return std::make_shared(sps,pps,0,0); + } + + + return nullptr; +} + + + +RtpCodec::Ptr Factory::getRtpEncoderById(CodecId codecId, + uint32_t ui32Ssrc, + uint32_t ui32MtuSize, + uint32_t ui32SampleRate, + uint8_t ui8PlayloadType, + uint8_t ui8Interleaved) { + switch (codecId){ + case CodecH264: + return std::make_shared(ui32Ssrc,ui32MtuSize,ui32SampleRate,ui8PlayloadType,ui8Interleaved); + case CodecAAC: + return std::make_shared(ui32Ssrc,ui32MtuSize,ui32SampleRate,ui8PlayloadType,ui8Interleaved); + default: + return nullptr; + } +} + +RtpCodec::Ptr Factory::getRtpDecoderById(CodecId codecId, uint32_t ui32SampleRate) { + switch (codecId){ + case CodecH264: + return std::make_shared(); + case CodecAAC: + return std::make_shared(ui32SampleRate); + default: + return nullptr; + } +} + diff --git a/src/Common/Factory.h b/src/Common/Factory.h new file mode 100644 index 00000000..de3966f9 --- /dev/null +++ b/src/Common/Factory.h @@ -0,0 +1,57 @@ +// +// Created by xzl on 2018/10/24. +// + +#ifndef ZLMEDIAKIT_FACTORY_H +#define ZLMEDIAKIT_FACTORY_H + +#include +#include "Player/Track.h" +#include "Rtsp/RtspSdp.h" + +using namespace std; +using namespace ZL::Rtsp; + +class Factory { +public: + /** + * 根据sdp生成Track对象 + */ + static Track::Ptr getTrackBySdp(const string &sdp); + + /** + * 根据Track生成SDP对象 + * @param track 媒体信息 + * @return 返回sdp对象 + */ + static Sdp::Ptr getSdpByTrack(const Track::Ptr &track); + + + /** + * 根据CodecId生成Rtp打包器 + * @param codecId + * @param ui32Ssrc + * @param ui32MtuSize + * @param ui32SampleRate + * @param ui8PlayloadType + * @param ui8Interleaved + * @return + */ + static RtpCodec::Ptr getRtpEncoderById(CodecId codecId, + uint32_t ui32Ssrc, + uint32_t ui32MtuSize, + uint32_t ui32SampleRate, + uint8_t ui8PlayloadType, + uint8_t ui8Interleaved); + + /** + * 根据CodecId生成Rtp解包器 + * @param codecId + * @param ui32SampleRate + * @return + */ + static RtpCodec::Ptr getRtpDecoderById(CodecId codecId, uint32_t ui32SampleRate); +}; + + +#endif //ZLMEDIAKIT_FACTORY_H diff --git a/src/Player/Track.cpp b/src/Player/Track.cpp deleted file mode 100644 index eab3e49f..00000000 --- a/src/Player/Track.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// -// Created by xzl on 2018/10/21. -// - -#include "Track.h" -#include "Util/util.h" -#include "Util/base64.h" - -using namespace ZL::Util; - -Track::Ptr Track::getTrackBySdp(const string &sdp) { - if (strcasestr(sdp.data(), "mpeg4-generic") != nullptr) { - string aac_cfg_str = FindField(sdp.c_str(), "config=", "\r\n"); - if (aac_cfg_str.size() != 4) { - aac_cfg_str = FindField(sdp.c_str(), "config=", ";"); - } - if (aac_cfg_str.size() != 4) { - return nullptr; - } - string aac_cfg; - - unsigned int cfg1; - sscanf(aac_cfg_str.substr(0, 2).c_str(), "%02X", &cfg1); - cfg1 &= 0x00FF; - aac_cfg.push_back(cfg1); - - unsigned int cfg2; - sscanf(aac_cfg_str.substr(2, 2).c_str(), "%02X", &cfg2); - cfg2 &= 0x00FF; - aac_cfg.push_back(cfg2); - - return std::make_shared(aac_cfg); - } - - if (strcasestr(sdp.data(), "h264") != nullptr) { - string sps_pps = FindField(sdp.c_str(), "sprop-parameter-sets=", "\r\n"); - if(sps_pps.empty()){ - return std::make_shared(); - } - string base64_SPS = FindField(sps_pps.c_str(), NULL, ","); - string base64_PPS = FindField(sps_pps.c_str(), ",", NULL); - if(base64_PPS.back() == ';'){ - base64_PPS.pop_back(); - } - - auto sps = decodeBase64(base64_SPS); - auto pps = decodeBase64(base64_PPS); - return std::make_shared(sps,pps,0,0); - } - - - return nullptr; -} diff --git a/src/Player/Track.h b/src/Player/Track.h index c9fe3b3a..daf48b14 100644 --- a/src/Player/Track.h +++ b/src/Player/Track.h @@ -20,11 +20,6 @@ public: typedef std::shared_ptr Ptr; Track(){} virtual ~Track(){} - - /** - * 根据sdp生成Track对象 - */ - static Ptr getTrackBySdp(const string &sdp); }; class VideoTrack : public Track { diff --git a/src/RTP/RtpCodec.cpp b/src/RTP/RtpCodec.cpp deleted file mode 100644 index 996d889b..00000000 --- a/src/RTP/RtpCodec.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// -// Created by xzl on 2018/10/18. -// - -#include "RtpCodec.h" -#include "AACRtpCodec.h" -#include "H264RtpCodec.h" - -RtpCodec::Ptr RtpCodec::getRtpEncoderById(CodecId codecId, - uint32_t ui32Ssrc, - uint32_t ui32MtuSize, - uint32_t ui32SampleRate, - uint8_t ui8PlayloadType, - uint8_t ui8Interleaved) { - switch (codecId){ - case CodecH264: - return std::make_shared(ui32Ssrc,ui32MtuSize,ui32SampleRate,ui8PlayloadType,ui8Interleaved); - case CodecAAC: - return std::make_shared(ui32Ssrc,ui32MtuSize,ui32SampleRate,ui8PlayloadType,ui8Interleaved); - default: - return nullptr; - } -} - -RtpCodec::Ptr RtpCodec::getRtpDecoderById(CodecId codecId, uint32_t ui32SampleRate) { - switch (codecId){ - case CodecH264: - return std::make_shared(); - case CodecAAC: - return std::make_shared(ui32SampleRate); - default: - return nullptr; - } -} - diff --git a/src/RTP/RtpCodec.h b/src/RTP/RtpCodec.h index 8a1e61a0..6001b297 100644 --- a/src/RTP/RtpCodec.h +++ b/src/RTP/RtpCodec.h @@ -161,31 +161,6 @@ public: typedef std::shared_ptr Ptr; RtpCodec(){} virtual ~RtpCodec(){} - - /** - * 根据CodecId生成Rtp打包器 - * @param codecId - * @param ui32Ssrc - * @param ui32MtuSize - * @param ui32SampleRate - * @param ui8PlayloadType - * @param ui8Interleaved - * @return - */ - static Ptr getRtpEncoderById(CodecId codecId, - uint32_t ui32Ssrc, - uint32_t ui32MtuSize, - uint32_t ui32SampleRate, - uint8_t ui8PlayloadType, - uint8_t ui8Interleaved); - - /** - * 根据CodecId生成Rtp解包器 - * @param codecId - * @param ui32SampleRate - * @return - */ - static Ptr getRtpDecoderById(CodecId codecId,uint32_t ui32SampleRate); }; diff --git a/src/Rtsp/RtpParser.cpp b/src/Rtsp/RtpParser.cpp index 15c73b3e..6d0b4b0b 100644 --- a/src/Rtsp/RtpParser.cpp +++ b/src/Rtsp/RtpParser.cpp @@ -29,6 +29,7 @@ #include "RtpParser.h" #include "Util/base64.h" #include "H264/SPSParser.h" +#include "Common/Factory.h" using namespace std; @@ -97,10 +98,10 @@ inline bool RtpParser::inputAudio(const RtpPacket::Ptr &rtp) { inline void RtpParser::onGetAudioTrack(const RtspTrack& audio) { //生成Track对象 - _audioTrack = dynamic_pointer_cast(Track::getTrackBySdp(audio.trackSdp)); + _audioTrack = dynamic_pointer_cast(Factory::getTrackBySdp(audio.trackSdp)); if(_audioTrack){ //生成RtpCodec对象以便解码rtp - _audioRtpDecoder = RtpCodec::getRtpDecoderById(_audioTrack->getCodecId(),_audioTrack->getAudioSampleRate()); + _audioRtpDecoder = Factory::getRtpDecoderById(_audioTrack->getCodecId(),_audioTrack->getAudioSampleRate()); if(_audioRtpDecoder){ //设置rtp解码器代理,生成的frame写入该Track _audioRtpDecoder->setDelegate(_audioTrack); @@ -110,10 +111,10 @@ inline void RtpParser::onGetAudioTrack(const RtspTrack& audio) { inline void RtpParser::onGetVideoTrack(const RtspTrack& video) { //生成Track对象 - _videoTrack = dynamic_pointer_cast(Track::getTrackBySdp(video.trackSdp)); + _videoTrack = dynamic_pointer_cast(Factory::getTrackBySdp(video.trackSdp)); if(_videoTrack){ //生成RtpCodec对象以便解码rtp - _videoRtpDecoder = RtpCodec::getRtpDecoderById(_videoTrack->getCodecId(),90000); + _videoRtpDecoder = Factory::getRtpDecoderById(_videoTrack->getCodecId(),90000); if(_videoRtpDecoder){ //设置rtp解码器代理,生成的frame写入该Track _videoRtpDecoder->setDelegate(_videoTrack); diff --git a/src/Rtsp/RtspSdp.cpp b/src/Rtsp/RtspSdp.cpp index e762c020..2b8fdc52 100644 --- a/src/Rtsp/RtspSdp.cpp +++ b/src/Rtsp/RtspSdp.cpp @@ -1,38 +1,22 @@ -// -// Created by xzl on 2018/10/23. -// -#include "RtspSdp.h" +#include "RtspSdp.h" +#include "Common/Factory.h" -namespace ZL{ -namespace Rtsp{ +void Sdp::createRtpEncoder(uint32_t ssrc, int mtu) { + _encoder = Factory::getRtpEncoderById(getCodecId(), + ssrc, + mtu, + _sample_rate, + _playload_type, + getTrackType() * 2); +} - -Sdp::Ptr Sdp::getSdpByTrack(const Track::Ptr &track) { - switch (track->getCodecId()){ - case CodecH264:{ - H264Track::Ptr h264Track = dynamic_pointer_cast(track); - if(!h264Track){ - return nullptr; - } - return std::make_shared(h264Track->getSps(),h264Track->getPps()); +void RtspMaker::addTrack(const Track::Ptr &track, uint32_t ssrc, int mtu) { + if (track->getCodecId() == CodecInvalid) { + addTrack(std::make_shared(), ssrc, mtu); + } else { + Sdp::Ptr sdp = Factory::getSdpByTrack(track); + if (sdp) { + addTrack(sdp, ssrc, mtu); } - - case CodecAAC:{ - AACTrack::Ptr aacTrack = dynamic_pointer_cast(track); - if(!aacTrack){ - return nullptr; - } - return std::make_shared(aacTrack->getAacCfg(),aacTrack->getAudioSampleRate()); - } - - default: - return nullptr; } } - - - - -} -} - diff --git a/src/Rtsp/RtspSdp.h b/src/Rtsp/RtspSdp.h index 72c0b123..99b03211 100644 --- a/src/Rtsp/RtspSdp.h +++ b/src/Rtsp/RtspSdp.h @@ -30,13 +30,6 @@ public: _playload_type = playload_type; } - /** - * 根据Track生成SDP对象 - * @param track 媒体信息 - * @return 返回sdp对象 - */ - static Ptr getSdpByTrack(const Track::Ptr &track); - virtual ~Sdp(){} /** @@ -115,14 +108,7 @@ public: * @param ssrc 打包器ssrc,可以为0 * @param mtu mtu大小,一般小于1500字节,推荐1400 */ - virtual void createRtpEncoder(uint32_t ssrc, int mtu) { - _encoder = RtpCodec::getRtpEncoderById(getCodecId(), - ssrc, - mtu, - _sample_rate, - _playload_type, - getTrackType() * 2); - } + virtual void createRtpEncoder(uint32_t ssrc, int mtu); private: RtpCodec::Ptr _encoder; uint8_t _playload_type; @@ -311,16 +297,7 @@ public: * @param ssrc 媒体rtp ssrc * @param mtu 媒体rtp mtu */ - void addTrack(const Track::Ptr & track,uint32_t ssrc = 0,int mtu = 1400) { - if(track->getCodecId() == CodecInvalid){ - addTrack(std::make_shared(),ssrc,mtu); - } else { - Sdp::Ptr sdp = Sdp::getSdpByTrack(track); - if(sdp){ - addTrack(sdp,ssrc,mtu); - } - } - } + void addTrack(const Track::Ptr & track,uint32_t ssrc = 0,int mtu = 1400) ; /** * 获取完整的SDP字符串