mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-22 19:00:01 +08:00
整理MediaSink
This commit is contained in:
parent
c1ab73f758
commit
c55f26fba7
@ -111,21 +111,16 @@ void MediaSink::inputFrame(const Frame::Ptr &frame) {
|
||||
}
|
||||
}
|
||||
|
||||
bool MediaSink::isAllTrackReady() const {
|
||||
return _allTrackReady;
|
||||
}
|
||||
|
||||
Track::Ptr MediaSink::getTrack(TrackType type,bool trackReady) const {
|
||||
vector<Track::Ptr> MediaSink::getTracks(bool trackReady) const{
|
||||
vector<Track::Ptr> ret;
|
||||
lock_guard<recursive_mutex> lck(_mtx);
|
||||
for (auto &pr : _track_map){
|
||||
if(pr.second->getTrackType() == type){
|
||||
if(!trackReady){
|
||||
return pr.second;
|
||||
if(trackReady && !pr.second->ready()){
|
||||
continue;
|
||||
}
|
||||
return pr.second->ready() ? pr.second : nullptr;
|
||||
ret.emplace_back(pr.second);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
return std::move(ret);
|
||||
}
|
||||
|
||||
|
||||
|
@ -38,11 +38,29 @@ using namespace toolkit;
|
||||
|
||||
namespace mediakit{
|
||||
|
||||
class MediaSinkInterface : public FrameWriterInterface {
|
||||
public:
|
||||
MediaSinkInterface(){};
|
||||
virtual ~MediaSinkInterface(){};
|
||||
|
||||
/**
|
||||
* 添加track,内部会调用Track的clone方法
|
||||
* 只会克隆sps pps这些信息 ,而不会克隆Delegate相关关系
|
||||
* @param track
|
||||
*/
|
||||
virtual void addTrack(const Track::Ptr & track) = 0;
|
||||
|
||||
/**
|
||||
* 重置track
|
||||
*/
|
||||
virtual void resetTracks() = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* 该类的作用是等待Track ready()返回true也就是就绪后再通知派生类进行下一步的操作
|
||||
* 目的是输入Frame前由Track截取处理下,以便获取有效的信息(譬如sps pps aa_cfg)
|
||||
*/
|
||||
class MediaSink : public FrameWriterInterface , public std::enable_shared_from_this<MediaSink>{
|
||||
class MediaSink : public MediaSinkInterface , public TrackSource , public std::enable_shared_from_this<MediaSink>{
|
||||
public:
|
||||
typedef std::shared_ptr<MediaSink> Ptr;
|
||||
MediaSink(){}
|
||||
@ -59,26 +77,18 @@ public:
|
||||
* 只会克隆sps pps这些信息 ,而不会克隆Delegate相关关系
|
||||
* @param track
|
||||
*/
|
||||
virtual void addTrack(const Track::Ptr & track);
|
||||
void addTrack(const Track::Ptr & track) override;
|
||||
|
||||
/**
|
||||
* 重置track
|
||||
*/
|
||||
virtual void resetTracks();
|
||||
void resetTracks() override;
|
||||
|
||||
/**
|
||||
* 全部Track是否都准备好了
|
||||
* @return
|
||||
*/
|
||||
bool isAllTrackReady() const;
|
||||
|
||||
/**
|
||||
* 获取特定类型的Track
|
||||
* @param type track类型
|
||||
* 获取所有Track
|
||||
* @param trackReady 是否获取已经准备好的Track
|
||||
* @return
|
||||
*/
|
||||
Track::Ptr getTrack(TrackType type,bool trackReady = true) const;
|
||||
vector<Track::Ptr> getTracks(bool trackReady = true) const override ;
|
||||
protected:
|
||||
/**
|
||||
* 某track已经准备好,其ready()状态返回true,
|
||||
|
@ -92,7 +92,7 @@ public:
|
||||
string _param_strs;
|
||||
};
|
||||
|
||||
class MediaSource: public enable_shared_from_this<MediaSource> {
|
||||
class MediaSource: public TrackSource, public enable_shared_from_this<MediaSource> {
|
||||
public:
|
||||
typedef std::shared_ptr<MediaSource> Ptr;
|
||||
typedef unordered_map<string, weak_ptr<MediaSource> > StreamMap;
|
||||
@ -191,14 +191,6 @@ public:
|
||||
}
|
||||
|
||||
virtual int readerCount() = 0;
|
||||
|
||||
/**
|
||||
* 获取track
|
||||
* @return
|
||||
*/
|
||||
virtual vector<Track::Ptr> getTracks(bool trackReady) const{
|
||||
return vector<Track::Ptr>(0);
|
||||
}
|
||||
protected:
|
||||
void regist() ;
|
||||
bool unregist() ;
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include "Rtmp/RtmpMediaSourceMuxer.h"
|
||||
#include "MediaFile/MediaRecorder.h"
|
||||
|
||||
class MultiMediaSourceMuxer : public FrameWriterInterface{
|
||||
class MultiMediaSourceMuxer : public MediaSink{
|
||||
public:
|
||||
typedef std::shared_ptr<MultiMediaSourceMuxer> Ptr;
|
||||
|
||||
@ -54,25 +54,10 @@ public:
|
||||
}
|
||||
virtual ~MultiMediaSourceMuxer(){}
|
||||
|
||||
|
||||
/**
|
||||
* 添加音视频媒体
|
||||
* @param track 媒体描述
|
||||
*/
|
||||
void addTrack(const Track::Ptr & track) {
|
||||
if(_rtmp){
|
||||
_rtmp->addTrack(track);
|
||||
}
|
||||
if(_rtsp){
|
||||
_rtsp->addTrack(track);
|
||||
}
|
||||
_record->addTrack(track);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置音视频媒体
|
||||
*/
|
||||
void resetTracks() {
|
||||
void resetTracks() override{
|
||||
if(_rtmp){
|
||||
_rtmp->resetTracks();
|
||||
}
|
||||
@ -82,20 +67,6 @@ public:
|
||||
_record->resetTracks();
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入帧数据然后打包rtmp
|
||||
* @param frame 帧数据
|
||||
*/
|
||||
void inputFrame(const Frame::Ptr &frame) override {
|
||||
if(_rtmp) {
|
||||
_rtmp->inputFrame(frame);
|
||||
}
|
||||
if(_rtsp) {
|
||||
_rtsp->inputFrame(frame);
|
||||
}
|
||||
_record->inputFrame(frame);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置事件监听器
|
||||
* @param listener
|
||||
@ -122,6 +93,47 @@ public:
|
||||
_rtsp->setTimeStamp(stamp);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* 添加音视频媒体
|
||||
* @param track 媒体描述
|
||||
*/
|
||||
void onTrackReady(const Track::Ptr & track) override {
|
||||
if(_rtmp){
|
||||
_rtmp->addTrack(track);
|
||||
}
|
||||
if(_rtsp){
|
||||
_rtsp->addTrack(track);
|
||||
}
|
||||
_record->addTrack(track);
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入帧数据然后打包rtmp
|
||||
* @param frame 帧数据
|
||||
*/
|
||||
void onTrackFrame(const Frame::Ptr &frame) override {
|
||||
if(_rtmp) {
|
||||
_rtmp->inputFrame(frame);
|
||||
}
|
||||
if(_rtsp) {
|
||||
_rtsp->inputFrame(frame);
|
||||
}
|
||||
_record->inputFrame(frame);
|
||||
}
|
||||
|
||||
/**
|
||||
* 所有Track都准备就绪,触发媒体注册事件
|
||||
*/
|
||||
void onAllTrackReady() override{
|
||||
if(_rtmp) {
|
||||
_rtmp->onAllTrackReady();
|
||||
}
|
||||
if(_rtsp) {
|
||||
_rtsp->onAllTrackReady();
|
||||
}
|
||||
}
|
||||
private:
|
||||
RtmpMediaSourceMuxer::Ptr _rtmp;
|
||||
RtspMediaSourceMuxer::Ptr _rtsp;
|
||||
|
@ -50,7 +50,7 @@ typedef enum {
|
||||
TrackVideo = 0,
|
||||
TrackAudio,
|
||||
TrackTitle,
|
||||
TrackMax = 0x7FFF
|
||||
TrackMax = 3
|
||||
} TrackType;
|
||||
|
||||
/**
|
||||
|
@ -131,6 +131,37 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class TrackSource{
|
||||
public:
|
||||
TrackSource(){}
|
||||
virtual ~TrackSource(){}
|
||||
|
||||
/**
|
||||
* 获取全部的Track
|
||||
* @param trackReady 是否获取全部已经准备好的Track
|
||||
* @return
|
||||
*/
|
||||
virtual vector<Track::Ptr> getTracks(bool trackReady = true) const {
|
||||
return vector<Track::Ptr>();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取特定Track
|
||||
* @param type track类型
|
||||
* @param trackReady 是否获取全部已经准备好的Track
|
||||
* @return
|
||||
*/
|
||||
Track::Ptr getTrack(TrackType type , bool trackReady = true) const {
|
||||
auto tracks = getTracks(trackReady);
|
||||
for(auto &track : tracks){
|
||||
if(track->getTrackType() == type){
|
||||
return track;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
}//namespace mediakit
|
||||
|
||||
#endif //ZLMEDIAKIT_TRACK_H
|
||||
|
@ -67,8 +67,12 @@ void MP4MuxerBase::init(int flags) {
|
||||
}
|
||||
|
||||
///////////////////////////////////
|
||||
void MP4Muxer::resetTracks() {
|
||||
_codec_to_trackid.clear();
|
||||
_started = false;
|
||||
}
|
||||
|
||||
void MP4Muxer::onTrackFrame(const Frame::Ptr &frame) {
|
||||
void MP4Muxer::inputFrame(const Frame::Ptr &frame) {
|
||||
if(frame->configFrame()){
|
||||
//忽略配置帧
|
||||
return;
|
||||
@ -117,7 +121,7 @@ void MP4Muxer::onTrackFrame(const Frame::Ptr &frame) {
|
||||
with_nalu_size);
|
||||
}
|
||||
|
||||
void MP4Muxer::onTrackReady(const Track::Ptr &track) {
|
||||
void MP4Muxer::addTrack(const Track::Ptr &track) {
|
||||
switch (track->getCodecId()) {
|
||||
case CodecAAC: {
|
||||
auto aac_track = dynamic_pointer_cast<AACTrack>(track);
|
||||
@ -210,7 +214,12 @@ void MP4Muxer::onTrackReady(const Track::Ptr &track) {
|
||||
}
|
||||
}
|
||||
|
||||
MP4MuxerFile::MP4MuxerFile(const char *file) {
|
||||
MP4MuxerFile::MP4MuxerFile(const char *file){
|
||||
_file_name = file;
|
||||
openFile(file);
|
||||
}
|
||||
|
||||
void MP4MuxerFile::openFile(const char *file) {
|
||||
//创建文件
|
||||
auto fp = File::createfile_file(file,"wb+");
|
||||
if(!fp){
|
||||
@ -237,7 +246,6 @@ MP4MuxerFile::MP4MuxerFile(const char *file) {
|
||||
});
|
||||
|
||||
GET_CONFIG(bool, mp4FastStart, Record::kFastStart);
|
||||
|
||||
init(mp4FastStart ? MOV_FLAG_FASTSTART : 0);
|
||||
}
|
||||
|
||||
@ -264,6 +272,12 @@ uint64_t MP4MuxerFile::onTell() {
|
||||
return ftell64(_file.get());
|
||||
}
|
||||
|
||||
|
||||
void MP4MuxerFile::resetTracks(){
|
||||
MP4Muxer::resetTracks();
|
||||
openFile(_file_name.data());
|
||||
}
|
||||
|
||||
}//namespace mediakit
|
||||
|
||||
#endif//#ifdef ENABLE_MP4RECORD
|
||||
|
@ -57,23 +57,24 @@ protected:
|
||||
std::shared_ptr<mov_writer_t> _mov_writter;
|
||||
};
|
||||
|
||||
class MP4Muxer : public MediaSink , public MP4MuxerBase{
|
||||
class MP4Muxer : public MediaSinkInterface , public MP4MuxerBase{
|
||||
public:
|
||||
MP4Muxer() = default;
|
||||
~MP4Muxer() override = default;
|
||||
protected:
|
||||
/**
|
||||
* 某track已经准备好,其ready()状态返回true,
|
||||
* 此时代表可以获取其例如sps pps等相关信息了
|
||||
* @param track
|
||||
*/
|
||||
void onTrackReady(const Track::Ptr & track) override;
|
||||
|
||||
/**
|
||||
* 某Track输出frame,在onAllTrackReady触发后才会调用此方法
|
||||
* @param frame
|
||||
* 添加已经ready状态的track
|
||||
*/
|
||||
void onTrackFrame(const Frame::Ptr &frame) override;
|
||||
void addTrack(const Track::Ptr & track) override;
|
||||
/**
|
||||
* 输入帧
|
||||
*/
|
||||
void inputFrame(const Frame::Ptr &frame) override;
|
||||
|
||||
/**
|
||||
* 重置所有track
|
||||
*/
|
||||
void resetTracks() override ;
|
||||
private:
|
||||
struct track_info{
|
||||
int track_id = -1;
|
||||
@ -89,13 +90,16 @@ public:
|
||||
typedef std::shared_ptr<MP4MuxerFile> Ptr;
|
||||
MP4MuxerFile(const char *file);
|
||||
~MP4MuxerFile();
|
||||
void resetTracks() override ;
|
||||
protected:
|
||||
int onRead(void* data, uint64_t bytes) override;
|
||||
int onWrite(const void* data, uint64_t bytes) override;
|
||||
int onSeek( uint64_t offset) override;
|
||||
uint64_t onTell() override ;
|
||||
void openFile(const char *file);
|
||||
private:
|
||||
std::shared_ptr<FILE> _file;
|
||||
string _file_name;
|
||||
};
|
||||
|
||||
}//namespace mediakit
|
||||
|
@ -128,7 +128,7 @@ void MP4Recorder::closeFile() {
|
||||
}
|
||||
}
|
||||
|
||||
void MP4Recorder::onTrackFrame(const Frame::Ptr &frame) {
|
||||
void MP4Recorder::inputFrame(const Frame::Ptr &frame) {
|
||||
GET_CONFIG(uint32_t,recordSec,Record::kFileSecond);
|
||||
if(!_muxer || ((_createFileTicker.elapsedTime() > recordSec * 1000) &&
|
||||
(!_haveVideo || (_haveVideo && frame->keyFrame()))) ){
|
||||
@ -145,7 +145,7 @@ void MP4Recorder::onTrackFrame(const Frame::Ptr &frame) {
|
||||
}
|
||||
}
|
||||
|
||||
void MP4Recorder::onTrackReady(const Track::Ptr & track){
|
||||
void MP4Recorder::addTrack(const Track::Ptr & track){
|
||||
//保存所有的track,为创建MP4MuxerFile做准备
|
||||
_tracks.emplace_back(track);
|
||||
if(track->getTrackType() == TrackVideo){
|
||||
@ -158,7 +158,6 @@ void MP4Recorder::resetTracks() {
|
||||
_tracks.clear();
|
||||
_haveVideo = false;
|
||||
_createFileTicker.resetTime();
|
||||
MediaSink::resetTracks();
|
||||
}
|
||||
|
||||
} /* namespace mediakit */
|
||||
|
@ -55,7 +55,7 @@ public:
|
||||
string strStreamId;//流ID
|
||||
string strVhost;//vhost
|
||||
};
|
||||
class MP4Recorder : public MediaSink{
|
||||
class MP4Recorder : public MediaSinkInterface{
|
||||
public:
|
||||
typedef std::shared_ptr<MP4Recorder> Ptr;
|
||||
MP4Recorder(const string &strPath,
|
||||
@ -68,19 +68,16 @@ public:
|
||||
* 重置所有Track
|
||||
*/
|
||||
void resetTracks() override;
|
||||
private:
|
||||
/**
|
||||
* 某Track输出frame,在onAllTrackReady触发后才会调用此方法
|
||||
* @param frame
|
||||
*/
|
||||
void onTrackFrame(const Frame::Ptr &frame) override ;
|
||||
|
||||
/**
|
||||
* 某track已经准备好,其ready()状态返回true,
|
||||
* 此时代表可以获取其例如sps pps等相关信息了
|
||||
* @param track
|
||||
* 输入frame
|
||||
*/
|
||||
void onTrackReady(const Track::Ptr & track) override;
|
||||
void inputFrame(const Frame::Ptr &frame) override;
|
||||
|
||||
/**
|
||||
* 添加ready状态的track
|
||||
*/
|
||||
void addTrack(const Track::Ptr & track) override;
|
||||
private:
|
||||
void createFile();
|
||||
void closeFile();
|
||||
|
@ -37,7 +37,7 @@ using namespace toolkit;
|
||||
|
||||
namespace mediakit {
|
||||
|
||||
class MediaRecorder : public MediaSink{
|
||||
class MediaRecorder : public MediaSinkInterface{
|
||||
public:
|
||||
typedef std::shared_ptr<MediaRecorder> Ptr;
|
||||
MediaRecorder(const string &strVhost,
|
||||
|
@ -38,7 +38,7 @@ using namespace toolkit;
|
||||
|
||||
namespace mediakit {
|
||||
|
||||
class TsMuxer : public MediaSink {
|
||||
class TsMuxer : public MediaSinkInterface {
|
||||
public:
|
||||
TsMuxer();
|
||||
virtual ~TsMuxer();
|
||||
|
@ -41,7 +41,7 @@ using namespace toolkit;
|
||||
|
||||
namespace mediakit {
|
||||
|
||||
class DemuxerBase {
|
||||
class DemuxerBase : public TrackSource{
|
||||
public:
|
||||
typedef std::shared_ptr<DemuxerBase> Ptr;
|
||||
|
||||
@ -57,29 +57,6 @@ public:
|
||||
* @return
|
||||
*/
|
||||
virtual bool isInited(int analysisMs) { return true; }
|
||||
|
||||
/**
|
||||
* 获取全部的Track
|
||||
* @param trackReady 是否获取全部已经准备好的Track
|
||||
* @return
|
||||
*/
|
||||
virtual vector<Track::Ptr> getTracks(bool trackReady = true) const { return vector<Track::Ptr>();}
|
||||
|
||||
/**
|
||||
* 获取特定Track
|
||||
* @param type track类型
|
||||
* @param trackReady 是否获取全部已经准备好的Track
|
||||
* @return
|
||||
*/
|
||||
virtual Track::Ptr getTrack(TrackType type , bool trackReady = true) const {
|
||||
auto tracks = getTracks(trackReady);
|
||||
for(auto &track : tracks){
|
||||
if(track->getTrackType() == type){
|
||||
return track;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -274,14 +251,14 @@ public:
|
||||
bool isInited(int analysisMs) override;
|
||||
|
||||
/**
|
||||
* 获取所有可用Track,请在isInited()返回true时调用
|
||||
* @return
|
||||
* 获取所有Track
|
||||
* @return 所有Track
|
||||
*/
|
||||
vector<Track::Ptr> getTracks(bool trackReady = true) const override;
|
||||
|
||||
/**
|
||||
* 获取节目总时长
|
||||
* @return
|
||||
* @return 节目总时长,单位秒
|
||||
*/
|
||||
float getDuration() const override;
|
||||
protected:
|
||||
|
@ -48,11 +48,12 @@ public:
|
||||
void setListener(const std::weak_ptr<MediaSourceEvent> &listener){
|
||||
_mediaSouce->setListener(listener);
|
||||
}
|
||||
|
||||
int readerCount() const{
|
||||
return _mediaSouce->readerCount();
|
||||
}
|
||||
private:
|
||||
void onAllTrackReady() override {
|
||||
|
||||
void onAllTrackReady(){
|
||||
_mediaSouce->onGetMetaData(getMetadata());
|
||||
}
|
||||
private:
|
||||
|
@ -38,13 +38,7 @@ RtmpMuxer::RtmpMuxer(const TitleMeta::Ptr &title) {
|
||||
_rtmpRing = std::make_shared<RtmpRingInterface::RingType>();
|
||||
}
|
||||
|
||||
void RtmpMuxer::onTrackReady(const Track::Ptr &track) {
|
||||
//生成rtmp编码器
|
||||
//克隆该Track,防止循环引用
|
||||
auto encoder = Factory::getRtmpCodecByTrack(track->clone());
|
||||
if (!encoder) {
|
||||
return;
|
||||
}
|
||||
void RtmpMuxer::addTrack(const Track::Ptr &track) {
|
||||
//根据track生产metadata
|
||||
Metadata::Ptr metadata;
|
||||
switch (track->getTrackType()){
|
||||
@ -57,26 +51,34 @@ void RtmpMuxer::onTrackReady(const Track::Ptr &track) {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;;
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
auto &encoder = _encoder[track->getTrackType()];
|
||||
//生成rtmp编码器,克隆该Track,防止循环引用
|
||||
encoder = Factory::getRtmpCodecByTrack(track->clone());
|
||||
if (!encoder) {
|
||||
return;
|
||||
}
|
||||
|
||||
//设置rtmp输出环形缓存
|
||||
encoder->setRtmpRing(_rtmpRing);
|
||||
|
||||
//添加其metadata
|
||||
metadata->getMetadata().object_for_each([&](const std::string &key, const AMFValue &value){
|
||||
_metadata.set(key,value);
|
||||
});
|
||||
//设置Track的代理,这样输入frame至Track时,最终数据将输出到RtmpEncoder中
|
||||
track->addDelegate(encoder);
|
||||
//Rtmp编码器共用同一个环形缓存
|
||||
encoder->setRtmpRing(_rtmpRing);
|
||||
}
|
||||
|
||||
void RtmpMuxer::inputFrame(const Frame::Ptr &frame) {
|
||||
auto &encoder = _encoder[frame->getTrackType()];
|
||||
if(encoder){
|
||||
encoder->inputFrame(frame);
|
||||
}
|
||||
}
|
||||
|
||||
const AMFValue &RtmpMuxer::getMetadata() const {
|
||||
if(!isAllTrackReady()){
|
||||
//尚未就绪
|
||||
static AMFValue s_amf;
|
||||
return s_amf;
|
||||
}
|
||||
return _metadata;
|
||||
}
|
||||
|
||||
@ -84,4 +86,12 @@ RtmpRingInterface::RingType::Ptr RtmpMuxer::getRtmpRing() const {
|
||||
return _rtmpRing;
|
||||
}
|
||||
|
||||
void RtmpMuxer::resetTracks() {
|
||||
_metadata.clear();
|
||||
for(auto &encoder : _encoder){
|
||||
encoder = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}/* namespace mediakit */
|
@ -34,7 +34,7 @@
|
||||
|
||||
namespace mediakit{
|
||||
|
||||
class RtmpMuxer : public MediaSink{
|
||||
class RtmpMuxer : public MediaSinkInterface{
|
||||
public:
|
||||
typedef std::shared_ptr<RtmpMuxer> Ptr;
|
||||
|
||||
@ -55,16 +55,26 @@ public:
|
||||
* @return
|
||||
*/
|
||||
RtmpRingInterface::RingType::Ptr getRtmpRing() const;
|
||||
protected:
|
||||
|
||||
/**
|
||||
* 某track已经准备好,其ready()状态返回true,
|
||||
* 此时代表可以获取其例如sps pps等相关信息了
|
||||
* @param track
|
||||
* 添加ready状态的track
|
||||
*/
|
||||
void onTrackReady(const Track::Ptr & track) override ;
|
||||
void addTrack(const Track::Ptr & track) override;
|
||||
|
||||
/**
|
||||
* 写入帧数据
|
||||
* @param frame 帧
|
||||
*/
|
||||
void inputFrame(const Frame::Ptr &frame) override;
|
||||
|
||||
/**
|
||||
* 重置所有track
|
||||
*/
|
||||
void resetTracks() override ;
|
||||
private:
|
||||
RtmpRingInterface::RingType::Ptr _rtmpRing;
|
||||
AMFValue _metadata;
|
||||
RtmpCodec::Ptr _encoder[TrackMax];
|
||||
};
|
||||
|
||||
|
||||
|
@ -48,14 +48,16 @@ public:
|
||||
void setListener(const std::weak_ptr<MediaSourceEvent> &listener){
|
||||
_mediaSouce->setListener(listener);
|
||||
}
|
||||
|
||||
int readerCount() const{
|
||||
return _mediaSouce->readerCount();
|
||||
}
|
||||
|
||||
void setTimeStamp(uint32_t stamp){
|
||||
_mediaSouce->setTimeStamp(stamp);
|
||||
}
|
||||
private:
|
||||
void onAllTrackReady() override {
|
||||
|
||||
void onAllTrackReady(){
|
||||
_mediaSouce->onGetSDP(getSdp());
|
||||
}
|
||||
private:
|
||||
|
@ -38,29 +38,34 @@ RtspMuxer::RtspMuxer(const TitleSdp::Ptr &title){
|
||||
_rtpRing = std::make_shared<RtpRingInterface::RingType>();
|
||||
}
|
||||
|
||||
void RtspMuxer::onTrackReady(const Track::Ptr &track) {
|
||||
void RtspMuxer::addTrack(const Track::Ptr &track) {
|
||||
//根据track生成sdp
|
||||
Sdp::Ptr sdp = track->getSdp();
|
||||
if (!sdp) {
|
||||
return;
|
||||
}
|
||||
auto encoder = Factory::getRtpEncoderBySdp(sdp);
|
||||
|
||||
auto &encoder = _encoder[track->getTrackType()];
|
||||
encoder = Factory::getRtpEncoderBySdp(sdp);
|
||||
if (!encoder) {
|
||||
return;
|
||||
}
|
||||
|
||||
//设置rtp输出环形缓存
|
||||
encoder->setRtpRing(_rtpRing);
|
||||
|
||||
//添加其sdp
|
||||
_sdp.append(sdp->getSdp());
|
||||
//设置Track的代理,这样输入frame至Track时,最终数据将输出到RtpEncoder中
|
||||
track->addDelegate(encoder);
|
||||
//rtp编码器共用同一个环形缓存
|
||||
encoder->setRtpRing(_rtpRing);
|
||||
}
|
||||
|
||||
void RtspMuxer::inputFrame(const Frame::Ptr &frame) {
|
||||
auto &encoder = _encoder[frame->getTrackType()];
|
||||
if(encoder){
|
||||
encoder->inputFrame(frame);
|
||||
}
|
||||
}
|
||||
|
||||
string RtspMuxer::getSdp() {
|
||||
if(!isAllTrackReady()){
|
||||
//尚未就绪
|
||||
return "";
|
||||
}
|
||||
return _sdp;
|
||||
}
|
||||
|
||||
@ -68,5 +73,12 @@ RtpRingInterface::RingType::Ptr RtspMuxer::getRtpRing() const {
|
||||
return _rtpRing;
|
||||
}
|
||||
|
||||
void RtspMuxer::resetTracks() {
|
||||
_sdp.clear();
|
||||
for(auto &encoder : _encoder){
|
||||
encoder = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} /* namespace mediakit */
|
@ -35,7 +35,7 @@ namespace mediakit{
|
||||
/**
|
||||
* rtsp生成器
|
||||
*/
|
||||
class RtspMuxer : public MediaSink{
|
||||
class RtspMuxer : public MediaSinkInterface{
|
||||
public:
|
||||
typedef std::shared_ptr<RtspMuxer> Ptr;
|
||||
|
||||
@ -57,16 +57,26 @@ public:
|
||||
* @return
|
||||
*/
|
||||
RtpRingInterface::RingType::Ptr getRtpRing() const;
|
||||
protected:
|
||||
|
||||
/**
|
||||
* 某track已经准备好,其ready()状态返回true,
|
||||
* 此时代表可以获取其例如sps pps等相关信息了
|
||||
* @param track
|
||||
* 添加ready状态的track
|
||||
*/
|
||||
void onTrackReady(const Track::Ptr & track) override ;
|
||||
void addTrack(const Track::Ptr & track) override;
|
||||
|
||||
/**
|
||||
* 写入帧数据
|
||||
* @param frame 帧
|
||||
*/
|
||||
void inputFrame(const Frame::Ptr &frame) override;
|
||||
|
||||
/**
|
||||
* 重置所有track
|
||||
*/
|
||||
void resetTracks() override ;
|
||||
private:
|
||||
RtpRingInterface::RingType::Ptr _rtpRing;
|
||||
string _sdp;
|
||||
RtpCodec::Ptr _encoder[TrackMax];
|
||||
RtpRingInterface::RingType::Ptr _rtpRing;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user