Fixed RTSP/SDP control track selection

This commit is contained in:
Ramoe 2017-08-02 10:51:09 +02:00 committed by Thulinma
parent baca95f0bf
commit d2d80c7360

View file

@ -4,6 +4,7 @@
#include "encode.h" #include "encode.h"
#include "h264.h" #include "h264.h"
#include "h265.h" #include "h265.h"
#include "http_parser.h"
#include "util.h" #include "util.h"
namespace SDP{ namespace SDP{
@ -93,8 +94,7 @@ namespace SDP{
mediaDesc << Encodings::Base64::encode(*it); mediaDesc << Encodings::Base64::encode(*it);
} }
} }
mediaDesc << "\r\na=framerate:" mediaDesc << "\r\na=framerate:" << ((double)trk.fpks) / 1000.0 << "\r\n"
<< ((double)trk.fpks) / 1000.0 << "\r\n"
"a=control:track" "a=control:track"
<< trk.trackID << "\r\n"; << trk.trackID << "\r\n";
}else if (trk.codec == "MPEG2"){ }else if (trk.codec == "MPEG2"){
@ -423,9 +423,12 @@ namespace SDP{
updateH264Init(trackNo); updateH264Init(trackNo);
} }
if (thisTrack->codec == "HEVC"){ if (thisTrack->codec == "HEVC"){
tracks[trackNo].hevcInfo.addUnit(Encodings::Base64::decode(tracks[trackNo].getParamString("sprop-vps"))); tracks[trackNo].hevcInfo.addUnit(
tracks[trackNo].hevcInfo.addUnit(Encodings::Base64::decode(tracks[trackNo].getParamString("sprop-sps"))); Encodings::Base64::decode(tracks[trackNo].getParamString("sprop-vps")));
tracks[trackNo].hevcInfo.addUnit(Encodings::Base64::decode(tracks[trackNo].getParamString("sprop-pps"))); tracks[trackNo].hevcInfo.addUnit(
Encodings::Base64::decode(tracks[trackNo].getParamString("sprop-sps")));
tracks[trackNo].hevcInfo.addUnit(
Encodings::Base64::decode(tracks[trackNo].getParamString("sprop-pps")));
updateH265Init(trackNo); updateH265Init(trackNo);
} }
continue; continue;
@ -498,14 +501,22 @@ namespace SDP{
return trackCounter; return trackCounter;
} }
HTTP::URL url(H.url);
std::string urlString = url.getBareUrl();
std::string pw = H.GetVar("pass");
if (tracks.size()){ if (tracks.size()){
for (std::map<uint32_t, Track>::iterator it = tracks.begin(); it != tracks.end(); ++it){ for (std::map<uint32_t, Track>::iterator it = tracks.begin(); it != tracks.end(); ++it){
if (!it->second.control.size()){ if (!it->second.control.size()){
it->second.control = "track" + JSON::Value((long long)it->first).asString(); it->second.control = "/track" + JSON::Value((long long)it->first).asString();
INFO_MSG("Control track: %s", it->second.control.c_str()); INFO_MSG("Control track: %s", it->second.control.c_str());
} }
if (H.url.find(it->second.control) != std::string::npos ||
H.GetVar("pass").find(it->second.control) != std::string::npos){ if ((urlString.size() >= it->second.control.size() &&
urlString.substr(urlString.size() - it->second.control.size()) ==
it->second.control) ||
(pw.size() >= it->second.control.size() &&
pw.substr(pw.size() - it->second.control.size()) == it->second.control)){
INFO_MSG("Parsing SETUP against track %lu", it->first); INFO_MSG("Parsing SETUP against track %lu", it->first);
if (!it->second.parseTransport(H.GetHeader("Transport"), cH, src, if (!it->second.parseTransport(H.GetHeader("Transport"), cH, src,
myMeta->tracks[it->first])){ myMeta->tracks[it->first])){
@ -656,7 +667,8 @@ namespace SDP{
if (incomingPacketCallback){incomingPacketCallback(nextPack);} if (incomingPacketCallback){incomingPacketCallback(nextPack);}
} }
///Returns the multiplier to use to get milliseconds from the RTP payload type for the given track /// Returns the multiplier to use to get milliseconds from the RTP payload type for the given
/// track
double getMultiplier(const DTSC::Track &Trk){ double getMultiplier(const DTSC::Track &Trk){
if (Trk.type == "video" || Trk.codec == "MP2" || Trk.codec == "MP3"){return 90.0;} if (Trk.type == "video" || Trk.codec == "MP2" || Trk.codec == "MP3"){return 90.0;}
return ((double)Trk.rate / 1000.0); return ((double)Trk.rate / 1000.0);
@ -670,7 +682,8 @@ namespace SDP{
uint64_t millis = (pkt.getTimeStamp() - tracks[track].firstTime + 1) / getMultiplier(Trk); uint64_t millis = (pkt.getTimeStamp() - tracks[track].firstTime + 1) / getMultiplier(Trk);
char *pl = pkt.getPayload(); char *pl = pkt.getPayload();
uint32_t plSize = pkt.getPayloadSize(); uint32_t plSize = pkt.getPayloadSize();
INSANE_MSG("Received RTP packet for track %llu, time %llu -> %llu", track, pkt.getTimeStamp(), millis); INSANE_MSG("Received RTP packet for track %llu, time %llu -> %llu", track, pkt.getTimeStamp(),
millis);
if (Trk.codec == "ALAW" || Trk.codec == "opus" || Trk.codec == "PCM"){ if (Trk.codec == "ALAW" || Trk.codec == "opus" || Trk.codec == "PCM"){
DTSC::Packet nextPack; DTSC::Packet nextPack;
nextPack.genericFill(millis, 0, track, pl, plSize, 0, false); nextPack.genericFill(millis, 0, track, pl, plSize, 0, false);
@ -689,10 +702,9 @@ namespace SDP{
uint32_t auSize = 0; uint32_t auSize = 0;
for (uint32_t i = 2; i < headLen; i += 2){ for (uint32_t i = 2; i < headLen; i += 2){
auSize = Bit::btohs(pl + i) >> 3; // only the upper 13 bits auSize = Bit::btohs(pl + i) >> 3; // only the upper 13 bits
nextPack.genericFill((pkt.getTimeStamp() + sampleOffset - tracks[track].firstTime + 1) / nextPack.genericFill(
getMultiplier(Trk), (pkt.getTimeStamp() + sampleOffset - tracks[track].firstTime + 1) / getMultiplier(Trk),
0, track, pl + headLen + offset, 0, track, pl + headLen + offset, std::min(auSize, plSize - headLen - offset), 0, false);
std::min(auSize, plSize - headLen - offset), 0, false);
offset += auSize; offset += auSize;
sampleOffset += samples; sampleOffset += samples;
if (incomingPacketCallback){incomingPacketCallback(nextPack);} if (incomingPacketCallback){incomingPacketCallback(nextPack);}
@ -738,8 +750,7 @@ namespace SDP{
HIGH_MSG("Not start of a new FU - throwing away"); HIGH_MSG("Not start of a new FU - throwing away");
return; return;
} }
if (fuaBuffer.size() && if (fuaBuffer.size() && ((pl[2] & 0x80) || (tracks[track].rtpSeq != pkt.getSequence()))){
((pl[2] & 0x80) || (tracks[track].rtpSeq != pkt.getSequence()))){
WARN_MSG("H265 FU packet incompleted: %lu", fuaBuffer.size()); WARN_MSG("H265 FU packet incompleted: %lu", fuaBuffer.size());
Bit::htobl(fuaBuffer, fuaBuffer.size() - 4); // size-prepend Bit::htobl(fuaBuffer, fuaBuffer.size() - 4); // size-prepend
fuaBuffer[4] |= 0x80; // set error bit fuaBuffer[4] |= 0x80; // set error bit
@ -763,8 +774,9 @@ namespace SDP{
fuaBuffer.size() += len; fuaBuffer.size() += len;
if (pl[2] & 0x40){// last packet if (pl[2] & 0x40){// last packet
VERYHIGH_MSG("H265 FU packet type %s (%u) completed: %lu", h265::typeToStr((fuaBuffer[4] & 0x7E) >> 1), (uint8_t)((fuaBuffer[4] & 0x7E) >> 1), VERYHIGH_MSG("H265 FU packet type %s (%u) completed: %lu",
fuaBuffer.size()); h265::typeToStr((fuaBuffer[4] & 0x7E) >> 1),
(uint8_t)((fuaBuffer[4] & 0x7E) >> 1), fuaBuffer.size());
Bit::htobl(fuaBuffer, fuaBuffer.size() - 4); // size-prepend Bit::htobl(fuaBuffer, fuaBuffer.size() - 4); // size-prepend
h265Packet((pkt.getTimeStamp() - tracks[track].firstTime + 1) / 90, track, fuaBuffer, h265Packet((pkt.getTimeStamp() - tracks[track].firstTime + 1) / 90, track, fuaBuffer,
fuaBuffer.size(), h265::isKeyframe(fuaBuffer + 4, fuaBuffer.size() - 4)); fuaBuffer.size(), h265::isKeyframe(fuaBuffer + 4, fuaBuffer.size() - 4));
@ -845,8 +857,7 @@ namespace SDP{
HIGH_MSG("Not start of a new FU-A - throwing away"); HIGH_MSG("Not start of a new FU-A - throwing away");
return; return;
} }
if (fuaBuffer.size() && if (fuaBuffer.size() && ((pl[1] & 0x80) || (tracks[track].rtpSeq != pkt.getSequence()))){
((pl[1] & 0x80) || (tracks[track].rtpSeq != pkt.getSequence()))){
WARN_MSG("Ending unfinished FU-A"); WARN_MSG("Ending unfinished FU-A");
INSANE_MSG("H264 FU-A packet incompleted: %lu", fuaBuffer.size()); INSANE_MSG("H264 FU-A packet incompleted: %lu", fuaBuffer.size());
uint8_t nalType = (fuaBuffer[4] & 0x1F); uint8_t nalType = (fuaBuffer[4] & 0x1F);