Merge header-only neteq-rtpplay changes.

TEST=build

Review URL: https://webrtc-codereview.appspot.com/452003

git-svn-id: http://webrtc.googlecode.com/svn/trunk@1947 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
andrew@webrtc.org
2012-03-27 17:05:44 +00:00
parent 258d1d4ce0
commit f589dfede4
11 changed files with 916 additions and 553 deletions

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. # Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
# #
# Use of this source code is governed by a BSD-style license # Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source # that can be found in the LICENSE file in the root of the source
@@ -229,10 +229,25 @@
'test/RTPcat.cc', 'test/RTPcat.cc',
], ],
}, },
{
'target_name': 'rtp_to_text',
'type': 'executable',
'dependencies': [
'NetEqTestTools',
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
],
'sources': [
'test/rtp_to_text.cc',
],
},
{ {
'target_name': 'NetEqTestTools', 'target_name': 'NetEqTestTools',
# Collection of useful functions used in other tests # Collection of useful functions used in other tests
'type': '<(library)', 'type': '<(library)',
'variables': {
# Expects RTP packets without payloads when enabled.
'neteq_dummy_rtp%': 0,
},
'dependencies': [ 'dependencies': [
'G711', 'G711',
'G722', 'G722',
@@ -269,21 +284,17 @@
'test', 'test',
], ],
'sources': [ 'sources': [
'test/NETEQTEST_NetEQClass.cc',
'test/NETEQTEST_RTPpacket.cc',
'test/NETEQTEST_CodecClass.cc', 'test/NETEQTEST_CodecClass.cc',
'test/NETEQTEST_NetEQClass.h',
'test/NETEQTEST_RTPpacket.h',
'test/NETEQTEST_CodecClass.h', 'test/NETEQTEST_CodecClass.h',
'test/NETEQTEST_DummyRTPpacket.cc',
'test/NETEQTEST_DummyRTPpacket.h',
'test/NETEQTEST_NetEQClass.cc',
'test/NETEQTEST_NetEQClass.h',
'test/NETEQTEST_RTPpacket.cc',
'test/NETEQTEST_RTPpacket.h',
], ],
}, },
], # targets ], # targets
}], # build_with_chromium }], # build_with_chromium
], # conditions ], # conditions
} }
# Local Variables:
# tab-width:2
# indent-tabs-mode:nil
# End:
# vim: set expandtab tabstop=2 shiftwidth=2:

View File

@@ -0,0 +1,191 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "NETEQTEST_DummyRTPpacket.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#ifdef WIN32
#include <winsock2.h>
#else
#include <netinet/in.h> // for htons, htonl, etc
#endif
int NETEQTEST_DummyRTPpacket::readFromFile(FILE *fp)
{
if (!fp)
{
return -1;
}
WebRtc_UWord16 length, plen;
WebRtc_UWord32 offset;
if (fread(&length, 2, 1, fp) == 0)
{
reset();
return -2;
}
length = ntohs(length);
if (fread(&plen, 2, 1, fp) == 0)
{
reset();
return -1;
}
int packetLen = ntohs(plen);
if (fread(&offset, 4, 1, fp) == 0)
{
reset();
return -1;
}
// Store in local variable until we have passed the reset below.
WebRtc_UWord32 receiveTime = ntohl(offset);
// Use length here because a plen of 0 specifies rtcp.
length = (WebRtc_UWord16) (length - _kRDHeaderLen);
// check buffer size
if (_datagram && _memSize < length)
{
reset();
}
if (!_datagram)
{
_datagram = new WebRtc_UWord8[length];
_memSize = length;
}
memset(_datagram, 0, length);
if (length == 0)
{
_datagramLen = 0;
return packetLen;
}
// Read basic header
if (fread((unsigned short *) _datagram, 1, _kBasicHeaderLen, fp)
!= (size_t)_kBasicHeaderLen)
{
reset();
return -1;
}
_receiveTime = receiveTime;
_datagramLen = _kBasicHeaderLen;
// Parse the basic header
WebRtcNetEQ_RTPInfo tempRTPinfo;
int P, X, CC;
parseBasicHeader(&tempRTPinfo, &P, &X, &CC);
// Check if we have to extend the header
if (X != 0 || CC != 0)
{
int newLen = _kBasicHeaderLen + CC * 4 + X * 4;
assert(_memSize >= newLen);
// Read extension from file
size_t readLen = newLen - _kBasicHeaderLen;
if (fread((unsigned short *) _datagram + _kBasicHeaderLen, 1, readLen,
fp) != readLen)
{
reset();
return -1;
}
_datagramLen = newLen;
if (X != 0)
{
int totHdrLen = calcHeaderLength(X, CC);
assert(_memSize >= totHdrLen);
// Read extension from file
size_t readLen = totHdrLen - newLen;
if (fread((unsigned short *) _datagram + newLen, 1, readLen, fp)
!= readLen)
{
reset();
return -1;
}
_datagramLen = totHdrLen;
}
}
_datagramLen = length;
if (!_blockList.empty() && _blockList.count(payloadType()) > 0)
{
// discard this payload
return readFromFile(fp);
}
return packetLen;
}
int NETEQTEST_DummyRTPpacket::writeToFile(FILE *fp)
{
if (!fp)
{
return -1;
}
WebRtc_UWord16 length, plen;
WebRtc_UWord32 offset;
// length including RTPplay header
length = htons(_datagramLen + _kRDHeaderLen);
if (fwrite(&length, 2, 1, fp) != 1)
{
return -1;
}
// payload length
plen = htons(_datagramLen);
if (fwrite(&plen, 2, 1, fp) != 1)
{
return -1;
}
// offset (=receive time)
offset = htonl(_receiveTime);
if (fwrite(&offset, 4, 1, fp) != 1)
{
return -1;
}
// Figure out the length of the RTP header.
int headerLen;
if (_datagramLen == 0)
{
// No payload at all; we are done writing to file.
headerLen = 0;
}
else
{
parseHeader();
headerLen = _payloadPtr - _datagram;
assert(headerLen >= 0);
}
// write RTP header
if (fwrite((unsigned short *) _datagram, 1, headerLen, fp) !=
static_cast<size_t>(headerLen))
{
return -1;
}
return (headerLen + _kRDHeaderLen); // total number of bytes written
}

View File

