From f26076635d4c596014b8c61b8e2d16d784c71acf Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Fri, 26 Oct 2018 16:09:48 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9EFrame=E5=A4=9A=E8=BD=AC?= =?UTF-8?q?=E5=8F=91=E4=BB=A3=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Device/Device.cpp | 3 + src/Device/Device.h | 20 +++++ src/Device/PlayerProxy.cpp | 3 +- src/MediaFile/MediaReader.cpp | 28 ++----- src/Player/Frame.h | 142 +++++++++++++++++++++++++--------- src/Player/Track.h | 12 --- src/RtmpMuxer/RtmpDemuxer.cpp | 4 +- src/RtmpMuxer/RtmpMuxer.cpp | 2 +- src/RtspMuxer/RtspDemuxer.cpp | 4 +- src/RtspMuxer/RtspMuxer.cpp | 6 +- 10 files changed, 145 insertions(+), 79 deletions(-) diff --git a/src/Device/Device.cpp b/src/Device/Device.cpp index 9346bea7..163541ba 100644 --- a/src/Device/Device.cpp +++ b/src/Device/Device.cpp @@ -35,6 +35,7 @@ using namespace toolkit; namespace mediakit { +#if 0 DevChannel::DevChannel(const char *strVhost, const char *strApp, const char *strId, @@ -303,5 +304,7 @@ void DevChannel::initAudio(const AudioInfo& info) { _pAdtsHeader->no_raw_data_blocks_in_frame = 0; } + +#endif } /* namespace mediakit */ diff --git a/src/Device/Device.h b/src/Device/Device.h index d180ace7..8fb93061 100644 --- a/src/Device/Device.h +++ b/src/Device/Device.h @@ -37,10 +37,12 @@ #include "Rtsp/RtspToRtmpMediaSource.h" #include "RtspMuxer/RtspSdp.h" #include "Util/TimeTicker.h" +#include "Common/MultiMediaSourceMuxer.h" using namespace std; using namespace toolkit; + #ifdef ENABLE_FAAC #include "Codec/AACEncoder.h" #endif //ENABLE_FAAC @@ -52,6 +54,7 @@ using namespace toolkit; namespace mediakit { +#if 0 class VideoInfo { public: int iWidth; @@ -119,6 +122,23 @@ private: std::shared_ptr _pAdtsHeader; }; +#endif //0 +class DevChannelNew : public MultiMediaSourceMuxer +{ +public: + typedef std::shared_ptr Ptr; + + DevChannelNew(const char *strVhost, + const char *strApp, + const char *strId, + float fDuration = 0, + bool bEanbleHls = true, + bool bEnableMp4 = false): + MultiMediaSourceMuxer(strVhost,strApp,strId,fDuration){}; + virtual ~DevChannelNew(){} +}; + +typedef DevChannelNew DevChannel; } /* namespace mediakit */ diff --git a/src/Device/PlayerProxy.cpp b/src/Device/PlayerProxy.cpp index 1b1cf088..e85e9b6e 100644 --- a/src/Device/PlayerProxy.cpp +++ b/src/Device/PlayerProxy.cpp @@ -83,6 +83,7 @@ void PlayerProxy::play(const char* strUrl) { weak_ptr weakSelf = shared_from_this(); //todo(xzl) 修复此处 + // setOnVideoCB( [weakSelf](const H264Frame &data ) { // auto strongSelf = weakSelf.lock(); // if(!strongSelf){ @@ -212,7 +213,7 @@ void PlayerProxy::makeMuteAudio(uint32_t stamp) { auto iAudioIndex = stamp / MUTE_ADTS_DATA_MS; if(_iAudioIndex != iAudioIndex){ _iAudioIndex = iAudioIndex; - _pChn->inputAAC((char *)MUTE_ADTS_DATA,MUTE_ADTS_DATA_LEN, _iAudioIndex * MUTE_ADTS_DATA_MS); + _pChn->inputFrame(std::make_shared((char *)MUTE_ADTS_DATA,MUTE_ADTS_DATA_LEN, _iAudioIndex * MUTE_ADTS_DATA_MS)); //DebugL << _iAudioIndex * MUTE_ADTS_DATA_MS << " " << stamp; } } diff --git a/src/MediaFile/MediaReader.cpp b/src/MediaFile/MediaReader.cpp index 653b5215..dd3bb74f 100644 --- a/src/MediaFile/MediaReader.cpp +++ b/src/MediaFile/MediaReader.cpp @@ -129,29 +129,13 @@ MediaReader::MediaReader(const string &strVhost,const string &strApp, const stri _iDuration = MAX(_video_ms,_audio_ms); _pChn.reset(new DevChannel(strVhost.data(),strApp.data(),strId.data(),_iDuration/1000.0,false, false)); if (_audio_trId != MP4_INVALID_TRACK_ID) { - AudioInfo info; - info.iChannel = _audio_num_channels; - info.iSampleBit = 16; - info.iSampleRate = _audio_sample_rate; - _pChn->initAudio(info); + AACTrack::Ptr track = std::make_shared(_strAacCfg); + _pChn->addTrack(track); } if (_video_trId != MP4_INVALID_TRACK_ID) { - VideoInfo info; - info.iFrameRate = _video_framerate; - info.iWidth = _video_width; - info.iHeight = _video_height; - _pChn->initVideo(info); - } - - if (_audio_trId != MP4_INVALID_TRACK_ID) { - _pChn->inputAAC((char *)_adts.buffer, 7, 0); - } - - if (_video_trId != MP4_INVALID_TRACK_ID) { - //_pChn->initVideo(info); - _pChn->inputH264((char *) _strSps.data(), _strSps.size(), 0); - _pChn->inputH264((char *) _strPps.data(), _strPps.size(), 0); + H264Track::Ptr track = std::make_shared(_strSps,_strPps); + _pChn->addTrack(track); } } @@ -252,11 +236,11 @@ inline bool MediaReader::readAudioSample(int iTimeInc) { } inline void MediaReader::writeH264(uint8_t *pucData,int iLen,uint32_t uiStamp) { - _pChn->inputH264((char *)pucData, iLen, uiStamp); + _pChn->inputFrame(std::make_shared((char*)pucData,iLen,uiStamp)); } inline void MediaReader::writeAAC(uint8_t *pucData,int iLen,uint32_t uiStamp) { - _pChn->inputAAC((char *)pucData, iLen, uiStamp); + _pChn->inputFrame(std::make_shared((char*)pucData,iLen,uiStamp)); } inline MP4SampleId MediaReader::getVideoSampleId(int iTimeInc ) { diff --git a/src/Player/Frame.h b/src/Player/Frame.h index ff48c672..cae66630 100644 --- a/src/Player/Frame.h +++ b/src/Player/Frame.h @@ -27,8 +27,11 @@ #ifndef ZLMEDIAKIT_FRAME_H #define ZLMEDIAKIT_FRAME_H +#include #include "Util/RingBuffer.h" #include "Network/Socket.h" + +using namespace std; using namespace toolkit; namespace mediakit{ @@ -103,10 +106,23 @@ private: ResourcePool _pool; }; +class FrameRingWriterInterface { +public: + typedef std::shared_ptr Ptr; + + FrameRingWriterInterface(){} + virtual ~FrameRingWriterInterface(){} + /** + * 写入帧数据 + * @param frame 帧 + */ + virtual void inputFrame(const Frame::Ptr &frame) = 0; +}; + /** * 帧环形缓存接口类 */ -class FrameRingInterface { +class FrameRingInterface : public FrameRingWriterInterface{ public: typedef RingBuffer RingType; typedef std::shared_ptr Ptr; @@ -125,12 +141,6 @@ public: * @param ring */ virtual void setFrameRing(const RingType::Ptr &ring) = 0; - - /** - * 写入帧数据 - * @param frame 帧 - */ - virtual void inputFrame(const Frame::Ptr &frame) = 0; }; class FrameRing : public FrameRingInterface{ @@ -171,37 +181,21 @@ protected: RingType::Ptr _frameRing; }; -class FrameRingInterfaceDelegate : public FrameRingInterface { +class FrameRingInterfaceDelegate : public FrameRing { public: typedef std::shared_ptr Ptr; - FrameRingInterfaceDelegate(){ - _delegate = std::make_shared(); - } + FrameRingInterfaceDelegate(){} virtual ~FrameRingInterfaceDelegate(){} - void setDelegate(const FrameRingInterface::Ptr &delegate){ - _delegate = delegate; - } - /** - * 获取帧环形缓存 - * @return - */ - FrameRingInterface::RingType::Ptr getFrameRing() const override { - if(_delegate){ - return _delegate->getFrameRing(); - } - return nullptr; + void addDelegate(const FrameRingWriterInterface::Ptr &delegate){ + lock_guard lck(_mtx); + _delegateMap.emplace(delegate.get(),delegate); } - /** - * 设置帧环形缓存 - * @param ring - */ - void setFrameRing(const FrameRingInterface::RingType::Ptr &ring) override { - if(_delegate){ - _delegate->setFrameRing(ring); - } + void delDelegate(void *ptr){ + lock_guard lck(_mtx); + _delegateMap.erase(ptr); } /** @@ -209,12 +203,16 @@ public: * @param frame 帧 */ void inputFrame(const Frame::Ptr &frame) override{ - if(_delegate){ - _delegate->inputFrame(frame); + FrameRing::inputFrame(frame); + lock_guard lck(_mtx); + for(auto &pr : _delegateMap){ + pr.second->inputFrame(frame); } } private: - FrameRingInterface::Ptr _delegate; + mutex _mtx; + map _delegateMap; + FrameRing::Ptr _frameRing; }; @@ -257,6 +255,7 @@ public: uint32_t iPrefixSize = 4; }; + /** * aac帧,包含adts头 */ @@ -311,7 +310,80 @@ public: unsigned char buffer[2 * 1024 + 7]; uint16_t sequence; uint32_t timeStamp; - uint32_t iPrefixSize = 4; + uint32_t iPrefixSize = 7; +} ; + + + +class FrameNoCopyAble : public Frame{ +public: + typedef std::shared_ptr Ptr; + char *data() const override{ + return buffer_ptr; + } + uint32_t size() const override { + return buffer_size; + } + uint32_t stamp() const override { + return timeStamp; + } + uint32_t prefixSize() const override{ + return iPrefixSize; + } +public: + char *buffer_ptr; + uint32_t buffer_size; + uint32_t timeStamp; + uint32_t iPrefixSize; +}; + + +class H264FrameNoCopyAble : public FrameNoCopyAble { +public: + typedef std::shared_ptr Ptr; + + H264FrameNoCopyAble(char *ptr,uint32_t size,uint32_t stamp,int prefixeSize = 4){ + buffer_ptr = ptr; + buffer_size = size; + timeStamp = stamp; + iPrefixSize = prefixeSize; + } + + TrackType getTrackType() const override{ + return TrackVideo; + } + + CodecId getCodecId() const override{ + return CodecH264; + } + + bool keyFrame() const override { + return (buffer_ptr[iPrefixSize] & 0x1F) == 5; + } +}; + +class AACFrameNoCopyAble : public FrameNoCopyAble { +public: + typedef std::shared_ptr Ptr; + + AACFrameNoCopyAble(char *ptr,uint32_t size,uint32_t stamp,int prefixeSize = 7){ + buffer_ptr = ptr; + buffer_size = size; + timeStamp = stamp; + iPrefixSize = prefixeSize; + } + + TrackType getTrackType() const override{ + return TrackAudio; + } + + CodecId getCodecId() const override{ + return CodecAAC; + } + + bool keyFrame() const override { + return false; + } } ; diff --git a/src/Player/Track.h b/src/Player/Track.h index 2ef2c85e..231a663d 100644 --- a/src/Player/Track.h +++ b/src/Player/Track.h @@ -48,12 +48,6 @@ public: * @return */ virtual bool ready() = 0; - - /** - * 克隆接口,用于复制本对象用 - * @return - */ - virtual Track::Ptr clone() = 0; }; class VideoTrack : public Track { @@ -251,9 +245,6 @@ private: void parseSps(const string &sps){ getAVCInfo(sps,_width,_height,_fps); } - Track::Ptr clone() override { - return std::make_shared::type >(*this); - } private: string _sps; string _pps; @@ -378,9 +369,6 @@ private: makeAdtsHeader(aac_cfg,aacFrame); getAACInfo(aacFrame,_sampleRate,_channel); } - Track::Ptr clone() override { - return std::make_shared::type >(*this); - } private: string _cfg; int _sampleRate = 0; diff --git a/src/RtmpMuxer/RtmpDemuxer.cpp b/src/RtmpMuxer/RtmpDemuxer.cpp index 0d3d9b6a..bfc005b3 100644 --- a/src/RtmpMuxer/RtmpDemuxer.cpp +++ b/src/RtmpMuxer/RtmpDemuxer.cpp @@ -84,7 +84,7 @@ void RtmpDemuxer::makeVideoTrack(const AMFValue &videoCodec) { _videoRtmpDecoder = Factory::getRtmpCodecByTrack(_videoTrack); if (_videoRtmpDecoder) { //设置rtmp解码器代理,生成的frame写入该Track - _videoRtmpDecoder->setDelegate(_videoTrack); + _videoRtmpDecoder->addDelegate(_videoTrack); } else { //找不到相应的rtmp解码器,该track无效 _videoTrack.reset(); @@ -100,7 +100,7 @@ void RtmpDemuxer::makeAudioTrack(const AMFValue &audioCodec) { _audioRtmpDecoder = Factory::getRtmpCodecByTrack(_audioTrack); if (_audioRtmpDecoder) { //设置rtmp解码器代理,生成的frame写入该Track - _audioRtmpDecoder->setDelegate(_audioTrack); + _audioRtmpDecoder->addDelegate(_audioTrack); } else { //找不到相应的rtmp解码器,该track无效 _audioTrack.reset(); diff --git a/src/RtmpMuxer/RtmpMuxer.cpp b/src/RtmpMuxer/RtmpMuxer.cpp index 402a0b23..32408fe1 100644 --- a/src/RtmpMuxer/RtmpMuxer.cpp +++ b/src/RtmpMuxer/RtmpMuxer.cpp @@ -60,7 +60,7 @@ void RtmpMuxer::addTrack(const Track::Ptr &track) { _metedata.set(key,value); }); //设置Track的代理,这样输入frame至Track时,最终数据将输出到RtmpEncoder中 - track->setDelegate(encoder); + track->addDelegate(encoder); //Rtmp编码器共用同一个环形缓存 encoder->setRtmpRing(_rtmpRing); }; diff --git a/src/RtspMuxer/RtspDemuxer.cpp b/src/RtspMuxer/RtspDemuxer.cpp index e1672325..1933af74 100644 --- a/src/RtspMuxer/RtspDemuxer.cpp +++ b/src/RtspMuxer/RtspDemuxer.cpp @@ -93,7 +93,7 @@ void RtspDemuxer::makeAudioTrack(const SdpTrack::Ptr &audio) { _audioRtpDecoder = Factory::getRtpDecoderById(_audioTrack->getCodecId()); if(_audioRtpDecoder){ //设置rtp解码器代理,生成的frame写入该Track - _audioRtpDecoder->setDelegate(_audioTrack); + _audioRtpDecoder->addDelegate(_audioTrack); } else{ //找不到相应的rtp解码器,该track无效 _audioTrack.reset(); @@ -109,7 +109,7 @@ void RtspDemuxer::makeVideoTrack(const SdpTrack::Ptr &video) { _videoRtpDecoder = Factory::getRtpDecoderById(_videoTrack->getCodecId()); if(_videoRtpDecoder){ //设置rtp解码器代理,生成的frame写入该Track - _videoRtpDecoder->setDelegate(_videoTrack); + _videoRtpDecoder->addDelegate(_videoTrack); }else{ //找不到相应的rtp解码器,该track无效 _videoTrack.reset(); diff --git a/src/RtspMuxer/RtspMuxer.cpp b/src/RtspMuxer/RtspMuxer.cpp index 3a9c6a65..e05eb717 100644 --- a/src/RtspMuxer/RtspMuxer.cpp +++ b/src/RtspMuxer/RtspMuxer.cpp @@ -29,9 +29,7 @@ namespace mediakit { -void RtspMuxer::addTrack(const Track::Ptr &track_in, uint32_t ssrc, int mtu) { - //克隆对象,防止在setDelegate时错误覆盖 - auto track = track_in->clone(); +void RtspMuxer::addTrack(const Track::Ptr &track, uint32_t ssrc, int mtu) { auto codec_id = track->getCodecId(); _track_map[codec_id] = track; @@ -51,7 +49,7 @@ void RtspMuxer::addTrack(const Track::Ptr &track_in, uint32_t ssrc, int mtu) { //添加其sdp _sdp.append(sdp->getSdp()); //设置Track的代理,这样输入frame至Track时,最终数据将输出到RtpEncoder中 - track->setDelegate(encoder); + track->addDelegate(encoder); //rtp编码器共用同一个环形缓存 encoder->setRtpRing(_rtpRing); };