- changes to library
This commit is contained in:
parent
c34bcdc058
commit
c303b6f09d
|
|
@ -56,7 +56,8 @@ SpeexResampler::~SpeexResampler()
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t SpeexResampler::processBuffer(const void* src, size_t sourceLength, size_t& sourceProcessed, void* dest, size_t destCapacity)
|
size_t SpeexResampler::processBuffer(const void* src, size_t sourceLength, size_t& sourceProcessed,
|
||||||
|
void* dest, size_t destCapacity)
|
||||||
{
|
{
|
||||||
assert(mSourceRate != 0 && mDestRate != 0);
|
assert(mSourceRate != 0 && mDestRate != 0);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,14 +24,15 @@ namespace Audio
|
||||||
|
|
||||||
void start(int channels, int sourceRate, int destRate);
|
void start(int channels, int sourceRate, int destRate);
|
||||||
void stop();
|
void stop();
|
||||||
int processBuffer(const void* source, int sourceLength, int& sourceProcessed, void* dest, int destCapacity);
|
size_t processBuffer(const void* source, size_t sourceLength, size_t& sourceProcessed,
|
||||||
|
void* dest, size_t destCapacity);
|
||||||
int sourceRate();
|
int sourceRate();
|
||||||
int destRate();
|
int destRate();
|
||||||
int getDestLength(int sourceLen);
|
size_t getDestLength(size_t sourceLen);
|
||||||
int getSourceLength(int destLen);
|
size_t getSourceLength(size_t destLen);
|
||||||
|
|
||||||
// Returns instance + speex encoder size in bytes
|
// Returns instance + speex encoder size in bytes
|
||||||
int getSize() const;
|
size_t getSize() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void* mContext;
|
void* mContext;
|
||||||
|
|
@ -59,9 +60,10 @@ namespace Audio
|
||||||
UniversalResampler();
|
UniversalResampler();
|
||||||
~UniversalResampler();
|
~UniversalResampler();
|
||||||
|
|
||||||
int resample(int sourceRate, const void* sourceBuffer, int sourceLength, int& sourceProcessed, int destRate, void* destBuffer, int destCapacity);
|
size_t resample(int sourceRate, const void* sourceBuffer, size_t sourceLength, size_t& sourceProcessed,
|
||||||
int getDestLength(int sourceRate, int destRate, int sourceLength);
|
int destRate, void* destBuffer, size_t destCapacity);
|
||||||
int getSourceLength(int sourceRate, int destRate, int destLength);
|
size_t getDestLength(int sourceRate, int destRate, size_t sourceLength);
|
||||||
|
size_t getSourceLength(int sourceRate, int destRate, size_t destLength);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef std::pair<int, int> RatePair;
|
typedef std::pair<int, int> RatePair;
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,9 @@ public:
|
||||||
struct PacketData
|
struct PacketData
|
||||||
{
|
{
|
||||||
const uint8_t* mData;
|
const uint8_t* mData;
|
||||||
int mLength;
|
size_t mLength;
|
||||||
|
|
||||||
PacketData(const uint8_t* data, int length)
|
PacketData(const uint8_t* data, size_t length)
|
||||||
:mData(data), mLength(length)
|
:mData(data), mLength(length)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,208 +17,208 @@
|
||||||
|
|
||||||
struct RtpHeader
|
struct RtpHeader
|
||||||
{
|
{
|
||||||
unsigned char cc:4; /* CSRC count */
|
unsigned char cc:4; /* CSRC count */
|
||||||
unsigned char x:1; /* header extension flag */
|
unsigned char x:1; /* header extension flag */
|
||||||
unsigned char p:1; /* padding flag */
|
unsigned char p:1; /* padding flag */
|
||||||
unsigned char version:2; /* protocol version */
|
unsigned char version:2; /* protocol version */
|
||||||
unsigned char pt:7; /* payload type */
|
unsigned char pt:7; /* payload type */
|
||||||
unsigned char m:1; /* marker bit */
|
unsigned char m:1; /* marker bit */
|
||||||
unsigned short seq; /* sequence number */
|
unsigned short seq; /* sequence number */
|
||||||
unsigned int ts; /* timestamp */
|
unsigned int ts; /* timestamp */
|
||||||
unsigned int ssrc; /* synchronization source */
|
unsigned int ssrc; /* synchronization source */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RtcpHeader
|
struct RtcpHeader
|
||||||
{
|
{
|
||||||
unsigned char rc:5; /* reception report count */
|
unsigned char rc:5; /* reception report count */
|
||||||
unsigned char p:1; /* padding flag */
|
unsigned char p:1; /* padding flag */
|
||||||
unsigned char version:2; /* protocol version */
|
unsigned char version:2; /* protocol version */
|
||||||
unsigned char pt:8; /* payload type */
|
unsigned char pt:8; /* payload type */
|
||||||
uint16_t len; /* length */
|
uint16_t len; /* length */
|
||||||
uint32_t ssrc; /* synchronization source */
|
uint32_t ssrc; /* synchronization source */
|
||||||
};
|
};
|
||||||
|
|
||||||
bool RtpHelper::isRtp(const void* buffer, int length)
|
bool RtpHelper::isRtp(const void* buffer, size_t length)
|
||||||
{
|
{
|
||||||
if (length < 12)
|
if (length < 12)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned char _type = reinterpret_cast<const RtpHeader*>(buffer)->pt;
|
unsigned char _type = reinterpret_cast<const RtpHeader*>(buffer)->pt;
|
||||||
bool rtp = ( (_type & 0x7F) >= 96 && (_type & 0x7F) < 127) || ((_type & 0x7F) < 35);
|
bool rtp = ( (_type & 0x7F) >= 96 && (_type & 0x7F) < 127) || ((_type & 0x7F) < 35);
|
||||||
return rtp;
|
return rtp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool RtpHelper::isRtpOrRtcp(const void* buffer, int length)
|
bool RtpHelper::isRtpOrRtcp(const void* buffer, size_t length)
|
||||||
{
|
{
|
||||||
if (length < 12)
|
if (length < 12)
|
||||||
return false;
|
return false;
|
||||||
unsigned char b = ((const unsigned char*)buffer)[0];
|
unsigned char b = ((const unsigned char*)buffer)[0];
|
||||||
|
|
||||||
return (b & 0xC0 ) == 128;
|
return (b & 0xC0 ) == 128;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RtpHelper::isRtcp(const void* buffer, int length)
|
bool RtpHelper::isRtcp(const void* buffer, size_t length)
|
||||||
{
|
{
|
||||||
return (isRtpOrRtcp(buffer, length) && !isRtp(buffer, length));
|
return (isRtpOrRtcp(buffer, length) && !isRtp(buffer, length));
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned RtpHelper::findSsrc(const void* buffer, int length)
|
unsigned RtpHelper::findSsrc(const void* buffer, size_t length)
|
||||||
{
|
{
|
||||||
if (isRtp(buffer, length))
|
if (isRtp(buffer, length))
|
||||||
return reinterpret_cast<const RtpHeader*>(buffer)->ssrc;
|
return reinterpret_cast<const RtpHeader*>(buffer)->ssrc;
|
||||||
else
|
else
|
||||||
return reinterpret_cast<const RtcpHeader*>(buffer)->ssrc;
|
return reinterpret_cast<const RtcpHeader*>(buffer)->ssrc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RtpHelper::findPtype(const void* buffer, int length)
|
int RtpHelper::findPtype(const void* buffer, size_t length)
|
||||||
{
|
{
|
||||||
if (isRtp(buffer, length))
|
if (isRtp(buffer, length))
|
||||||
return reinterpret_cast<const RtpHeader*>(buffer)->pt;
|
return reinterpret_cast<const RtpHeader*>(buffer)->pt;
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RtpHelper::findPayloadLength(const void* buffer, int length)
|
int RtpHelper::findPayloadLength(const void* buffer, size_t length)
|
||||||
{
|
{
|
||||||
if (isRtp(buffer, length))
|
if (isRtp(buffer, length))
|
||||||
{
|
{
|
||||||
return length - 12;
|
return length - 12;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtpDump::RtpDump(const char *filename)
|
RtpDump::RtpDump(const char *filename)
|
||||||
:mFilename(filename)
|
:mFilename(filename)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
RtpDump::~RtpDump()
|
RtpDump::~RtpDump()
|
||||||
{
|
{
|
||||||
flush();
|
flush();
|
||||||
for (PacketList::iterator packetIter=mPacketList.begin(); packetIter!=mPacketList.end(); ++packetIter)
|
for (PacketList::iterator packetIter=mPacketList.begin(); packetIter!=mPacketList.end(); ++packetIter)
|
||||||
{
|
{
|
||||||
//free(packetIter->mData);
|
//free(packetIter->mData);
|
||||||
delete packetIter->mPacket;
|
delete packetIter->mPacket;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtpDump::load()
|
void RtpDump::load()
|
||||||
{
|
{
|
||||||
FILE* f = fopen(mFilename.c_str(), "rb");
|
FILE* f = fopen(mFilename.c_str(), "rb");
|
||||||
if (!f)
|
if (!f)
|
||||||
throw Exception(ERR_WAVFILE_FAILED);
|
throw Exception(ERR_WAVFILE_FAILED);
|
||||||
|
|
||||||
while (!feof(f))
|
while (!feof(f))
|
||||||
{
|
{
|
||||||
|
RtpData data;
|
||||||
|
fread(&data.mLength, sizeof data.mLength, 1, f);
|
||||||
|
data.mData = new char[data.mLength];
|
||||||
|
fread(data.mData, 1, data.mLength, f);
|
||||||
|
jrtplib::RTPIPv4Address addr(jrtplib::RTPAddress::IPv4Address);
|
||||||
|
jrtplib::RTPTime t(0);
|
||||||
|
jrtplib::RTPRawPacket* raw = new jrtplib::RTPRawPacket((unsigned char*)data.mData, data.mLength, &addr, t, true);
|
||||||
|
data.mPacket = new jrtplib::RTPPacket(*raw);
|
||||||
|
mPacketList.push_back(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t RtpDump::count() const
|
||||||
|
{
|
||||||
|
return mPacketList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
jrtplib::RTPPacket& RtpDump::packetAt(size_t index)
|
||||||
|
{
|
||||||
|
return *mPacketList[index].mPacket;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtpDump::add(const void* buffer, size_t len)
|
||||||
|
{
|
||||||
RtpData data;
|
RtpData data;
|
||||||
fread(&data.mLength, sizeof data.mLength, 1, f);
|
data.mData = malloc(len);
|
||||||
data.mData = new char[data.mLength];
|
memcpy(data.mData, buffer, len);
|
||||||
fread(data.mData, 1, data.mLength, f);
|
data.mLength = len;
|
||||||
|
|
||||||
jrtplib::RTPIPv4Address addr(jrtplib::RTPAddress::IPv4Address);
|
jrtplib::RTPIPv4Address addr(jrtplib::RTPAddress::IPv4Address);
|
||||||
jrtplib::RTPTime t(0);
|
jrtplib::RTPTime t(0);
|
||||||
jrtplib::RTPRawPacket* raw = new jrtplib::RTPRawPacket((unsigned char*)data.mData, data.mLength, &addr, t, true);
|
jrtplib::RTPRawPacket* raw = new jrtplib::RTPRawPacket((unsigned char*)const_cast<void*>(data.mData), data.mLength, &addr, t, true);
|
||||||
data.mPacket = new jrtplib::RTPPacket(*raw);
|
data.mPacket = new jrtplib::RTPPacket(*raw);
|
||||||
|
//delete raw;
|
||||||
mPacketList.push_back(data);
|
mPacketList.push_back(data);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int RtpDump::count() const
|
|
||||||
{
|
|
||||||
return mPacketList.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
jrtplib::RTPPacket& RtpDump::packetAt(int index)
|
|
||||||
{
|
|
||||||
return *mPacketList[index].mPacket;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RtpDump::add(const void* buffer, int len)
|
|
||||||
{
|
|
||||||
RtpData data;
|
|
||||||
data.mData = malloc(len);
|
|
||||||
memcpy(data.mData, buffer, len);
|
|
||||||
data.mLength = len;
|
|
||||||
|
|
||||||
jrtplib::RTPIPv4Address addr(jrtplib::RTPAddress::IPv4Address);
|
|
||||||
jrtplib::RTPTime t(0);
|
|
||||||
jrtplib::RTPRawPacket* raw = new jrtplib::RTPRawPacket((unsigned char*)const_cast<void*>(data.mData), data.mLength, &addr, t, true);
|
|
||||||
data.mPacket = new jrtplib::RTPPacket(*raw);
|
|
||||||
//delete raw;
|
|
||||||
mPacketList.push_back(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtpDump::flush()
|
void RtpDump::flush()
|
||||||
{
|
{
|
||||||
FILE* f = fopen(mFilename.c_str(), "wb");
|
FILE* f = fopen(mFilename.c_str(), "wb");
|
||||||
if (!f)
|
if (!f)
|
||||||
throw Exception(ERR_WAVFILE_FAILED);
|
throw Exception(ERR_WAVFILE_FAILED);
|
||||||
|
|
||||||
PacketList::iterator packetIter = mPacketList.begin();
|
PacketList::iterator packetIter = mPacketList.begin();
|
||||||
for (;packetIter != mPacketList.end(); ++packetIter)
|
for (;packetIter != mPacketList.end(); ++packetIter)
|
||||||
{
|
{
|
||||||
RtpData& data = *packetIter;
|
RtpData& data = *packetIter;
|
||||||
// Disabled for debugging only
|
// Disabled for debugging only
|
||||||
//fwrite(&data.mLength, sizeof data.mLength, 1, f);
|
//fwrite(&data.mLength, sizeof data.mLength, 1, f);
|
||||||
fwrite(data.mData, data.mLength, 1, f);
|
fwrite(data.mData, data.mLength, 1, f);
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------- MediaStreamId --------------------
|
// -------------- MediaStreamId --------------------
|
||||||
bool MediaStreamId::operator < (const MediaStreamId& right) const
|
bool MediaStreamId::operator < (const MediaStreamId& right) const
|
||||||
{
|
{
|
||||||
if (mSsrcIsId)
|
if (mSsrcIsId)
|
||||||
return std::tie(mSSRC, mSource, mDestination) < std::tie(right.mSSRC, right.mSource, right.mDestination);
|
return std::tie(mSSRC, mSource, mDestination) < std::tie(right.mSSRC, right.mSource, right.mDestination);
|
||||||
else
|
else
|
||||||
return std::tie(mSource, mDestination) < std::tie(right.mSource, right.mDestination);
|
return std::tie(mSource, mDestination) < std::tie(right.mSource, right.mDestination);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MediaStreamId::operator == (const MediaStreamId& right) const
|
bool MediaStreamId::operator == (const MediaStreamId& right) const
|
||||||
{
|
{
|
||||||
if (mSsrcIsId)
|
if (mSsrcIsId)
|
||||||
return std::tie(mSSRC, mSource, mDestination) == std::tie(right.mSSRC, right.mSource, right.mDestination);
|
return std::tie(mSSRC, mSource, mDestination) == std::tie(right.mSSRC, right.mSource, right.mDestination);
|
||||||
else
|
else
|
||||||
return std::tie(mSource, mDestination) == std::tie(right.mSource, right.mDestination);
|
return std::tie(mSource, mDestination) == std::tie(right.mSource, right.mDestination);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string MediaStreamId::toString() const
|
std::string MediaStreamId::toString() const
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "src: " << mSource.toStdString() <<
|
oss << "src: " << mSource.toStdString() <<
|
||||||
" dst: " << mDestination.toStdString() <<
|
" dst: " << mDestination.toStdString() <<
|
||||||
" ssrc: " << StringHelper::toHex(mSSRC);
|
" ssrc: " << StringHelper::toHex(mSSRC);
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void writeToJson(const MediaStreamId& id, std::ostringstream& oss)
|
void writeToJson(const MediaStreamId& id, std::ostringstream& oss)
|
||||||
{
|
{
|
||||||
oss << " \"src\": \"" << id.mSource.toStdString() << "\"," << std::endl
|
oss << " \"src\": \"" << id.mSource.toStdString() << "\"," << std::endl
|
||||||
<< " \"dst\": \"" << id.mDestination.toStdString() << "\"," << std::endl
|
<< " \"dst\": \"" << id.mDestination.toStdString() << "\"," << std::endl
|
||||||
<< " \"ssrc\": \"" << StringHelper::toHex(id.mSSRC) << "\"," << std::endl
|
<< " \"ssrc\": \"" << StringHelper::toHex(id.mSSRC) << "\"," << std::endl
|
||||||
<< " \"link_id\": \"" << id.mLinkId.toString() << "\"" << std::endl;
|
<< " \"link_id\": \"" << id.mLinkId.toString() << "\"" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string MediaStreamId::getDetectDescription() const
|
std::string MediaStreamId::getDetectDescription() const
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "{\"event\": \"stream_detected\"," << std::endl;
|
oss << "{\"event\": \"stream_detected\"," << std::endl;
|
||||||
writeToJson(*this, oss);
|
writeToJson(*this, oss);
|
||||||
oss << "}";
|
oss << "}";
|
||||||
|
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string MediaStreamId::getFinishDescription() const
|
std::string MediaStreamId::getFinishDescription() const
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "{" << std::endl
|
oss << "{" << std::endl
|
||||||
<< " \"event\": \"stream_finished\", " << std::endl;
|
<< " \"event\": \"stream_finished\", " << std::endl;
|
||||||
writeToJson(*this, oss);
|
writeToJson(*this, oss);
|
||||||
oss << "}";
|
oss << "}";
|
||||||
|
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,12 +33,12 @@ struct RtpPair
|
||||||
class RtpHelper
|
class RtpHelper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static bool isRtp(const void* buffer, int length);
|
static bool isRtp(const void* buffer, size_t length);
|
||||||
static int findPtype(const void* buffer, int length);
|
static int findPtype(const void* buffer, size_t length);
|
||||||
static bool isRtpOrRtcp(const void* buffer, int length);
|
static bool isRtpOrRtcp(const void* buffer, size_t length);
|
||||||
static bool isRtcp(const void* buffer, int length);
|
static bool isRtcp(const void* buffer, size_t length);
|
||||||
static unsigned findSsrc(const void* buffer, int length);
|
static unsigned findSsrc(const void* buffer, size_t length);
|
||||||
static int findPayloadLength(const void* buffer, int length);
|
static int findPayloadLength(const void* buffer, size_t length);
|
||||||
};
|
};
|
||||||
|
|
||||||
class RtpDump
|
class RtpDump
|
||||||
|
|
@ -48,7 +48,7 @@ protected:
|
||||||
{
|
{
|
||||||
jrtplib::RTPPacket* mPacket;
|
jrtplib::RTPPacket* mPacket;
|
||||||
void* mData;
|
void* mData;
|
||||||
unsigned mLength;
|
size_t mLength;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<RtpData> PacketList;
|
typedef std::vector<RtpData> PacketList;
|
||||||
|
|
@ -60,9 +60,9 @@ public:
|
||||||
~RtpDump();
|
~RtpDump();
|
||||||
|
|
||||||
void load();
|
void load();
|
||||||
int count() const;
|
size_t count() const;
|
||||||
jrtplib::RTPPacket& packetAt(int index);
|
jrtplib::RTPPacket& packetAt(size_t index);
|
||||||
void add(const void* data, int len);
|
void add(const void* data, size_t len);
|
||||||
void flush();
|
void flush();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -583,7 +583,7 @@ void AudioReceiver::makeMonoAndResample(int rate, int channels)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int processedInput = 0;
|
size_t processedInput = 0;
|
||||||
mResampledLength = r->processBuffer(frames, length, processedInput, mResampledFrame, r->getDestLength(length));
|
mResampledLength = r->processBuffer(frames, length, processedInput, mResampledFrame, r->getDestLength(length));
|
||||||
// processedInput result value is ignored - it is always equal to length as internal sample rate is 8/16/32/48K
|
// processedInput result value is ignored - it is always equal to length as internal sample rate is 8/16/32/48K
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,7 @@ void AudioStream::addData(const void* buffer, int bytes)
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int processedInput = 0;
|
size_t processedInput = 0;
|
||||||
dstlen = r->processBuffer(buffer, bytes, processedInput, mResampleBuffer, dstlen);
|
dstlen = r->processBuffer(buffer, bytes, processedInput, mResampleBuffer, dstlen);
|
||||||
// ProcessedInput output value is ignored - because sample rate of input is always 8/16/32/48K - so all buffer is processed
|
// ProcessedInput output value is ignored - because sample rate of input is always 8/16/32/48K - so all buffer is processed
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue