Commit 6364b147 by xiongziliang

MP4、hls适配新代码

parent 83a0ee85
...@@ -83,5 +83,15 @@ bool MediaSink::isAllTrackReady() const { ...@@ -83,5 +83,15 @@ bool MediaSink::isAllTrackReady() const {
return _allTrackReady; return _allTrackReady;
} }
Track::Ptr MediaSink::getTrack(TrackType type) const {
lock_guard<mutex> lck(_mtx);
for (auto &pr : _track_map){
if(pr.second->getTrackType() == type){
return pr.second;
}
}
return nullptr;
}
}//namespace mediakit }//namespace mediakit
...@@ -58,7 +58,7 @@ public: ...@@ -58,7 +58,7 @@ public:
* 只会克隆sps pps这些信息 ,而不会克隆Delegate相关关系 * 只会克隆sps pps这些信息 ,而不会克隆Delegate相关关系
* @param track * @param track
*/ */
void addTrack(const Track::Ptr & track); virtual void addTrack(const Track::Ptr & track);
/** /**
...@@ -66,6 +66,14 @@ public: ...@@ -66,6 +66,14 @@ public:
* @return * @return
*/ */
bool isAllTrackReady() const ; bool isAllTrackReady() const ;
/**
* 获取特定类型的Track
* @param type
* @return
*/
Track::Ptr getTrack(TrackType type) const ;
protected: protected:
/** /**
* 某track已经准备好,其ready()状态返回true, * 某track已经准备好,其ready()状态返回true,
...@@ -85,7 +93,7 @@ protected: ...@@ -85,7 +93,7 @@ protected:
*/ */
virtual void onTrackFrame(const Frame::Ptr &frame) {}; virtual void onTrackFrame(const Frame::Ptr &frame) {};
private: private:
mutex _mtx; mutable mutex _mtx;
map<int,Track::Ptr> _track_map; map<int,Track::Ptr> _track_map;
map<int,function<void()> > _trackReadyCallback; map<int,function<void()> > _trackReadyCallback;
bool _allTrackReady = false; bool _allTrackReady = false;
......
...@@ -131,12 +131,12 @@ bool HLSMaker::write_index_file(int iFirstSegment, unsigned int uiLastSegment, i ...@@ -131,12 +131,12 @@ bool HLSMaker::write_index_file(int iFirstSegment, unsigned int uiLastSegment, i
return true; return true;
} }
void HLSMaker::inputH264(void *data, uint32_t length, uint32_t timeStamp, int type) { void HLSMaker::inputH264(void *data, uint32_t length, uint32_t timeStamp) {
if(_ui32LastStamp == 0){ if(_ui32LastStamp == 0){
_ui32LastStamp = timeStamp; _ui32LastStamp = timeStamp;
} }
int stampInc = timeStamp - _ui32LastStamp; int stampInc = timeStamp - _ui32LastStamp;
auto type = ((uint8_t*)data)[4] & 0x1F;
switch (type) { switch (type) {
case 7: //SPS case 7: //SPS
if (stampInc >= _ui32SegmentDuration * 1000) { if (stampInc >= _ui32SegmentDuration * 1000) {
...@@ -182,5 +182,29 @@ bool HLSMaker::removets() { ...@@ -182,5 +182,29 @@ bool HLSMaker::removets() {
return true; return true;
} }
void HLSMaker::onTrackFrame(const Frame::Ptr &frame) {
switch (frame->getCodecId()){
case CodecH264:{
if( frame->prefixSize() == 4){
inputH264(frame->data(), frame->size(),frame->stamp());
}else{
WarnL << "h264必须要有头4个字节的前缀";
}
}
break;
case CodecAAC:{
if( frame->prefixSize() == 7) {
inputAAC(frame->data(), frame->size(), frame->stamp());
}else{
WarnL << "adts必须要有头7个字节的adts头";
}
}
break;
default:
break;
}
}
} /* namespace mediakit */ } /* namespace mediakit */
...@@ -27,18 +27,19 @@ ...@@ -27,18 +27,19 @@
#ifndef HLSMAKER_H_ #ifndef HLSMAKER_H_
#define HLSMAKER_H_ #define HLSMAKER_H_
#include <deque>
#include "TSMaker.h" #include "TSMaker.h"
#include "Common/config.h"
#include "Util/TimeTicker.h" #include "Util/TimeTicker.h"
#include "Util/File.h" #include "Util/File.h"
#include "Util/util.h" #include "Util/util.h"
#include "Util/logger.h" #include "Util/logger.h"
#include <deque> #include "Common/config.h"
#include "Common/MediaSink.h"
using namespace toolkit; using namespace toolkit;
namespace mediakit { namespace mediakit {
class HLSMaker { class HLSMaker : public MediaSink{
public: public:
HLSMaker(const string &strM3u8File, HLSMaker(const string &strM3u8File,
uint32_t ui32BufSize = 64 * 1024, uint32_t ui32BufSize = 64 * 1024,
...@@ -47,16 +48,28 @@ public: ...@@ -47,16 +48,28 @@ public:
virtual ~HLSMaker(); virtual ~HLSMaker();
protected:
/**
* 某Track输出frame,在onAllTrackReady触发后才会调用此方法
* @param frame
*/
void onTrackFrame(const Frame::Ptr &frame) override ;
private:
//时间戳:参考频率1000 //时间戳:参考频率1000
void inputH264( void *pData, void inputH264(void *pData,
uint32_t ui32Length, uint32_t ui32Length,
uint32_t ui32TimeStamp, uint32_t ui32TimeStamp);
int iType);
//时间戳:参考频率1000 //时间戳:参考频率1000
void inputAAC( void *pData, void inputAAC(void *pData,
uint32_t ui32Length, uint32_t ui32Length,
uint32_t ui32TimeStamp); uint32_t ui32TimeStamp);
bool write_index_file(int iFirstSegment,
unsigned int uiLastSegment,
int iEnd);
bool removets();
private: private:
TSMaker _ts; TSMaker _ts;
string _strM3u8File; string _strM3u8File;
...@@ -69,8 +82,7 @@ private: ...@@ -69,8 +82,7 @@ private:
uint32_t _ui32LastStamp; uint32_t _ui32LastStamp;
std::deque<int> _iDurations; std::deque<int> _iDurations;
bool write_index_file(int iFirstSegment, unsigned int uiLastSegment, int iEnd);
bool removets();
}; };
} /* namespace mediakit */ } /* namespace mediakit */
......
...@@ -37,7 +37,6 @@ namespace mediakit { ...@@ -37,7 +37,6 @@ namespace mediakit {
MediaRecorder::MediaRecorder(const string &strVhost_tmp, MediaRecorder::MediaRecorder(const string &strVhost_tmp,
const string &strApp, const string &strApp,
const string &strId, const string &strId,
const std::shared_ptr<PlayerBase> &pPlayer,
bool enableHls, bool enableHls,
bool enableMp4) { bool enableMp4) {
...@@ -63,7 +62,7 @@ MediaRecorder::MediaRecorder(const string &strVhost_tmp, ...@@ -63,7 +62,7 @@ MediaRecorder::MediaRecorder(const string &strVhost_tmp,
if(enableMp4){ if(enableMp4){
auto mp4FilePath = recordPath + "/" + strVhost + "/" + recordAppName + "/" + strApp + "/" + strId + "/"; auto mp4FilePath = recordPath + "/" + strVhost + "/" + recordAppName + "/" + strApp + "/" + strId + "/";
_mp4Maker.reset(new Mp4Maker(mp4FilePath,strVhost,strApp,strId,pPlayer)); _mp4Maker.reset(new Mp4Maker(mp4FilePath,strVhost,strApp,strId));
} }
#endif //ENABLE_MP4V2 #endif //ENABLE_MP4V2
} }
...@@ -73,22 +72,22 @@ MediaRecorder::~MediaRecorder() { ...@@ -73,22 +72,22 @@ MediaRecorder::~MediaRecorder() {
void MediaRecorder::inputH264(void* pData, uint32_t ui32Length, uint32_t ui32TimeStamp, int iType) { void MediaRecorder::inputH264(void* pData, uint32_t ui32Length, uint32_t ui32TimeStamp, int iType) {
if(_hlsMaker){ if(_hlsMaker){
_hlsMaker->inputH264(pData, ui32Length, ui32TimeStamp, iType); // _hlsMaker->inputH264(pData, ui32Length, ui32TimeStamp, iType);
} }
#ifdef ENABLE_MP4V2 #ifdef ENABLE_MP4V2
if(_mp4Maker){ if(_mp4Maker){
_mp4Maker->inputH264(pData, ui32Length, ui32TimeStamp, iType); // _mp4Maker->inputH264(pData, ui32Length, ui32TimeStamp, iType);
} }
#endif //ENABLE_MP4V2 #endif //ENABLE_MP4V2
} }
void MediaRecorder::inputAAC(void* pData, uint32_t ui32Length, uint32_t ui32TimeStamp) { void MediaRecorder::inputAAC(void* pData, uint32_t ui32Length, uint32_t ui32TimeStamp) {
if(_hlsMaker){ if(_hlsMaker){
_hlsMaker->inputAAC(pData, ui32Length, ui32TimeStamp); // _hlsMaker->inputAAC(pData, ui32Length, ui32TimeStamp);
} }
#ifdef ENABLE_MP4V2 #ifdef ENABLE_MP4V2
if(_mp4Maker){ if(_mp4Maker){
_mp4Maker->inputAAC(pData, ui32Length, ui32TimeStamp); // _mp4Maker->inputAAC(pData, ui32Length, ui32TimeStamp);
} }
#endif //ENABLE_MP4V2 #endif //ENABLE_MP4V2
} }
......
...@@ -45,7 +45,6 @@ public: ...@@ -45,7 +45,6 @@ public:
MediaRecorder(const string &strVhost, MediaRecorder(const string &strVhost,
const string &strApp, const string &strApp,
const string &strId, const string &strId,
const std::shared_ptr<PlayerBase> &pPlayer,
bool enableHls = true, bool enableHls = true,
bool enableMp4 = false); bool enableMp4 = false);
virtual ~MediaRecorder(); virtual ~MediaRecorder();
......
...@@ -57,10 +57,8 @@ string timeStr(const char *fmt) { ...@@ -57,10 +57,8 @@ string timeStr(const char *fmt) {
Mp4Maker::Mp4Maker(const string& strPath, Mp4Maker::Mp4Maker(const string& strPath,
const string &strVhost, const string &strVhost,
const string &strApp, const string &strApp,
const string &strStreamId, const string &strStreamId) {
const PlayerBase::Ptr &pPlayer) {
DebugL << strPath; DebugL << strPath;
_pPlayer = pPlayer;
_strPath = strPath; _strPath = strPath;
/////record 业务逻辑////// /////record 业务逻辑//////
...@@ -74,7 +72,8 @@ Mp4Maker::~Mp4Maker() { ...@@ -74,7 +72,8 @@ Mp4Maker::~Mp4Maker() {
closeFile(); closeFile();
} }
void Mp4Maker::inputH264(void *pData, uint32_t ui32Length, uint32_t ui32TimeStamp, int iType){ void Mp4Maker::inputH264(void *pData, uint32_t ui32Length, uint32_t ui32TimeStamp){
auto iType = ((uint8_t*)pData)[0] & 0x1F;
switch (iType) { switch (iType) {
case 1: //P case 1: //P
case 5: { //IDR case 5: { //IDR
...@@ -84,16 +83,14 @@ void Mp4Maker::inputH264(void *pData, uint32_t ui32Length, uint32_t ui32TimeStam ...@@ -84,16 +83,14 @@ void Mp4Maker::inputH264(void *pData, uint32_t ui32Length, uint32_t ui32TimeStam
if(iTimeInc == 0 || iTimeInc == 500){ if(iTimeInc == 0 || iTimeInc == 500){
WarnL << "abnormal time stamp increment:" << ui32TimeStamp << " " << _ui32LastVideoTime; WarnL << "abnormal time stamp increment:" << ui32TimeStamp << " " << _ui32LastVideoTime;
} }
_inputH264((char *) _strLastVideo.data(), _strLastVideo.size(), iTimeInc, _iLastVideoType); inputH264_l((char *) _strLastVideo.data(), _strLastVideo.size(), iTimeInc);
} }
//_strLastVideo.assign(("\x0\x0\x0\x2\x9\xf0"), 6);
uint32_t *p = (uint32_t *) pData; uint32_t prefixe = htonl(ui32Length);
*p = htonl(ui32Length - 4); _strLastVideo.assign((char *) &prefixe, 4);
_strLastVideo.assign((char *) pData, ui32Length); _strLastVideo.append((char *)pData,ui32Length);
memcpy(pData, "\x00\x00\x00\x01", 4);
_ui32LastVideoTime = ui32TimeStamp; _ui32LastVideoTime = ui32TimeStamp;
_iLastVideoType = iType;
} }
break; break;
default: default:
...@@ -107,16 +104,17 @@ void Mp4Maker::inputAAC(void *pData, uint32_t ui32Length, uint32_t ui32TimeStamp ...@@ -107,16 +104,17 @@ void Mp4Maker::inputAAC(void *pData, uint32_t ui32Length, uint32_t ui32TimeStamp
if(iTimeInc == 0 || iTimeInc == 500){ if(iTimeInc == 0 || iTimeInc == 500){
WarnL << "abnormal time stamp increment:" << ui32TimeStamp << " " << _ui32LastAudioTime; WarnL << "abnormal time stamp increment:" << ui32TimeStamp << " " << _ui32LastAudioTime;
} }
_inputAAC((char *)_strLastAudio.data(), _strLastAudio.size(), iTimeInc); inputAAC_l((char *) _strLastAudio.data(), _strLastAudio.size(), iTimeInc);
} }
_strLastAudio.assign((char *)pData, ui32Length); _strLastAudio.assign((char *)pData, ui32Length);
_ui32LastAudioTime = ui32TimeStamp; _ui32LastAudioTime = ui32TimeStamp;
} }
void Mp4Maker::_inputH264(void* pData, uint32_t ui32Length, uint32_t ui32Duration, int iType) { void Mp4Maker::inputH264_l(void *pData, uint32_t ui32Length, uint32_t ui32Duration) {
GET_CONFIG_AND_REGISTER(uint32_t,recordSec,Record::kFileSecond); GET_CONFIG_AND_REGISTER(uint32_t,recordSec,Record::kFileSecond);
if(iType == 5 && (_hMp4 == MP4_INVALID_FILE_HANDLE || _ticker.elapsedTime() > recordSec * 1000)){ auto iType = ((uint8_t*)pData)[0] & 0x1F;
if(iType == 5 && (_hMp4 == MP4_INVALID_FILE_HANDLE || _ticker.elapsedTime() > recordSec * 1000)){
//在I帧率处新建MP4文件 //在I帧率处新建MP4文件
//如果文件未创建或者文件超过10分钟则创建新文件 //如果文件未创建或者文件超过10分钟则创建新文件
createFile(); createFile();
...@@ -126,27 +124,21 @@ void Mp4Maker::_inputH264(void* pData, uint32_t ui32Length, uint32_t ui32Duratio ...@@ -126,27 +124,21 @@ void Mp4Maker::_inputH264(void* pData, uint32_t ui32Length, uint32_t ui32Duratio
} }
} }
void Mp4Maker::_inputAAC(void* pData, uint32_t ui32Length, uint32_t ui32Duration) { void Mp4Maker::inputAAC_l(void *pData, uint32_t ui32Length, uint32_t ui32Duration) {
GET_CONFIG_AND_REGISTER(uint32_t,recordSec,Record::kFileSecond); GET_CONFIG_AND_REGISTER(uint32_t,recordSec,Record::kFileSecond);
//todo(xzl) 修复此处 if (!_haveVideo && (_hMp4 == MP4_INVALID_FILE_HANDLE || _ticker.elapsedTime() > recordSec * 1000)) {
//在I帧率处新建MP4文件
// //如果文件未创建或者文件超过10分钟则创建新文件
// if (!_pPlayer->containVideo() && (_hMp4 == MP4_INVALID_FILE_HANDLE || _ticker.elapsedTime() > recordSec * 1000)) { createFile();
// //在I帧率处新建MP4文件 }
// //如果文件未创建或者文件超过10分钟则创建新文件 if (_hAudio != MP4_INVALID_TRACK_ID) {
// createFile(); auto duration = ui32Duration * _audioSampleRate /1000.0;
// } MP4WriteSample(_hMp4, _hAudio, (uint8_t*)pData, ui32Length,duration,0,false);
// if (_hAudio != MP4_INVALID_TRACK_ID) { }
// auto duration = ui32Duration * _pPlayer->getAudioSampleRate() /1000.0;
// MP4WriteSample(_hMp4, _hAudio, (uint8_t*)pData + 7, ui32Length - 7,duration,0,false);
// }
} }
void Mp4Maker::createFile() { void Mp4Maker::createFile() {
if(!_pPlayer->isInited()){
return;
}
closeFile(); closeFile();
auto strDate = timeStr("%Y-%m-%d"); auto strDate = timeStr("%Y-%m-%d");
...@@ -184,30 +176,38 @@ void Mp4Maker::createFile() { ...@@ -184,30 +176,38 @@ void Mp4Maker::createFile() {
_strFile = strFile; _strFile = strFile;
_ticker.resetTime(); _ticker.resetTime();
//todo(xzl) 修复此处 auto videoTrack = dynamic_pointer_cast<H264Track>(getTrack(TrackVideo));
if(videoTrack){
// if(_pPlayer->containVideo()){ auto &sps = videoTrack->getSps();
// auto &sps = _pPlayer->getSps(); auto &pps = videoTrack->getPps();
// auto &pps = _pPlayer->getPps(); _hVideo = MP4AddH264VideoTrack(_hMp4,
// _hVideo = MP4AddH264VideoTrack(_hMp4, 90000, MP4_INVALID_DURATION, 90000,
// _pPlayer->getVideoWidth(), _pPlayer->getVideoHeight(), MP4_INVALID_DURATION,
// sps[5], sps[6], sps[7], 3); videoTrack->getVideoWidth(),
// if(_hVideo !=MP4_INVALID_TRACK_ID){ videoTrack->getVideoHeight(),
// MP4AddH264SequenceParameterSet(_hMp4, _hVideo, (uint8_t *)sps.data() + 4, sps.size() - 4); sps[1],
// MP4AddH264PictureParameterSet(_hMp4, _hVideo, (uint8_t *)pps.data() + 4, pps.size() - 4); sps[2],
// }else{ sps[3],
// WarnL << "添加视频通道失败:" << strFileTmp; 3);
// } if(_hVideo != MP4_INVALID_TRACK_ID){
// } MP4AddH264SequenceParameterSet(_hMp4, _hVideo, (uint8_t *)sps.data(), sps.size());
// if(_pPlayer->containAudio()){ MP4AddH264PictureParameterSet(_hMp4, _hVideo, (uint8_t *)pps.data(), pps.size());
// _hAudio = MP4AddAudioTrack(_hMp4, _pPlayer->getAudioSampleRate(), MP4_INVALID_DURATION, MP4_MPEG4_AUDIO_TYPE); }else{
// if (_hAudio != MP4_INVALID_TRACK_ID) { WarnL << "添加视频通道失败:" << strFileTmp;
// auto &cfg = _pPlayer->getAudioCfg(); }
// MP4SetTrackESConfiguration(_hMp4, _hAudio,(uint8_t *)cfg.data(), cfg.size()); }
// }else{
// WarnL << "添加音频通道失败:" << strFileTmp; auto audioTrack = dynamic_pointer_cast<AACTrack>(getTrack(TrackAudio));
// } if(audioTrack){
// } _audioSampleRate = audioTrack->getAudioSampleRate();
_hAudio = MP4AddAudioTrack(_hMp4, _audioSampleRate, MP4_INVALID_DURATION, MP4_MPEG4_AUDIO_TYPE);
if (_hAudio != MP4_INVALID_TRACK_ID) {
auto &cfg = audioTrack->getAacCfg();
MP4SetTrackESConfiguration(_hMp4, _hAudio,(uint8_t *)cfg.data(), cfg.size());
}else{
WarnL << "添加音频通道失败:" << strFileTmp;
}
}
} }
void Mp4Maker::closeFile() { void Mp4Maker::closeFile() {
...@@ -232,6 +232,26 @@ void Mp4Maker::closeFile() { ...@@ -232,6 +232,26 @@ void Mp4Maker::closeFile() {
} }
} }
void Mp4Maker::onTrackFrame(const Frame::Ptr &frame) {
switch (frame->getCodecId()){
case CodecH264:{
inputH264(frame->data() + frame->prefixSize(), frame->size() - frame->prefixSize(),frame->stamp());
}
break;
case CodecAAC:{
inputAAC(frame->data() + frame->prefixSize(), frame->size() - frame->prefixSize(),frame->stamp());
}
break;
default:
break;
}
}
void Mp4Maker::onAllTrackReady() {
_haveVideo = getTrack(TrackVideo).operator bool();
}
} /* namespace mediakit */ } /* namespace mediakit */
......
...@@ -37,12 +37,14 @@ ...@@ -37,12 +37,14 @@
#include "Util/logger.h" #include "Util/logger.h"
#include "Util/TimeTicker.h" #include "Util/TimeTicker.h"
#include "Util/TimeTicker.h" #include "Util/TimeTicker.h"
#include "Common/MediaSink.h"
#include "Player/Track.h"
using namespace toolkit; using namespace toolkit;
namespace mediakit { namespace mediakit {
class Mp4Info class Mp4Info {
{
public: public:
time_t ui64StartedTime; //GMT标准时间,单位秒 time_t ui64StartedTime; //GMT标准时间,单位秒
time_t ui64TimeLen;//录像长度,单位秒 time_t ui64TimeLen;//录像长度,单位秒
...@@ -55,43 +57,54 @@ public: ...@@ -55,43 +57,54 @@ public:
string strStreamId;//流ID string strStreamId;//流ID
string strVhost;//vhost string strVhost;//vhost
}; };
class Mp4Maker { class Mp4Maker : public MediaSink{
public: public:
typedef std::shared_ptr<Mp4Maker> Ptr; typedef std::shared_ptr<Mp4Maker> Ptr;
Mp4Maker(const string &strPath, Mp4Maker(const string &strPath,
const string &strVhost , const string &strVhost ,
const string &strApp, const string &strApp,
const string &strStreamId, const string &strStreamId);
const PlayerBase::Ptr &pPlayer);
virtual ~Mp4Maker(); virtual ~Mp4Maker();
private:
/**
* 某Track输出frame,在onAllTrackReady触发后才会调用此方法
* @param frame
*/
void onTrackFrame(const Frame::Ptr &frame) override ;
/**
* 所有Track准备好了
*/
void onAllTrackReady() override;
private:
void createFile();
void closeFile();
//时间戳:参考频率1000 //时间戳:参考频率1000
void inputH264(void *pData, uint32_t ui32Length, uint32_t ui32TimeStamp, int iType); void inputH264(void *pData, uint32_t ui32Length, uint32_t ui32TimeStamp);
//时间戳:参考频率1000 //时间戳:参考频率1000
void inputAAC(void *pData, uint32_t ui32Length, uint32_t ui32TimeStamp); void inputAAC(void *pData, uint32_t ui32Length, uint32_t ui32TimeStamp);
void inputH264_l(void *pData, uint32_t ui32Length, uint32_t ui64Duration);
void inputAAC_l(void *pData, uint32_t ui32Length, uint32_t ui64Duration);
private: private:
MP4FileHandle _hMp4 = MP4_INVALID_FILE_HANDLE; MP4FileHandle _hMp4 = MP4_INVALID_FILE_HANDLE;
MP4TrackId _hVideo = MP4_INVALID_TRACK_ID; MP4TrackId _hVideo = MP4_INVALID_TRACK_ID;
MP4TrackId _hAudio = MP4_INVALID_TRACK_ID; MP4TrackId _hAudio = MP4_INVALID_TRACK_ID;
PlayerBase::Ptr _pPlayer;
string _strPath; string _strPath;
string _strFile; string _strFile;
string _strFileTmp; string _strFileTmp;
Ticker _ticker; Ticker _ticker;
SmoothTicker _mediaTicker[2];
void createFile();
void closeFile();
void _inputH264(void *pData, uint32_t ui32Length, uint32_t ui64Duration, int iType);
void _inputAAC(void *pData, uint32_t ui32Length, uint32_t ui64Duration);
string _strLastVideo; string _strLastVideo;
string _strLastAudio; string _strLastAudio;
uint32_t _ui32LastVideoTime = 0; uint32_t _ui32LastVideoTime = 0;
uint32_t _ui32LastAudioTime = 0; uint32_t _ui32LastAudioTime = 0;
int _iLastVideoType = 0;
Mp4Info _info; Mp4Info _info;
bool _haveVideo = false;
int _audioSampleRate;
}; };
} /* namespace mediakit */ } /* namespace mediakit */
......
...@@ -238,21 +238,29 @@ public: ...@@ -238,21 +238,29 @@ public:
case 5:{ case 5:{
//I //I
if(!_sps.empty()){ if(!_sps.empty()){
H264Frame::Ptr insertFrame = std::make_shared<H264Frame>(); if(!_spsFrame){
insertFrame->timeStamp = frame->stamp(); H264Frame::Ptr insertFrame = std::make_shared<H264Frame>();
insertFrame->type = 7; insertFrame->timeStamp = frame->stamp();
insertFrame->buffer = _sps; insertFrame->type = 7;
insertFrame->iPrefixSize = 0; insertFrame->buffer.assign("\x0\x0\x0\x1");
VideoTrack::inputFrame(insertFrame); insertFrame->buffer.append(_sps);
insertFrame->iPrefixSize = 4;
_spsFrame = insertFrame;
}
VideoTrack::inputFrame(_spsFrame);
} }
if(!_pps.empty()){ if(!_pps.empty()){
H264Frame::Ptr insertFrame = std::make_shared<H264Frame>(); if(!_ppsFrame){
insertFrame->timeStamp = frame->stamp(); H264Frame::Ptr insertFrame = std::make_shared<H264Frame>();
insertFrame->type = 8; insertFrame->timeStamp = frame->stamp();
insertFrame->buffer = _pps; insertFrame->type = 8;
insertFrame->iPrefixSize = 0; insertFrame->buffer.assign("\x0\x0\x0\x1");
VideoTrack::inputFrame(insertFrame); insertFrame->buffer.append(_pps);
insertFrame->iPrefixSize = 4;
_ppsFrame = insertFrame;
}
VideoTrack::inputFrame(_ppsFrame);
} }
VideoTrack::inputFrame(frame); VideoTrack::inputFrame(frame);
} }
...@@ -282,6 +290,8 @@ private: ...@@ -282,6 +290,8 @@ private:
int _width = 0; int _width = 0;
int _height = 0; int _height = 0;
float _fps = 0; float _fps = 0;
H264Frame::Ptr _spsFrame;
H264Frame::Ptr _ppsFrame;
}; };
/** /**
......
...@@ -61,7 +61,7 @@ public: ...@@ -61,7 +61,7 @@ public:
void onGetMetaData(const AMFValue &_metadata) override { void onGetMetaData(const AMFValue &_metadata) override {
try { try {
_pParser.reset(new RtmpDemuxer(_metadata)); _pParser.reset(new RtmpDemuxer(_metadata));
_pRecorder.reset(new MediaRecorder(getVhost(),getApp(),getId(),_pParser,_bEnableHls,_bEnableMp4)); _pRecorder.reset(new MediaRecorder(getVhost(),getApp(),getId(),_bEnableHls,_bEnableMp4));
//todo(xzl) 修复此处 //todo(xzl) 修复此处
// _pParser->setOnAudioCB(std::bind(&RtmpToRtspMediaSource::onGetAAC, this, placeholders::_1)); // _pParser->setOnAudioCB(std::bind(&RtmpToRtspMediaSource::onGetAAC, this, placeholders::_1));
......
...@@ -52,7 +52,7 @@ public: ...@@ -52,7 +52,7 @@ public:
RtspMediaSource::onGetSDP(strSdp); RtspMediaSource::onGetSDP(strSdp);
try { try {
_pParser.reset(new RtspDemuxer(_sdpAttr)); _pParser.reset(new RtspDemuxer(_sdpAttr));
_pRecorder.reset(new MediaRecorder(getVhost(),getApp(),getId(),_pParser,_bEnableHls,_bEnableMp4)); _pRecorder.reset(new MediaRecorder(getVhost(),getApp(),getId(),_bEnableHls,_bEnableMp4));
//todo(xzl) 修复此处 //todo(xzl) 修复此处
// _pParser->setOnAudioCB( std::bind(&RtspToRtmpMediaSource::onGetAAC, this, placeholders::_1)); // _pParser->setOnAudioCB( std::bind(&RtspToRtmpMediaSource::onGetAAC, this, placeholders::_1));
// _pParser->setOnVideoCB( std::bind(&RtspToRtmpMediaSource::onGetH264, this, placeholders::_1)); // _pParser->setOnVideoCB( std::bind(&RtspToRtmpMediaSource::onGetH264, this, placeholders::_1));
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论