mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-23 00:18:37 -05:00
DATV: external LDPC tool implementation (5): dequeue outputs in run() method
This commit is contained in:
parent
8c45107c8c
commit
6e8b573b5f
@ -28,6 +28,7 @@ static const int DEFAULT_TRIALS = 50;
|
|||||||
#include "layered_decoder.h"
|
#include "layered_decoder.h"
|
||||||
static const int DEFAULT_TRIALS = 25;
|
static const int DEFAULT_TRIALS = 25;
|
||||||
#endif
|
#endif
|
||||||
|
static const int DEFAULT_BATCH_SIZE = 32;
|
||||||
|
|
||||||
//ldpctool::LDPCInterface *create_ldpc(char *standard, char prefix, int number);
|
//ldpctool::LDPCInterface *create_ldpc(char *standard, char prefix, int number);
|
||||||
|
|
||||||
@ -46,7 +47,7 @@ void fatal(const char *msg)
|
|||||||
|
|
||||||
void usage(const char *name, FILE *f, int c, const char *info = NULL)
|
void usage(const char *name, FILE *f, int c, const char *info = NULL)
|
||||||
{
|
{
|
||||||
fprintf(f, "Usage: %s [--standard DVB-S2] --modcod INT [--trials INT] [--shortframes] < FECFRAMES.int8 > FECFRAMES.int8\n", name);
|
fprintf(f, "Usage: %s [--standard DVB-S2] --modcod INT [--trials 25] [--batch-size 32] [--shortframes] < FECFRAMES.int8 > FECFRAMES.int8\n", name);
|
||||||
if (info)
|
if (info)
|
||||||
fprintf(f, "** Error while processing '%s'\n", info);
|
fprintf(f, "** Error while processing '%s'\n", info);
|
||||||
exit(c);
|
exit(c);
|
||||||
@ -57,6 +58,7 @@ int main(int argc, char **argv)
|
|||||||
const char *standard = "DVB-S2";
|
const char *standard = "DVB-S2";
|
||||||
int modcod = -1;
|
int modcod = -1;
|
||||||
int max_trials = DEFAULT_TRIALS;
|
int max_trials = DEFAULT_TRIALS;
|
||||||
|
int batch_size = DEFAULT_BATCH_SIZE;
|
||||||
bool shortframes = false;
|
bool shortframes = false;
|
||||||
|
|
||||||
for (int i = 1; i < argc; ++i)
|
for (int i = 1; i < argc; ++i)
|
||||||
@ -67,6 +69,8 @@ int main(int argc, char **argv)
|
|||||||
modcod = atoi(argv[++i]);
|
modcod = atoi(argv[++i]);
|
||||||
else if (!strcmp(argv[i], "--trials") && i + 1 < argc)
|
else if (!strcmp(argv[i], "--trials") && i + 1 < argc)
|
||||||
max_trials = atoi(argv[++i]);
|
max_trials = atoi(argv[++i]);
|
||||||
|
else if (!strcmp(argv[i], "--batch-size") && i + 1 < argc)
|
||||||
|
batch_size = atoi(argv[++i]);
|
||||||
else if (!strcmp(argv[i], "--shortframes"))
|
else if (!strcmp(argv[i], "--shortframes"))
|
||||||
shortframes = true;
|
shortframes = true;
|
||||||
else if (!strcmp(argv[i], "-h"))
|
else if (!strcmp(argv[i], "-h"))
|
||||||
@ -123,7 +127,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
decode.init(ldpc);
|
decode.init(ldpc);
|
||||||
|
|
||||||
int BLOCKS = 32;
|
int BLOCKS = batch_size;
|
||||||
ldpctool::code_type *code = new ldpctool::code_type[BLOCKS * CODE_LEN];
|
ldpctool::code_type *code = new ldpctool::code_type[BLOCKS * CODE_LEN];
|
||||||
void *aligned_buffer = aligned_alloc(sizeof(ldpctool::simd_type), sizeof(ldpctool::simd_type) * CODE_LEN);
|
void *aligned_buffer = aligned_alloc(sizeof(ldpctool::simd_type), sizeof(ldpctool::simd_type) * CODE_LEN);
|
||||||
ldpctool::simd_type *simd = reinterpret_cast<ldpctool::simd_type *>(aligned_buffer);
|
ldpctool::simd_type *simd = reinterpret_cast<ldpctool::simd_type *>(aligned_buffer);
|
||||||
@ -172,6 +176,7 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
iterations += blocks * trials;
|
iterations += blocks * trials;
|
||||||
std::cerr << "ldpc_tool: decoder failed at converging to a code word in " << trials << " trials" << std::endl;
|
std::cerr << "ldpc_tool: decoder failed at converging to a code word in " << trials << " trials" << std::endl;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -393,7 +393,7 @@ struct s2_frame_transmitter : runnable
|
|||||||
private:
|
private:
|
||||||
pipereader<plslot<hard_ss>> in;
|
pipereader<plslot<hard_ss>> in;
|
||||||
pipewriter<complex<T>> out;
|
pipewriter<complex<T>> out;
|
||||||
cstln_lut<hard_ss, 256> *cstln; // NULL initially
|
cstln_lut<hard_ss, 256> *cstln; // nullptr initially
|
||||||
complex<T> *csymbols; // Valid iff cstln is valid. RMS cstln_amp.
|
complex<T> *csymbols; // Valid iff cstln is valid. RMS cstln_amp.
|
||||||
void update_cstln(const modcod_info *mcinfo)
|
void update_cstln(const modcod_info *mcinfo)
|
||||||
{
|
{
|
||||||
@ -445,13 +445,13 @@ struct s2_frame_receiver : runnable
|
|||||||
sampler_interface<T> *_sampler,
|
sampler_interface<T> *_sampler,
|
||||||
pipebuf<complex<T>> &_in,
|
pipebuf<complex<T>> &_in,
|
||||||
pipebuf<plslot<SOFTSYMB>> &_out,
|
pipebuf<plslot<SOFTSYMB>> &_out,
|
||||||
pipebuf<float> *_freq_out = NULL,
|
pipebuf<float> *_freq_out = nullptr,
|
||||||
pipebuf<float> *_ss_out = NULL,
|
pipebuf<float> *_ss_out = nullptr,
|
||||||
pipebuf<float> *_mer_out = NULL,
|
pipebuf<float> *_mer_out = nullptr,
|
||||||
pipebuf<complex<float>> *_cstln_out = NULL,
|
pipebuf<complex<float>> *_cstln_out = nullptr,
|
||||||
pipebuf<complex<float>> *_cstln_pls_out = NULL,
|
pipebuf<complex<float>> *_cstln_pls_out = nullptr,
|
||||||
pipebuf<complex<float>> *_symbols_out = NULL,
|
pipebuf<complex<float>> *_symbols_out = nullptr,
|
||||||
pipebuf<int> *_state_out = NULL)
|
pipebuf<int> *_state_out = nullptr)
|
||||||
: runnable(sch, "S2 frame receiver"),
|
: runnable(sch, "S2 frame receiver"),
|
||||||
sampler(_sampler),
|
sampler(_sampler),
|
||||||
meas_decimation(1048576),
|
meas_decimation(1048576),
|
||||||
@ -459,7 +459,7 @@ struct s2_frame_receiver : runnable
|
|||||||
strongpls(false),
|
strongpls(false),
|
||||||
in_power(0), ev_power(0), agc_gain(1), agc_bw(1e-3),
|
in_power(0), ev_power(0), agc_gain(1), agc_bw(1e-3),
|
||||||
nsyncs(0),
|
nsyncs(0),
|
||||||
cstln(NULL),
|
cstln(nullptr),
|
||||||
in(_in), out(_out, 1 + modcod_info::MAX_SLOTS_PER_FRAME),
|
in(_in), out(_out, 1 + modcod_info::MAX_SLOTS_PER_FRAME),
|
||||||
meas_count(0),
|
meas_count(0),
|
||||||
freq_out(opt_writer(_freq_out)),
|
freq_out(opt_writer(_freq_out)),
|
||||||
@ -612,7 +612,7 @@ struct s2_frame_receiver : runnable
|
|||||||
if (cstln_out && cstln_out->writable() >= 1024)
|
if (cstln_out && cstln_out->writable() >= 1024)
|
||||||
psampled = cstln_out->wr();
|
psampled = cstln_out->wr();
|
||||||
else
|
else
|
||||||
psampled = NULL;
|
psampled = nullptr;
|
||||||
|
|
||||||
// Preserve float precision
|
// Preserve float precision
|
||||||
phase16 -= 65536 * floor(phase16 / 65536);
|
phase16 -= 65536 * floor(phase16 / 65536);
|
||||||
@ -714,15 +714,15 @@ struct s2_frame_receiver : runnable
|
|||||||
if (cstln_out && cstln_out->writable() >= 1024)
|
if (cstln_out && cstln_out->writable() >= 1024)
|
||||||
psampled = cstln_out->wr();
|
psampled = cstln_out->wr();
|
||||||
else
|
else
|
||||||
psampled = NULL;
|
psampled = nullptr;
|
||||||
complex<float> *psampled_pls;
|
complex<float> *psampled_pls;
|
||||||
if (cstln_pls_out && cstln_pls_out->writable() >= 1024)
|
if (cstln_pls_out && cstln_pls_out->writable() >= 1024)
|
||||||
psampled_pls = cstln_pls_out->wr();
|
psampled_pls = cstln_pls_out->wr();
|
||||||
else
|
else
|
||||||
psampled_pls = NULL;
|
psampled_pls = nullptr;
|
||||||
|
|
||||||
#if TEST_DIVERSITY
|
#if TEST_DIVERSITY
|
||||||
complex<float> *psymbols = symbols_out ? symbols_out->wr() : NULL;
|
complex<float> *psymbols = symbols_out ? symbols_out->wr() : nullptr;
|
||||||
float scale_symbols = 1.0 / cstln_amp;
|
float scale_symbols = 1.0 / cstln_amp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1941,7 +1941,7 @@ struct s2_ldpc_engines
|
|||||||
const fec_info *fi = &fec_infos[sf][fec];
|
const fec_info *fi = &fec_infos[sf][fec];
|
||||||
if (!fi->ldpc)
|
if (!fi->ldpc)
|
||||||
{
|
{
|
||||||
ldpcs[sf][fec] = NULL;
|
ldpcs[sf][fec] = nullptr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2095,8 +2095,8 @@ struct s2_fecdec : runnable
|
|||||||
int bitflips;
|
int bitflips;
|
||||||
s2_fecdec(scheduler *sch,
|
s2_fecdec(scheduler *sch,
|
||||||
pipebuf<fecframe<SOFTBYTE>> &_in, pipebuf<bbframe> &_out,
|
pipebuf<fecframe<SOFTBYTE>> &_in, pipebuf<bbframe> &_out,
|
||||||
pipebuf<int> *_bitcount = NULL,
|
pipebuf<int> *_bitcount = nullptr,
|
||||||
pipebuf<int> *_errcount = NULL)
|
pipebuf<int> *_errcount = nullptr)
|
||||||
: runnable(sch, "S2 fecdec"),
|
: runnable(sch, "S2 fecdec"),
|
||||||
bitflips(0),
|
bitflips(0),
|
||||||
in(_in), out(_out),
|
in(_in), out(_out),
|
||||||
@ -2309,7 +2309,7 @@ private:
|
|||||||
uint8_t bch_buf[64800 / 8]; // Temp storage for hardening before BCH
|
uint8_t bch_buf[64800 / 8]; // Temp storage for hardening before BCH
|
||||||
s2_bch_engines s2bch;
|
s2_bch_engines s2bch;
|
||||||
s2_bbscrambling bbscrambling;
|
s2_bbscrambling bbscrambling;
|
||||||
};
|
}; // s2_fecdec_soft
|
||||||
|
|
||||||
// External LDPC decoder
|
// External LDPC decoder
|
||||||
// Spawns a user-specified command, FEC frames on stdin/stdout.
|
// Spawns a user-specified command, FEC frames on stdin/stdout.
|
||||||
@ -2351,69 +2351,40 @@ struct s2_fecdec_helper : runnable
|
|||||||
pipebuf<fecframe<SOFTBYTE>> &_in,
|
pipebuf<fecframe<SOFTBYTE>> &_in,
|
||||||
pipebuf<bbframe> &_out,
|
pipebuf<bbframe> &_out,
|
||||||
const char *_command,
|
const char *_command,
|
||||||
pipebuf<int> *_bitcount = NULL,
|
pipebuf<int> *_bitcount = nullptr,
|
||||||
pipebuf<int> *_errcount = NULL)
|
pipebuf<int> *_errcount = nullptr)
|
||||||
: runnable(sch, "S2 fecdec io"),
|
: runnable(sch, "S2 fecdec io"),
|
||||||
batch_size(32),
|
batch_size(16),
|
||||||
nhelpers(1),
|
nhelpers(1),
|
||||||
must_buffer(false),
|
must_buffer(false),
|
||||||
in(_in), out(_out),
|
in(_in), out(_out),
|
||||||
command(_command),
|
command(_command),
|
||||||
writing_modulo(1),
|
|
||||||
zeros_count(0),
|
|
||||||
run_count(0),
|
|
||||||
bitcount(opt_writer(_bitcount, 1)),
|
bitcount(opt_writer(_bitcount, 1)),
|
||||||
errcount(opt_writer(_errcount, 1))
|
errcount(opt_writer(_errcount, 1))
|
||||||
{
|
{
|
||||||
for (int mc = 0; mc < 32; ++mc)
|
for (int mc = 0; mc < 32; ++mc)
|
||||||
for (int sf = 0; sf < 2; ++sf)
|
for (int sf = 0; sf < 2; ++sf)
|
||||||
pools[mc][sf].procs = NULL;
|
pools[mc][sf].procs = nullptr;
|
||||||
}
|
}
|
||||||
void run()
|
void run()
|
||||||
{
|
{
|
||||||
// Send work until all helpers block.
|
// Send work until all helpers block.
|
||||||
while (in.readable() >= 1 && !jobs.full())
|
while (in.readable() >= 1 && !jobs.full())
|
||||||
{
|
{
|
||||||
if (!send_frame(in.rd())) {
|
if (out.writable() >= 1)
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
in.read(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// while (
|
|
||||||
// !jobs.empty() &&
|
|
||||||
// jobs.peek()->h->b_out &&
|
|
||||||
// out.writable() >= 1 &&
|
|
||||||
// opt_writable(bitcount, 1) &&
|
|
||||||
// opt_writable(errcount, 1)
|
|
||||||
// )
|
|
||||||
while (
|
|
||||||
!jobs.empty() &&
|
|
||||||
jobs.peek()->h->b_out)
|
|
||||||
{
|
{
|
||||||
receive_frame(jobs.get());
|
if (bbframe_q.size() != 0)
|
||||||
}
|
|
||||||
|
|
||||||
if ((run_count % writing_modulo == 0) && (bbframe_q.size() != 0) && out.writable() >= 1)
|
|
||||||
{
|
{
|
||||||
if (zeros_count != 0)
|
|
||||||
{
|
|
||||||
writing_modulo = (bbframe_q.size() + zeros_count) / bbframe_q.size();
|
|
||||||
fprintf(stderr, "s2_fecdec_helper::run: bbframe queue size: %lu zeros: %d writing_modulo: %d\n",
|
|
||||||
bbframe_q.size(), zeros_count, writing_modulo);
|
|
||||||
}
|
|
||||||
|
|
||||||
bbframe *pout = out.wr();
|
bbframe *pout = out.wr();
|
||||||
pout->pls = bbframe_q.front().pls;
|
pout->pls = bbframe_q.front().pls;
|
||||||
std::copy(bbframe_q.front().bytes, bbframe_q.front().bytes + (58192 / 8), pout->bytes);
|
std::copy(bbframe_q.front().bytes, bbframe_q.front().bytes + (58192 / 8), pout->bytes);
|
||||||
bbframe_q.pop_front();
|
bbframe_q.pop_front();
|
||||||
out.written(1);
|
out.written(1);
|
||||||
zeros_count = 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
zeros_count++;
|
fprintf(stderr, "s2_fecdec_helper::run: WARNING: bbframe queue is empty\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((bitcount_q.size() != 0) && opt_writable(bitcount, 1))
|
if ((bitcount_q.size() != 0) && opt_writable(bitcount, 1))
|
||||||
@ -2428,7 +2399,19 @@ struct s2_fecdec_helper : runnable
|
|||||||
errcount_q.pop_front();
|
errcount_q.pop_front();
|
||||||
}
|
}
|
||||||
|
|
||||||
run_count++;
|
if (!send_frame(in.rd())) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
in.read(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (
|
||||||
|
!jobs.empty() &&
|
||||||
|
jobs.peek()->h->b_out)
|
||||||
|
{
|
||||||
|
receive_frame(jobs.get());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -2442,7 +2425,7 @@ struct s2_fecdec_helper : runnable
|
|||||||
};
|
};
|
||||||
struct pool
|
struct pool
|
||||||
{
|
{
|
||||||
helper_instance *procs; // NULL or [nprocs]
|
helper_instance *procs; // nullptr or [nprocs]
|
||||||
int nprocs;
|
int nprocs;
|
||||||
} pools[32][2]; // [modcod][sf]
|
} pools[32][2]; // [modcod][sf]
|
||||||
struct helper_job
|
struct helper_job
|
||||||
@ -2533,7 +2516,10 @@ struct s2_fecdec_helper : runnable
|
|||||||
fprintf(stderr, "*** Throughput will be suboptimal.\n");
|
fprintf(stderr, "*** Throughput will be suboptimal.\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
int child = vfork();
|
// vfork() differs from fork(2) in that the calling thread is
|
||||||
|
// suspended until the child terminates
|
||||||
|
int child = fork();
|
||||||
|
|
||||||
if (!child)
|
if (!child)
|
||||||
{
|
{
|
||||||
// Child process
|
// Child process
|
||||||
@ -2543,16 +2529,19 @@ struct s2_fecdec_helper : runnable
|
|||||||
dup2(rx[1], 1);
|
dup2(rx[1], 1);
|
||||||
char mc_arg[16];
|
char mc_arg[16];
|
||||||
sprintf(mc_arg, "%d", pls->modcod);
|
sprintf(mc_arg, "%d", pls->modcod);
|
||||||
const char *sf_arg = pls->sf ? "--shortframes" : NULL;
|
char batch_size_arg[16];
|
||||||
const char *argv[] = {command, "--trials", "10", "--modcod", mc_arg, sf_arg, NULL};
|
sprintf(batch_size_arg, "%d", batch_size);
|
||||||
execve(command, (char *const *)argv, NULL);
|
const char *sf_arg = pls->sf ? "--shortframes" : nullptr;
|
||||||
|
const char *argv[] = {command, "--trials", "5", "--batch-size", batch_size_arg, "--modcod", mc_arg, sf_arg, nullptr};
|
||||||
|
execve(command, (char *const *)argv, nullptr);
|
||||||
fatal(command);
|
fatal(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
h->fd_tx = tx[1];
|
h->fd_tx = tx[1];
|
||||||
close(tx[0]);
|
close(tx[0]);
|
||||||
h->fd_rx = rx[0];
|
h->fd_rx = rx[0];
|
||||||
close(rx[1]);
|
close(rx[1]);
|
||||||
h->batch_size = 32; // TBD
|
h->batch_size = batch_size; // TBD
|
||||||
h->b_in = h->b_out = 0;
|
h->b_in = h->b_out = 0;
|
||||||
int flags = fcntl(h->fd_tx, F_GETFL);
|
int flags = fcntl(h->fd_tx, F_GETFL);
|
||||||
if (fcntl(h->fd_tx, F_SETFL, flags | O_NONBLOCK))
|
if (fcntl(h->fd_tx, F_SETFL, flags | O_NONBLOCK))
|
||||||
@ -2618,9 +2607,6 @@ struct s2_fecdec_helper : runnable
|
|||||||
std::deque<bbframe> bbframe_q;
|
std::deque<bbframe> bbframe_q;
|
||||||
std::deque<int> bitcount_q;
|
std::deque<int> bitcount_q;
|
||||||
std::deque<int> errcount_q;
|
std::deque<int> errcount_q;
|
||||||
unsigned int writing_modulo;
|
|
||||||
unsigned int zeros_count;
|
|
||||||
unsigned int run_count;
|
|
||||||
pipewriter<int> *bitcount, *errcount;
|
pipewriter<int> *bitcount, *errcount;
|
||||||
}; // s2_fecdec_helper
|
}; // s2_fecdec_helper
|
||||||
|
|
||||||
@ -2714,8 +2700,8 @@ struct s2_framer : runnable
|
|||||||
struct s2_deframer : runnable
|
struct s2_deframer : runnable
|
||||||
{
|
{
|
||||||
s2_deframer(scheduler *sch, pipebuf<bbframe> &_in, pipebuf<tspacket> &_out,
|
s2_deframer(scheduler *sch, pipebuf<bbframe> &_in, pipebuf<tspacket> &_out,
|
||||||
pipebuf<int> *_state_out = NULL,
|
pipebuf<int> *_state_out = nullptr,
|
||||||
pipebuf<unsigned long> *_locktime_out = NULL)
|
pipebuf<unsigned long> *_locktime_out = nullptr)
|
||||||
: runnable(sch, "S2 deframer"),
|
: runnable(sch, "S2 deframer"),
|
||||||
missing(-1),
|
missing(-1),
|
||||||
in(_in), out(_out, MAX_TS_PER_BBFRAME),
|
in(_in), out(_out, MAX_TS_PER_BBFRAME),
|
||||||
@ -2767,7 +2753,9 @@ struct s2_deframer : runnable
|
|||||||
syncd > dfl || (dfl & 7) || (syncd & 7))
|
syncd > dfl || (dfl & 7) || (syncd & 7))
|
||||||
{
|
{
|
||||||
// Note: Maybe accept syncd=65535
|
// Note: Maybe accept syncd=65535
|
||||||
|
if (sch->debug) {
|
||||||
fprintf(stderr, "Bad bbframe\n");
|
fprintf(stderr, "Bad bbframe\n");
|
||||||
|
}
|
||||||
missing = -1;
|
missing = -1;
|
||||||
info_unlocked();
|
info_unlocked();
|
||||||
return;
|
return;
|
||||||
@ -2778,7 +2766,9 @@ struct s2_deframer : runnable
|
|||||||
{
|
{
|
||||||
// Skip unusable data at beginning of bbframe
|
// Skip unusable data at beginning of bbframe
|
||||||
pos = syncd / 8;
|
pos = syncd / 8;
|
||||||
|
if (sch->debug) {
|
||||||
fprintf(stderr, "Start TS at %d\n", pos);
|
fprintf(stderr, "Start TS at %d\n", pos);
|
||||||
|
}
|
||||||
missing = 0;
|
missing = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2786,7 +2776,9 @@ struct s2_deframer : runnable
|
|||||||
// Sanity check
|
// Sanity check
|
||||||
if (syncd / 8 != missing)
|
if (syncd / 8 != missing)
|
||||||
{
|
{
|
||||||
|
if (sch->debug) {
|
||||||
fprintf(stderr, "Lost a bbframe ?\n");
|
fprintf(stderr, "Lost a bbframe ?\n");
|
||||||
|
}
|
||||||
missing = -1;
|
missing = -1;
|
||||||
info_unlocked();
|
info_unlocked();
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user