mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-10-06 12:13:49 +08:00
替换sdp解析逻辑
This commit is contained in:
parent
a69d7d0f71
commit
6fe90fe4ba
|
@ -66,11 +66,11 @@ Sdp::Ptr Factory::getSdpByTrack(const Track::Ptr &track) {
|
|||
}
|
||||
|
||||
|
||||
Track::Ptr Factory::getTrackBySdp(const string &sdp) {
|
||||
if (strcasestr(sdp.data(), "mpeg4-generic") != nullptr) {
|
||||
string aac_cfg_str = FindField(sdp.c_str(), "config=", "\r\n");
|
||||
Track::Ptr Factory::getTrackBySdp(const SdpTrack::Ptr &track) {
|
||||
if (strcasestr(track->_codec.data(), "mpeg4-generic") != nullptr) {
|
||||
string aac_cfg_str = FindField(track->_fmtp.c_str(), "config=", "\r\n");
|
||||
if (aac_cfg_str.size() != 4) {
|
||||
aac_cfg_str = FindField(sdp.c_str(), "config=", ";");
|
||||
aac_cfg_str = FindField(track->_fmtp.c_str(), "config=", ";");
|
||||
}
|
||||
if (aac_cfg_str.size() != 4) {
|
||||
//延后获取adts头
|
||||
|
@ -91,8 +91,8 @@ Track::Ptr Factory::getTrackBySdp(const string &sdp) {
|
|||
return std::make_shared<AACTrack>(aac_cfg);
|
||||
}
|
||||
|
||||
if (strcasestr(sdp.data(), "h264") != nullptr) {
|
||||
string sps_pps = FindField(sdp.c_str(), "sprop-parameter-sets=", "\r\n");
|
||||
if (strcasestr(track->_codec.data(), "h264") != nullptr) {
|
||||
string sps_pps = FindField(track->_fmtp.c_str(), "sprop-parameter-sets=", "\r\n");
|
||||
if(sps_pps.empty()){
|
||||
return std::make_shared<H264Track>();
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ Track::Ptr Factory::getTrackBySdp(const string &sdp) {
|
|||
return std::make_shared<H264Track>(sps,pps,0,0);
|
||||
}
|
||||
|
||||
WarnL << "暂不支持该sdp:" << sdp;
|
||||
WarnL << "暂不支持该sdp:" << track->_codec << " " << track->_fmtp;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ public:
|
|||
/**
|
||||
* 根据sdp生成Track对象
|
||||
*/
|
||||
static Track::Ptr getTrackBySdp(const string &sdp);
|
||||
static Track::Ptr getTrackBySdp(const SdpTrack::Ptr &track);
|
||||
|
||||
/**
|
||||
* 根据Track生成SDP对象
|
||||
|
|
|
@ -110,13 +110,13 @@ void SdpAttr::load(const string &sdp) {
|
|||
for (auto &pr : _track_map) {
|
||||
auto &track = *pr.second;
|
||||
if (pr.first == "") {
|
||||
track._type = TrackTitle;
|
||||
track.type = TrackTitle;
|
||||
} else if (pr.first == "video") {
|
||||
track._type = TrackVideo;
|
||||
track.type = TrackVideo;
|
||||
} else if (pr.first == "audio") {
|
||||
track._type = TrackAudio;
|
||||
track.type = TrackAudio;
|
||||
} else {
|
||||
track._type = TrackInvalid;
|
||||
track.type = TrackInvalid;
|
||||
}
|
||||
|
||||
auto it = track._attr.find("range");
|
||||
|
@ -153,6 +153,8 @@ void SdpAttr::load(const string &sdp) {
|
|||
it = track._attr.find("control");
|
||||
if(it != track._attr.end()) {
|
||||
track._control = it->second;
|
||||
auto surffix = string("/") + track._control;
|
||||
track._control_surffix = surffix.substr(1 + surffix.rfind('/'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -163,64 +165,25 @@ bool SdpAttr::available() const {
|
|||
|
||||
SdpTrack::Ptr SdpAttr::getTrack(TrackType type) const {
|
||||
for (auto &pr : _track_map){
|
||||
if(pr.second->_type == type){
|
||||
if(pr.second->type == type){
|
||||
return pr.second;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int parserSDP(const string& sdp, RtspTrack Track[2]) {
|
||||
int track_cnt = 0;
|
||||
string::size_type pos_head = 0;
|
||||
while ((pos_head = sdp.find("m=",pos_head)) != string::npos ) {
|
||||
auto pos_end = sdp.find("m=", pos_head + 2);
|
||||
if (pos_end == string::npos) {
|
||||
pos_end = sdp.size();
|
||||
}
|
||||
auto sdp_mid = sdp.substr(pos_head, pos_end - pos_head);
|
||||
pos_head = pos_end;
|
||||
Track[track_cnt].trackSdp = sdp_mid;
|
||||
Track[track_cnt].inited = false;
|
||||
Track[track_cnt].PT = atoi(FindField(sdp_mid.c_str(), "a=rtpmap:", " ").c_str());
|
||||
auto control = string("/") + trim(FindField(sdp_mid.c_str(), "a=control:", "\n"));
|
||||
Track[track_cnt].controlSuffix = control.substr(1 + control.rfind('/'));
|
||||
|
||||
if (sdp_mid.find("m=video") != string::npos) {
|
||||
//视频通道
|
||||
Track[track_cnt].type = TrackVideo;
|
||||
} else if (sdp_mid.find("m=audio") != string::npos) {
|
||||
//音频通道
|
||||
Track[track_cnt].type = TrackAudio;
|
||||
} else {
|
||||
//不识别的track
|
||||
continue;
|
||||
}
|
||||
track_cnt++;
|
||||
vector<SdpTrack::Ptr> SdpAttr::getAvailableTrack() const {
|
||||
vector<SdpTrack::Ptr> ret;
|
||||
auto video = getTrack(TrackVideo);
|
||||
if(video){
|
||||
ret.emplace_back(video);
|
||||
}
|
||||
return track_cnt;
|
||||
auto audio = getTrack(TrackAudio);
|
||||
if(audio){
|
||||
ret.emplace_back(audio);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
static onceToken s_token([](){
|
||||
string str = "v=0\n"
|
||||
"o=- 1001 1 IN IP4 192.168.0.22\n"
|
||||
"s=VCP IPC Realtime stream\n"
|
||||
"a=range:npt=0-\n"
|
||||
"m=video 0 RTP/AVP 105\n"
|
||||
"c=IN IP4 192.168.0.22\n"
|
||||
"a=control:rtsp://192.168.0.22/media/video1/video\n"
|
||||
"a=rtpmap:105 H264/90000\n"
|
||||
"a=fmtp:105 profile-level-id=64001f; packetization-mode=1; sprop-parameter-sets=Z2QAH6wrUCgC3QgAAB9AAAYahCAA,aO4xsg==\n"
|
||||
"a=recvonly\n"
|
||||
"m=application 0 RTP/AVP 107\n"
|
||||
"c=IN IP4 192.168.0.22\n"
|
||||
"a=control:rtsp://192.168.0.22/media/video1/metadata\n"
|
||||
"a=rtpmap:107 vnd.onvif.metadata/90000\n"
|
||||
"a=fmtp:107 DecoderTag=h3c-v3 RTCP=0\n"
|
||||
"a=recvonly";
|
||||
RtspTrack track[2];
|
||||
parserSDP(str,track);
|
||||
SdpAttr attr(str);
|
||||
track[0].inited=true;
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -62,34 +62,31 @@ public:
|
|||
int _samplerate;
|
||||
string _fmtp;
|
||||
string _control;
|
||||
TrackType _type;
|
||||
string _control_surffix;
|
||||
TrackType type;
|
||||
public:
|
||||
uint8_t interleaved = 0;
|
||||
bool inited = false;
|
||||
uint32_t ssrc = 0;
|
||||
uint16_t seq = 0;
|
||||
uint32_t timeStamp = 0;
|
||||
};
|
||||
class SdpAttr {
|
||||
public:
|
||||
typedef std::shared_ptr<SdpAttr> Ptr;
|
||||
SdpAttr(const string &sdp){load(sdp);};
|
||||
SdpAttr(){}
|
||||
SdpAttr(const string &sdp){load(sdp);}
|
||||
~SdpAttr(){}
|
||||
|
||||
void load(const string &sdp);
|
||||
SdpTrack::Ptr getTrack(TrackType type) const;
|
||||
bool available() const ;
|
||||
void load(const string &sdp);
|
||||
bool available() const ;
|
||||
|
||||
SdpTrack::Ptr getTrack(TrackType type) const;
|
||||
vector<SdpTrack::Ptr> getAvailableTrack() const;
|
||||
private:
|
||||
map<string,SdpTrack::Ptr> _track_map;
|
||||
map<string,SdpTrack::Ptr> _track_map;
|
||||
};
|
||||
|
||||
class RtspTrack{
|
||||
public:
|
||||
uint8_t PT;
|
||||
uint8_t interleaved;
|
||||
TrackType type = TrackInvalid;
|
||||
string trackSdp;
|
||||
string controlSuffix;
|
||||
bool inited;
|
||||
uint32_t ssrc = 0;
|
||||
uint16_t seq;
|
||||
uint32_t timeStamp;
|
||||
uint32_t sampleRate;
|
||||
};
|
||||
|
||||
class RtcpCounter {
|
||||
public:
|
||||
|
@ -99,7 +96,6 @@ public:
|
|||
};
|
||||
|
||||
string FindField(const char* buf, const char* start, const char *end,int bufSize = 0 );
|
||||
int parserSDP(const string& sdp, RtspTrack Track[2]);
|
||||
|
||||
struct StrCaseCompare
|
||||
{
|
||||
|
|
|
@ -95,7 +95,7 @@ public:
|
|||
_pRing->write(rtppt,keyPos);
|
||||
}
|
||||
protected:
|
||||
unordered_map<int, RtspTrack> _mapTracks;
|
||||
unordered_map<int, SdpTrack> _mapTracks;
|
||||
string _strSdp; //媒体描述信息
|
||||
RingType::Ptr _pRing; //rtp环形缓冲
|
||||
};
|
||||
|
|
|
@ -70,7 +70,7 @@ void RtspPlayer::teardown(){
|
|||
|
||||
erase(kRtspMd5Nonce);
|
||||
erase(kRtspRealm);
|
||||
_uiTrackCnt = 0;
|
||||
_aTrackInfo.clear();
|
||||
_onHandshake = nullptr;
|
||||
_uiRtpBufLen = 0;
|
||||
_strSession.clear();
|
||||
|
@ -276,17 +276,21 @@ void RtspPlayer::handleResDESCRIBE(const Parser& parser) {
|
|||
}
|
||||
|
||||
//解析sdp
|
||||
_uiTrackCnt = parserSDP(strSdp, _aTrackInfo);
|
||||
for (unsigned int i=0; i<_uiTrackCnt; i++) {
|
||||
_aTrackInfo[i].ssrc=0;
|
||||
_aui32SsrcErrorCnt[i]=0;
|
||||
}
|
||||
if (!_uiTrackCnt) {
|
||||
_sdpAttr.load(strSdp);
|
||||
_aTrackInfo = _sdpAttr.getAvailableTrack();
|
||||
|
||||
if (_aTrackInfo.empty()) {
|
||||
throw std::runtime_error("解析SDP失败");
|
||||
}
|
||||
if (!onCheckSDP(strSdp, _aTrackInfo, _uiTrackCnt)) {
|
||||
if (!onCheckSDP(strSdp, _sdpAttr)) {
|
||||
throw std::runtime_error("onCheckSDP faied");
|
||||
}
|
||||
|
||||
CLEAR_ARR(_aui32SsrcErrorCnt)
|
||||
for (auto &track : _aTrackInfo) {
|
||||
track->ssrc=0;
|
||||
}
|
||||
|
||||
sendSetup(0);
|
||||
}
|
||||
//发送SETUP命令
|
||||
|
@ -294,11 +298,11 @@ bool RtspPlayer::sendSetup(unsigned int trackIndex) {
|
|||
_onHandshake = std::bind(&RtspPlayer::handleResSETUP,this, placeholders::_1,trackIndex);
|
||||
|
||||
auto &track = _aTrackInfo[trackIndex];
|
||||
auto baseUrl = _strContentBase + "/" + track.controlSuffix;
|
||||
auto baseUrl = _strContentBase + "/" + track->_control_surffix;
|
||||
switch (_eType) {
|
||||
case RTP_TCP: {
|
||||
StrCaseMap header;
|
||||
header["Transport"] = StrPrinter << "RTP/AVP/TCP;unicast;interleaved=" << track.type * 2 << "-" << track.type * 2 + 1;
|
||||
header["Transport"] = StrPrinter << "RTP/AVP/TCP;unicast;interleaved=" << track->type * 2 << "-" << track->type * 2 + 1;
|
||||
return sendRtspRequest("SETUP",baseUrl,header);
|
||||
}
|
||||
break;
|
||||
|
@ -348,7 +352,7 @@ void RtspPlayer::handleResSETUP(const Parser &parser, unsigned int uiTrackIndex)
|
|||
|
||||
if(_eType == RTP_TCP) {
|
||||
string interleaved = FindField( FindField((strTransport + ";").c_str(), "interleaved=", ";").c_str(), NULL, "-");
|
||||
_aTrackInfo[uiTrackIndex].interleaved = atoi(interleaved.c_str());
|
||||
_aTrackInfo[uiTrackIndex]->interleaved = atoi(interleaved.c_str());
|
||||
}else{
|
||||
const char *strPos = (_eType == RTP_MULTICAST ? "port=" : "server_port=") ;
|
||||
auto port_str = FindField((strTransport + ";").c_str(), strPos, ";");
|
||||
|
@ -377,13 +381,13 @@ void RtspPlayer::handleResSETUP(const Parser &parser, unsigned int uiTrackIndex)
|
|||
}
|
||||
}
|
||||
|
||||
if (uiTrackIndex < _uiTrackCnt - 1) {
|
||||
if (uiTrackIndex < _aTrackInfo.size() - 1) {
|
||||
//需要继续发送SETUP命令
|
||||
sendSetup(uiTrackIndex + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < _uiTrackCnt && _eType != RTP_TCP; i++) {
|
||||
for (unsigned int i = 0; i < _aTrackInfo.size() && _eType != RTP_TCP; i++) {
|
||||
auto &pUdpSockRef = _apUdpSock[i];
|
||||
if(!pUdpSockRef){
|
||||
continue;
|
||||
|
@ -436,13 +440,8 @@ bool RtspPlayer::sendPause(bool bPause,float fTime){
|
|||
_aNowStampTicker[0].resetTime();
|
||||
_aNowStampTicker[1].resetTime();
|
||||
float iTimeInc = fTime - getProgressTime();
|
||||
for(unsigned int i = 0 ;i < _uiTrackCnt ;i++){
|
||||
if (_aTrackInfo[i].type == TrackVideo) {
|
||||
_adFistStamp[i] = _adNowStamp[i] + iTimeInc * 90000.0;
|
||||
}else if (_aTrackInfo[i].type == TrackAudio){
|
||||
//todo(xzl) 修复此处
|
||||
// _adFistStamp[i] = _adNowStamp[i] + iTimeInc * getAudioSampleRate();
|
||||
}
|
||||
for(unsigned int i = 0 ;i < _aTrackInfo.size() ;i++){
|
||||
_adFistStamp[i] = _adNowStamp[i] + iTimeInc * _aTrackInfo[i]->_samplerate;
|
||||
_adNowStamp[i] = _adFistStamp[i];
|
||||
}
|
||||
_fSeekTo = fTime;
|
||||
|
@ -590,7 +589,7 @@ bool RtspPlayer::handleOneRtp(int iTrackidx, unsigned char *pucData, unsigned in
|
|||
auto &track = _aTrackInfo[iTrackidx];
|
||||
auto pt_ptr=_pktPool.obtain();
|
||||
auto &rtppt=*pt_ptr;
|
||||
rtppt.interleaved = track.interleaved;
|
||||
rtppt.interleaved = track->interleaved;
|
||||
rtppt.length = uiLen + 4;
|
||||
|
||||
rtppt.mark = pucData[1] >> 7;
|
||||
|
@ -604,15 +603,15 @@ bool RtspPlayer::handleOneRtp(int iTrackidx, unsigned char *pucData, unsigned in
|
|||
//ssrc
|
||||
memcpy(&rtppt.ssrc,pucData+8,4);//内存对齐
|
||||
rtppt.ssrc = ntohl(rtppt.ssrc);
|
||||
rtppt.type = track.type;
|
||||
if (track.ssrc == 0) {
|
||||
track.ssrc = rtppt.ssrc;
|
||||
rtppt.type = track->type;
|
||||
if (track->ssrc == 0) {
|
||||
track->ssrc = rtppt.ssrc;
|
||||
//保存SSRC
|
||||
} else if (track.ssrc != rtppt.ssrc) {
|
||||
} else if (track->ssrc != rtppt.ssrc) {
|
||||
//ssrc错误
|
||||
WarnL << "ssrc错误";
|
||||
if (_aui32SsrcErrorCnt[iTrackidx]++ > 10) {
|
||||
track.ssrc = rtppt.ssrc;
|
||||
track->ssrc = rtppt.ssrc;
|
||||
WarnL << "ssrc更换!";
|
||||
}
|
||||
return false;
|
||||
|
@ -694,7 +693,7 @@ float RtspPlayer::getRtpLossRate(int iTrackType) const{
|
|||
if(iTrackIdx == -1){
|
||||
uint64_t totalRecv = 0;
|
||||
uint64_t totalSend = 0;
|
||||
for (unsigned int i = 0; i < _uiTrackCnt; i++) {
|
||||
for (unsigned int i = 0; i < _aTrackInfo.size(); i++) {
|
||||
totalRecv += _aui64RtpRecv[i];
|
||||
totalSend += (_aui16NowSeq[i] - _aui16FirstSeq[i] + 1);
|
||||
}
|
||||
|
@ -713,15 +712,8 @@ float RtspPlayer::getRtpLossRate(int iTrackType) const{
|
|||
|
||||
float RtspPlayer::getProgressTime() const{
|
||||
double iTime[2] = {0,0};
|
||||
for(unsigned int i = 0 ;i < _uiTrackCnt ;i++){
|
||||
if (_aTrackInfo[i].type == TrackVideo) {
|
||||
iTime[i] = (_adNowStamp[i] - _adFistStamp[i]) / 90000.0;
|
||||
}else if (_aTrackInfo[i].type == TrackAudio){
|
||||
//todo(xzl) 修复此处
|
||||
#if 0
|
||||
iTime[i] = (_adNowStamp[i] - _adFistStamp[i]) / getAudioSampleRate();
|
||||
#endif
|
||||
}
|
||||
for(unsigned int i = 0 ;i < _aTrackInfo.size() ;i++){
|
||||
iTime[i] = (_adNowStamp[i] - _adFistStamp[i]) / _aTrackInfo[i]->_samplerate;
|
||||
}
|
||||
return _fSeekTo + MAX(iTime[0],iTime[1]);
|
||||
}
|
||||
|
@ -785,7 +777,7 @@ void RtspPlayer::onShutdown_l(const SockException &ex) {
|
|||
_pBeatTimer.reset();
|
||||
onShutdown(ex);
|
||||
}
|
||||
void RtspPlayer::onRecvRTP_l(const RtpPacket::Ptr &pRtppt, const RtspTrack &track) {
|
||||
void RtspPlayer::onRecvRTP_l(const RtpPacket::Ptr &pRtppt, const SdpTrack::Ptr &track) {
|
||||
_rtpTicker.resetTime();
|
||||
onRecvRTP(pRtppt,track);
|
||||
}
|
||||
|
@ -814,16 +806,16 @@ void RtspPlayer::onPlayResult_l(const SockException &ex) {
|
|||
}
|
||||
|
||||
int RtspPlayer::getTrackIndexByControlSuffix(const string &controlSuffix) const{
|
||||
for (unsigned int i = 0; i < _uiTrackCnt; i++) {
|
||||
if (_aTrackInfo[i].controlSuffix == controlSuffix) {
|
||||
for (unsigned int i = 0; i < _aTrackInfo.size(); i++) {
|
||||
if (_aTrackInfo[i]->_control_surffix == controlSuffix) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
int RtspPlayer::getTrackIndexByInterleaved(int interleaved) const{
|
||||
for (unsigned int i = 0; i < _uiTrackCnt; i++) {
|
||||
if (_aTrackInfo[i].interleaved == interleaved) {
|
||||
for (unsigned int i = 0; i < _aTrackInfo.size(); i++) {
|
||||
if (_aTrackInfo[i]->interleaved == interleaved) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
@ -831,8 +823,8 @@ int RtspPlayer::getTrackIndexByInterleaved(int interleaved) const{
|
|||
}
|
||||
|
||||
int RtspPlayer::getTrackIndexByTrackType(TrackType trackType) const {
|
||||
for (unsigned int i = 0; i < _uiTrackCnt; i++) {
|
||||
if (_aTrackInfo[i].type == trackType) {
|
||||
for (unsigned int i = 0; i < _aTrackInfo.size(); i++) {
|
||||
if (_aTrackInfo[i]->type == trackType) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,14 +58,14 @@ public:
|
|||
float getRtpLossRate(int iTrackType) const override;
|
||||
protected:
|
||||
//派生类回调函数
|
||||
virtual bool onCheckSDP(const string &strSdp, const RtspTrack *pTrack, int iTrackCnt) = 0;
|
||||
virtual void onRecvRTP(const RtpPacket::Ptr &pRtppt, const RtspTrack &track) = 0;
|
||||
virtual bool onCheckSDP(const string &strSdp, const SdpAttr &sdpAttr) = 0;
|
||||
virtual void onRecvRTP(const RtpPacket::Ptr &pRtppt, const SdpTrack::Ptr &track) = 0;
|
||||
float getProgressTime() const;
|
||||
void seekToTime(float fTime);
|
||||
private:
|
||||
void onShutdown_l(const SockException &ex);
|
||||
void onRecvRTP_l(const RtpPacket::Ptr &pRtppt, int iTrackidx);
|
||||
void onRecvRTP_l(const RtpPacket::Ptr &pRtppt, const RtspTrack &track);
|
||||
void onRecvRTP_l(const RtpPacket::Ptr &pRtppt, const SdpTrack::Ptr &track);
|
||||
void onPlayResult_l(const SockException &ex);
|
||||
|
||||
int getTrackIndexByControlSuffix(const string &controlSuffix) const;
|
||||
|
@ -97,8 +97,9 @@ private:
|
|||
bool sendRtspRequest(const string &cmd, const string &url ,const StrCaseMap &header = StrCaseMap());
|
||||
private:
|
||||
string _strUrl;
|
||||
unsigned int _uiTrackCnt = 0;
|
||||
RtspTrack _aTrackInfo[2];
|
||||
|
||||
SdpAttr _sdpAttr;
|
||||
vector<SdpTrack::Ptr> _aTrackInfo;
|
||||
|
||||
function<void(const Parser&)> _onHandshake;
|
||||
RtspMediaSource::PoolType _pktPool;
|
||||
|
|
|
@ -62,7 +62,7 @@ public:
|
|||
};
|
||||
private:
|
||||
//派生类回调函数
|
||||
bool onCheckSDP(const string &sdp, const RtspTrack *track, int trackCnt) override {
|
||||
bool onCheckSDP(const string &sdp, const SdpAttr &sdpAttr) override {
|
||||
_pRtspMediaSrc = dynamic_pointer_cast<RtspMediaSource>(_pMediaSrc);
|
||||
if(_pRtspMediaSrc){
|
||||
_pRtspMediaSrc->onGetSDP(sdp);
|
||||
|
@ -70,7 +70,7 @@ private:
|
|||
_parser.reset(new RtspDemuxer(sdp));
|
||||
return true;
|
||||
}
|
||||
void onRecvRTP(const RtpPacket::Ptr &rtppt, const RtspTrack &track) override {
|
||||
void onRecvRTP(const RtpPacket::Ptr &rtppt, const SdpTrack::Ptr &track) override {
|
||||
if(_pRtspMediaSrc){
|
||||
_pRtspMediaSrc->onWrite(rtppt,true);
|
||||
}
|
||||
|
|
|
@ -511,12 +511,12 @@ bool RtspSession::handleReq_Setup() {
|
|||
//未找到相应track
|
||||
return false;
|
||||
}
|
||||
RtspTrack &trackRef = _aTrackInfo[trackIdx];
|
||||
if (trackRef.inited) {
|
||||
SdpTrack::Ptr &trackRef = _aTrackInfo[trackIdx];
|
||||
if (trackRef->inited) {
|
||||
//已经初始化过该Track
|
||||
return false;
|
||||
}
|
||||
trackRef.inited = true; //现在初始化
|
||||
trackRef->inited = true; //现在初始化
|
||||
|
||||
auto strongRing = _pWeakRing.lock();
|
||||
if (!strongRing) {
|
||||
|
@ -562,9 +562,9 @@ bool RtspSession::handleReq_Setup() {
|
|||
"x-Dynamic-Rate: 1\r\n\r\n",
|
||||
_iCseq, SERVER_NAME,
|
||||
RTSP_VERSION, RTSP_BUILDTIME,
|
||||
dateHeader().data(), trackRef.type * 2,
|
||||
trackRef.type * 2 + 1,
|
||||
printSSRC(trackRef.ssrc).data(),
|
||||
dateHeader().data(), trackRef->type * 2,
|
||||
trackRef->type * 2 + 1,
|
||||
printSSRC(trackRef->ssrc).data(),
|
||||
_strSession.data());
|
||||
SocketHelper::send(_pcBuf, iLen);
|
||||
}
|
||||
|
@ -609,7 +609,7 @@ bool RtspSession::handleReq_Setup() {
|
|||
RTSP_VERSION, RTSP_BUILDTIME,
|
||||
dateHeader().data(), strClientPort.data(),
|
||||
pSockRtp->get_local_port(), pSockRtcp->get_local_port(),
|
||||
printSSRC(trackRef.ssrc).data(),
|
||||
printSSRC(trackRef->ssrc).data(),
|
||||
_strSession.data());
|
||||
SocketHelper::send(_pcBuf, n);
|
||||
}
|
||||
|
@ -630,7 +630,7 @@ bool RtspSession::handleReq_Setup() {
|
|||
strongSelf->safeShutdown();
|
||||
});
|
||||
}
|
||||
int iSrvPort = _pBrdcaster->getPort(trackRef.type);
|
||||
int iSrvPort = _pBrdcaster->getPort(trackRef->type);
|
||||
//我们用trackIdx区分rtp和rtcp包
|
||||
auto pSockRtcp = UDPServer::Instance().getSock(get_local_ip().data(),2*trackIdx + 1,iSrvPort + 1);
|
||||
if (!pSockRtcp) {
|
||||
|
@ -652,7 +652,7 @@ bool RtspSession::handleReq_Setup() {
|
|||
RTSP_VERSION, RTSP_BUILDTIME,
|
||||
dateHeader().data(), _pBrdcaster->getIP().data(),
|
||||
get_local_ip().data(), iSrvPort, pSockRtcp->get_local_port(),
|
||||
udpTTL,printSSRC(trackRef.ssrc).data(),
|
||||
udpTTL,printSSRC(trackRef->ssrc).data(),
|
||||
_strSession.data());
|
||||
SocketHelper::send(_pcBuf, n);
|
||||
}
|
||||
|
@ -733,9 +733,9 @@ bool RtspSession::handleReq_Play() {
|
|||
}
|
||||
for (unsigned int i = 0; i < _uiTrackCnt; i++) {
|
||||
auto &track = _aTrackInfo[i];
|
||||
track.ssrc = pMediaSrc->getSsrc(track.type);
|
||||
track.seq = pMediaSrc->getSeqence(track.type);
|
||||
track.timeStamp = pMediaSrc->getTimestamp(track.type);
|
||||
track->ssrc = pMediaSrc->getSsrc(track->type);
|
||||
track->seq = pMediaSrc->getSeqence(track->type);
|
||||
track->timeStamp = pMediaSrc->getTimestamp(track->type);
|
||||
}
|
||||
}
|
||||
_bFirstPlay = false;
|
||||
|
@ -750,13 +750,13 @@ bool RtspSession::handleReq_Play() {
|
|||
|
||||
for (unsigned int i = 0; i < _uiTrackCnt; i++) {
|
||||
auto &track = _aTrackInfo[i];
|
||||
if (track.inited == false) {
|
||||
if (track->inited == false) {
|
||||
//还有track没有setup
|
||||
shutdown();
|
||||
return;
|
||||
}
|
||||
iLen += sprintf(_pcBuf + iLen, "url=%s/%s;seq=%d;rtptime=%u,",
|
||||
_strUrl.data(), track.controlSuffix.data(), track.seq,track.timeStamp);
|
||||
_strUrl.data(), track->_control_surffix.data(), track->seq,track->timeStamp);
|
||||
}
|
||||
iLen -= 1;
|
||||
(_pcBuf)[iLen] = '\0';
|
||||
|
@ -895,7 +895,10 @@ inline bool RtspSession::findStream() {
|
|||
_strSdp = pMediaSrc->getSdp();
|
||||
_pWeakRing = pMediaSrc->getRing();
|
||||
|
||||
_uiTrackCnt = parserSDP(_strSdp, _aTrackInfo);
|
||||
_sdpAttr.load(_strSdp);
|
||||
_aTrackInfo = _sdpAttr.getAvailableTrack();
|
||||
_uiTrackCnt = _aTrackInfo.size();
|
||||
|
||||
if (_uiTrackCnt == 0 || _uiTrackCnt > 2) {
|
||||
return false;
|
||||
}
|
||||
|
@ -904,9 +907,9 @@ inline bool RtspSession::findStream() {
|
|||
|
||||
for (unsigned int i = 0; i < _uiTrackCnt; i++) {
|
||||
auto &track = _aTrackInfo[i];
|
||||
track.ssrc = pMediaSrc->getSsrc(track.type);
|
||||
track.seq = pMediaSrc->getSeqence(track.type);
|
||||
track.timeStamp = pMediaSrc->getTimestamp(track.type);
|
||||
track->ssrc = pMediaSrc->getSsrc(track->type);
|
||||
track->seq = pMediaSrc->getSeqence(track->type);
|
||||
track->timeStamp = pMediaSrc->getTimestamp(track->type);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -118,7 +118,7 @@ private:
|
|||
}
|
||||
inline int getTrackIndexByTrackType(TrackType type) {
|
||||
for (unsigned int i = 0; i < _uiTrackCnt; i++) {
|
||||
if (type == _aTrackInfo[i].type) {
|
||||
if (type == _aTrackInfo[i]->type) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ private:
|
|||
}
|
||||
inline int getTrackIndexByControlSuffix(const string &controlSuffix) {
|
||||
for (unsigned int i = 0; i < _uiTrackCnt; i++) {
|
||||
if (controlSuffix == _aTrackInfo[i].controlSuffix) {
|
||||
if (controlSuffix == _aTrackInfo[i]->_control_surffix) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
@ -161,8 +161,11 @@ private:
|
|||
PlayerBase::eRtpType _rtpType = PlayerBase::RTP_UDP;
|
||||
bool _bSetUped = false;
|
||||
int _iCseq = 0;
|
||||
|
||||
SdpAttr _sdpAttr;
|
||||
unsigned int _uiTrackCnt = 0; //媒体track个数
|
||||
RtspTrack _aTrackInfo[2]; //媒体track信息,trackid idx 为数组下标
|
||||
vector<SdpTrack::Ptr> _aTrackInfo;
|
||||
|
||||
bool _bGotAllPeerUdp = false;
|
||||
|
||||
#ifdef RTSP_SEND_RTCP
|
||||
|
|
|
@ -51,25 +51,34 @@ static int getTimeInSDP(const string &sdp) {
|
|||
return atof(strEnd.data()) - atof(strStart.data());
|
||||
}
|
||||
RtspDemuxer::RtspDemuxer(const string& sdp) {
|
||||
RtspTrack tmp[2];
|
||||
int cnt = parserSDP(sdp, tmp);
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
switch (tmp[i].type) {
|
||||
case TrackVideo: {
|
||||
makeVideoTrack(tmp[i]);
|
||||
}
|
||||
break;
|
||||
case TrackAudio: {
|
||||
makeAudioTrack(tmp[i]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
_fDuration = getTimeInSDP(sdp);
|
||||
loadSdp(SdpAttr(sdp));
|
||||
}
|
||||
|
||||
RtspDemuxer::RtspDemuxer(const SdpAttr &attr) {
|
||||
loadSdp(attr);
|
||||
}
|
||||
|
||||
void RtspDemuxer::loadSdp(const SdpAttr &attr) {
|
||||
auto tracks = attr.getAvailableTrack();
|
||||
for (auto &track : tracks){
|
||||
switch (track->type) {
|
||||
case TrackVideo: {
|
||||
makeVideoTrack(track);
|
||||
}
|
||||
break;
|
||||
case TrackAudio: {
|
||||
makeAudioTrack(track);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
auto titleTrack = attr.getTrack(TrackTitle);
|
||||
if(titleTrack){
|
||||
_fDuration = titleTrack->_duration;
|
||||
}
|
||||
}
|
||||
bool RtspDemuxer::inputRtp(const RtpPacket::Ptr & rtp) {
|
||||
switch (rtp->type) {
|
||||
case TrackVideo:{
|
||||
|
@ -91,9 +100,9 @@ bool RtspDemuxer::inputRtp(const RtpPacket::Ptr & rtp) {
|
|||
}
|
||||
|
||||
|
||||
void RtspDemuxer::makeAudioTrack(const RtspTrack &audio) {
|
||||
void RtspDemuxer::makeAudioTrack(const SdpTrack::Ptr &audio) {
|
||||
//生成Track对象
|
||||
_audioTrack = dynamic_pointer_cast<AudioTrack>(Factory::getTrackBySdp(audio.trackSdp));
|
||||
_audioTrack = dynamic_pointer_cast<AudioTrack>(Factory::getTrackBySdp(audio));
|
||||
if(_audioTrack){
|
||||
//生成RtpCodec对象以便解码rtp
|
||||
_audioRtpDecoder = Factory::getRtpDecoderById(_audioTrack->getCodecId(),_audioTrack->getAudioSampleRate());
|
||||
|
@ -107,9 +116,9 @@ void RtspDemuxer::makeAudioTrack(const RtspTrack &audio) {
|
|||
}
|
||||
}
|
||||
|
||||
void RtspDemuxer::makeVideoTrack(const RtspTrack &video) {
|
||||
void RtspDemuxer::makeVideoTrack(const SdpTrack::Ptr &video) {
|
||||
//生成Track对象
|
||||
_videoTrack = dynamic_pointer_cast<VideoTrack>(Factory::getTrackBySdp(video.trackSdp));
|
||||
_videoTrack = dynamic_pointer_cast<VideoTrack>(Factory::getTrackBySdp(video));
|
||||
if(_videoTrack){
|
||||
//生成RtpCodec对象以便解码rtp
|
||||
_videoRtpDecoder = Factory::getRtpDecoderById(_videoTrack->getCodecId(),90000);
|
||||
|
@ -152,5 +161,4 @@ float RtspDemuxer::getDuration() const {
|
|||
return _fDuration;
|
||||
}
|
||||
|
||||
|
||||
} /* namespace mediakit */
|
||||
|
|
|
@ -43,6 +43,7 @@ class RtspDemuxer : public PlayerBase{
|
|||
public:
|
||||
typedef std::shared_ptr<RtspDemuxer> Ptr;
|
||||
RtspDemuxer(const string &sdp);
|
||||
RtspDemuxer(const SdpAttr &attr);
|
||||
virtual ~RtspDemuxer(){};
|
||||
|
||||
/**
|
||||
|
@ -72,8 +73,9 @@ public:
|
|||
*/
|
||||
vector<Track::Ptr> getTracks() const override;
|
||||
private:
|
||||
void makeAudioTrack(const RtspTrack &audio);
|
||||
void makeVideoTrack(const RtspTrack &video);
|
||||
void makeAudioTrack(const SdpTrack::Ptr &audio);
|
||||
void makeVideoTrack(const SdpTrack::Ptr &video);
|
||||
void loadSdp(const SdpAttr &attr);
|
||||
private:
|
||||
float _fDuration = 0;
|
||||
AudioTrack::Ptr _audioTrack;
|
||||
|
|
Loading…
Reference in New Issue
Block a user