diff --git a/3rdpart/ZLToolKit b/3rdpart/ZLToolKit index fe572323..936d3c05 160000 --- a/3rdpart/ZLToolKit +++ b/3rdpart/ZLToolKit @@ -1 +1 @@ -Subproject commit fe572323b10d72819a4d69b326dd70e73c7bf1a6 +Subproject commit 936d3c05b183cba279bb348f8eac9eca0cc810c2 diff --git a/src/Extension/H264Rtmp.cpp b/src/Extension/H264Rtmp.cpp index 8f735fe3..9ff10e27 100644 --- a/src/Extension/H264Rtmp.cpp +++ b/src/Extension/H264Rtmp.cpp @@ -51,6 +51,8 @@ bool H264RtmpDecoder::decodeRtmp(const RtmpPacket::Ptr &pkt) { //缓存sps pps,后续插入到I帧之前 _sps = pkt->getH264SPS(); _pps = pkt->getH264PPS(); + onGetH264(_sps.data(), _sps.size(), pkt->timeStamp , pkt->timeStamp); + onGetH264(_pps.data(), _pps.size(), pkt->timeStamp , pkt->timeStamp); return false; } @@ -69,44 +71,13 @@ bool H264RtmpDecoder::decodeRtmp(const RtmpPacket::Ptr &pkt) { if(iFrameLen + iOffset > iTotalLen){ break; } - onGetH264_l(pkt->strBuf.data() + iOffset, iFrameLen, pkt->timeStamp , pts); + onGetH264(pkt->strBuf.data() + iOffset, iFrameLen, pkt->timeStamp , pts); iOffset += iFrameLen; } } return pkt->isVideoKeyFrame(); } - -inline void H264RtmpDecoder::onGetH264_l(const char* pcData, int iLen, uint32_t dts,uint32_t pts) { - switch (H264_TYPE(pcData[0])) { - case H264Frame::NAL_IDR: { - //I frame - if(_sps.length()){ - onGetH264(_sps.data(), _sps.length(), dts , pts); - } - if(_pps.length()){ - onGetH264(_pps.data(), _pps.length(), dts , pts); - } - onGetH264(pcData, iLen, dts , pts); - } - break; - case H264Frame::NAL_B_P: { - //I or P or B frame - onGetH264(pcData, iLen, dts , pts); - } - break; - case H264Frame::NAL_SPS: { - _sps.assign(pcData, iLen); - } - break; - case H264Frame::NAL_PPS:{ - _pps.assign(pcData, iLen); - } - break; - default: - break; - } -} inline void H264RtmpDecoder::onGetH264(const char* pcData, int iLen, uint32_t dts,uint32_t pts) { #if 1 _h264frame->type = H264_TYPE(pcData[0]); diff --git a/src/Extension/H264Rtmp.h b/src/Extension/H264Rtmp.h index e4bd4bbe..ed015e76 100644 --- a/src/Extension/H264Rtmp.h +++ b/src/Extension/H264Rtmp.h @@ -60,7 +60,6 @@ public: } protected: bool decodeRtmp(const RtmpPacket::Ptr &Rtmp); - void onGetH264_l(const char *pcData, int iLen, uint32_t dts,uint32_t pts); void onGetH264(const char *pcData, int iLen, uint32_t dts,uint32_t pts); H264Frame::Ptr obtainFrame(); protected: diff --git a/src/Player/PlayerBase.h b/src/Player/PlayerBase.h index cb115ee7..50330b06 100644 --- a/src/Player/PlayerBase.h +++ b/src/Player/PlayerBase.h @@ -245,14 +245,9 @@ protected: _playResultCB = nullptr; return; } - //播放成功后,我们还必须等待各个Track初始化完毕才能回调告知已经初始化完毕 - if(isInited(0xFFFF)){ - //初始化完毕则立即回调 - _playResultCB(ex); - _playResultCB = nullptr; - return; - } - //播放成功却未初始化完毕,这个时候不回调汇报播放成功 + //播放成功 + _playResultCB(ex); + _playResultCB = nullptr; } void onResume() override{ @@ -260,16 +255,6 @@ protected: _resumeCB(); } } - - void checkInited(int analysisMs){ - if(!_playResultCB){ - return; - } - if(isInited(analysisMs)){ - _playResultCB(SockException(Err_success,"play success")); - _playResultCB = nullptr; - } - } protected: function _shutdownCB; function _playResultCB; diff --git a/src/Rtmp/RtmpPlayer.cpp b/src/Rtmp/RtmpPlayer.cpp index b22a2885..75ce6593 100644 --- a/src/Rtmp/RtmpPlayer.cpp +++ b/src/Rtmp/RtmpPlayer.cpp @@ -321,7 +321,6 @@ void RtmpPlayer::onCmd_onMetaData(AMFDecoder &dec) { if(!onCheckMeta(val)){ throw std::runtime_error("onCheckMeta faied"); } - onPlayResult_l(SockException(Err_success,"play rtmp success")); } void RtmpPlayer::onStreamDry(uint32_t ui32StreamId) { @@ -329,6 +328,25 @@ void RtmpPlayer::onStreamDry(uint32_t ui32StreamId) { onPlayResult_l(SockException(Err_other,"rtmp stream dry")); } +void RtmpPlayer::onMediaData_l(const RtmpPacket::Ptr &packet) { + _mediaTicker.resetTime(); + if(!_pPlayTimer){ + //已经触发了onPlayResult事件,直接触发onMediaData事件 + onMediaData(packet); + return; + } + + if(packet->isCfgFrame()){ + //输入配置帧以便初始化完成各个track + onMediaData(packet); + }else{ + //先触发onPlayResult事件,这个时候解码器才能初始化完毕 + onPlayResult_l(SockException(Err_success,"play rtmp success")); + //触发onPlayResult事件后,再把帧数据输入到解码器 + onMediaData(packet); + } +} + void RtmpPlayer::onRtmpChunk(RtmpPacket &chunkData) { switch (chunkData.typeId) { @@ -351,6 +369,7 @@ void RtmpPlayer::onRtmpChunk(RtmpPacket &chunkData) { case MSG_VIDEO: { auto idx = chunkData.typeId%2; if (_aNowStampTicker[idx].elapsedTime() > 500) { + //计算播放进度时间轴用 _aiNowStamp[idx] = chunkData.timeStamp; } onMediaData_l(std::make_shared(std::move(chunkData))); diff --git a/src/Rtmp/RtmpPlayer.h b/src/Rtmp/RtmpPlayer.h index 66e8ae66..142ab5fb 100644 --- a/src/Rtmp/RtmpPlayer.h +++ b/src/Rtmp/RtmpPlayer.h @@ -60,11 +60,7 @@ protected: uint32_t getProgressMilliSecond() const; void seekToMilliSecond(uint32_t ms); protected: - void onMediaData_l(const RtmpPacket::Ptr &chunkData) { - _mediaTicker.resetTime(); - onMediaData(chunkData); - } - + void onMediaData_l(const RtmpPacket::Ptr &chunkData); void onPlayResult_l(const SockException &ex); //for Tcpclient @@ -97,7 +93,7 @@ protected: inline void send_createStream(); inline void send_play(); inline void send_pause(bool bPause); - +private: string _strApp; string _strStream; string _strTcUrl; diff --git a/src/Rtmp/RtmpPlayerImp.h b/src/Rtmp/RtmpPlayerImp.h index 6774e076..fb8064dd 100644 --- a/src/Rtmp/RtmpPlayerImp.h +++ b/src/Rtmp/RtmpPlayerImp.h @@ -58,7 +58,6 @@ public: seekToMilliSecond(fProgress * getDuration() * 1000); }; void play(const string &strUrl) override { - _analysisMs = (*this)[kMaxAnalysisMS].as(); PlayerImp::play(strUrl); } private: @@ -76,16 +75,13 @@ private: _pRtmpMediaSrc->onWrite(chunkData); } if(!_parser){ - //这个流没有metedata,那么尝试在音视频包里面还原出相关信息 + //这个流没有metedata _parser.reset(new RtmpDemuxer()); - onPlayResult_l(SockException(Err_success,"play rtmp success")); } _parser->inputRtmp(chunkData); - checkInited(_analysisMs); } private: RtmpMediaSource::Ptr _pRtmpMediaSrc; - int _analysisMs; }; diff --git a/tests/test_player.cpp b/tests/test_player.cpp index f0ee2dad..6ddfb256 100644 --- a/tests/test_player.cpp +++ b/tests/test_player.cpp @@ -39,9 +39,9 @@ using namespace std; using namespace toolkit; using namespace mediakit; -std::string Utf8ToGbk(std::string src_str) -{ #ifdef WIN32 +std::string Utf8ToGbk(std::string src_str){ + int len = MultiByteToWideChar(CP_UTF8, 0, src_str.c_str(), -1, NULL, 0); wchar_t* wszGBK = new wchar_t[len + 1]; memset(wszGBK, 0, len * 2 + 2); @@ -54,9 +54,6 @@ std::string Utf8ToGbk(std::string src_str) if (wszGBK) delete[] wszGBK; if (szGBK) delete[] szGBK; return strTemp; -#else - return src_str; -#endif } class log4Channel : public LogChannel { @@ -75,6 +72,9 @@ public: printf("%s %s\n", logContext->_function, Utf8ToGbk(logContext->str()).c_str()); } }; +#else +typedef ConsoleChannel log4Channel; +#endif #ifdef WIN32 #include