Commit c55f26fb by xiongziliang

整理MediaSink

parent c1ab73f7
......@@ -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;
}
return pr.second->ready() ? pr.second : nullptr;
if(trackReady && !pr.second->ready()){
continue;
}
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();
/**
* 全部Track是否都准备好了
* @return
*/
bool isAllTrackReady() const;
void resetTracks() override;
/**
* 获取特定类型的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();
}
......@@ -83,20 +68,6 @@ public:
}
/**
* 写入帧数据然后打包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:
/**
* 添加已经ready状态的track
*/
void addTrack(const Track::Ptr & track) override;
/**
* 某track已经准备好,其ready()状态返回true,
* 此时代表可以获取其例如sps pps等相关信息了
* @param track
* 输入帧
*/
void onTrackReady(const Track::Ptr & track) override;
void inputFrame(const Frame::Ptr &frame) override;
/**
* 某Track输出frame,在onAllTrackReady触发后才会调用此方法
* @param frame
* 重置所有track
*/
void onTrackFrame(const Frame::Ptr &frame) override;
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
* 输入frame
*/
void onTrackFrame(const Frame::Ptr &frame) override ;
void inputFrame(const Frame::Ptr &frame) override;
/**
* 某track已经准备好,其ready()状态返回true,
* 此时代表可以获取其例如sps pps等相关信息了
* @param track
* 添加ready状态的track
*/
void onTrackReady(const Track::Ptr & track) override;
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 */
\ No newline at end of file
......@@ -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:
/**
* 添加ready状态的track
*/
void addTrack(const Track::Ptr & track) override;
/**
* 某track已经准备好,其ready()状态返回true,
* 此时代表可以获取其例如sps pps等相关信息了
* @param track
*/
void onTrackReady(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);
}
string RtspMuxer::getSdp() {
if(!isAllTrackReady()){
//尚未就绪
return "";
void RtspMuxer::inputFrame(const Frame::Ptr &frame) {
auto &encoder = _encoder[frame->getTrackType()];
if(encoder){
encoder->inputFrame(frame);
}
}
string RtspMuxer::getSdp() {
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 */
\ No newline at end of file
......@@ -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:
/**
* 添加ready状态的track
*/
void addTrack(const Track::Ptr & track) override;
/**
* 写入帧数据
* @param frame 帧
*/
void inputFrame(const Frame::Ptr &frame) override;
/**
* 某track已经准备好,其ready()状态返回true,
* 此时代表可以获取其例如sps pps等相关信息了
* @param track
*/
void onTrackReady(const Track::Ptr & track) override ;
* 重置所有track
*/
void resetTracks() override ;
private:
RtpRingInterface::RingType::Ptr _rtpRing;
string _sdp;
RtpCodec::Ptr _encoder[TrackMax];
RtpRingInterface::RingType::Ptr _rtpRing;
};
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论