替换sdp解析逻辑

This commit is contained in:
xiongziliang 2018-10-26 09:56:29 +08:00
parent a69d7d0f71
commit 6fe90fe4ba
12 changed files with 147 additions and 179 deletions

View File

@ -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;
}

View File

@ -53,7 +53,7 @@ public:
/**
* sdp生成Track对象
*/
static Track::Ptr getTrackBySdp(const string &sdp);
static Track::Ptr getTrackBySdp(const SdpTrack::Ptr &track);
/**
* Track生成SDP对象

View File

@ -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;
});

View File

@ -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
{

View File

@ -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环形缓冲
};

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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

View File

@ -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 */

View File

@ -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;