Files
webrtc/src/modules/audio_coding/NetEQ/main/test/NETEQTEST_NetEQClass.cc
henrik.lundin@webrtc.org 35dcc23110 Adding regression test to NetEQ
The test inputs RTP packets from an RTPdump file into NetEQ
and compares the output to the corresponding reference file.
Test files are included.

The change also includes a new method in NETEQTEST_RTPpacket
class, which reads past the initial file header in an RTPdump
file.

Finally, a few warnings are removed.
Review URL: http://webrtc-codereview.appspot.com/138012

git-svn-id: http://webrtc.googlecode.com/svn/trunk@568 4adac7df-926f-26a2-2b94-8c16560cd09d
2011-09-09 08:01:16 +00:00

371 lines
7.3 KiB
C++

/*
* Copyright (c) 2011 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 <memory.h>
#include "NETEQTEST_NetEQClass.h"
NETEQTEST_NetEQClass::NETEQTEST_NetEQClass()
:
_inst(NULL),
_instMem(NULL),
_bufferMem(NULL),
_preparseRTP(false),
_fsmult(1),
_isMaster(true)
{
#ifdef WINDOWS_TIMING
_totTimeRecIn.QuadPart = 0;
_totTimeRecOut.QuadPart = 0;
#endif
}
NETEQTEST_NetEQClass::NETEQTEST_NetEQClass(enum WebRtcNetEQDecoder *usedCodec, int noOfCodecs,
WebRtc_UWord16 fs, WebRtcNetEQNetworkType nwType)
:
_inst(NULL),
_instMem(NULL),
_bufferMem(NULL),
_preparseRTP(false),
_fsmult(1),
_isMaster(true)
{
#ifdef WINDOWS_TIMING
_totTimeRecIn.QuadPart = 0;
_totTimeRecOut.QuadPart = 0;
#endif
if (assign() == 0)
{
if (init(fs) == 0)
{
assignBuffer(usedCodec, noOfCodecs, nwType);
}
}
}
NETEQTEST_NetEQClass::~NETEQTEST_NetEQClass()
{
if (_instMem)
{
delete [] _instMem;
_instMem = NULL;
}
if (_bufferMem)
{
delete [] _bufferMem;
_bufferMem = NULL;
}
_inst = NULL;
}
int NETEQTEST_NetEQClass::assign()
{
int memSize;
WebRtcNetEQ_AssignSize(&memSize);
if (_instMem)
{
delete [] _instMem;
_instMem = NULL;
}
_instMem = new WebRtc_Word8[memSize];
int ret = WebRtcNetEQ_Assign(&_inst, _instMem);
if (ret)
{
printError();
}
return (ret);
}
int NETEQTEST_NetEQClass::init(WebRtc_UWord16 fs)
{
int ret;
if (!_inst)
{
// not assigned
ret = assign();
if (ret != 0)
{
printError();
return (ret);
}
}
ret = WebRtcNetEQ_Init(_inst, fs);
if (ret != 0)
{
printError();
}
return (ret);
}
int NETEQTEST_NetEQClass::assignBuffer(enum WebRtcNetEQDecoder *usedCodec, int noOfCodecs, WebRtcNetEQNetworkType nwType)
{
int numPackets, memSize, ret;
if (!_inst)
{
// not assigned
ret = assign();
if (ret != 0)
{
printError();
return (ret);
}
ret = init();
if (ret != 0)
{
printError();
return (ret);
}
}
ret = WebRtcNetEQ_GetRecommendedBufferSize(_inst, usedCodec, noOfCodecs, nwType, &numPackets, &memSize);
if (ret != 0)
{
printError();
return (ret);
}
if (_bufferMem)
{
delete [] _bufferMem;
_bufferMem = NULL;
}
_bufferMem = new WebRtc_Word8[memSize];
memset(_bufferMem, -1, memSize);
ret = WebRtcNetEQ_AssignBuffer(_inst, numPackets, _bufferMem, memSize);
if (ret != 0)
{
printError();
}
return (ret);
}
int NETEQTEST_NetEQClass::loadCodec(WebRtcNetEQ_CodecDef &codecInst)
{
int err = WebRtcNetEQ_CodecDbAdd(_inst, &codecInst);
if (err)
{
printError();
}
return (err);
}
void NETEQTEST_NetEQClass::printError()
{
if (_inst)
{
int errorCode = WebRtcNetEQ_GetErrorCode(_inst);
if (errorCode)
{
char errorName[WEBRTC_NETEQ_MAX_ERROR_NAME];
WebRtcNetEQ_GetErrorName(errorCode, errorName, WEBRTC_NETEQ_MAX_ERROR_NAME);
printf("Error %i: %s\n", errorCode, errorName);
}
}
}
void NETEQTEST_NetEQClass::printError(NETEQTEST_RTPpacket &rtp)
{
// print regular error info
printError();
// print extra info from packet
printf("\tRTP: TS=%u, SN=%u, PT=%u, M=%i, len=%i\n",
rtp.timeStamp(), rtp.sequenceNumber(), rtp.payloadType(),
rtp.markerBit(), rtp.payloadLen());
}
int NETEQTEST_NetEQClass::recIn(NETEQTEST_RTPpacket &rtp)
{
int err;
#ifdef WINDOWS_TIMING
LARGE_INTEGER countA, countB;
#endif
if (_preparseRTP)
{
WebRtcNetEQ_RTPInfo rtpInfo;
// parse RTP header
rtp.parseHeader(rtpInfo);
#ifdef WINDOWS_TIMING
QueryPerformanceCounter(&countA); // get start count for processor
#endif
err = WebRtcNetEQ_RecInRTPStruct(_inst, &rtpInfo, rtp.payload(), rtp.payloadLen(), rtp.time() * _fsmult * 8);
#ifdef WINDOWS_TIMING
QueryPerformanceCounter(&countB); // get stop count for processor
_totTimeRecIn.QuadPart += (countB.QuadPart - countA.QuadPart);
#endif
}
else
{
#ifdef WINDOWS_TIMING
QueryPerformanceCounter(&countA); // get start count for processor
#endif
err = WebRtcNetEQ_RecIn(_inst, (WebRtc_Word16 *) rtp.datagram(), rtp.dataLen(), rtp.time() * _fsmult * 8);
#ifdef WINDOWS_TIMING
QueryPerformanceCounter(&countB); // get stop count for processor
_totTimeRecIn.QuadPart += (countB.QuadPart - countA.QuadPart);
#endif
}
if (err)
{
printError(rtp);
}
return (err);
}
WebRtc_Word16 NETEQTEST_NetEQClass::recOut(WebRtc_Word16 *outData, void *msInfo, enum WebRtcNetEQOutputType *outputType)
{
int err;
WebRtc_Word16 outLen = 0;
#ifdef WINDOWS_TIMING
LARGE_INTEGER countA, countB;
#endif
#ifdef WINDOWS_TIMING
QueryPerformanceCounter(&countA); // get start count for processor
#endif
if (!msInfo)
{
// no msInfo given, do mono mode
err = WebRtcNetEQ_RecOut(_inst, outData, &outLen);
}
else
{
// master/slave mode
err = WebRtcNetEQ_RecOutMasterSlave(_inst, outData, &outLen, msInfo, static_cast<WebRtc_Word16>(_isMaster));
}
#ifdef WINDOWS_TIMING
QueryPerformanceCounter(&countB); // get stop count for processor
_totTimeRecOut.QuadPart += (countB.QuadPart - countA.QuadPart);
#endif
if (err)
{
printError();
}
else
{
int newfsmult = static_cast<int>(outLen / 80);
if (newfsmult != _fsmult)
{
printf("Warning: output sample rate changed\n");
_fsmult = newfsmult;
}
}
if (outputType != NULL)
{
err = WebRtcNetEQ_GetSpeechOutputType(_inst, outputType);
if (err)
{
printError();
}
}
return (outLen);
}
WebRtc_UWord32 NETEQTEST_NetEQClass::getSpeechTimeStamp()
{
WebRtc_UWord32 ts = 0;
int err;
err = WebRtcNetEQ_GetSpeechTimeStamp(_inst, &ts);
if (err)
{
printError();
ts = 0;
}
return (ts);
}
//NETEQTEST_NetEQVector::NETEQTEST_NetEQVector(int numChannels)
//:
//channels(numChannels, new NETEQTEST_NetEQClass())
//{
// //for (int i = 0; i < numChannels; i++)
// //{
// // channels.push_back(new NETEQTEST_NetEQClass());
// //}
//}
//
//NETEQTEST_NetEQVector::NETEQTEST_NetEQVector(int numChannels, enum WebRtcNetEQDecoder *usedCodec, int noOfCodecs,
// WebRtc_UWord16 fs, WebRtcNetEQNetworkType nwType)
// :
//channels(numChannels, new NETEQTEST_NetEQClass(usedCodec, noOfCodecs, fs, nwType))
//{
// //for (int i = 0; i < numChannels; i++)
// //{
// // channels.push_back(new NETEQTEST_NetEQClass(usedCodec, noOfCodecs, fs, nwType));
// //}
//}
//
//NETEQTEST_NetEQVector::~NETEQTEST_NetEQVector()
//{
//}