@@ -0,0 +1,23 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NETEQTEST_DUMMYRTPPACKET_H
#define NETEQTEST_DUMMYRTPPACKET_H
#include "NETEQTEST_RTPpacket.h"
class NETEQTEST_DummyRTPpacket : public NETEQTEST_RTPpacket
{
public:
virtual int readFromFile(FILE *fp);
virtual int writeToFile(FILE *fp);
};
#endif //NETEQTEST_DUMMYRTPPACKET_H

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
* *
* Use of this source code is governed by a BSD-style license * Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source * that can be found in the LICENSE file in the root of the source
@@ -20,7 +20,8 @@ NETEQTEST_NetEQClass::NETEQTEST_NetEQClass()
_bufferMem(NULL), _bufferMem(NULL),
_preparseRTP(false), _preparseRTP(false),
_fsmult(1), _fsmult(1),
_isMaster(true) _isMaster(true),
_noDecode(false)
{ {
#ifdef WINDOWS_TIMING #ifdef WINDOWS_TIMING
_totTimeRecIn.QuadPart = 0; _totTimeRecIn.QuadPart = 0;
@@ -283,8 +284,15 @@ WebRtc_Word16 NETEQTEST_NetEQClass::recOut(WebRtc_Word16 *outData, void *msInfo,
if (!msInfo) if (!msInfo)
{ {
// no msInfo given, do mono mode // no msInfo given, do mono mode
if (_noDecode)
{
err = WebRtcNetEQ_RecOutNoDecode(_inst, outData, &outLen);
}
else
{
err = WebRtcNetEQ_RecOut(_inst, outData, &outLen); err = WebRtcNetEQ_RecOut(_inst, outData, &outLen);
} }
}
else else
{ {
// master/slave mode // master/slave mode

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
* *
* Use of this source code is governed by a BSD-style license * Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source * that can be found in the LICENSE file in the root of the source
@@ -47,8 +47,10 @@ public:
bool usingPreparseRTP() { return (_preparseRTP); }; bool usingPreparseRTP() { return (_preparseRTP); };
void setMaster( bool isMaster = true ) { _isMaster = isMaster; }; void setMaster( bool isMaster = true ) { _isMaster = isMaster; };
void setSlave() { _isMaster = false; }; void setSlave() { _isMaster = false; };
void setNoDecode(bool noDecode = true) { _noDecode = noDecode; };
bool isMaster() { return (_isMaster); }; bool isMaster() { return (_isMaster); };
bool isSlave() { return (!_isMaster); }; bool isSlave() { return (!_isMaster); };
bool isNoDecode() { return _noDecode; };
#ifdef WINDOWS_TIMING #ifdef WINDOWS_TIMING
double getRecInTime() { return (static_cast<double>( _totTimeRecIn.QuadPart )); }; double getRecInTime() { return (static_cast<double>( _totTimeRecIn.QuadPart )); };
@@ -69,24 +71,11 @@ private:
bool _preparseRTP; bool _preparseRTP;
int _fsmult; int _fsmult;
bool _isMaster; bool _isMaster;
bool _noDecode;
#ifdef WINDOWS_TIMING #ifdef WINDOWS_TIMING
LARGE_INTEGER _totTimeRecIn; LARGE_INTEGER _totTimeRecIn;
LARGE_INTEGER _totTimeRecOut; LARGE_INTEGER _totTimeRecOut;
#endif #endif
}; };
//class NETEQTEST_NetEQVector
//{
//public:
// NETEQTEST_NetEQVector(int numChannels);
// NETEQTEST_NetEQVector(int numChannels, enum WebRtcNetEQDecoder *usedCodec, int noOfCodecs,
// WebRtc_UWord16 fs = 8000, WebRtcNetEQNetworkType nwType = kTCPLargeJitter);
// ~NETEQTEST_NetEQVector();
//
//private:
// std::vector<NETEQTEST_NetEQClass *> channels;
//};
#endif //NETEQTEST_NETEQCLASS_H #endif //NETEQTEST_NETEQCLASS_H

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
* *
* Use of this source code is governed by a BSD-style license * Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source * that can be found in the LICENSE file in the root of the source
@@ -19,12 +19,8 @@
#include <netinet/in.h> // for htons, htonl, etc #include <netinet/in.h> // for htons, htonl, etc
#endif #endif
#include <cstdlib> const int NETEQTEST_RTPpacket::_kRDHeaderLen = 8;
const int NETEQTEST_RTPpacket::_kBasicHeaderLen = 12;
#include "gtest/gtest.h"
#define HDR_SIZE 8 // rtpplay packet header size in bytes
NETEQTEST_RTPpacket::NETEQTEST_RTPpacket() NETEQTEST_RTPpacket::NETEQTEST_RTPpacket()
: :
@@ -41,79 +37,6 @@ _lost(false)
_blockList.clear(); _blockList.clear();
} }
NETEQTEST_RTPpacket::NETEQTEST_RTPpacket(const NETEQTEST_RTPpacket& copyFromMe)
{
memcpy(this, &copyFromMe, sizeof(NETEQTEST_RTPpacket));
_datagram = NULL;
_payloadPtr = NULL;
if(copyFromMe._datagram)
{
_datagram = new WebRtc_UWord8[_memSize];
if(_datagram)
{
memcpy(_datagram, copyFromMe._datagram, _memSize);
}
}
if(copyFromMe._payloadPtr)
{
_payloadPtr = _datagram + (copyFromMe._payloadPtr - copyFromMe._datagram);
}
_blockList = copyFromMe._blockList;
}
NETEQTEST_RTPpacket & NETEQTEST_RTPpacket::operator = (const NETEQTEST_RTPpacket & other)
{
if (this != &other) // protect against invalid self-assignment
{
// deallocate datagram memory if allocated
if(_datagram)
{
delete [] _datagram;
}
// do shallow copy
memcpy(this, &other, sizeof(NETEQTEST_RTPpacket));
// reset pointers
_datagram = NULL;
_payloadPtr = NULL;
if(other._datagram)
{
_datagram = new WebRtc_UWord8[other._memSize];
_memSize = other._memSize;
if(_datagram)
{
memcpy(_datagram, other._datagram, _memSize);
}
}
if(other._payloadPtr)
{
_payloadPtr = _datagram + (other._payloadPtr - other._datagram);
}
// copy the blocking list (map)
_blockList = other._blockList;
}
// by convention, always return *this
return *this;
}
NETEQTEST_RTPpacket::~NETEQTEST_RTPpacket() NETEQTEST_RTPpacket::~NETEQTEST_RTPpacket()
{ {
if(_datagram) if(_datagram)
@@ -122,7 +45,6 @@ NETEQTEST_RTPpacket::~NETEQTEST_RTPpacket()
} }
} }
void NETEQTEST_RTPpacket::reset() void NETEQTEST_RTPpacket::reset()
{ {
if(_datagram) { if(_datagram) {
@@ -205,7 +127,7 @@ int NETEQTEST_RTPpacket::readFromFile(FILE *fp)
WebRtc_UWord32 receiveTime = ntohl(offset); // store in local variable until we have passed the reset below WebRtc_UWord32 receiveTime = ntohl(offset); // store in local variable until we have passed the reset below
// Use length here because a plen of 0 specifies rtcp // Use length here because a plen of 0 specifies rtcp
length = (WebRtc_UWord16) (length - HDR_SIZE); length = (WebRtc_UWord16) (length - _kRDHeaderLen);
// check buffer size // check buffer size
if (_datagram && _memSize < length) if (_datagram && _memSize < length)
@@ -289,7 +211,7 @@ int NETEQTEST_RTPpacket::writeToFile(FILE *fp)
WebRtc_UWord32 offset; WebRtc_UWord32 offset;
// length including RTPplay header // length including RTPplay header
length = htons(_datagramLen + HDR_SIZE); length = htons(_datagramLen + _kRDHeaderLen);
if (fwrite(&length, 2, 1, fp) != 1) if (fwrite(&length, 2, 1, fp) != 1)
{ {
return -1; return -1;
@@ -317,7 +239,7 @@ int NETEQTEST_RTPpacket::writeToFile(FILE *fp)
return -1; return -1;
} }
return _datagramLen + HDR_SIZE; // total number of bytes written return _datagramLen + _kRDHeaderLen; // total number of bytes written
} }
@@ -336,13 +258,13 @@ void NETEQTEST_RTPpacket::parseHeader()
return; return;
} }
if (_datagramLen < 12) if (_datagramLen < _kBasicHeaderLen)
{ {
// corrupt packet? // corrupt packet?
return; return;
} }
_payloadLen = parseRTPheader(_datagram, _datagramLen, &_rtpInfo, &_payloadPtr); _payloadLen = parseRTPheader(&_payloadPtr);
_rtpParsed = true; _rtpParsed = true;
@@ -397,8 +319,9 @@ WebRtc_UWord8 * NETEQTEST_RTPpacket::payload() const
} }
} }
WebRtc_Word16 NETEQTEST_RTPpacket::payloadLen() const WebRtc_Word16 NETEQTEST_RTPpacket::payloadLen()
{ {
parseHeader();
return _payloadLen; return _payloadLen;
} }
@@ -421,9 +344,9 @@ WebRtc_UWord8 NETEQTEST_RTPpacket::payloadType() const
{ {
WebRtcNetEQ_RTPInfo tempRTPinfo; WebRtcNetEQ_RTPInfo tempRTPinfo;
if(_datagram) if(_datagram && _datagramLen >= _kBasicHeaderLen)
{ {
parseRTPheader(_datagram, _datagramLen, &tempRTPinfo); parseRTPheader(&tempRTPinfo);
} }
else else
{ {
@@ -437,9 +360,9 @@ WebRtc_UWord16 NETEQTEST_RTPpacket::sequenceNumber() const
{ {
WebRtcNetEQ_RTPInfo tempRTPinfo; WebRtcNetEQ_RTPInfo tempRTPinfo;
if(_datagram) if(_datagram && _datagramLen >= _kBasicHeaderLen)
{ {
parseRTPheader(_datagram, _datagramLen, &tempRTPinfo); parseRTPheader(&tempRTPinfo);
} }
else else
{ {
@@ -453,9 +376,9 @@ WebRtc_UWord32 NETEQTEST_RTPpacket::timeStamp() const
{ {
WebRtcNetEQ_RTPInfo tempRTPinfo; WebRtcNetEQ_RTPInfo tempRTPinfo;
if(_datagram) if(_datagram && _datagramLen >= _kBasicHeaderLen)
{ {
parseRTPheader(_datagram, _datagramLen, &tempRTPinfo); parseRTPheader(&tempRTPinfo);
} }
else else
{ {
@@ -469,9 +392,9 @@ WebRtc_UWord32 NETEQTEST_RTPpacket::SSRC() const
{ {
WebRtcNetEQ_RTPInfo tempRTPinfo; WebRtcNetEQ_RTPInfo tempRTPinfo;
if(_datagram) if(_datagram && _datagramLen >= _kBasicHeaderLen)
{ {
parseRTPheader(_datagram, _datagramLen, &tempRTPinfo); parseRTPheader(&tempRTPinfo);
} }
else else
{ {
@@ -485,9 +408,9 @@ WebRtc_UWord8 NETEQTEST_RTPpacket::markerBit() const
{ {
WebRtcNetEQ_RTPInfo tempRTPinfo; WebRtcNetEQ_RTPInfo tempRTPinfo;
if(_datagram) if(_datagram && _datagramLen >= _kBasicHeaderLen)
{ {
parseRTPheader(_datagram, _datagramLen, &tempRTPinfo); parseRTPheader(&tempRTPinfo);
} }
else else
{ {
@@ -627,7 +550,8 @@ int NETEQTEST_RTPpacket::setRTPheader(const WebRtcNetEQ_RTPInfo *RTPinfo)
} }
int NETEQTEST_RTPpacket::splitStereo(NETEQTEST_RTPpacket& slaveRtp, enum stereoModes mode) int NETEQTEST_RTPpacket::splitStereo(NETEQTEST_RTPpacket* slaveRtp,
enum stereoModes mode)
{ {
// if mono, do nothing // if mono, do nothing
if (mode == stereoModeMono) if (mode == stereoModeMono)
@@ -639,7 +563,7 @@ int NETEQTEST_RTPpacket::splitStereo(NETEQTEST_RTPpacket& slaveRtp, enum stereoM
parseHeader(); parseHeader();
// start by copying the main rtp packet // start by copying the main rtp packet
slaveRtp = *this; *slaveRtp = *this;
if(_payloadLen == 0) if(_payloadLen == 0)
{ {
@@ -711,65 +635,114 @@ void NETEQTEST_RTPpacket::makeRTPheader(unsigned char* rtp_data, WebRtc_UWord8 p
rtp_data[11]=(unsigned char)(ssrc & 0xFF); rtp_data[11]=(unsigned char)(ssrc & 0xFF);
} }
WebRtc_UWord16
WebRtc_UWord16 NETEQTEST_RTPpacket::parseRTPheader(const WebRtc_UWord8 *datagram, int datagramLen, WebRtcNetEQ_RTPInfo *RTPinfo, WebRtc_UWord8 **payloadPtr) const NETEQTEST_RTPpacket::parseRTPheader(WebRtcNetEQ_RTPInfo *RTPinfo,
WebRtc_UWord8 **payloadPtr) const
{ {
WebRtc_Word16 *rtp_data = (WebRtc_Word16 *) datagram; WebRtc_Word16 *rtp_data = (WebRtc_Word16 *) _datagram;
int i_P, i_X, i_CC, i_extlength=-1, i_padlength=0, i_startPosition; int i_P, i_X, i_CC;
i_P=(((WebRtc_UWord16)(rtp_data[0] & 0x20))>>5); /* Extract the P bit */ assert(_datagramLen >= 12);
i_X=(((WebRtc_UWord16)(rtp_data[0] & 0x10))>>4); /* Extract the X bit */ parseBasicHeader(RTPinfo, &i_P, &i_X, &i_CC);
i_CC=(WebRtc_UWord16)(rtp_data[0] & 0xF); /* Get the CC number */
RTPinfo->markerBit = (WebRtc_UWord8) ((rtp_data[0] >> 15) & 0x01); /* Get the marker bit */
RTPinfo->payloadType = (WebRtc_UWord8) ((rtp_data[0] >> 8) & 0x7F); /* Get the coder type */
RTPinfo->sequenceNumber = ((( ((WebRtc_UWord16)rtp_data[1]) >> 8) & 0xFF) |
( ((WebRtc_UWord16)(rtp_data[1] & 0xFF)) << 8)); /* Get the packet number */
RTPinfo->timeStamp = ((((WebRtc_UWord16)rtp_data[2]) & 0xFF) << 24) |
((((WebRtc_UWord16)rtp_data[2]) & 0xFF00) << 8) |
((((WebRtc_UWord16)rtp_data[3]) >> 8) & 0xFF) |
((((WebRtc_UWord16)rtp_data[3]) & 0xFF) << 8); /* Get timestamp */
RTPinfo->SSRC=((((WebRtc_UWord16)rtp_data[4]) & 0xFF) << 24) |
((((WebRtc_UWord16)rtp_data[4]) & 0xFF00) << 8) |
((((WebRtc_UWord16)rtp_data[5]) >> 8) & 0xFF) |
((((WebRtc_UWord16)rtp_data[5]) & 0xFF) << 8); /* Get the SSRC */
if (i_X==1) { int i_startPosition = calcHeaderLength(i_X, i_CC);
/* Extention header exists. Find out how many WebRtc_Word32 it consists of */
i_extlength=((( ((WebRtc_UWord16)rtp_data[7+2*i_CC]) >> 8) & 0xFF) |
( ((WebRtc_UWord16)(rtp_data[7+2*i_CC]&0xFF)) << 8));
}
if (i_P==1) {
/* Padding exists. Find out how many bytes the padding consists of */
if (datagramLen & 0x1) {
/* odd number of bytes => last byte in higher byte */
i_padlength=(rtp_data[datagramLen>>1] & 0xFF);
} else {
/* even number of bytes => last byte in lower byte */
i_padlength=(((WebRtc_UWord16)rtp_data[(datagramLen>>1)-1]) >> 8);
}
}
i_startPosition=12+4*(i_extlength+1)+4*i_CC; int i_padlength = calcPadLength(i_P);
if (payloadPtr) { if (payloadPtr)
{
*payloadPtr = (WebRtc_UWord8*) &rtp_data[i_startPosition >> 1]; *payloadPtr = (WebRtc_UWord8*) &rtp_data[i_startPosition >> 1];
} }
return (WebRtc_UWord16) (datagramLen-i_startPosition-i_padlength); return (WebRtc_UWord16) (_datagramLen - i_startPosition - i_padlength);
} }
//void NETEQTEST_RTPpacket::splitStereoSample(WebRtc_UWord8 *data, WebRtc_UWord16 *lenBytes, WebRtc_UWord8 *slaveData, WebRtc_UWord16 *slaveLenBytes, int stride)
void NETEQTEST_RTPpacket::splitStereoSample(NETEQTEST_RTPpacket& slaveRtp, int stride) void NETEQTEST_RTPpacket::parseBasicHeader(WebRtcNetEQ_RTPInfo *RTPinfo,
int *i_P, int *i_X, int *i_CC) const
{ {
if(!_payloadPtr || !slaveRtp._payloadPtr WebRtc_Word16 *rtp_data = (WebRtc_Word16 *) _datagram;
|| _payloadLen <= 0 || slaveRtp._memSize < _memSize) if (_datagramLen < 12)
{
assert(false);
return;
}
*i_P=(((WebRtc_UWord16)(rtp_data[0] & 0x20))>>5); /* Extract the P bit */
*i_X=(((WebRtc_UWord16)(rtp_data[0] & 0x10))>>4); /* Extract the X bit */
*i_CC=(WebRtc_UWord16)(rtp_data[0] & 0xF); /* Get the CC number */
/* Get the marker bit */
RTPinfo->markerBit = (WebRtc_UWord8) ((rtp_data[0] >> 15) & 0x01);
/* Get the coder type */
RTPinfo->payloadType = (WebRtc_UWord8) ((rtp_data[0] >> 8) & 0x7F);
/* Get the packet number */
RTPinfo->sequenceNumber = ((( ((WebRtc_UWord16)rtp_data[1]) >> 8) & 0xFF) |
( ((WebRtc_UWord16)(rtp_data[1] & 0xFF)) << 8));
/* Get timestamp */
RTPinfo->timeStamp = ((((WebRtc_UWord16)rtp_data[2]) & 0xFF) << 24) |
((((WebRtc_UWord16)rtp_data[2]) & 0xFF00) << 8) |
((((WebRtc_UWord16)rtp_data[3]) >> 8) & 0xFF) |
((((WebRtc_UWord16)rtp_data[3]) & 0xFF) << 8);
/* Get the SSRC */
RTPinfo->SSRC=((((WebRtc_UWord16)rtp_data[4]) & 0xFF) << 24) |
((((WebRtc_UWord16)rtp_data[4]) & 0xFF00) << 8) |
((((WebRtc_UWord16)rtp_data[5]) >> 8) & 0xFF) |
((((WebRtc_UWord16)rtp_data[5]) & 0xFF) << 8);
}
int NETEQTEST_RTPpacket::calcHeaderLength(int i_X, int i_CC) const
{
int i_extlength = 0;
WebRtc_Word16 *rtp_data = (WebRtc_Word16 *) _datagram;
if (i_X == 1)
{
// Extension header exists.
// Find out how many WebRtc_Word32 it consists of.
assert(_datagramLen > 2 * (7 + 2 * i_CC));
if (_datagramLen > 2 * (7 + 2 * i_CC))
{
i_extlength = (((((WebRtc_UWord16) rtp_data[7 + 2 * i_CC]) >> 8)
& 0xFF) | (((WebRtc_UWord16) (rtp_data[7 + 2 * i_CC] & 0xFF))
<< 8)) + 1;
}
}
return 12 + 4 * i_extlength + 4 * i_CC;
}
int NETEQTEST_RTPpacket::calcPadLength(int i_P) const
{
WebRtc_Word16 *rtp_data = (WebRtc_Word16 *) _datagram;
if (i_P == 1)
{
/* Padding exists. Find out how many bytes the padding consists of. */
if (_datagramLen & 0x1)
{
/* odd number of bytes => last byte in higher byte */
return rtp_data[_datagramLen >> 1] & 0xFF;
}
else
{
/* even number of bytes => last byte in lower byte */
return ((WebRtc_UWord16) rtp_data[(_datagramLen >> 1) - 1]) >> 8;
}
}
return 0;
}
void NETEQTEST_RTPpacket::splitStereoSample(NETEQTEST_RTPpacket* slaveRtp,
int stride)
{
if(!_payloadPtr || !slaveRtp || !slaveRtp->_payloadPtr
|| _payloadLen <= 0 || slaveRtp->_memSize < _memSize)
{ {
return; return;
} }
WebRtc_UWord8 *readDataPtr = _payloadPtr; WebRtc_UWord8 *readDataPtr = _payloadPtr;
WebRtc_UWord8 *writeDataPtr = _payloadPtr; WebRtc_UWord8 *writeDataPtr = _payloadPtr;
WebRtc_UWord8 *slaveData = slaveRtp._payloadPtr; WebRtc_UWord8 *slaveData = slaveRtp->_payloadPtr;
while (readDataPtr - _payloadPtr < _payloadLen) while (readDataPtr - _payloadPtr < _payloadLen)
{ {
@@ -789,23 +762,22 @@ void NETEQTEST_RTPpacket::splitStereoSample(NETEQTEST_RTPpacket& slaveRtp, int s
} }
_payloadLen /= 2; _payloadLen /= 2;
slaveRtp._payloadLen = _payloadLen; slaveRtp->_payloadLen = _payloadLen;
} }
//void NETEQTEST_RTPpacket::splitStereoFrame(WebRtc_UWord8 *data, WebRtc_UWord16 *lenBytes, WebRtc_UWord8 *slaveData, WebRtc_UWord16 *slaveLenBytes) void NETEQTEST_RTPpacket::splitStereoFrame(NETEQTEST_RTPpacket* slaveRtp)
void NETEQTEST_RTPpacket::splitStereoFrame(NETEQTEST_RTPpacket& slaveRtp)
{ {
if(!_payloadPtr || !slaveRtp._payloadPtr if(!_payloadPtr || !slaveRtp || !slaveRtp->_payloadPtr
|| _payloadLen <= 0 || slaveRtp._memSize < _memSize) || _payloadLen <= 0 || slaveRtp->_memSize < _memSize)
{ {
return; return;
} }
memmove(slaveRtp._payloadPtr, _payloadPtr + _payloadLen/2, _payloadLen/2); memmove(slaveRtp->_payloadPtr, _payloadPtr + _payloadLen/2, _payloadLen/2);
_payloadLen /= 2; _payloadLen /= 2;
slaveRtp._payloadLen = _payloadLen; slaveRtp->_payloadLen = _payloadLen;
} }
// Get the RTP header for the RED payload indicated by argument index. // Get the RTP header for the RED payload indicated by argument index.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
* *
* Use of this source code is governed by a BSD-style license * Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source * that can be found in the LICENSE file in the root of the source
@@ -27,15 +27,13 @@ class NETEQTEST_RTPpacket
{ {
public: public:
NETEQTEST_RTPpacket(); NETEQTEST_RTPpacket();
NETEQTEST_RTPpacket(const NETEQTEST_RTPpacket& copyFromMe);
NETEQTEST_RTPpacket & operator = (const NETEQTEST_RTPpacket & other);
bool operator !() const { return (dataLen() < 0); }; bool operator !() const { return (dataLen() < 0); };
~NETEQTEST_RTPpacket(); virtual ~NETEQTEST_RTPpacket();
void reset(); void reset();
static int skipFileHeader(FILE *fp); static int skipFileHeader(FILE *fp);
int readFromFile(FILE *fp); virtual int readFromFile(FILE *fp);
int readFixedFromFile(FILE *fp, size_t len); int readFixedFromFile(FILE *fp, size_t len);
int writeToFile(FILE *fp); virtual int writeToFile(FILE *fp);
void blockPT(WebRtc_UWord8 pt); void blockPT(WebRtc_UWord8 pt);
//WebRtc_Word16 payloadType(); //WebRtc_Word16 payloadType();
void parseHeader(); void parseHeader();
@@ -43,7 +41,7 @@ public:
WebRtcNetEQ_RTPInfo const * RTPinfo() const; WebRtcNetEQ_RTPInfo const * RTPinfo() const;
WebRtc_UWord8 * datagram() const; WebRtc_UWord8 * datagram() const;
WebRtc_UWord8 * payload() const; WebRtc_UWord8 * payload() const;
WebRtc_Word16 payloadLen() const; WebRtc_Word16 payloadLen();
WebRtc_Word16 dataLen() const; WebRtc_Word16 dataLen() const;
bool isParsed() const; bool isParsed() const;
bool isLost() const; bool isLost() const;
@@ -64,7 +62,7 @@ public:
int setRTPheader(const WebRtcNetEQ_RTPInfo *RTPinfo); int setRTPheader(const WebRtcNetEQ_RTPInfo *RTPinfo);
int splitStereo(NETEQTEST_RTPpacket& slaveRtp, enum stereoModes mode); int splitStereo(NETEQTEST_RTPpacket* slaveRtp, enum stereoModes mode);
int extractRED(int index, WebRtcNetEQ_RTPInfo& red); int extractRED(int index, WebRtcNetEQ_RTPInfo& red);
@@ -81,11 +79,25 @@ public:
bool _lost; bool _lost;
std::map<WebRtc_UWord8, bool> _blockList; std::map<WebRtc_UWord8, bool> _blockList;
protected:
static const int _kRDHeaderLen;
static const int _kBasicHeaderLen;
void parseBasicHeader(WebRtcNetEQ_RTPInfo *RTPinfo, int *i_P, int *i_X,
int *i_CC) const;
int calcHeaderLength(int i_X, int i_CC) const;
private: private:
void makeRTPheader(unsigned char* rtp_data, WebRtc_UWord8 payloadType, WebRtc_UWord16 seqNo, WebRtc_UWord32 timestamp, WebRtc_UWord32 ssrc, WebRtc_UWord8 markerBit) const; void makeRTPheader(unsigned char* rtp_data, WebRtc_UWord8 payloadType,
WebRtc_UWord16 parseRTPheader(const WebRtc_UWord8 *datagram, int datagramLen, WebRtcNetEQ_RTPInfo *RTPinfo, WebRtc_UWord8 **payloadPtr = NULL) const; WebRtc_UWord16 seqNo, WebRtc_UWord32 timestamp,
void splitStereoSample(NETEQTEST_RTPpacket& slaveRtp, int stride); WebRtc_UWord32 ssrc, WebRtc_UWord8 markerBit) const;
void splitStereoFrame(NETEQTEST_RTPpacket& slaveRtp); WebRtc_UWord16 parseRTPheader(WebRtcNetEQ_RTPInfo *RTPinfo,
WebRtc_UWord8 **payloadPtr = NULL) const;
WebRtc_UWord16 parseRTPheader(WebRtc_UWord8 **payloadPtr = NULL)
{ return parseRTPheader(&_rtpInfo, payloadPtr);};
int calcPadLength(int i_P) const;
void splitStereoSample(NETEQTEST_RTPpacket* slaveRtp, int stride);
void splitStereoFrame(NETEQTEST_RTPpacket* slaveRtp);
}; };
#endif //NETEQTEST_RTPPACKET_H #endif //NETEQTEST_RTPPACKET_H

View File

@@ -19,6 +19,7 @@
#include "neteq_error_codes.h" // for the API test #include "neteq_error_codes.h" // for the API test
#include "NETEQTEST_RTPpacket.h" #include "NETEQTEST_RTPpacket.h"
#include "NETEQTEST_DummyRTPpacket.h"
#include "NETEQTEST_NetEQClass.h" #include "NETEQTEST_NetEQClass.h"
#include "NETEQTEST_CodecClass.h" #include "NETEQTEST_CodecClass.h"
@@ -113,7 +114,7 @@ typedef struct {
void stereoInterleave(WebRtc_Word16 *data, WebRtc_Word16 totalLen); void stereoInterleave(WebRtc_Word16 *data, WebRtc_Word16 totalLen);
int getNextRecoutTime(FILE *fp, WebRtc_UWord32 *nextTime); int getNextRecoutTime(FILE *fp, WebRtc_UWord32 *nextTime);
void getNextExtraDelay(FILE *fp, WebRtc_UWord32 *t, int *d); void getNextExtraDelay(FILE *fp, WebRtc_UWord32 *t, int *d);
bool splitStereo(NETEQTEST_RTPpacket& rtp, NETEQTEST_RTPpacket& rtpSlave, bool splitStereo(NETEQTEST_RTPpacket* rtp, NETEQTEST_RTPpacket* rtpSlave,
const WebRtc_Word16 *stereoPtype, const enum stereoModes *stereoMode, int noOfStereoCodecs, const WebRtc_Word16 *stereoPtype, const enum stereoModes *stereoMode, int noOfStereoCodecs,
const WebRtc_Word16 *cngPtype, int noOfCngCodecs, const WebRtc_Word16 *cngPtype, int noOfCngCodecs,
bool *isStereo); bool *isStereo);
@@ -150,12 +151,8 @@ WebRtc_UWord32 simClock=0;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
std::vector<NETEQTEST_NetEQClass *> NetEQvector; std::vector<NETEQTEST_NetEQClass *> NetEQvector;
NETEQTEST_RTPpacket rtp;
char version[20]; char version[20];
NETEQTEST_RTPpacket slaveRtp;
//bool switchMS = false;
//bool duplicatePayload = false;
enum WebRtcNetEQDecoder usedCodec[kDecoderReservedEnd-1]; enum WebRtcNetEQDecoder usedCodec[kDecoderReservedEnd-1];
int noOfCodecs; int noOfCodecs;
int ok; int ok;
@@ -185,6 +182,8 @@ int main(int argc, char* argv[])
int packetLen = 0; int packetLen = 0;
int packetCount = 0; int packetCount = 0;
std::map<WebRtc_UWord8, decoderStruct> decoders; std::map<WebRtc_UWord8, decoderStruct> decoders;
bool dummyRtp = false;
bool noDecode = false;
/* get the version string */ /* get the version string */
WebRtcNetEQ_GetVersion(version); WebRtcNetEQ_GetVersion(version);
@@ -225,6 +224,8 @@ int main(int argc, char* argv[])
printf("\t-fax : engage fax mode\n"); printf("\t-fax : engage fax mode\n");
printf("\t-preparsertp : use RecIn with pre-parsed RTP\n"); printf("\t-preparsertp : use RecIn with pre-parsed RTP\n");
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-nodecode : no decoding will be done\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");
@@ -269,7 +270,6 @@ int main(int argc, char* argv[])
printf("Output file: %s\n",outfilename); printf("Output file: %s\n",outfilename);
// Parse for more arguments, all beginning with '-' // Parse for more arguments, all beginning with '-'
while( argIx < argc ) { while( argIx < argc ) {
if (argv[argIx][0] != '-') { if (argv[argIx][0] != '-') {
fprintf(stderr,"Unknown input argument %s\n", argv[argIx]); fprintf(stderr,"Unknown input argument %s\n", argv[argIx]);
@@ -311,6 +311,18 @@ int main(int argc, char* argv[])
exit(1); exit(1);
} }
} }
else if (strcmp(argv[argIx], "-dummyrtp") == 0
|| strcmp(argv[argIx], "-dummy") == 0)
{
argIx++;
dummyRtp = true;
noDecode = true; // force noDecode since there are no payloads
}
else if (strcmp(argv[argIx], "-nodecode") == 0)
{
argIx++;
noDecode = true;
}
//else if( strcmp(argv[argIx], "-switchms") == 0 ) { //else if( strcmp(argv[argIx], "-switchms") == 0 ) {
// argIx++; // argIx++;
// switchMS = true; // switchMS = true;
@@ -382,32 +394,45 @@ int main(int argc, char* argv[])
long tempFilePos = ftell(in_file); long tempFilePos = ftell(in_file);
enum stereoModes stereoMode = stereoModeMono; enum stereoModes stereoMode = stereoModeMono;
NETEQTEST_RTPpacket *rtp;
NETEQTEST_RTPpacket *slaveRtp;
if (!dummyRtp)
{
rtp = new NETEQTEST_RTPpacket();
slaveRtp = new NETEQTEST_RTPpacket();
}
else
{
rtp = new NETEQTEST_DummyRTPpacket();
slaveRtp = new NETEQTEST_DummyRTPpacket();
}
if (!rtpOnly) if (!rtpOnly)
{ {
while (rtp.readFromFile(in_file) >= 0) while (rtp->readFromFile(in_file) >= 0)
{ {
if (decoders.count(rtp.payloadType()) > 0 if (decoders.count(rtp->payloadType()) > 0
&& decoders[rtp.payloadType()].codec != kDecoderRED && decoders[rtp->payloadType()].codec != kDecoderRED
&& decoders[rtp.payloadType()].codec != kDecoderAVT && decoders[rtp->payloadType()].codec != kDecoderAVT
&& decoders[rtp.payloadType()].codec != kDecoderCNG ) && decoders[rtp->payloadType()].codec != kDecoderCNG )
{ {
stereoMode = decoders[rtp.payloadType()].stereo; stereoMode = decoders[rtp->payloadType()].stereo;
fs = decoders[rtp.payloadType()].fs; fs = decoders[rtp->payloadType()].fs;
break; break;
} }
} }
} }
else else
{ {
while (rtp.readFixedFromFile(in_file, packetLen) >= 0) while (rtp->readFixedFromFile(in_file, packetLen) >= 0)
{ {
if (decoders.count(rtp.payloadType()) > 0 if (decoders.count(rtp->payloadType()) > 0
&& decoders[rtp.payloadType()].codec != kDecoderRED && decoders[rtp->payloadType()].codec != kDecoderRED
&& decoders[rtp.payloadType()].codec != kDecoderAVT && decoders[rtp->payloadType()].codec != kDecoderAVT
&& decoders[rtp.payloadType()].codec != kDecoderCNG ) && decoders[rtp->payloadType()].codec != kDecoderCNG )
{ {
stereoMode = decoders[rtp.payloadType()].stereo; stereoMode = decoders[rtp->payloadType()].stereo;
fs = decoders[rtp.payloadType()].fs; fs = decoders[rtp->payloadType()].fs;
break; break;
} }
} }
@@ -417,18 +442,18 @@ int main(int argc, char* argv[])
/* block some payload types */ /* block some payload types */
//rtp.blockPT(72); //rtp->blockPT(72);
//rtp.blockPT(23); //rtp->blockPT(23);
/* read first packet */ /* read first packet */
if (!rtpOnly) if (!rtpOnly)
{ {
rtp.readFromFile(in_file); rtp->readFromFile(in_file);
} }
else else
{ {
rtp.readFixedFromFile(in_file, packetLen); rtp->readFixedFromFile(in_file, packetLen);
rtp.setTime((1000 * rtp.timeStamp()) / fs); rtp->setTime((1000 * rtp->timeStamp()) / fs);
} }
if (!rtp) if (!rtp)
{ {
@@ -456,26 +481,28 @@ int main(int argc, char* argv[])
NetEQvector[i]->usePreparseRTP(preParseRTP); NetEQvector[i]->usePreparseRTP(preParseRTP);
NetEQvector[i]->setNoDecode(noDecode);
if (numInst > 1) if (numInst > 1)
{ {
// we are using master/slave mode // we are using master/slave mode
if (i == 0) if (i == 0)
{ {
// first instance is master // first instance is master
NetEQvector[i]->isMaster(); NetEQvector[i]->setMaster();
} }
else else
{ {
// all other are slaves // all other are slaves
NetEQvector[i]->isSlave(); NetEQvector[i]->setSlave();
} }
} }
} }
#ifdef ZERO_TS_START #ifdef ZERO_TS_START
WebRtc_UWord32 firstTS = rtp.timeStamp(); WebRtc_UWord32 firstTS = rtp->timeStamp();
rtp.setTimeStamp(0); rtp->setTimeStamp(0);
#else #else
WebRtc_UWord32 firstTS = 0; WebRtc_UWord32 firstTS = 0;
#endif #endif
@@ -483,14 +510,14 @@ int main(int argc, char* argv[])
// check stereo mode // check stereo mode
if (stereoMode > stereoModeMono) if (stereoMode > stereoModeMono)
{ {
if(rtp.splitStereo(slaveRtp, stereoMode)) if(rtp->splitStereo(slaveRtp, stereoMode))
{ {
printf("Error in splitStereo\n"); printf("Error in splitStereo\n");
} }
} }
#ifdef PLAY_CLEAN #ifdef PLAY_CLEAN
WebRtc_UWord32 prevTS = rtp.timeStamp(); WebRtc_UWord32 prevTS = rtp->timeStamp();
WebRtc_UWord32 currTS, prev_time; WebRtc_UWord32 currTS, prev_time;
#endif #endif
@@ -511,9 +538,9 @@ int main(int argc, char* argv[])
int lastRecout = getNextRecoutTime(recoutTimes, &nextRecoutTime); // does nothing if recoutTimes == NULL int lastRecout = getNextRecoutTime(recoutTimes, &nextRecoutTime); // does nothing if recoutTimes == NULL
if (recoutTimes) if (recoutTimes)
simClock = (rtp.time() < nextRecoutTime ? rtp.time(): nextRecoutTime); simClock = (rtp->time() < nextRecoutTime ? rtp->time(): nextRecoutTime);
else else
simClock = rtp.time(); // start immediately with first packet simClock = rtp->time(); // start immediately with first packet
WebRtc_UWord32 start_clock = simClock; WebRtc_UWord32 start_clock = simClock;
@@ -526,7 +553,7 @@ int main(int argc, char* argv[])
if(msInfo == NULL) if(msInfo == NULL)
return(-1); return(-1);
while(rtp.dataLen() >= 0 || (recoutTimes && !lastRecout)) { while(rtp->dataLen() >= 0 || (recoutTimes && !lastRecout)) {
// printf("simClock = %Lu\n", simClock); // printf("simClock = %Lu\n", simClock);
#ifdef NETEQ_DELAY_LOGGING #ifdef NETEQ_DELAY_LOGGING
@@ -546,60 +573,60 @@ int main(int argc, char* argv[])
} }
/* check if time to receive */ /* check if time to receive */
while (simClock >= rtp.time() && rtp.dataLen() >= 0) while (simClock >= rtp->time() && rtp->dataLen() >= 0)
{ {
if (rtp.dataLen() > 0) if (rtp->dataLen() > 0)
{ {
// insert main packet // insert main packet
NetEQvector[0]->recIn(rtp); NetEQvector[0]->recIn(*rtp);
if (stereoMode > stereoModeMono if (stereoMode > stereoModeMono
&& slaveRtp.dataLen() > 0) && slaveRtp->dataLen() > 0)
{ {
// insert slave packet // insert slave packet
NetEQvector[1]->recIn(slaveRtp); NetEQvector[1]->recIn(*slaveRtp);
} }
} }
/* get next packet */ /* get next packet */
#ifdef PLAY_CLEAN #ifdef PLAY_CLEAN
prev_time = rtp.time(); prev_time = rtp->time();
#endif #endif
if (!rtpOnly) if (!rtpOnly)
{ {
rtp.readFromFile(in_file); rtp->readFromFile(in_file);
} }
else else
{ {
rtp.readFixedFromFile(in_file, packetLen); rtp->readFixedFromFile(in_file, packetLen);
rtp.setTime((1000 * rtp.timeStamp()) / fs); rtp->setTime((1000 * rtp->timeStamp()) / fs);
} }
if (rtp.dataLen() >= 0) if (rtp->dataLen() >= 0)
{ {
rtp.setTimeStamp(rtp.timeStamp() - firstTS); rtp->setTimeStamp(rtp->timeStamp() - firstTS);
} }
packetCount++; packetCount++;
if (changeStereoMode(rtp, decoders, &stereoMode)) if (changeStereoMode(*rtp, decoders, &stereoMode))
{ {
printf("Warning: stereo mode changed\n"); printf("Warning: stereo mode changed\n");
} }
if (stereoMode > stereoModeMono) if (stereoMode > stereoModeMono)
{ {
if(rtp.splitStereo(slaveRtp, stereoMode)) if(rtp->splitStereo(slaveRtp, stereoMode))
{ {
printf("Error in splitStereo\n"); printf("Error in splitStereo\n");
} }
} }
#ifdef PLAY_CLEAN #ifdef PLAY_CLEAN
currTS = rtp.timeStamp(); currTS = rtp->timeStamp();
rtp.setTime(prev_time + (currTS-prevTS)/(fs/1000)); rtp->setTime(prev_time + (currTS-prevTS)/(fs/1000));
prevTS = currTS; prevTS = currTS;
#endif #endif
} }
@@ -668,6 +695,9 @@ int main(int argc, char* argv[])
printf(" RecIn complexity : %.2f MCPS\n", NetEQvector[0]->getRecInTime() / ((float) 1000*(simClock-start_clock))); printf(" RecIn complexity : %.2f MCPS\n", NetEQvector[0]->getRecInTime() / ((float) 1000*(simClock-start_clock)));
printf(" RecOut complexity : %.2f MCPS\n", NetEQvector[0]->getRecOutTime() / ((float) 1000*(simClock-start_clock))); printf(" RecOut complexity : %.2f MCPS\n", NetEQvector[0]->getRecOutTime() / ((float) 1000*(simClock-start_clock)));
delete rtp;
delete slaveRtp;
free_coders(decoders); free_coders(decoders);
//free_coders(0 /* first channel */); //free_coders(0 /* first channel */);
// if (stereoMode > stereoModeMono) { // if (stereoMode > stereoModeMono) {
@@ -709,7 +739,7 @@ int main(int argc, char* argv[])
/* Subfunctions */ /* Subfunctions */
/****************/ /****************/
bool splitStereo(NETEQTEST_RTPpacket& rtp, NETEQTEST_RTPpacket& rtpSlave, bool splitStereo(NETEQTEST_RTPpacket* rtp, NETEQTEST_RTPpacket* rtpSlave,
const WebRtc_Word16 *stereoPtype, const enum stereoModes *stereoMode, int noOfStereoCodecs, const WebRtc_Word16 *stereoPtype, const enum stereoModes *stereoMode, int noOfStereoCodecs,
const WebRtc_Word16 *cngPtype, int noOfCngCodecs, const WebRtc_Word16 *cngPtype, int noOfCngCodecs,
bool *isStereo) bool *isStereo)
@@ -721,13 +751,13 @@ bool splitStereo(NETEQTEST_RTPpacket& rtp, NETEQTEST_RTPpacket& rtpSlave,
bool isCng = false; bool isCng = false;
// check payload length // check payload length
if (rtp.dataLen() <= 0) { if (rtp->dataLen() <= 0) {
//*isStereo = false; // don't change //*isStereo = false; // don't change
return(*isStereo); return(*isStereo);
} }
// check payload type // check payload type
WebRtc_Word16 ptype = rtp.payloadType(); WebRtc_Word16 ptype = rtp->payloadType();
// is this a cng payload? // is this a cng payload?
for (int k = 0; k < noOfCngCodecs; k++) { for (int k = 0; k < noOfCngCodecs; k++) {
@@ -756,7 +786,7 @@ bool splitStereo(NETEQTEST_RTPpacket& rtp, NETEQTEST_RTPpacket& rtpSlave,
{ {
// split the payload if stereo // split the payload if stereo
if(rtp.splitStereo(rtpSlave, tempStereoMode)) if(rtp->splitStereo(rtpSlave, tempStereoMode))
{ {
printf("Error in splitStereo\n"); printf("Error in splitStereo\n");
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
* *
* Use of this source code is governed by a BSD-style license * Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source * that can be found in the LICENSE file in the root of the source
@@ -13,6 +13,9 @@
#include <vector> #include <vector>
#include "modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.h" #include "modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.h"
#include "modules/audio_coding/neteq/test/NETEQTEST_DummyRTPpacket.h"
//#define WEBRTC_DUMMY_RTP
enum { enum {
kRedPayloadType = 127 kRedPayloadType = 127
@@ -38,7 +41,11 @@ int main(int argc, char* argv[]) {
// Read file header. // Read file header.
NETEQTEST_RTPpacket::skipFileHeader(in_file); NETEQTEST_RTPpacket::skipFileHeader(in_file);
#ifdef WEBRTC_DUMMY_RTP
NETEQTEST_DummyRTPpacket packet;
#else
NETEQTEST_RTPpacket packet; NETEQTEST_RTPpacket packet;
#endif
while (packet.readFromFile(in_file) >= 0) { while (packet.readFromFile(in_file) >= 0) {
// Write packet data to file. // Write packet data to file.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
* *
* Use of this source code is governed by a BSD-style license * Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source * that can be found in the LICENSE file in the root of the source
@@ -13,10 +13,11 @@
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
#include "gtest/gtest.h"
#include "modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.h" #include "modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.h"
#include "modules/audio_coding/neteq/test/NETEQTEST_DummyRTPPacket.h"
#define FIRSTLINELEN 40 #define FIRSTLINELEN 40
//#define WEBRTC_DUMMY_RTP
static bool pktCmp(NETEQTEST_RTPpacket *a, NETEQTEST_RTPpacket *b) { static bool pktCmp(NETEQTEST_RTPpacket *a, NETEQTEST_RTPpacket *b) {
return (a->time() < b->time()); return (a->time() < b->time());
@@ -91,7 +92,11 @@ int main(int argc, char* argv[]) {
while (1) { while (1) {
// Insert in vector. // Insert in vector.
#ifdef WEBRTC_DUMMY_RTP
NETEQTEST_RTPpacket *new_packet = new NETEQTEST_DummyRTPpacket();
#else
NETEQTEST_RTPpacket *new_packet = new NETEQTEST_RTPpacket(); NETEQTEST_RTPpacket *new_packet = new NETEQTEST_RTPpacket();
#endif
if (new_packet->readFromFile(in_file) < 0) { if (new_packet->readFromFile(in_file) < 0) {
// End of file. // End of file.
break; break;

View File

@@ -0,0 +1,115 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
/*
* Parses an rtpdump file and outputs a text table parsable by parseLog.m.
* The output file will have .txt appended to the specified base name.
* $ rtp_to_text [-d] <input_rtp_file> <output_base_name>
*
* -d RTP headers only
*
*/
#include "data_log.h"
#include "NETEQTEST_DummyRTPpacket.h"
#include "NETEQTEST_RTPpacket.h"
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <vector>
/*********************/
/* Misc. definitions */
/*********************/
#define FIRSTLINELEN 40
using ::webrtc::DataLog;
int main(int argc, char* argv[])
{
int arg_count = 1;
NETEQTEST_RTPpacket* packet;
if (argc < 3)
{
printf("Usage: %s [-d] <input_rtp_file> <output_base_name>\n", argv[0]);
return -1;
}
// Parse dummy option
if (argc >= 3 && strcmp(argv[arg_count], "-d") == 0)
{
packet = new NETEQTEST_DummyRTPpacket;
++arg_count;
}
else
{
packet = new NETEQTEST_RTPpacket;
}
std::string input_filename = argv[arg_count++];
std::string table_name = argv[arg_count];
std::cout << "Input file: " << input_filename << std::endl;
std::cout << "Output file: " << table_name << ".txt" << std::endl;
FILE *inFile=fopen(input_filename.c_str(),"rb");
if (!inFile)
{
std::cout << "Cannot open input file " << input_filename << std::endl;
return -1;
}
// Set up the DataLog and define the table
DataLog::CreateLog();
if (DataLog::AddTable(table_name) < 0)
{
std::cout << "Error adding table " << table_name << ".txt" << std::endl;
return -1;
}
DataLog::AddColumn(table_name, "seq", 1);
DataLog::AddColumn(table_name, "ssrc", 1);
DataLog::AddColumn(table_name, "payload type", 1);
DataLog::AddColumn(table_name, "length", 1);
DataLog::AddColumn(table_name, "timestamp", 1);
DataLog::AddColumn(table_name, "marker bit", 1);
DataLog::AddColumn(table_name, "arrival", 1);
// read file header
char firstline[FIRSTLINELEN];
fgets(firstline, FIRSTLINELEN, inFile);
// start_sec + start_usec + source + port + padding
fread(firstline, 4+4+4+2+2, 1, inFile);
while (packet->readFromFile(inFile) >= 0)
{
// write packet headers to
DataLog::InsertCell(table_name, "seq", packet->sequenceNumber());
DataLog::InsertCell(table_name, "ssrc", packet->SSRC());
DataLog::InsertCell(table_name, "payload type", packet->payloadType());
DataLog::InsertCell(table_name, "length", packet->dataLen());
DataLog::InsertCell(table_name, "timestamp", packet->timeStamp());
DataLog::InsertCell(table_name, "marker bit", packet->markerBit());
DataLog::InsertCell(table_name, "arrival", packet->time());
DataLog::NextRow(table_name);
return -1;
}
DataLog::ReturnLog();
fclose(inFile);
return 0;
}