diff --git a/erizo/src/erizo/SdesTransport.cpp b/erizo/src/erizo/SdesTransport.cpp index 93b6d9b584..369c12ce01 100644 --- a/erizo/src/erizo/SdesTransport.cpp +++ b/erizo/src/erizo/SdesTransport.cpp @@ -69,10 +69,7 @@ void SdesTransport::onNiceData(unsigned int component_id, char* data, int len, N } rtcpheader *chead = reinterpret_cast (unprotectBuf_); - if (chead->packettype == RTCP_Sender_PT || - chead->packettype == RTCP_Receiver_PT || - chead->packettype == RTCP_PS_Feedback_PT|| - chead->packettype == RTCP_RTP_Feedback_PT){ + if (chead->isRtcp()){ if(srtp->unprotectRtcp(unprotectBuf_, &length)<0) return; } else { diff --git a/erizo/src/erizo/WebRtcConnection.cpp b/erizo/src/erizo/WebRtcConnection.cpp index 29d55f0ba2..00079047a6 100644 --- a/erizo/src/erizo/WebRtcConnection.cpp +++ b/erizo/src/erizo/WebRtcConnection.cpp @@ -194,7 +194,7 @@ namespace erizo { int WebRtcConnection::deliverFeedback(char* buf, int len){ // Check where to send the feedback - rtcpheader *chead = (rtcpheader*) buf; + rtcpheader *chead = reinterpret_cast (buf); ELOG_DEBUG("received Feedback type %u ssrc %u, sourcessrc %u", chead->packettype, ntohl(chead->ssrc), ntohl(chead->ssrcsource)); if (ntohl(chead->ssrcsource) == this->getAudioSourceSSRC()) { writeSsrc(buf,len,this->getAudioSinkSSRC()); @@ -216,10 +216,10 @@ namespace erizo { } void WebRtcConnection::writeSsrc(char* buf, int len, unsigned int ssrc) { - rtpheader *head = (rtpheader*) buf; + rtpheader *head = reinterpret_cast (buf); rtcpheader *chead = reinterpret_cast (buf); //if it is RTCP we check it it is a compound packet - if (chead->packettype == RTCP_Sender_PT || chead->packettype == RTCP_Receiver_PT || chead->packettype == RTCP_PS_Feedback_PT || chead->packettype == RTCP_RTP_Feedback_PT) { + if (chead->isRtcp()) { processRtcpHeaders(buf,len,ssrc); } else { head->ssrc=htonl(ssrc); diff --git a/erizo/src/erizo/media/ExternalOutput.cpp b/erizo/src/erizo/media/ExternalOutput.cpp index 8110716f19..7e708e0d2c 100644 --- a/erizo/src/erizo/media/ExternalOutput.cpp +++ b/erizo/src/erizo/media/ExternalOutput.cpp @@ -246,11 +246,19 @@ namespace erizo { } int ExternalOutput::deliverAudioData(char* buf, int len) { + rtcpheader *head = reinterpret_cast(buf); + if (head->isRtcp()){ + return 0; + } this->queueData(buf,len,AUDIO_PACKET); return 0; } int ExternalOutput::deliverVideoData(char* buf, int len) { + rtcpheader *head = reinterpret_cast(buf); + if (head->isRtcp()){ + return 0; + } this->queueData(buf,len,VIDEO_PACKET); return 0; } @@ -319,16 +327,11 @@ namespace erizo { return; } boost::mutex::scoped_lock lock(queueMutex_); - - if (packetQueue_.size()>1000){ - return; + if (type == VIDEO_PACKET){ + videoQueue_.pushPacket(buffer, length); + }else{ + audioQueue_.pushPacket(buffer, length); } - dataPacket p; - memset(p.data, 0,length); - memcpy(p.data, buffer, length); - p.type = type; - p.length = length; - packetQueue_.push(p); cond_.notify_one(); } @@ -365,20 +368,30 @@ namespace erizo { while (sending_ == true) { boost::unique_lock lock(queueMutex_); - while (packetQueue_.size() == 0) { + while ((!audioQueue_.getSize())&&(!videoQueue_.getSize())) { cond_.wait(lock); if (sending_ == false) { lock.unlock(); return; } } + if (audioQueue_.getSize()){ + boost::shared_ptr audioP = audioQueue_.popPacket(); + this->writeAudioData(audioP->data, audioP->length); + } + if (videoQueue_.getSize()) { + boost::shared_ptr videoP = videoQueue_.popPacket(); + this->writeVideoData(videoP->data, videoP->length); + } + /* if (packetQueue_.front().type == VIDEO_PACKET) { this->writeVideoData(packetQueue_.front().data, packetQueue_.front().length); } else { this->writeAudioData(packetQueue_.front().data, packetQueue_.front().length); } - packetQueue_.pop(); +*/ + lock.unlock(); } } diff --git a/erizo/src/erizo/media/ExternalOutput.h b/erizo/src/erizo/media/ExternalOutput.h index 56a0b25e25..8df70752b8 100644 --- a/erizo/src/erizo/media/ExternalOutput.h +++ b/erizo/src/erizo/media/ExternalOutput.h @@ -3,8 +3,8 @@ #include #include -#include #include "../MediaDefinitions.h" +#include "rtp/RtpPacketQueue.h" #include "codecs/VideoCodec.h" #include "codecs/AudioCodec.h" #include "MediaProcessor.h" @@ -32,15 +32,16 @@ namespace erizo{ private: OutputProcessor* op_; + RtpPacketQueue audioQueue_, videoQueue_; unsigned char* decodedBuffer_; char* sendVideoBuffer_; + std::string url; volatile bool sending_; boost::mutex queueMutex_; boost::thread thread_; boost::condition_variable cond_; - std::queue packetQueue_; AVStream *video_st, *audio_st; AudioEncoder* audioCoder_; diff --git a/erizo/src/erizo/media/rtp/RtpHeader.h b/erizo/src/erizo/media/rtp/RtpHeader.h index 00a8f7d83e..f995961409 100644 --- a/erizo/src/erizo/media/rtp/RtpHeader.h +++ b/erizo/src/erizo/media/rtp/RtpHeader.h @@ -8,6 +8,8 @@ #ifndef RTPHEADER_H_ #define RTPHEADER_H_ +#include + class RTPHeader { public: // constants diff --git a/erizo/src/erizo/media/rtp/RtpPacketQueue.cpp b/erizo/src/erizo/media/rtp/RtpPacketQueue.cpp new file mode 100644 index 0000000000..5b704e73d2 --- /dev/null +++ b/erizo/src/erizo/media/rtp/RtpPacketQueue.cpp @@ -0,0 +1,114 @@ +#include + +#include "RtpPacketQueue.h" +#include "../../MediaDefinitions.h" +#include "RtpHeader.h" + + +namespace erizo{ + + DEFINE_LOGGER(RtpPacketQueue, "RtpPacketQueue"); + + RtpPacketQueue::RtpPacketQueue() + : lastNseq_(0), lastTs_(0) + { + } + + RtpPacketQueue::~RtpPacketQueue(void) + { + cleanQueue(); + } + + void RtpPacketQueue::pushPacket(const char *data, int length) + { + + const RTPHeader *header = reinterpret_cast(data); + uint16_t nseq = header->getSeqNumber(); + uint32_t ts = header->getTimestamp(); + + long long int ltsdiff = (long long int)ts - (long long int)lastTs_; + int tsdiff = (int)ltsdiff; + int nseqdiff = nseq - lastNseq_; + /* + // nseq sequence cicle test + if ( abs(nseqdiff) > ( USHRT_MAX - MAX_DIFF ) ) + { + NOTIFY("Vuelta del NSeq ns=%d last=%d\n", nseq, lastNseq_); + if (nseqdiff > 0) + nseqdiff-= (USHRT_MAX + 1); + else + nseqdiff+= (USHRT_MAX + 1); + } + */ + + if (abs(tsdiff) > MAX_DIFF_TS || abs(nseqdiff) > MAX_DIFF ) + { + // new flow, process and clean queue + ELOG_DEBUG("Max diff reached, new Flow? nsqediff %d , tsdiff %d", nseqdiff, tsdiff); + ELOG_DEBUG("PT %d", header->getPayloadType()); + lastNseq_ = nseq; + lastTs_ = ts; + cleanQueue(); + } + else if (nseqdiff > 1) + { + // Jump in nseq, enqueue + ELOG_DEBUG("Jump in nseq"); + enqueuePacket(data, length, nseq); + } + else if (nseqdiff == 1) + { + // next packet, process + lastNseq_ = nseq; + lastTs_ = ts; + enqueuePacket(data, length, nseq); + } + else if (nseqdiff < 0) + { + ELOG_DEBUG("Old Packet Received"); + // old packet, discard? + // stats? + } + else if (nseqdiff == 0) + { + ELOG_DEBUG("Duplicate Packet received"); + //duplicate packet, process (for stats)? + } + } + + void RtpPacketQueue::enqueuePacket(const char *data, int length, uint16_t nseq) + { + if (queue_.size() > MAX_SIZE) { // if queue is growing too much, we start again + cleanQueue(); + } + + boost::shared_ptr packet(new dataPacket()); + memcpy(packet->data, data, length); + packet->length = length; + queue_.insert(std::map< int, boost::shared_ptr>::value_type(nseq,packet)); + + } + + void RtpPacketQueue::cleanQueue() + { + queue_.clear(); + } + + boost::shared_ptr RtpPacketQueue::popPacket() + { + boost::shared_ptr packet = queue_.begin()->second; + if (packet.get() == NULL){ + return packet; + } + const RTPHeader *header = reinterpret_cast(packet->data); + lastNseq_ = queue_.begin()->first; + lastTs_ = header->getTimestamp(); + queue_.erase(queue_.begin()); + return packet; + } + + int RtpPacketQueue::getSize(){ + uint16_t size = queue_.size(); + return size; + } +} /* namespace erizo */ diff --git a/erizo/src/erizo/media/rtp/RtpPacketQueue.h b/erizo/src/erizo/media/rtp/RtpPacketQueue.h new file mode 100644 index 0000000000..a61754504f --- /dev/null +++ b/erizo/src/erizo/media/rtp/RtpPacketQueue.h @@ -0,0 +1,40 @@ +#ifndef __RTPPACKETQUEUE_H__ +#define __RTPPACKETQUEUE_H__ + +#include +#include + +#include "logger.h" + +namespace erizo{ + //forward declaration + class dataPacket; + + class RtpPacketQueue + { + DECLARE_LOGGER(); + + public: + RtpPacketQueue(); + virtual ~RtpPacketQueue(void); + + void pushPacket(const char *data, int length); + boost::shared_ptr popPacket(); + int getSize(); + + private: + static const int MAX_DIFF = 50; + static const int MAX_DIFF_TS = 50000; + static const unsigned int MAX_SIZE = 10; + std::map< int, boost::shared_ptr> queue_; + uint16_t lastNseq_; + uint32_t lastTs_; + + void enqueuePacket(const char *data, int length, uint16_t nseq); + void cleanQueue(void); + + }; +} /* namespace erizo */ + +#endif /* RTPPACKETQUEUE*/ + diff --git a/erizo/src/erizo/rtputils.h b/erizo/src/erizo/rtputils.h index 16de762834..a59a33e1dc 100644 --- a/erizo/src/erizo/rtputils.h +++ b/erizo/src/erizo/rtputils.h @@ -7,132 +7,153 @@ #include -// 0 1 2 3 -// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// |V=2|P|X| CC |M| PT | sequence number | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | timestamp | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | synchronization source (SSRC) identifier | -// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ -// | contributing source (CSRC) identifiers | -// | .... | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +namespace erizo{ + // Payload types +#define RTCP_Sender_PT 200 // RTCP Sender Report +#define RTCP_Receiver_PT 201 // RTCP Receiver Report +#define RTCP_RTP_Feedback_PT 205 // RTCP Transport Layer Feedback Packet +#define RTCP_PS_Feedback_PT 206 // RTCP Payload Specific Feedback Packet + +#define VP8_90000_PT 100 // VP8 Video Codec +#define RED_90000_PT 116 // REDundancy (RFC 2198) +#define ULP_90000_PT 117 // ULP/FEC +#define ISAC_16000_PT 103 // ISAC Audio Codec +#define ISAC_32000_PT 104 // ISAC Audio Codec +#define PCMU_8000_PT 0 // PCMU Audio Codec +#define OPUS_48000_PT 111 // Opus Audio Codec +#define PCMA_8000_PT 8 // PCMA Audio Codec +#define CN_8000_PT 13 // CN Audio Codec +#define CN_16000_PT 105 // CN Audio Codec +#define CN_32000_PT 106 // CN Audio Codec +#define CN_48000_PT 107 // CN Audio Codec +#define TEL_8000_PT 126 // Tel Audio Events -// The first twelve octets are present in every RTP packet, while the -// list of CSRC identifiers is present only when inserted by a mixer. -// The fields have the following meaning: + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |V=2|P|X| CC |M| PT | sequence number | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | timestamp | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | synchronization source (SSRC) identifier | + // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + // | contributing source (CSRC) identifiers | + // | .... | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// version (V): 2 bits -// This field identifies the version of RTP. The version defined by -// this specification is two (2). (The value 1 is used by the first -// draft version of RTP and the value 0 is used by the protocol -// initially implemented in the "vat" audio tool.) + // The first twelve octets are present in every RTP packet, while the + // list of CSRC identifiers is present only when inserted by a mixer. + // The fields have the following meaning: -// padding (P): 1 bit -// If the padding bit is set, the packet contains one or more -// additional padding octets at the end which are not part of the -// payload. The last octet of the padding contains a count of how -// many padding octets should be ignored. Padding may be needed by -// some encryption algorithms with fixed block sizes or for -// carrying several RTP packets in a lower-layer protocol data -// unit. + // version (V): 2 bits + // This field identifies the version of RTP. The version defined by + // this specification is two (2). (The value 1 is used by the first + // draft version of RTP and the value 0 is used by the protocol + // initially implemented in the "vat" audio tool.) -// extension (X): 1 bit -// If the extension bit is set, the fixed header is followed by -// exactly one header extension, with a format defined in Section -// 5.3.1. + // padding (P): 1 bit + // If the padding bit is set, the packet contains one or more + // additional padding octets at the end which are not part of the + // payload. The last octet of the padding contains a count of how + // many padding octets should be ignored. Padding may be needed by + // some encryption algorithms with fixed block sizes or for + // carrying several RTP packets in a lower-layer protocol data + // unit. -// CSRC count (CC): 4 bits -// The CSRC count contains the number of CSRC identifiers that -// follow the fixed header. + // extension (X): 1 bit + // If the extension bit is set, the fixed header is followed by + // exactly one header extension, with a format defined in Section + // 5.3.1. -// marker (M): 1 bit -// The interpretation of the marker is defined by a profile. It is -// intended to allow significant events such as frame boundaries to -// be marked in the packet stream. A profile may define additional -// marker bits or specify that there is no marker bit by changing -// the number of bits in the payload type field (see Section 5.3). + // CSRC count (CC): 4 bits + // The CSRC count contains the number of CSRC identifiers that + // follow the fixed header. -// payload type (PT): 7 bits -// This field identifies the format of the RTP payload and -// determines its interpretation by the application. A profile -// specifies a default static mapping of payload type codes to -// payload formats. Additional payload type codes may be defined -// dynamically through non-RTP means (see Section 3). An initial -// set of default mappings for audio and video is specified in the -// companion profile Internet-Draft draft-ietf-avt-profile, and -// may be extended in future editions of the Assigned Numbers RFC -// [6]. An RTP sender emits a single RTP payload type at any given -// time; this field is not intended for multiplexing separate media -// streams (see Section 5.2). + // marker (M): 1 bit + // The interpretation of the marker is defined by a profile. It is + // intended to allow significant events such as frame boundaries to + // be marked in the packet stream. A profile may define additional + // marker bits or specify that there is no marker bit by changing + // the number of bits in the payload type field (see Section 5.3). -// sequence number: 16 bits -// The sequence number increments by one for each RTP data packet -// sent, and may be used by the receiver to detect packet loss and -// to restore packet sequence. The initial value of the sequence -// number is random (unpredictable) to make known-plaintext attacks -// on encryption more difficult, even if the source itself does not -// encrypt, because the packets may flow through a translator that -// does. Techniques for choosing unpredictable numbers are -// discussed in [7]. + // payload type (PT): 7 bits + // This field identifies the format of the RTP payload and + // determines its interpretation by the application. A profile + // specifies a default static mapping of payload type codes to + // payload formats. Additional payload type codes may be defined + // dynamically through non-RTP means (see Section 3). An initial + // set of default mappings for audio and video is specified in the + // companion profile Internet-Draft draft-ietf-avt-profile, and + // may be extended in future editions of the Assigned Numbers RFC + // [6]. An RTP sender emits a single RTP payload type at any given + // time; this field is not intended for multiplexing separate media + // streams (see Section 5.2). -// timestamp: 32 bits -// The timestamp reflects the sampling instant of the first octet -// in the RTP data packet. The sampling instant must be derived -// from a clock that increments monotonically and linearly in time -// to allow synchronization and jitter calculations (see Section -// 6.3.1). The resolution of the clock must be sufficient for the -// desired synchronization accuracy and for measuring packet -// arrival jitter (one tick per video frame is typically not -// sufficient). The clock frequency is dependent on the format of -// data carried as payload and is specified statically in the -// profile or payload format specification that defines the format, -// or may be specified dynamically for payload formats defined -// through non-RTP means. If RTP packets are generated -// periodically, the nominal sampling instant as determined from -// the sampling clock is to be used, not a reading of the system -// clock. As an example, for fixed-rate audio the timestamp clock -// would likely increment by one for each sampling period. If an -// audio application reads blocks covering 160 sampling periods -// from the input device, the timestamp would be increased by 160 -// for each such block, regardless of whether the block is -// transmitted in a packet or dropped as silent. + // sequence number: 16 bits + // The sequence number increments by one for each RTP data packet + // sent, and may be used by the receiver to detect packet loss and + // to restore packet sequence. The initial value of the sequence + // number is random (unpredictable) to make known-plaintext attacks + // on encryption more difficult, even if the source itself does not + // encrypt, because the packets may flow through a translator that + // does. Techniques for choosing unpredictable numbers are + // discussed in [7]. -// The initial value of the timestamp is random, as for the sequence -// number. Several consecutive RTP packets may have equal timestamps if -// they are (logically) generated at once, e.g., belong to the same -// video frame. Consecutive RTP packets may contain timestamps that are -// not monotonic if the data is not transmitted in the order it was -// sampled, as in the case of MPEG interpolated video frames. (The -// sequence numbers of the packets as transmitted will still be -// monotonic.) + // timestamp: 32 bits + // The timestamp reflects the sampling instant of the first octet + // in the RTP data packet. The sampling instant must be derived + // from a clock that increments monotonically and linearly in time + // to allow synchronization and jitter calculations (see Section + // 6.3.1). The resolution of the clock must be sufficient for the + // desired synchronization accuracy and for measuring packet + // arrival jitter (one tick per video frame is typically not + // sufficient). The clock frequency is dependent on the format of + // data carried as payload and is specified statically in the + // profile or payload format specification that defines the format, + // or may be specified dynamically for payload formats defined + // through non-RTP means. If RTP packets are generated + // periodically, the nominal sampling instant as determined from + // the sampling clock is to be used, not a reading of the system + // clock. As an example, for fixed-rate audio the timestamp clock + // would likely increment by one for each sampling period. If an + // audio application reads blocks covering 160 sampling periods + // from the input device, the timestamp would be increased by 160 + // for each such block, regardless of whether the block is + // transmitted in a packet or dropped as silent. -// SSRC: 32 bits -// The SSRC field identifies the synchronization source. This -// identifier is chosen randomly, with the intent that no two -// synchronization sources within the same RTP session will have -// the same SSRC identifier. An example algorithm for generating a -// random identifier is presented in Appendix A.6. Although the -// probability of multiple sources choosing the same identifier is -// low, all RTP implementations must be prepared to detect and -// resolve collisions. Section 8 describes the probability of -// collision along with a mechanism for resolving collisions and -// detecting RTP-level forwarding loops based on the uniqueness of -// the SSRC identifier. If a source changes its source transport -// address, it must also choose a new SSRC identifier to avoid -// being interpreted as a looped source. + // The initial value of the timestamp is random, as for the sequence + // number. Several consecutive RTP packets may have equal timestamps if + // they are (logically) generated at once, e.g., belong to the same + // video frame. Consecutive RTP packets may contain timestamps that are + // not monotonic if the data is not transmitted in the order it was + // sampled, as in the case of MPEG interpolated video frames. (The + // sequence numbers of the packets as transmitted will still be + // monotonic.) -// 0 1 2 3 -// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | defined by profile | length | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | header extension | -// | .... | + // SSRC: 32 bits + // The SSRC field identifies the synchronization source. This + // identifier is chosen randomly, with the intent that no two + // synchronization sources within the same RTP session will have + // the same SSRC identifier. An example algorithm for generating a + // random identifier is presented in Appendix A.6. Although the + // probability of multiple sources choosing the same identifier is + // low, all RTP implementations must be prepared to detect and + // resolve collisions. Section 8 describes the probability of + // collision along with a mechanism for resolving collisions and + // detecting RTP-level forwarding loops based on the uniqueness of + // the SSRC identifier. If a source changes its source transport + // address, it must also choose a new SSRC identifier to avoid + // being interpreted as a looped source. -typedef struct { + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | defined by profile | length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | header extension | + // | .... | + + typedef struct { uint32_t cc :4; uint32_t extension :1; uint32_t padding :1; @@ -144,35 +165,35 @@ typedef struct { uint32_t ssrc; uint32_t extensionpayload:16; uint32_t extensionlength:16; -} rtpheader; + } rtpheader; -// 0 1 2 3 -// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// |V=2|P| RC | PT=RR=201 | length | header -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | SSRC of packet sender | -// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ -// | SSRC_1 (SSRC of first source) | report -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block -// | fraction lost | cumulative number of packets lost | 1 -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | extended highest sequence number received | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | interarrival jitter | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | last SR (LSR) | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | delay since last SR (DLSR) | -// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ -// | SSRC_2 (SSRC of second source) | report -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block -// : ... : 2 -// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ -// | profile-specific extensions | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |V=2|P| RC | PT=RR=201 | length | header + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | SSRC of packet sender | + // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + // | SSRC_1 (SSRC of first source) | report + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block + // | fraction lost | cumulative number of packets lost | 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | extended highest sequence number received | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | interarrival jitter | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | last SR (LSR) | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | delay since last SR (DLSR) | + // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + // | SSRC_2 (SSRC of second source) | report + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block + // : ... : 2 + // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + // | profile-specific extensions | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -typedef struct { + typedef struct { uint32_t blockcount :5; uint32_t padding :1; uint32_t version :2; @@ -181,36 +202,45 @@ typedef struct { uint32_t ssrc; uint32_t ssrcsource; uint32_t fractionlost:8; -} rtcpheader; + bool isRtcp(){ + if (packettype == RTCP_Sender_PT || + packettype == RTCP_Receiver_PT || + packettype == RTCP_PS_Feedback_PT|| + packettype == RTCP_RTP_Feedback_PT){ + return true; + } + return false; + } + } rtcpheader; -// 0 1 2 3 -// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// |V=2|P| FMT | PT | length | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | SSRC of packet sender | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | SSRC of media source | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// : Feedback Control Information (FCI) : -// : : + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |V=2|P| FMT | PT | length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | SSRC of packet sender | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | SSRC of media source | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // : Feedback Control Information (FCI) : + // : : -// The Feedback Control Information (FCI) for the Full Intra Request -// consists of one or more FCI entries, the content of which is depicted -// in Figure 4. The length of the FIR feedback message MUST be set to -// 2+2*N, where N is the number of FCI entries. -// -// 0 1 2 3 -// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | SSRC | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | Seq nr. | Reserved | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // The Feedback Control Information (FCI) for the Full Intra Request + // consists of one or more FCI entries, the content of which is depicted + // in Figure 4. The length of the FIR feedback message MUST be set to + // 2+2*N, where N is the number of FCI entries. + // + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | SSRC | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Seq nr. | Reserved | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -typedef struct { + typedef struct { uint32_t fmt :5; uint32_t padding :1; uint32_t version :2; @@ -219,66 +249,47 @@ typedef struct { uint32_t ssrc; uint32_t ssrcofmediasource; uint32_t ssrc_fir; -} firheader; + } firheader; -// 0 1 2 3 -// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// |F| block PT | timestamp offset | block length | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// -// -// RFC 2198 RTP Payload for Redundant Audio Data September 1997 -// -// The bits in the header are specified as follows: -// -// F: 1 bit First bit in header indicates whether another header block -// follows. If 1 further header blocks follow, if 0 this is the -// last header block. -// If 0 there is only 1 byte RED header -// -// block PT: 7 bits RTP payload type for this block. -// -// timestamp offset: 14 bits Unsigned offset of timestamp of this block -// relative to timestamp given in RTP header. The use of an unsigned -// offset implies that redundant data must be sent after the primary -// data, and is hence a time to be subtracted from the current -// timestamp to determine the timestamp of the data for which this -// block is the redundancy. -// -// block length: 10 bits Length in bytes of the corresponding data -// block excluding header. -struct redheader { + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |F| block PT | timestamp offset | block length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // + // RFC 2198 RTP Payload for Redundant Audio Data September 1997 + // + // The bits in the header are specified as follows: + // + // F: 1 bit First bit in header indicates whether another header block + // follows. If 1 further header blocks follow, if 0 this is the + // last header block. + // If 0 there is only 1 byte RED header + // + // block PT: 7 bits RTP payload type for this block. + // + // timestamp offset: 14 bits Unsigned offset of timestamp of this block + // relative to timestamp given in RTP header. The use of an unsigned + // offset implies that redundant data must be sent after the primary + // data, and is hence a time to be subtracted from the current + // timestamp to determine the timestamp of the data for which this + // block is the redundancy. + // + // block length: 10 bits Length in bytes of the corresponding data + // block excluding header. + struct redheader { uint32_t payloadtype :7; uint32_t follow :1; uint32_t tsLength :24; uint32_t getTS() { - return (ntohl(tsLength) & 0xfffc00) >> 10; + return (ntohl(tsLength) & 0xfffc00) >> 10; } uint32_t getLength() { - return (ntohl(tsLength) & 0x3ff); + return (ntohl(tsLength) & 0x3ff); } -}; - -// Payload types -#define RTCP_Sender_PT 200 // RTCP Sender Report -#define RTCP_Receiver_PT 201 // RTCP Receiver Report -#define RTCP_RTP_Feedback_PT 205 // RTCP Transport Layer Feedback Packet -#define RTCP_PS_Feedback_PT 206 // RTCP Payload Specific Feedback Packet - -#define VP8_90000_PT 100 // VP8 Video Codec -#define RED_90000_PT 116 // REDundancy (RFC 2198) -#define ULP_90000_PT 117 // ULP/FEC -#define ISAC_16000_PT 103 // ISAC Audio Codec -#define ISAC_32000_PT 104 // ISAC Audio Codec -#define PCMU_8000_PT 0 // PCMU Audio Codec -#define OPUS_48000_PT 111 // Opus Audio Codec -#define PCMA_8000_PT 8 // PCMA Audio Codec -#define CN_8000_PT 13 // CN Audio Codec -#define CN_16000_PT 105 // CN Audio Codec -#define CN_32000_PT 106 // CN Audio Codec -#define CN_48000_PT 107 // CN Audio Codec -#define TEL_8000_PT 126 // Tel Audio Events + }; +} /*namespace erizo*/ #endif /* RTPUTILS_H */ diff --git a/erizo_controller/erizoController/log4cxx.properties b/erizo_controller/erizoController/log4cxx.properties index 87a38d836d..5ef52b97cf 100644 --- a/erizo_controller/erizoController/log4cxx.properties +++ b/erizo_controller/erizoController/log4cxx.properties @@ -31,6 +31,7 @@ log4j.logger.media.ExternalOutput=DEBUG log4j.logger.media.rtp.RtpVP8Fragmenter=DEBUG log4j.logger.media.rtp.RtpParser=DEBUG +log4j.logger.media.rtp.RtpPacketQueue=INFO log4j.logger.media.mixers.VideoUtils=DEBUG log4j.logger.media.mixers.VideoMixer=DEBUG @@ -38,4 +39,4 @@ log4j.logger.media.mixers.VideoMixer=DEBUG log4j.logger.media.codecs.VideoEncoder=DEBUG log4j.logger.media.codecs.VideoDecoder=DEBUG log4j.logger.media.codecs.AudioEncoder=DEBUG -log4j.logger.media.codecs.AudioDecoder=DEBUG \ No newline at end of file +log4j.logger.media.codecs.AudioDecoder=DEBUG