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
# that can be found in the LICENSE file in the root of the source
@ -105,8 +105,8 @@
'target_name': 'NetEqRTPplay',
'type': 'executable',
'dependencies': [
'NetEq', # NetEQ library defined above
'NetEqTestTools',# Test helpers
'NetEq', # NetEQ library defined above
'NetEqTestTools', # Test helpers
'G711',
'G722',
'PCM16B',
@ -229,10 +229,25 @@
'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',
# Collection of useful functions used in other tests
'type': '<(library)',
'variables': {
# Expects RTP packets without payloads when enabled.
'neteq_dummy_rtp%': 0,
},
'dependencies': [
'G711',
'G722',
@ -269,21 +284,17 @@
'test',
],
'sources': [
'test/NETEQTEST_NetEQClass.cc',
'test/NETEQTEST_RTPpacket.cc',
'test/NETEQTEST_CodecClass.cc',
'test/NETEQTEST_NetEQClass.h',
'test/NETEQTEST_RTPpacket.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
}], # build_with_chromium
], # 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
* that can be found in the LICENSE file in the root of the source
@ -20,7 +20,8 @@ NETEQTEST_NetEQClass::NETEQTEST_NetEQClass()
_bufferMem(NULL),
_preparseRTP(false),
_fsmult(1),
_isMaster(true)
_isMaster(true),
_noDecode(false)
{
#ifdef WINDOWS_TIMING
_totTimeRecIn.QuadPart = 0;
@ -283,7 +284,14 @@ WebRtc_Word16 NETEQTEST_NetEQClass::recOut(WebRtc_Word16 *outData, void *msInfo,
if (!msInfo)
{
// no msInfo given, do mono mode
err = WebRtcNetEQ_RecOut(_inst, outData, &outLen);
if (_noDecode)
{
err = WebRtcNetEQ_RecOutNoDecode(_inst, outData, &outLen);
}
else
{
err = WebRtcNetEQ_RecOut(_inst, outData, &outLen);
}
}
else
{

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
* that can be found in the LICENSE file in the root of the source
@ -47,8 +47,10 @@ public:
bool usingPreparseRTP() { return (_preparseRTP); };
void setMaster( bool isMaster = true ) { _isMaster = isMaster; };
void setSlave() { _isMaster = false; };
void setNoDecode(bool noDecode = true) { _noDecode = noDecode; };
bool isMaster() { return (_isMaster); };
bool isSlave() { return (!_isMaster); };
bool isNoDecode() { return _noDecode; };
#ifdef WINDOWS_TIMING
double getRecInTime() { return (static_cast<double>( _totTimeRecIn.QuadPart )); };
@ -69,24 +71,11 @@ private:
bool _preparseRTP;
int _fsmult;
bool _isMaster;
bool _noDecode;
#ifdef WINDOWS_TIMING
LARGE_INTEGER _totTimeRecIn;
LARGE_INTEGER _totTimeRecOut;
#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

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
* 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
#endif
#include <cstdlib>
#include "gtest/gtest.h"
#define HDR_SIZE 8 // rtpplay packet header size in bytes
const int NETEQTEST_RTPpacket::_kRDHeaderLen = 8;
const int NETEQTEST_RTPpacket::_kBasicHeaderLen = 12;
NETEQTEST_RTPpacket::NETEQTEST_RTPpacket()
:
@ -41,88 +37,14 @@ _lost(false)
_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()
{
if(_datagram)
if(_datagram)
{
delete [] _datagram;
}
}
void NETEQTEST_RTPpacket::reset()
{
if(_datagram) {
@ -180,7 +102,7 @@ int NETEQTEST_RTPpacket::readFromFile(FILE *fp)
return(-1);
}
WebRtc_UWord16 length, plen;
WebRtc_UWord16 length, plen;
WebRtc_UWord32 offset;
if (fread(&length,2,1,fp)==0)
@ -203,9 +125,9 @@ int NETEQTEST_RTPpacket::readFromFile(FILE *fp)
return(-1);
}
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
length = (WebRtc_UWord16) (length - HDR_SIZE);
// Use length here because a plen of 0 specifies rtcp
length = (WebRtc_UWord16) (length - _kRDHeaderLen);
// check buffer size
if (_datagram && _memSize < length)
@ -219,10 +141,10 @@ int NETEQTEST_RTPpacket::readFromFile(FILE *fp)
_memSize = length;
}
if (fread((unsigned short *) _datagram,1,length,fp) != length)
if (fread((unsigned short *) _datagram,1,length,fp) != length)
{
reset();
return(-1);
return(-1);
}
_datagramLen = length;
@ -234,7 +156,7 @@ int NETEQTEST_RTPpacket::readFromFile(FILE *fp)
return(readFromFile(fp));
}
return(packetLen);
return(packetLen);
}
@ -289,7 +211,7 @@ int NETEQTEST_RTPpacket::writeToFile(FILE *fp)
WebRtc_UWord32 offset;
// length including RTPplay header
length = htons(_datagramLen + HDR_SIZE);
length = htons(_datagramLen + _kRDHeaderLen);
if (fwrite(&length, 2, 1, fp) != 1)
{
return -1;
@ -301,7 +223,7 @@ int NETEQTEST_RTPpacket::writeToFile(FILE *fp)
{
return -1;
}
// offset (=receive time)
offset = htonl(_receiveTime);
if (fwrite(&offset, 4, 1, fp) != 1)
@ -317,7 +239,7 @@ int NETEQTEST_RTPpacket::writeToFile(FILE *fp)
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;
}
if (_datagramLen < 12)
if (_datagramLen < _kBasicHeaderLen)
{
// corrupt packet?
return;
}
_payloadLen = parseRTPheader(_datagram, _datagramLen, &_rtpInfo, &_payloadPtr);
_payloadLen = parseRTPheader(&_payloadPtr);
_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;
}
@ -420,10 +343,10 @@ bool NETEQTEST_RTPpacket::isLost() const
WebRtc_UWord8 NETEQTEST_RTPpacket::payloadType() const
{
WebRtcNetEQ_RTPInfo tempRTPinfo;
if(_datagram)
if(_datagram && _datagramLen >= _kBasicHeaderLen)
{
parseRTPheader(_datagram, _datagramLen, &tempRTPinfo);
parseRTPheader(&tempRTPinfo);
}
else
{
@ -436,10 +359,10 @@ WebRtc_UWord8 NETEQTEST_RTPpacket::payloadType() const
WebRtc_UWord16 NETEQTEST_RTPpacket::sequenceNumber() const
{
WebRtcNetEQ_RTPInfo tempRTPinfo;
if(_datagram)
if(_datagram && _datagramLen >= _kBasicHeaderLen)
{
parseRTPheader(_datagram, _datagramLen, &tempRTPinfo);
parseRTPheader(&tempRTPinfo);
}
else
{
@ -452,10 +375,10 @@ WebRtc_UWord16 NETEQTEST_RTPpacket::sequenceNumber() const
WebRtc_UWord32 NETEQTEST_RTPpacket::timeStamp() const
{
WebRtcNetEQ_RTPInfo tempRTPinfo;
if(_datagram)
if(_datagram && _datagramLen >= _kBasicHeaderLen)
{
parseRTPheader(_datagram, _datagramLen, &tempRTPinfo);
parseRTPheader(&tempRTPinfo);
}
else
{
@ -468,10 +391,10 @@ WebRtc_UWord32 NETEQTEST_RTPpacket::timeStamp() const
WebRtc_UWord32 NETEQTEST_RTPpacket::SSRC() const
{
WebRtcNetEQ_RTPInfo tempRTPinfo;
if(_datagram)
if(_datagram && _datagramLen >= _kBasicHeaderLen)
{
parseRTPheader(_datagram, _datagramLen, &tempRTPinfo);
parseRTPheader(&tempRTPinfo);
}
else
{
@ -484,10 +407,10 @@ WebRtc_UWord32 NETEQTEST_RTPpacket::SSRC() const
WebRtc_UWord8 NETEQTEST_RTPpacket::markerBit() const
{
WebRtcNetEQ_RTPInfo tempRTPinfo;
if(_datagram)
if(_datagram && _datagramLen >= _kBasicHeaderLen)
{
parseRTPheader(_datagram, _datagramLen, &tempRTPinfo);
parseRTPheader(&tempRTPinfo);
}
else
{
@ -501,7 +424,7 @@ WebRtc_UWord8 NETEQTEST_RTPpacket::markerBit() const
int NETEQTEST_RTPpacket::setPayloadType(WebRtc_UWord8 pt)
{
if (_datagramLen < 12)
{
return -1;
@ -520,7 +443,7 @@ int NETEQTEST_RTPpacket::setPayloadType(WebRtc_UWord8 pt)
int NETEQTEST_RTPpacket::setSequenceNumber(WebRtc_UWord16 sn)
{
if (_datagramLen < 12)
{
return -1;
@ -540,7 +463,7 @@ int NETEQTEST_RTPpacket::setSequenceNumber(WebRtc_UWord16 sn)
int NETEQTEST_RTPpacket::setTimeStamp(WebRtc_UWord32 ts)
{
if (_datagramLen < 12)
{
return -1;
@ -553,7 +476,7 @@ int NETEQTEST_RTPpacket::setTimeStamp(WebRtc_UWord32 ts)
_datagram[4]=(unsigned char)((ts>>24)&0xFF);
_datagram[5]=(unsigned char)((ts>>16)&0xFF);
_datagram[6]=(unsigned char)((ts>>8)&0xFF);
_datagram[6]=(unsigned char)((ts>>8)&0xFF);
_datagram[7]=(unsigned char)(ts & 0xFF);
return 0;
@ -562,7 +485,7 @@ int NETEQTEST_RTPpacket::setTimeStamp(WebRtc_UWord32 ts)
int NETEQTEST_RTPpacket::setSSRC(WebRtc_UWord32 ssrc)
{
if (_datagramLen < 12)
{
return -1;
@ -584,7 +507,7 @@ int NETEQTEST_RTPpacket::setSSRC(WebRtc_UWord32 ssrc)
int NETEQTEST_RTPpacket::setMarkerBit(WebRtc_UWord8 mb)
{
if (_datagramLen < 12)
{
return -1;
@ -616,10 +539,10 @@ int NETEQTEST_RTPpacket::setRTPheader(const WebRtcNetEQ_RTPInfo *RTPinfo)
return -1;
}
makeRTPheader(_datagram,
RTPinfo->payloadType,
RTPinfo->sequenceNumber,
RTPinfo->timeStamp,
makeRTPheader(_datagram,
RTPinfo->payloadType,
RTPinfo->sequenceNumber,
RTPinfo->timeStamp,
RTPinfo->SSRC,
RTPinfo->markerBit);
@ -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 (mode == stereoModeMono)
@ -639,7 +563,7 @@ int NETEQTEST_RTPpacket::splitStereo(NETEQTEST_RTPpacket& slaveRtp, enum stereoM
parseHeader();
// start by copying the main rtp packet
slaveRtp = *this;
*slaveRtp = *this;
if(_payloadLen == 0)
{
@ -701,7 +625,7 @@ void NETEQTEST_RTPpacket::makeRTPheader(unsigned char* rtp_data, WebRtc_UWord8 p
rtp_data[4]=(unsigned char)((timestamp>>24)&0xFF);
rtp_data[5]=(unsigned char)((timestamp>>16)&0xFF);
rtp_data[6]=(unsigned char)((timestamp>>8)&0xFF);
rtp_data[6]=(unsigned char)((timestamp>>8)&0xFF);
rtp_data[7]=(unsigned char)(timestamp & 0xFF);
rtp_data[8]=(unsigned char)((ssrc>>24)&0xFF);
@ -711,65 +635,114 @@ void NETEQTEST_RTPpacket::makeRTPheader(unsigned char* rtp_data, WebRtc_UWord8 p
rtp_data[11]=(unsigned char)(ssrc & 0xFF);
}
WebRtc_UWord16 NETEQTEST_RTPpacket::parseRTPheader(const WebRtc_UWord8 *datagram, int datagramLen, WebRtcNetEQ_RTPInfo *RTPinfo, WebRtc_UWord8 **payloadPtr) const
WebRtc_UWord16
NETEQTEST_RTPpacket::parseRTPheader(WebRtcNetEQ_RTPInfo *RTPinfo,
WebRtc_UWord8 **payloadPtr) const
{
WebRtc_Word16 *rtp_data = (WebRtc_Word16 *) datagram;
int i_P, i_X, i_CC, i_extlength=-1, i_padlength=0, i_startPosition;
WebRtc_Word16 *rtp_data = (WebRtc_Word16 *) _datagram;
int i_P, i_X, i_CC;
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 */
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 */
assert(_datagramLen >= 12);
parseBasicHeader(RTPinfo, &i_P, &i_X, &i_CC);
if (i_X==1) {
/* 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);
}
}
int i_startPosition = calcHeaderLength(i_X, i_CC);
i_startPosition=12+4*(i_extlength+1)+4*i_CC;
int i_padlength = calcPadLength(i_P);
if (payloadPtr) {
*payloadPtr = (WebRtc_UWord8*) &rtp_data[i_startPosition>>1];
if (payloadPtr)
{
*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
|| _payloadLen <= 0 || slaveRtp._memSize < _memSize)
WebRtc_Word16 *rtp_data = (WebRtc_Word16 *) _datagram;
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;
}
WebRtc_UWord8 *readDataPtr = _payloadPtr;
WebRtc_UWord8 *writeDataPtr = _payloadPtr;
WebRtc_UWord8 *slaveData = slaveRtp._payloadPtr;
WebRtc_UWord8 *slaveData = slaveRtp->_payloadPtr;
while (readDataPtr - _payloadPtr < _payloadLen)
{
@ -789,23 +762,22 @@ void NETEQTEST_RTPpacket::splitStereoSample(NETEQTEST_RTPpacket& slaveRtp, int s
}
_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
|| _payloadLen <= 0 || slaveRtp._memSize < _memSize)
if(!_payloadPtr || !slaveRtp || !slaveRtp->_payloadPtr
|| _payloadLen <= 0 || slaveRtp->_memSize < _memSize)
{
return;
}
memmove(slaveRtp._payloadPtr, _payloadPtr + _payloadLen/2, _payloadLen/2);
memmove(slaveRtp->_payloadPtr, _payloadPtr + _payloadLen/2, _payloadLen/2);
_payloadLen /= 2;
slaveRtp._payloadLen = _payloadLen;
slaveRtp->_payloadLen = _payloadLen;
}
// 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
* that can be found in the LICENSE file in the root of the source
@ -27,15 +27,13 @@ class NETEQTEST_RTPpacket
{
public:
NETEQTEST_RTPpacket();
NETEQTEST_RTPpacket(const NETEQTEST_RTPpacket& copyFromMe);
NETEQTEST_RTPpacket & operator = (const NETEQTEST_RTPpacket & other);
bool operator !() const { return (dataLen() < 0); };
~NETEQTEST_RTPpacket();
virtual ~NETEQTEST_RTPpacket();
void reset();
static int skipFileHeader(FILE *fp);
int readFromFile(FILE *fp);
virtual int readFromFile(FILE *fp);
int readFixedFromFile(FILE *fp, size_t len);
int writeToFile(FILE *fp);
virtual int writeToFile(FILE *fp);
void blockPT(WebRtc_UWord8 pt);
//WebRtc_Word16 payloadType();
void parseHeader();
@ -43,7 +41,7 @@ public:
WebRtcNetEQ_RTPInfo const * RTPinfo() const;
WebRtc_UWord8 * datagram() const;
WebRtc_UWord8 * payload() const;
WebRtc_Word16 payloadLen() const;
WebRtc_Word16 payloadLen();
WebRtc_Word16 dataLen() const;
bool isParsed() const;
bool isLost() const;
@ -64,7 +62,7 @@ public:
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);
@ -81,11 +79,25 @@ public:
bool _lost;
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:
void makeRTPheader(unsigned char* rtp_data, WebRtc_UWord8 payloadType, WebRtc_UWord16 seqNo, WebRtc_UWord32 timestamp, WebRtc_UWord32 ssrc, WebRtc_UWord8 markerBit) const;
WebRtc_UWord16 parseRTPheader(const WebRtc_UWord8 *datagram, int datagramLen, WebRtcNetEQ_RTPInfo *RTPinfo, WebRtc_UWord8 **payloadPtr = NULL) const;
void splitStereoSample(NETEQTEST_RTPpacket& slaveRtp, int stride);
void splitStereoFrame(NETEQTEST_RTPpacket& slaveRtp);
void makeRTPheader(unsigned char* rtp_data, WebRtc_UWord8 payloadType,
WebRtc_UWord16 seqNo, WebRtc_UWord32 timestamp,
WebRtc_UWord32 ssrc, WebRtc_UWord8 markerBit) const;
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

File diff suppressed because it is too large Load Diff

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
* that can be found in the LICENSE file in the root of the source
@ -13,6 +13,9 @@
#include <vector>
#include "modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.h"
#include "modules/audio_coding/neteq/test/NETEQTEST_DummyRTPpacket.h"
//#define WEBRTC_DUMMY_RTP
enum {
kRedPayloadType = 127
@ -38,7 +41,11 @@ int main(int argc, char* argv[]) {
// Read file header.
NETEQTEST_RTPpacket::skipFileHeader(in_file);
#ifdef WEBRTC_DUMMY_RTP
NETEQTEST_DummyRTPpacket packet;
#else
NETEQTEST_RTPpacket packet;
#endif
while (packet.readFromFile(in_file) >= 0) {
// 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
* that can be found in the LICENSE file in the root of the source
@ -13,10 +13,11 @@
#include <algorithm>
#include <vector>
#include "gtest/gtest.h"
#include "modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.h"
#include "modules/audio_coding/neteq/test/NETEQTEST_DummyRTPPacket.h"
#define FIRSTLINELEN 40
//#define WEBRTC_DUMMY_RTP
static bool pktCmp(NETEQTEST_RTPpacket *a, NETEQTEST_RTPpacket *b) {
return (a->time() < b->time());
@ -91,7 +92,11 @@ int main(int argc, char* argv[]) {
while (1) {
// Insert in vector.
#ifdef WEBRTC_DUMMY_RTP
NETEQTEST_RTPpacket *new_packet = new NETEQTEST_DummyRTPpacket();
#else
NETEQTEST_RTPpacket *new_packet = new NETEQTEST_RTPpacket();
#endif
if (new_packet->readFromFile(in_file) < 0) {
// End of file.
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;
}