Fix dummy RTP playout in NetEqRTPplay
Make sure that playing dummy RTP files works, i.e., RTP dumps with only headers, no actual payloads. It turs out that some RTP dumps did not state how long the actual packet was (including the discarded payload), which resulted in packets with zero length payload being inserted into NetEQ. Now, the dummy packet will contain at least one byte of payload (set to zero). Also added capability to filter out a specific SSRC from the RTP dump file. Finally, added SSRC printout from RTPanalyze, and corresponding change in RTPchange. TEST=trybots Review URL: https://webrtc-codereview.appspot.com/857007 git-svn-id: http://webrtc.googlecode.com/svn/trunk@2876 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
3df18d72ba
commit
25fadd74d0
@ -14,6 +14,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <algorithm> // max
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#else
|
#else
|
||||||
@ -56,17 +58,18 @@ int NETEQTEST_DummyRTPpacket::readFromFile(FILE *fp)
|
|||||||
length = (WebRtc_UWord16) (length - _kRDHeaderLen);
|
length = (WebRtc_UWord16) (length - _kRDHeaderLen);
|
||||||
|
|
||||||
// check buffer size
|
// check buffer size
|
||||||
if (_datagram && _memSize < length)
|
if (_datagram && _memSize < length + 1)
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_datagram)
|
if (!_datagram)
|
||||||
{
|
{
|
||||||
_datagram = new WebRtc_UWord8[length];
|
// Add one extra byte, to be able to fake a dummy payload of one byte.
|
||||||
_memSize = length;
|
_datagram = new WebRtc_UWord8[length + 1];
|
||||||
|
_memSize = length + 1;
|
||||||
}
|
}
|
||||||
memset(_datagram, 0, length);
|
memset(_datagram, 0, length + 1);
|
||||||
|
|
||||||
if (length == 0)
|
if (length == 0)
|
||||||
{
|
{
|
||||||
@ -75,7 +78,7 @@ int NETEQTEST_DummyRTPpacket::readFromFile(FILE *fp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read basic header
|
// Read basic header
|
||||||
if (fread((unsigned short *) _datagram, 1, _kBasicHeaderLen, fp)
|
if (fread(_datagram, 1, _kBasicHeaderLen, fp)
|
||||||
!= (size_t)_kBasicHeaderLen)
|
!= (size_t)_kBasicHeaderLen)
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
@ -83,6 +86,7 @@ int NETEQTEST_DummyRTPpacket::readFromFile(FILE *fp)
|
|||||||
}
|
}
|
||||||
_receiveTime = receiveTime;
|
_receiveTime = receiveTime;
|
||||||
_datagramLen = _kBasicHeaderLen;
|
_datagramLen = _kBasicHeaderLen;
|
||||||
|
int header_length = _kBasicHeaderLen;
|
||||||
|
|
||||||
// Parse the basic header
|
// Parse the basic header
|
||||||
WebRtcNetEQ_RTPInfo tempRTPinfo;
|
WebRtcNetEQ_RTPInfo tempRTPinfo;
|
||||||
@ -93,17 +97,18 @@ int NETEQTEST_DummyRTPpacket::readFromFile(FILE *fp)
|
|||||||
if (X != 0 || CC != 0)
|
if (X != 0 || CC != 0)
|
||||||
{
|
{
|
||||||
int newLen = _kBasicHeaderLen + CC * 4 + X * 4;
|
int newLen = _kBasicHeaderLen + CC * 4 + X * 4;
|
||||||
assert(_memSize >= newLen);
|
assert(_memSize >= newLen + 1);
|
||||||
|
|
||||||
// Read extension from file
|
// Read extension from file
|
||||||
size_t readLen = newLen - _kBasicHeaderLen;
|
size_t readLen = newLen - _kBasicHeaderLen;
|
||||||
if (fread((unsigned short *) _datagram + _kBasicHeaderLen, 1, readLen,
|
if (fread(_datagram + _kBasicHeaderLen, 1, readLen,
|
||||||
fp) != readLen)
|
fp) != readLen)
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
_datagramLen = newLen;
|
_datagramLen = newLen;
|
||||||
|
header_length = newLen;
|
||||||
|
|
||||||
if (X != 0)
|
if (X != 0)
|
||||||
{
|
{
|
||||||
@ -112,16 +117,19 @@ int NETEQTEST_DummyRTPpacket::readFromFile(FILE *fp)
|
|||||||
|
|
||||||
// Read extension from file
|
// Read extension from file
|
||||||
size_t readLen = totHdrLen - newLen;
|
size_t readLen = totHdrLen - newLen;
|
||||||
if (fread((unsigned short *) _datagram + newLen, 1, readLen, fp)
|
if (fread(_datagram + newLen, 1, readLen, fp)
|
||||||
!= readLen)
|
!= readLen)
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
_datagramLen = totHdrLen;
|
_datagramLen = totHdrLen;
|
||||||
|
header_length = totHdrLen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_datagramLen = length;
|
// Make sure that we have at least one byte of dummy payload.
|
||||||
|
_datagramLen = std::max(static_cast<int>(length), header_length + 1);
|
||||||
|
assert(_datagramLen <= _memSize);
|
||||||
|
|
||||||
if (!_blockList.empty() && _blockList.count(payloadType()) > 0)
|
if (!_blockList.empty() && _blockList.count(payloadType()) > 0)
|
||||||
{
|
{
|
||||||
@ -129,6 +137,12 @@ int NETEQTEST_DummyRTPpacket::readFromFile(FILE *fp)
|
|||||||
return readFromFile(fp);
|
return readFromFile(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_filterSSRC && _selectSSRC != SSRC())
|
||||||
|
{
|
||||||
|
// Discard this payload.
|
||||||
|
return(readFromFile(fp));
|
||||||
|
}
|
||||||
|
|
||||||
return packetLen;
|
return packetLen;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,9 @@ _datagramLen(-1),
|
|||||||
_payloadLen(0),
|
_payloadLen(0),
|
||||||
_rtpParsed(false),
|
_rtpParsed(false),
|
||||||
_receiveTime(0),
|
_receiveTime(0),
|
||||||
_lost(false)
|
_lost(false),
|
||||||
|
_selectSSRC(0),
|
||||||
|
_filterSSRC(false)
|
||||||
{
|
{
|
||||||
memset(&_rtpInfo, 0, sizeof(_rtpInfo));
|
memset(&_rtpInfo, 0, sizeof(_rtpInfo));
|
||||||
_blockList.clear();
|
_blockList.clear();
|
||||||
@ -157,6 +159,12 @@ int NETEQTEST_RTPpacket::readFromFile(FILE *fp)
|
|||||||
return(readFromFile(fp));
|
return(readFromFile(fp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_filterSSRC && _selectSSRC != SSRC())
|
||||||
|
{
|
||||||
|
// Discard this payload.
|
||||||
|
return(readFromFile(fp));
|
||||||
|
}
|
||||||
|
|
||||||
return(packetLen);
|
return(packetLen);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -250,6 +258,11 @@ void NETEQTEST_RTPpacket::blockPT(WebRtc_UWord8 pt)
|
|||||||
_blockList[pt] = true;
|
_blockList[pt] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NETEQTEST_RTPpacket::selectSSRC(uint32_t ssrc)
|
||||||
|
{
|
||||||
|
_selectSSRC = ssrc;
|
||||||
|
_filterSSRC = true;
|
||||||
|
}
|
||||||
|
|
||||||
void NETEQTEST_RTPpacket::parseHeader()
|
void NETEQTEST_RTPpacket::parseHeader()
|
||||||
{
|
{
|
||||||
|
@ -36,6 +36,7 @@ public:
|
|||||||
int readFixedFromFile(FILE *fp, size_t len);
|
int readFixedFromFile(FILE *fp, size_t len);
|
||||||
virtual int writeToFile(FILE *fp);
|
virtual int writeToFile(FILE *fp);
|
||||||
void blockPT(WebRtc_UWord8 pt);
|
void blockPT(WebRtc_UWord8 pt);
|
||||||
|
void selectSSRC(uint32_t ssrc);
|
||||||
//WebRtc_Word16 payloadType();
|
//WebRtc_Word16 payloadType();
|
||||||
void parseHeader();
|
void parseHeader();
|
||||||
void parseHeader(WebRtcNetEQ_RTPInfo & rtpInfo);
|
void parseHeader(WebRtcNetEQ_RTPInfo & rtpInfo);
|
||||||
@ -79,6 +80,8 @@ public:
|
|||||||
WebRtc_UWord32 _receiveTime;
|
WebRtc_UWord32 _receiveTime;
|
||||||
bool _lost;
|
bool _lost;
|
||||||
std::map<WebRtc_UWord8, bool> _blockList;
|
std::map<WebRtc_UWord8, bool> _blockList;
|
||||||
|
uint32_t _selectSSRC;
|
||||||
|
bool _filterSSRC;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static const int _kRDHeaderLen;
|
static const int _kRDHeaderLen;
|
||||||
|
@ -185,6 +185,8 @@ int main(int argc, char* argv[])
|
|||||||
std::map<WebRtc_UWord8, decoderStruct> decoders;
|
std::map<WebRtc_UWord8, decoderStruct> decoders;
|
||||||
bool dummyRtp = false;
|
bool dummyRtp = false;
|
||||||
bool noDecode = false;
|
bool noDecode = false;
|
||||||
|
bool filterSSRC = false;
|
||||||
|
uint32_t ssrc;
|
||||||
|
|
||||||
#ifdef DEF_BUILD_DATE
|
#ifdef DEF_BUILD_DATE
|
||||||
printf("Build time: %s\n", __BUILD_DATE);
|
printf("Build time: %s\n", __BUILD_DATE);
|
||||||
@ -224,6 +226,7 @@ int main(int argc, char* argv[])
|
|||||||
printf("\t-rtponly packLenBytes : input file consists of constant size RTP packets without RTPplay headers\n");
|
printf("\t-rtponly packLenBytes : input file consists of constant size RTP packets without RTPplay headers\n");
|
||||||
printf("\t-dummyrtp : input file contains only RTP headers\n");
|
printf("\t-dummyrtp : input file contains only RTP headers\n");
|
||||||
printf("\t-nodecode : no decoding will be done\n");
|
printf("\t-nodecode : no decoding will be done\n");
|
||||||
|
printf("\t-ssrc 0xNNNNNNNN : discard all other SSRCs\n");
|
||||||
//printf("\t-switchms : switch from mono to stereo (copy channel) after 10 seconds\n");
|
//printf("\t-switchms : switch from mono to stereo (copy channel) after 10 seconds\n");
|
||||||
//printf("\t-duplicate : use two instances with identical input (2-channel mono)\n");
|
//printf("\t-duplicate : use two instances with identical input (2-channel mono)\n");
|
||||||
|
|
||||||
@ -321,6 +324,17 @@ int main(int argc, char* argv[])
|
|||||||
argIx++;
|
argIx++;
|
||||||
noDecode = true;
|
noDecode = true;
|
||||||
}
|
}
|
||||||
|
else if (strcmp(argv[argIx], "-ssrc") == 0)
|
||||||
|
{
|
||||||
|
argIx++;
|
||||||
|
filterSSRC = true;
|
||||||
|
if (sscanf(argv[argIx], "%X", &ssrc) != 1)
|
||||||
|
{
|
||||||
|
printf("Could not read SSRC argument.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
argIx++;
|
||||||
|
}
|
||||||
//else if( strcmp(argv[argIx], "-switchms") == 0 ) {
|
//else if( strcmp(argv[argIx], "-switchms") == 0 ) {
|
||||||
// argIx++;
|
// argIx++;
|
||||||
// switchMS = true;
|
// switchMS = true;
|
||||||
@ -407,6 +421,15 @@ int main(int argc, char* argv[])
|
|||||||
slaveRtp = new NETEQTEST_DummyRTPpacket();
|
slaveRtp = new NETEQTEST_DummyRTPpacket();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Uncomment and edit the line(s) below to block some payload types. */
|
||||||
|
//rtp->blockPT(72);
|
||||||
|
//rtp->blockPT(23);
|
||||||
|
|
||||||
|
/* Select a specific SSRC. */
|
||||||
|
if (filterSSRC) {
|
||||||
|
rtp->selectSSRC(ssrc);
|
||||||
|
}
|
||||||
|
|
||||||
if (!rtpOnly)
|
if (!rtpOnly)
|
||||||
{
|
{
|
||||||
while (rtp->readFromFile(in_file) >= 0)
|
while (rtp->readFromFile(in_file) >= 0)
|
||||||
@ -440,11 +463,6 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
fseek(in_file, tempFilePos, SEEK_SET /* from beginning */);
|
fseek(in_file, tempFilePos, SEEK_SET /* from beginning */);
|
||||||
|
|
||||||
|
|
||||||
/* block some payload types */
|
|
||||||
//rtp->blockPT(72);
|
|
||||||
//rtp->blockPT(23);
|
|
||||||
|
|
||||||
/* read first packet */
|
/* read first packet */
|
||||||
if (!rtpOnly)
|
if (!rtpOnly)
|
||||||
{
|
{
|
||||||
|
@ -37,7 +37,7 @@ int main(int argc, char* argv[]) {
|
|||||||
printf("Output file: %s\n\n", argv[2]);
|
printf("Output file: %s\n\n", argv[2]);
|
||||||
|
|
||||||
// Print file header.
|
// Print file header.
|
||||||
fprintf(out_file, "SeqNo TimeStamp SendTime Size PT M\n");
|
fprintf(out_file, "SeqNo TimeStamp SendTime Size PT M SSRC\n");
|
||||||
|
|
||||||
// Read file header.
|
// Read file header.
|
||||||
NETEQTEST_RTPpacket::skipFileHeader(in_file);
|
NETEQTEST_RTPpacket::skipFileHeader(in_file);
|
||||||
@ -49,9 +49,10 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
while (packet.readFromFile(in_file) >= 0) {
|
while (packet.readFromFile(in_file) >= 0) {
|
||||||
// Write packet data to file.
|
// Write packet data to file.
|
||||||
fprintf(out_file, "%5u %10u %10u %5i %5i %2i\n",
|
fprintf(out_file, "%5u %10u %10u %5i %5i %2i %#08X\n",
|
||||||
packet.sequenceNumber(), packet.timeStamp(), packet.time(),
|
packet.sequenceNumber(), packet.timeStamp(), packet.time(),
|
||||||
packet.dataLen(), packet.payloadType(), packet.markerBit());
|
packet.dataLen(), packet.payloadType(), packet.markerBit(),
|
||||||
|
packet.SSRC());
|
||||||
if (packet.payloadType() == kRedPayloadType) {
|
if (packet.payloadType() == kRedPayloadType) {
|
||||||
WebRtcNetEQ_RTPInfo red_header;
|
WebRtcNetEQ_RTPInfo red_header;
|
||||||
int len;
|
int len;
|
||||||
|
@ -59,7 +59,7 @@ int main(int argc, char* argv[]) {
|
|||||||
uint32_t send_time;
|
uint32_t send_time;
|
||||||
|
|
||||||
while (fscanf(stat_file,
|
while (fscanf(stat_file,
|
||||||
"%hu %u %u %*i %*i\n", &seq_no, &ts, &send_time) == 3) {
|
"%hu %u %u %*i %*i %*i %*x\n", &seq_no, &ts, &send_time) == 3) {
|
||||||
std::pair<uint16_t, uint32_t>
|
std::pair<uint16_t, uint32_t>
|
||||||
temp_pair = std::pair<uint16_t, uint32_t>(seq_no, ts);
|
temp_pair = std::pair<uint16_t, uint32_t>(seq_no, ts);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user