213 lines
5.6 KiB
C++
213 lines
5.6 KiB
C++
/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com)
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef __MT_AUDIO_RECEIVER_H
|
|
#define __MT_AUDIO_RECEIVER_H
|
|
|
|
#include "MT_Stream.h"
|
|
#include "MT_CodecList.h"
|
|
#include "MT_AudioCodec.h"
|
|
#include "MT_CngHelper.h"
|
|
#include "../helper/HL_Pointer.h"
|
|
#include "../helper/HL_Sync.h"
|
|
#include "../helper/HL_Optional.hpp"
|
|
|
|
#include "jrtplib/src/rtppacket.h"
|
|
#include "jrtplib/src/rtcppacket.h"
|
|
#include "jrtplib/src/rtpsourcedata.h"
|
|
#include "../audio/Audio_DataWindow.h"
|
|
#include "../audio/Audio_Resampler.h"
|
|
|
|
#if defined(USE_PVQA_LIBRARY)
|
|
# include "pvqa++.h"
|
|
#endif
|
|
|
|
#include <map>
|
|
|
|
// #define DUMP_DECODED
|
|
|
|
namespace MT
|
|
{
|
|
using jrtplib::RTPPacket;
|
|
class RtpBuffer
|
|
{
|
|
public:
|
|
enum class FetchResult
|
|
{
|
|
RegularPacket,
|
|
Gap,
|
|
NoPacket
|
|
};
|
|
|
|
// Owns rtp packet data
|
|
class Packet
|
|
{
|
|
public:
|
|
Packet(const std::shared_ptr<RTPPacket>& packet, int timelen, int rate);
|
|
std::shared_ptr<RTPPacket> rtp() const;
|
|
int timelength() const;
|
|
int rate() const;
|
|
|
|
protected:
|
|
std::shared_ptr<RTPPacket> mRtp;
|
|
int mTimelength = 0, mRate = 0;
|
|
};
|
|
|
|
RtpBuffer(Statistics& stat);
|
|
~RtpBuffer();
|
|
|
|
unsigned ssrc();
|
|
void setSsrc(unsigned ssrc);
|
|
|
|
void setHigh(int milliseconds);
|
|
int high();
|
|
|
|
void setLow(int milliseconds);
|
|
int low();
|
|
|
|
void setPrebuffer(int milliseconds);
|
|
int prebuffer();
|
|
|
|
int getNumberOfReturnedPackets() const;
|
|
int getNumberOfAddPackets() const;
|
|
|
|
int findTimelength();
|
|
int getCount() const;
|
|
|
|
// Returns false if packet was not add - maybe too old or too new or duplicate
|
|
bool add(std::shared_ptr<RTPPacket> packet, int timelength, int rate);
|
|
|
|
typedef std::vector<std::shared_ptr<RTPPacket>> ResultList;
|
|
typedef std::shared_ptr<ResultList> PResultList;
|
|
|
|
FetchResult fetch(ResultList& rl);
|
|
|
|
protected:
|
|
unsigned mSsrc;
|
|
int mHigh, mLow, mPrebuffer;
|
|
int mReturnedCounter, mAddCounter;
|
|
mutable Mutex mGuard;
|
|
typedef std::vector<Packet> PacketList;
|
|
PacketList mPacketList;
|
|
Statistics& mStat;
|
|
bool mFirstPacketWillGo;
|
|
jrtplib::RTPSourceStats mRtpStats;
|
|
Packet mFetchedPacket;
|
|
|
|
// To calculate average interval between packet add. It is close to jitter but more useful in debugging.
|
|
float mLastAddTime = 0.0;
|
|
};
|
|
|
|
class Receiver
|
|
{
|
|
public:
|
|
Receiver(Statistics& stat);
|
|
virtual ~Receiver();
|
|
|
|
protected:
|
|
Statistics& mStat;
|
|
};
|
|
|
|
class AudioReceiver: public Receiver
|
|
{
|
|
public:
|
|
AudioReceiver(const CodecList::Settings& codecSettings, Statistics& stat);
|
|
~AudioReceiver();
|
|
|
|
// Returns false when packet is rejected as illegal. codec parameter will show codec which will be used for decoding.
|
|
// Lifetime of pointer to codec is limited by lifetime of AudioReceiver (it is container).
|
|
bool add(const std::shared_ptr<jrtplib::RTPPacket>& p, Codec** codec = nullptr);
|
|
|
|
// Returns false when there is no rtp data from jitter
|
|
enum DecodeOptions
|
|
{
|
|
DecodeOptions_ResampleToMainRate = 0,
|
|
DecodeOptions_DontResample = 1,
|
|
DecodeOptions_FillCngGap = 2,
|
|
DecodeOptions_SkipDecode = 4
|
|
};
|
|
|
|
bool getAudio(Audio::DataWindow& output, int options = DecodeOptions_ResampleToMainRate, int* rate = nullptr);
|
|
|
|
// Looks for codec by payload type
|
|
Codec* findCodec(int payloadType);
|
|
RtpBuffer& getRtpBuffer() { return mBuffer; }
|
|
|
|
// Returns size of AudioReceiver's instance in bytes (including size of all data + codecs + etc.)
|
|
int getSize() const;
|
|
|
|
// Returns timelength for given packet
|
|
int timelengthFor(jrtplib::RTPPacket& p);
|
|
|
|
// Return samplerate for given packet
|
|
int samplerateFor(jrtplib::RTPPacket& p);
|
|
|
|
protected:
|
|
RtpBuffer mBuffer;
|
|
CodecMap mCodecMap;
|
|
PCodec mCodec;
|
|
int mFrameCount = 0;
|
|
CodecList::Settings mCodecSettings;
|
|
CodecList mCodecList;
|
|
JitterStatistics mJitterStats;
|
|
std::shared_ptr<jrtplib::RTPPacket> mCngPacket;
|
|
CngDecoder mCngDecoder;
|
|
|
|
// Buffer to hold decoded data
|
|
char mDecodedFrame[65536];
|
|
int mDecodedLength = 0;
|
|
|
|
// Buffer to hold data converted to stereo/mono
|
|
char mConvertedFrame[32768];
|
|
int mConvertedLength = 0;
|
|
|
|
// Buffer to hold data resampled to AUDIO_SAMPLERATE
|
|
char mResampledFrame[65536];
|
|
int mResampledLength = 0;
|
|
|
|
// Last packet time length
|
|
int mLastPacketTimeLength = 0;
|
|
|
|
int mFailedCount;
|
|
Audio::Resampler mResampler8, mResampler16,
|
|
mResampler32, mResampler48;
|
|
|
|
Audio::PWavFileWriter mDecodedDump;
|
|
|
|
float mLastDecodeTime = 0.0; // Time last call happened to codec->decode()
|
|
|
|
float mIntervalSum = 0.0;
|
|
int mIntervalCount = 0;
|
|
|
|
// Zero rate will make audio mono but resampling will be skipped
|
|
void makeMonoAndResample(int rate, int channels);
|
|
|
|
// Resamples, sends to analysis, writes to dump and queues to output decoded frames from mDecodedFrame
|
|
void processDecoded(Audio::DataWindow& output, int options);
|
|
|
|
#if defined(USE_PVQA_LIBRARY) && defined(PVQA_IN_RECEIVER)
|
|
std::shared_ptr<sevana::pvqa> mPVQA;
|
|
void initPvqa();
|
|
void updatePvqa(const void* data, int size);
|
|
float calculatePvqaMos(int rate, std::string& report);
|
|
|
|
std::shared_ptr<Audio::DataWindow> mPvqaBuffer;
|
|
#endif
|
|
|
|
void processStatisticsWithAmrCodec(Codec* c);
|
|
};
|
|
|
|
class DtmfReceiver: public Receiver
|
|
{
|
|
public:
|
|
DtmfReceiver(Statistics& stat);
|
|
~DtmfReceiver();
|
|
|
|
void add(std::shared_ptr<RTPPacket> p);
|
|
};
|
|
}
|
|
|
|
#endif
|