#include "analyser_rtsp.h" AnalyserRTSP *classPointer = 0; void incomingPacket(const DTSC::Packet &pkt){ classPointer->incoming(pkt); } void AnalyserRTSP::init(Util::Config &conf){ Analyser::init(conf); } void AnalyserRTSP::incoming(const DTSC::Packet &pkt){ char *dataPtr; size_t dataSize; pkt.getString("data", dataPtr, dataSize); DETAIL_MED("Received %zub %sfor track %zu (%s) @ %" PRIu64 "ms", dataSize, pkt.getFlag("keyframe") ? "keyframe " : "", pkt.getTrackId(), myMeta.getTrackIdentifier(pkt.getTrackId()).c_str(), pkt.getTime()); if (detail >= 8){ for (uint32_t i = 0; i < dataSize; ++i){ std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)dataPtr[i] << " "; if (i % 32 == 31){std::cout << std::endl;} } std::cout << std::endl; } } bool AnalyserRTSP::open(const std::string &filename){ if (!Analyser::open(filename)){return false;} myConn.open(1, 0); return true; } AnalyserRTSP::AnalyserRTSP(Util::Config &conf) : Analyser(conf){ sdpState.myMeta = &myMeta; sdpState.incomingPacketCallback = incomingPacket; classPointer = this; } bool AnalyserRTSP::isOpen(){ return myConn; } bool AnalyserRTSP::parsePacket(){ do{ // No new data? Sleep and retry, if connection still open if (!myConn.Received().size() || !myConn.Received().available(1)){ if (!myConn.spool() && isOpen()){Util::sleep(500);} continue; } if (myConn.Received().copy(1) != "$"){ // not a TCP RTP packet, read RTSP commands if (HTTP.Read(myConn)){ if (HTTP.hasHeader("Content-Type") && HTTP.GetHeader("Content-Type") == "application/sdp"){ sdpState.parseSDP(HTTP.body); HTTP.Clean(); return true; } if (HTTP.hasHeader("Transport")){ size_t trackNo = sdpState.parseSetup(HTTP, "", ""); if (trackNo){ DETAIL_MED("Parsed transport for track: %zu", trackNo); }else{ DETAIL_MED("Could not parse transport string!"); } HTTP.Clean(); return true; } std::cout << HTTP.BuildRequest() << std::endl; HTTP.Clean(); return true; }else{ if (!myConn.spool() && isOpen()){Util::sleep(500);} } continue; } if (!myConn.Received().available(4)){ if (!myConn.spool() && isOpen()){Util::sleep(500);} continue; }// a TCP RTP packet, but not complete yet // We have a TCP packet! Read it... // Format: 1 byte '$', 1 byte channel, 2 bytes len, len bytes binary data std::string tcpHead = myConn.Received().copy(4); uint16_t len = ntohs(*(short *)(tcpHead.data() + 2)); if (!myConn.Received().available(len + 4)){ if (!myConn.spool() && isOpen()){Util::sleep(500);} continue; }// a TCP RTP packet, but not complete yet // remove whole packet from buffer, including 4 byte header std::string tcpPacket = myConn.Received().remove(len + 4); RTP::Packet pkt(tcpPacket.data() + 4, len); uint8_t chan = tcpHead.data()[1]; uint32_t trackNo = sdpState.getTrackNoForChannel(chan); DETAIL_HI("Received %ub RTP packet #%u on channel %u, time %" PRIu32, len, pkt.getSequence(), chan, pkt.getTimeStamp()); if (!trackNo && (chan % 2) != 1){ DETAIL_MED("Received packet for unknown track number on channel %u", chan); } if (trackNo){sdpState.tracks[trackNo].sorter.rtpSeq = pkt.getSequence();} if (detail >= 10){ const char *pl = pkt.getPayload(); uint32_t payLen = pkt.getPayloadSize(); for (uint32_t i = 0; i < payLen; ++i){ std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)pl[i] << " "; if (i % 32 == 31){std::cout << std::endl;} } std::cout << std::endl; } sdpState.handleIncomingRTP(trackNo, pkt); return true; }while (isOpen()); return false; }