Commit 6a7c76be by xiongziliang

添加新的sdp解析算法

parent 062bdd6e
...@@ -44,6 +44,7 @@ typedef enum { ...@@ -44,6 +44,7 @@ typedef enum {
TrackInvalid = -1, TrackInvalid = -1,
TrackVideo = 0, TrackVideo = 0,
TrackAudio, TrackAudio,
TrackTitle,
TrackMax TrackMax
} TrackType; } TrackType;
......
...@@ -75,7 +75,7 @@ public: ...@@ -75,7 +75,7 @@ public:
* @return * @return
*/ */
TrackType getTrackType() const override { TrackType getTrackType() const override {
return TrackInvalid; return TrackTitle;
} }
/** /**
......
...@@ -49,78 +49,124 @@ string FindField(const char* buf, const char* start, const char *end ,int bufSiz ...@@ -49,78 +49,124 @@ string FindField(const char* buf, const char* start, const char *end ,int bufSiz
} }
return string(msg_start, msg_end); return string(msg_start, msg_end);
} }
int parserSDP(const string& sdp, RtspTrack Track[2]) {
map<string,map<char ,map<string ,string> > > sdpAttr;
string sdpTrack = ""; void SdpAttr::load(const string &sdp) {
_track_map.clear();
string key;
SdpTrack::Ptr track = std::make_shared<SdpTrack>();
auto lines = split(sdp,"\n"); auto lines = split(sdp,"\n");
for (auto &line : lines){ for (auto &line : lines){
trim(line); trim(line);
if(line.size() < 2){ if(line.size() < 2 || line[1] != '='){
continue;
}
if(line[1] != '='){
continue; continue;
} }
char opt = line[0]; char opt = line[0];
string opt_val = line.substr(2); string opt_val = line.substr(2);
switch (opt){ switch (opt){
case 'o': case 'o':
track->_o = opt_val;
break;
case 's': case 's':
track->_s = opt_val;
break;
case 'i': case 'i':
track->_i = opt_val;
break;
case 'c': case 'c':
case 't':{ track->_c = opt_val;
sdpAttr[sdpTrack][opt][""] = opt_val; break;
} case 't':
track->_t = opt_val;
break;
case 'b':
track->_b = opt_val;
break; break;
case 'm':{ case 'm':{
sdpTrack = FindField(opt_val.data(), nullptr," "); _track_map[key] = track;
sdpAttr[sdpTrack][opt][""] = opt_val; track = std::make_shared<SdpTrack>();
key = FindField(opt_val.data(), nullptr," ");;
track->_m = opt_val;
} }
break; break;
case 'a':{ case 'a':{
string attr = FindField(opt_val.data(), nullptr,":"); string attr = FindField(opt_val.data(), nullptr,":");
if(attr.empty()){ if(attr.empty()){
sdpAttr[sdpTrack][opt][opt_val] = opt_val; track->_attr[opt_val] = "";
}else{ }else{
sdpAttr[sdpTrack][opt][attr] = FindField(opt_val.data(),":", nullptr); track->_attr[attr] = FindField(opt_val.data(),":", nullptr);
} }
} }
break; break;
default: default:
track->_other[opt] = opt_val;
break; break;
} }
} }
_track_map[key] = track;
for (auto &pr : sdpAttr) { for (auto &pr : _track_map) {
TrackType trackType = TrackInvalid; auto &track = *pr.second;
if (pr.first == "video") { if (pr.first == "") {
trackType = TrackVideo; track._type = TrackTitle;
} else if (pr.first == "video") {
track._type = TrackVideo;
} else if (pr.first == "audio") { } else if (pr.first == "audio") {
trackType = TrackAudio; track._type = TrackAudio;
} else if (pr.first == "") { } else {
//title track._type = TrackInvalid;
auto range = pr.second['a']["range"]; }
char name[16] = {0},start[16] = {0},end[16] = {0};
if (2 == sscanf(range.data(), "%15[^=]=%15[^-]-%15s", name, start, end)) {
auto it = track._attr.find("range");
if (it != track._attr.end()) {
char name[16] = {0}, start[16] = {0}, end[16] = {0};
int ret = sscanf(it->second.data(), "%15[^=]=%15[^-]-%15s", name, start, end);
if (3 == ret || 2 == ret) {
if (strcmp(start, "now") == 0) {
strcpy(start, "0");
}
track._start = atof(start);
track._end = atof(end);
track._duration = track._end - track._start;
} }
DebugL << range;
continue;
} else {
continue;
} }
auto rtpmap = pr.second['a']["rtpmap"]; it = track._attr.find("rtpmap");
int pt, samplerate; if(it != track._attr.end()){
char codec[16] = {0}; auto rtpmap = it->second;
if (3 == sscanf(rtpmap.data(), "%d %15[^/]/%d", &pt, codec, &samplerate)) { int pt, samplerate;
char codec[16] = {0};
if (3 == sscanf(rtpmap.data(), "%d %15[^/]/%d", &pt, codec, &samplerate)) {
track._pt = pt;
track._codec = codec;
track._samplerate = samplerate;
}
}
it = track._attr.find("fmtp");
if(it != track._attr.end()) {
track._fmtp = it->second;
}
it = track._attr.find("control");
if(it != track._attr.end()) {
track._control = it->second;
} }
DebugL << codec;
} }
}
SdpTrack::Ptr SdpAttr::getTrack(TrackType type) {
for (auto &pr : _track_map){
if(pr.second->_type == type){
return pr.second;
}
}
return nullptr;
}
int parserSDP(const string& sdp, RtspTrack Track[2]) {
int track_cnt = 0; int track_cnt = 0;
string::size_type pos_head = 0; string::size_type pos_head = 0;
while ((pos_head = sdp.find("m=",pos_head)) != string::npos ) { while ((pos_head = sdp.find("m=",pos_head)) != string::npos ) {
...@@ -169,6 +215,7 @@ static onceToken s_token([](){ ...@@ -169,6 +215,7 @@ static onceToken s_token([](){
"a=recvonly"; "a=recvonly";
RtspTrack track[2]; RtspTrack track[2];
parserSDP(str,track); parserSDP(str,track);
SdpAttr attr(str);
track[0].inited=true; track[0].inited=true;
}); });
bool MakeNalu(uint8_t in, NALU &nal) { bool MakeNalu(uint8_t in, NALU &nal) {
...@@ -190,3 +237,5 @@ bool MakeFU(uint8_t in, FU &fu) { ...@@ -190,3 +237,5 @@ bool MakeFU(uint8_t in, FU &fu) {
} }
return true; return true;
} }
...@@ -38,6 +38,43 @@ using namespace std; ...@@ -38,6 +38,43 @@ using namespace std;
using namespace toolkit; using namespace toolkit;
using namespace mediakit; using namespace mediakit;
class SdpTrack{
public:
typedef std::shared_ptr<SdpTrack> Ptr;
string _m;
string _o;
string _s;
string _i;
string _c;
string _t;
string _b;
float _duration = 0;
float _start = 0;
float _end = 0;
map<char,string> _other;
map<string,string> _attr;
public:
int _pt;
string _codec;
int _samplerate;
string _fmtp;
string _control;
TrackType _type;
};
class SdpAttr {
public:
typedef std::shared_ptr<SdpAttr> Ptr;
SdpAttr(const string &sdp){load(sdp);};
~SdpAttr(){}
void load(const string &sdp);
SdpTrack::Ptr getTrack(TrackType type);
private:
map<string,SdpTrack::Ptr> _track_map;
};
class RtspTrack{ class RtspTrack{
public: public:
...@@ -63,7 +100,6 @@ public: ...@@ -63,7 +100,6 @@ public:
string FindField(const char* buf, const char* start, const char *end,int bufSize = 0 ); string FindField(const char* buf, const char* start, const char *end,int bufSize = 0 );
int parserSDP(const string& sdp, RtspTrack Track[2]); int parserSDP(const string& sdp, RtspTrack Track[2]);
struct StrCaseCompare struct StrCaseCompare
{ {
bool operator()(const string& __x, const string& __y) const bool operator()(const string& __x, const string& __y) const
......
...@@ -115,7 +115,7 @@ public: ...@@ -115,7 +115,7 @@ public:
* @return * @return
*/ */
TrackType getTrackType() const override { TrackType getTrackType() const override {
return TrackInvalid; return TrackTitle;
} }
/** /**
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论