mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-26 01:39:05 -05:00
qrtplib: copy Audio to UDP/RTP: use a single UDP socket for UDP and RTP
This commit is contained in:
parent
f310eb4dad
commit
5b0f62c3e2
@ -48,6 +48,7 @@ RTPUDPTransmitter::RTPUDPTransmitter() :
|
|||||||
m_init = false;
|
m_init = false;
|
||||||
m_rtcpsock = 0;
|
m_rtcpsock = 0;
|
||||||
m_rtpsock = 0;
|
m_rtpsock = 0;
|
||||||
|
m_deletesocketswhendone = false;
|
||||||
m_waitingfordata = false;
|
m_waitingfordata = false;
|
||||||
m_rtcpPort = 0;
|
m_rtcpPort = 0;
|
||||||
m_rtpPort = 0;
|
m_rtpPort = 0;
|
||||||
@ -122,6 +123,14 @@ int RTPUDPTransmitter::Create(std::size_t maximumpacketsize, const RTPTransmissi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (params->GetUseExistingSockets(&m_rtpsock, &m_rtcpsock))
|
||||||
|
{
|
||||||
|
m_deletesocketswhendone = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_deletesocketswhendone = true;
|
||||||
|
|
||||||
m_rtpsock = new QUdpSocket();
|
m_rtpsock = new QUdpSocket();
|
||||||
|
|
||||||
// If we're multiplexing, we're just going to set the RTCP socket to equal the RTP socket
|
// If we're multiplexing, we're just going to set the RTCP socket to equal the RTP socket
|
||||||
@ -132,6 +141,7 @@ int RTPUDPTransmitter::Create(std::size_t maximumpacketsize, const RTPTransmissi
|
|||||||
} else {
|
} else {
|
||||||
m_rtcpsock = new QUdpSocket();
|
m_rtcpsock = new QUdpSocket();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// set socket buffer sizes
|
// set socket buffer sizes
|
||||||
|
|
||||||
@ -174,17 +184,6 @@ int RTPUDPTransmitter::BindSockets()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RTPUDPTransmitter::moveToThread(QThread *thread)
|
|
||||||
{
|
|
||||||
if (m_rtpsock) {
|
|
||||||
m_rtpsock->moveToThread(thread);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_rtpsock != m_rtcpsock) {
|
|
||||||
m_rtcpsock->moveToThread(thread);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RTPUDPTransmitter::Destroy()
|
void RTPUDPTransmitter::Destroy()
|
||||||
{
|
{
|
||||||
if (!m_init) {
|
if (!m_init) {
|
||||||
@ -196,11 +195,14 @@ void RTPUDPTransmitter::Destroy()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_deletesocketswhendone)
|
||||||
|
{
|
||||||
if (m_rtpsock != m_rtcpsock) {
|
if (m_rtpsock != m_rtcpsock) {
|
||||||
delete m_rtcpsock;
|
delete m_rtcpsock;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete m_rtpsock;
|
delete m_rtpsock;
|
||||||
|
}
|
||||||
|
|
||||||
m_created = false;
|
m_created = false;
|
||||||
}
|
}
|
||||||
|
@ -142,6 +142,16 @@ public:
|
|||||||
m_forcedrtcpport = rtcpport;
|
m_forcedrtcpport = rtcpport;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Use sockets that have already been created, no checks on port numbers
|
||||||
|
* will be done, and no buffer sizes will be set; you'll need to close
|
||||||
|
* the sockets yourself when done, it will **not** be done automatically. */
|
||||||
|
void SetUseExistingSockets(QUdpSocket *rtpsocket, QUdpSocket *rtcpsocket)
|
||||||
|
{
|
||||||
|
m_rtpsock = rtpsocket;
|
||||||
|
m_rtcpsock = rtcpsocket;
|
||||||
|
m_useexistingsockets = true;
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns the RTP socket's send buffer size. */
|
/** Returns the RTP socket's send buffer size. */
|
||||||
int GetRTPSendBufferSize() const
|
int GetRTPSendBufferSize() const
|
||||||
{
|
{
|
||||||
@ -184,6 +194,20 @@ public:
|
|||||||
return m_forcedrtcpport;
|
return m_forcedrtcpport;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns true and fills in sockets if existing sockets were set
|
||||||
|
* using RTPUDPv4TransmissionParams::SetUseExistingSockets. */
|
||||||
|
bool GetUseExistingSockets(QUdpSocket **rtpsocket, QUdpSocket **rtcpsocket) const
|
||||||
|
{
|
||||||
|
if (!m_useexistingsockets) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*rtpsocket = m_rtpsock;
|
||||||
|
*rtcpsocket = m_rtcpsock;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QHostAddress m_bindAddress;
|
QHostAddress m_bindAddress;
|
||||||
QNetworkInterface m_mcastInterface;
|
QNetworkInterface m_mcastInterface;
|
||||||
@ -195,6 +219,7 @@ private:
|
|||||||
uint16_t m_forcedrtcpport;
|
uint16_t m_forcedrtcpport;
|
||||||
|
|
||||||
QUdpSocket *m_rtpsock, *m_rtcpsock;
|
QUdpSocket *m_rtpsock, *m_rtcpsock;
|
||||||
|
bool m_useexistingsockets;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline RTPUDPTransmissionParams::RTPUDPTransmissionParams() :
|
inline RTPUDPTransmissionParams::RTPUDPTransmissionParams() :
|
||||||
@ -210,6 +235,7 @@ inline RTPUDPTransmissionParams::RTPUDPTransmissionParams() :
|
|||||||
m_forcedrtcpport = 0;
|
m_forcedrtcpport = 0;
|
||||||
m_rtpsock = 0;
|
m_rtpsock = 0;
|
||||||
m_rtcpsock = 0;
|
m_rtcpsock = 0;
|
||||||
|
m_useexistingsockets = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Additional information about the UDP over IPv4 transmitter. */
|
/** Additional information about the UDP over IPv4 transmitter. */
|
||||||
@ -321,6 +347,7 @@ private:
|
|||||||
bool m_created;
|
bool m_created;
|
||||||
bool m_waitingfordata;
|
bool m_waitingfordata;
|
||||||
QUdpSocket *m_rtpsock, *m_rtcpsock;
|
QUdpSocket *m_rtpsock, *m_rtcpsock;
|
||||||
|
bool m_deletesocketswhendone;
|
||||||
QHostAddress m_localIP; //!< from parameters bind IP
|
QHostAddress m_localIP; //!< from parameters bind IP
|
||||||
QNetworkInterface m_multicastInterface; //!< from parameters multicast interface
|
QNetworkInterface m_multicastInterface; //!< from parameters multicast interface
|
||||||
uint16_t m_rtpPort, m_rtcpPort;
|
uint16_t m_rtpPort, m_rtcpPort;
|
||||||
|
@ -16,34 +16,36 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "audionetsink.h"
|
#include "audionetsink.h"
|
||||||
#include "util/udpsink.h"
|
|
||||||
#include "util/rtpsink.h"
|
#include "util/rtpsink.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <QUdpSocket>
|
||||||
|
|
||||||
const int AudioNetSink::m_udpBlockSize = 512;
|
const int AudioNetSink::m_udpBlockSize = 512;
|
||||||
|
|
||||||
AudioNetSink::AudioNetSink(QObject *parent, bool stereo) :
|
AudioNetSink::AudioNetSink(QObject *parent, bool stereo) :
|
||||||
m_type(SinkUDP),
|
m_type(SinkUDP),
|
||||||
m_udpBufferAudioMono(0),
|
m_rtpBufferAudio(0),
|
||||||
m_rtpBufferAudio(0)
|
m_bufferIndex(0),
|
||||||
|
m_port(9998)
|
||||||
{
|
{
|
||||||
m_udpBufferAudioMono = new UDPSink<int16_t>(parent, m_udpBlockSize);
|
m_udpSocket = new QUdpSocket(parent);
|
||||||
//m_rtpBufferAudio = new RTPSink("127.0.0.1", 9999, stereo ? RTPSink::PayloadL16Stereo : RTPSink::PayloadL16Mono);
|
m_rtpBufferAudio = new RTPSink(m_udpSocket, stereo);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioNetSink::~AudioNetSink()
|
AudioNetSink::~AudioNetSink()
|
||||||
{
|
{
|
||||||
if (m_udpBufferAudioMono) {
|
|
||||||
delete m_udpBufferAudioMono;
|
|
||||||
}
|
|
||||||
if (m_rtpBufferAudio) {
|
if (m_rtpBufferAudio) {
|
||||||
delete m_rtpBufferAudio;
|
delete m_rtpBufferAudio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_udpSocket->deleteLater(); // this thread is not the owner thread (was moved)
|
||||||
}
|
}
|
||||||
|
|
||||||
//bool AudioNetSink::isRTPCapable() const
|
bool AudioNetSink::isRTPCapable() const
|
||||||
//{
|
{
|
||||||
// return m_rtpBufferAudio->isValid();
|
return m_rtpBufferAudio->isValid();
|
||||||
//}
|
}
|
||||||
|
|
||||||
bool AudioNetSink::selectType(SinkType type)
|
bool AudioNetSink::selectType(SinkType type)
|
||||||
{
|
{
|
||||||
@ -65,9 +67,9 @@ bool AudioNetSink::selectType(SinkType type)
|
|||||||
|
|
||||||
void AudioNetSink::setDestination(const QString& address, uint16_t port)
|
void AudioNetSink::setDestination(const QString& address, uint16_t port)
|
||||||
{
|
{
|
||||||
if (m_udpBufferAudioMono) {
|
m_address.setAddress(const_cast<QString&>(address));
|
||||||
m_udpBufferAudioMono->setDestination(address, port);
|
m_port = port;
|
||||||
}
|
|
||||||
if (m_rtpBufferAudio) {
|
if (m_rtpBufferAudio) {
|
||||||
m_rtpBufferAudio->setDestination(address, port);
|
m_rtpBufferAudio->setDestination(address, port);
|
||||||
}
|
}
|
||||||
@ -89,21 +91,28 @@ void AudioNetSink::deleteDestination(const QString& address, uint16_t port)
|
|||||||
|
|
||||||
void AudioNetSink::write(qint16 sample)
|
void AudioNetSink::write(qint16 sample)
|
||||||
{
|
{
|
||||||
if (m_type == SinkUDP) {
|
if (m_type == SinkUDP)
|
||||||
m_udpBufferAudioMono->write(sample);
|
{
|
||||||
} else if (m_type == SinkRTP) {
|
if (m_bufferIndex >= m_udpBlockSize)
|
||||||
|
{
|
||||||
|
m_udpSocket->writeDatagram((const char*)m_data, (qint64 ) m_udpBlockSize, m_address, m_port);
|
||||||
|
m_bufferIndex = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qint16 *p = (qint16*) &m_data[m_bufferIndex];
|
||||||
|
*p = sample;
|
||||||
|
m_bufferIndex += sizeof(qint16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_type == SinkRTP)
|
||||||
|
{
|
||||||
m_rtpBufferAudio->write((uint8_t *) &sample);
|
m_rtpBufferAudio->write((uint8_t *) &sample);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioNetSink::moveToThread(QThread *thread)
|
void AudioNetSink::moveToThread(QThread *thread)
|
||||||
{
|
{
|
||||||
if (m_udpBufferAudioMono) {
|
m_udpSocket->moveToThread(thread);
|
||||||
m_udpBufferAudioMono->moveToThread(thread);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_rtpBufferAudio) {
|
|
||||||
m_rtpBufferAudio->moveToThread(thread);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,10 +21,11 @@
|
|||||||
#include "dsp/dsptypes.h"
|
#include "dsp/dsptypes.h"
|
||||||
#include "util/export.h"
|
#include "util/export.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QHostAddress>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
template<typename T> class UDPSink;
|
class QUdpSocket;
|
||||||
class RTPSink;
|
class RTPSink;
|
||||||
class QThread;
|
class QThread;
|
||||||
|
|
||||||
@ -45,7 +46,7 @@ public:
|
|||||||
|
|
||||||
void write(qint16 sample);
|
void write(qint16 sample);
|
||||||
|
|
||||||
bool isRTPCapable() const { return false; }
|
bool isRTPCapable() const;
|
||||||
bool selectType(SinkType type);
|
bool selectType(SinkType type);
|
||||||
|
|
||||||
void moveToThread(QThread *thread);
|
void moveToThread(QThread *thread);
|
||||||
@ -54,8 +55,12 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
SinkType m_type;
|
SinkType m_type;
|
||||||
UDPSink<qint16> *m_udpBufferAudioMono;
|
QUdpSocket *m_udpSocket;
|
||||||
RTPSink *m_rtpBufferAudio;
|
RTPSink *m_rtpBufferAudio;
|
||||||
|
char m_data[65536];
|
||||||
|
unsigned int m_bufferIndex;
|
||||||
|
QHostAddress m_address;
|
||||||
|
unsigned int m_port;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,19 +19,20 @@
|
|||||||
#include "dsp/dsptypes.h"
|
#include "dsp/dsptypes.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
RTPSink::RTPSink(const QString& address, uint16_t port, PayloadType payloadType) :
|
RTPSink::RTPSink(QUdpSocket *udpSocket, bool stereo) :
|
||||||
m_payloadType(payloadType),
|
m_payloadType(stereo ? RTPSink::PayloadL16Stereo : RTPSink::PayloadL16Mono),
|
||||||
m_sampleRate(48000),
|
m_sampleRate(48000),
|
||||||
m_sampleBytes(0),
|
m_sampleBytes(0),
|
||||||
m_packetSamples(0),
|
m_packetSamples(0),
|
||||||
m_bufferSize(0),
|
m_bufferSize(0),
|
||||||
m_sampleBufferIndex(0),
|
m_sampleBufferIndex(0),
|
||||||
m_byteBuffer(0),
|
m_byteBuffer(0),
|
||||||
m_destport(port),
|
m_destport(9998),
|
||||||
m_mutex(QMutex::Recursive)
|
m_mutex(QMutex::Recursive)
|
||||||
{
|
{
|
||||||
m_rtpSessionParams.SetOwnTimestampUnit(1.0 / (double) m_sampleRate);
|
m_rtpSessionParams.SetOwnTimestampUnit(1.0 / (double) m_sampleRate);
|
||||||
m_rtpTransmissionParams.SetRTCPMultiplexing(true); // do not allocate another socket for RTCP
|
m_rtpTransmissionParams.SetRTCPMultiplexing(true); // do not allocate another socket for RTCP
|
||||||
|
m_rtpTransmissionParams.SetUseExistingSockets(udpSocket, udpSocket);
|
||||||
|
|
||||||
int status = m_rtpTransmitter.Init();
|
int status = m_rtpTransmitter.Init();
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
@ -52,14 +53,12 @@ RTPSink::RTPSink(const QString& address, uint16_t port, PayloadType payloadType)
|
|||||||
qDebug("RTPSink::RTPSink: created session: %s", qrtplib::RTPGetErrorString(status).c_str());
|
qDebug("RTPSink::RTPSink: created session: %s", qrtplib::RTPGetErrorString(status).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
setPayloadType(payloadType);
|
setPayloadType(m_payloadType);
|
||||||
m_valid = true;
|
m_valid = true;
|
||||||
|
|
||||||
uint32_t endianTest32 = 1;
|
uint32_t endianTest32 = 1;
|
||||||
uint8_t *ptr = (uint8_t*) &endianTest32;
|
uint8_t *ptr = (uint8_t*) &endianTest32;
|
||||||
m_endianReverse = (*ptr == 1);
|
m_endianReverse = (*ptr == 1);
|
||||||
|
|
||||||
m_destip.setAddress(address);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RTPSink::~RTPSink()
|
RTPSink::~RTPSink()
|
||||||
|
@ -33,6 +33,8 @@
|
|||||||
|
|
||||||
#include "util/export.h"
|
#include "util/export.h"
|
||||||
|
|
||||||
|
class QUdpSocket;
|
||||||
|
|
||||||
class RTPSink
|
class RTPSink
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -42,7 +44,7 @@ public:
|
|||||||
PayloadL16Stereo,
|
PayloadL16Stereo,
|
||||||
} PayloadType;
|
} PayloadType;
|
||||||
|
|
||||||
RTPSink(const QString& address, uint16_t port, PayloadType payloadType = PayloadL16Mono);
|
RTPSink(QUdpSocket *udpSocket, bool stereo);
|
||||||
~RTPSink();
|
~RTPSink();
|
||||||
|
|
||||||
bool isValid() const { return m_valid; }
|
bool isValid() const { return m_valid; }
|
||||||
@ -55,10 +57,6 @@ public:
|
|||||||
void write(const uint8_t *sampleByte);
|
void write(const uint8_t *sampleByte);
|
||||||
void write(const uint8_t *sampleByte, int nbSamples);
|
void write(const uint8_t *sampleByte, int nbSamples);
|
||||||
|
|
||||||
void moveToThread(QThread *thread) {
|
|
||||||
m_rtpTransmitter.moveToThread(thread);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Reverse endianess in destination buffer */
|
/** Reverse endianess in destination buffer */
|
||||||
static void writeNetBuf(uint8_t *dest, const uint8_t *src, unsigned int elemLen, unsigned int bytesLen, bool endianReverse);
|
static void writeNetBuf(uint8_t *dest, const uint8_t *src, unsigned int elemLen, unsigned int bytesLen, bool endianReverse);
|
||||||
|
Loading…
Reference in New Issue
Block a user