mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-29 22:55:52 +08:00
新增Frame多转发代理
This commit is contained in:
parent
6870292fd6
commit
f26076635d
@ -35,6 +35,7 @@ using namespace toolkit;
|
|||||||
|
|
||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
|
#if 0
|
||||||
DevChannel::DevChannel(const char *strVhost,
|
DevChannel::DevChannel(const char *strVhost,
|
||||||
const char *strApp,
|
const char *strApp,
|
||||||
const char *strId,
|
const char *strId,
|
||||||
@ -303,5 +304,7 @@ void DevChannel::initAudio(const AudioInfo& info) {
|
|||||||
_pAdtsHeader->no_raw_data_blocks_in_frame = 0;
|
_pAdtsHeader->no_raw_data_blocks_in_frame = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
} /* namespace mediakit */
|
} /* namespace mediakit */
|
||||||
|
|
||||||
|
@ -37,10 +37,12 @@
|
|||||||
#include "Rtsp/RtspToRtmpMediaSource.h"
|
#include "Rtsp/RtspToRtmpMediaSource.h"
|
||||||
#include "RtspMuxer/RtspSdp.h"
|
#include "RtspMuxer/RtspSdp.h"
|
||||||
#include "Util/TimeTicker.h"
|
#include "Util/TimeTicker.h"
|
||||||
|
#include "Common/MultiMediaSourceMuxer.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace toolkit;
|
using namespace toolkit;
|
||||||
|
|
||||||
|
|
||||||
#ifdef ENABLE_FAAC
|
#ifdef ENABLE_FAAC
|
||||||
#include "Codec/AACEncoder.h"
|
#include "Codec/AACEncoder.h"
|
||||||
#endif //ENABLE_FAAC
|
#endif //ENABLE_FAAC
|
||||||
@ -52,6 +54,7 @@ using namespace toolkit;
|
|||||||
|
|
||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
|
#if 0
|
||||||
class VideoInfo {
|
class VideoInfo {
|
||||||
public:
|
public:
|
||||||
int iWidth;
|
int iWidth;
|
||||||
@ -119,6 +122,23 @@ private:
|
|||||||
std::shared_ptr<AACFrame> _pAdtsHeader;
|
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 */
|
} /* namespace mediakit */
|
||||||
|
|
||||||
|
@ -83,6 +83,7 @@ void PlayerProxy::play(const char* strUrl) {
|
|||||||
weak_ptr<PlayerProxy> weakSelf = shared_from_this();
|
weak_ptr<PlayerProxy> weakSelf = shared_from_this();
|
||||||
|
|
||||||
//todo(xzl) 修复此处
|
//todo(xzl) 修复此处
|
||||||
|
|
||||||
// setOnVideoCB( [weakSelf](const H264Frame &data ) {
|
// setOnVideoCB( [weakSelf](const H264Frame &data ) {
|
||||||
// auto strongSelf = weakSelf.lock();
|
// auto strongSelf = weakSelf.lock();
|
||||||
// if(!strongSelf){
|
// if(!strongSelf){
|
||||||
@ -212,7 +213,7 @@ void PlayerProxy::makeMuteAudio(uint32_t stamp) {
|
|||||||
auto iAudioIndex = stamp / MUTE_ADTS_DATA_MS;
|
auto iAudioIndex = stamp / MUTE_ADTS_DATA_MS;
|
||||||
if(_iAudioIndex != iAudioIndex){
|
if(_iAudioIndex != iAudioIndex){
|
||||||
_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;
|
//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);
|
_iDuration = MAX(_video_ms,_audio_ms);
|
||||||
_pChn.reset(new DevChannel(strVhost.data(),strApp.data(),strId.data(),_iDuration/1000.0,false, false));
|
_pChn.reset(new DevChannel(strVhost.data(),strApp.data(),strId.data(),_iDuration/1000.0,false, false));
|
||||||
if (_audio_trId != MP4_INVALID_TRACK_ID) {
|
if (_audio_trId != MP4_INVALID_TRACK_ID) {
|
||||||
AudioInfo info;
|
AACTrack::Ptr track = std::make_shared<AACTrack>(_strAacCfg);
|
||||||
info.iChannel = _audio_num_channels;
|
_pChn->addTrack(track);
|
||||||
info.iSampleBit = 16;
|
|
||||||
info.iSampleRate = _audio_sample_rate;
|
|
||||||
_pChn->initAudio(info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_video_trId != MP4_INVALID_TRACK_ID) {
|
if (_video_trId != MP4_INVALID_TRACK_ID) {
|
||||||
VideoInfo info;
|
H264Track::Ptr track = std::make_shared<H264Track>(_strSps,_strPps);
|
||||||
info.iFrameRate = _video_framerate;
|
_pChn->addTrack(track);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,11 +236,11 @@ inline bool MediaReader::readAudioSample(int iTimeInc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline void MediaReader::writeH264(uint8_t *pucData,int iLen,uint32_t uiStamp) {
|
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) {
|
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 ) {
|
inline MP4SampleId MediaReader::getVideoSampleId(int iTimeInc ) {
|
||||||
|
@ -27,8 +27,11 @@
|
|||||||
#ifndef ZLMEDIAKIT_FRAME_H
|
#ifndef ZLMEDIAKIT_FRAME_H
|
||||||
#define ZLMEDIAKIT_FRAME_H
|
#define ZLMEDIAKIT_FRAME_H
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
#include "Util/RingBuffer.h"
|
#include "Util/RingBuffer.h"
|
||||||
#include "Network/Socket.h"
|
#include "Network/Socket.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
using namespace toolkit;
|
using namespace toolkit;
|
||||||
|
|
||||||
namespace mediakit{
|
namespace mediakit{
|
||||||
@ -103,10 +106,23 @@ private:
|
|||||||
ResourcePool<T> _pool;
|
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:
|
public:
|
||||||
typedef RingBuffer<Frame::Ptr> RingType;
|
typedef RingBuffer<Frame::Ptr> RingType;
|
||||||
typedef std::shared_ptr<FrameRingInterface> Ptr;
|
typedef std::shared_ptr<FrameRingInterface> Ptr;
|
||||||
@ -125,12 +141,6 @@ public:
|
|||||||
* @param ring
|
* @param ring
|
||||||
*/
|
*/
|
||||||
virtual void setFrameRing(const RingType::Ptr &ring) = 0;
|
virtual void setFrameRing(const RingType::Ptr &ring) = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* 写入帧数据
|
|
||||||
* @param frame 帧
|
|
||||||
*/
|
|
||||||
virtual void inputFrame(const Frame::Ptr &frame) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class FrameRing : public FrameRingInterface{
|
class FrameRing : public FrameRingInterface{
|
||||||
@ -171,37 +181,21 @@ protected:
|
|||||||
RingType::Ptr _frameRing;
|
RingType::Ptr _frameRing;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FrameRingInterfaceDelegate : public FrameRingInterface {
|
class FrameRingInterfaceDelegate : public FrameRing {
|
||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<FrameRingInterfaceDelegate> Ptr;
|
typedef std::shared_ptr<FrameRingInterfaceDelegate> Ptr;
|
||||||
|
|
||||||
FrameRingInterfaceDelegate(){
|
FrameRingInterfaceDelegate(){}
|
||||||
_delegate = std::make_shared<FrameRing>();
|
|
||||||
}
|
|
||||||
virtual ~FrameRingInterfaceDelegate(){}
|
virtual ~FrameRingInterfaceDelegate(){}
|
||||||
|
|
||||||
void setDelegate(const FrameRingInterface::Ptr &delegate){
|
void addDelegate(const FrameRingWriterInterface::Ptr &delegate){
|
||||||
_delegate = delegate;
|
lock_guard<mutex> lck(_mtx);
|
||||||
}
|
_delegateMap.emplace(delegate.get(),delegate);
|
||||||
/**
|
|
||||||
* 获取帧环形缓存
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
FrameRingInterface::RingType::Ptr getFrameRing() const override {
|
|
||||||
if(_delegate){
|
|
||||||
return _delegate->getFrameRing();
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void delDelegate(void *ptr){
|
||||||
* 设置帧环形缓存
|
lock_guard<mutex> lck(_mtx);
|
||||||
* @param ring
|
_delegateMap.erase(ptr);
|
||||||
*/
|
|
||||||
void setFrameRing(const FrameRingInterface::RingType::Ptr &ring) override {
|
|
||||||
if(_delegate){
|
|
||||||
_delegate->setFrameRing(ring);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -209,12 +203,16 @@ public:
|
|||||||
* @param frame 帧
|
* @param frame 帧
|
||||||
*/
|
*/
|
||||||
void inputFrame(const Frame::Ptr &frame) override{
|
void inputFrame(const Frame::Ptr &frame) override{
|
||||||
if(_delegate){
|
FrameRing::inputFrame(frame);
|
||||||
_delegate->inputFrame(frame);
|
lock_guard<mutex> lck(_mtx);
|
||||||
|
for(auto &pr : _delegateMap){
|
||||||
|
pr.second->inputFrame(frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
FrameRingInterface::Ptr _delegate;
|
mutex _mtx;
|
||||||
|
map<void *,FrameRingWriterInterface::Ptr> _delegateMap;
|
||||||
|
FrameRing::Ptr _frameRing;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -257,6 +255,7 @@ public:
|
|||||||
uint32_t iPrefixSize = 4;
|
uint32_t iPrefixSize = 4;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* aac帧,包含adts头
|
* aac帧,包含adts头
|
||||||
*/
|
*/
|
||||||
@ -311,7 +310,80 @@ public:
|
|||||||
unsigned char buffer[2 * 1024 + 7];
|
unsigned char buffer[2 * 1024 + 7];
|
||||||
uint16_t sequence;
|
uint16_t sequence;
|
||||||
uint32_t timeStamp;
|
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
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual bool ready() = 0;
|
virtual bool ready() = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* 克隆接口,用于复制本对象用
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
virtual Track::Ptr clone() = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class VideoTrack : public Track {
|
class VideoTrack : public Track {
|
||||||
@ -251,9 +245,6 @@ private:
|
|||||||
void parseSps(const string &sps){
|
void parseSps(const string &sps){
|
||||||
getAVCInfo(sps,_width,_height,_fps);
|
getAVCInfo(sps,_width,_height,_fps);
|
||||||
}
|
}
|
||||||
Track::Ptr clone() override {
|
|
||||||
return std::make_shared<std::remove_reference<decltype(*this)>::type >(*this);
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
string _sps;
|
string _sps;
|
||||||
string _pps;
|
string _pps;
|
||||||
@ -378,9 +369,6 @@ private:
|
|||||||
makeAdtsHeader(aac_cfg,aacFrame);
|
makeAdtsHeader(aac_cfg,aacFrame);
|
||||||
getAACInfo(aacFrame,_sampleRate,_channel);
|
getAACInfo(aacFrame,_sampleRate,_channel);
|
||||||
}
|
}
|
||||||
Track::Ptr clone() override {
|
|
||||||
return std::make_shared<std::remove_reference<decltype(*this)>::type >(*this);
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
string _cfg;
|
string _cfg;
|
||||||
int _sampleRate = 0;
|
int _sampleRate = 0;
|
||||||
|
@ -84,7 +84,7 @@ void RtmpDemuxer::makeVideoTrack(const AMFValue &videoCodec) {
|
|||||||
_videoRtmpDecoder = Factory::getRtmpCodecByTrack(_videoTrack);
|
_videoRtmpDecoder = Factory::getRtmpCodecByTrack(_videoTrack);
|
||||||
if (_videoRtmpDecoder) {
|
if (_videoRtmpDecoder) {
|
||||||
//设置rtmp解码器代理,生成的frame写入该Track
|
//设置rtmp解码器代理,生成的frame写入该Track
|
||||||
_videoRtmpDecoder->setDelegate(_videoTrack);
|
_videoRtmpDecoder->addDelegate(_videoTrack);
|
||||||
} else {
|
} else {
|
||||||
//找不到相应的rtmp解码器,该track无效
|
//找不到相应的rtmp解码器,该track无效
|
||||||
_videoTrack.reset();
|
_videoTrack.reset();
|
||||||
@ -100,7 +100,7 @@ void RtmpDemuxer::makeAudioTrack(const AMFValue &audioCodec) {
|
|||||||
_audioRtmpDecoder = Factory::getRtmpCodecByTrack(_audioTrack);
|
_audioRtmpDecoder = Factory::getRtmpCodecByTrack(_audioTrack);
|
||||||
if (_audioRtmpDecoder) {
|
if (_audioRtmpDecoder) {
|
||||||
//设置rtmp解码器代理,生成的frame写入该Track
|
//设置rtmp解码器代理,生成的frame写入该Track
|
||||||
_audioRtmpDecoder->setDelegate(_audioTrack);
|
_audioRtmpDecoder->addDelegate(_audioTrack);
|
||||||
} else {
|
} else {
|
||||||
//找不到相应的rtmp解码器,该track无效
|
//找不到相应的rtmp解码器,该track无效
|
||||||
_audioTrack.reset();
|
_audioTrack.reset();
|
||||||
|
@ -60,7 +60,7 @@ void RtmpMuxer::addTrack(const Track::Ptr &track) {
|
|||||||
_metedata.set(key,value);
|
_metedata.set(key,value);
|
||||||
});
|
});
|
||||||
//设置Track的代理,这样输入frame至Track时,最终数据将输出到RtmpEncoder中
|
//设置Track的代理,这样输入frame至Track时,最终数据将输出到RtmpEncoder中
|
||||||
track->setDelegate(encoder);
|
track->addDelegate(encoder);
|
||||||
//Rtmp编码器共用同一个环形缓存
|
//Rtmp编码器共用同一个环形缓存
|
||||||
encoder->setRtmpRing(_rtmpRing);
|
encoder->setRtmpRing(_rtmpRing);
|
||||||
};
|
};
|
||||||
|
@ -93,7 +93,7 @@ void RtspDemuxer::makeAudioTrack(const SdpTrack::Ptr &audio) {
|
|||||||
_audioRtpDecoder = Factory::getRtpDecoderById(_audioTrack->getCodecId());
|
_audioRtpDecoder = Factory::getRtpDecoderById(_audioTrack->getCodecId());
|
||||||
if(_audioRtpDecoder){
|
if(_audioRtpDecoder){
|
||||||
//设置rtp解码器代理,生成的frame写入该Track
|
//设置rtp解码器代理,生成的frame写入该Track
|
||||||
_audioRtpDecoder->setDelegate(_audioTrack);
|
_audioRtpDecoder->addDelegate(_audioTrack);
|
||||||
} else{
|
} else{
|
||||||
//找不到相应的rtp解码器,该track无效
|
//找不到相应的rtp解码器,该track无效
|
||||||
_audioTrack.reset();
|
_audioTrack.reset();
|
||||||
@ -109,7 +109,7 @@ void RtspDemuxer::makeVideoTrack(const SdpTrack::Ptr &video) {
|
|||||||
_videoRtpDecoder = Factory::getRtpDecoderById(_videoTrack->getCodecId());
|
_videoRtpDecoder = Factory::getRtpDecoderById(_videoTrack->getCodecId());
|
||||||
if(_videoRtpDecoder){
|
if(_videoRtpDecoder){
|
||||||
//设置rtp解码器代理,生成的frame写入该Track
|
//设置rtp解码器代理,生成的frame写入该Track
|
||||||
_videoRtpDecoder->setDelegate(_videoTrack);
|
_videoRtpDecoder->addDelegate(_videoTrack);
|
||||||
}else{
|
}else{
|
||||||
//找不到相应的rtp解码器,该track无效
|
//找不到相应的rtp解码器,该track无效
|
||||||
_videoTrack.reset();
|
_videoTrack.reset();
|
||||||
|
@ -29,9 +29,7 @@
|
|||||||
|
|
||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
void RtspMuxer::addTrack(const Track::Ptr &track_in, uint32_t ssrc, int mtu) {
|
void RtspMuxer::addTrack(const Track::Ptr &track, uint32_t ssrc, int mtu) {
|
||||||
//克隆对象,防止在setDelegate时错误覆盖
|
|
||||||
auto track = track_in->clone();
|
|
||||||
auto codec_id = track->getCodecId();
|
auto codec_id = track->getCodecId();
|
||||||
_track_map[codec_id] = track;
|
_track_map[codec_id] = track;
|
||||||
|
|
||||||
@ -51,7 +49,7 @@ void RtspMuxer::addTrack(const Track::Ptr &track_in, uint32_t ssrc, int mtu) {
|
|||||||
//添加其sdp
|
//添加其sdp
|
||||||
_sdp.append(sdp->getSdp());
|
_sdp.append(sdp->getSdp());
|
||||||
//设置Track的代理,这样输入frame至Track时,最终数据将输出到RtpEncoder中
|
//设置Track的代理,这样输入frame至Track时,最终数据将输出到RtpEncoder中
|
||||||
track->setDelegate(encoder);
|
track->addDelegate(encoder);
|
||||||
//rtp编码器共用同一个环形缓存
|
//rtp编码器共用同一个环形缓存
|
||||||
encoder->setRtpRing(_rtpRing);
|
encoder->setRtpRing(_rtpRing);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user