SDRDaemon: channel sink thread: data block handling with FEC encoding

This commit is contained in:
f4exb 2018-08-20 18:32:46 +02:00
parent 6c08494fd2
commit 75b505d012
4 changed files with 72 additions and 5 deletions

View File

@ -48,12 +48,14 @@ include_directories(
${CMAKE_SOURCE_DIR}/sdrbase
${CMAKE_SOURCE_DIR}/logging
${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}
)
target_link_libraries(sdrdaemon
${QT_LIBRARIES}
${CM256CC_LIBRARIES}
sdrbase
logging
)

View File

@ -25,10 +25,13 @@
#include "channel/sdrdaemondatablock.h"
#include "channel/sdrdaemonchannelsinkthread.h"
SDRDaemonChannelSinkThread::SDRDaemonChannelSinkThread(SDRDaemonDataQueue *dataQueue, QObject* parent) :
#include "cm256.h"
SDRDaemonChannelSinkThread::SDRDaemonChannelSinkThread(SDRDaemonDataQueue *dataQueue, CM256 *cm256, QObject* parent) :
QThread(parent),
m_running(false),
m_dataQueue(dataQueue)
m_dataQueue(dataQueue),
m_cm256(cm256)
{
connect(m_dataQueue, SIGNAL(dataBlockEnqueued()), this, SLOT(handleData()));
}
@ -72,6 +75,65 @@ void SDRDaemonChannelSinkThread::run()
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;
}

View File

@ -26,12 +26,13 @@
class SDRDaemonDataQueue;
class SDRDaemonDataBlock;
class CM256;
class SDRDaemonChannelSinkThread : public QThread {
Q_OBJECT
public:
SDRDaemonChannelSinkThread(SDRDaemonDataQueue *dataQueue, QObject* parent = 0);
SDRDaemonChannelSinkThread(SDRDaemonDataQueue *dataQueue, CM256 *cm256, QObject* parent = 0);
~SDRDaemonChannelSinkThread();
void startWork();
@ -44,6 +45,8 @@ private:
SDRDaemonDataQueue *m_dataQueue;
CM256 *m_cm256; //!< CM256 library object
void run();
bool handleDataBlock(SDRDaemonDataBlock& dataBlock);

View File

@ -96,7 +96,7 @@ class SDRDaemonDataBlock
{
public:
SDRDaemonTxControlBlock m_controlBlock;
SDRDaemonSuperBlock m_superBlock;
SDRDaemonSuperBlock m_superBlocks[256];
};
#endif /* SDRDAEMON_CHANNEL_SDRDAEMONDATABLOCK_H_ */