From 0a2c022fa8d89eec7f0cb2cce119f38354349fa5 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Fri, 28 Jun 2019 16:12:39 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 3rdpart/ZLToolKit | 2 +- src/Extension/AAC.cpp | 9 +++ src/Extension/AAC.h | 5 +- src/Extension/Factory.cpp | 73 ++++--------------- src/Extension/Factory.h | 25 +------ src/Extension/H264.cpp | 7 ++ src/Extension/H264.h | 7 +- src/Extension/H265.cpp | 8 ++- src/Extension/H265.h | 9 ++- src/Extension/Track.h | 6 ++ src/Rtsp/Rtsp.h | 125 +++++++++++++++++++++++++++++++-- src/RtspMuxer/RtpCodec.h | 14 ---- src/RtspMuxer/RtspMuxer.cpp | 11 +-- src/RtspMuxer/RtspMuxer.h | 2 +- src/RtspMuxer/RtspSdp.cpp | 42 ----------- src/RtspMuxer/RtspSdp.h | 136 ------------------------------------ 16 files changed, 182 insertions(+), 299 deletions(-) delete mode 100644 src/RtspMuxer/RtspSdp.cpp delete mode 100644 src/RtspMuxer/RtspSdp.h diff --git a/3rdpart/ZLToolKit b/3rdpart/ZLToolKit index 3ce80a66..3a01ee3d 160000 --- a/3rdpart/ZLToolKit +++ b/3rdpart/ZLToolKit @@ -1 +1 @@ -Subproject commit 3ce80a66b80ac98afae6c51e7f077b326dfacc6c +Subproject commit 3a01ee3dc901d40b8542a4ba81287805456506b5 diff --git a/src/Extension/AAC.cpp b/src/Extension/AAC.cpp index 307c407b..f805e2d5 100644 --- a/src/Extension/AAC.cpp +++ b/src/Extension/AAC.cpp @@ -115,6 +115,15 @@ void getAACInfo(const AACFrame &adts,int &iSampleRate,int &iChannel){ iChannel = adts.channel_configuration; } + +Sdp::Ptr AACTrack::getSdp() { + if(!ready()){ + WarnL << "AAC Track未准备好"; + return nullptr; + } + return std::make_shared(getAacCfg(),getAudioSampleRate()); +} + }//namespace mediakit diff --git a/src/Extension/AAC.h b/src/Extension/AAC.h index d5d61fc2..24832f8a 100644 --- a/src/Extension/AAC.h +++ b/src/Extension/AAC.h @@ -29,8 +29,6 @@ #include "Frame.h" #include "Track.h" -#include "RtspMuxer/RtspSdp.h" - namespace mediakit{ @@ -258,6 +256,9 @@ private: Track::Ptr clone() override { return std::make_shared::type >(*this); } + + //生成sdp + Sdp::Ptr getSdp() override ; private: string _cfg; int _sampleRate = 0; diff --git a/src/Extension/Factory.cpp b/src/Extension/Factory.cpp index fc2d3a5f..ce8b9b05 100644 --- a/src/Extension/Factory.cpp +++ b/src/Extension/Factory.cpp @@ -33,53 +33,6 @@ namespace mediakit{ -Sdp::Ptr Factory::getSdpByTrack(const Track::Ptr &track) { - switch (track->getCodecId()){ - case CodecH264:{ - H264Track::Ptr h264Track = dynamic_pointer_cast(track); - if(!h264Track){ - WarnL << "该Track不是H264Track类型"; - return nullptr; - } - if(!h264Track->ready()){ - WarnL << "该Track未准备好"; - return nullptr; - } - return std::make_shared(h264Track->getSps(),h264Track->getPps()); - } - - case CodecH265:{ - H265Track::Ptr h265Track = dynamic_pointer_cast(track); - if(!h265Track){ - WarnL << "该Track不是H265Track类型"; - return nullptr; - } - if(!h265Track->ready()){ - WarnL << "该Track未准备好"; - return nullptr; - } - return std::make_shared(h265Track->getVps(),h265Track->getSps(),h265Track->getPps()); - } - - case CodecAAC:{ - AACTrack::Ptr aacTrack = dynamic_pointer_cast(track); - if(!aacTrack){ - WarnL << "该Track不是AACTrack类型"; - return nullptr; - } - if(!aacTrack->ready()){ - WarnL << "该Track未准备好"; - return nullptr; - } - return std::make_shared(aacTrack->getAacCfg(),aacTrack->getAudioSampleRate()); - } - default: - WarnL << "暂不支持的CodecId:" << track->getCodecId(); - return nullptr; - } -} - - Track::Ptr Factory::getTrackBySdp(const SdpTrack::Ptr &track) { if (strcasecmp(track->_codec.data(), "mpeg4-generic") == 0) { string aac_cfg_str = FindField(track->_fmtp.data(), "config=", nullptr); @@ -162,21 +115,25 @@ Track::Ptr Factory::getTrackByCodecId(CodecId codecId) { } } -RtpCodec::Ptr Factory::getRtpEncoderById(CodecId codecId, - uint32_t ui32Ssrc, - uint32_t ui32MtuSize, - uint32_t ui32SampleRate, - uint8_t ui8PlayloadType, - uint8_t ui8Interleaved) { - switch (codecId){ +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不冲突即可 + uint32_t ssrc = ((uint64_t) sdp.get()) & 0xFFFFFFFF; + auto mtu = (sdp->getTrackType() == TrackVideo ? video_mtu : audio_mtu); + auto sample_rate = sdp->getSampleRate(); + auto pt = sdp->getPlayloadType(); + auto interleaved = sdp->getTrackType() * 2; + auto codec_id = sdp->getCodecId(); + switch (codec_id){ case CodecH264: - return std::make_shared(ui32Ssrc,ui32MtuSize,ui32SampleRate,ui8PlayloadType,ui8Interleaved); + return std::make_shared(ssrc,mtu,sample_rate,pt,interleaved); case CodecH265: - return std::make_shared(ui32Ssrc,ui32MtuSize,ui32SampleRate,ui8PlayloadType,ui8Interleaved); + return std::make_shared(ssrc,mtu,sample_rate,pt,interleaved); case CodecAAC: - return std::make_shared(ui32Ssrc,ui32MtuSize,ui32SampleRate,ui8PlayloadType,ui8Interleaved); + return std::make_shared(ssrc,mtu,sample_rate,pt,interleaved); default: - WarnL << "暂不支持该CodecId:" << codecId; + WarnL << "暂不支持该CodecId:" << codec_id; return nullptr; } } diff --git a/src/Extension/Factory.h b/src/Extension/Factory.h index e9bcc46e..578c9efd 100644 --- a/src/Extension/Factory.h +++ b/src/Extension/Factory.h @@ -30,7 +30,6 @@ #include #include "Rtmp/amf.h" #include "Extension/Track.h" -#include "RtspMuxer/RtspSdp.h" #include "RtspMuxer/RtpCodec.h" #include "RtmpMuxer/RtmpCodec.h" @@ -56,29 +55,11 @@ public: static Track::Ptr getTrackBySdp(const SdpTrack::Ptr &track); /** - * 根据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 + * 根据sdp生成rtp编码器 + * @param sdp sdp对象 * @return */ - static RtpCodec::Ptr getRtpEncoderById(CodecId codecId, - uint32_t ui32Ssrc, - uint32_t ui32MtuSize, - uint32_t ui32SampleRate, - uint8_t ui8PlayloadType, - uint8_t ui8Interleaved); + static RtpCodec::Ptr getRtpEncoderBySdp(const Sdp::Ptr &sdp); /** * 根据Track生成Rtp解包器 diff --git a/src/Extension/H264.cpp b/src/Extension/H264.cpp index 8f93cfc7..83336248 100644 --- a/src/Extension/H264.cpp +++ b/src/Extension/H264.cpp @@ -77,6 +77,13 @@ void splitH264(const char *ptr, int len, const std::function(getSps(),getPps()); +} }//namespace mediakit diff --git a/src/Extension/H264.h b/src/Extension/H264.h index df0ac71c..67962787 100644 --- a/src/Extension/H264.h +++ b/src/Extension/H264.h @@ -29,9 +29,8 @@ #include "Frame.h" #include "Track.h" -#include "RtspMuxer/RtspSdp.h" - - +#include "Util/base64.h" +using namespace toolkit; #define H264_TYPE(v) ((uint8_t)(v) & 0x1F) namespace mediakit{ @@ -302,6 +301,8 @@ private: } } + //生成sdp + Sdp::Ptr getSdp() override ; private: //在idr帧前插入sps pps帧 void insertConfigFrame(const Frame::Ptr &frame){ diff --git a/src/Extension/H265.cpp b/src/Extension/H265.cpp index 7483680a..6894264c 100644 --- a/src/Extension/H265.cpp +++ b/src/Extension/H265.cpp @@ -28,6 +28,12 @@ namespace mediakit{ - +Sdp::Ptr H265Track::getSdp() { + if(!ready()){ + WarnL << "H265 Track未准备好"; + return nullptr; + } + return std::make_shared(getVps(),getSps(),getPps()); +} }//namespace mediakit diff --git a/src/Extension/H265.h b/src/Extension/H265.h index e3f82deb..32892ed9 100644 --- a/src/Extension/H265.h +++ b/src/Extension/H265.h @@ -29,12 +29,12 @@ #include "Frame.h" #include "Track.h" -#include "RtspMuxer/RtspSdp.h" +#include "Util/base64.h" +using namespace toolkit; +#define H265_TYPE(v) (((uint8_t)(v) >> 1) & 0x3f) namespace mediakit { -#define H265_TYPE(v) (((uint8_t)(v) >> 1) & 0x3f) - /** * 265帧类 */ @@ -254,6 +254,9 @@ private: return std::make_shared::type>(*this); } + //生成sdp + Sdp::Ptr getSdp() override ; + //在idr帧前插入vps sps pps帧 void insertConfigFrame(const Frame::Ptr &frame){ if(_last_frame_is_idr){ diff --git a/src/Extension/Track.h b/src/Extension/Track.h index fe20dcaa..5209c74e 100644 --- a/src/Extension/Track.h +++ b/src/Extension/Track.h @@ -60,6 +60,12 @@ public: */ virtual Track::Ptr clone() = 0; + /** + * 生成sdp + * @return sdp对象 + */ + virtual Sdp::Ptr getSdp() = 0; + /** * 复制拷贝,只能拷贝派生类的信息, * 环形缓存和代理关系不能拷贝,否则会关系紊乱 diff --git a/src/Rtsp/Rtsp.h b/src/Rtsp/Rtsp.h index 60f03a0e..4bcf9972 100644 --- a/src/Rtsp/Rtsp.h +++ b/src/Rtsp/Rtsp.h @@ -49,6 +49,20 @@ typedef enum { } eRtpType; }; +class RtpPacket : public BufferRaw{ +public: + typedef std::shared_ptr Ptr; + uint8_t interleaved; + uint8_t PT; + bool mark; + //时间戳,单位毫秒 + uint32_t timeStamp; + uint16_t sequence; + uint32_t ssrc; + uint8_t offset; + TrackType type; +}; + class SdpTrack { public: typedef std::shared_ptr Ptr; @@ -89,19 +103,12 @@ public: typedef std::shared_ptr Ptr; SdpAttr() {} - SdpAttr(const string &sdp) { load(sdp); } - ~SdpAttr() {} - void load(const string &sdp); - bool available() const; - SdpTrack::Ptr getTrack(TrackType type) const; - vector getAvailableTrack() const; - private: map _track_map; }; @@ -279,6 +286,110 @@ private: mutable StrCaseMap _mapUrlArgs; }; + +/** +* rtsp sdp基类 +*/ +class Sdp : public CodecInfo{ +public: + typedef std::shared_ptr Ptr; + + /** + * 构造sdp + * @param sample_rate 采样率 + * @param playload_type pt类型 + */ + Sdp(uint32_t sample_rate, uint8_t playload_type){ + _sample_rate = sample_rate; + _playload_type = playload_type; + } + + virtual ~Sdp(){} + + /** + * 获取sdp字符串 + * @return + */ + virtual string getSdp() const = 0; + + /** + * 获取pt + * @return + */ + uint8_t getPlayloadType() const{ + return _playload_type; + } + + /** + * 获取采样率 + * @return + */ + uint32_t getSampleRate() const{ + return _sample_rate; + } +private: + uint8_t _playload_type; + uint32_t _sample_rate; +}; + +/** +* sdp中除音视频外的其他描述部分 +*/ +class TitleSdp : public Sdp{ +public: + + /** + * 构造title类型sdp + * @param dur_sec rtsp点播时长,0代表直播,单位秒 + * @param header 自定义sdp描述 + * @param version sdp版本 + */ + TitleSdp(float dur_sec = 0, + const map &header = map(), + int version = 0) : Sdp(0,0){ + _printer << "v=" << version << "\r\n"; + + if(!header.empty()){ + for (auto &pr : header){ + _printer << pr.first << "=" << pr.second << "\r\n"; + } + } else { + _printer << "o=- 1383190487994921 1 IN IP4 0.0.0.0\r\n"; + _printer << "s=RTSP Session, streamed by the ZLMediaKit\r\n"; + _printer << "i=ZLMediaKit Live Stream\r\n"; + _printer << "c=IN IP4 0.0.0.0\r\n"; + _printer << "t=0 0\r\n"; + } + + if(dur_sec <= 0){ + _printer << "a=range:npt=0-\r\n"; + }else{ + _printer << "a=range:npt=0-" << dur_sec << "\r\n"; + } + _printer << "a=control:*\r\n"; + } + string getSdp() const override { + return _printer; + } + /** + * 返回音频或视频类型 + * @return + */ + TrackType getTrackType() const override { + return TrackTitle; + } + + /** + * 返回编码器id + * @return + */ + CodecId getCodecId() const override{ + return CodecInvalid; + } +private: + _StrPrinter _printer; +}; + } //namespace mediakit #endif //RTSP_RTSP_H_ diff --git a/src/RtspMuxer/RtpCodec.h b/src/RtspMuxer/RtpCodec.h index 49c96544..a422703a 100644 --- a/src/RtspMuxer/RtpCodec.h +++ b/src/RtspMuxer/RtpCodec.h @@ -35,20 +35,6 @@ using namespace toolkit; namespace mediakit{ -class RtpPacket : public BufferRaw{ -public: - typedef std::shared_ptr Ptr; - uint8_t interleaved; - uint8_t PT; - bool mark; - //时间戳,单位毫秒 - uint32_t timeStamp; - uint16_t sequence; - uint32_t ssrc; - uint8_t offset; - TrackType type; -}; - class RtpRingInterface { public: typedef RingBuffer RingType; diff --git a/src/RtspMuxer/RtspMuxer.cpp b/src/RtspMuxer/RtspMuxer.cpp index e89d0403..c78a7e5c 100644 --- a/src/RtspMuxer/RtspMuxer.cpp +++ b/src/RtspMuxer/RtspMuxer.cpp @@ -40,18 +40,11 @@ RtspMuxer::RtspMuxer(const TitleSdp::Ptr &title){ void RtspMuxer::onTrackReady(const Track::Ptr &track) { //根据track生产sdp - Sdp::Ptr sdp = Factory::getSdpByTrack(track); + Sdp::Ptr sdp = track->getSdp(); if (!sdp) { return; } - uint32_t ssrc = ((uint64_t) sdp.get()) & 0xFFFFFFFF; - - GET_CONFIG(uint32_t,audio_mtu,Rtp::kAudioMtuSize); - GET_CONFIG(uint32_t,video_mtu,Rtp::kVideoMtuSize); - - auto mtu = (track->getTrackType() == TrackVideo ? video_mtu : audio_mtu); - // 根据sdp生成rtp编码器ssrc - auto encoder = sdp->createRtpEncoder(ssrc, mtu); + auto encoder = Factory::getRtpEncoderBySdp(sdp); if (!encoder) { return; } diff --git a/src/RtspMuxer/RtspMuxer.h b/src/RtspMuxer/RtspMuxer.h index e1e192db..3d99537b 100644 --- a/src/RtspMuxer/RtspMuxer.h +++ b/src/RtspMuxer/RtspMuxer.h @@ -27,9 +27,9 @@ #ifndef ZLMEDIAKIT_RTSPMUXER_H #define ZLMEDIAKIT_RTSPMUXER_H -#include "RtspSdp.h" #include "Extension/Frame.h" #include "Common/MediaSink.h" +#include "RtpCodec.h" namespace mediakit{ /** diff --git a/src/RtspMuxer/RtspSdp.cpp b/src/RtspMuxer/RtspSdp.cpp deleted file mode 100644 index 7e2d02c4..00000000 --- a/src/RtspMuxer/RtspSdp.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* -* MIT License -* -* Copyright (c) 2016-2019 xiongziliang <771730766@qq.com> -* -* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit). -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in all -* copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -*/ -#include "RtspSdp.h" -#include "Extension/Factory.h" - -namespace mediakit{ - -RtpCodec::Ptr Sdp::createRtpEncoder(uint32_t ssrc, int mtu) { - return Factory::getRtpEncoderById(getCodecId(), - ssrc, - mtu, - _sample_rate, - _playload_type, - getTrackType() * 2); -} - -} - - diff --git a/src/RtspMuxer/RtspSdp.h b/src/RtspMuxer/RtspSdp.h deleted file mode 100644 index d8df5a9d..00000000 --- a/src/RtspMuxer/RtspSdp.h +++ /dev/null @@ -1,136 +0,0 @@ -/* -* MIT License -* -* Copyright (c) 2016-2019 xiongziliang <771730766@qq.com> -* -* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit). -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in all -* copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -*/ -#ifndef ZLMEDIAKIT_RTSPSDP_H -#define ZLMEDIAKIT_RTSPSDP_H - -#include "Util/base64.h" -#include "Extension/Track.h" -#include "RtspMuxer/RtpCodec.h" - -namespace mediakit { - -/** -* rtsp sdp基类 -*/ -class Sdp : public CodecInfo{ -public: - typedef std::shared_ptr Ptr; - - /** - * 构造sdp - * @param sample_rate 采样率 - * @param playload_type pt类型 - */ - Sdp(uint32_t sample_rate, uint8_t playload_type){ - _sample_rate = sample_rate; - _playload_type = playload_type; - } - - virtual ~Sdp(){} - - /** - * 获取sdp字符串 - * @return - */ - virtual string getSdp() const = 0; - - - /** - * 创建Rtp打包器 - * @param ssrc 打包器ssrc,可以为0 - * @param mtu mtu大小,一般小于1500字节,推荐1400 - * @return Rtp打包器 - */ - virtual RtpCodec::Ptr createRtpEncoder(uint32_t ssrc, int mtu); -private: - uint8_t _playload_type; - uint32_t _sample_rate; -}; - -/** -* sdp中除音视频外的其他描述部分 -*/ -class TitleSdp : public Sdp{ -public: - - /** - * 构造title类型sdp - * @param dur_sec rtsp点播时长,0代表直播,单位秒 - * @param header 自定义sdp描述 - * @param version sdp版本 - */ - TitleSdp(float dur_sec = 0, - const map &header = map(), - int version = 0) : Sdp(0,0){ - _printer << "v=" << version << "\r\n"; - - if(!header.empty()){ - for (auto &pr : header){ - _printer << pr.first << "=" << pr.second << "\r\n"; - } - } else { - _printer << "o=- 1383190487994921 1 IN IP4 0.0.0.0\r\n"; - _printer << "s=RTSP Session, streamed by the ZLMediaKit\r\n"; - _printer << "i=ZLMediaKit Live Stream\r\n"; - _printer << "c=IN IP4 0.0.0.0\r\n"; - _printer << "t=0 0\r\n"; - } - - if(dur_sec <= 0){ - _printer << "a=range:npt=0-\r\n"; - }else{ - _printer << "a=range:npt=0-" << dur_sec << "\r\n"; - } - _printer << "a=control:*\r\n"; - } - string getSdp() const override { - return _printer; - } - /** - * 返回音频或视频类型 - * @return - */ - TrackType getTrackType() const override { - return TrackTitle; - } - - /** - * 返回编码器id - * @return - */ - CodecId getCodecId() const override{ - return CodecInvalid; - } -private: - _StrPrinter _printer; -}; - - -} /* namespace mediakit */ - - - -#endif //ZLMEDIAKIT_RTSPSDP_H