From 625d7e30c032e4098012100bf4da22b796216139 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Mon, 11 May 2020 22:33:10 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B4=E7=90=86=E5=92=8C=E7=B2=BE=E7=AE=80?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Common/Device.cpp | 4 +- src/Extension/AAC.h | 86 +++++---------- src/Extension/AACRtmp.cpp | 4 +- src/Extension/AACRtmp.h | 4 - src/Extension/AACRtp.cpp | 4 +- src/Extension/AACRtp.h | 3 - src/Extension/Frame.cpp | 70 +++++++++++- src/Extension/Frame.h | 216 +++++++++++++++++-------------------- src/Extension/G711.h | 128 +++------------------- src/Extension/G711Rtmp.cpp | 8 +- src/Extension/G711Rtmp.h | 4 - src/Extension/G711Rtp.cpp | 19 ++-- src/Extension/G711Rtp.h | 4 - src/Extension/H264.h | 96 +++-------------- src/Extension/H264Rtmp.h | 4 - src/Extension/H264Rtp.h | 4 - src/Extension/H265.h | 96 ++++------------- src/Extension/H265Rtmp.h | 4 - src/Extension/H265Rtp.h | 4 - src/Extension/Track.h | 67 ++++++++++-- src/Rtmp/Rtmp.h | 41 +------ src/Rtp/RtpProcess.cpp | 8 +- src/Rtsp/Rtsp.h | 12 --- 23 files changed, 326 insertions(+), 564 deletions(-) diff --git a/src/Common/Device.cpp b/src/Common/Device.cpp index 91408acc..71f42b39 100644 --- a/src/Common/Device.cpp +++ b/src/Common/Device.cpp @@ -163,7 +163,9 @@ void DevChannel::inputG711(const char *data, int len, uint32_t dts){ if (dts == 0) { dts = (uint32_t)_aTicker[1].elapsedTime(); } - inputFrame(std::make_shared(_audio->codecId, (char*)data, len, dts, 0)); + auto frame = std::make_shared((char*)data, len, dts, 0); + frame->setCodec(_audio->codecId); + inputFrame(frame); } void DevChannel::initVideo(const VideoInfo &info) { diff --git a/src/Extension/AAC.h b/src/Extension/AAC.h index 2a57d6d4..40a3b6c2 100644 --- a/src/Extension/AAC.h +++ b/src/Extension/AAC.h @@ -18,19 +18,11 @@ namespace mediakit{ class AACFrame; -unsigned const samplingFrequencyTable[16] = { 96000, 88200, - 64000, 48000, - 44100, 32000, - 24000, 22050, - 16000, 12000, - 11025, 8000, - 7350, 0, 0, 0 }; - -void makeAdtsHeader(const string &strAudioCfg,AACFrame &adts); -void writeAdtsHeader(const AACFrame &adts, uint8_t *pcAdts) ; -string makeAdtsConfig(const uint8_t *pcAdts); -void getAACInfo(const AACFrame &adts,int &iSampleRate,int &iChannel); - +unsigned const samplingFrequencyTable[16] = { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350, 0, 0, 0 }; +void makeAdtsHeader(const string &strAudioCfg,AACFrame &adts); +void writeAdtsHeader(const AACFrame &adts, uint8_t *pcAdts) ; +string makeAdtsConfig(const uint8_t *pcAdts); +void getAACInfo(const AACFrame &adts,int &iSampleRate,int &iChannel); /** * aac帧,包含adts头 @@ -46,14 +38,10 @@ public: return aac_frame_length; } uint32_t dts() const override { - return timeStamp; + return _dts; } uint32_t prefixSize() const override{ - return iPrefixSize; - } - - TrackType getTrackType() const override{ - return TrackAudio; + return _prefix_size; } CodecId getCodecId() const override{ @@ -83,16 +71,16 @@ public: unsigned int copyright_identification_start; //1 bslbf unsigned int aac_frame_length; // 13 bslbf 一个ADTS帧的长度包括ADTS头和raw data block unsigned int adts_buffer_fullness; //11 bslbf 0x7FF 说明是码率可变的码流 -//no_raw_data_blocks_in_frame 表示ADTS帧中有number_of_raw_data_blocks_in_frame + 1个AAC原始帧. -//所以说number_of_raw_data_blocks_in_frame == 0 -//表示说ADTS帧中有一个AAC数据块并不是说没有。(一个AAC原始帧包含一段时间内1024个采样及相关数据) + //no_raw_data_blocks_in_frame 表示ADTS帧中有number_of_raw_data_blocks_in_frame + 1个AAC原始帧. + //所以说number_of_raw_data_blocks_in_frame == 0 + //表示说ADTS帧中有一个AAC数据块并不是说没有。(一个AAC原始帧包含一段时间内1024个采样及相关数据) unsigned int no_raw_data_blocks_in_frame; //2 uimsfb unsigned char buffer[2 * 1024 + 7]; - uint32_t timeStamp; - uint32_t iPrefixSize = 7; -} ; + uint32_t _dts; + uint32_t _prefix_size = 7; +}; -class AACFrameNoCacheAble : public FrameNoCacheAble { +class AACFrameNoCacheAble : public FrameFromPtr { public: typedef std::shared_ptr Ptr; @@ -100,11 +88,7 @@ public: _ptr = ptr; _size = size; _dts = dts; - _prefixSize = prefixeSize; - } - - TrackType getTrackType() const override{ - return TrackAudio; + _prefix_size = prefixeSize; } CodecId getCodecId() const override{ @@ -118,8 +102,7 @@ public: bool configFrame() const override{ return false; } -} ; - +}; /** * aac音频通道 @@ -173,7 +156,6 @@ public: /** * 获取aac两个字节的配置 - * @return */ const string &getAacCfg() const{ return _cfg; @@ -181,7 +163,6 @@ public: /** * 返回编码类型 - * @return */ CodecId getCodecId() const override{ return CodecAAC; @@ -189,39 +170,36 @@ public: /** * 在获取aac_cfg前是无效的Track - * @return */ bool ready() override { return !_cfg.empty(); } - /** - * 返回音频采样率 - * @return - */ + * 返回音频采样率 + */ int getAudioSampleRate() const override{ return _sampleRate; } + /** * 返回音频采样位数,一般为16或8 - * @return */ int getAudioSampleBit() const override{ return _sampleBit; } + /** * 返回音频通道数 - * @return */ int getAudioChannel() const override{ return _channel; } /** - * 输入数据帧,并获取aac_cfg - * @param frame 数据帧 - */ + * 输入数据帧,并获取aac_cfg + * @param frame 数据帧 + */ void inputFrame(const Frame::Ptr &frame) override{ if (_cfg.empty()) { //未获取到aac_cfg信息 @@ -247,6 +225,7 @@ private: makeAdtsHeader(_cfg,aacFrame); getAACInfo(aacFrame,_sampleRate,_channel); } + Track::Ptr clone() override { return std::make_shared::type >(*this); } @@ -260,15 +239,13 @@ private: int _channel = 0; }; - /** -* aac类型SDP -*/ + * aac类型SDP + */ class AACSdp : public Sdp { public: - /** - * + * 构造函数 * @param aac_cfg aac两个字节的配置描述 * @param sample_rate 音频采样率 * @param playload_type rtp playload type 默认98 @@ -288,16 +265,13 @@ public: _printer << "a=fmtp:" << playload_type << " streamtype=5;profile-level-id=1;mode=AAC-hbr;" << "sizelength=13;indexlength=3;indexdeltalength=3;config=" << configStr << "\r\n"; - _printer << "a=control:trackID=" << getTrackType() << "\r\n"; + _printer << "a=control:trackID=" << (int)TrackAudio << "\r\n"; } string getSdp() const override { return _printer; } - TrackType getTrackType() const override { - return TrackAudio; - } CodecId getCodecId() const override { return CodecAAC; } @@ -306,6 +280,4 @@ private: }; }//namespace mediakit - - -#endif //ZLMEDIAKIT_AAC_H +#endif //ZLMEDIAKIT_AAC_H \ No newline at end of file diff --git a/src/Extension/AACRtmp.cpp b/src/Extension/AACRtmp.cpp index 2b1d3bd2..0367664f 100644 --- a/src/Extension/AACRtmp.cpp +++ b/src/Extension/AACRtmp.cpp @@ -21,7 +21,7 @@ AACFrame::Ptr AACRtmpDecoder::obtainFrame() { //从缓存池重新申请对象,防止覆盖已经写入环形缓存的对象 auto frame = ResourcePoolHelper::obtainObj(); frame->aac_frame_length = 7; - frame->iPrefixSize = 7; + frame->_prefix_size = 7; return frame; } @@ -63,7 +63,7 @@ void AACRtmpDecoder::onGetAAC(const char* pcData, int iLen, uint32_t ui32TimeSta //拷贝aac负载 memcpy(_adts->buffer + 7, pcData, iLen); _adts->aac_frame_length = 7 + iLen; - _adts->timeStamp = ui32TimeStamp; + _adts->_dts = ui32TimeStamp; //adts结构头转成头7个字节 writeAdtsHeader(*_adts, _adts->buffer); diff --git a/src/Extension/AACRtmp.h b/src/Extension/AACRtmp.h index 20f424d5..207fc18f 100644 --- a/src/Extension/AACRtmp.h +++ b/src/Extension/AACRtmp.h @@ -33,10 +33,6 @@ public: */ bool inputRtmp(const RtmpPacket::Ptr &Rtmp, bool key_pos = false) override; - TrackType getTrackType() const override{ - return TrackAudio; - } - CodecId getCodecId() const override{ return CodecAAC; } diff --git a/src/Extension/AACRtp.cpp b/src/Extension/AACRtp.cpp index a09a8d76..b3d7cc1b 100644 --- a/src/Extension/AACRtp.cpp +++ b/src/Extension/AACRtp.cpp @@ -78,7 +78,7 @@ AACFrame::Ptr AACRtpDecoder::obtainFrame() { //从缓存池重新申请对象,防止覆盖已经写入环形缓存的对象 auto frame = ResourcePoolHelper::obtainObj(); frame->aac_frame_length = ADTS_HEADER_LEN; - frame->iPrefixSize = ADTS_HEADER_LEN; + frame->_prefix_size = ADTS_HEADER_LEN; if(frame->syncword == 0 && !_aac_cfg.empty()) { makeAdtsHeader(_aac_cfg,*frame); } @@ -109,7 +109,7 @@ bool AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) { //追加aac数据 memcpy(_adts->buffer + _adts->aac_frame_length, ptr, size); _adts->aac_frame_length += size; - _adts->timeStamp = rtppack->timeStamp; + _adts->_dts = rtppack->timeStamp; ptr += size; } diff --git a/src/Extension/AACRtp.h b/src/Extension/AACRtp.h index eba5ceb5..e4758fef 100644 --- a/src/Extension/AACRtp.h +++ b/src/Extension/AACRtp.h @@ -31,9 +31,6 @@ public: */ bool inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = false) override; - TrackType getTrackType() const override{ - return TrackAudio; - } CodecId getCodecId() const override{ return CodecAAC; } diff --git a/src/Extension/Frame.cpp b/src/Extension/Frame.cpp index 9d543706..9aab3fad 100644 --- a/src/Extension/Frame.cpp +++ b/src/Extension/Frame.cpp @@ -15,6 +15,59 @@ using namespace toolkit; namespace mediakit{ +/** + * 该对象的功能是把一个不可缓存的帧转换成可缓存的帧 + */ +class FrameCacheAble : public FrameFromPtr { +public: + typedef std::shared_ptr Ptr; + + FrameCacheAble(const Frame::Ptr &frame){ + if(frame->cacheAble()){ + _frame = frame; + _ptr = frame->data(); + }else{ + _buffer = std::make_shared(); + _buffer->assign(frame->data(),frame->size()); + _ptr = _buffer->data(); + } + _size = frame->size(); + _dts = frame->dts(); + _pts = frame->pts(); + _prefix_size = frame->prefixSize(); + _codecid = frame->getCodecId(); + _key = frame->keyFrame(); + _config = frame->configFrame(); + } + + virtual ~FrameCacheAble() = default; + + /** + * 可以被缓存 + */ + bool cacheAble() const override { + return true; + } + + CodecId getCodecId() const override{ + return _codecid; + } + + bool keyFrame() const override{ + return _key; + } + + bool configFrame() const override{ + return _config; + } +private: + Frame::Ptr _frame; + BufferRaw::Ptr _buffer; + CodecId _codecid; + bool _key; + bool _config; +}; + Frame::Ptr Frame::getCacheAbleFrame(const Frame::Ptr &frame){ if(frame->cacheAble()){ return frame; @@ -30,10 +83,21 @@ const char *CodecInfo::getCodecName() { SWITCH_CASE(CodecAAC); SWITCH_CASE(CodecG711A); SWITCH_CASE(CodecG711U); - default: - return "unknown codec"; + SWITCH_CASE(CodecOpus); + default : return "unknown codec"; + } +} + +TrackType CodecInfo::getTrackType(){ + switch (getCodecId()){ + case CodecH264: + case CodecH265: return TrackVideo; + case CodecAAC: + case CodecG711A: + case CodecG711U: + case CodecOpus: return TrackAudio; + default: return TrackInvalid; } } }//namespace mediakit - diff --git a/src/Extension/Frame.h b/src/Extension/Frame.h index 32df0e3d..cafa876a 100644 --- a/src/Extension/Frame.h +++ b/src/Extension/Frame.h @@ -28,6 +28,7 @@ typedef enum { CodecAAC, CodecG711A, CodecG711U, + CodecOpus, CodecMax = 0x7FFF } CodecId; @@ -49,11 +50,6 @@ public: CodecInfo(){} virtual ~CodecInfo(){} - /** - * 获取音视频类型 - */ - virtual TrackType getTrackType() const = 0; - /** * 获取编解码器类型 */ @@ -61,9 +57,13 @@ public: /** * 获取编码器名称 - * @return 编码器名称 */ const char *getCodecName(); + + /** + * 获取音视频类型 + */ + TrackType getTrackType(); }; /** @@ -76,15 +76,11 @@ public: /** * 返回解码时间戳,单位毫秒 - * @return */ virtual uint32_t dts() const = 0; - - /** * 返回显示时间戳,单位毫秒 - * @return */ virtual uint32_t pts() const { return dts(); @@ -98,13 +94,11 @@ public: /** * 返回是否为关键帧 - * @return */ virtual bool keyFrame() const = 0; /** * 是否为配置帧,譬如sps pps vps - * @return */ virtual bool configFrame() const = 0; @@ -115,14 +109,77 @@ public: /** * 返回可缓存的frame - * @return */ static Ptr getCacheAbleFrame(const Ptr &frame); }; +class FrameImp : public Frame { +public: + typedef std::shared_ptr Ptr; + + char *data() const override{ + return (char *)_buffer.data(); + } + + uint32_t size() const override { + return _buffer.size(); + } + + uint32_t dts() const override { + return _dts; + } + + uint32_t pts() const override{ + return _pts ? _pts : _dts; + } + + uint32_t prefixSize() const override{ + return _prefix_size; + } + + CodecId getCodecId() const override{ + return _codecid; + } + + bool keyFrame() const override { + return false; + } + + bool configFrame() const override{ + return false; + } + +public: + CodecId _codecid = CodecInvalid; + string _buffer; + uint32_t _dts = 0; + uint32_t _pts = 0; + uint32_t _prefix_size = 0; +}; + +/** + * 一个Frame类中可以有多个帧,他们通过 0x 00 00 01 分隔 + * ZLMediaKit会先把这种复合帧split成单个帧然后再处理 + * 一个复合帧可以通过无内存拷贝的方式切割成多个子Frame + * 提供该类的目的是切割复合帧时防止内存拷贝,提高性能 + */ +template +class FrameInternal : public Parent{ +public: + typedef std::shared_ptr Ptr; + FrameInternal(const Frame::Ptr &parent_frame, char *ptr, uint32_t size, int prefix_size) + : Parent(ptr, size, parent_frame->dts(), parent_frame->pts(), prefix_size) { + _parent_frame = parent_frame; + } + bool cacheAble() const override { + return _parent_frame->cacheAble(); + } +private: + Frame::Ptr _parent_frame; +}; + /** * 循环池辅助类 - * @tparam T */ template class ResourcePoolHelper{ @@ -140,18 +197,17 @@ private: }; /** - * 写帧接口的抽闲接口 + * 写帧接口的抽象接口类 */ class FrameWriterInterface { public: typedef std::shared_ptr Ptr; - FrameWriterInterface(){} virtual ~FrameWriterInterface(){} + /** - * 写入帧数据 - * @param frame 帧 - */ + * 写入帧数据 + */ virtual void inputFrame(const Frame::Ptr &frame) = 0; }; @@ -165,16 +221,16 @@ public: /** * inputFrame后触发onWriteFrame回调 - * @param cb */ FrameWriterInterfaceHelper(const onWriteFrame& cb){ _writeCallback = cb; } + virtual ~FrameWriterInterfaceHelper(){} + /** - * 写入帧数据 - * @param frame 帧 - */ + * 写入帧数据 + */ void inputFrame(const Frame::Ptr &frame) override { _writeCallback(frame); } @@ -182,7 +238,6 @@ private: onWriteFrame _writeCallback; }; - /** * 支持代理转发的帧环形缓存 */ @@ -193,6 +248,9 @@ public: FrameDispatcher(){} virtual ~FrameDispatcher(){} + /** + * 添加代理 + */ void addDelegate(const FrameWriterInterface::Ptr &delegate){ //_delegates_write可能多线程同时操作 lock_guard lck(_mtx); @@ -200,6 +258,9 @@ public: _need_update = true; } + /** + * 删除代理 + */ void delDelegate(void *ptr){ //_delegates_write可能多线程同时操作 lock_guard lck(_mtx); @@ -208,8 +269,7 @@ public: } /** - * 写入帧数据 - * @param frame 帧 + * 写入帧并派发 */ void inputFrame(const Frame::Ptr &frame) override{ if(_need_update){ @@ -223,7 +283,13 @@ public: for(auto &pr : _delegates_read){ pr.second->inputFrame(frame); } + } + /** + * 返回代理个数 + */ + int size() const { + return _delegates_write.size(); } private: mutex _mtx; @@ -250,105 +316,23 @@ public: } uint32_t pts() const override{ - if(_pts){ - return _pts; - } - return dts(); + return _pts ? _pts : dts(); } uint32_t prefixSize() const override{ - return _prefixSize; + return _prefix_size; + } + + bool cacheAble() const override { + return false; } protected: char *_ptr; uint32_t _size; uint32_t _dts; uint32_t _pts = 0; - uint32_t _prefixSize; + uint32_t _prefix_size; }; -/** - * 不可缓存的帧,在DevChannel类中有用到。 - * 该帧类型用于防止内存拷贝,直接使用指针传递数据 - * 在大多数情况下,ZLMediaKit是同步对帧数据进行使用和处理的 - * 所以提供此类型的帧很有必要,但是有时又无法避免缓存帧做后续处理 - * 所以可以通过Frame::getCacheAbleFrame方法拷贝一个可缓存的帧 - */ -class FrameNoCacheAble : public FrameFromPtr{ -public: - typedef std::shared_ptr Ptr; - - /** - * 该帧不可缓存 - * @return - */ - bool cacheAble() const override { - return false; - } -}; - -/** - * 该对象的功能是把一个不可缓存的帧转换成可缓存的帧 - * @see FrameNoCacheAble - */ -class FrameCacheAble : public FrameFromPtr { -public: - typedef std::shared_ptr Ptr; - - FrameCacheAble(const Frame::Ptr &frame){ - if(frame->cacheAble()){ - _frame = frame; - _ptr = frame->data(); - }else{ - _buffer = std::make_shared(); - _buffer->assign(frame->data(),frame->size()); - _ptr = _buffer->data(); - } - _size = frame->size(); - _dts = frame->dts(); - _pts = frame->pts(); - _prefixSize = frame->prefixSize(); - _trackType = frame->getTrackType(); - _codec = frame->getCodecId(); - _key = frame->keyFrame(); - _config = frame->configFrame(); - } - - virtual ~FrameCacheAble() = default; - - /** - * 可以被缓存 - * @return - */ - bool cacheAble() const override { - return true; - } - - TrackType getTrackType() const override{ - return _trackType; - } - - CodecId getCodecId() const override{ - return _codec; - } - - bool keyFrame() const override{ - return _key; - } - - bool configFrame() const override{ - return _config; - } -private: - Frame::Ptr _frame; - BufferRaw::Ptr _buffer; - TrackType _trackType; - CodecId _codec; - bool _key; - bool _config; -}; - - }//namespace mediakit - -#endif //ZLMEDIAKIT_FRAME_H +#endif //ZLMEDIAKIT_FRAME_H \ No newline at end of file diff --git a/src/Extension/G711.h b/src/Extension/G711.h index e4929e7b..b2d22b23 100644 --- a/src/Extension/G711.h +++ b/src/Extension/G711.h @@ -19,76 +19,28 @@ namespace mediakit{ /** * G711帧 */ -class G711Frame : public Frame { +class G711Frame : public FrameImp { public: - typedef std::shared_ptr Ptr; - - char *data() const override{ - return (char *)buffer.data(); + G711Frame(){ + _codecid = CodecG711A; } +}; - uint32_t size() const override { - return buffer.size(); - } - - uint32_t dts() const override { - return timeStamp; - } - - uint32_t prefixSize() const override{ - return 0; - } - - TrackType getTrackType() const override{ - return TrackAudio; - } - - CodecId getCodecId() const override{ - return _codecId; - } - - bool keyFrame() const override { - return false; - } - - bool configFrame() const override{ - return false; - } -public: - CodecId _codecId = CodecG711A; - string buffer; - uint32_t timeStamp; -} ; - -class G711FrameNoCacheAble : public FrameNoCacheAble { +class G711FrameNoCacheAble : public FrameFromPtr { public: typedef std::shared_ptr Ptr; - //兼容通用接口 - G711FrameNoCacheAble(char *ptr,uint32_t size,uint32_t dts, uint32_t pts = 0,int prefixeSize = 0){ + G711FrameNoCacheAble(char *ptr,uint32_t size,uint32_t dts, uint32_t pts = 0,int prefix_size = 0){ _ptr = ptr; _size = size; _dts = dts; - _prefixSize = prefixeSize; + _prefix_size = prefix_size; } - //兼容通用接口 void setCodec(CodecId codecId){ _codecId = codecId; } - G711FrameNoCacheAble(CodecId codecId, char *ptr,uint32_t size,uint32_t dts,int prefixeSize = 0){ - _codecId = codecId; - _ptr = ptr; - _size = size; - _dts = dts; - _prefixSize = prefixeSize; - } - - TrackType getTrackType() const override{ - return TrackAudio; - } - CodecId getCodecId() const override{ return _codecId; } @@ -108,67 +60,18 @@ private: /** * G711音频通道 */ -class G711Track : public AudioTrack{ +class G711Track : public AudioTrackImp{ public: typedef std::shared_ptr Ptr; - - /** - * G711A G711U - */ - G711Track(CodecId codecId,int sample_rate, int channels, int sample_bit){ - _codecid = codecId; - _sample_rate = sample_rate; - _channels = channels; - _sample_bit = sample_bit; - } - - /** - * 返回编码类型 - */ - CodecId getCodecId() const override{ - return _codecid; - } - - /** - * 是否已经初始化 - */ - bool ready() override { - return true; - } - - /** - * 返回音频采样率 - */ - int getAudioSampleRate() const override{ - return _sample_rate; - } - - /** - * 返回音频采样位数,一般为16或8 - */ - int getAudioSampleBit() const override{ - return _sample_bit; - } - - /** - * 返回音频通道数 - */ - int getAudioChannel() const override{ - return _channels; - } + G711Track(CodecId codecId,int sample_rate, int channels, int sample_bit) : AudioTrackImp(codecId,sample_rate,channels,sample_bit){} private: + //克隆该Track Track::Ptr clone() override { return std::make_shared::type >(*this); } - //生成sdp Sdp::Ptr getSdp() override ; -private: - CodecId _codecid; - int _sample_rate; - int _channels; - int _sample_bit; }; /** @@ -190,27 +93,20 @@ public: int bitrate = 128) : Sdp(sample_rate,playload_type), _codecId(codecId){ _printer << "m=audio 0 RTP/AVP " << playload_type << "\r\n"; _printer << "a=rtpmap:" << playload_type << (codecId == CodecG711A ? " PCMA/" : " PCMU/") << sample_rate << "/" << channels << "\r\n"; - _printer << "a=control:trackID=" << getTrackType() << "\r\n"; + _printer << "a=control:trackID=" << (int)TrackAudio << "\r\n"; } string getSdp() const override { return _printer; } - TrackType getTrackType() const override { - return TrackAudio; - } - CodecId getCodecId() const override { return _codecId; } - private: _StrPrinter _printer; CodecId _codecId; }; }//namespace mediakit - - -#endif //ZLMEDIAKIT_AAC_H +#endif //ZLMEDIAKIT_G711_H \ No newline at end of file diff --git a/src/Extension/G711Rtmp.cpp b/src/Extension/G711Rtmp.cpp index 11e46d61..7ffca2f0 100644 --- a/src/Extension/G711Rtmp.cpp +++ b/src/Extension/G711Rtmp.cpp @@ -20,15 +20,15 @@ G711RtmpDecoder::G711RtmpDecoder(CodecId codecId) { G711Frame::Ptr G711RtmpDecoder::obtainFrame() { //从缓存池重新申请对象,防止覆盖已经写入环形缓存的对象 auto frame = ResourcePoolHelper::obtainObj(); - frame->buffer.clear(); - frame->_codecId = _codecId; + frame->_buffer.clear(); + frame->_codecid = _codecId; return frame; } bool G711RtmpDecoder::inputRtmp(const RtmpPacket::Ptr &pkt, bool) { //拷贝G711负载 - _frame->buffer.assign(pkt->strBuf.data() + 1, pkt->strBuf.size() - 1); - _frame->timeStamp = pkt->timeStamp; + _frame->_buffer.assign(pkt->strBuf.data() + 1, pkt->strBuf.size() - 1); + _frame->_dts = pkt->timeStamp; //写入环形缓存 RtmpCodec::inputFrame(_frame); _frame = obtainFrame(); diff --git a/src/Extension/G711Rtmp.h b/src/Extension/G711Rtmp.h index 71f3e069..c2fea41b 100644 --- a/src/Extension/G711Rtmp.h +++ b/src/Extension/G711Rtmp.h @@ -33,10 +33,6 @@ public: */ bool inputRtmp(const RtmpPacket::Ptr &Rtmp, bool key_pos = false) override; - TrackType getTrackType() const override{ - return TrackAudio; - } - CodecId getCodecId() const override{ return _codecId; } diff --git a/src/Extension/G711Rtp.cpp b/src/Extension/G711Rtp.cpp index e4d3329c..e9a77d1e 100644 --- a/src/Extension/G711Rtp.cpp +++ b/src/Extension/G711Rtp.cpp @@ -20,9 +20,9 @@ G711RtpDecoder::G711RtpDecoder(const Track::Ptr &track){ G711Frame::Ptr G711RtpDecoder::obtainFrame() { //从缓存池重新申请对象,防止覆盖已经写入环形缓存的对象 auto frame = ResourcePoolHelper::obtainObj(); - frame->buffer.clear(); - frame->_codecId = _codecid; - frame->timeStamp = 0; + frame->_buffer.clear(); + frame->_codecid = _codecid; + frame->_dts = 0; return frame; } @@ -32,17 +32,17 @@ bool G711RtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool) { // 获取rtp数据 const char *rtp_packet_buf = rtppack->data() + rtppack->offset; - if (rtppack->timeStamp != _frame->timeStamp) { + if (rtppack->timeStamp != _frame->_dts) { //时间戳变更,清空上一帧 onGetG711(_frame); } //追加数据 - _frame->buffer.append(rtp_packet_buf, length); + _frame->_buffer.append(rtp_packet_buf, length); //赋值时间戳 - _frame->timeStamp = rtppack->timeStamp; + _frame->_dts = rtppack->timeStamp; - if (rtppack->mark || _frame->buffer.size() > 10 * 1024) { + if (rtppack->mark || _frame->_buffer.size() > 10 * 1024) { //标记为mark时,或者内存快溢出时,我们认为这是该帧最后一个包 onGetG711(_frame); } @@ -50,7 +50,7 @@ bool G711RtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool) { } void G711RtpDecoder::onGetG711(const G711Frame::Ptr &frame) { - if(!frame->buffer.empty()){ + if(!frame->_buffer.empty()){ //写入环形缓存 RtpCodec::inputFrame(frame); _frame = obtainFrame(); @@ -96,6 +96,3 @@ void G711RtpEncoder::makeG711Rtp(const void *data, unsigned int len, bool mark, } }//namespace mediakit - - - diff --git a/src/Extension/G711Rtp.h b/src/Extension/G711Rtp.h index 31547464..f829b7fc 100644 --- a/src/Extension/G711Rtp.h +++ b/src/Extension/G711Rtp.h @@ -31,10 +31,6 @@ public: */ bool inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = false) override; - TrackType getTrackType() const override{ - return TrackAudio; - } - CodecId getCodecId() const override{ return _codecid; } diff --git a/src/Extension/H264.h b/src/Extension/H264.h index 955b1733..dbc5cfb1 100644 --- a/src/Extension/H264.h +++ b/src/Extension/H264.h @@ -25,7 +25,7 @@ void splitH264(const char *ptr, int len, int prefix, const std::function Ptr; @@ -36,30 +36,8 @@ public: NAL_SEI = 6, } NalType; - char *data() const override{ - return (char *)_buffer.data(); - } - uint32_t size() const override { - return _buffer.size(); - } - uint32_t dts() const override { - return _dts; - } - - uint32_t pts() const override { - return _pts ? _pts : _dts; - } - - uint32_t prefixSize() const override{ - return _prefix_size; - } - - TrackType getTrackType() const override{ - return TrackVideo; - } - - CodecId getCodecId() const override{ - return CodecH264; + H264Frame(){ + _codecid = CodecH264; } bool keyFrame() const override { @@ -69,39 +47,27 @@ public: bool configFrame() const override{ switch(H264_TYPE(_buffer[_prefix_size]) ){ case H264Frame::NAL_SPS: - case H264Frame::NAL_PPS: - return true; - default: - return false; + case H264Frame::NAL_PPS:return true; + default:return false; } } -public: - uint32_t _dts = 0; - uint32_t _pts = 0; - uint32_t _prefix_size = 4; - string _buffer; }; - /** * 防止内存拷贝的H264类 * 用户可以通过该类型快速把一个指针无拷贝的包装成Frame类 * 该类型在DevChannel中有使用 */ -class H264FrameNoCacheAble : public FrameNoCacheAble { +class H264FrameNoCacheAble : public FrameFromPtr { public: typedef std::shared_ptr Ptr; - H264FrameNoCacheAble(char *ptr,uint32_t size,uint32_t dts , uint32_t pts ,int prefixeSize = 4){ + H264FrameNoCacheAble(char *ptr,uint32_t size,uint32_t dts , uint32_t pts ,int prefix_size = 4){ _ptr = ptr; _size = size; _dts = dts; _pts = pts; - _prefixSize = prefixeSize; - } - - TrackType getTrackType() const override{ - return TrackVideo; + _prefix_size = prefix_size; } CodecId getCodecId() const override{ @@ -109,43 +75,18 @@ public: } bool keyFrame() const override { - return H264_TYPE(_ptr[_prefixSize]) == H264Frame::NAL_IDR; + return H264_TYPE(_ptr[_prefix_size]) == H264Frame::NAL_IDR; } bool configFrame() const override{ - switch(H264_TYPE(_ptr[_prefixSize])){ + switch(H264_TYPE(_ptr[_prefix_size])){ case H264Frame::NAL_SPS: - case H264Frame::NAL_PPS: - return true; - default: - return false; + case H264Frame::NAL_PPS:return true; + default:return false; } } }; -/** - * 一个H264Frame类中可以有多个帧,他们通过 0x 00 00 01 分隔 - * ZLMediaKit会先把这种复合帧split成单个帧然后再处理 - * 一个复合帧可以通过无内存拷贝的方式切割成多个H264FrameSubFrame - * 提供该类的目的是切换复合帧时防止内存拷贝,提高性能 - */ -template -class FrameInternal : public Parent{ -public: - typedef std::shared_ptr Ptr; - FrameInternal(const Frame::Ptr &parent_frame, - char *ptr, - uint32_t size, - int prefixeSize) : Parent(ptr,size,parent_frame->dts(),parent_frame->pts(),prefixeSize){ - _parent_frame = parent_frame; - } - bool cacheAble() const override { - return _parent_frame->cacheAble(); - } -private: - Frame::Ptr _parent_frame; -}; - typedef FrameInternal H264FrameInternal; /** @@ -334,13 +275,11 @@ private: bool _last_frame_is_idr = false; }; - /** * h264类型sdp */ class H264Sdp : public Sdp { public: - /** * * @param sps 264 sps,不带0x00000001头 @@ -375,17 +314,13 @@ public: memset(strTemp, 0, 100); av_base64_encode(strTemp, 100, (uint8_t *) strPPS.data(), strPPS.size()); _printer << strTemp << "\r\n"; - _printer << "a=control:trackID=" << getTrackType() << "\r\n"; + _printer << "a=control:trackID=" << (int)TrackVideo << "\r\n"; } string getSdp() const override { return _printer; } - TrackType getTrackType() const override { - return TrackVideo; - } - CodecId getCodecId() const override { return CodecH264; } @@ -393,8 +328,5 @@ private: _StrPrinter _printer; }; - }//namespace mediakit - - -#endif //ZLMEDIAKIT_H264_H +#endif //ZLMEDIAKIT_H264_H \ No newline at end of file diff --git a/src/Extension/H264Rtmp.h b/src/Extension/H264Rtmp.h index e63c6a34..cf8f4dbe 100644 --- a/src/Extension/H264Rtmp.h +++ b/src/Extension/H264Rtmp.h @@ -36,10 +36,6 @@ public: */ bool inputRtmp(const RtmpPacket::Ptr &rtmp, bool key_pos = true) override; - TrackType getTrackType() const override{ - return TrackVideo; - } - CodecId getCodecId() const override{ return CodecH264; } diff --git a/src/Extension/H264Rtp.h b/src/Extension/H264Rtp.h index a4e8793c..3453bf3e 100644 --- a/src/Extension/H264Rtp.h +++ b/src/Extension/H264Rtp.h @@ -38,10 +38,6 @@ public: */ bool inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = true) override; - TrackType getTrackType() const override{ - return TrackVideo; - } - CodecId getCodecId() const override{ return CodecH264; } diff --git a/src/Extension/H265.h b/src/Extension/H265.h index 676af0b2..31a68415 100644 --- a/src/Extension/H265.h +++ b/src/Extension/H265.h @@ -23,9 +23,9 @@ namespace mediakit { bool getHEVCInfo(const string &strVps, const string &strSps, int &iVideoWidth, int &iVideoHeight, float &iVideoFps); /** -* 265帧类 -*/ -class H265Frame : public Frame { + * 265帧类 + */ +class H265Frame : public FrameImp { public: typedef std::shared_ptr Ptr; @@ -60,32 +60,8 @@ public: NAL_SEI_SUFFIX = 40, } NaleType; - char *data() const override { - return (char *) _buffer.data(); - } - - uint32_t size() const override { - return _buffer.size(); - } - - uint32_t dts() const override { - return _dts; - } - - uint32_t pts() const override { - return _pts ? _pts : _dts; - } - - uint32_t prefixSize() const override { - return _prefix_size; - } - - TrackType getTrackType() const override { - return TrackVideo; - } - - CodecId getCodecId() const override { - return CodecH265; + H265Frame(){ + _codecid = CodecH265; } bool keyFrame() const override { @@ -96,39 +72,26 @@ public: switch(H265_TYPE(_buffer[_prefix_size])){ case H265Frame::NAL_VPS: case H265Frame::NAL_SPS: - case H265Frame::NAL_PPS: - return true; - default: - return false; + case H265Frame::NAL_PPS : return true; + default : return false; } } static bool isKeyFrame(int type) { return type >= NAL_BLA_W_LP && type <= NAL_RSV_IRAP_VCL23; } - -public: - uint32_t _dts = 0; - uint32_t _pts = 0; - uint32_t _prefix_size = 4; - string _buffer; }; - -class H265FrameNoCacheAble : public FrameNoCacheAble { +class H265FrameNoCacheAble : public FrameFromPtr { public: typedef std::shared_ptr Ptr; - H265FrameNoCacheAble(char *ptr, uint32_t size, uint32_t dts,uint32_t pts, int prefixeSize = 4) { + H265FrameNoCacheAble(char *ptr, uint32_t size, uint32_t dts,uint32_t pts, int prefix_size = 4) { _ptr = ptr; _size = size; _dts = dts; _pts = pts; - _prefixSize = prefixeSize; - } - - TrackType getTrackType() const override { - return TrackVideo; + _prefix_size = prefix_size; } CodecId getCodecId() const override { @@ -136,17 +99,15 @@ public: } bool keyFrame() const override { - return H265Frame::isKeyFrame(H265_TYPE(((uint8_t *) _ptr)[_prefixSize])); + return H265Frame::isKeyFrame(H265_TYPE(((uint8_t *) _ptr)[_prefix_size])); } bool configFrame() const override{ - switch(H265_TYPE(((uint8_t *) _ptr)[_prefixSize])){ + switch(H265_TYPE(((uint8_t *) _ptr)[_prefix_size])){ case H265Frame::NAL_VPS: case H265Frame::NAL_SPS: - case H265Frame::NAL_PPS: - return true; - default: - return false; + case H265Frame::NAL_PPS:return true; + default:return false; } } }; @@ -184,7 +145,6 @@ public: /** * 返回不带0x00 00 00 01头的vps - * @return */ const string &getVps() const { return _vps; @@ -192,7 +152,6 @@ public: /** * 返回不带0x00 00 00 01头的sps - * @return */ const string &getSps() const { return _sps; @@ -200,7 +159,6 @@ public: /** * 返回不带0x00 00 00 01头的pps - * @return */ const string &getPps() const { return _pps; @@ -212,7 +170,6 @@ public: /** * 返回视频高度 - * @return */ int getVideoHeight() const override{ return _height ; @@ -220,7 +177,6 @@ public: /** * 返回视频宽度 - * @return */ int getVideoWidth() const override{ return _width; @@ -228,7 +184,6 @@ public: /** * 返回视频fps - * @return */ float getVideoFps() const override{ return _fps; @@ -238,11 +193,10 @@ public: return !_vps.empty() && !_sps.empty() && !_pps.empty(); } - /** - * 输入数据帧,并获取sps pps - * @param frame 数据帧 - */ + * 输入数据帧,并获取sps pps + * @param frame 数据帧 + */ void inputFrame(const Frame::Ptr &frame) override{ int type = H265_TYPE(*((uint8_t *)frame->data() + frame->prefixSize())); if(frame->configFrame()){ @@ -352,15 +306,13 @@ private: bool _last_frame_is_idr = false; }; - /** * h265类型sdp */ class H265Sdp : public Sdp { public: - /** - * + * 构造函数 * @param sps 265 sps,不带0x00000001头 * @param pps 265 pps,不带0x00000001头 * @param playload_type rtp playload type 默认96 @@ -382,17 +334,13 @@ public: _printer << encodeBase64(strSPS) << "; "; _printer << "sprop-pps="; _printer << encodeBase64(strPPS) << "\r\n"; - _printer << "a=control:trackID=" << getTrackType() << "\r\n"; + _printer << "a=control:trackID=" << (int)TrackVideo << "\r\n"; } string getSdp() const override { return _printer; } - TrackType getTrackType() const override { - return TrackVideo; - } - CodecId getCodecId() const override { return CodecH265; } @@ -400,9 +348,5 @@ private: _StrPrinter _printer; }; - - }//namespace mediakit - - -#endif //ZLMEDIAKIT_H265_H +#endif //ZLMEDIAKIT_H265_H \ No newline at end of file diff --git a/src/Extension/H265Rtmp.h b/src/Extension/H265Rtmp.h index 3bcf09c9..4a151251 100644 --- a/src/Extension/H265Rtmp.h +++ b/src/Extension/H265Rtmp.h @@ -36,10 +36,6 @@ public: */ bool inputRtmp(const RtmpPacket::Ptr &rtmp, bool key_pos = true) override; - TrackType getTrackType() const override{ - return TrackVideo; - } - CodecId getCodecId() const override{ return CodecH265; } diff --git a/src/Extension/H265Rtp.h b/src/Extension/H265Rtp.h index 1098983a..33e28b5f 100644 --- a/src/Extension/H265Rtp.h +++ b/src/Extension/H265Rtp.h @@ -39,10 +39,6 @@ public: */ bool inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = true) override; - TrackType getTrackType() const override{ - return TrackVideo; - } - CodecId getCodecId() const override{ return CodecH265; } diff --git a/src/Extension/Track.h b/src/Extension/Track.h index 29b679e8..788af78f 100644 --- a/src/Extension/Track.h +++ b/src/Extension/Track.h @@ -65,8 +65,6 @@ class VideoTrack : public Track { public: typedef std::shared_ptr Ptr; - TrackType getTrackType() const override { return TrackVideo;}; - /** * 返回视频高度 * @return @@ -93,8 +91,6 @@ class AudioTrack : public Track { public: typedef std::shared_ptr Ptr; - TrackType getTrackType() const override { return TrackAudio;}; - /** * 返回音频采样率 * @return @@ -114,6 +110,64 @@ public: virtual int getAudioChannel() const {return 0;}; }; +class AudioTrackImp : public AudioTrack{ +public: + typedef std::shared_ptr Ptr; + + /** + * 构造函数 + * @param codecId 编码类型 + * @param sample_rate 采样率(HZ) + * @param channels 通道数 + * @param sample_bit 采样位数,一般为16 + */ + AudioTrackImp(CodecId codecId,int sample_rate, int channels, int sample_bit){ + _codecid = codecId; + _sample_rate = sample_rate; + _channels = channels; + _sample_bit = sample_bit; + } + + /** + * 返回编码类型 + */ + CodecId getCodecId() const override{ + return _codecid; + } + + /** + * 是否已经初始化 + */ + bool ready() override { + return true; + } + + /** + * 返回音频采样率 + */ + int getAudioSampleRate() const override{ + return _sample_rate; + } + + /** + * 返回音频采样位数,一般为16或8 + */ + int getAudioSampleBit() const override{ + return _sample_bit; + } + + /** + * 返回音频通道数 + */ + int getAudioChannel() const override{ + return _channels; + } +private: + CodecId _codecid; + int _sample_rate; + int _channels; + int _sample_bit; +}; class TrackSource{ public: @@ -123,7 +177,6 @@ public: /** * 获取全部的Track * @param trackReady 是否获取全部已经准备好的Track - * @return */ virtual vector getTracks(bool trackReady = true) const = 0; @@ -131,7 +184,6 @@ public: * 获取特定Track * @param type track类型 * @param trackReady 是否获取全部已经准备好的Track - * @return */ Track::Ptr getTrack(TrackType type , bool trackReady = true) const { auto tracks = getTracks(trackReady); @@ -145,5 +197,4 @@ public: }; }//namespace mediakit - -#endif //ZLMEDIAKIT_TRACK_H +#endif //ZLMEDIAKIT_TRACK_H \ No newline at end of file diff --git a/src/Rtmp/Rtmp.h b/src/Rtmp/Rtmp.h index ec4c4e72..22f0775f 100644 --- a/src/Rtmp/Rtmp.h +++ b/src/Rtmp/Rtmp.h @@ -242,18 +242,6 @@ public: } } - /** - * 返回音频或视频类型 - * @return - */ - TrackType getTrackType() const override { - return TrackTitle; - } - - /** - * 返回编码器id - * @return - */ CodecId getCodecId() const override{ return CodecInvalid; } @@ -266,18 +254,6 @@ public: VideoMeta(const VideoTrack::Ptr &video,int datarate = 5000); virtual ~VideoMeta(){} - /** - * 返回音频或视频类型 - * @return - */ - TrackType getTrackType() const override { - return TrackVideo; - } - - /** - * 返回编码器id - * @return - */ CodecId getCodecId() const override{ return _codecId; } @@ -294,18 +270,6 @@ public: virtual ~AudioMeta(){} - /** - * 返回音频或视频类型 - * @return - */ - TrackType getTrackType() const override { - return TrackAudio; - } - - /** - * 返回编码器id - * @return - */ CodecId getCodecId() const override{ return _codecId; } @@ -317,7 +281,4 @@ private: uint8_t getAudioRtmpFlags(const Track::Ptr &track); }//namespace mediakit - - - -#endif +#endif//__rtmp_h diff --git a/src/Rtp/RtpProcess.cpp b/src/Rtp/RtpProcess.cpp index 7c9053e2..4d27332d 100644 --- a/src/Rtp/RtpProcess.cpp +++ b/src/Rtp/RtpProcess.cpp @@ -20,8 +20,8 @@ namespace mediakit{ /** -* 合并一些时间戳相同的frame -*/ + * 合并一些时间戳相同的frame + */ class FrameMerger { public: FrameMerger() = default; @@ -319,7 +319,9 @@ void RtpProcess::onDecode(int stream,int codecid,int flags,int64_t pts,int64_t d WarnP(this) << "audio track change to G711 from codecid:" << getCodecName(_codecid_audio); return; } - _muxer->inputFrame(std::make_shared(codec, (char *) data, bytes, dts)); + auto frame = std::make_shared((char *) data, bytes, dts); + frame->setCodec(codec); + _muxer->inputFrame(frame); break; } default: diff --git a/src/Rtsp/Rtsp.h b/src/Rtsp/Rtsp.h index 0a42add5..102bae11 100644 --- a/src/Rtsp/Rtsp.h +++ b/src/Rtsp/Rtsp.h @@ -263,18 +263,7 @@ public: string getSdp() const override { return _printer; } - /** - * 返回音频或视频类型 - * @return - */ - TrackType getTrackType() const override { - return TrackTitle; - } - /** - * 返回编码器id - * @return - */ CodecId getCodecId() const override{ return CodecInvalid; } @@ -283,5 +272,4 @@ private: }; } //namespace mediakit - #endif //RTSP_RTSP_H_