mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-26 04:31:37 +08:00
时间戳统一使用毫秒
This commit is contained in:
parent
e816c56f2e
commit
8f8eda9337
@ -184,12 +184,12 @@ RtpCodec::Ptr Factory::getRtpEncoderById(CodecId codecId,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RtpCodec::Ptr Factory::getRtpDecoderById(CodecId codecId, uint32_t ui32SampleRate) {
|
RtpCodec::Ptr Factory::getRtpDecoderById(CodecId codecId) {
|
||||||
switch (codecId){
|
switch (codecId){
|
||||||
case CodecH264:
|
case CodecH264:
|
||||||
return std::make_shared<H264RtpDecoder>();
|
return std::make_shared<H264RtpDecoder>();
|
||||||
case CodecAAC:
|
case CodecAAC:
|
||||||
return std::make_shared<AACRtpDecoder>(ui32SampleRate);
|
return std::make_shared<AACRtpDecoder>();
|
||||||
default:
|
default:
|
||||||
WarnL << "暂不支持该CodecId:" << codecId;
|
WarnL << "暂不支持该CodecId:" << codecId;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -86,7 +86,7 @@ public:
|
|||||||
* @param ui32SampleRate
|
* @param ui32SampleRate
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static RtpCodec::Ptr getRtpDecoderById(CodecId codecId, uint32_t ui32SampleRate);
|
static RtpCodec::Ptr getRtpDecoderById(CodecId codecId);
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////rtmp相关//////////////////////////////////
|
////////////////////////////////rtmp相关//////////////////////////////////
|
||||||
|
@ -32,6 +32,8 @@
|
|||||||
|
|
||||||
class MultiMediaSourceMuxer {
|
class MultiMediaSourceMuxer {
|
||||||
public:
|
public:
|
||||||
|
typedef std::shared_ptr<MultiMediaSourceMuxer> Ptr;
|
||||||
|
|
||||||
MultiMediaSourceMuxer(const string &vhost,
|
MultiMediaSourceMuxer(const string &vhost,
|
||||||
const string &strApp,
|
const string &strApp,
|
||||||
const string &strId,
|
const string &strId,
|
||||||
@ -68,6 +70,18 @@ public:
|
|||||||
_rtmp->setListener(listener);
|
_rtmp->setListener(listener);
|
||||||
_rtsp->setListener(listener);
|
_rtsp->setListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回总的消费者个数
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int readerCount() const{
|
||||||
|
return _rtsp->readerCount() + _rtmp->readerCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateTimeStamp(uint32_t stamp){
|
||||||
|
_rtsp->updateTimeStamp(stamp);
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
RtmpMediaSourceMuxer::Ptr _rtmp;
|
RtmpMediaSourceMuxer::Ptr _rtmp;
|
||||||
RtspMediaSourceMuxer::Ptr _rtsp;
|
RtspMediaSourceMuxer::Ptr _rtsp;
|
||||||
|
@ -46,9 +46,29 @@ class DemuxerBase {
|
|||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<DemuxerBase> Ptr;
|
typedef std::shared_ptr<DemuxerBase> Ptr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取节目总时长,单位秒
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
virtual float getDuration() const { return 0;}
|
virtual float getDuration() const { return 0;}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否初始化完毕,完毕后方可调用getTrack方法
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
virtual bool isInited() const { return true; }
|
virtual bool isInited() const { return true; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取全部的Track
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
virtual vector<Track::Ptr> getTracks() const { return vector<Track::Ptr>();}
|
virtual vector<Track::Ptr> getTracks() const { return vector<Track::Ptr>();}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取特定Track
|
||||||
|
* @param type
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
virtual Track::Ptr getTrack(TrackType type) const {
|
virtual Track::Ptr getTrack(TrackType type) const {
|
||||||
auto tracks = getTracks();
|
auto tracks = getTracks();
|
||||||
for(auto &track : tracks){
|
for(auto &track : tracks){
|
||||||
@ -85,18 +105,60 @@ public:
|
|||||||
|
|
||||||
PlayerBase(){}
|
PlayerBase(){}
|
||||||
virtual ~PlayerBase(){}
|
virtual ~PlayerBase(){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始播放
|
||||||
|
* @param strUrl 视频url,支持rtsp/rtmp
|
||||||
|
*/
|
||||||
virtual void play(const char* strUrl) {}
|
virtual void play(const char* strUrl) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 暂停或恢复
|
||||||
|
* @param bPause
|
||||||
|
*/
|
||||||
virtual void pause(bool bPause) {}
|
virtual void pause(bool bPause) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中断播放
|
||||||
|
*/
|
||||||
virtual void teardown() {}
|
virtual void teardown() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置异常中断回调
|
||||||
|
* @param cb
|
||||||
|
*/
|
||||||
virtual void setOnShutdown( const function<void(const SockException &)> &cb) {}
|
virtual void setOnShutdown( const function<void(const SockException &)> &cb) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置播放结果回调
|
||||||
|
* @param cb
|
||||||
|
*/
|
||||||
virtual void setOnPlayResult( const function<void(const SockException &ex)> &cb) {}
|
virtual void setOnPlayResult( const function<void(const SockException &ex)> &cb) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取播放进度,取值 0.0 ~ 1.0
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
virtual float getProgress() const { return 0;}
|
virtual float getProgress() const { return 0;}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拖动进度条
|
||||||
|
* @param fProgress 进度,取值 0.0 ~ 1.0
|
||||||
|
*/
|
||||||
virtual void seekTo(float fProgress) {}
|
virtual void seekTo(float fProgress) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置一个MediaSource,直接生产rtsp/rtmp代理
|
||||||
|
* @param src
|
||||||
|
*/
|
||||||
virtual void setMediaSouce(const MediaSource::Ptr & src) {}
|
virtual void setMediaSouce(const MediaSource::Ptr & src) {}
|
||||||
virtual float getRtpLossRate(TrackType trackType) const {return 0; }
|
|
||||||
|
/**
|
||||||
|
* 获取丢包率,只支持rtsp
|
||||||
|
* @param trackType 音频或视频,TrackInvalid时为总丢包率
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual float getPacketLossRate(TrackType trackType) const {return 0; }
|
||||||
protected:
|
protected:
|
||||||
virtual void onShutdown(const SockException &ex) {}
|
virtual void onShutdown(const SockException &ex) {}
|
||||||
virtual void onPlayResult(const SockException &ex) {}
|
virtual void onPlayResult(const SockException &ex) {}
|
||||||
|
@ -66,9 +66,9 @@ void RtmpPlayer::teardown() {
|
|||||||
_pBeatTimer.reset();
|
_pBeatTimer.reset();
|
||||||
_pPlayTimer.reset();
|
_pPlayTimer.reset();
|
||||||
_pMediaTimer.reset();
|
_pMediaTimer.reset();
|
||||||
_fSeekTo = 0;
|
_iSeekTo = 0;
|
||||||
CLEAR_ARR(_adFistStamp);
|
CLEAR_ARR(_aiFistStamp);
|
||||||
CLEAR_ARR(_adNowStamp);
|
CLEAR_ARR(_aiNowStamp);
|
||||||
reset();
|
reset();
|
||||||
shutdown();
|
shutdown();
|
||||||
}
|
}
|
||||||
@ -310,7 +310,7 @@ void RtmpPlayer::onRtmpChunk(RtmpPacket &chunkData) {
|
|||||||
case MSG_VIDEO: {
|
case MSG_VIDEO: {
|
||||||
auto idx = chunkData.typeId%2;
|
auto idx = chunkData.typeId%2;
|
||||||
if (_aNowStampTicker[idx].elapsedTime() > 500) {
|
if (_aNowStampTicker[idx].elapsedTime() > 500) {
|
||||||
_adNowStamp[idx] = chunkData.timeStamp;
|
_aiNowStamp[idx] = chunkData.timeStamp;
|
||||||
}
|
}
|
||||||
_onMediaData(std::make_shared<RtmpPacket>(chunkData));
|
_onMediaData(std::make_shared<RtmpPacket>(chunkData));
|
||||||
}
|
}
|
||||||
@ -321,30 +321,30 @@ void RtmpPlayer::onRtmpChunk(RtmpPacket &chunkData) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float RtmpPlayer::getProgressTime() const{
|
uint32_t RtmpPlayer::getProgressMilliSecond() const{
|
||||||
double iTime[2] = {0,0};
|
uint32_t iTime[2] = {0,0};
|
||||||
for(auto i = 0 ;i < 2 ;i++){
|
for(auto i = 0 ;i < 2 ;i++){
|
||||||
iTime[i] = (_adNowStamp[i] - _adFistStamp[i]) / 1000.0;
|
iTime[i] = _aiNowStamp[i] - _aiFistStamp[i];
|
||||||
}
|
}
|
||||||
return _fSeekTo + MAX(iTime[0],iTime[1]);
|
return _iSeekTo + MAX(iTime[0],iTime[1]);
|
||||||
}
|
}
|
||||||
void RtmpPlayer::seekToTime(float fTime){
|
void RtmpPlayer::seekToMilliSecond(uint32_t seekMS){
|
||||||
if (_bPaused) {
|
if (_bPaused) {
|
||||||
pause(false);
|
pause(false);
|
||||||
}
|
}
|
||||||
AMFEncoder enc;
|
AMFEncoder enc;
|
||||||
enc << "seek" << ++_iReqID << nullptr << fTime * 1000.0;
|
enc << "seek" << ++_iReqID << nullptr << seekMS * 1.0;
|
||||||
sendRequest(MSG_CMD, enc.data());
|
sendRequest(MSG_CMD, enc.data());
|
||||||
addOnStatusCB([this,fTime](AMFValue &val) {
|
addOnStatusCB([this,seekMS](AMFValue &val) {
|
||||||
//TraceL << "seek result";
|
//TraceL << "seek result";
|
||||||
_aNowStampTicker[0].resetTime();
|
_aNowStampTicker[0].resetTime();
|
||||||
_aNowStampTicker[1].resetTime();
|
_aNowStampTicker[1].resetTime();
|
||||||
float iTimeInc = fTime - getProgressTime();
|
auto iTimeInc = seekMS - getProgressMilliSecond();
|
||||||
for(auto i = 0 ;i < 2 ;i++){
|
for(auto i = 0 ;i < 2 ;i++){
|
||||||
_adFistStamp[i] = _adNowStamp[i] + iTimeInc * 1000.0;
|
_aiFistStamp[i] = _aiNowStamp[i] + iTimeInc;
|
||||||
_adNowStamp[i] = _adFistStamp[i];
|
_aiNowStamp[i] = _aiFistStamp[i];
|
||||||
}
|
}
|
||||||
_fSeekTo = fTime;
|
_iSeekTo = seekMS;
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -55,8 +55,8 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
virtual bool onCheckMeta(AMFValue &val) =0;
|
virtual bool onCheckMeta(AMFValue &val) =0;
|
||||||
virtual void onMediaData(const RtmpPacket::Ptr &chunkData) =0;
|
virtual void onMediaData(const RtmpPacket::Ptr &chunkData) =0;
|
||||||
float getProgressTime() const;
|
uint32_t getProgressMilliSecond() const;
|
||||||
void seekToTime(float fTime);
|
void seekToMilliSecond(uint32_t ms);
|
||||||
private:
|
private:
|
||||||
void _onShutdown(const SockException &ex) {
|
void _onShutdown(const SockException &ex) {
|
||||||
WarnL << ex.getErrCode() << " " << ex.what();
|
WarnL << ex.getErrCode() << " " << ex.what();
|
||||||
@ -145,9 +145,9 @@ private:
|
|||||||
std::shared_ptr<Timer> _pBeatTimer;
|
std::shared_ptr<Timer> _pBeatTimer;
|
||||||
|
|
||||||
//播放进度控制
|
//播放进度控制
|
||||||
float _fSeekTo = 0;
|
uint32_t _iSeekTo = 0;
|
||||||
double _adFistStamp[2] = { 0, 0 };
|
uint32_t _aiFistStamp[2] = { 0, 0 };
|
||||||
double _adNowStamp[2] = { 0, 0 };
|
uint32_t _aiNowStamp[2] = { 0, 0 };
|
||||||
Ticker _aNowStampTicker[2];
|
Ticker _aNowStampTicker[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -49,13 +49,13 @@ public:
|
|||||||
};
|
};
|
||||||
float getProgress() const override{
|
float getProgress() const override{
|
||||||
if(getDuration() > 0){
|
if(getDuration() > 0){
|
||||||
return getProgressTime() / getDuration();
|
return getProgressMilliSecond() / (getDuration() * 1000);
|
||||||
}
|
}
|
||||||
return PlayerBase::getProgress();
|
return PlayerBase::getProgress();
|
||||||
};
|
};
|
||||||
void seekTo(float fProgress) override{
|
void seekTo(float fProgress) override{
|
||||||
fProgress = MAX(float(0),MIN(fProgress,float(1.0)));
|
fProgress = MAX(float(0),MIN(fProgress,float(1.0)));
|
||||||
seekToTime(fProgress * getDuration());
|
seekToMilliSecond(fProgress * getDuration() * 1000);
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
//派生类回调函数
|
//派生类回调函数
|
||||||
|
@ -521,7 +521,7 @@ void RtmpSession::onRtmpChunk(RtmpPacket &chunkData) {
|
|||||||
void RtmpSession::onCmd_seek(AMFDecoder &dec) {
|
void RtmpSession::onCmd_seek(AMFDecoder &dec) {
|
||||||
dec.load<AMFValue>();/* NULL */
|
dec.load<AMFValue>();/* NULL */
|
||||||
auto milliSeconds = dec.load<AMFValue>().as_number();
|
auto milliSeconds = dec.load<AMFValue>().as_number();
|
||||||
InfoL << "rtmp seekTo:" << milliSeconds/1000.0;
|
InfoL << "rtmp seekTo(ms):" << milliSeconds;
|
||||||
auto stongSrc = _pPlayerSrc.lock();
|
auto stongSrc = _pPlayerSrc.lock();
|
||||||
if (stongSrc) {
|
if (stongSrc) {
|
||||||
stongSrc->seekTo(milliSeconds);
|
stongSrc->seekTo(milliSeconds);
|
||||||
|
@ -48,6 +48,9 @@ public:
|
|||||||
void setListener(const std::weak_ptr<MediaSourceEvent> &listener){
|
void setListener(const std::weak_ptr<MediaSourceEvent> &listener){
|
||||||
_mediaSouce->setListener(listener);
|
_mediaSouce->setListener(listener);
|
||||||
}
|
}
|
||||||
|
int readerCount() const{
|
||||||
|
return _mediaSouce->getRing()->readerCount();
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
void onInited() override {
|
void onInited() override {
|
||||||
_mediaSouce->onGetMetaData(getMetedata());
|
_mediaSouce->onGetMetaData(getMetedata());
|
||||||
|
@ -69,6 +69,7 @@ public:
|
|||||||
bool _inited = false;
|
bool _inited = false;
|
||||||
uint32_t _ssrc = 0;
|
uint32_t _ssrc = 0;
|
||||||
uint16_t _seq = 0;
|
uint16_t _seq = 0;
|
||||||
|
//时间戳,单位毫秒
|
||||||
uint32_t _time_stamp = 0;
|
uint32_t _time_stamp = 0;
|
||||||
};
|
};
|
||||||
class SdpAttr {
|
class SdpAttr {
|
||||||
|
@ -84,7 +84,7 @@ public:
|
|||||||
}
|
}
|
||||||
return track->_seq;
|
return track->_seq;
|
||||||
}
|
}
|
||||||
virtual uint32_t getTimestamp(TrackType trackType) {
|
virtual uint32_t getTimeStamp(TrackType trackType) {
|
||||||
auto track = _sdpAttr.getTrack(trackType);
|
auto track = _sdpAttr.getTrack(trackType);
|
||||||
if(!track){
|
if(!track){
|
||||||
return 0;
|
return 0;
|
||||||
@ -92,6 +92,13 @@ public:
|
|||||||
return track->_time_stamp;
|
return track->_time_stamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateTimeStamp(uint32_t uiStamp) {
|
||||||
|
auto tracks = _sdpAttr.getAvailableTrack();
|
||||||
|
for (auto &track : tracks) {
|
||||||
|
track->_time_stamp = uiStamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual void onGetSDP(const string& sdp) {
|
virtual void onGetSDP(const string& sdp) {
|
||||||
//派生类设置该媒体源媒体描述信息
|
//派生类设置该媒体源媒体描述信息
|
||||||
_strSdp = sdp;
|
_strSdp = sdp;
|
||||||
|
@ -91,9 +91,9 @@ void RtspPlayer::teardown(){
|
|||||||
_pBeatTimer.reset();
|
_pBeatTimer.reset();
|
||||||
_pPlayTimer.reset();
|
_pPlayTimer.reset();
|
||||||
_pRtpTimer.reset();
|
_pRtpTimer.reset();
|
||||||
_fSeekTo = 0;
|
_iSeekTo = 0;
|
||||||
CLEAR_ARR(_adFistStamp);
|
CLEAR_ARR(_aiFistStamp);
|
||||||
CLEAR_ARR(_adNowStamp);
|
CLEAR_ARR(_aiNowStamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtspPlayer::play(const char* strUrl){
|
void RtspPlayer::play(const char* strUrl){
|
||||||
@ -430,17 +430,17 @@ bool RtspPlayer::sendDescribe() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool RtspPlayer::sendPause(bool bPause,float fTime){
|
bool RtspPlayer::sendPause(bool bPause,uint32_t seekMS){
|
||||||
if(!bPause){
|
if(!bPause){
|
||||||
//修改时间轴
|
//修改时间轴
|
||||||
_aNowStampTicker[0].resetTime();
|
_aNowStampTicker[0].resetTime();
|
||||||
_aNowStampTicker[1].resetTime();
|
_aNowStampTicker[1].resetTime();
|
||||||
float iTimeInc = fTime - getProgressTime();
|
auto iTimeInc = seekMS - getProgressMilliSecond();
|
||||||
for(unsigned int i = 0 ;i < _aTrackInfo.size() ;i++){
|
for(unsigned int i = 0 ;i < _aTrackInfo.size() ;i++){
|
||||||
_adFistStamp[i] = _adNowStamp[i] + iTimeInc * _aTrackInfo[i]->_samplerate;
|
_aiFistStamp[i] = _aiNowStamp[i] + iTimeInc;
|
||||||
_adNowStamp[i] = _adFistStamp[i];
|
_aiNowStamp[i] = _aiFistStamp[i];
|
||||||
}
|
}
|
||||||
_fSeekTo = fTime;
|
_iSeekTo = seekMS;
|
||||||
}
|
}
|
||||||
|
|
||||||
//开启或暂停rtsp
|
//开启或暂停rtsp
|
||||||
@ -448,12 +448,12 @@ bool RtspPlayer::sendPause(bool bPause,float fTime){
|
|||||||
|
|
||||||
StrCaseMap header;
|
StrCaseMap header;
|
||||||
char buf[8];
|
char buf[8];
|
||||||
sprintf(buf,"%.2f",fTime);
|
sprintf(buf,"%.2f",seekMS / 1000.0);
|
||||||
header["Range"] = StrPrinter << "npt=" << buf << "-";
|
header["Range"] = StrPrinter << "npt=" << buf << "-";
|
||||||
return sendRtspRequest(bPause ? "PAUSE" : "PLAY",_strContentBase,header);
|
return sendRtspRequest(bPause ? "PAUSE" : "PLAY",_strContentBase,header);
|
||||||
}
|
}
|
||||||
void RtspPlayer::pause(bool bPause) {
|
void RtspPlayer::pause(bool bPause) {
|
||||||
sendPause(bPause,getProgressTime());
|
sendPause(bPause, getProgressMilliSecond());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtspPlayer::handleResPAUSE(const Parser& parser, bool bPause) {
|
void RtspPlayer::handleResPAUSE(const Parser& parser, bool bPause) {
|
||||||
@ -471,8 +471,8 @@ void RtspPlayer::handleResPAUSE(const Parser& parser, bool bPause) {
|
|||||||
if (strStart == "now") {
|
if (strStart == "now") {
|
||||||
strStart = "0";
|
strStart = "0";
|
||||||
}
|
}
|
||||||
_fSeekTo = atof(strStart.data());
|
_iSeekTo = 1000 * atof(strStart.data());
|
||||||
DebugL << "Range:" << _fSeekTo << " " << strStart ;
|
DebugL << "seekTo(ms):" << _iSeekTo ;
|
||||||
}
|
}
|
||||||
auto strRtpInfo = parser["RTP-Info"];
|
auto strRtpInfo = parser["RTP-Info"];
|
||||||
if (strRtpInfo.size()) {
|
if (strRtpInfo.size()) {
|
||||||
@ -482,10 +482,10 @@ void RtspPlayer::handleResPAUSE(const Parser& parser, bool bPause) {
|
|||||||
strTrack.append(";");
|
strTrack.append(";");
|
||||||
auto strControlSuffix = strTrack.substr(1 + strTrack.rfind('/'),strTrack.find(';') - strTrack.rfind('/') - 1);
|
auto strControlSuffix = strTrack.substr(1 + strTrack.rfind('/'),strTrack.find(';') - strTrack.rfind('/') - 1);
|
||||||
auto strRtpTime = FindField(strTrack.data(), "rtptime=", ";");
|
auto strRtpTime = FindField(strTrack.data(), "rtptime=", ";");
|
||||||
auto iIdx = getTrackIndexByControlSuffix(strControlSuffix);
|
auto idx = getTrackIndexByControlSuffix(strControlSuffix);
|
||||||
_adFistStamp[iIdx] = atoll(strRtpTime.data());
|
_aiFistStamp[idx] = atoll(strRtpTime.data()) * 1000 / _aTrackInfo[idx]->_samplerate;
|
||||||
_adNowStamp[iIdx] = _adFistStamp[iIdx];
|
_aiNowStamp[idx] = _aiFistStamp[idx];
|
||||||
DebugL << "rtptime:" << strControlSuffix <<" " << strRtpTime;
|
DebugL << "rtptime(ms):" << strControlSuffix <<" " << strRtpTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onPlayResult_l(SockException(Err_success, "rtsp play success"));
|
onPlayResult_l(SockException(Err_success, "rtsp play success"));
|
||||||
@ -595,7 +595,8 @@ bool RtspPlayer::handleOneRtp(int iTrackidx, unsigned char *pucData, unsigned in
|
|||||||
rtppt.sequence = ntohs(rtppt.sequence);
|
rtppt.sequence = ntohs(rtppt.sequence);
|
||||||
//时间戳
|
//时间戳
|
||||||
memcpy(&rtppt.timeStamp, pucData+4, 4);//内存对齐
|
memcpy(&rtppt.timeStamp, pucData+4, 4);//内存对齐
|
||||||
rtppt.timeStamp = ntohl(rtppt.timeStamp);
|
//时间戳转换成毫秒
|
||||||
|
rtppt.timeStamp = ntohl(rtppt.timeStamp) * 1000 / track->_samplerate;
|
||||||
//ssrc
|
//ssrc
|
||||||
memcpy(&rtppt.ssrc,pucData+8,4);//内存对齐
|
memcpy(&rtppt.ssrc,pucData+8,4);//内存对齐
|
||||||
rtppt.ssrc = ntohl(rtppt.ssrc);
|
rtppt.ssrc = ntohl(rtppt.ssrc);
|
||||||
@ -679,12 +680,12 @@ void RtspPlayer::onRecvRTP_l(const RtpPacket::Ptr &rtppt, int trackidx){
|
|||||||
_aui16NowSeq[trackidx] = rtppt->sequence;
|
_aui16NowSeq[trackidx] = rtppt->sequence;
|
||||||
|
|
||||||
if (_aNowStampTicker[trackidx].elapsedTime() > 500) {
|
if (_aNowStampTicker[trackidx].elapsedTime() > 500) {
|
||||||
_adNowStamp[trackidx] = rtppt->timeStamp;
|
_aiNowStamp[trackidx] = rtppt->timeStamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
onRecvRTP_l(rtppt,_aTrackInfo[trackidx]);
|
onRecvRTP_l(rtppt,_aTrackInfo[trackidx]);
|
||||||
}
|
}
|
||||||
float RtspPlayer::getRtpLossRate(TrackType type) const{
|
float RtspPlayer::getPacketLossRate(TrackType type) const{
|
||||||
int iTrackIdx = getTrackIndexByTrackType(type);
|
int iTrackIdx = getTrackIndexByTrackType(type);
|
||||||
if(iTrackIdx == -1){
|
if(iTrackIdx == -1){
|
||||||
uint64_t totalRecv = 0;
|
uint64_t totalRecv = 0;
|
||||||
@ -706,15 +707,15 @@ float RtspPlayer::getRtpLossRate(TrackType type) const{
|
|||||||
return 1.0 - (double)_aui64RtpRecv[iTrackIdx] / (_aui16NowSeq[iTrackIdx] - _aui16FirstSeq[iTrackIdx] + 1);
|
return 1.0 - (double)_aui64RtpRecv[iTrackIdx] / (_aui16NowSeq[iTrackIdx] - _aui16FirstSeq[iTrackIdx] + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
float RtspPlayer::getProgressTime() const{
|
uint32_t RtspPlayer::getProgressMilliSecond() const{
|
||||||
double iTime[2] = {0,0};
|
uint32_t iTime[2] = {0,0};
|
||||||
for(unsigned int i = 0 ;i < _aTrackInfo.size() ;i++){
|
for(unsigned int i = 0 ;i < _aTrackInfo.size() ;i++){
|
||||||
iTime[i] = (_adNowStamp[i] - _adFistStamp[i]) / _aTrackInfo[i]->_samplerate;
|
iTime[i] = _aiNowStamp[i] - _aiFistStamp[i];
|
||||||
}
|
}
|
||||||
return _fSeekTo + MAX(iTime[0],iTime[1]);
|
return _iSeekTo + MAX(iTime[0],iTime[1]);
|
||||||
}
|
}
|
||||||
void RtspPlayer::seekToTime(float fTime) {
|
void RtspPlayer::seekToMilliSecond(uint32_t ms) {
|
||||||
sendPause(false,fTime);
|
sendPause(false,ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RtspPlayer::sendRtspRequest(const string &cmd, const string &url,const StrCaseMap &header_const) {
|
bool RtspPlayer::sendRtspRequest(const string &cmd, const string &url,const StrCaseMap &header_const) {
|
||||||
|
@ -55,13 +55,13 @@ public:
|
|||||||
void play(const char* strUrl) override;
|
void play(const char* strUrl) override;
|
||||||
void pause(bool bPause) override;
|
void pause(bool bPause) override;
|
||||||
void teardown() override;
|
void teardown() override;
|
||||||
float getRtpLossRate(TrackType type) const override;
|
float getPacketLossRate(TrackType type) const override;
|
||||||
protected:
|
protected:
|
||||||
//派生类回调函数
|
//派生类回调函数
|
||||||
virtual bool onCheckSDP(const string &strSdp, const SdpAttr &sdpAttr) = 0;
|
virtual bool onCheckSDP(const string &strSdp, const SdpAttr &sdpAttr) = 0;
|
||||||
virtual void onRecvRTP(const RtpPacket::Ptr &pRtppt, const SdpTrack::Ptr &track) = 0;
|
virtual void onRecvRTP(const RtpPacket::Ptr &pRtppt, const SdpTrack::Ptr &track) = 0;
|
||||||
float getProgressTime() const;
|
uint32_t getProgressMilliSecond() const;
|
||||||
void seekToTime(float fTime);
|
void seekToMilliSecond(uint32_t ms);
|
||||||
private:
|
private:
|
||||||
void onShutdown_l(const SockException &ex);
|
void onShutdown_l(const SockException &ex);
|
||||||
void onRecvRTP_l(const RtpPacket::Ptr &pRtppt, int iTrackidx);
|
void onRecvRTP_l(const RtpPacket::Ptr &pRtppt, int iTrackidx);
|
||||||
@ -91,7 +91,7 @@ private:
|
|||||||
|
|
||||||
//发送SETUP命令
|
//发送SETUP命令
|
||||||
bool sendSetup(unsigned int uiTrackIndex);
|
bool sendSetup(unsigned int uiTrackIndex);
|
||||||
bool sendPause(bool bPause,float fTime);
|
bool sendPause(bool bPause,uint32_t ms);
|
||||||
bool sendOptions();
|
bool sendOptions();
|
||||||
bool sendDescribe();
|
bool sendDescribe();
|
||||||
bool sendRtspRequest(const string &cmd, const string &url ,const StrCaseMap &header = StrCaseMap());
|
bool sendRtspRequest(const string &cmd, const string &url ,const StrCaseMap &header = StrCaseMap());
|
||||||
@ -131,10 +131,12 @@ private:
|
|||||||
//心跳定时器
|
//心跳定时器
|
||||||
std::shared_ptr<Timer> _pBeatTimer;
|
std::shared_ptr<Timer> _pBeatTimer;
|
||||||
|
|
||||||
//播放进度控制
|
//播放进度控制,单位毫秒
|
||||||
float _fSeekTo = 0;
|
uint32_t _iSeekTo = 0;
|
||||||
double _adFistStamp[2] = {0,0};
|
|
||||||
double _adNowStamp[2] = {0,0};
|
//单位毫秒
|
||||||
|
uint32_t _aiFistStamp[2] = {0,0};
|
||||||
|
uint32_t _aiNowStamp[2] = {0,0};
|
||||||
Ticker _aNowStampTicker[2];
|
Ticker _aNowStampTicker[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -51,14 +51,14 @@ public:
|
|||||||
};
|
};
|
||||||
float getProgress() const override{
|
float getProgress() const override{
|
||||||
if(getDuration() > 0){
|
if(getDuration() > 0){
|
||||||
return getProgressTime() / getDuration();
|
return getProgressMilliSecond() / (getDuration() * 1000);
|
||||||
}
|
}
|
||||||
return PlayerBase::getProgress();
|
return PlayerBase::getProgress();
|
||||||
|
|
||||||
};
|
};
|
||||||
void seekTo(float fProgress) override{
|
void seekTo(float fProgress) override{
|
||||||
fProgress = MAX(float(0),MIN(fProgress,float(1.0)));
|
fProgress = MAX(float(0),MIN(fProgress,float(1.0)));
|
||||||
seekToTime(fProgress * getDuration());
|
seekToMilliSecond(fProgress * getDuration() * 1000);
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
//派生类回调函数
|
//派生类回调函数
|
||||||
|
@ -735,7 +735,7 @@ bool RtspSession::handleReq_Play() {
|
|||||||
for(auto &track : _aTrackInfo){
|
for(auto &track : _aTrackInfo){
|
||||||
track->_ssrc = pMediaSrc->getSsrc(track->_type);
|
track->_ssrc = pMediaSrc->getSsrc(track->_type);
|
||||||
track->_seq = pMediaSrc->getSeqence(track->_type);
|
track->_seq = pMediaSrc->getSeqence(track->_type);
|
||||||
track->_time_stamp = pMediaSrc->getTimestamp(track->_type);
|
track->_time_stamp = pMediaSrc->getTimeStamp(track->_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_bFirstPlay = false;
|
_bFirstPlay = false;
|
||||||
@ -754,7 +754,11 @@ bool RtspSession::handleReq_Play() {
|
|||||||
shutdown();
|
shutdown();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
iLen += sprintf(_pcBuf + iLen, "url=%s/%s;seq=%d;rtptime=%u,", _strUrl.data(), track->_control_surffix.data(), track->_seq,track->_time_stamp);
|
iLen += sprintf(_pcBuf + iLen, "url=%s/%s;seq=%d;rtptime=%u,",
|
||||||
|
_strUrl.data(),
|
||||||
|
track->_control_surffix.data(),
|
||||||
|
track->_seq,
|
||||||
|
track->_time_stamp * track->_samplerate / 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
iLen -= 1;
|
iLen -= 1;
|
||||||
@ -906,7 +910,7 @@ inline bool RtspSession::findStream() {
|
|||||||
for(auto &track : _aTrackInfo){
|
for(auto &track : _aTrackInfo){
|
||||||
track->_ssrc = pMediaSrc->getSsrc(track->_type);
|
track->_ssrc = pMediaSrc->getSsrc(track->_type);
|
||||||
track->_seq = pMediaSrc->getSeqence(track->_type);
|
track->_seq = pMediaSrc->getSeqence(track->_type);
|
||||||
track->_time_stamp = pMediaSrc->getTimestamp(track->_type);
|
track->_time_stamp = pMediaSrc->getTimeStamp(track->_type);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -72,13 +72,6 @@ public:
|
|||||||
return getRing()->readerCount() + (_pRtmpSrc ? _pRtmpSrc->getRing()->readerCount() : 0);
|
return getRing()->readerCount() + (_pRtmpSrc ? _pRtmpSrc->getRing()->readerCount() : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateTimeStamp(uint32_t uiStamp) {
|
|
||||||
auto tracks = _sdpAttr.getAvailableTrack();
|
|
||||||
for (auto &track : tracks) {
|
|
||||||
track->_time_stamp = uiStamp * (track->_samplerate / 1000.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void onGetH264(const H264Frame &frame);
|
void onGetH264(const H264Frame &frame);
|
||||||
void onGetAAC(const AACFrame &frame);
|
void onGetAAC(const AACFrame &frame);
|
||||||
|
@ -36,8 +36,7 @@ AACRtpEncoder::AACRtpEncoder(uint32_t ui32Ssrc,
|
|||||||
ui32MtuSize,
|
ui32MtuSize,
|
||||||
ui32SampleRate,
|
ui32SampleRate,
|
||||||
ui8PlayloadType,
|
ui8PlayloadType,
|
||||||
ui8Interleaved),
|
ui8Interleaved){
|
||||||
AACRtpDecoder(ui32SampleRate){
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AACRtpEncoder::inputFrame(const Frame::Ptr &frame) {
|
void AACRtpEncoder::inputFrame(const Frame::Ptr &frame) {
|
||||||
@ -74,8 +73,7 @@ void AACRtpEncoder::inputFrame(const Frame::Ptr &frame) {
|
|||||||
|
|
||||||
void AACRtpEncoder::makeAACRtp(const void *pData, unsigned int uiLen, bool bMark, uint32_t uiStamp) {
|
void AACRtpEncoder::makeAACRtp(const void *pData, unsigned int uiLen, bool bMark, uint32_t uiStamp) {
|
||||||
uint16_t u16RtpLen = uiLen + 12;
|
uint16_t u16RtpLen = uiLen + 12;
|
||||||
_ui32TimeStamp = (_ui32SampleRate / 1000) * uiStamp;
|
uint32_t ts = htonl((_ui32SampleRate / 1000) * uiStamp);
|
||||||
uint32_t ts = htonl(_ui32TimeStamp);
|
|
||||||
uint16_t sq = htons(_ui16Sequence);
|
uint16_t sq = htons(_ui16Sequence);
|
||||||
uint32_t sc = htonl(_ui32Ssrc);
|
uint32_t sc = htonl(_ui32Ssrc);
|
||||||
auto pRtppkt = ResourcePoolHelper<RtpPacket>::obtainObj();
|
auto pRtppkt = ResourcePoolHelper<RtpPacket>::obtainObj();
|
||||||
@ -99,19 +97,19 @@ void AACRtpEncoder::makeAACRtp(const void *pData, unsigned int uiLen, bool bMark
|
|||||||
rtppkt.mark = bMark;
|
rtppkt.mark = bMark;
|
||||||
rtppkt.length = uiLen + 16;
|
rtppkt.length = uiLen + 16;
|
||||||
rtppkt.sequence = _ui16Sequence;
|
rtppkt.sequence = _ui16Sequence;
|
||||||
rtppkt.timeStamp = _ui32TimeStamp;
|
rtppkt.timeStamp = uiStamp;
|
||||||
rtppkt.ssrc = _ui32Ssrc;
|
rtppkt.ssrc = _ui32Ssrc;
|
||||||
rtppkt.type = TrackAudio;
|
rtppkt.type = TrackAudio;
|
||||||
rtppkt.offset = 16;
|
rtppkt.offset = 16;
|
||||||
|
|
||||||
RtpCodec::inputRtp(pRtppkt, false);
|
RtpCodec::inputRtp(pRtppkt, false);
|
||||||
_ui16Sequence++;
|
_ui16Sequence++;
|
||||||
|
_ui32TimeStamp = uiStamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
AACRtpDecoder::AACRtpDecoder(uint32_t ui32SampleRate) {
|
AACRtpDecoder::AACRtpDecoder() {
|
||||||
_adts = obtainFrame();
|
_adts = obtainFrame();
|
||||||
_sampleRate = ui32SampleRate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AACFrame::Ptr AACRtpDecoder::obtainFrame() {
|
AACFrame::Ptr AACRtpDecoder::obtainFrame() {
|
||||||
@ -135,7 +133,7 @@ bool AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) {
|
|||||||
_adts->aac_frame_length += (length - 4);
|
_adts->aac_frame_length += (length - 4);
|
||||||
if (rtppack->mark == true) {
|
if (rtppack->mark == true) {
|
||||||
_adts->sequence = rtppack->sequence;
|
_adts->sequence = rtppack->sequence;
|
||||||
_adts->timeStamp = rtppack->timeStamp * (1000.0 / _sampleRate);
|
_adts->timeStamp = rtppack->timeStamp;
|
||||||
writeAdtsHeader(*_adts, _adts->buffer);
|
writeAdtsHeader(*_adts, _adts->buffer);
|
||||||
onGetAAC(_adts);
|
onGetAAC(_adts);
|
||||||
}
|
}
|
||||||
|
@ -37,10 +37,7 @@ class AACRtpDecoder : public RtpCodec , public ResourcePoolHelper<AACFrame> {
|
|||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<AACRtpDecoder> Ptr;
|
typedef std::shared_ptr<AACRtpDecoder> Ptr;
|
||||||
|
|
||||||
/**
|
AACRtpDecoder();
|
||||||
* @param ui32SampleRate 采样率,用于时间戳转换用
|
|
||||||
*/
|
|
||||||
AACRtpDecoder(uint32_t ui32SampleRate);
|
|
||||||
~AACRtpDecoder() {}
|
~AACRtpDecoder() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,7 +59,6 @@ private:
|
|||||||
AACFrame::Ptr obtainFrame();
|
AACFrame::Ptr obtainFrame();
|
||||||
private:
|
private:
|
||||||
AACFrame::Ptr _adts;
|
AACFrame::Ptr _adts;
|
||||||
uint32_t _sampleRate;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
|
|||||||
_h264frame->buffer.assign("\x0\x0\x0\x1", 4);
|
_h264frame->buffer.assign("\x0\x0\x0\x1", 4);
|
||||||
_h264frame->buffer.append((char *)frame, length);
|
_h264frame->buffer.append((char *)frame, length);
|
||||||
_h264frame->type = nal.type;
|
_h264frame->type = nal.type;
|
||||||
_h264frame->timeStamp = rtppack->timeStamp / 90;
|
_h264frame->timeStamp = rtppack->timeStamp;
|
||||||
_h264frame->sequence = rtppack->sequence;
|
_h264frame->sequence = rtppack->sequence;
|
||||||
auto isIDR = _h264frame->type == 5;
|
auto isIDR = _h264frame->type == 5;
|
||||||
onGetH264(_h264frame);
|
onGetH264(_h264frame);
|
||||||
@ -119,7 +119,7 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
|
|||||||
_h264frame->buffer.push_back(tmp);
|
_h264frame->buffer.push_back(tmp);
|
||||||
_h264frame->buffer.append((char *)frame + 2, length - 2);
|
_h264frame->buffer.append((char *)frame + 2, length - 2);
|
||||||
_h264frame->type = fu.type;
|
_h264frame->type = fu.type;
|
||||||
_h264frame->timeStamp = rtppack->timeStamp / 90;
|
_h264frame->timeStamp = rtppack->timeStamp;
|
||||||
_h264frame->sequence = rtppack->sequence;
|
_h264frame->sequence = rtppack->sequence;
|
||||||
return (_h264frame->type == 5); //i frame
|
return (_h264frame->type == 5); //i frame
|
||||||
}
|
}
|
||||||
@ -133,7 +133,7 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
|
|||||||
if (fu.E == 1) {
|
if (fu.E == 1) {
|
||||||
//FU-A end
|
//FU-A end
|
||||||
_h264frame->buffer.append((char *)frame + 2, length - 2);
|
_h264frame->buffer.append((char *)frame + 2, length - 2);
|
||||||
_h264frame->timeStamp = rtppack->timeStamp / 90;
|
_h264frame->timeStamp = rtppack->timeStamp;
|
||||||
auto isIDR = _h264frame->type == 5;
|
auto isIDR = _h264frame->type == 5;
|
||||||
onGetH264(_h264frame);
|
onGetH264(_h264frame);
|
||||||
return isIDR;
|
return isIDR;
|
||||||
@ -227,8 +227,7 @@ void H264RtpEncoder::inputFrame(const Frame::Ptr &frame) {
|
|||||||
|
|
||||||
void H264RtpEncoder::makeH264Rtp(const void* data, unsigned int len, bool mark, uint32_t uiStamp) {
|
void H264RtpEncoder::makeH264Rtp(const void* data, unsigned int len, bool mark, uint32_t uiStamp) {
|
||||||
uint16_t ui16RtpLen = len + 12;
|
uint16_t ui16RtpLen = len + 12;
|
||||||
_ui32TimeStamp = (_ui32SampleRate / 1000) * uiStamp;
|
uint32_t ts = htonl((_ui32SampleRate / 1000) * uiStamp);
|
||||||
uint32_t ts = htonl(_ui32TimeStamp);
|
|
||||||
uint16_t sq = htons(_ui16Sequence);
|
uint16_t sq = htons(_ui16Sequence);
|
||||||
uint32_t sc = htonl(_ui32Ssrc);
|
uint32_t sc = htonl(_ui32Ssrc);
|
||||||
|
|
||||||
@ -252,7 +251,7 @@ void H264RtpEncoder::makeH264Rtp(const void* data, unsigned int len, bool mark,
|
|||||||
rtppkt->mark = mark;
|
rtppkt->mark = mark;
|
||||||
rtppkt->length = len + 16;
|
rtppkt->length = len + 16;
|
||||||
rtppkt->sequence = _ui16Sequence;
|
rtppkt->sequence = _ui16Sequence;
|
||||||
rtppkt->timeStamp = _ui32TimeStamp;
|
rtppkt->timeStamp = uiStamp;
|
||||||
rtppkt->ssrc = _ui32Ssrc;
|
rtppkt->ssrc = _ui32Ssrc;
|
||||||
rtppkt->type = TrackVideo;
|
rtppkt->type = TrackVideo;
|
||||||
rtppkt->offset = 16;
|
rtppkt->offset = 16;
|
||||||
@ -260,6 +259,7 @@ void H264RtpEncoder::makeH264Rtp(const void* data, unsigned int len, bool mark,
|
|||||||
uint8_t type = ((uint8_t *) (data))[0] & 0x1F;
|
uint8_t type = ((uint8_t *) (data))[0] & 0x1F;
|
||||||
RtpCodec::inputRtp(rtppkt,type == 5);
|
RtpCodec::inputRtp(rtppkt,type == 5);
|
||||||
_ui16Sequence++;
|
_ui16Sequence++;
|
||||||
|
_ui32TimeStamp = uiStamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
}//namespace mediakit
|
}//namespace mediakit
|
@ -42,6 +42,7 @@ public:
|
|||||||
uint8_t PT;
|
uint8_t PT;
|
||||||
bool mark;
|
bool mark;
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
|
//时间戳,单位毫秒
|
||||||
uint32_t timeStamp;
|
uint32_t timeStamp;
|
||||||
uint16_t sequence;
|
uint16_t sequence;
|
||||||
uint32_t ssrc;
|
uint32_t ssrc;
|
||||||
|
@ -62,8 +62,7 @@ void RtpMaker_AAC::makeRtp(const char *pcData, int iLen, uint32_t uiStamp) {
|
|||||||
|
|
||||||
inline void RtpMaker_AAC::makeAACRtp(const void *pData, unsigned int uiLen, bool bMark, uint32_t uiStamp) {
|
inline void RtpMaker_AAC::makeAACRtp(const void *pData, unsigned int uiLen, bool bMark, uint32_t uiStamp) {
|
||||||
uint16_t u16RtpLen = uiLen + 12;
|
uint16_t u16RtpLen = uiLen + 12;
|
||||||
_ui32TimeStamp = (_ui32SampleRate / 1000) * uiStamp;
|
uint32_t ts = htonl((_ui32SampleRate / 1000) * uiStamp);
|
||||||
uint32_t ts = htonl(_ui32TimeStamp);
|
|
||||||
uint16_t sq = htons(_ui16Sequence);
|
uint16_t sq = htons(_ui16Sequence);
|
||||||
uint32_t sc = htonl(_ui32Ssrc);
|
uint32_t sc = htonl(_ui32Ssrc);
|
||||||
auto pRtppkt = obtainPkt();
|
auto pRtppkt = obtainPkt();
|
||||||
@ -87,13 +86,14 @@ inline void RtpMaker_AAC::makeAACRtp(const void *pData, unsigned int uiLen, bool
|
|||||||
rtppkt.mark = bMark;
|
rtppkt.mark = bMark;
|
||||||
rtppkt.length = uiLen + 16;
|
rtppkt.length = uiLen + 16;
|
||||||
rtppkt.sequence = _ui16Sequence;
|
rtppkt.sequence = _ui16Sequence;
|
||||||
rtppkt.timeStamp = _ui32TimeStamp;
|
rtppkt.timeStamp = uiStamp;
|
||||||
rtppkt.ssrc = _ui32Ssrc;
|
rtppkt.ssrc = _ui32Ssrc;
|
||||||
rtppkt.type = TrackAudio;
|
rtppkt.type = TrackAudio;
|
||||||
rtppkt.offset = 16;
|
rtppkt.offset = 16;
|
||||||
|
|
||||||
onMakeRtp(pRtppkt, false);
|
onMakeRtp(pRtppkt, false);
|
||||||
_ui16Sequence++;
|
_ui16Sequence++;
|
||||||
|
_ui32TimeStamp = uiStamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
}//namespace mediakit
|
}//namespace mediakit
|
@ -78,8 +78,7 @@ void RtpMaker_H264::makeRtp(const char* pcData, int iLen, uint32_t uiStamp) {
|
|||||||
|
|
||||||
inline void RtpMaker_H264::makeH264Rtp(const void* data, unsigned int len, bool mark, uint32_t uiStamp) {
|
inline void RtpMaker_H264::makeH264Rtp(const void* data, unsigned int len, bool mark, uint32_t uiStamp) {
|
||||||
uint16_t ui16RtpLen = len + 12;
|
uint16_t ui16RtpLen = len + 12;
|
||||||
_ui32TimeStamp = (_ui32SampleRate / 1000) * uiStamp;
|
uint32_t ts = htonl((_ui32SampleRate / 1000) * uiStamp);
|
||||||
uint32_t ts = htonl(_ui32TimeStamp);
|
|
||||||
uint16_t sq = htons(_ui16Sequence);
|
uint16_t sq = htons(_ui16Sequence);
|
||||||
uint32_t sc = htonl(_ui32Ssrc);
|
uint32_t sc = htonl(_ui32Ssrc);
|
||||||
|
|
||||||
@ -104,7 +103,7 @@ inline void RtpMaker_H264::makeH264Rtp(const void* data, unsigned int len, bool
|
|||||||
rtppkt.mark = mark;
|
rtppkt.mark = mark;
|
||||||
rtppkt.length = len + 16;
|
rtppkt.length = len + 16;
|
||||||
rtppkt.sequence = _ui16Sequence;
|
rtppkt.sequence = _ui16Sequence;
|
||||||
rtppkt.timeStamp = _ui32TimeStamp;
|
rtppkt.timeStamp = uiStamp;
|
||||||
rtppkt.ssrc = _ui32Ssrc;
|
rtppkt.ssrc = _ui32Ssrc;
|
||||||
rtppkt.type = TrackVideo;
|
rtppkt.type = TrackVideo;
|
||||||
rtppkt.offset = 16;
|
rtppkt.offset = 16;
|
||||||
@ -112,6 +111,7 @@ inline void RtpMaker_H264::makeH264Rtp(const void* data, unsigned int len, bool
|
|||||||
uint8_t type = ((uint8_t *) (data))[0] & 0x1F;
|
uint8_t type = ((uint8_t *) (data))[0] & 0x1F;
|
||||||
onMakeRtp(pRtppkt, type == 5);
|
onMakeRtp(pRtppkt, type == 5);
|
||||||
_ui16Sequence++;
|
_ui16Sequence++;
|
||||||
|
_ui32TimeStamp = uiStamp;
|
||||||
//InfoL<<timeStamp<<" "<<time<<" "<<sampleRate;
|
//InfoL<<timeStamp<<" "<<time<<" "<<sampleRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ void RtspDemuxer::makeAudioTrack(const SdpTrack::Ptr &audio) {
|
|||||||
_audioTrack = dynamic_pointer_cast<AudioTrack>(Factory::getTrackBySdp(audio));
|
_audioTrack = dynamic_pointer_cast<AudioTrack>(Factory::getTrackBySdp(audio));
|
||||||
if(_audioTrack){
|
if(_audioTrack){
|
||||||
//生成RtpCodec对象以便解码rtp
|
//生成RtpCodec对象以便解码rtp
|
||||||
_audioRtpDecoder = Factory::getRtpDecoderById(_audioTrack->getCodecId(),_audioTrack->getAudioSampleRate());
|
_audioRtpDecoder = Factory::getRtpDecoderById(_audioTrack->getCodecId());
|
||||||
if(_audioRtpDecoder){
|
if(_audioRtpDecoder){
|
||||||
//设置rtp解码器代理,生成的frame写入该Track
|
//设置rtp解码器代理,生成的frame写入该Track
|
||||||
_audioRtpDecoder->setDelegate(_audioTrack);
|
_audioRtpDecoder->setDelegate(_audioTrack);
|
||||||
@ -121,7 +121,7 @@ void RtspDemuxer::makeVideoTrack(const SdpTrack::Ptr &video) {
|
|||||||
_videoTrack = dynamic_pointer_cast<VideoTrack>(Factory::getTrackBySdp(video));
|
_videoTrack = dynamic_pointer_cast<VideoTrack>(Factory::getTrackBySdp(video));
|
||||||
if(_videoTrack){
|
if(_videoTrack){
|
||||||
//生成RtpCodec对象以便解码rtp
|
//生成RtpCodec对象以便解码rtp
|
||||||
_videoRtpDecoder = Factory::getRtpDecoderById(_videoTrack->getCodecId(),90000);
|
_videoRtpDecoder = Factory::getRtpDecoderById(_videoTrack->getCodecId());
|
||||||
if(_videoRtpDecoder){
|
if(_videoRtpDecoder){
|
||||||
//设置rtp解码器代理,生成的frame写入该Track
|
//设置rtp解码器代理,生成的frame写入该Track
|
||||||
_videoRtpDecoder->setDelegate(_videoTrack);
|
_videoRtpDecoder->setDelegate(_videoTrack);
|
||||||
|
@ -48,6 +48,12 @@ public:
|
|||||||
void setListener(const std::weak_ptr<MediaSourceEvent> &listener){
|
void setListener(const std::weak_ptr<MediaSourceEvent> &listener){
|
||||||
_mediaSouce->setListener(listener);
|
_mediaSouce->setListener(listener);
|
||||||
}
|
}
|
||||||
|
int readerCount() const{
|
||||||
|
return _mediaSouce->getRing()->readerCount();
|
||||||
|
}
|
||||||
|
void updateTimeStamp(uint32_t stamp){
|
||||||
|
_mediaSouce->updateTimeStamp(stamp);
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
void onInited() override {
|
void onInited() override {
|
||||||
_mediaSouce->onGetSDP(getSdp());
|
_mediaSouce->onGetSDP(getSdp());
|
||||||
|
Loading…
Reference in New Issue
Block a user