diff --git a/src/modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.cc b/src/modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.cc index 86263af36..30ee4171a 100644 --- a/src/modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.cc +++ b/src/modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.cc @@ -19,6 +19,8 @@ #include // for htons, htonl, etc #endif +#include + #define HDR_SIZE 8 // rtpplay packet header size in bytes @@ -802,3 +804,68 @@ void NETEQTEST_RTPpacket::splitStereoFrame(NETEQTEST_RTPpacket& slaveRtp) slaveRtp._payloadLen = _payloadLen; } +// Get the RTP header for the RED payload indicated by argument index. +// The first RED payload is index = 0. +int NETEQTEST_RTPpacket::extractRED(int index, WebRtcNetEQ_RTPInfo& red) +{ +// +// 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 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// |1| block PT | timestamp offset | block length | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// |1| ... | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// |0| block PT | +// +-+-+-+-+-+-+-+-+ +// + + parseHeader(); + + WebRtc_UWord8* ptr = payload(); + WebRtc_UWord8* payloadEndPtr = ptr + payloadLen(); + int num_encodings = 0; + int total_len = 0; + + while ((ptr < payloadEndPtr) && (*ptr & 0x80)) + { + int len = ((ptr[2] & 0x03) << 8) + ptr[3]; + if (num_encodings == index) + { + // Header found. + red.payloadType = ptr[0] & 0x7F; + WebRtc_UWord32 offset = (ptr[1] << 6) + ((ptr[2] & 0xFC) >> 2); + red.sequenceNumber = sequenceNumber(); + red.timeStamp = timeStamp() - offset; + red.markerBit = markerBit(); + red.SSRC = SSRC(); + return len; + } + ++num_encodings; + total_len += len; + ptr += 4; + } + if ((ptr < payloadEndPtr) && (num_encodings == index)) + { + // Last header. + red.payloadType = ptr[0] & 0x7F; + red.sequenceNumber = sequenceNumber(); + red.timeStamp = timeStamp(); + red.markerBit = markerBit(); + red.SSRC = SSRC(); + ++ptr; + return payloadLen() - (ptr - payload()) - total_len; + } + return -1; +} + +// Randomize the payload, not the RTP header. +void NETEQTEST_RTPpacket::scramblePayload(void) +{ + parseHeader(); + + for (int i = 0; i < _payloadLen; ++i) + { + _payloadPtr[i] = static_cast(std::rand()); + } +} diff --git a/src/modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.h b/src/modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.h index 829eccdf9..047856862 100644 --- a/src/modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.h +++ b/src/modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.h @@ -66,6 +66,10 @@ public: int splitStereo(NETEQTEST_RTPpacket& slaveRtp, enum stereoModes mode); + int extractRED(int index, WebRtcNetEQ_RTPInfo& red); + + void scramblePayload(void); + WebRtc_UWord8 * _datagram; WebRtc_UWord8 * _payloadPtr; int _memSize; diff --git a/src/modules/audio_coding/neteq/test/RTPanalyze.cc b/src/modules/audio_coding/neteq/test/RTPanalyze.cc index 3c6170f47..f70ca8b6c 100644 --- a/src/modules/audio_coding/neteq/test/RTPanalyze.cc +++ b/src/modules/audio_coding/neteq/test/RTPanalyze.cc @@ -8,6 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ +#include #include #include @@ -20,6 +21,7 @@ #define FIRSTLINELEN 40 +enum {kRedPayloadType = 127}; int main(int argc, char* argv[]) { @@ -56,6 +58,18 @@ int main(int argc, char* argv[]) fprintf(outFile, "%5u %10u %10u %5i %5i %2i\n", packet.sequenceNumber(), packet.timeStamp(), packet.time(), packet.dataLen(), packet.payloadType(), packet.markerBit()); + if (packet.payloadType() == kRedPayloadType) { + WebRtcNetEQ_RTPInfo redHdr; + int len; + int redIndex = 0; + while ((len = packet.extractRED(redIndex++, redHdr)) >= 0) + { + fprintf(outFile, "* %5u %10u %10u %5i %5i\n", + redHdr.sequenceNumber, redHdr.timeStamp, packet.time(), + len, redHdr.payloadType); + } + assert(redIndex > 1); // We must get at least one payload. + } } fclose(inFile);