完成FLV复用器改造

优化代码结构
This commit is contained in:
xiongziliang
2018-08-31 14:13:00 +08:00
parent ef9ebc89e0
commit 732eb2d197
15 changed files with 74 additions and 68 deletions

View File

@@ -21,9 +21,6 @@ void FlvMuxer::start(const RtmpMediaSource::Ptr &media) {
if(!media){
throw std::runtime_error("RtmpMediaSource 无效");
}
if(!media->ready()){
throw std::runtime_error("RtmpMediaSource 未准备好");
}
onWriteFlvHeader(media);
@@ -176,6 +173,7 @@ void FlvRecorder::startRecord(const string &vhost, const string &app, const stri
}
void FlvRecorder::startRecord(const RtmpMediaSource::Ptr &media, const string &file_path) {
lock_guard<recursive_mutex> lck(_file_mtx);
//开辟文件写缓存
std::shared_ptr<char> fileBuf(new char[FILE_BUF_SIZE],[](char *ptr){
if(ptr){
@@ -183,7 +181,7 @@ void FlvRecorder::startRecord(const RtmpMediaSource::Ptr &media, const string &f
}
});
//新建文件
std::shared_ptr<FILE> _file(File::createfile_file(file_path.data(),"wb"),[fileBuf](FILE *fp){
_file.reset(File::createfile_file(file_path.data(),"wb"),[fileBuf](FILE *fp){
if(fp){
fflush(fp);
fclose(fp);
@@ -221,6 +219,12 @@ std::shared_ptr<FlvMuxer> FlvRecorder::getSharedPtr() {
return shared_from_this();
}
FlvRecorder::FlvRecorder() {
}
FlvRecorder::~FlvRecorder() {
}
}//namespace Rtmp
}//namespace ZL

View File

@@ -16,6 +16,7 @@ namespace Rtmp {
class FlvMuxer{
public:
typedef std::shared_ptr<FlvMuxer> Ptr;
FlvMuxer();
virtual ~FlvMuxer();
void stop();
@@ -38,6 +39,7 @@ private:
class FlvRecorder : public FlvMuxer , public std::enable_shared_from_this<FlvRecorder>{
public:
typedef std::shared_ptr<FlvRecorder> Ptr;
FlvRecorder();
virtual ~FlvRecorder();
void startRecord(const string &vhost,const string &app,const string &stream,const string &file_path);

View File

@@ -34,6 +34,7 @@
#include <unordered_map>
#include "amf.h"
#include "Rtmp.h"
#include "RtmpParser.h"
#include "Common/config.h"
#include "Common/MediaSender.h"
#include "Common/MediaSource.h"
@@ -71,6 +72,7 @@ public:
}
const AMFValue &getMetaData() const {
lock_guard<recursive_mutex> lock(m_mtxMap);
return m_metadata;
}
template<typename FUN>
@@ -80,29 +82,52 @@ public:
f(pr.second);
}
}
bool ready() const {
lock_guard<recursive_mutex> lock(m_mtxMap);
return (m_mapCfgFrame.size() != 0);
}
virtual void onGetMetaData(const AMFValue &_metadata) {
lock_guard<recursive_mutex> lock(m_mtxMap);
m_metadata = _metadata;
RtmpParser parser(_metadata);
m_iCfgFrameSize = parser.containAudio() + parser.containVideo();
if(ready()){
MediaSource::regist();
m_bRegisted = true;
} else{
m_bAsyncRegist = true;
}
}
virtual void onGetMedia(const RtmpPacket::Ptr &pkt) {
if (pkt->isCfgFrame()) {
if(!m_bRegisted){
lock_guard<recursive_mutex> lock(m_mtxMap);
m_mapCfgFrame.emplace(pkt->typeId, pkt);
if (m_mapCfgFrame.size() != m_iCfgFrameSize && pkt->isCfgFrame()) {
m_mapCfgFrame.emplace(pkt->typeId, pkt);
if( m_mapCfgFrame.size() == m_iCfgFrameSize && m_bAsyncRegist){
m_bAsyncRegist = false;
MediaSource::regist();
m_bRegisted = true;
}
}
}
auto _ring = m_pRing;
m_thPool.async([_ring,pkt]() {
_ring->write(pkt,pkt->isVideoKeyFrame());
});
}
private:
bool ready(){
lock_guard<recursive_mutex> lock(m_mtxMap);
return m_iCfgFrameSize != -1 && m_iCfgFrameSize == m_mapCfgFrame.size();
}
protected:
AMFValue m_metadata;
unordered_map<int, RtmpPacket::Ptr> m_mapCfgFrame;
mutable recursive_mutex m_mtxMap;
RingBuffer<RtmpPacket::Ptr>::Ptr m_pRing; //rtp环形缓冲
ThreadPool &m_thPool;
int m_iCfgFrameSize = -1;
bool m_bAsyncRegist = false;
bool m_bRegisted = false;
};
} /* namespace Rtmp */

View File

@@ -194,10 +194,7 @@ inline void RtmpPusher::send_metaData(){
if (!src) {
throw std::runtime_error("the media source was released");
}
if (!src->ready()) {
throw std::runtime_error("the media source is not ready");
}
AMFEncoder enc;
enc << "@setDataFrame" << "onMetaData" << src->getMetaData();
sendRequest(MSG_DATA, enc.data());

View File

@@ -167,7 +167,6 @@ void RtmpSession::onCmd_publish(AMFDecoder &dec) {
shutdown();
return;
}
m_bPublisherSrcRegisted = false;
m_pPublisherSrc.reset(new RtmpToRtspMediaSource(m_mediaInfo.m_vhost,m_mediaInfo.m_app,m_mediaInfo.m_streamid));
m_pPublisherSrc->setListener(dynamic_pointer_cast<MediaSourceEvent>(shared_from_this()));
};
@@ -212,13 +211,6 @@ void RtmpSession::doPlayResponse(const string &err,bool tryDelay,const std::shar
m_mediaInfo.m_app,
m_mediaInfo.m_streamid,
true));
if(src ){
if(!src->ready()){
//流未准备好那么相当于没有
src = nullptr;
}
}
//是否鉴权成功
bool authSuccess = err.empty();
if(authSuccess && !src && tryDelay ){
@@ -509,10 +501,6 @@ void RtmpSession::onRtmpChunk(RtmpPacket &chunkData) {
chunkData.timeStamp = m_stampTicker[chunkData.typeId % 2].elapsedTime();
}
m_pPublisherSrc->onGetMedia(std::make_shared<RtmpPacket>(chunkData));
if(!m_bPublisherSrcRegisted && m_pPublisherSrc->ready()){
m_bPublisherSrcRegisted = true;
m_pPublisherSrc->regist();
}
}
break;
default:

View File

@@ -102,7 +102,6 @@ private:
SmoothTicker m_stampTicker[2];//时间戳生产器
RingBuffer<RtmpPacket::Ptr>::RingReader::Ptr m_pRingReader;
std::shared_ptr<RtmpMediaSource> m_pPublisherSrc;
bool m_bPublisherSrcRegisted = false;
std::weak_ptr<RtmpMediaSource> m_pPlayerSrc;
uint32_t m_aui32FirstStamp[2] = {0};
//消耗的总流量

View File

@@ -45,19 +45,6 @@ RtmpToRtspMediaSource::RtmpToRtspMediaSource(const string &vhost,
}
RtmpToRtspMediaSource::~RtmpToRtspMediaSource() {}
bool RtmpToRtspMediaSource::regist() {
if (m_pRtspSrc) {
m_pRtspSrc->regist();
}
return MediaSource::regist();
}
bool RtmpToRtspMediaSource::unregist() {
if(m_pRtspSrc){
m_pRtspSrc->unregist();
}
return MediaSource::unregist();
}
void RtmpToRtspMediaSource::onGetH264(const H264Frame &frame) {
if(m_pRecorder){
@@ -166,7 +153,6 @@ void RtmpToRtspMediaSource::makeSDP() {
m_pRtspSrc.reset(new RtspMediaSource(getVhost(),getApp(),getId()));
m_pRtspSrc->setListener(m_listener);
m_pRtspSrc->onGetSDP(strSDP);
m_pRtspSrc->regist();
}

View File

@@ -63,9 +63,6 @@ public:
bool bEnableMp4 = false);
virtual ~RtmpToRtspMediaSource();
bool regist() override;
bool unregist() override;
void onGetMetaData(const AMFValue &_metadata) override {
try {
m_pParser.reset(new RtmpParser(_metadata));