统一成员变量命名风格

This commit is contained in:
xiongziliang
2018-10-24 15:43:52 +08:00
parent 97567ec36d
commit 39baaebc55
74 changed files with 2048 additions and 2048 deletions

View File

@@ -43,8 +43,8 @@ void FlvMuxer::start(const RtmpMediaSource::Ptr &media) {
}
void FlvMuxer::onWriteFlvHeader(const RtmpMediaSource::Ptr &mediaSrc) {
m_previousTagSize = 0;
CLEAR_ARR(m_aui32FirstStamp);
_previousTagSize = 0;
CLEAR_ARR(_aui32FirstStamp);
//发送flv文件头
char flv_file_header[] = "FLV\x1\x5\x0\x0\x0\x9"; // have audio and have video
@@ -118,7 +118,7 @@ private:
void FlvMuxer::onWriteFlvTag(const RtmpPacket::Ptr &pkt, uint32_t ui32TimeStamp) {
auto size = htonl(m_previousTagSize);
auto size = htonl(_previousTagSize);
onWrite((char *)&size,4);//onWrite PreviousTagSize
RtmpTagHeader header;
header.type = pkt->typeId;
@@ -127,11 +127,11 @@ void FlvMuxer::onWriteFlvTag(const RtmpPacket::Ptr &pkt, uint32_t ui32TimeStamp)
set_be24(header.timestamp,ui32TimeStamp & 0xFFFFFF);
onWrite((char *)&header, sizeof(header));//onWrite tag header
onWrite(std::make_shared<BufferRtmp>(pkt));//onWrite tag data
m_previousTagSize += (pkt->strBuf.size() + sizeof(header));
_previousTagSize += (pkt->strBuf.size() + sizeof(header));
}
void FlvMuxer::onWriteFlvTag(uint8_t ui8Type, const std::string &strBuf, uint32_t ui32TimeStamp) {
auto size = htonl(m_previousTagSize);
auto size = htonl(_previousTagSize);
onWrite((char *)&size,4);//onWrite PreviousTagSize
RtmpTagHeader header;
header.type = ui8Type;
@@ -140,12 +140,12 @@ void FlvMuxer::onWriteFlvTag(uint8_t ui8Type, const std::string &strBuf, uint32_
set_be24(header.timestamp,ui32TimeStamp & 0xFFFFFF);
onWrite((char *)&header, sizeof(header));//onWrite tag header
onWrite(std::make_shared<BufferString>(strBuf));//onWrite tag data
m_previousTagSize += (strBuf.size() + sizeof(header));
_previousTagSize += (strBuf.size() + sizeof(header));
}
void FlvMuxer::onWriteRtmp(const RtmpPacket::Ptr &pkt) {
auto modifiedStamp = pkt->timeStamp;
auto &firstStamp = m_aui32FirstStamp[pkt->typeId % 2];
auto &firstStamp = _aui32FirstStamp[pkt->typeId % 2];
if(!firstStamp){
firstStamp = modifiedStamp;
}
@@ -154,7 +154,7 @@ void FlvMuxer::onWriteRtmp(const RtmpPacket::Ptr &pkt) {
modifiedStamp -= firstStamp;
}else{
//发生回环,重新计算时间戳增量
CLEAR_ARR(m_aui32FirstStamp);
CLEAR_ARR(_aui32FirstStamp);
modifiedStamp = 0;
}
onWriteFlvTag(pkt, modifiedStamp);

View File

@@ -33,8 +33,8 @@ private:
void onWriteFlvTag(uint8_t ui8Type, const std::string &strBuf, uint32_t ui32TimeStamp);
private:
RtmpMediaSource::RingType::RingReader::Ptr _ring_reader;
uint32_t m_aui32FirstStamp[2] = {0};
uint32_t m_previousTagSize = 0;
uint32_t _aui32FirstStamp[2] = {0};
uint32_t _previousTagSize = 0;
};
class FlvRecorder : public FlvMuxer , public std::enable_shared_from_this<FlvRecorder>{

View File

@@ -60,66 +60,66 @@ public:
RtmpMediaSource(const string &vhost,const string &strApp, const string &strId) :
MediaSource(RTMP_SCHEMA,vhost,strApp,strId),
m_pRing(new RingBuffer<RtmpPacket::Ptr>()) {
_pRing(new RingBuffer<RtmpPacket::Ptr>()) {
}
virtual ~RtmpMediaSource() {}
const RingType::Ptr &getRing() const {
//获取媒体源的rtp环形缓冲
return m_pRing;
return _pRing;
}
const AMFValue &getMetaData() const {
lock_guard<recursive_mutex> lock(m_mtxMap);
return m_metadata;
lock_guard<recursive_mutex> lock(_mtxMap);
return _metadata;
}
template<typename FUN>
void getConfigFrame(const FUN &f) {
lock_guard<recursive_mutex> lock(m_mtxMap);
for (auto &pr : m_mapCfgFrame) {
lock_guard<recursive_mutex> lock(_mtxMap);
for (auto &pr : _mapCfgFrame) {
f(pr.second);
}
}
virtual void onGetMetaData(const AMFValue &_metadata) {
lock_guard<recursive_mutex> lock(m_mtxMap);
m_metadata = _metadata;
RtmpParser parser(_metadata);
m_iCfgFrameSize = parser.getTracks().size();
virtual void onGetMetaData(const AMFValue &metadata) {
lock_guard<recursive_mutex> lock(_mtxMap);
_metadata = metadata;
RtmpParser parser(metadata);
_iCfgFrameSize = parser.getTracks().size();
if(ready()){
MediaSource::regist();
m_bRegisted = true;
_bRegisted = true;
} else{
m_bAsyncRegist = true;
_bAsyncRegist = true;
}
}
virtual void onGetMedia(const RtmpPacket::Ptr &pkt) {
lock_guard<recursive_mutex> lock(m_mtxMap);
lock_guard<recursive_mutex> lock(_mtxMap);
if (pkt->isCfgFrame()) {
m_mapCfgFrame.emplace(pkt->typeId, pkt);
_mapCfgFrame.emplace(pkt->typeId, pkt);
if(m_bAsyncRegist && !m_bRegisted && m_mapCfgFrame.size() == m_iCfgFrameSize){
m_bAsyncRegist = false;
if(_bAsyncRegist && !_bRegisted && _mapCfgFrame.size() == _iCfgFrameSize){
_bAsyncRegist = false;
MediaSource::regist();
m_bRegisted = true;
_bRegisted = true;
}
}
m_pRing->write(pkt,pkt->isVideoKeyFrame());
_pRing->write(pkt,pkt->isVideoKeyFrame());
}
private:
bool ready(){
lock_guard<recursive_mutex> lock(m_mtxMap);
return m_iCfgFrameSize != -1 && m_iCfgFrameSize == m_mapCfgFrame.size();
lock_guard<recursive_mutex> lock(_mtxMap);
return _iCfgFrameSize != -1 && _iCfgFrameSize == _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环形缓冲
int m_iCfgFrameSize = -1;
bool m_bAsyncRegist = false;
bool m_bRegisted = false;
AMFValue _metadata;
unordered_map<int, RtmpPacket::Ptr> _mapCfgFrame;
mutable recursive_mutex _mtxMap;
RingBuffer<RtmpPacket::Ptr>::Ptr _pRing; //rtp环形缓冲
int _iCfgFrameSize = -1;
bool _bAsyncRegist = false;
bool _bRegisted = false;
};
} /* namespace Rtmp */

View File

@@ -36,13 +36,13 @@ RtmpParser::RtmpParser(const AMFValue &val) {
if (videoCodec.type() == AMF_STRING) {
if (videoCodec.as_string() == "avc1") {
//h264
m_iVideoCodecID = H264_CODEC_ID;
_iVideoCodecID = H264_CODEC_ID;
} else {
InfoL << "不支持RTMP视频格式:" << videoCodec.as_string();
}
}else if (videoCodec.type() != AMF_NULL){
m_iVideoCodecID = videoCodec.as_integer();
if (m_iVideoCodecID != H264_CODEC_ID) {
_iVideoCodecID = videoCodec.as_integer();
if (_iVideoCodecID != H264_CODEC_ID) {
InfoL << "不支持RTMP视频格式:" << videoCodec.as_integer();
}
}
@@ -50,13 +50,13 @@ RtmpParser::RtmpParser(const AMFValue &val) {
if (audioCodec.type() == AMF_STRING) {
if (audioCodec.as_string() == "mp4a") {
//aac
m_iAudioCodecID = AAC_CODEC_ID;
_iAudioCodecID = AAC_CODEC_ID;
} else {
InfoL << "不支持RTMP音频格式:" << audioCodec.as_string();
}
}else if (audioCodec.type() != AMF_NULL) {
m_iAudioCodecID = audioCodec.as_integer();
if (m_iAudioCodecID != AAC_CODEC_ID) {
_iAudioCodecID = audioCodec.as_integer();
if (_iAudioCodecID != AAC_CODEC_ID) {
InfoL << "不支持RTMP音频格式:" << audioCodec.as_integer();
}
}
@@ -69,28 +69,28 @@ RtmpParser::~RtmpParser() {
bool RtmpParser::inputRtmp(const RtmpPacket::Ptr &pkt) {
switch (pkt->typeId) {
case MSG_VIDEO:{
if(m_iVideoCodecID == 0){
if(_iVideoCodecID == 0){
//未初始化视频
m_iVideoCodecID = pkt->getMediaType();
if(m_iVideoCodecID != H264_CODEC_ID){
InfoL << "不支持RTMP视频格式:" << m_iVideoCodecID;
_iVideoCodecID = pkt->getMediaType();
if(_iVideoCodecID != H264_CODEC_ID){
InfoL << "不支持RTMP视频格式:" << _iVideoCodecID;
}
}
if(m_iVideoCodecID == H264_CODEC_ID){
if(_iVideoCodecID == H264_CODEC_ID){
return inputVideo(pkt);
}
return false;
}
case MSG_AUDIO: {
if(m_iAudioCodecID == 0){
if(_iAudioCodecID == 0){
//未初始化音频
m_iAudioCodecID = pkt->getMediaType();
if(m_iAudioCodecID != AAC_CODEC_ID){
InfoL << "不支持RTMP音频格式:" << m_iAudioCodecID;
_iAudioCodecID = pkt->getMediaType();
if(_iAudioCodecID != AAC_CODEC_ID){
InfoL << "不支持RTMP音频格式:" << _iAudioCodecID;
}
}
if (m_iAudioCodecID == AAC_CODEC_ID) {
if (_iAudioCodecID == AAC_CODEC_ID) {
return inputAudio(pkt);
}
return false;
@@ -104,20 +104,20 @@ bool RtmpParser::inputRtmp(const RtmpPacket::Ptr &pkt) {
inline bool RtmpParser::inputVideo(const RtmpPacket::Ptr &pkt) {
if (pkt->isCfgFrame()) {
//WarnL << " got h264 cfg";
if (m_strSPS.size()) {
if (_strSPS.size()) {
return false;
}
m_strSPS.assign("\x00\x00\x00\x01", 4);
m_strSPS.append(pkt->getH264SPS());
_strSPS.assign("\x00\x00\x00\x01", 4);
_strSPS.append(pkt->getH264SPS());
m_strPPS.assign("\x00\x00\x00\x01", 4);
m_strPPS.append(pkt->getH264PPS());
_strPPS.assign("\x00\x00\x00\x01", 4);
_strPPS.append(pkt->getH264PPS());
getAVCInfo(pkt->getH264SPS(), m_iVideoWidth, m_iVideoHeight, m_fVideoFps);
getAVCInfo(pkt->getH264SPS(), _iVideoWidth, _iVideoHeight, _fVideoFps);
return false;
}
if (m_strSPS.size()) {
if (_strSPS.size()) {
uint32_t iTotalLen = pkt->strBuf.size();
uint32_t iOffset = 5;
while(iOffset + 4 < iTotalLen){
@@ -137,8 +137,8 @@ inline bool RtmpParser::inputVideo(const RtmpPacket::Ptr &pkt) {
inline void RtmpParser::_onGetH264(const char* pcData, int iLen, uint32_t ui32TimeStamp) {
switch (pcData[0] & 0x1F) {
case 5: {
onGetH264(m_strSPS.data() + 4, m_strSPS.length() - 4, ui32TimeStamp);
onGetH264(m_strPPS.data() + 4, m_strPPS.length() - 4, ui32TimeStamp);
onGetH264(_strSPS.data() + 4, _strSPS.length() - 4, ui32TimeStamp);
onGetH264(_strPPS.data() + 4, _strPPS.length() - 4, ui32TimeStamp);
}
case 1: {
onGetH264(pcData, iLen, ui32TimeStamp);
@@ -150,82 +150,82 @@ inline void RtmpParser::_onGetH264(const char* pcData, int iLen, uint32_t ui32Ti
}
}
inline void RtmpParser::onGetH264(const char* pcData, int iLen, uint32_t ui32TimeStamp) {
m_h264frame.type = pcData[0] & 0x1F;
m_h264frame.timeStamp = ui32TimeStamp;
m_h264frame.buffer.assign("\x0\x0\x0\x1", 4); //添加264头
m_h264frame.buffer.append(pcData, iLen);
_h264frame.type = pcData[0] & 0x1F;
_h264frame.timeStamp = ui32TimeStamp;
_h264frame.buffer.assign("\x0\x0\x0\x1", 4); //添加264头
_h264frame.buffer.append(pcData, iLen);
{
lock_guard<recursive_mutex> lck(m_mtxCB);
lock_guard<recursive_mutex> lck(_mtxCB);
if (onVideo) {
onVideo(m_h264frame);
onVideo(_h264frame);
}
}
m_h264frame.buffer.clear();
_h264frame.buffer.clear();
}
inline bool RtmpParser::inputAudio(const RtmpPacket::Ptr &pkt) {
if (pkt->isCfgFrame()) {
if (m_strAudioCfg.size()) {
if (_strAudioCfg.size()) {
return false;
}
m_strAudioCfg = pkt->getAacCfg();
m_iSampleBit = pkt->getAudioSampleBit();
makeAdtsHeader(m_strAudioCfg,m_adts);
getAACInfo(m_adts, m_iSampleRate, m_iChannel);
_strAudioCfg = pkt->getAacCfg();
_iSampleBit = pkt->getAudioSampleBit();
makeAdtsHeader(_strAudioCfg,_adts);
getAACInfo(_adts, _iSampleRate, _iChannel);
return false;
}
if (m_strAudioCfg.size()) {
if (_strAudioCfg.size()) {
onGetAAC(pkt->strBuf.data() + 2, pkt->strBuf.size() - 2, pkt->timeStamp);
}
return false;
}
inline void RtmpParser::onGetAAC(const char* pcData, int iLen, uint32_t ui32TimeStamp) {
if(iLen + 7 > sizeof(m_adts.buffer)){
if(iLen + 7 > sizeof(_adts.buffer)){
WarnL << "Illegal adts data, exceeding the length limit.";
return;
}
//添加adts头
memcpy(m_adts.buffer + 7, pcData, iLen);
m_adts.aac_frame_length = 7 + iLen;
m_adts.timeStamp = ui32TimeStamp;
writeAdtsHeader(m_adts, m_adts.buffer);
memcpy(_adts.buffer + 7, pcData, iLen);
_adts.aac_frame_length = 7 + iLen;
_adts.timeStamp = ui32TimeStamp;
writeAdtsHeader(_adts, _adts.buffer);
{
lock_guard<recursive_mutex> lck(m_mtxCB);
lock_guard<recursive_mutex> lck(_mtxCB);
if (onAudio) {
onAudio(m_adts);
onAudio(_adts);
}
}
m_adts.aac_frame_length = 7;
_adts.aac_frame_length = 7;
}
inline void RtmpParser::onCheckMedia(const AMFValue& obj) {
obj.object_for_each([&](const string &key ,const AMFValue& val) {
if(key == "duration") {
m_fDuration = val.as_number();
_fDuration = val.as_number();
return;
}
if(key == "width") {
m_iVideoWidth = val.as_number();
_iVideoWidth = val.as_number();
return;
}
if(key == "height") {
m_iVideoHeight = val.as_number();
_iVideoHeight = val.as_number();
return;
}
if(key == "framerate") {
m_fVideoFps = val.as_number();
_fVideoFps = val.as_number();
return;
}
if(key == "audiosamplerate") {
m_iSampleRate = val.as_number();
_iSampleRate = val.as_number();
return;
}
if(key == "audiosamplesize") {
m_iSampleBit = val.as_number();
_iSampleBit = val.as_number();
return;
}
if(key == "stereo") {
m_iChannel = val.as_boolean() ? 2 :1;
_iChannel = val.as_boolean() ? 2 :1;
return;
}
});

View File

@@ -54,19 +54,19 @@ public:
bool inputRtmp(const RtmpPacket::Ptr &pkt);
bool isInited() const override{
if((m_iAudioCodecID | m_iVideoCodecID) == 0){
if((_iAudioCodecID | _iVideoCodecID) == 0){
//音视频codec_id都未获取到说明还未初始化成功
return false;
}
if((m_iAudioCodecID & m_iVideoCodecID) == 0 && m_ticker.elapsedTime() < 300){
if((_iAudioCodecID & _iVideoCodecID) == 0 && _ticker.elapsedTime() < 300){
//音视频codec_id有其一未获取到,且最少分析300ms才能断定没有音频或视频
return false;
}
if (m_iAudioCodecID && !m_strAudioCfg.size()) {
if (_iAudioCodecID && !_strAudioCfg.size()) {
//如果音频是aac但是还未获取aac config ,则未初始化成功
return false;
}
if (m_iVideoCodecID && !m_strSPS.size()) {
if (_iVideoCodecID && !_strSPS.size()) {
//如果视频是h264但是还未获取sps ,则未初始化成功
return false;
}
@@ -74,7 +74,7 @@ public:
return true;
}
float getDuration() const override{
return m_fDuration;
return _fDuration;
}
private:
inline void onCheckMedia(const AMFValue &obj);
@@ -86,28 +86,28 @@ private:
inline void onGetH264(const char *pcData, int iLen, uint32_t ui32TimeStamp);
inline void onGetAAC(const char *pcData, int iLen, uint32_t ui32TimeStamp);
//video
H264Frame m_h264frame;
H264Frame _h264frame;
//aduio
AACFrame m_adts;
AACFrame _adts;
int m_iSampleRate = 44100;
int m_iSampleBit = 16;
int m_iChannel = 1;
int _iSampleRate = 44100;
int _iSampleBit = 16;
int _iChannel = 1;
string m_strSPS;
string m_strPPS;
string m_strAudioCfg;
int m_iVideoWidth = 0;
int m_iVideoHeight = 0;
float m_fVideoFps = 0;
string _strSPS;
string _strPPS;
string _strAudioCfg;
int _iVideoWidth = 0;
int _iVideoHeight = 0;
float _fVideoFps = 0;
//音视频codec_id初始为0代表尚未获取到
int m_iAudioCodecID = 0;
int m_iVideoCodecID = 0;
float m_fDuration = 0;
mutable Ticker m_ticker;
int _iAudioCodecID = 0;
int _iVideoCodecID = 0;
float _fDuration = 0;
mutable Ticker _ticker;
function<void(const H264Frame &frame)> onVideo;
function<void(const AACFrame &frame)> onAudio;
recursive_mutex m_mtxCB;
recursive_mutex _mtxCB;
};

View File

@@ -53,24 +53,24 @@ RtmpPlayer::~RtmpPlayer() {
}
void RtmpPlayer::teardown() {
if (alive()) {
m_strApp.clear();
m_strStream.clear();
m_strTcUrl.clear();
_strApp.clear();
_strStream.clear();
_strTcUrl.clear();
{
lock_guard<recursive_mutex> lck(m_mtxOnResultCB);
m_mapOnResultCB.clear();
lock_guard<recursive_mutex> lck(_mtxOnResultCB);
_mapOnResultCB.clear();
}
{
lock_guard<recursive_mutex> lck(m_mtxOnStatusCB);
m_dqOnStatusCB.clear();
lock_guard<recursive_mutex> lck(_mtxOnStatusCB);
_dqOnStatusCB.clear();
}
m_pBeatTimer.reset();
m_pPlayTimer.reset();
m_pMediaTimer.reset();
m_fSeekTo = 0;
CLEAR_ARR(m_adFistStamp);
CLEAR_ARR(m_adNowStamp);
_pBeatTimer.reset();
_pPlayTimer.reset();
_pMediaTimer.reset();
_fSeekTo = 0;
CLEAR_ARR(_adFistStamp);
CLEAR_ARR(_adNowStamp);
reset();
shutdown();
}
@@ -78,15 +78,15 @@ void RtmpPlayer::teardown() {
void RtmpPlayer::play(const char* strUrl) {
teardown();
string strHost = FindField(strUrl, "://", "/");
m_strApp = FindField(strUrl, (strHost + "/").data(), "/");
m_strStream = FindField(strUrl, (strHost + "/" + m_strApp + "/").data(), NULL);
m_strTcUrl = string("rtmp://") + strHost + "/" + m_strApp;
_strApp = FindField(strUrl, (strHost + "/").data(), "/");
_strStream = FindField(strUrl, (strHost + "/" + _strApp + "/").data(), NULL);
_strTcUrl = string("rtmp://") + strHost + "/" + _strApp;
if (!m_strApp.size() || !m_strStream.size()) {
if (!_strApp.size() || !_strStream.size()) {
_onPlayResult(SockException(Err_other,"rtmp url非法"));
return;
}
DebugL << strHost << " " << m_strApp << " " << m_strStream;
DebugL << strHost << " " << _strApp << " " << _strStream;
auto iPort = atoi(FindField(strHost.c_str(), ":", NULL).c_str());
if (iPort <= 0) {
@@ -111,7 +111,7 @@ void RtmpPlayer::onConnect(const SockException &err){
}
weak_ptr<RtmpPlayer> weakSelf= dynamic_pointer_cast<RtmpPlayer>(shared_from_this());
m_pPlayTimer.reset( new Timer(10, [weakSelf]() {
_pPlayTimer.reset( new Timer(10, [weakSelf]() {
auto strongSelf=weakSelf.lock();
if(!strongSelf) {
return false;
@@ -145,8 +145,8 @@ void RtmpPlayer::pause(bool bPause) {
inline void RtmpPlayer::send_connect() {
AMFValue obj(AMF_OBJECT);
obj.set("app", m_strApp);
obj.set("tcUrl", m_strTcUrl);
obj.set("app", _strApp);
obj.set("tcUrl", _strTcUrl);
//未使用代理
obj.set("fpad", false);
//参考librtmp,什么作用?
@@ -177,14 +177,14 @@ inline void RtmpPlayer::send_createStream() {
addOnResultCB([this](AMFDecoder &dec){
//TraceL << "createStream result";
dec.load<AMFValue>();
m_ui32StreamId = dec.load<int>();
_ui32StreamId = dec.load<int>();
send_play();
});
}
inline void RtmpPlayer::send_play() {
AMFEncoder enc;
enc << "play" << ++m_iReqID << nullptr << m_strStream << (double)m_ui32StreamId;
enc << "play" << ++_iReqID << nullptr << _strStream << (double)_ui32StreamId;
sendRequest(MSG_CMD, enc.data());
auto fun = [this](AMFValue &val){
//TraceL << "play onStatus";
@@ -200,7 +200,7 @@ inline void RtmpPlayer::send_play() {
inline void RtmpPlayer::send_pause(bool bPause) {
AMFEncoder enc;
enc << "pause" << ++m_iReqID << nullptr << bPause;
enc << "pause" << ++_iReqID << nullptr << bPause;
sendRequest(MSG_CMD, enc.data());
auto fun = [this,bPause](AMFValue &val){
//TraceL << "pause onStatus";
@@ -211,21 +211,21 @@ inline void RtmpPlayer::send_pause(bool bPause) {
throw std::runtime_error(StrPrinter <<"pause 恢复播放失败:" << level << " " << code << endl);
}
}else{
m_bPaused = bPause;
_bPaused = bPause;
if(!bPause){
_onPlayResult(SockException(Err_success, "rtmp resum success"));
}else{
//暂停播放
m_pMediaTimer.reset();
_pMediaTimer.reset();
}
}
};
addOnStatusCB(fun);
m_pBeatTimer.reset();
_pBeatTimer.reset();
if(bPause){
weak_ptr<RtmpPlayer> weakSelf = dynamic_pointer_cast<RtmpPlayer>(shared_from_this());
m_pBeatTimer.reset(new Timer(3,[weakSelf](){
_pBeatTimer.reset(new Timer(3,[weakSelf](){
auto strongSelf = weakSelf.lock();
if (!strongSelf){
return false;
@@ -239,11 +239,11 @@ inline void RtmpPlayer::send_pause(bool bPause) {
void RtmpPlayer::onCmd_result(AMFDecoder &dec){
auto iReqId = dec.load<int>();
lock_guard<recursive_mutex> lck(m_mtxOnResultCB);
auto it = m_mapOnResultCB.find(iReqId);
if(it != m_mapOnResultCB.end()){
lock_guard<recursive_mutex> lck(_mtxOnResultCB);
auto it = _mapOnResultCB.find(iReqId);
if(it != _mapOnResultCB.end()){
it->second(dec);
m_mapOnResultCB.erase(it);
_mapOnResultCB.erase(it);
}else{
WarnL << "unhandled _result";
}
@@ -260,10 +260,10 @@ void RtmpPlayer::onCmd_onStatus(AMFDecoder &dec) {
throw std::runtime_error("onStatus:the result object was not found");
}
lock_guard<recursive_mutex> lck(m_mtxOnStatusCB);
if(m_dqOnStatusCB.size()){
m_dqOnStatusCB.front()(val);
m_dqOnStatusCB.pop_front();
lock_guard<recursive_mutex> lck(_mtxOnStatusCB);
if(_dqOnStatusCB.size()){
_dqOnStatusCB.front()(val);
_dqOnStatusCB.pop_front();
}else{
auto level = val["level"];
auto code = val["code"].as_string();
@@ -311,8 +311,8 @@ void RtmpPlayer::onRtmpChunk(RtmpPacket &chunkData) {
case MSG_AUDIO:
case MSG_VIDEO: {
auto idx = chunkData.typeId%2;
if (m_aNowStampTicker[idx].elapsedTime() > 500) {
m_adNowStamp[idx] = chunkData.timeStamp;
if (_aNowStampTicker[idx].elapsedTime() > 500) {
_adNowStamp[idx] = chunkData.timeStamp;
}
_onMediaData(std::make_shared<RtmpPacket>(chunkData));
}
@@ -326,27 +326,27 @@ void RtmpPlayer::onRtmpChunk(RtmpPacket &chunkData) {
float RtmpPlayer::getProgressTime() const{
double iTime[2] = {0,0};
for(auto i = 0 ;i < 2 ;i++){
iTime[i] = (m_adNowStamp[i] - m_adFistStamp[i]) / 1000.0;
iTime[i] = (_adNowStamp[i] - _adFistStamp[i]) / 1000.0;
}
return m_fSeekTo + MAX(iTime[0],iTime[1]);
return _fSeekTo + MAX(iTime[0],iTime[1]);
}
void RtmpPlayer::seekToTime(float fTime){
if (m_bPaused) {
if (_bPaused) {
pause(false);
}
AMFEncoder enc;
enc << "seek" << ++m_iReqID << nullptr << fTime * 1000.0;
enc << "seek" << ++_iReqID << nullptr << fTime * 1000.0;
sendRequest(MSG_CMD, enc.data());
addOnStatusCB([this,fTime](AMFValue &val) {
//TraceL << "seek result";
m_aNowStampTicker[0].resetTime();
m_aNowStampTicker[1].resetTime();
_aNowStampTicker[0].resetTime();
_aNowStampTicker[1].resetTime();
float iTimeInc = fTime - getProgressTime();
for(auto i = 0 ;i < 2 ;i++){
m_adFistStamp[i] = m_adNowStamp[i] + iTimeInc * 1000.0;
m_adNowStamp[i] = m_adFistStamp[i];
_adFistStamp[i] = _adNowStamp[i] + iTimeInc * 1000.0;
_adNowStamp[i] = _adFistStamp[i];
}
m_fSeekTo = fTime;
_fSeekTo = fTime;
});
}

View File

@@ -65,28 +65,28 @@ protected:
private:
void _onShutdown(const SockException &ex) {
WarnL << ex.getErrCode() << " " << ex.what();
m_pPlayTimer.reset();
m_pMediaTimer.reset();
m_pBeatTimer.reset();
_pPlayTimer.reset();
_pMediaTimer.reset();
_pBeatTimer.reset();
onShutdown(ex);
}
void _onMediaData(const RtmpPacket::Ptr &chunkData) {
m_mediaTicker.resetTime();
_mediaTicker.resetTime();
onMediaData(chunkData);
}
void _onPlayResult(const SockException &ex) {
WarnL << ex.getErrCode() << " " << ex.what();
m_pPlayTimer.reset();
m_pMediaTimer.reset();
_pPlayTimer.reset();
_pMediaTimer.reset();
if (!ex) {
m_mediaTicker.resetTime();
_mediaTicker.resetTime();
weak_ptr<RtmpPlayer> weakSelf = dynamic_pointer_cast<RtmpPlayer>(shared_from_this());
m_pMediaTimer.reset( new Timer(5, [weakSelf]() {
_pMediaTimer.reset( new Timer(5, [weakSelf]() {
auto strongSelf=weakSelf.lock();
if(!strongSelf) {
return false;
}
if(strongSelf->m_mediaTicker.elapsedTime()>10000) {
if(strongSelf->_mediaTicker.elapsedTime()>10000) {
//recv media timeout!
strongSelf->_onShutdown(SockException(Err_timeout,"recv rtmp timeout"));
strongSelf->teardown();
@@ -111,13 +111,13 @@ private:
template<typename FUN>
inline void addOnResultCB(const FUN &fun) {
lock_guard<recursive_mutex> lck(m_mtxOnResultCB);
m_mapOnResultCB.emplace(m_iReqID, fun);
lock_guard<recursive_mutex> lck(_mtxOnResultCB);
_mapOnResultCB.emplace(_iReqID, fun);
}
template<typename FUN>
inline void addOnStatusCB(const FUN &fun) {
lock_guard<recursive_mutex> lck(m_mtxOnStatusCB);
m_dqOnStatusCB.emplace_back(fun);
lock_guard<recursive_mutex> lck(_mtxOnStatusCB);
_dqOnStatusCB.emplace_back(fun);
}
void onCmd_result(AMFDecoder &dec);
@@ -129,31 +129,31 @@ private:
inline void send_play();
inline void send_pause(bool bPause);
string m_strApp;
string m_strStream;
string m_strTcUrl;
bool m_bPaused = false;
string _strApp;
string _strStream;
string _strTcUrl;
bool _bPaused = false;
unordered_map<int, function<void(AMFDecoder &dec)> > m_mapOnResultCB;
recursive_mutex m_mtxOnResultCB;
deque<function<void(AMFValue &dec)> > m_dqOnStatusCB;
recursive_mutex m_mtxOnStatusCB;
unordered_map<int, function<void(AMFDecoder &dec)> > _mapOnResultCB;
recursive_mutex _mtxOnResultCB;
deque<function<void(AMFValue &dec)> > _dqOnStatusCB;
recursive_mutex _mtxOnStatusCB;
typedef void (RtmpPlayer::*rtmpCMDHandle)(AMFDecoder &dec);
static unordered_map<string, rtmpCMDHandle> g_mapCmd;
//超时功能实现
Ticker m_mediaTicker;
std::shared_ptr<Timer> m_pMediaTimer;
std::shared_ptr<Timer> m_pPlayTimer;
Ticker _mediaTicker;
std::shared_ptr<Timer> _pMediaTimer;
std::shared_ptr<Timer> _pPlayTimer;
//心跳定时器
std::shared_ptr<Timer> m_pBeatTimer;
std::shared_ptr<Timer> _pBeatTimer;
//播放进度控制
float m_fSeekTo = 0;
double m_adFistStamp[2] = { 0, 0 };
double m_adNowStamp[2] = { 0, 0 };
Ticker m_aNowStampTicker[2];
float _fSeekTo = 0;
double _adFistStamp[2] = { 0, 0 };
double _adNowStamp[2] = { 0, 0 };
Ticker _aNowStampTicker[2];
};
} /* namespace Rtmp */

View File

@@ -63,32 +63,32 @@ public:
private:
//派生类回调函数
bool onCheckMeta(AMFValue &val) override {
m_pRtmpMediaSrc = dynamic_pointer_cast<RtmpMediaSource>(m_pMediaSrc);
if(m_pRtmpMediaSrc){
m_pRtmpMediaSrc->onGetMetaData(val);
_pRtmpMediaSrc = dynamic_pointer_cast<RtmpMediaSource>(_pMediaSrc);
if(_pRtmpMediaSrc){
_pRtmpMediaSrc->onGetMetaData(val);
}
try {
m_parser.reset(new RtmpParser(val));
_parser.reset(new RtmpParser(val));
//todo(xzl) 修复此处
// m_parser->setOnVideoCB(m_onGetVideoCB);
// m_parser->setOnAudioCB(m_onGetAudioCB);
// _parser->setOnVideoCB(_onGetVideoCB);
// _parser->setOnAudioCB(_onGetAudioCB);
return true;
} catch (std::exception &ex) {
WarnL << ex.what();
return m_pRtmpMediaSrc ? true : false;
return _pRtmpMediaSrc ? true : false;
}
}
void onMediaData(const RtmpPacket::Ptr &chunkData) override {
if(m_parser){
m_parser->inputRtmp(chunkData);
if(_parser){
_parser->inputRtmp(chunkData);
}
if(m_pRtmpMediaSrc){
m_pRtmpMediaSrc->onGetMedia(chunkData);
if(_pRtmpMediaSrc){
_pRtmpMediaSrc->onGetMedia(chunkData);
}
}
private:
RtmpMediaSource::Ptr m_pRtmpMediaSrc;
RtmpMediaSource::Ptr _pRtmpMediaSrc;
};

View File

@@ -76,7 +76,7 @@ namespace ZL {
namespace Rtmp {
RtmpProtocol::RtmpProtocol() {
m_nextHandle = [this](){
_nextHandle = [this](){
handle_C0C1();
};
}
@@ -85,25 +85,25 @@ RtmpProtocol::~RtmpProtocol() {
}
void RtmpProtocol::reset() {
////////////ChunkSize////////////
m_iChunkLenIn = DEFAULT_CHUNK_LEN;
m_iChunkLenOut = DEFAULT_CHUNK_LEN;
_iChunkLenIn = DEFAULT_CHUNK_LEN;
_iChunkLenOut = DEFAULT_CHUNK_LEN;
////////////Acknowledgement////////////
m_ui32ByteSent = 0;
m_ui32LastSent = 0;
m_ui32WinSize = 0;
_ui32ByteSent = 0;
_ui32LastSent = 0;
_ui32WinSize = 0;
///////////PeerBandwidth///////////
m_ui32Bandwidth = 2500000;
m_ui8LimitType = 2;
_ui32Bandwidth = 2500000;
_ui8LimitType = 2;
////////////Chunk////////////
m_mapChunkData.clear();
m_iNowStreamID = 0;
m_iNowChunkID = 0;
_mapChunkData.clear();
_iNowStreamID = 0;
_iNowChunkID = 0;
//////////Invoke Request//////////
m_iReqID = 0;
_iReqID = 0;
//////////Rtmp parser//////////
m_strRcvBuf.clear();
m_ui32StreamId = STREAM_CONTROL;
m_nextHandle = [this]() {
_strRcvBuf.clear();
_ui32StreamId = STREAM_CONTROL;
_nextHandle = [this]() {
handle_C0C1();
};
}
@@ -132,7 +132,7 @@ void RtmpProtocol::sendChunkSize(uint32_t ui32Size) {
uint32_t len = htonl(ui32Size);
std::string set_chunk((char *) &len, 4);
sendRequest(MSG_SET_CHUNK, set_chunk);
m_iChunkLenOut = ui32Size;
_iChunkLenOut = ui32Size;
}
void RtmpProtocol::sendPingRequest(uint32_t ui32TimeStamp) {
@@ -173,20 +173,20 @@ void RtmpProtocol::sendUserControl(uint16_t ui16EventType,
}
void RtmpProtocol::sendResponse(int iType, const string& str) {
if(!m_bDataStarted && (iType == MSG_DATA)){
m_bDataStarted = true;
if(!_bDataStarted && (iType == MSG_DATA)){
_bDataStarted = true;
}
sendRtmp(iType, m_iNowStreamID, str, 0, m_bDataStarted ? CHUNK_CLIENT_REQUEST_AFTER : CHUNK_CLIENT_REQUEST_BEFORE);
sendRtmp(iType, _iNowStreamID, str, 0, _bDataStarted ? CHUNK_CLIENT_REQUEST_AFTER : CHUNK_CLIENT_REQUEST_BEFORE);
}
void RtmpProtocol::sendInvoke(const string& strCmd, const AMFValue& val) {
AMFEncoder enc;
enc << strCmd << ++m_iReqID << val;
enc << strCmd << ++_iReqID << val;
sendRequest(MSG_CMD, enc.data());
}
void RtmpProtocol::sendRequest(int iCmd, const string& str) {
sendRtmp(iCmd, m_ui32StreamId, str, 0, CHUNK_SERVER_REQUEST);
sendRtmp(iCmd, _ui32StreamId, str, 0, CHUNK_SERVER_REQUEST);
}
void RtmpProtocol::sendRtmp(uint8_t ui8Type, uint32_t ui32StreamId,
@@ -205,7 +205,7 @@ void RtmpProtocol::sendRtmp(uint8_t ui8Type, uint32_t ui32StreamId,
set_le32(header.streamId, ui32StreamId);
//估算rtmp包数据大小
uint32_t capacity = ((bExtStamp ? 5 : 1) * (1 + (strBuf.size() / m_iChunkLenOut))) + strBuf.size() + sizeof(header);
uint32_t capacity = ((bExtStamp ? 5 : 1) * (1 + (strBuf.size() / _iChunkLenOut))) + strBuf.size() + sizeof(header);
uint32_t totalSize = 0;
BufferRaw::Ptr buffer = obtainBuffer();
buffer->setCapacity(capacity);
@@ -229,23 +229,23 @@ void RtmpProtocol::sendRtmp(uint8_t ui8Type, uint32_t ui32StreamId,
memcpy(buffer->data() + totalSize,acExtStamp, 4);
totalSize += 4;
}
size_t chunk = min(m_iChunkLenOut, strBuf.size() - pos);
size_t chunk = min(_iChunkLenOut, strBuf.size() - pos);
memcpy(buffer->data() + totalSize,strBuf.data() + pos, chunk);
totalSize += chunk;
pos += chunk;
}
buffer->setSize(totalSize);
onSendRawData(buffer);
m_ui32ByteSent += totalSize;
if (m_ui32WinSize > 0 && m_ui32ByteSent - m_ui32LastSent >= m_ui32WinSize) {
m_ui32LastSent = m_ui32ByteSent;
sendAcknowledgement(m_ui32ByteSent);
_ui32ByteSent += totalSize;
if (_ui32WinSize > 0 && _ui32ByteSent - _ui32LastSent >= _ui32WinSize) {
_ui32LastSent = _ui32ByteSent;
sendAcknowledgement(_ui32ByteSent);
}
}
void RtmpProtocol::onParseRtmp(const char *pcRawData, int iSize) {
m_strRcvBuf.append(pcRawData, iSize);
auto cb = m_nextHandle;
_strRcvBuf.append(pcRawData, iSize);
auto cb = _nextHandle;
cb();
}
@@ -256,25 +256,25 @@ void RtmpProtocol::startClientSession(const function<void()> &callBack) {
onSendRawData(obtainBuffer(&handshake_head, 1));
RtmpHandshake c1(0);
onSendRawData(obtainBuffer((char *) (&c1), sizeof(c1)));
m_nextHandle = [this,callBack]() {
_nextHandle = [this,callBack]() {
//等待 S0+S1+S2
handle_S0S1S2(callBack);
};
}
void RtmpProtocol::handle_S0S1S2(const function<void()> &callBack) {
if (m_strRcvBuf.size() < 1 + 2 * C1_HANDSHARK_SIZE) {
if (_strRcvBuf.size() < 1 + 2 * C1_HANDSHARK_SIZE) {
//数据不够
return;
}
if (m_strRcvBuf[0] != HANDSHAKE_PLAINTEXT) {
if (_strRcvBuf[0] != HANDSHAKE_PLAINTEXT) {
throw std::runtime_error("only plaintext[0x03] handshake supported");
}
//发送 C2
const char *pcC2 = m_strRcvBuf.data() + 1;
const char *pcC2 = _strRcvBuf.data() + 1;
onSendRawData(obtainBuffer(pcC2, C1_HANDSHARK_SIZE));
m_strRcvBuf.erase(0, 1 + 2 * C1_HANDSHARK_SIZE);
_strRcvBuf.erase(0, 1 + 2 * C1_HANDSHARK_SIZE);
//握手结束
m_nextHandle = [this]() {
_nextHandle = [this]() {
//握手结束并且开始进入解析命令模式
handle_rtmp();
};
@@ -282,14 +282,14 @@ void RtmpProtocol::handle_S0S1S2(const function<void()> &callBack) {
}
////for server ////
void RtmpProtocol::handle_C0C1() {
if (m_strRcvBuf.size() < 1 + C1_HANDSHARK_SIZE) {
if (_strRcvBuf.size() < 1 + C1_HANDSHARK_SIZE) {
//need more data!
return;
}
if (m_strRcvBuf[0] != HANDSHAKE_PLAINTEXT) {
if (_strRcvBuf[0] != HANDSHAKE_PLAINTEXT) {
throw std::runtime_error("only plaintext[0x03] handshake supported");
}
if(memcmp(m_strRcvBuf.c_str() + 5,"\x00\x00\x00\x00",4) ==0 ){
if(memcmp(_strRcvBuf.c_str() + 5,"\x00\x00\x00\x00",4) ==0 ){
//simple handsharke
handle_C1_simple();
}else{
@@ -301,7 +301,7 @@ void RtmpProtocol::handle_C0C1() {
handle_C1_simple();
#endif//ENABLE_OPENSSL
}
m_strRcvBuf.erase(0, 1 + C1_HANDSHARK_SIZE);
_strRcvBuf.erase(0, 1 + C1_HANDSHARK_SIZE);
}
void RtmpProtocol::handle_C1_simple(){
//发送S0
@@ -311,9 +311,9 @@ void RtmpProtocol::handle_C1_simple(){
RtmpHandshake s1(0);
onSendRawData(obtainBuffer((char *) &s1, C1_HANDSHARK_SIZE));
//发送S2
onSendRawData(obtainBuffer(m_strRcvBuf.c_str() + 1, C1_HANDSHARK_SIZE));
onSendRawData(obtainBuffer(_strRcvBuf.c_str() + 1, C1_HANDSHARK_SIZE));
//等待C2
m_nextHandle = [this]() {
_nextHandle = [this]() {
handle_C2();
};
}
@@ -321,7 +321,7 @@ void RtmpProtocol::handle_C1_simple(){
void RtmpProtocol::handle_C1_complex(){
//参考自:http://blog.csdn.net/win_lin/article/details/13006803
//skip c0,time,version
const char *c1_start = m_strRcvBuf.data() + 1;
const char *c1_start = _strRcvBuf.data() + 1;
const char *schema_start = c1_start + 8;
char *digest_start;
try{
@@ -470,57 +470,57 @@ void RtmpProtocol::send_complex_S0S1S2(int schemeType,const string &digest){
memcpy((char *)&s2 + C1_HANDSHARK_SIZE - C1_DIGEST_SIZE,s2_digest.data(),C1_DIGEST_SIZE);
onSendRawData(obtainBuffer((char *)&s2, sizeof(s2)));
//等待C2
m_nextHandle = [this]() {
_nextHandle = [this]() {
handle_C2();
};
}
#endif //ENABLE_OPENSSL
void RtmpProtocol::handle_C2() {
if (m_strRcvBuf.size() < C1_HANDSHARK_SIZE) {
if (_strRcvBuf.size() < C1_HANDSHARK_SIZE) {
//need more data!
return;
}
m_strRcvBuf.erase(0, C1_HANDSHARK_SIZE);
_strRcvBuf.erase(0, C1_HANDSHARK_SIZE);
//握手结束,进入命令模式
if (!m_strRcvBuf.empty()) {
if (!_strRcvBuf.empty()) {
handle_rtmp();
}
m_nextHandle = [this]() {
_nextHandle = [this]() {
handle_rtmp();
};
}
void RtmpProtocol::handle_rtmp() {
while (!m_strRcvBuf.empty()) {
uint8_t flags = m_strRcvBuf[0];
while (!_strRcvBuf.empty()) {
uint8_t flags = _strRcvBuf[0];
int iOffset = 0;
static const size_t HEADER_LENGTH[] = { 12, 8, 4, 1 };
size_t iHeaderLen = HEADER_LENGTH[flags >> 6];
m_iNowChunkID = flags & 0x3f;
if(m_iNowChunkID >10){
_iNowChunkID = flags & 0x3f;
if(_iNowChunkID >10){
int i=0;
i++;
}
switch (m_iNowChunkID) {
switch (_iNowChunkID) {
case 0: {
//0 值表示二字节形式,并且 ID 范围 64 - 319
//(第二个字节 + 64)。
if (m_strRcvBuf.size() < 2) {
if (_strRcvBuf.size() < 2) {
//need more data
return;
}
m_iNowChunkID = 64 + (uint8_t) (m_strRcvBuf[1]);
_iNowChunkID = 64 + (uint8_t) (_strRcvBuf[1]);
iOffset = 1;
}
break;
case 1: {
//1 值表示三字节形式,并且 ID 范围为 64 - 65599
//((第三个字节) * 256 + 第二个字节 + 64)。
if (m_strRcvBuf.size() < 3) {
if (_strRcvBuf.size() < 3) {
//need more data
return;
}
m_iNowChunkID = 64 + ((uint8_t) (m_strRcvBuf[2]) << 8) + (uint8_t) (m_strRcvBuf[1]);
_iNowChunkID = 64 + ((uint8_t) (_strRcvBuf[2]) << 8) + (uint8_t) (_strRcvBuf[1]);
iOffset = 2;
}
break;
@@ -529,13 +529,13 @@ void RtmpProtocol::handle_rtmp() {
break;
}
if (m_strRcvBuf.size() < iHeaderLen + iOffset) {
if (_strRcvBuf.size() < iHeaderLen + iOffset) {
//need more data
return;
}
RtmpHeader &header = *((RtmpHeader *) (m_strRcvBuf.data() + iOffset));
auto &chunkData = m_mapChunkData[m_iNowChunkID];
chunkData.chunkId = m_iNowChunkID;
RtmpHeader &header = *((RtmpHeader *) (_strRcvBuf.data() + iOffset));
auto &chunkData = _mapChunkData[_iNowChunkID];
chunkData.chunkId = _iNowChunkID;
switch (iHeaderLen) {
case 12:
chunkData.hasAbsStamp = true;
@@ -549,11 +549,11 @@ void RtmpProtocol::handle_rtmp() {
}
if (chunkData.hasExtStamp) {
if (m_strRcvBuf.size() < iHeaderLen + iOffset + 4) {
if (_strRcvBuf.size() < iHeaderLen + iOffset + 4) {
//need more data
return;
}
chunkData.deltaStamp = load_be32(m_strRcvBuf.data() + iOffset + iHeaderLen);
chunkData.deltaStamp = load_be32(_strRcvBuf.data() + iOffset + iHeaderLen);
iOffset += 4;
}
@@ -561,18 +561,18 @@ void RtmpProtocol::handle_rtmp() {
throw std::runtime_error("非法的bodySize");
}
auto iMore = min(m_iChunkLenIn, chunkData.bodySize - chunkData.strBuf.size());
if (m_strRcvBuf.size() < iHeaderLen + iOffset + iMore) {
auto iMore = min(_iChunkLenIn, chunkData.bodySize - chunkData.strBuf.size());
if (_strRcvBuf.size() < iHeaderLen + iOffset + iMore) {
//need more data
return;
}
chunkData.strBuf.append(m_strRcvBuf, iHeaderLen + iOffset, iMore);
m_strRcvBuf.erase(0, iHeaderLen + iOffset + iMore);
chunkData.strBuf.append(_strRcvBuf, iHeaderLen + iOffset, iMore);
_strRcvBuf.erase(0, iHeaderLen + iOffset + iMore);
if (chunkData.strBuf.size() == chunkData.bodySize) {
//frame is ready
m_iNowStreamID = chunkData.streamId;
_iNowStreamID = chunkData.streamId;
chunkData.timeStamp = chunkData.deltaStamp + (chunkData.hasAbsStamp ? 0 : chunkData.timeStamp);
if(chunkData.bodySize){
@@ -600,8 +600,8 @@ void RtmpProtocol::handle_rtmpChunk(RtmpPacket& chunkData) {
if (chunkData.strBuf.size() < 4) {
throw std::runtime_error("MSG_SET_CHUNK :Not enough data");
}
m_iChunkLenIn = load_be32(&chunkData.strBuf[0]);
TraceL << "MSG_SET_CHUNK:" << m_iChunkLenIn;
_iChunkLenIn = load_be32(&chunkData.strBuf[0]);
TraceL << "MSG_SET_CHUNK:" << _iChunkLenIn;
}
break;
case MSG_USER_CONTROL: {
@@ -668,14 +668,14 @@ void RtmpProtocol::handle_rtmpChunk(RtmpPacket& chunkData) {
break;
case MSG_WIN_SIZE: {
m_ui32WinSize = load_be32(&chunkData.strBuf[0]);
TraceL << "MSG_WIN_SIZE:" << m_ui32WinSize;
_ui32WinSize = load_be32(&chunkData.strBuf[0]);
TraceL << "MSG_WIN_SIZE:" << _ui32WinSize;
}
break;
case MSG_SET_PEER_BW: {
m_ui32Bandwidth = load_be32(&chunkData.strBuf[0]);
m_ui8LimitType = chunkData.strBuf[4];
TraceL << "MSG_SET_PEER_BW:" << m_ui32WinSize;
_ui32Bandwidth = load_be32(&chunkData.strBuf[0]);
_ui8LimitType = chunkData.strBuf[4];
TraceL << "MSG_SET_PEER_BW:" << _ui32WinSize;
}
break;
case MSG_AGGREGATE:

View File

@@ -57,7 +57,7 @@ protected:
virtual void onSendRawData(const Buffer::Ptr &buffer) = 0;
virtual void onRtmpChunk(RtmpPacket &chunkData) = 0;
virtual void onStreamBegin(uint32_t ui32StreamId){
m_ui32StreamId = ui32StreamId;
_ui32StreamId = ui32StreamId;
}
virtual void onStreamEof(uint32_t ui32StreamId){};
virtual void onStreamDry(uint32_t ui32StreamId){};
@@ -77,14 +77,14 @@ protected:
void sendResponse(int iType, const string &str);
void sendRtmp(uint8_t ui8Type, uint32_t ui32StreamId, const std::string &strBuf, uint32_t ui32TimeStamp, int iChunkID);
protected:
int m_iReqID = 0;
uint32_t m_ui32StreamId = STREAM_CONTROL;
int m_iNowStreamID = 0;
int m_iNowChunkID = 0;
bool m_bDataStarted = false;
int _iReqID = 0;
uint32_t _ui32StreamId = STREAM_CONTROL;
int _iNowStreamID = 0;
int _iNowChunkID = 0;
bool _bDataStarted = false;
inline BufferRaw::Ptr obtainBuffer();
inline BufferRaw::Ptr obtainBuffer(const void *data, int len);
//ResourcePool<BufferRaw,MAX_SEND_PKT> m_bufferPool;
//ResourcePool<BufferRaw,MAX_SEND_PKT> _bufferPool;
private:
void handle_S0S1S2(const function<void()> &cb);
void handle_C0C1();
@@ -103,20 +103,20 @@ private:
private:
////////////ChunkSize////////////
size_t m_iChunkLenIn = DEFAULT_CHUNK_LEN;
size_t m_iChunkLenOut = DEFAULT_CHUNK_LEN;
size_t _iChunkLenIn = DEFAULT_CHUNK_LEN;
size_t _iChunkLenOut = DEFAULT_CHUNK_LEN;
////////////Acknowledgement////////////
uint32_t m_ui32ByteSent = 0;
uint32_t m_ui32LastSent = 0;
uint32_t m_ui32WinSize = 0;
uint32_t _ui32ByteSent = 0;
uint32_t _ui32LastSent = 0;
uint32_t _ui32WinSize = 0;
///////////PeerBandwidth///////////
uint32_t m_ui32Bandwidth = 2500000;
uint8_t m_ui8LimitType = 2;
uint32_t _ui32Bandwidth = 2500000;
uint8_t _ui8LimitType = 2;
////////////Chunk////////////
unordered_map<int, RtmpPacket> m_mapChunkData;
unordered_map<int, RtmpPacket> _mapChunkData;
//////////Rtmp parser//////////
string m_strRcvBuf;
function<void()> m_nextHandle;
string _strRcvBuf;
function<void()> _nextHandle;
};
} /* namespace Rtmp */

View File

@@ -56,7 +56,7 @@ void RtmpPusher::init(const RtmpMediaSource::Ptr &src){
g_mapCmd.emplace("_result",&RtmpPusher::onCmd_result);
g_mapCmd.emplace("onStatus",&RtmpPusher::onCmd_onStatus);
}, []() {});
m_pMediaSrc=src;
_pMediaSrc=src;
}
RtmpPusher::~RtmpPusher() {
@@ -65,18 +65,18 @@ RtmpPusher::~RtmpPusher() {
}
void RtmpPusher::teardown() {
if (alive()) {
m_strApp.clear();
m_strStream.clear();
m_strTcUrl.clear();
_strApp.clear();
_strStream.clear();
_strTcUrl.clear();
{
lock_guard<recursive_mutex> lck(m_mtxOnResultCB);
m_mapOnResultCB.clear();
lock_guard<recursive_mutex> lck(_mtxOnResultCB);
_mapOnResultCB.clear();
}
{
lock_guard<recursive_mutex> lck(m_mtxOnStatusCB);
m_dqOnStatusCB.clear();
lock_guard<recursive_mutex> lck(_mtxOnStatusCB);
_dqOnStatusCB.clear();
}
m_pPublishTimer.reset();
_pPublishTimer.reset();
reset();
shutdown();
}
@@ -85,15 +85,15 @@ void RtmpPusher::teardown() {
void RtmpPusher::publish(const char* strUrl) {
teardown();
string strHost = FindField(strUrl, "://", "/");
m_strApp = FindField(strUrl, (strHost + "/").data(), "/");
m_strStream = FindField(strUrl, (strHost + "/" + m_strApp + "/").data(), NULL);
m_strTcUrl = string("rtmp://") + strHost + "/" + m_strApp;
_strApp = FindField(strUrl, (strHost + "/").data(), "/");
_strStream = FindField(strUrl, (strHost + "/" + _strApp + "/").data(), NULL);
_strTcUrl = string("rtmp://") + strHost + "/" + _strApp;
if (!m_strApp.size() || !m_strStream.size()) {
if (!_strApp.size() || !_strStream.size()) {
onPublishResult(SockException(Err_other,"rtmp url非法"));
return;
}
DebugL << strHost << " " << m_strApp << " " << m_strStream;
DebugL << strHost << " " << _strApp << " " << _strStream;
auto iPort = atoi(FindField(strHost.c_str(), ":", NULL).c_str());
if (iPort <= 0) {
@@ -115,7 +115,7 @@ void RtmpPusher::onConnect(const SockException &err){
return;
}
weak_ptr<RtmpPusher> weakSelf = dynamic_pointer_cast<RtmpPusher>(shared_from_this());
m_pPublishTimer.reset( new Timer(10, [weakSelf]() {
_pPublishTimer.reset( new Timer(10, [weakSelf]() {
auto strongSelf=weakSelf.lock();
if(!strongSelf) {
return false;
@@ -147,10 +147,10 @@ void RtmpPusher::onRecv(const Buffer::Ptr &pBuf){
inline void RtmpPusher::send_connect() {
AMFValue obj(AMF_OBJECT);
obj.set("app", m_strApp);
obj.set("app", _strApp);
obj.set("type", "nonprivate");
obj.set("tcUrl", m_strTcUrl);
obj.set("swfUrl", m_strTcUrl);
obj.set("tcUrl", _strTcUrl);
obj.set("swfUrl", _strTcUrl);
sendInvoke("connect", obj);
addOnResultCB([this](AMFDecoder &dec){
//TraceL << "connect result";
@@ -171,13 +171,13 @@ inline void RtmpPusher::send_createStream() {
addOnResultCB([this](AMFDecoder &dec){
//TraceL << "createStream result";
dec.load<AMFValue>();
m_ui32StreamId = dec.load<int>();
_ui32StreamId = dec.load<int>();
send_publish();
});
}
inline void RtmpPusher::send_publish() {
AMFEncoder enc;
enc << "publish" << ++m_iReqID << nullptr << m_strStream << m_strApp ;
enc << "publish" << ++_iReqID << nullptr << _strStream << _strApp ;
sendRequest(MSG_CMD, enc.data());
addOnStatusCB([this](AMFValue &val) {
@@ -192,7 +192,7 @@ inline void RtmpPusher::send_publish() {
}
inline void RtmpPusher::send_metaData(){
auto src = m_pMediaSrc.lock();
auto src = _pMediaSrc.lock();
if (!src) {
throw std::runtime_error("the media source was released");
}
@@ -202,19 +202,19 @@ inline void RtmpPusher::send_metaData(){
sendRequest(MSG_DATA, enc.data());
src->getConfigFrame([&](const RtmpPacket::Ptr &pkt){
sendRtmp(pkt->typeId, m_ui32StreamId, pkt->strBuf, pkt->timeStamp, pkt->chunkId );
sendRtmp(pkt->typeId, _ui32StreamId, pkt->strBuf, pkt->timeStamp, pkt->chunkId );
});
m_pRtmpReader = src->getRing()->attach();
_pRtmpReader = src->getRing()->attach();
weak_ptr<RtmpPusher> weakSelf = dynamic_pointer_cast<RtmpPusher>(shared_from_this());
m_pRtmpReader->setReadCB([weakSelf](const RtmpPacket::Ptr &pkt){
_pRtmpReader->setReadCB([weakSelf](const RtmpPacket::Ptr &pkt){
auto strongSelf = weakSelf.lock();
if(!strongSelf) {
return;
}
strongSelf->sendRtmp(pkt->typeId, strongSelf->m_ui32StreamId, pkt->strBuf, pkt->timeStamp, pkt->chunkId);
strongSelf->sendRtmp(pkt->typeId, strongSelf->_ui32StreamId, pkt->strBuf, pkt->timeStamp, pkt->chunkId);
});
m_pRtmpReader->setDetachCB([weakSelf](){
_pRtmpReader->setDetachCB([weakSelf](){
auto strongSelf = weakSelf.lock();
if(strongSelf){
strongSelf->onShutdown(SockException(Err_other,"媒体源被释放"));
@@ -228,11 +228,11 @@ inline void RtmpPusher::send_metaData(){
}
void RtmpPusher::onCmd_result(AMFDecoder &dec){
auto iReqId = dec.load<int>();
lock_guard<recursive_mutex> lck(m_mtxOnResultCB);
auto it = m_mapOnResultCB.find(iReqId);
if(it != m_mapOnResultCB.end()){
lock_guard<recursive_mutex> lck(_mtxOnResultCB);
auto it = _mapOnResultCB.find(iReqId);
if(it != _mapOnResultCB.end()){
it->second(dec);
m_mapOnResultCB.erase(it);
_mapOnResultCB.erase(it);
}else{
WarnL << "unhandled _result";
}
@@ -249,10 +249,10 @@ void RtmpPusher::onCmd_onStatus(AMFDecoder &dec) {
throw std::runtime_error("onStatus:the result object was not found");
}
lock_guard<recursive_mutex> lck(m_mtxOnStatusCB);
if(m_dqOnStatusCB.size()){
m_dqOnStatusCB.front()(val);
m_dqOnStatusCB.pop_front();
lock_guard<recursive_mutex> lck(_mtxOnStatusCB);
if(_dqOnStatusCB.size()){
_dqOnStatusCB.front()(val);
_dqOnStatusCB.pop_front();
}else{
auto level = val["level"];
auto code = val["code"].as_string();

View File

@@ -46,11 +46,11 @@ public:
void teardown();
void setOnPublished(Event onPublished) {
m_onPublished = onPublished;
_onPublished = onPublished;
}
void setOnShutdown(Event onShutdown) {
m_onShutdown = onShutdown;
_onShutdown = onShutdown;
}
protected:
@@ -67,28 +67,28 @@ protected:
private:
void init(const RtmpMediaSource::Ptr &src);
void onShutdown(const SockException &ex) {
m_pPublishTimer.reset();
if(m_onShutdown){
m_onShutdown(ex);
_pPublishTimer.reset();
if(_onShutdown){
_onShutdown(ex);
}
m_pRtmpReader.reset();
_pRtmpReader.reset();
}
void onPublishResult(const SockException &ex) {
m_pPublishTimer.reset();
if(m_onPublished){
m_onPublished(ex);
_pPublishTimer.reset();
if(_onPublished){
_onPublished(ex);
}
}
template<typename FUN>
inline void addOnResultCB(const FUN &fun) {
lock_guard<recursive_mutex> lck(m_mtxOnResultCB);
m_mapOnResultCB.emplace(m_iReqID, fun);
lock_guard<recursive_mutex> lck(_mtxOnResultCB);
_mapOnResultCB.emplace(_iReqID, fun);
}
template<typename FUN>
inline void addOnStatusCB(const FUN &fun) {
lock_guard<recursive_mutex> lck(m_mtxOnStatusCB);
m_dqOnStatusCB.emplace_back(fun);
lock_guard<recursive_mutex> lck(_mtxOnStatusCB);
_dqOnStatusCB.emplace_back(fun);
}
void onCmd_result(AMFDecoder &dec);
@@ -100,27 +100,27 @@ private:
inline void send_publish();
inline void send_metaData();
string m_strApp;
string m_strStream;
string m_strTcUrl;
string _strApp;
string _strStream;
string _strTcUrl;
unordered_map<int, function<void(AMFDecoder &dec)> > m_mapOnResultCB;
recursive_mutex m_mtxOnResultCB;
deque<function<void(AMFValue &dec)> > m_dqOnStatusCB;
recursive_mutex m_mtxOnStatusCB;
unordered_map<int, function<void(AMFDecoder &dec)> > _mapOnResultCB;
recursive_mutex _mtxOnResultCB;
deque<function<void(AMFValue &dec)> > _dqOnStatusCB;
recursive_mutex _mtxOnStatusCB;
typedef void (RtmpPusher::*rtmpCMDHandle)(AMFDecoder &dec);
static unordered_map<string, rtmpCMDHandle> g_mapCmd;
//超时功能实现
std::shared_ptr<Timer> m_pPublishTimer;
std::shared_ptr<Timer> _pPublishTimer;
//源
std::weak_ptr<RtmpMediaSource> m_pMediaSrc;
RtmpMediaSource::RingType::RingReader::Ptr m_pRtmpReader;
std::weak_ptr<RtmpMediaSource> _pMediaSrc;
RtmpMediaSource::RingType::RingReader::Ptr _pRtmpReader;
//事件监听
Event m_onShutdown;
Event m_onPublished;
Event _onShutdown;
Event _onPublished;
};
} /* namespace Rtmp */

View File

@@ -45,9 +45,9 @@ RtmpSession::RtmpSession(const std::shared_ptr<ThreadPool> &pTh, const Socket::P
RtmpSession::~RtmpSession() {
DebugL << get_peer_ip();
if(m_delayTask){
m_delayTask();
m_delayTask = nullptr;
if(_delayTask){
_delayTask();
_delayTask = nullptr;
}
}
@@ -57,41 +57,41 @@ void RtmpSession::onError(const SockException& err) {
//流量统计事件广播
GET_CONFIG_AND_REGISTER(uint32_t,iFlowThreshold,Broadcast::kFlowThreshold);
if(m_ui64TotalBytes > iFlowThreshold * 1024){
if(_ui64TotalBytes > iFlowThreshold * 1024){
NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastFlowReport,
m_mediaInfo,
m_ui64TotalBytes,
m_ticker.createdTime()/1000,
_mediaInfo,
_ui64TotalBytes,
_ticker.createdTime()/1000,
*this);
}
}
void RtmpSession::onManager() {
if (m_ticker.createdTime() > 15 * 1000) {
if (!m_pRingReader && !m_pPublisherSrc) {
if (_ticker.createdTime() > 15 * 1000) {
if (!_pRingReader && !_pPublisherSrc) {
WarnL << "非法链接:" << get_peer_ip();
shutdown();
}
}
if (m_pPublisherSrc) {
if (_pPublisherSrc) {
//publisher
if (m_ticker.elapsedTime() > 15 * 1000) {
if (_ticker.elapsedTime() > 15 * 1000) {
WarnL << "数据接收超时:" << get_peer_ip();
shutdown();
}
}
if(m_delayTask){
if(time(NULL) > m_iTaskTimeLine){
m_delayTask();
m_delayTask = nullptr;
if(_delayTask){
if(time(NULL) > _iTaskTimeLine){
_delayTask();
_delayTask = nullptr;
}
}
}
void RtmpSession::onRecv(const Buffer::Ptr &pBuf) {
m_ticker.resetTime();
_ticker.resetTime();
try {
m_ui64TotalBytes += pBuf->size();
_ui64TotalBytes += pBuf->size();
onParseRtmp(pBuf->data(), pBuf->size());
} catch (exception &e) {
WarnL << e.what();
@@ -113,11 +113,11 @@ void RtmpSession::onCmd_connect(AMFDecoder &dec) {
///////////set peerBandwidth////////////////
sendPeerBandwidth(5000000);
m_mediaInfo.m_app = params["app"].as_string();
m_strTcUrl = params["tcUrl"].as_string();
if(m_strTcUrl.empty()){
_mediaInfo._app = params["app"].as_string();
_strTcUrl = params["tcUrl"].as_string();
if(_strTcUrl.empty()){
//defaultVhost:默认vhost
m_strTcUrl = string(RTMP_SCHEMA) + "://" + DEFAULT_VHOST + "/" + m_mediaInfo.m_app;
_strTcUrl = string(RTMP_SCHEMA) + "://" + DEFAULT_VHOST + "/" + _mediaInfo._app;
}
bool ok = true; //(app == APP_NAME);
AMFValue version(AMF_OBJECT);
@@ -130,7 +130,7 @@ void RtmpSession::onCmd_connect(AMFDecoder &dec) {
status.set("objectEncoding", amfVer);
sendReply(ok ? "_result" : "_error", version, status);
if (!ok) {
throw std::runtime_error("Unsupported application: " + m_mediaInfo.m_app);
throw std::runtime_error("Unsupported application: " + _mediaInfo._app);
}
AMFEncoder invoke;
@@ -148,16 +148,16 @@ void RtmpSession::onCmd_publish(AMFDecoder &dec) {
DebugL << "publish 回复时间:" << pTicker->elapsedTime() << "ms";
}));
dec.load<AMFValue>();/* NULL */
m_mediaInfo.parse(m_strTcUrl + "/" + dec.load<std::string>());
_mediaInfo.parse(_strTcUrl + "/" + dec.load<std::string>());
auto onRes = [this,pToken](const string &err){
auto src = dynamic_pointer_cast<RtmpMediaSource>(MediaSource::find(RTMP_SCHEMA,
m_mediaInfo.m_vhost,
m_mediaInfo.m_app,
m_mediaInfo.m_streamid,
_mediaInfo._vhost,
_mediaInfo._app,
_mediaInfo._streamid,
false));
bool authSuccess = err.empty();
bool ok = (!src && !m_pPublisherSrc && authSuccess);
bool ok = (!src && !_pPublisherSrc && authSuccess);
AMFValue status(AMF_OBJECT);
status.set("level", ok ? "status" : "error");
status.set("code", ok ? "NetStream.Publish.Start" : (authSuccess ? "NetStream.Publish.BadName" : "NetStream.Publish.BadAuth"));
@@ -167,14 +167,14 @@ void RtmpSession::onCmd_publish(AMFDecoder &dec) {
if (!ok) {
WarnL << "onPublish:"
<< (authSuccess ? "Already publishing:" : err.data()) << " "
<< m_mediaInfo.m_vhost << " "
<< m_mediaInfo.m_app << " "
<< m_mediaInfo.m_streamid << endl;
<< _mediaInfo._vhost << " "
<< _mediaInfo._app << " "
<< _mediaInfo._streamid << endl;
shutdown();
return;
}
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()));
_pPublisherSrc.reset(new RtmpToRtspMediaSource(_mediaInfo._vhost,_mediaInfo._app,_mediaInfo._streamid));
_pPublisherSrc->setListener(dynamic_pointer_cast<MediaSourceEvent>(shared_from_this()));
};
weak_ptr<RtmpSession> weakSelf = dynamic_pointer_cast<RtmpSession>(shared_from_this());
@@ -192,7 +192,7 @@ void RtmpSession::onCmd_publish(AMFDecoder &dec) {
});
};
auto flag = NoticeCenter::Instance().emitEvent(Config::Broadcast::kBroadcastRtmpPublish,
m_mediaInfo,
_mediaInfo,
invoker,
*this);
if(!flag){
@@ -213,9 +213,9 @@ void RtmpSession::onCmd_deleteStream(AMFDecoder &dec) {
void RtmpSession::doPlayResponse(const string &err,bool tryDelay,const std::shared_ptr<onceToken> &pToken) {
//获取流对象
auto src = dynamic_pointer_cast<RtmpMediaSource>(MediaSource::find(RTMP_SCHEMA,
m_mediaInfo.m_vhost,
m_mediaInfo.m_app,
m_mediaInfo.m_streamid,
_mediaInfo._vhost,
_mediaInfo._app,
_mediaInfo._streamid,
true));
//是否鉴权成功
bool authSuccess = err.empty();
@@ -223,17 +223,17 @@ void RtmpSession::doPlayResponse(const string &err,bool tryDelay,const std::shar
//校验成功,但是流不存在而导致的不能播放
//所以我们注册rtmp注册事件等rtmp推流端推流成功后再告知播放器开始播放
auto task_id = this;
auto media_info = m_mediaInfo;
auto media_info = _mediaInfo;
weak_ptr<RtmpSession> weakSelf = dynamic_pointer_cast<RtmpSession>(shared_from_this());
NoticeCenter::Instance().addListener(task_id,Broadcast::kBroadcastMediaChanged,
[task_id,weakSelf,media_info,pToken](BroadcastMediaChangedArgs){
if(bRegist &&
schema == media_info.m_schema &&
vhost == media_info.m_vhost &&
app == media_info.m_app &&
stream == media_info.m_streamid){
schema == media_info._schema &&
vhost == media_info._vhost &&
app == media_info._app &&
stream == media_info._streamid){
//播发器请求的rtmp流终于注册上了
auto strongSelf = weakSelf.lock();
if(!strongSelf) {
@@ -249,7 +249,7 @@ void RtmpSession::doPlayResponse(const string &err,bool tryDelay,const std::shar
if(!strongSelf) {
return;
}
DebugL << "收到rtmp注册事件,回复播放器:" << media_info.m_schema << "/" << media_info.m_vhost << "/" << media_info.m_app << "/" << media_info.m_streamid;
DebugL << "收到rtmp注册事件,回复播放器:" << media_info._schema << "/" << media_info._vhost << "/" << media_info._app << "/" << media_info._streamid;
//回复播放器
strongSelf->doPlayResponse("",false,pToken);
//取消延时任务,防止多次回复
@@ -291,15 +291,15 @@ void RtmpSession::doPlayResponse(const string &err,bool tryDelay,const std::shar
status.set("level", ok ? "status" : "error");
status.set("code", ok ? "NetStream.Play.Reset" : (authSuccess ? "NetStream.Play.StreamNotFound" : "NetStream.Play.BadAuth"));
status.set("description", ok ? "Resetting and playing." : (authSuccess ? "No such stream." : err.data()));
status.set("details", m_mediaInfo.m_streamid);
status.set("details", _mediaInfo._streamid);
status.set("clientid", "0");
sendReply("onStatus", nullptr, status);
if (!ok) {
WarnL << "onPlayed:"
<< (authSuccess ? "No such stream:" : err.data()) << " "
<< m_mediaInfo.m_vhost << " "
<< m_mediaInfo.m_app << " "
<< m_mediaInfo.m_streamid
<< _mediaInfo._vhost << " "
<< _mediaInfo._app << " "
<< _mediaInfo._streamid
<< endl;
shutdown();
return;
@@ -310,7 +310,7 @@ void RtmpSession::doPlayResponse(const string &err,bool tryDelay,const std::shar
status.set("level", "status");
status.set("code", "NetStream.Play.Start");
status.set("description", "Started playing.");
status.set("details", m_mediaInfo.m_streamid);
status.set("details", _mediaInfo._streamid);
status.set("clientid", "0");
sendReply("onStatus", nullptr, status);
@@ -331,7 +331,7 @@ void RtmpSession::doPlayResponse(const string &err,bool tryDelay,const std::shar
status.set("level", "status");
status.set("code", "NetStream.Play.PublishNotify");
status.set("description", "Now published.");
status.set("details", m_mediaInfo.m_streamid);
status.set("details", _mediaInfo._streamid);
status.set("clientid", "0");
sendReply("onStatus", nullptr, status);
@@ -345,10 +345,10 @@ void RtmpSession::doPlayResponse(const string &err,bool tryDelay,const std::shar
onSendMedia(pkt);
});
m_pRingReader = src->getRing()->attach();
_pRingReader = src->getRing()->attach();
weak_ptr<RtmpSession> weakSelf = dynamic_pointer_cast<RtmpSession>(shared_from_this());
SockUtil::setNoDelay(_sock->rawFD(), false);
m_pRingReader->setReadCB([weakSelf](const RtmpPacket::Ptr &pkt) {
_pRingReader->setReadCB([weakSelf](const RtmpPacket::Ptr &pkt) {
auto strongSelf = weakSelf.lock();
if (!strongSelf) {
return;
@@ -361,14 +361,14 @@ void RtmpSession::doPlayResponse(const string &err,bool tryDelay,const std::shar
strongSelf->onSendMedia(pkt);
});
});
m_pRingReader->setDetachCB([weakSelf]() {
_pRingReader->setDetachCB([weakSelf]() {
auto strongSelf = weakSelf.lock();
if (!strongSelf) {
return;
}
strongSelf->safeShutdown();
});
m_pPlayerSrc = src;
_pPlayerSrc = src;
if (src->getRing()->readerCount() == 1) {
src->seekTo(0);
}
@@ -397,7 +397,7 @@ void RtmpSession::doPlay(AMFDecoder &dec){
strongSelf->doPlayResponse(err,true,pToken);
});
};
auto flag = NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastMediaPlayed,m_mediaInfo,invoker,*this);
auto flag = NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastMediaPlayed,_mediaInfo,invoker,*this);
if(!flag){
//该事件无人监听,默认不鉴权
doPlayResponse("",true,pToken);
@@ -408,7 +408,7 @@ void RtmpSession::onCmd_play2(AMFDecoder &dec) {
}
void RtmpSession::onCmd_play(AMFDecoder &dec) {
dec.load<AMFValue>();/* NULL */
m_mediaInfo.parse(m_strTcUrl + "/" + dec.load<std::string>());
_mediaInfo.parse(_strTcUrl + "/" + dec.load<std::string>());
doPlay(dec);
}
@@ -424,14 +424,14 @@ void RtmpSession::onCmd_pause(AMFDecoder &dec) {
//streamBegin
sendUserControl(paused ? CONTROL_STREAM_EOF : CONTROL_STREAM_BEGIN,
STREAM_MEDIA);
if (!m_pRingReader) {
if (!_pRingReader) {
throw std::runtime_error("Rtmp not started yet!");
}
if (paused) {
m_pRingReader->setReadCB(nullptr);
_pRingReader->setReadCB(nullptr);
} else {
weak_ptr<RtmpSession> weakSelf = dynamic_pointer_cast<RtmpSession>(shared_from_this());
m_pRingReader->setReadCB([weakSelf](const RtmpPacket::Ptr &pkt) {
_pRingReader->setReadCB([weakSelf](const RtmpPacket::Ptr &pkt) {
auto strongSelf = weakSelf.lock();
if(!strongSelf) {
return;
@@ -448,14 +448,14 @@ void RtmpSession::onCmd_pause(AMFDecoder &dec) {
}
void RtmpSession::setMetaData(AMFDecoder &dec) {
if (!m_pPublisherSrc) {
if (!_pPublisherSrc) {
throw std::runtime_error("not a publisher");
}
std::string type = dec.load<std::string>();
if (type != "onMetaData") {
throw std::runtime_error("can only set metadata");
}
m_pPublisherSrc->onGetMetaData(dec.load<AMFValue>());
_pPublisherSrc->onGetMetaData(dec.load<AMFValue>());
}
void RtmpSession::onProcessCmd(AMFDecoder &dec) {
@@ -477,7 +477,7 @@ void RtmpSession::onProcessCmd(AMFDecoder &dec) {
TraceL << "can not support cmd:" << method;
return;
}
m_dNowReqID = dec.load<double>();
_dNowReqID = dec.load<double>();
auto fun = it->second;
(this->*fun)(dec);
}
@@ -503,14 +503,14 @@ void RtmpSession::onRtmpChunk(RtmpPacket &chunkData) {
break;
case MSG_AUDIO:
case MSG_VIDEO: {
if (!m_pPublisherSrc) {
if (!_pPublisherSrc) {
throw std::runtime_error("Not a rtmp publisher!");
}
GET_CONFIG_AND_REGISTER(bool,rtmp_modify_stamp,Config::Rtmp::kModifyStamp);
if(rtmp_modify_stamp){
chunkData.timeStamp = m_stampTicker[chunkData.typeId % 2].elapsedTime();
chunkData.timeStamp = _stampTicker[chunkData.typeId % 2].elapsedTime();
}
m_pPublisherSrc->onGetMedia(std::make_shared<RtmpPacket>(chunkData));
_pPublisherSrc->onGetMedia(std::make_shared<RtmpPacket>(chunkData));
}
break;
default:
@@ -523,7 +523,7 @@ void RtmpSession::onCmd_seek(AMFDecoder &dec) {
dec.load<AMFValue>();/* NULL */
auto milliSeconds = dec.load<AMFValue>().as_number();
InfoL << "rtmp seekTo:" << milliSeconds/1000.0;
auto stongSrc = m_pPlayerSrc.lock();
auto stongSrc = _pPlayerSrc.lock();
if (stongSrc) {
stongSrc->seekTo(milliSeconds);
}
@@ -537,7 +537,7 @@ void RtmpSession::onCmd_seek(AMFDecoder &dec) {
void RtmpSession::onSendMedia(const RtmpPacket::Ptr &pkt) {
auto modifiedStamp = pkt->timeStamp;
auto &firstStamp = m_aui32FirstStamp[pkt->typeId % 2];
auto &firstStamp = _aui32FirstStamp[pkt->typeId % 2];
if(!firstStamp){
firstStamp = modifiedStamp;
}
@@ -546,22 +546,22 @@ void RtmpSession::onSendMedia(const RtmpPacket::Ptr &pkt) {
modifiedStamp -= firstStamp;
}else{
//发生回环,重新计算时间戳增量
CLEAR_ARR(m_aui32FirstStamp);
CLEAR_ARR(_aui32FirstStamp);
modifiedStamp = 0;
}
sendRtmp(pkt->typeId, pkt->streamId, pkt->strBuf, modifiedStamp, pkt->chunkId);
}
void RtmpSession::doDelay(int delaySec, const std::function<void()> &fun) {
if(m_delayTask){
m_delayTask();
if(_delayTask){
_delayTask();
}
m_delayTask = fun;
m_iTaskTimeLine = time(NULL) + delaySec;
_delayTask = fun;
_iTaskTimeLine = time(NULL) + delaySec;
}
void RtmpSession::cancelDelyaTask(){
m_delayTask = nullptr;
_delayTask = nullptr;
}

View File

@@ -70,7 +70,7 @@ private:
void onSendMedia(const RtmpPacket::Ptr &pkt);
void onSendRawData(const Buffer::Ptr &buffer) override{
m_ui64TotalBytes += buffer->size();
_ui64TotalBytes += buffer->size();
send(buffer);
}
void onRtmpChunk(RtmpPacket &chunkData) override;
@@ -78,12 +78,12 @@ private:
template<typename first, typename second>
inline void sendReply(const char *str, const first &reply, const second &status) {
AMFEncoder invoke;
invoke << str << m_dNowReqID << reply << status;
invoke << str << _dNowReqID << reply << status;
sendResponse(MSG_CMD, invoke.data());
}
bool shutDown() override {
InfoL << "kick out:" << m_mediaInfo.m_vhost << " " << m_mediaInfo.m_app << " " << m_mediaInfo.m_streamid;
InfoL << "kick out:" << _mediaInfo._vhost << " " << _mediaInfo._app << " " << _mediaInfo._streamid;
safeShutdown();
return true;
}
@@ -91,19 +91,19 @@ private:
void doDelay(int delaySec,const std::function<void()> &fun);
void cancelDelyaTask();
private:
std::string m_strTcUrl;
MediaInfo m_mediaInfo;
double m_dNowReqID = 0;
Ticker m_ticker;//数据接收时间
SmoothTicker m_stampTicker[2];//时间戳生产器
RingBuffer<RtmpPacket::Ptr>::RingReader::Ptr m_pRingReader;
std::shared_ptr<RtmpMediaSource> m_pPublisherSrc;
std::weak_ptr<RtmpMediaSource> m_pPlayerSrc;
uint32_t m_aui32FirstStamp[2] = {0};
std::string _strTcUrl;
MediaInfo _mediaInfo;
double _dNowReqID = 0;
Ticker _ticker;//数据接收时间
SmoothTicker _stampTicker[2];//时间戳生产器
RingBuffer<RtmpPacket::Ptr>::RingReader::Ptr _pRingReader;
std::shared_ptr<RtmpMediaSource> _pPublisherSrc;
std::weak_ptr<RtmpMediaSource> _pPlayerSrc;
uint32_t _aui32FirstStamp[2] = {0};
//消耗的总流量
uint64_t m_ui64TotalBytes = 0;
std::function<void()> m_delayTask;
uint32_t m_iTaskTimeLine = 0;
uint64_t _ui64TotalBytes = 0;
std::function<void()> _delayTask;
uint32_t _iTaskTimeLine = 0;
};

View File

@@ -41,27 +41,27 @@ RtmpToRtspMediaSource::RtmpToRtspMediaSource(const string &vhost,
const string &id,
bool bEnableHls,
bool bEnableMp4) :
RtmpMediaSource(vhost,app,id),m_bEnableHls(bEnableHls),m_bEnableMp4(bEnableMp4) {
RtmpMediaSource(vhost,app,id),_bEnableHls(bEnableHls),_bEnableMp4(bEnableMp4) {
}
RtmpToRtspMediaSource::~RtmpToRtspMediaSource() {}
void RtmpToRtspMediaSource::onGetH264(const H264Frame &frame) {
if(m_pRecorder){
m_pRecorder->inputH264((char *) frame.data(), frame.size(), frame.timeStamp, frame.type);
if(_pRecorder){
_pRecorder->inputH264((char *) frame.data(), frame.size(), frame.timeStamp, frame.type);
}
if(m_pRtpMaker_h264){
m_pRtpMaker_h264->makeRtp(frame.data() + 4, frame.size() - 4, frame.timeStamp);
if(_pRtpMaker_h264){
_pRtpMaker_h264->makeRtp(frame.data() + 4, frame.size() - 4, frame.timeStamp);
}
}
inline void RtmpToRtspMediaSource::onGetAAC(const AACFrame &frame) {
if(m_pRecorder){
m_pRecorder->inputAAC((char *) frame.buffer, frame.aac_frame_length, frame.timeStamp);
if(_pRecorder){
_pRecorder->inputAAC((char *) frame.buffer, frame.aac_frame_length, frame.timeStamp);
}
if (m_pRtpMaker_aac) {
m_pRtpMaker_aac->makeRtp((char *) frame.buffer + 7, frame.aac_frame_length - 7, frame.timeStamp);
if (_pRtpMaker_aac) {
_pRtpMaker_aac->makeRtp((char *) frame.buffer + 7, frame.aac_frame_length - 7, frame.timeStamp);
}
}
@@ -73,40 +73,40 @@ void RtmpToRtspMediaSource::makeSDP() {
strSDP += "i=ZL Live Stream\r\n";
strSDP += "c=IN IP4 0.0.0.0\r\n";
strSDP += "t=0 0\r\n";
if(m_pParser->getDuration() <= 0){
if(_pParser->getDuration() <= 0){
strSDP += "a=range:npt=0-\r\n";
}else{
strSDP += StrPrinter << "0-"<< m_pParser->getDuration()<< "\r\n" << endl;
strSDP += StrPrinter << "0-"<< _pParser->getDuration()<< "\r\n" << endl;
}
strSDP += "a=control:*\r\n";
//todo(xzl) 修复此处
// if (m_pParser->containVideo()) {
// if (_pParser->containVideo()) {
// uint32_t ssrc0;
// memcpy(&ssrc0, makeRandStr(4, false).data(), 4);
// auto lam = [this](const RtpPacket::Ptr &pkt, bool bKeyPos) {
// m_pRtspSrc->onGetRTP(pkt,bKeyPos);
// _pRtspSrc->onGetRTP(pkt,bKeyPos);
// };
//
// GET_CONFIG_AND_REGISTER(uint32_t,videoMtu,Config::Rtp::kVideoMtuSize);
// m_pRtpMaker_h264.reset(new RtpMaker_H264(lam, ssrc0,videoMtu));
// _pRtpMaker_h264.reset(new RtpMaker_H264(lam, ssrc0,videoMtu));
//
// char strTemp[100];
// int profile_level_id = 0;
// string strSPS =m_pParser->getSps().substr(4);
// string strPPS =m_pParser->getPps().substr(4);
// string strSPS =_pParser->getSps().substr(4);
// string strPPS =_pParser->getPps().substr(4);
// if (strSPS.length() >= 4) { // sanity check
// profile_level_id = (strSPS[1] << 16) | (strSPS[2] << 8) | strSPS[3]; // profile_idc|constraint_setN_flag|level_idc
// }
//
// //视频通道
// strSDP += StrPrinter << "m=video 0 RTP/AVP " << m_pRtpMaker_h264->getPlayloadType()
// strSDP += StrPrinter << "m=video 0 RTP/AVP " << _pRtpMaker_h264->getPlayloadType()
// << "\r\n" << endl;
// strSDP += "b=AS:5100\r\n";
// strSDP += StrPrinter << "a=rtpmap:" << m_pRtpMaker_h264->getPlayloadType()
// << " H264/" << m_pRtpMaker_h264->getSampleRate() << "\r\n" << endl;
// strSDP += StrPrinter << "a=fmtp:" << m_pRtpMaker_h264->getPlayloadType()
// strSDP += StrPrinter << "a=rtpmap:" << _pRtpMaker_h264->getPlayloadType()
// << " H264/" << _pRtpMaker_h264->getSampleRate() << "\r\n" << endl;
// strSDP += StrPrinter << "a=fmtp:" << _pRtpMaker_h264->getPlayloadType()
// << " packetization-mode=1;profile-level-id=" << endl;
//
// memset(strTemp, 0, 100);
@@ -121,41 +121,41 @@ void RtmpToRtspMediaSource::makeSDP() {
// av_base64_encode(strTemp, 100, (uint8_t *) strPPS.data(), strPPS.size());
// strSDP += strTemp;
// strSDP += "\r\n";
// strSDP += StrPrinter << "a=control:trackID=" << m_pRtpMaker_h264->getInterleaved() / 2
// strSDP += StrPrinter << "a=control:trackID=" << _pRtpMaker_h264->getInterleaved() / 2
// << "\r\n" << endl;
// }
//
// if (m_pParser->containAudio()) {
// if (_pParser->containAudio()) {
// uint32_t ssrc1;
// memcpy(&ssrc1, makeRandStr(8, false).data() + 4, 4);
// auto lam = [this](const RtpPacket::Ptr &pkt, bool bKeyPos) {
// m_pRtspSrc->onGetRTP(pkt,bKeyPos);
// _pRtspSrc->onGetRTP(pkt,bKeyPos);
// };
// GET_CONFIG_AND_REGISTER(uint32_t,audioMtu,Config::Rtp::kAudioMtuSize);
// m_pRtpMaker_aac.reset(new RtpMaker_AAC(lam, ssrc1, audioMtu,m_pParser->getAudioSampleRate()));
// _pRtpMaker_aac.reset(new RtpMaker_AAC(lam, ssrc1, audioMtu,_pParser->getAudioSampleRate()));
//
// char configStr[32];
// const string & strAacCfg = m_pParser->getAudioCfg();
// const string & strAacCfg = _pParser->getAudioCfg();
// snprintf(configStr, sizeof(configStr), "%02X%02x", strAacCfg[0], strAacCfg[1]);
// strSDP += StrPrinter << "m=audio 0 RTP/AVP " << m_pRtpMaker_aac->getPlayloadType()
// strSDP += StrPrinter << "m=audio 0 RTP/AVP " << _pRtpMaker_aac->getPlayloadType()
// << "\r\n" << endl;
// strSDP += "b=AS:96\r\n";
// strSDP += StrPrinter << "a=rtpmap:" << m_pRtpMaker_aac->getPlayloadType()
// << " MPEG4-GENERIC/" << m_pRtpMaker_aac->getSampleRate() << "\r\n"
// strSDP += StrPrinter << "a=rtpmap:" << _pRtpMaker_aac->getPlayloadType()
// << " MPEG4-GENERIC/" << _pRtpMaker_aac->getSampleRate() << "\r\n"
// << endl;
// strSDP += StrPrinter << "a=fmtp:" << m_pRtpMaker_aac->getPlayloadType()
// strSDP += StrPrinter << "a=fmtp:" << _pRtpMaker_aac->getPlayloadType()
// << " streamtype=5;profile-level-id=1;mode=AAC-hbr;"
// << "sizelength=13;indexlength=3;indexdeltalength=3;config="
// << endl;
// strSDP.append(configStr, 4);
// strSDP += "\r\n";
// strSDP += StrPrinter << "a=control:trackID=" << m_pRtpMaker_aac->getInterleaved() / 2
// strSDP += StrPrinter << "a=control:trackID=" << _pRtpMaker_aac->getInterleaved() / 2
// << "\r\n" << endl;
// }
m_pRtspSrc.reset(new RtspMediaSource(getVhost(),getApp(),getId()));
m_pRtspSrc->setListener(m_listener);
m_pRtspSrc->onGetSDP(strSDP);
_pRtspSrc.reset(new RtspMediaSource(getVhost(),getApp(),getId()));
_pRtspSrc->setListener(_listener);
_pRtspSrc->onGetSDP(strSDP);
}

View File

@@ -65,12 +65,12 @@ public:
void onGetMetaData(const AMFValue &_metadata) override {
try {
m_pParser.reset(new RtmpParser(_metadata));
m_pRecorder.reset(new MediaRecorder(getVhost(),getApp(),getId(),m_pParser,m_bEnableHls,m_bEnableMp4));
_pParser.reset(new RtmpParser(_metadata));
_pRecorder.reset(new MediaRecorder(getVhost(),getApp(),getId(),_pParser,_bEnableHls,_bEnableMp4));
//todo(xzl) 修复此处
// m_pParser->setOnAudioCB(std::bind(&RtmpToRtspMediaSource::onGetAAC, this, placeholders::_1));
// m_pParser->setOnVideoCB(std::bind(&RtmpToRtspMediaSource::onGetH264, this, placeholders::_1));
// _pParser->setOnAudioCB(std::bind(&RtmpToRtspMediaSource::onGetAAC, this, placeholders::_1));
// _pParser->setOnVideoCB(std::bind(&RtmpToRtspMediaSource::onGetH264, this, placeholders::_1));
} catch (exception &ex) {
WarnL << ex.what();
}
@@ -78,23 +78,23 @@ public:
}
void onGetMedia(const RtmpPacket::Ptr &pkt) override {
if (m_pParser) {
if (!m_pRtspSrc && m_pParser->isInited()) {
if (_pParser) {
if (!_pRtspSrc && _pParser->isInited()) {
makeSDP();
}
m_pParser->inputRtmp(pkt);
_pParser->inputRtmp(pkt);
}
RtmpMediaSource::onGetMedia(pkt);
}
private:
RtmpParser::Ptr m_pParser;
RtspMediaSource::Ptr m_pRtspSrc;
RtpMaker_AAC::Ptr m_pRtpMaker_aac;
RtpMaker_H264::Ptr m_pRtpMaker_h264;
MediaRecorder::Ptr m_pRecorder;
bool m_bEnableHls;
bool m_bEnableMp4;
RtmpParser::Ptr _pParser;
RtspMediaSource::Ptr _pRtspSrc;
RtpMaker_AAC::Ptr _pRtpMaker_aac;
RtpMaker_H264::Ptr _pRtpMaker_h264;
MediaRecorder::Ptr _pRecorder;
bool _bEnableHls;
bool _bEnableMp4;
void onGetH264(const H264Frame &frame);
void onGetAAC(const AACFrame &frame);
void makeSDP();

View File

@@ -36,24 +36,24 @@ using namespace ZL::Network;
/////////////////////AMFValue/////////////////////////////
inline void AMFValue::destroy() {
switch (m_type) {
switch (_type) {
case AMF_STRING:
if (m_value.string) {
delete m_value.string;
m_value.string = nullptr;
if (_value.string) {
delete _value.string;
_value.string = nullptr;
}
break;
case AMF_OBJECT:
case AMF_ECMA_ARRAY:
if (m_value.object) {
delete m_value.object;
m_value.object = nullptr;
if (_value.object) {
delete _value.object;
_value.object = nullptr;
}
break;
case AMF_STRICT_ARRAY:
if (m_value.array) {
delete m_value.array;
m_value.array = nullptr;
if (_value.array) {
delete _value.array;
_value.array = nullptr;
}
break;
default:
@@ -61,16 +61,16 @@ inline void AMFValue::destroy() {
}
}
inline void AMFValue::init() {
switch (m_type) {
switch (_type) {
case AMF_OBJECT:
case AMF_ECMA_ARRAY:
m_value.object = new mapType;
_value.object = new mapType;
break;
case AMF_STRING:
m_value.string = new std::string;
_value.string = new std::string;
break;
case AMF_STRICT_ARRAY:
m_value.array = new arrayType;
_value.array = new arrayType;
break;
default:
@@ -79,7 +79,7 @@ inline void AMFValue::init() {
}
AMFValue::AMFValue(AMFType type) :
m_type(type) {
_type(type) {
init();
}
@@ -89,38 +89,38 @@ AMFValue::~AMFValue() {
}
AMFValue::AMFValue(const char *s) :
m_type(AMF_STRING) {
_type(AMF_STRING) {
init();
*m_value.string = s;
*_value.string = s;
}
AMFValue::AMFValue(const std::string &s) :
m_type(AMF_STRING) {
_type(AMF_STRING) {
init();
*m_value.string = s;
*_value.string = s;
}
AMFValue::AMFValue(double n) :
m_type(AMF_NUMBER) {
_type(AMF_NUMBER) {
init();
m_value.number = n;
_value.number = n;
}
AMFValue::AMFValue(int i) :
m_type(AMF_INTEGER) {
_type(AMF_INTEGER) {
init();
m_value.integer = i;
_value.integer = i;
}
AMFValue::AMFValue(bool b) :
m_type(AMF_BOOLEAN) {
_type(AMF_BOOLEAN) {
init();
m_value.boolean = b;
_value.boolean = b;
}
AMFValue::AMFValue(const AMFValue &from) :
m_type(AMF_NULL) {
_type(AMF_NULL) {
*this = from;
}
@@ -134,27 +134,27 @@ AMFValue& AMFValue::operator =(const AMFValue &from) {
}
AMFValue& AMFValue::operator =(AMFValue &&from) {
destroy();
m_type = from.m_type;
_type = from._type;
init();
switch (m_type) {
switch (_type) {
case AMF_STRING:
*m_value.string = (*from.m_value.string);
*_value.string = (*from._value.string);
break;
case AMF_OBJECT:
case AMF_ECMA_ARRAY:
*m_value.object = (*from.m_value.object);
*_value.object = (*from._value.object);
break;
case AMF_STRICT_ARRAY:
*m_value.array = (*from.m_value.array);
*_value.array = (*from._value.array);
break;
case AMF_NUMBER:
m_value.number = from.m_value.number;
_value.number = from._value.number;
break;
case AMF_INTEGER:
m_value.integer = from.m_value.integer;
_value.integer = from._value.integer;
break;
case AMF_BOOLEAN:
m_value.boolean = from.m_value.boolean;
_value.boolean = from._value.boolean;
break;
default:
break;

View File

@@ -61,13 +61,13 @@ public:
~AMFValue();
void clear() {
switch (m_type) {
switch (_type) {
case AMF_STRING:
m_value.string->clear();
_value.string->clear();
break;
case AMF_OBJECT:
case AMF_ECMA_ARRAY:
m_value.object->clear();
_value.object->clear();
break;
default:
break;
@@ -75,23 +75,23 @@ public:
}
AMFType type() const {
return m_type;
return _type;
}
const std::string &as_string() const {
if(m_type != AMF_STRING){
if(_type != AMF_STRING){
throw std::runtime_error("AMF not a string");
}
return *m_value.string;
return *_value.string;
}
double as_number() const {
switch (m_type) {
switch (_type) {
case AMF_NUMBER:
return m_value.number;
return _value.number;
case AMF_INTEGER:
return m_value.integer;
return _value.integer;
case AMF_BOOLEAN:
return m_value.boolean;
return _value.boolean;
break;
default:
throw std::runtime_error("AMF not a number");
@@ -99,13 +99,13 @@ public:
}
}
int as_integer() const {
switch (m_type) {
switch (_type) {
case AMF_NUMBER:
return m_value.number;
return _value.number;
case AMF_INTEGER:
return m_value.integer;
return _value.integer;
case AMF_BOOLEAN:
return m_value.boolean;
return _value.boolean;
break;
default:
throw std::runtime_error("AMF not a integer");
@@ -113,13 +113,13 @@ public:
}
}
bool as_boolean() const {
switch (m_type) {
switch (_type) {
case AMF_NUMBER:
return m_value.number;
return _value.number;
case AMF_INTEGER:
return m_value.integer;
return _value.integer;
case AMF_BOOLEAN:
return m_value.boolean;
return _value.boolean;
break;
default:
throw std::runtime_error("AMF not a boolean");
@@ -128,11 +128,11 @@ public:
}
const AMFValue &operator[](const char *str) const {
if (m_type != AMF_OBJECT && m_type != AMF_ECMA_ARRAY) {
if (_type != AMF_OBJECT && _type != AMF_ECMA_ARRAY) {
throw std::runtime_error("AMF not a object");
}
auto i = m_value.object->find(str);
if (i == m_value.object->end()) {
auto i = _value.object->find(str);
if (i == _value.object->end()) {
static AMFValue val(AMF_NULL);
return val;
}
@@ -140,36 +140,36 @@ public:
}
template<typename FUN>
void object_for_each(const FUN &fun) const {
if (m_type != AMF_OBJECT && m_type != AMF_ECMA_ARRAY) {
if (_type != AMF_OBJECT && _type != AMF_ECMA_ARRAY) {
throw std::runtime_error("AMF not a object");
}
for (auto & pr : *(m_value.object)) {
for (auto & pr : *(_value.object)) {
fun(pr.first, pr.second);
}
}
operator bool() const{
return m_type != AMF_NULL;
return _type != AMF_NULL;
}
void set(const std::string &s, const AMFValue &val) {
if (m_type != AMF_OBJECT && m_type != AMF_ECMA_ARRAY) {
if (_type != AMF_OBJECT && _type != AMF_ECMA_ARRAY) {
throw std::runtime_error("AMF not a object");
}
m_value.object->emplace(s, val);
_value.object->emplace(s, val);
}
void add(const AMFValue &val) {
if (m_type != AMF_STRICT_ARRAY) {
if (_type != AMF_STRICT_ARRAY) {
throw std::runtime_error("AMF not a array");
}
assert(m_type == AMF_STRICT_ARRAY);
m_value.array->push_back(val);
assert(_type == AMF_STRICT_ARRAY);
_value.array->push_back(val);
}
private:
typedef std::map<std::string, AMFValue> mapType;
typedef std::vector<AMFValue> arrayType;
AMFType m_type;
AMFType _type;
union {
std::string *string;
double number;
@@ -177,20 +177,20 @@ private:
bool boolean;
mapType *object;
arrayType *array;
} m_value;
} _value;
friend class AMFEncoder;
const mapType &getMap() const {
if (m_type != AMF_OBJECT && m_type != AMF_ECMA_ARRAY) {
if (_type != AMF_OBJECT && _type != AMF_ECMA_ARRAY) {
throw std::runtime_error("AMF not a object");
}
return *m_value.object;
return *_value.object;
}
const arrayType &getArr() const {
if (m_type != AMF_STRICT_ARRAY) {
if (_type != AMF_STRICT_ARRAY) {
throw std::runtime_error("AMF not a array");
}
return *m_value.array;
return *_value.array;
}
inline void destroy();
inline void init();