From c1e91620d23e743645e9f89f884729af1a074422 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Tue, 23 Oct 2018 11:09:21 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=A7=E8=A7=84=E6=A8=A1=E4=BF=AE=E6=94=B9rt?= =?UTF-8?q?sp=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/Device/Device.cpp | 2 +- src/Device/Device.h | 3 +- src/Device/PlayerProxy.cpp | 2 +- src/MediaFile/MediaReader.h | 2 +- src/Player/Frame.h | 130 +++++++++++- src/Player/Player.cpp | 6 +- src/Player/Player.h | 6 +- src/Player/PlayerBase.h | 6 +- src/Player/Track.h | 36 +--- src/RTP/AACRtpCodec.cpp | 22 +- src/RTP/AACRtpCodec.h | 29 ++- src/RTP/H264RtpCodec.cpp | 16 +- src/RTP/H264RtpCodec.h | 20 +- src/RTP/RtpCodec.cpp | 13 ++ src/RTP/RtpCodec.h | 81 ++++++-- src/Rtmp/RtmpParser.h | 6 +- src/Rtmp/RtmpToRtspMediaSource.cpp | 2 +- src/Rtmp/RtmpToRtspMediaSource.h | 2 +- src/Rtsp/RtpParser.cpp | 4 +- src/Rtsp/RtpParser.h | 9 +- src/Rtsp/Rtsp.h | 24 +-- src/Rtsp/{RtspMaker.h => RtspEncoder.h} | 261 +++++++++++++++--------- src/Rtsp/RtspMediaSource.h | 1 + src/Rtsp/RtspToRtmpMediaSource.cpp | 2 +- src/Rtsp/RtspToRtmpMediaSource.h | 2 +- 25 files changed, 468 insertions(+), 219 deletions(-) rename src/Rtsp/{RtspMaker.h => RtspEncoder.h} (51%) diff --git a/src/Device/Device.cpp b/src/Device/Device.cpp index 79b5da6f..b2303615 100644 --- a/src/Device/Device.cpp +++ b/src/Device/Device.cpp @@ -278,7 +278,7 @@ void DevChannel::initVideo(const VideoInfo& info) { void DevChannel::initAudio(const AudioInfo& info) { m_audio.reset(new AudioInfo(info)); - m_pAdtsHeader = std::make_shared(); + m_pAdtsHeader = std::make_shared(); m_pAdtsHeader->syncword = 0x0FFF; m_pAdtsHeader->id = 0; diff --git a/src/Device/Device.h b/src/Device/Device.h index d53523f8..a4351cdc 100644 --- a/src/Device/Device.h +++ b/src/Device/Device.h @@ -35,6 +35,7 @@ #include "RTP/RtpMakerAAC.h" #include "RTP/RtpMakerH264.h" #include "Rtsp/RtspToRtmpMediaSource.h" +#include "Rtsp/RtspEncoder.h" #include "Util/TimeTicker.h" using namespace std; @@ -119,7 +120,7 @@ private: std::shared_ptr m_video; std::shared_ptr m_audio; SmoothTicker m_aTicker[2]; - std::shared_ptr m_pAdtsHeader; + std::shared_ptr m_pAdtsHeader; }; diff --git a/src/Device/PlayerProxy.cpp b/src/Device/PlayerProxy.cpp index 6882cc79..42dbbdad 100644 --- a/src/Device/PlayerProxy.cpp +++ b/src/Device/PlayerProxy.cpp @@ -97,7 +97,7 @@ void PlayerProxy::play(const char* strUrl) { strongSelf->initMedia(); } }); - setOnAudioCB( [weakSelf](const AdtsFrame &data ) { + setOnAudioCB( [weakSelf](const AACFrame &data ) { auto strongSelf = weakSelf.lock(); if(!strongSelf){ return; diff --git a/src/MediaFile/MediaReader.h b/src/MediaFile/MediaReader.h index ae43609f..19d44ad1 100644 --- a/src/MediaFile/MediaReader.h +++ b/src/MediaFile/MediaReader.h @@ -74,7 +74,7 @@ private: uint32_t m_audio_sample_rate = 0; uint32_t m_audio_num_channels = 0; string m_strAacCfg; - AdtsFrame m_adts; + AACFrame m_adts; int m_iDuration = 0; DevChannel::Ptr m_pChn; diff --git a/src/Player/Frame.h b/src/Player/Frame.h index 88cf82e7..5e936574 100644 --- a/src/Player/Frame.h +++ b/src/Player/Frame.h @@ -5,11 +5,43 @@ #ifndef ZLMEDIAKIT_FRAME_H #define ZLMEDIAKIT_FRAME_H +#include "Util/RingBuffer.h" #include "Network/Socket.h" +using namespace ZL::Util; using namespace ZL::Network; -class Frame : public Buffer { +typedef enum { + CodecInvalid = -1, + CodecH264 = 0, + CodecAAC = 0x0100, + CodecMax +} CodecId; + +typedef enum { + TrackInvalid = -1, + TrackVideo = 0, + TrackAudio, + TrackMax +} TrackType; + +class CodecInfo { +public: + CodecInfo(){} + virtual ~CodecInfo(){} + + /** + * 获取音视频类型 + */ + virtual TrackType getTrackType() const = 0; + + /** + * 获取编解码器类型 + */ + virtual CodecId getCodecId() const = 0; +}; + +class Frame : public Buffer, public CodecInfo{ public: typedef std::shared_ptr Ptr; virtual ~Frame(){} @@ -25,6 +57,78 @@ public: virtual uint32_t prefixSize() = 0; }; +/** + * 帧环形缓存接口类 + */ +class FrameRingInterface { +public: + typedef RingBuffer RingType; + + FrameRingInterface(){} + virtual ~FrameRingInterface(){} + + /** + * 获取帧环形缓存 + * @return + */ + virtual RingType::Ptr getFrameRing() const = 0; + + /** + * 设置帧环形缓存 + * @param ring + */ + virtual void setFrameRing(const RingType::Ptr &ring) = 0; + + /** + * 写入帧数据 + * @param frame 帧 + * @param key_pos 是否为关键帧 + */ + virtual void inputFrame(const Frame::Ptr &frame,bool key_pos) = 0; +}; + + +class FrameRing : public FrameRingInterface{ +public: + typedef std::shared_ptr Ptr; + + FrameRing(){ + //禁用缓存 + _frameRing = std::make_shared(1); + } + virtual ~FrameRing(){} + + /** + * 获取帧环形缓存 + * @return + */ + RingType::Ptr getFrameRing() const override { + return _frameRing; + } + + /** + * 设置帧环形缓存 + * @param ring + */ + void setFrameRing(const RingType::Ptr &ring) override { + _frameRing = ring; + } + + /** + * 输入数据帧 + * @param frame + * @param key_pos + */ + void inputFrame(const Frame::Ptr &frame,bool key_pos) override{ + _frameRing->write(frame,key_pos); + } +protected: + RingType::Ptr _frameRing; +}; + +/** + * 264帧类 + */ class H264Frame : public Frame { public: typedef std::shared_ptr Ptr; @@ -41,6 +145,14 @@ public: uint32_t prefixSize() override{ return iPrefixSize; } + + TrackType getTrackType() const override{ + return TrackVideo; + } + + CodecId getCodecId() const override{ + return CodecH264; + } public: uint16_t sequence; uint32_t timeStamp; @@ -49,10 +161,12 @@ public: uint32_t iPrefixSize = 4; }; -//ADTS 头中相对有用的信息 采样率、声道数、帧长度 -class AdtsFrame : public Frame { +/** + * aac帧,包含adts头 + */ +class AACFrame : public Frame { public: - typedef std::shared_ptr Ptr; + typedef std::shared_ptr Ptr; char *data() const override{ return (char *)buffer; @@ -66,6 +180,14 @@ public: uint32_t prefixSize() override{ return iPrefixSize; } + + TrackType getTrackType() const override{ + return TrackAudio; + } + + CodecId getCodecId() const override{ + return CodecAAC; + } public: unsigned int syncword; //12 bslbf 同步字The bit string ‘1111 1111 1111’,说明一个ADTS帧的开始 unsigned int id; //1 bslbf MPEG 标示符, 设置为1 diff --git a/src/Player/Player.cpp b/src/Player/Player.cpp index 4f2a1112..a4b64636 100644 --- a/src/Player/Player.cpp +++ b/src/Player/Player.cpp @@ -32,7 +32,7 @@ using namespace ZL::Util; -void writeAdtsHeader(const AdtsFrame &hed, uint8_t *pcAdts) { +void writeAdtsHeader(const AACFrame &hed, uint8_t *pcAdts) { pcAdts[0] = (hed.syncword >> 4 & 0xFF); //8bit pcAdts[1] = (hed.syncword << 4 & 0xF0); //4 bit pcAdts[1] |= (hed.id << 3 & 0x08); //1 bit @@ -85,7 +85,7 @@ string makeAdtsConfig(const uint8_t *pcAdts){ audioSpecificConfig[1] = (sampling_frequency_index << 7) | (channel_configuration << 3); return string((char *)audioSpecificConfig,2); } -void makeAdtsHeader(const string &strAudioCfg,AdtsFrame &adts) { +void makeAdtsHeader(const string &strAudioCfg,AACFrame &adts) { uint8_t cfg1 = strAudioCfg[0]; uint8_t cfg2 = strAudioCfg[1]; @@ -113,7 +113,7 @@ void makeAdtsHeader(const string &strAudioCfg,AdtsFrame &adts) { adts.adts_buffer_fullness = 2047; adts.no_raw_data_blocks_in_frame = 0; } -void getAACInfo(const AdtsFrame &adts,int &iSampleRate,int &iChannel){ +void getAACInfo(const AACFrame &adts,int &iSampleRate,int &iChannel){ iSampleRate = samplingFrequencyTable[adts.sf_index]; iChannel = adts.channel_configuration; } diff --git a/src/Player/Player.h b/src/Player/Player.h index 6808d117..0d00cf07 100644 --- a/src/Player/Player.h +++ b/src/Player/Player.h @@ -40,10 +40,10 @@ unsigned const samplingFrequencyTable[16] = { 96000, 88200, 11025, 8000, 7350, 0, 0, 0 }; -void makeAdtsHeader(const string &strAudioCfg,AdtsFrame &adts); -void writeAdtsHeader(const AdtsFrame &adts, uint8_t *pcAdts) ; +void makeAdtsHeader(const string &strAudioCfg,AACFrame &adts); +void writeAdtsHeader(const AACFrame &adts, uint8_t *pcAdts) ; string makeAdtsConfig(const uint8_t *pcAdts); -void getAACInfo(const AdtsFrame &adts,int &iSampleRate,int &iChannel); +void getAACInfo(const AACFrame &adts,int &iSampleRate,int &iChannel); bool getAVCInfo(const string &strSps,int &iVideoWidth, int &iVideoHeight, float &iVideoFps); #endif /* SRC_PLAYER_PLAYER_H_ */ diff --git a/src/Player/PlayerBase.h b/src/Player/PlayerBase.h index 21a52e68..0b91da62 100644 --- a/src/Player/PlayerBase.h +++ b/src/Player/PlayerBase.h @@ -94,7 +94,7 @@ public: virtual void setOnShutdown( const function &cb) {}; virtual void setOnPlayResult( const function &cb) {}; virtual void setOnVideoCB( const function &cb) {}; - virtual void setOnAudioCB( const function &cb) {}; + virtual void setOnAudioCB( const function &cb) {}; virtual float getProgress() const { return 0;}; virtual void seekTo(float fProgress) {}; @@ -140,7 +140,7 @@ public: } m_onGetVideoCB = cb; } - void setOnAudioCB(const function &cb) override{ + void setOnAudioCB(const function &cb) override{ if (m_parser) { m_parser->setOnAudioCB(cb); } @@ -269,7 +269,7 @@ protected: function m_playResultCB; std::shared_ptr m_parser; function m_onGetVideoCB; - function m_onGetAudioCB; + function m_onGetAudioCB; MediaSource::Ptr m_pMediaSrc; }; diff --git a/src/Player/Track.h b/src/Player/Track.h index b7dff3cc..b9421f53 100644 --- a/src/Player/Track.h +++ b/src/Player/Track.h @@ -14,35 +14,11 @@ using namespace std; using namespace ZL::Util; -class TrackFormat { +class TrackFormat : public FrameRingInterface , public CodecInfo{ public: typedef std::shared_ptr Ptr; - typedef RingBuffer RingType; - - typedef enum { - CodecInvalid = -1, - CodecH264 = 0, - CodecAAC = 0x0100, - CodecMax - } CodecID; - - TrackFormat(){ - _ring = std::make_shared(); - } + TrackFormat(){} virtual ~TrackFormat(){} - virtual TrackType getTrackType() const = 0; - virtual int getCodecId() const = 0; - - - void writeFrame(const Frame::Ptr &frame,bool keypos = true){ - _ring->write(frame, keypos); - } - - RingType::Ptr& getRing() { - return _ring; - } -private: - RingType::Ptr _ring; }; class VideoTrackFormat : public TrackFormat { @@ -73,8 +49,8 @@ public: const string &getPps() const{ return _pps; } - int getCodecId() const override{ - return TrackFormat::CodecH264; + CodecId getCodecId() const override{ + return CodecH264; } private: string _sps; @@ -89,8 +65,8 @@ public: const string &getAacCfg() const{ return _cfg; } - int getCodecId() const override{ - return TrackFormat::CodecAAC; + CodecId getCodecId() const override{ + return CodecAAC; } private: string _cfg; diff --git a/src/RTP/AACRtpCodec.cpp b/src/RTP/AACRtpCodec.cpp index 285c412f..64c89afe 100644 --- a/src/RTP/AACRtpCodec.cpp +++ b/src/RTP/AACRtpCodec.cpp @@ -9,16 +9,16 @@ AACRtpEncoder::AACRtpEncoder(uint32_t ui32Ssrc, uint32_t ui32SampleRate, uint8_t ui8PlayloadType, uint8_t ui8Interleaved) : - RtpInfo(ui32Ssrc, - ui32MtuSize, - ui32SampleRate, - ui8PlayloadType, - ui8Interleaved) { + RtpEncoder(ui32Ssrc, + ui32MtuSize, + ui32SampleRate, + ui8PlayloadType, + ui8Interleaved) { } -void AACRtpEncoder::inputFame(const Frame::Ptr &frame, bool key_pos) { - RtpCodec::inputFame(frame, false); +void AACRtpEncoder::inputFrame(const Frame::Ptr &frame, bool key_pos) { + RtpCodec::inputFrame(frame, false); GET_CONFIG_AND_REGISTER(uint32_t, cycleMS, Config::Rtp::kCycleMS); auto uiStamp = frame->stamp(); @@ -92,7 +92,7 @@ AACRtpDecoder::AACRtpDecoder(uint32_t ui32SampleRate) { m_sampleRate = ui32SampleRate; } -AdtsFrame::Ptr AACRtpDecoder::obtainFrame() { +AACFrame::Ptr AACRtpDecoder::obtainFrame() { //从缓存池重新申请对象,防止覆盖已经写入环形缓存的对象 auto frame = m_framePool.obtain(); frame->aac_frame_length = 7; @@ -104,7 +104,7 @@ void AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) { RtpCodec::inputRtp(rtppack, false); int length = rtppack->length - rtppack->offset; - if (m_adts->aac_frame_length + length - 4 > sizeof(AdtsFrame::buffer)) { + if (m_adts->aac_frame_length + length - 4 > sizeof(AACFrame::buffer)) { m_adts->aac_frame_length = 7; WarnL << "aac负载数据太长"; return; @@ -120,9 +120,9 @@ void AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) { } } -void AACRtpDecoder::onGetAdts(const AdtsFrame::Ptr &frame) { +void AACRtpDecoder::onGetAdts(const AACFrame::Ptr &frame) { //写入环形缓存 - RtpCodec::inputFame(frame, false); + RtpCodec::inputFrame(frame, false); m_adts = obtainFrame(); } diff --git a/src/RTP/AACRtpCodec.h b/src/RTP/AACRtpCodec.h index f8143d72..e679d27a 100644 --- a/src/RTP/AACRtpCodec.h +++ b/src/RTP/AACRtpCodec.h @@ -24,12 +24,20 @@ public: * @param key_pos 此参数内部强制转换为false,请忽略之 */ void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = false) override; + + TrackType getTrackType() const override{ + return TrackAudio; + } + + CodecId getCodecId() const override{ + return CodecAAC; + } private: - void onGetAdts(const AdtsFrame::Ptr &frame); - AdtsFrame::Ptr obtainFrame(); + void onGetAdts(const AACFrame::Ptr &frame); + AACFrame::Ptr obtainFrame(); private: - AdtsFrame::Ptr m_adts; - ResourcePool m_framePool; + AACFrame::Ptr m_adts; + ResourcePool m_framePool; uint32_t m_sampleRate; }; @@ -37,7 +45,7 @@ private: /** * aac adts转rtp类 */ -class AACRtpEncoder : public RtpInfo, public RtpCodec { +class AACRtpEncoder : public RtpEncoder { public: /** * @param ui32Ssrc ssrc @@ -58,7 +66,16 @@ public: * @param frame 带dats头的aac数据 * @param key_pos 此参数内部强制转换为false,请忽略之 */ - void inputFame(const Frame::Ptr &frame, bool key_pos = false) override; + void inputFrame(const Frame::Ptr &frame, bool key_pos = false) override; + + TrackType getTrackType() const override{ + return TrackAudio; + } + + CodecId getCodecId() const override{ + return CodecAAC; + } + private: void makeAACRtp(const void *pData, unsigned int uiLen, bool bMark, uint32_t uiStamp); private: diff --git a/src/RTP/H264RtpCodec.cpp b/src/RTP/H264RtpCodec.cpp index 81c58278..cf8788cb 100644 --- a/src/RTP/H264RtpCodec.cpp +++ b/src/RTP/H264RtpCodec.cpp @@ -97,7 +97,7 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) { void H264RtpDecoder::onGetH264(const H264Frame::Ptr &frame) { //写入环形缓存 - RtpCodec::inputFame(frame,frame->type == 5); + RtpCodec::inputFrame(frame,frame->type == 5); m_h264frame = obtainFrame(); } @@ -109,15 +109,15 @@ H264RtpEncoder::H264RtpEncoder(uint32_t ui32Ssrc, uint32_t ui32SampleRate, uint8_t ui8PlayloadType, uint8_t ui8Interleaved) : - RtpInfo(ui32Ssrc, - ui32MtuSize, - ui32SampleRate, - ui8PlayloadType, - ui8Interleaved) { + RtpEncoder(ui32Ssrc, + ui32MtuSize, + ui32SampleRate, + ui8PlayloadType, + ui8Interleaved) { } -void H264RtpEncoder::inputFame(const Frame::Ptr &frame, bool key_pos) { - RtpCodec::inputFame(frame, key_pos); +void H264RtpEncoder::inputFrame(const Frame::Ptr &frame, bool key_pos) { + RtpCodec::inputFrame(frame, key_pos); GET_CONFIG_AND_REGISTER(uint32_t,cycleMS,Config::Rtp::kCycleMS); auto uiStamp = frame->stamp(); diff --git a/src/RTP/H264RtpCodec.h b/src/RTP/H264RtpCodec.h index 05d87f58..2574a8fe 100644 --- a/src/RTP/H264RtpCodec.h +++ b/src/RTP/H264RtpCodec.h @@ -24,6 +24,14 @@ public: * @param key_pos 此参数忽略之 */ void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = true) override; + + TrackType getTrackType() const override{ + return TrackVideo; + } + + CodecId getCodecId() const override{ + return CodecH264; + } private: bool decodeRtp(const RtpPacket::Ptr &rtp); void onGetH264(const H264Frame::Ptr &frame); @@ -36,7 +44,7 @@ private: /** * 264 rtp打包类 */ -class H264RtpEncoder : public RtpInfo, public RtpCodec { +class H264RtpEncoder : public RtpEncoder{ public: /** @@ -58,7 +66,15 @@ public: * @param frame 帧数据,必须 * @param key_pos */ - void inputFame(const Frame::Ptr &frame, bool key_pos) override; + void inputFrame(const Frame::Ptr &frame, bool key_pos) override; + + TrackType getTrackType() const override{ + return TrackVideo; + } + + CodecId getCodecId() const override{ + return CodecH264; + } private: void makeH264Rtp(const void *pData, unsigned int uiLen, bool bMark, uint32_t uiStamp); private: diff --git a/src/RTP/RtpCodec.cpp b/src/RTP/RtpCodec.cpp index c738454d..b36437bf 100644 --- a/src/RTP/RtpCodec.cpp +++ b/src/RTP/RtpCodec.cpp @@ -3,3 +3,16 @@ // #include "RtpCodec.h" + +RtpEncoder::RtpEncoder(uint32_t ui32Ssrc, + uint32_t ui32MtuSize, + uint32_t ui32SampleRate, + uint8_t ui8PlayloadType, + uint8_t ui8Interleaved) : + RtpInfo(ui32Ssrc, + ui32MtuSize, + ui32SampleRate, + ui8PlayloadType, + ui8Interleaved) { + +} diff --git a/src/RTP/RtpCodec.h b/src/RTP/RtpCodec.h index 389cbea4..d0262bef 100644 --- a/src/RTP/RtpCodec.h +++ b/src/RTP/RtpCodec.h @@ -14,35 +14,55 @@ using namespace std; using namespace ZL::Util; using namespace ZL::Player; -class RtpCodec{ +class RtpPacket { public: - typedef std::shared_ptr Ptr; - typedef RingBuffer FrameRing; - typedef RingBuffer RtpRing; + typedef std::shared_ptr Ptr; + uint8_t interleaved; + uint8_t PT; + bool mark; + uint32_t length; + uint32_t timeStamp; + uint16_t sequence; + uint32_t ssrc; + uint8_t payload[1560]; + uint8_t offset; + TrackType type; +}; - RtpCodec(){ +class RtpRingInterface { +public: + typedef RingBuffer RingType; + + RtpRingInterface(){} + virtual ~RtpRingInterface(){} + virtual RingType::Ptr getRtpRing() const = 0; + virtual void setRtpRing(const RingType::Ptr &ring) = 0; + virtual void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) = 0; +}; + +class RtpRing : public RtpRingInterface { +public: + typedef std::shared_ptr Ptr; + + RtpRing(){ //禁用缓存 - _frameRing = std::make_shared(1); - _rtpRing = std::make_shared(1); + _rtpRing = std::make_shared(1); } - virtual ~RtpCodec(){} + virtual ~RtpRing(){} - FrameRing::Ptr &getFrameRing() { - return _frameRing; - } - RtpRing::Ptr &getRtpRing() { + RingType::Ptr getRtpRing() const override { return _rtpRing; } - virtual void inputFame(const Frame::Ptr &frame,bool key_pos){ - _frameRing->write(frame,key_pos); + void setRtpRing(const RingType::Ptr &ring) override { + _rtpRing = ring; } - virtual void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos){ + + void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) override{ _rtpRing->write(rtp,key_pos); } -private: - FrameRing::Ptr _frameRing; - RtpRing::Ptr _rtpRing; +protected: + RingType::Ptr _rtpRing; }; @@ -105,6 +125,31 @@ protected: ResourcePool m_rtpPool; }; +class RtpCodec : public RtpRing, public FrameRing , public CodecInfo{ +public: + typedef std::shared_ptr Ptr; + RtpCodec(){} + virtual ~RtpCodec(){} +}; + +class RtpEncoder : public RtpInfo, public RtpCodec{ +public: + typedef std::shared_ptr Ptr; + + /** + * @param ui32Ssrc ssrc + * @param ui32MtuSize mtu大小 + * @param ui32SampleRate 采样率,强制为90000 + * @param ui8PlayloadType pt类型 + * @param ui8Interleaved rtsp interleaved + */ + RtpEncoder(uint32_t ui32Ssrc, + uint32_t ui32MtuSize = 1400, + uint32_t ui32SampleRate = 90000, + uint8_t ui8PlayloadType = 96, + uint8_t ui8Interleaved = TrackVideo * 2); + ~RtpEncoder() {} +}; diff --git a/src/Rtmp/RtmpParser.h b/src/Rtmp/RtmpParser.h index ac687576..51d84b03 100644 --- a/src/Rtmp/RtmpParser.h +++ b/src/Rtmp/RtmpParser.h @@ -57,7 +57,7 @@ public: lock_guard lck(m_mtxCB); onVideo = cb; } - void setOnAudioCB(const function &cb) override{ + void setOnAudioCB(const function &cb) override{ lock_guard lck(m_mtxCB); onAudio = cb; } @@ -140,7 +140,7 @@ private: //video H264Frame m_h264frame; //aduio - AdtsFrame m_adts; + AACFrame m_adts; int m_iSampleRate = 44100; int m_iSampleBit = 16; @@ -158,7 +158,7 @@ private: float m_fDuration = 0; mutable Ticker m_ticker; function onVideo; - function onAudio; + function onAudio; recursive_mutex m_mtxCB; diff --git a/src/Rtmp/RtmpToRtspMediaSource.cpp b/src/Rtmp/RtmpToRtspMediaSource.cpp index 071e8d4f..87cade63 100644 --- a/src/Rtmp/RtmpToRtspMediaSource.cpp +++ b/src/Rtmp/RtmpToRtspMediaSource.cpp @@ -55,7 +55,7 @@ void RtmpToRtspMediaSource::onGetH264(const H264Frame &frame) { m_pRtpMaker_h264->makeRtp(frame.data() + 4, frame.size() - 4, frame.timeStamp); } } -inline void RtmpToRtspMediaSource::onGetAdts(const AdtsFrame &frame) { +inline void RtmpToRtspMediaSource::onGetAdts(const AACFrame &frame) { if(m_pRecorder){ m_pRecorder->inputAAC((char *) frame.buffer, frame.aac_frame_length, frame.timeStamp); } diff --git a/src/Rtmp/RtmpToRtspMediaSource.h b/src/Rtmp/RtmpToRtspMediaSource.h index f01cc594..cac34dc1 100644 --- a/src/Rtmp/RtmpToRtspMediaSource.h +++ b/src/Rtmp/RtmpToRtspMediaSource.h @@ -94,7 +94,7 @@ private: bool m_bEnableHls; bool m_bEnableMp4; void onGetH264(const H264Frame &frame); - void onGetAdts(const AdtsFrame &frame); + void onGetAdts(const AACFrame &frame); void makeSDP(); }; diff --git a/src/Rtsp/RtpParser.cpp b/src/Rtsp/RtpParser.cpp index 30f0a1c4..80c7046b 100644 --- a/src/Rtsp/RtpParser.cpp +++ b/src/Rtsp/RtpParser.cpp @@ -242,7 +242,7 @@ inline bool RtpParser::inputAudio(const RtpPacket& rtppack, char *frame = (char *) rtppack.payload + rtppack.offset; int length = rtppack.length - rtppack.offset; - if (m_adts.aac_frame_length + length - 4 > sizeof(AdtsFrame::buffer)) { + if (m_adts.aac_frame_length + length - 4 > sizeof(AACFrame::buffer)) { m_adts.aac_frame_length = 7; return false; } @@ -302,7 +302,7 @@ inline void RtpParser::onGetH264(H264Frame& frame) { } } -inline void RtpParser::onGetAdts(AdtsFrame& frame) { +inline void RtpParser::onGetAdts(AACFrame& frame) { //frame.timeStamp=ticker1.elapsedTime(); lock_guard lck(m_mtxCB); if (onAudio) { diff --git a/src/Rtsp/RtpParser.h b/src/Rtsp/RtpParser.h index 6f9e4849..bedf15b9 100644 --- a/src/Rtsp/RtpParser.h +++ b/src/Rtsp/RtpParser.h @@ -32,6 +32,7 @@ #include "Player/Player.h" #include "Player/PlayerBase.h" #include "Util/TimeTicker.h" +#include "RTP/RtpCodec.h" using namespace std; using namespace ZL::Util; @@ -51,7 +52,7 @@ public: lock_guard lck(m_mtxCB); onVideo = cb; } - void setOnAudioCB(const function &cb) override{ + void setOnAudioCB(const function &cb) override{ lock_guard lck(m_mtxCB); onAudio = cb; } @@ -120,11 +121,11 @@ private: inline bool inputAudio(const RtpPacket &rtp, const RtspTrack &track); inline void _onGetH264(H264Frame &frame); inline void onGetH264(H264Frame &frame); - inline void onGetAdts(AdtsFrame &frame); + inline void onGetAdts(AACFrame &frame); //video H264Frame m_h264frame; //aduio - AdtsFrame m_adts; + AACFrame m_adts; int m_iSampleRate = 44100; int m_iSampleBit = 16; @@ -142,7 +143,7 @@ private: bool m_bParseSpsDelay = false; function onVideo; - function onAudio; + function onAudio; recursive_mutex m_mtxCB; }; diff --git a/src/Rtsp/Rtsp.h b/src/Rtsp/Rtsp.h index 278df68d..642f7a7d 100644 --- a/src/Rtsp/Rtsp.h +++ b/src/Rtsp/Rtsp.h @@ -32,22 +32,17 @@ #include #include "Common/config.h" #include "Util/util.h" +#include "Player/Frame.h" using namespace std; using namespace ZL::Util; -typedef enum { - TrackVideo = 0, - TrackAudio, - TrackInvalid, - TrackMax -} TrackType; class RtspTrack{ public: uint8_t PT; uint8_t interleaved; - TrackType type = (TrackType) -1; + TrackType type = TrackInvalid; string trackSdp; string controlSuffix; bool inited; @@ -56,21 +51,6 @@ public: uint32_t timeStamp; }; -class RtpPacket { -public: - typedef std::shared_ptr Ptr; - uint8_t interleaved; - uint8_t PT; - bool mark; - uint32_t length; - uint32_t timeStamp; - uint16_t sequence; - uint32_t ssrc; - uint8_t payload[1560]; - uint8_t offset; - TrackType type; -}; - class RtcpCounter { public: uint32_t pktCnt = 0; diff --git a/src/Rtsp/RtspMaker.h b/src/Rtsp/RtspEncoder.h similarity index 51% rename from src/Rtsp/RtspMaker.h rename to src/Rtsp/RtspEncoder.h index 0e1cbcd0..49c7f5a8 100644 --- a/src/Rtsp/RtspMaker.h +++ b/src/Rtsp/RtspEncoder.h @@ -5,51 +5,71 @@ #ifndef ZLMEDIAKIT_RTSPMAKER_H #define ZLMEDIAKIT_RTSPMAKER_H -#include "Device/base64.h" -#include "Rtsp.h" -#include "RTP/RtpMaker.h" -#include "RTP/RtpMakerH264.h" -#include "RTP/RtpMakerAAC.h" -#include "Player/PlayerBase.h" - -using namespace ZL::Player; -using namespace ZL::Rtsp; +#include "RTP/H264RtpCodec.h" +#include "RTP/AACRtpCodec.h" +#include "Util/base64.h" namespace ZL{ namespace Rtsp{ /** - * sdp基类 - */ -class Sdp { +* sdp基类 +*/ +class Sdp : public TrackFormat , public RtpRingInterface{ public: typedef std::shared_ptr Ptr; + Sdp(){} virtual ~Sdp(){} /** * 获取sdp字符串 * @return */ - virtual string getSdp() const { return "";}; + virtual string getSdp() const = 0; - /** - * 获取track类型 - * @return - */ - virtual TrackType getTrackType() const { return TrackInvalid;}; + TrackType getTrackType() const override { + 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;}; + CodecId getCodecId() const override{ + return CodecInvalid; + } + + FrameRingInterface::RingType::Ptr getFrameRing() const override { + return _encoder->getFrameRing(); + } + + RtpRingInterface::RingType::Ptr getRtpRing() const override{ + return _encoder->getRtpRing(); + } + + void inputFrame(const Frame::Ptr &frame,bool key_pos) override{ + _encoder->inputFrame(frame,key_pos); + } + + void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) override{ + _encoder->inputRtp(rtp,key_pos); + } + + virtual void createRtpEncoder(uint32_t ssrc, int mtu) = 0; + + void setFrameRing(const FrameRingInterface::RingType::Ptr &ring) override{ + if(_encoder){ + _encoder->setFrameRing(ring); + } + } + void setRtpRing(const RtpRingInterface::RingType::Ptr &ring) override{ + if(_encoder){ + _encoder->setRtpRing(ring); + } + } + +protected: + RtpEncoder::Ptr _encoder; }; /** - * sdp中除音视频外的其他描述部分 - */ +* sdp中除音视频外的其他描述部分 +*/ class SdpTitle : public Sdp{ public: @@ -70,8 +90,8 @@ public: } } else { _printer << "o=- 1383190487994921 1 IN IP4 0.0.0.0\r\n"; - _printer << "s=RTSP Session, streamed by the ZL\r\n"; - _printer << "i=ZL Live Stream\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"; } @@ -86,14 +106,14 @@ public: string getSdp() const override { return _printer; } - + void createRtpEncoder(uint32_t ssrc, int mtu) override {} private: _StrPrinter _printer; }; /** - * h264类型sdp - */ +* h264类型sdp +*/ class SdpH264 : public Sdp { public: @@ -111,12 +131,12 @@ public: int sample_rate = 90000, int playload_type = 96, int track_id = TrackVideo, - int bitrate = 4000){ + int bitrate = 4000) { _playload_type = playload_type; _sample_rate = sample_rate; _track_id = track_id; - + //视频通道 _printer << "m=video 0 RTP/AVP " << playload_type << "\r\n"; _printer << "b=AS:" << bitrate << "\r\n"; @@ -149,12 +169,19 @@ public: TrackType getTrackType() const override { return TrackVideo; - }; + } - 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); - }; + CodecId getCodecId() const override { + return CodecH264; + } + void createRtpEncoder(uint32_t ssrc, int mtu) override{ + _encoder = std::make_shared(ssrc, + mtu, + _sample_rate, + _playload_type, + _track_id * 2); + } private: _StrPrinter _printer; int _playload_type; @@ -165,8 +192,8 @@ private: /** - * aac类型SDP - */ +* aac类型SDP +*/ class SdpAAC : public Sdp { public: @@ -207,10 +234,29 @@ public: TrackType getTrackType() const override { return TrackAudio; }; + CodecId getCodecId() const override { + return CodecAAC; + } - 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); - }; + void createRtpEncoder(uint32_t ssrc, + int mtu) override{ + _encoder = std::make_shared(ssrc, + mtu, + _sample_rate, + _playload_type, + _track_id * 2); + } + + void setFrameRing(const FrameRingInterface::RingType::Ptr &ring) override{ + if(_encoder){ + _encoder->setFrameRing(ring); + } + } + void setRtpRing(const RtpRingInterface::RingType::Ptr &ring) override{ + if(_encoder){ + _encoder->setRtpRing(ring); + } + } private: _StrPrinter _printer; int _playload_type; @@ -219,87 +265,118 @@ private: }; /** - * rtsp生成器 - */ -class RtspMaker{ +* rtsp生成器 +*/ +class RtspEncoder : public FrameRingInterface , public RtpRingInterface{ public: /** * 构成函数 - * @param callback rtp回调lambad */ - RtspMaker(const RtpMaker::onGetRTP &callback) : _vec_rtp_maker(TrackMax){ - _callback = callback; + RtspEncoder(){ + //自适应缓存 + _rtpRing = std::make_shared(0); + //禁用缓存 + _frameRing = std::make_shared(1); } + virtual ~RtspEncoder(){} /** * 添加音视频track - * @param sdp 媒体描述 + * @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; - } - + void addTrack(const Sdp::Ptr & sdp,uint32_t ssrc = 0,int mtu = 1400){ if(ssrc == 0){ - ssrc = ((uint64_t) &sdp) & 0xFFFFFFFF; + ssrc = ((uint64_t) sdp.get()) & 0xFFFFFFFF; } - - auto rtpMaker = sdp.createRtpMaker(_callback, ssrc,mtu); - _vec_rtp_maker[sdp.getTrackType()] = rtpMaker; - _printer << sdp.getSdp(); - return true; + sdp->createRtpEncoder(ssrc, mtu); + sdp->setFrameRing(_frameRing); + sdp->setRtpRing(_rtpRing); + _sdp_map[sdp->getTrackType()] = sdp; } - virtual ~RtspMaker() {}; /** * 获取完整的SDP字符串 * @return SDP字符串 */ string getSdp() { - return _printer; + _StrPrinter printer; + for(auto &pr : _sdp_map){ + printer << pr.second->getSdp() ; + } + return printer; } /** - * 打包RTP数据包 - * @param type 媒体类型 - * @param pcData 媒体数据 - * @param iDataLen 媒体数据长度 - * @param uiStamp 媒体时间戳,单位毫秒 - * @return 是否成功 + * 写入帧数据然后打包rtp + * @param frame 帧数据 + * @param key_pos 是否为关键帧 */ - bool makeRtp(TrackType type,const char *pcData, int iDataLen, uint32_t uiStamp){ - if(type < 0 || type >= _vec_rtp_maker.size()){ - return false; + void inputFrame(const Frame::Ptr &frame,bool key_pos = true) override { + auto it = _sdp_map.find(frame->getTrackType()); + if(it == _sdp_map.end()){ + return ; } - auto track = _vec_rtp_maker[type]; - if(!track){ - return false; - } - track->makeRtp(pcData,iDataLen,uiStamp); - return true; + it->second->inputFrame(frame,key_pos); } + /** + * 也可以在外部打包好rtp然后再写入 + * @param rtp rtp包 + * @param key_pos 是否为关键帧的第一个rtp包 + */ + void inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = true) override { + _rtpRing->write(rtp,key_pos); + } + + /** + * 获取rtp环形缓存 + * @return + */ + RtpRingInterface::RingType::Ptr getRtpRing() const override{ + return _rtpRing; + } + + /** + * 获取帧环形缓存 + * @return + */ + FrameRingInterface::RingType::Ptr getFrameRing() const override{ + return _frameRing; + } + + /** + * 设置帧环形缓存 + * @param ring + */ + void setFrameRing(const FrameRingInterface::RingType::Ptr &ring) override{ + _frameRing = ring; + for(auto &pr : _sdp_map){ + pr.second->setFrameRing(ring); + } + } + + + /** + * 设置rtp环形缓存 + * @param ring + */ + void setRtpRing(const RtpRingInterface::RingType::Ptr &ring) override{ + _rtpRing = ring; + for(auto &pr : _sdp_map){ + pr.second->setRtpRing(ring); + } + } private: - vector _vec_rtp_maker; - _StrPrinter _printer; - RtpMaker::onGetRTP _callback; + map _sdp_map; + RtpRingInterface::RingType::Ptr _rtpRing; + FrameRingInterface::RingType::Ptr _frameRing; }; - - - - } } diff --git a/src/Rtsp/RtspMediaSource.h b/src/Rtsp/RtspMediaSource.h index f8939d04..72e9f954 100644 --- a/src/Rtsp/RtspMediaSource.h +++ b/src/Rtsp/RtspMediaSource.h @@ -35,6 +35,7 @@ #include "Rtsp.h" #include "Common/config.h" #include "Common/MediaSource.h" +#include "RTP/RtpCodec.h" #include "Util/logger.h" #include "Util/RingBuffer.h" diff --git a/src/Rtsp/RtspToRtmpMediaSource.cpp b/src/Rtsp/RtspToRtmpMediaSource.cpp index 810ab116..9d3bd5c8 100644 --- a/src/Rtsp/RtspToRtmpMediaSource.cpp +++ b/src/Rtsp/RtspToRtmpMediaSource.cpp @@ -124,7 +124,7 @@ void RtspToRtmpMediaSource::onGetH264(const H264Frame& frame) { rtmpPkt->typeId = MSG_VIDEO; m_pRtmpSrc->onGetMedia(rtmpPkt); } -void RtspToRtmpMediaSource::onGetAdts(const AdtsFrame& frame) { +void RtspToRtmpMediaSource::onGetAdts(const AACFrame& frame) { if(m_pRecorder){ m_pRecorder->inputAAC((char *) frame.buffer, frame.aac_frame_length, frame.timeStamp); } diff --git a/src/Rtsp/RtspToRtmpMediaSource.h b/src/Rtsp/RtspToRtmpMediaSource.h index b8a05407..ac00a9ac 100644 --- a/src/Rtsp/RtspToRtmpMediaSource.h +++ b/src/Rtsp/RtspToRtmpMediaSource.h @@ -97,7 +97,7 @@ private: bool m_bEnableHls; bool m_bEnableMp4; void onGetH264(const H264Frame &frame); - void onGetAdts(const AdtsFrame &frame); + void onGetAdts(const AACFrame &frame); void makeVideoConfigPkt(); void makeAudioConfigPkt(); void makeMetaData();