From 23c2de9acfcea1e58c46314f5421807b28308590 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Wed, 19 Sep 2018 12:34:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=8C=E6=88=90=E4=B8=80?= =?UTF-8?q?=E4=BA=9B=E7=B1=BB=E7=9A=84=E6=8A=BD=E8=B1=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Player/PlayerBase.h | 107 +++++++++++++++++++++++++++++-- src/Rtsp/Rtsp.h | 5 +- src/Rtsp/RtspMaker.h | 139 ++++++++++++++++++++++++++++++++-------- 3 files changed, 218 insertions(+), 33 deletions(-) diff --git a/src/Player/PlayerBase.h b/src/Player/PlayerBase.h index 65b7e37a..0c93c5ee 100644 --- a/src/Player/PlayerBase.h +++ b/src/Player/PlayerBase.h @@ -35,6 +35,7 @@ #include "Network/Socket.h" #include "Util/mini.h" #include "Common/MediaSource.h" +#include "Util/RingBuffer.h" using namespace std; using namespace ZL::Util; @@ -44,6 +45,100 @@ using namespace ZL::Network; namespace ZL { namespace Player { +class TrackFrame : public Buffer { +public: + typedef std::shared_ptr Ptr; + virtual ~TrackFrame(){} + virtual uint32_t stamp() = 0; +}; + +class TrackFormat { +public: + typedef std::shared_ptr Ptr; + typedef RingBuffer RingType; + typedef RingType::RingReader::Ptr ReaderType; + + typedef enum { + VideoCodecInvalid = -1, + VideoCodecH264 = 0, + VideoCodecMax + } VideoCodecID; + + typedef enum { + AudioCodecInvalid = -1, + AudioCodecAAC = 0, + AudioCodecMax + } AudioCodecID; + TrackFormat(){ + _ring = std::make_shared(); + } + virtual ~TrackFormat(){} + virtual TrackType getTrackType() const = 0; + virtual int getCodecId() const = 0; + + ReaderType attachReader(bool useBuffer = false){ + return _ring->attach(useBuffer); + } + + void writeFrame(const TrackFrame::Ptr &frame,bool keypos = true){ + _ring->write(frame, keypos); + } +private: + RingType::Ptr _ring; +}; + +class VideoTrackFormat : public TrackFormat { +public: + TrackType getTrackType() const override { return TrackVideo;}; + virtual int getVideoHeight() const = 0; + virtual int getVideoWidth() const = 0; + virtual float getVideoFps() const = 0; +}; + +class AudioTrackFormat : public TrackFormat { +public: + TrackType getTrackType() const override { return TrackAudio;}; + virtual int getAudioSampleRate() const = 0; + virtual int getAudioSampleBit() const = 0; + virtual int getAudioChannel() const = 0; +}; + +class H264TrackFormat : public VideoTrackFormat{ +public: + H264TrackFormat(const string &sps,const string &pps){ + _sps = sps; + _pps = pps; + } + const string &getSps() const{ + return _sps; + } + const string &getPps() const{ + return _pps; + } + int getCodecId() const override{ + return TrackFormat::VideoCodecH264; + } +private: + string _sps; + string _pps; +}; + +class AACTrackFormat : public AudioTrackFormat{ +public: + AACTrackFormat(const string &aac_cfg){ + _cfg = aac_cfg; + } + const string &getAacCfg() const{ + return _cfg; + } + int getCodecId() const override{ + return TrackFormat::AudioCodecAAC; + } +private: + string _cfg; +}; + + class MediaFormat { public: virtual ~MediaFormat(){}; @@ -58,11 +153,6 @@ public: virtual const string& getPps() const { static string null;return null; }; virtual const string& getSps() const { static string null;return null; }; virtual const string& getAudioCfg() const { static string null;return null; }; - - virtual bool containAudio() const { return false; }; - virtual bool containVideo() const { return false; }; - - virtual float getDuration() const { return 0;}; }; class PlayerBase : public MediaFormat,public mINI{ @@ -105,6 +195,13 @@ public: virtual bool isInited() const { return true; }; //TrackVideo = 0, TrackAudio = 1 virtual float getRtpLossRate(int trackType) const {return 0; }; + virtual float getDuration() const { return 0;}; + + virtual bool containAudio() const { return false; }; + virtual bool containVideo() const { return false; }; + + virtual int getTrackCount() const { return 0;}; + virtual TrackFormat::Ptr getTrack(int index) const {return nullptr;}; protected: virtual void onShutdown(const SockException &ex) {}; virtual void onPlayResult(const SockException &ex) {}; diff --git a/src/Rtsp/Rtsp.h b/src/Rtsp/Rtsp.h index 2dc785ba..278df68d 100644 --- a/src/Rtsp/Rtsp.h +++ b/src/Rtsp/Rtsp.h @@ -37,9 +37,10 @@ using namespace std; using namespace ZL::Util; typedef enum { - TrackInvalid = -1, TrackVideo = 0, - TrackAudio + TrackAudio, + TrackInvalid, + TrackMax } TrackType; class RtspTrack{ diff --git a/src/Rtsp/RtspMaker.h b/src/Rtsp/RtspMaker.h index 9d66ee52..89464387 100644 --- a/src/Rtsp/RtspMaker.h +++ b/src/Rtsp/RtspMaker.h @@ -18,17 +18,47 @@ using namespace ZL::Rtsp; namespace ZL{ namespace Rtsp{ +/** + * sdp基类 + */ class Sdp { public: typedef std::shared_ptr Ptr; virtual ~Sdp(){} - virtual string getSdp() { return "";}; - virtual TrackType getTrackType() { return TrackInvalid;}; - virtual RtpMaker::Ptr createRtpMaker(const RtpMaker::onGetRTP &cb,uint32_t ui32Ssrc, int iMtuSize) { return nullptr;}; + /** + * 获取sdp字符串 + * @return + */ + virtual string getSdp() const { return "";}; + + /** + * 获取track类型 + * @return + */ + virtual TrackType getTrackType() const { return TrackInvalid;}; + + /** + * 获取rtp生成器 + * @param cb 回调lambad + * @param ui32Ssrc rtp ssrc + * @param iMtuSize rtp mtu + * @return + */ + virtual RtpMaker::Ptr createRtpMaker(const RtpMaker::onGetRTP &cb,uint32_t ui32Ssrc, int iMtuSize) const{ return nullptr;}; }; +/** + * sdp中除音视频外的其他描述部分 + */ class SdpTitle : public Sdp{ public: + + /** + * 构造title类型sdp + * @param dur_sec rtsp点播时长,0代表直播,单位秒 + * @param header 自定义sdp描述 + * @param version sdp版本 + */ SdpTitle(float dur_sec = 0, const map &header = map(), int version = 0){ @@ -53,7 +83,7 @@ public: } _printer << "a=control:*\r\n"; } - string getSdp() override { + string getSdp() const override { return _printer; } @@ -61,8 +91,21 @@ private: _StrPrinter _printer; }; +/** + * h264类型sdp + */ class SdpH264 : public Sdp { public: + + /** + * + * @param sps 264 sps,带0x00000001头 + * @param pps 264 pps,带0x00000001头 + * @param sample_rate 时间戳采样率,视频默认90000 + * @param playload_type rtp playload type 默认96 + * @param track_id trackID 默认为TrackVideo + * @param bitrate 比特率 + */ SdpH264(const string &sps, const string &pps, int sample_rate = 90000, @@ -100,15 +143,15 @@ public: _printer << "a=control:trackID=" << track_id << "\r\n"; } - string getSdp() override { + string getSdp() const override { return _printer; } - TrackType getTrackType() override { + TrackType getTrackType() const override { return TrackVideo; }; - RtpMaker::Ptr createRtpMaker(const RtpMaker::onGetRTP &cb,uint32_t ui32Ssrc, int iMtuSize) override{ + RtpMaker::Ptr createRtpMaker(const RtpMaker::onGetRTP &cb,uint32_t ui32Ssrc, int iMtuSize) const override{ return std::make_shared(cb,ui32Ssrc,iMtuSize,_sample_rate,_playload_type,_track_id * 2); }; @@ -121,8 +164,20 @@ private: }; +/** + * aac类型SDP + */ class SdpAAC : public Sdp { public: + + /** + * 构造aac sdp + * @param aac_cfg aac两个字节的配置描述 + * @param sample_rate 音频采样率 + * @param playload_type rtp playload type 默认96 + * @param track_id trackID 默认为TrackVideo + * @param bitrate 比特率 + */ SdpAAC(const string &aac_cfg, int sample_rate, int playload_type = 98, @@ -145,15 +200,15 @@ public: _printer << "a=control:trackID=" << track_id << "\r\n"; } - string getSdp() override { + string getSdp() const override { return _printer; } - TrackType getTrackType() override { + TrackType getTrackType() const override { return TrackAudio; }; - RtpMaker::Ptr createRtpMaker(const RtpMaker::onGetRTP &cb,uint32_t ui32Ssrc, int iMtuSize) override{ + RtpMaker::Ptr createRtpMaker(const RtpMaker::onGetRTP &cb,uint32_t ui32Ssrc, int iMtuSize) const override{ return std::make_shared(cb,ui32Ssrc,iMtuSize,_sample_rate,_playload_type,_track_id * 2); }; private: @@ -163,34 +218,67 @@ private: int _track_id; }; +/** + * rtsp生成器 + */ class RtspMaker{ public: - RtspMaker(const RtpMaker::onGetRTP &callback) : _vec_rtp_maker(8){ + /** + * 构成函数 + * @param callback rtp回调lambad + */ + RtspMaker(const RtpMaker::onGetRTP &callback) : _vec_rtp_maker(TrackMax){ _callback = callback; } - - template - void addTrack(First && first,Others &&...others){ - addTrack(std::forward(first)); - addTrack(std::forward(others)...); - } - template - void addTrack(First && first){ - _printer << first->getSdp(); - if(first->getTrackType() >= 0){ - auto rtpMaker = first-> createRtpMaker(_callback, 0,1400); - _vec_rtp_maker[first->getTrackType()] = rtpMaker; + + /** + * 添加音视频track + * @param sdp 媒体描述 + * @param ssrc 媒体rtp ssrc + * @param mtu 媒体rtp mtu + * @return 成功与否 + */ + bool addTrack(const Sdp & sdp,uint32_t ssrc = 0,int mtu = 1400){ + auto type = sdp.getTrackType(); + if(type < 0 || type >= _vec_rtp_maker.size()){ + return false; } + + if(_vec_rtp_maker[type]){ + return false; + } + + if(ssrc == 0){ + ssrc = ((uint64_t) &sdp) & 0xFFFFFFFF; + } + + auto rtpMaker = sdp.createRtpMaker(_callback, ssrc,mtu); + _vec_rtp_maker[sdp.getTrackType()] = rtpMaker; + _printer << sdp.getSdp(); + return true; } virtual ~RtspMaker() {}; - + + /** + * 获取完整的SDP字符串 + * @return SDP字符串 + */ string getSdp() { return _printer; } + + /** + * 打包RTP数据包 + * @param type 媒体类型 + * @param pcData 媒体数据 + * @param iDataLen 媒体数据长度 + * @param uiStamp 媒体时间戳,单位毫秒 + * @return 是否成功 + */ bool makeRtp(TrackType type,const char *pcData, int iDataLen, uint32_t uiStamp){ - if(type < 0 || type > _vec_rtp_maker.size()){ + if(type < 0 || type >= _vec_rtp_maker.size()){ return false; } auto track = _vec_rtp_maker[type]; @@ -205,7 +293,6 @@ private: vector _vec_rtp_maker; _StrPrinter _printer; RtpMaker::onGetRTP _callback; - };