mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-10-31 00:37:39 +08:00
新增Frame多转发代理
This commit is contained in:
parent
6870292fd6
commit
f26076635d
@ -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 */
|
||||
|
||||
|
@ -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<AACFrame> _pAdtsHeader;
|
||||
};
|
||||
|
||||
#endif //0
|
||||
class DevChannelNew : public MultiMediaSourceMuxer
|
||||
{
|
||||
public:
|
||||
typedef std::shared_ptr<DevChannelNew> 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 */
|
||||
|
||||
|
@ -83,6 +83,7 @@ void PlayerProxy::play(const char* strUrl) {
|
||||
weak_ptr<PlayerProxy> 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<AACFrameNoCopyAble>((char *)MUTE_ADTS_DATA,MUTE_ADTS_DATA_LEN, _iAudioIndex * MUTE_ADTS_DATA_MS));
|
||||
//DebugL << _iAudioIndex * MUTE_ADTS_DATA_MS << " " << stamp;
|
||||
}
|
||||
}
|
||||
|
@ -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<AACTrack>(_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<H264Track>(_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<H264FrameNoCopyAble>((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<AACFrameNoCopyAble>((char*)pucData,iLen,uiStamp));
|
||||
}
|
||||
|
||||
inline MP4SampleId MediaReader::getVideoSampleId(int iTimeInc ) {
|
||||
|
@ -27,8 +27,11 @@
|
||||
#ifndef ZLMEDIAKIT_FRAME_H
|
||||
#define ZLMEDIAKIT_FRAME_H
|
||||
|
||||
#include <mutex>
|
||||
#include "Util/RingBuffer.h"
|
||||
#include "Network/Socket.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace toolkit;
|
||||
|
||||
namespace mediakit{
|
||||
@ -103,10 +106,23 @@ private:
|
||||
ResourcePool<T> _pool;
|
||||
};
|
||||
|
||||
class FrameRingWriterInterface {
|
||||
public:
|
||||
typedef std::shared_ptr<FrameRingWriterInterface> Ptr;
|
||||
|
||||
FrameRingWriterInterface(){}
|
||||
virtual ~FrameRingWriterInterface(){}
|
||||
/**
|
||||
* 写入帧数据
|
||||
* @param frame 帧
|
||||
*/
|
||||
virtual void inputFrame(const Frame::Ptr &frame) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* 帧环形缓存接口类
|
||||
*/
|
||||
class FrameRingInterface {
|
||||
class FrameRingInterface : public FrameRingWriterInterface{
|
||||
public:
|
||||
typedef RingBuffer<Frame::Ptr> RingType;
|
||||
typedef std::shared_ptr<FrameRingInterface> 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<FrameRingInterfaceDelegate> Ptr;
|
||||
|
||||
FrameRingInterfaceDelegate(){
|
||||
_delegate = std::make_shared<FrameRing>();
|
||||
}
|
||||
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<mutex> 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<mutex> 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<mutex> lck(_mtx);
|
||||
for(auto &pr : _delegateMap){
|
||||
pr.second->inputFrame(frame);
|
||||
}
|
||||
}
|
||||
private:
|
||||
FrameRingInterface::Ptr _delegate;
|
||||
mutex _mtx;
|
||||
map<void *,FrameRingWriterInterface::Ptr> _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<FrameNoCopyAble> 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<H264FrameNoCopyAble> 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<AACFrameNoCopyAble> 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;
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -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<std::remove_reference<decltype(*this)>::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<std::remove_reference<decltype(*this)>::type >(*this);
|
||||
}
|
||||
private:
|
||||
string _cfg;
|
||||
int _sampleRate = 0;
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user