Commit 07c5341f by ziyue

兼容一些奇怪的rtsp流:#1031

parent 8b1d1d6e
...@@ -26,7 +26,18 @@ ...@@ -26,7 +26,18 @@
namespace mediakit{ namespace mediakit{
Track::Ptr Factory::getTrackBySdp(const SdpTrack::Ptr &track) { Track::Ptr Factory::getTrackBySdp(const SdpTrack::Ptr &track) {
if (strcasecmp(track->_codec.data(), "mpeg4-generic") == 0) { auto codec = getCodecId(track->_codec);
if (codec == CodecInvalid) {
//根据传统的payload type 获取编码类型以及采样率等信息
codec = RtpPayload::getCodecId(track->_pt);
}
switch (codec) {
case CodecG711A:
case CodecG711U: return std::make_shared<G711Track>(codec, track->_samplerate, track->_channel, 16);
case CodecL16: return std::make_shared<L16Track>(track->_samplerate, track->_channel);
case CodecOpus : return std::make_shared<OpusTrack>();
case CodecAAC : {
string aac_cfg_str = FindField(track->_fmtp.data(), "config=", ";"); string aac_cfg_str = FindField(track->_fmtp.data(), "config=", ";");
if (aac_cfg_str.empty()) { if (aac_cfg_str.empty()) {
aac_cfg_str = FindField(track->_fmtp.data(), "config=", nullptr); aac_cfg_str = FindField(track->_fmtp.data(), "config=", nullptr);
...@@ -36,70 +47,49 @@ Track::Ptr Factory::getTrackBySdp(const SdpTrack::Ptr &track) { ...@@ -36,70 +47,49 @@ Track::Ptr Factory::getTrackBySdp(const SdpTrack::Ptr &track) {
return nullptr; return nullptr;
} }
string aac_cfg; string aac_cfg;
for(size_t i = 0 ; i < aac_cfg_str.size() / 2 ; ++i ){ for (size_t i = 0; i < aac_cfg_str.size() / 2; ++i) {
unsigned int cfg; unsigned int cfg;
sscanf(aac_cfg_str.substr(i * 2, 2).data(), "%02X", &cfg); sscanf(aac_cfg_str.substr(i * 2, 2).data(), "%02X", &cfg);
cfg &= 0x00FF; cfg &= 0x00FF;
aac_cfg.push_back((char)cfg); aac_cfg.push_back((char) cfg);
} }
return std::make_shared<AACTrack>(aac_cfg); return std::make_shared<AACTrack>(aac_cfg);
} }
if (strcasecmp(track->_codec.data(), "opus") == 0) { case CodecH264 : {
return std::make_shared<OpusTrack>();
}
if (strcasecmp(track->_codec.data(), "PCMA") == 0) {
return std::make_shared<G711Track>(CodecG711A, track->_samplerate, track->_channel, 16);
}
if (strcasecmp(track->_codec.data(), "PCMU") == 0) {
return std::make_shared<G711Track>(CodecG711U, track->_samplerate, track->_channel, 16);
}
if (strcasecmp(track->_codec.data(), "L16") == 0) {
return std::make_shared<L16Track>(track->_samplerate, track->_channel);
}
if (strcasecmp(track->_codec.data(), "h264") == 0) {
//a=fmtp:96 packetization-mode=1;profile-level-id=42C01F;sprop-parameter-sets=Z0LAH9oBQBboQAAAAwBAAAAPI8YMqA==,aM48gA== //a=fmtp:96 packetization-mode=1;profile-level-id=42C01F;sprop-parameter-sets=Z0LAH9oBQBboQAAAAwBAAAAPI8YMqA==,aM48gA==
auto map = Parser::parseArgs(FindField(track->_fmtp.data()," ", nullptr),";","="); auto map = Parser::parseArgs(track->_fmtp, ";", "=");
auto sps_pps = map["sprop-parameter-sets"]; auto sps_pps = map["sprop-parameter-sets"];
string base64_SPS = FindField(sps_pps.data(), NULL, ","); string base64_SPS = FindField(sps_pps.data(), NULL, ",");
string base64_PPS = FindField(sps_pps.data(), ",", NULL); string base64_PPS = FindField(sps_pps.data(), ",", NULL);
auto sps = decodeBase64(base64_SPS); auto sps = decodeBase64(base64_SPS);
auto pps = decodeBase64(base64_PPS); auto pps = decodeBase64(base64_PPS);
if(sps.empty() || pps.empty()){ if (sps.empty() || pps.empty()) {
//如果sdp里面没有sps/pps,那么可能在后续的rtp里面恢复出sps/pps //如果sdp里面没有sps/pps,那么可能在后续的rtp里面恢复出sps/pps
return std::make_shared<H264Track>(); return std::make_shared<H264Track>();
} }
return std::make_shared<H264Track>(sps, pps, 0, 0);
return std::make_shared<H264Track>(sps,pps,0,0);
} }
if (strcasecmp(track->_codec.data(), "h265") == 0) { case CodecH265: {
//a=fmtp:96 sprop-sps=QgEBAWAAAAMAsAAAAwAAAwBdoAKAgC0WNrkky/AIAAADAAgAAAMBlQg=; sprop-pps=RAHA8vA8kAA= //a=fmtp:96 sprop-sps=QgEBAWAAAAMAsAAAAwAAAwBdoAKAgC0WNrkky/AIAAADAAgAAAMBlQg=; sprop-pps=RAHA8vA8kAA=
auto map = Parser::parseArgs(FindField(track->_fmtp.data()," ", nullptr),";","="); auto map = Parser::parseArgs(track->_fmtp, ";", "=");
auto vps = decodeBase64(map["sprop-vps"]); auto vps = decodeBase64(map["sprop-vps"]);
auto sps = decodeBase64(map["sprop-sps"]); auto sps = decodeBase64(map["sprop-sps"]);
auto pps = decodeBase64(map["sprop-pps"]); auto pps = decodeBase64(map["sprop-pps"]);
if(sps.empty() || pps.empty()){ if (sps.empty() || pps.empty()) {
//如果sdp里面没有sps/pps,那么可能在后续的rtp里面恢复出sps/pps //如果sdp里面没有sps/pps,那么可能在后续的rtp里面恢复出sps/pps
return std::make_shared<H265Track>(); return std::make_shared<H265Track>();
} }
return std::make_shared<H265Track>(vps,sps,pps,0,0,0); return std::make_shared<H265Track>(vps, sps, pps, 0, 0, 0);
}
//可以根据传统的payload type 获取编码类型以及采样率等信息
CodecId codec_id = RtpPayload::getCodecId(track->_pt);
switch (codec_id){
case CodecG711A :
case CodecG711U : return std::make_shared<G711Track>(codec_id, track->_samplerate, track->_channel, 16);
default : break;
} }
WarnL << "暂不支持该sdp:" << track->getName(); default: {
//其他codec不支持
WarnL << "暂不支持该rtsp编码类型:" << track->getName();
return nullptr; return nullptr;
}
}
} }
RtpCodec::Ptr Factory::getRtpEncoderBySdp(const Sdp::Ptr &sdp) { RtpCodec::Ptr Factory::getRtpEncoderBySdp(const Sdp::Ptr &sdp) {
......
...@@ -220,7 +220,7 @@ public: ...@@ -220,7 +220,7 @@ public:
float _end = 0; float _end = 0;
map<char, string> _other; map<char, string> _other;
map<string, string> _attr; multimap<string, string> _attr;
string toString() const; string toString() const;
string getName() const; string getName() const;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论