mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-10-02 09:46:38 -04:00
SDRDaemon: channel sink thread: data block handling with FEC encoding
This commit is contained in:
parent
6c08494fd2
commit
75b505d012
@ -48,12 +48,14 @@ include_directories(
|
|||||||
${CMAKE_SOURCE_DIR}/sdrbase
|
${CMAKE_SOURCE_DIR}/sdrbase
|
||||||
${CMAKE_SOURCE_DIR}/logging
|
${CMAKE_SOURCE_DIR}/logging
|
||||||
${CMAKE_SOURCE_DIR}/httpserver
|
${CMAKE_SOURCE_DIR}/httpserver
|
||||||
${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client
|
${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client
|
||||||
|
${CM256CC_INCLUDE_DIR}
|
||||||
${CMAKE_CURRENT_BINARY_DIR}
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(sdrdaemon
|
target_link_libraries(sdrdaemon
|
||||||
${QT_LIBRARIES}
|
${QT_LIBRARIES}
|
||||||
|
${CM256CC_LIBRARIES}
|
||||||
sdrbase
|
sdrbase
|
||||||
logging
|
logging
|
||||||
)
|
)
|
||||||
|
@ -25,10 +25,13 @@
|
|||||||
#include "channel/sdrdaemondatablock.h"
|
#include "channel/sdrdaemondatablock.h"
|
||||||
#include "channel/sdrdaemonchannelsinkthread.h"
|
#include "channel/sdrdaemonchannelsinkthread.h"
|
||||||
|
|
||||||
SDRDaemonChannelSinkThread::SDRDaemonChannelSinkThread(SDRDaemonDataQueue *dataQueue, QObject* parent) :
|
#include "cm256.h"
|
||||||
|
|
||||||
|
SDRDaemonChannelSinkThread::SDRDaemonChannelSinkThread(SDRDaemonDataQueue *dataQueue, CM256 *cm256, QObject* parent) :
|
||||||
QThread(parent),
|
QThread(parent),
|
||||||
m_running(false),
|
m_running(false),
|
||||||
m_dataQueue(dataQueue)
|
m_dataQueue(dataQueue),
|
||||||
|
m_cm256(cm256)
|
||||||
{
|
{
|
||||||
connect(m_dataQueue, SIGNAL(dataBlockEnqueued()), this, SLOT(handleData()));
|
connect(m_dataQueue, SIGNAL(dataBlockEnqueued()), this, SLOT(handleData()));
|
||||||
}
|
}
|
||||||
@ -72,6 +75,65 @@ void SDRDaemonChannelSinkThread::run()
|
|||||||
|
|
||||||
bool SDRDaemonChannelSinkThread::handleDataBlock(SDRDaemonDataBlock& dataBlock)
|
bool SDRDaemonChannelSinkThread::handleDataBlock(SDRDaemonDataBlock& dataBlock)
|
||||||
{
|
{
|
||||||
|
CM256::cm256_encoder_params cm256Params; //!< Main interface with CM256 encoder
|
||||||
|
CM256::cm256_block descriptorBlocks[256]; //!< Pointers to data for CM256 encoder
|
||||||
|
SDRDaemonProtectedBlock fecBlocks[256]; //!< FEC data
|
||||||
|
|
||||||
|
uint16_t frameIndex = dataBlock.m_controlBlock.m_frameIndex;
|
||||||
|
int nbBlocksFEC = dataBlock.m_controlBlock.m_nbBlocksFEC;
|
||||||
|
int txDelay = dataBlock.m_controlBlock.m_txDelay;
|
||||||
|
SDRDaemonSuperBlock *txBlockx = dataBlock.m_superBlocks;
|
||||||
|
|
||||||
|
if ((nbBlocksFEC == 0) || !m_cm256) // Do not FEC encode
|
||||||
|
{
|
||||||
|
for (int i = 0; i < SDRDaemonNbOrginalBlocks; i++)
|
||||||
|
{
|
||||||
|
// TODO: send block via UDP here
|
||||||
|
usleep(txDelay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cm256Params.BlockBytes = sizeof(SDRDaemonProtectedBlock);
|
||||||
|
cm256Params.OriginalCount = SDRDaemonNbOrginalBlocks;
|
||||||
|
cm256Params.RecoveryCount = nbBlocksFEC;
|
||||||
|
|
||||||
|
// Fill pointers to data
|
||||||
|
for (int i = 0; i < cm256Params.OriginalCount + cm256Params.RecoveryCount; ++i)
|
||||||
|
{
|
||||||
|
if (i >= cm256Params.OriginalCount) {
|
||||||
|
memset((void *) &txBlockx[i].m_protectedBlock, 0, sizeof(SDRDaemonProtectedBlock));
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlockx[i].m_header.m_frameIndex = frameIndex;
|
||||||
|
txBlockx[i].m_header.m_blockIndex = i;
|
||||||
|
descriptorBlocks[i].Block = (void *) &(txBlockx[i].m_protectedBlock);
|
||||||
|
descriptorBlocks[i].Index = txBlockx[i].m_header.m_blockIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode FEC blocks
|
||||||
|
if (m_cm256->cm256_encode(cm256Params, descriptorBlocks, fecBlocks))
|
||||||
|
{
|
||||||
|
qWarning("SDRDaemonChannelSinkThread::handleDataBlock: CM256 encode failed. No transmission.");
|
||||||
|
// TODO: send without FEC changing meta data to set indication of no FEC
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge FEC with data to transmit
|
||||||
|
for (int i = 0; i < cm256Params.RecoveryCount; i++)
|
||||||
|
{
|
||||||
|
txBlockx[i + cm256Params.OriginalCount].m_protectedBlock = fecBlocks[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transmit all blocks
|
||||||
|
for (int i = 0; i < cm256Params.OriginalCount + cm256Params.RecoveryCount; i++)
|
||||||
|
{
|
||||||
|
// TODO: send block via UDP here
|
||||||
|
usleep(txDelay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dataBlock.m_controlBlock.m_processed = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,12 +26,13 @@
|
|||||||
|
|
||||||
class SDRDaemonDataQueue;
|
class SDRDaemonDataQueue;
|
||||||
class SDRDaemonDataBlock;
|
class SDRDaemonDataBlock;
|
||||||
|
class CM256;
|
||||||
|
|
||||||
class SDRDaemonChannelSinkThread : public QThread {
|
class SDRDaemonChannelSinkThread : public QThread {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SDRDaemonChannelSinkThread(SDRDaemonDataQueue *dataQueue, QObject* parent = 0);
|
SDRDaemonChannelSinkThread(SDRDaemonDataQueue *dataQueue, CM256 *cm256, QObject* parent = 0);
|
||||||
~SDRDaemonChannelSinkThread();
|
~SDRDaemonChannelSinkThread();
|
||||||
|
|
||||||
void startWork();
|
void startWork();
|
||||||
@ -44,6 +45,8 @@ private:
|
|||||||
|
|
||||||
SDRDaemonDataQueue *m_dataQueue;
|
SDRDaemonDataQueue *m_dataQueue;
|
||||||
|
|
||||||
|
CM256 *m_cm256; //!< CM256 library object
|
||||||
|
|
||||||
void run();
|
void run();
|
||||||
bool handleDataBlock(SDRDaemonDataBlock& dataBlock);
|
bool handleDataBlock(SDRDaemonDataBlock& dataBlock);
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ class SDRDaemonDataBlock
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SDRDaemonTxControlBlock m_controlBlock;
|
SDRDaemonTxControlBlock m_controlBlock;
|
||||||
SDRDaemonSuperBlock m_superBlock;
|
SDRDaemonSuperBlock m_superBlocks[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* SDRDAEMON_CHANNEL_SDRDAEMONDATABLOCK_H_ */
|
#endif /* SDRDAEMON_CHANNEL_SDRDAEMONDATABLOCK_H_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user