1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-26 17:58:43 -05:00

DATV: external LDPC tool implementation (5): dequeue outputs in run() method

This commit is contained in:
f4exb 2021-03-06 07:37:44 +01:00
parent 8c45107c8c
commit 6e8b573b5f
2 changed files with 79 additions and 82 deletions

View File

@ -28,6 +28,7 @@ static const int DEFAULT_TRIALS = 50;
#include "layered_decoder.h"
static const int DEFAULT_TRIALS = 25;
#endif
static const int DEFAULT_BATCH_SIZE = 32;
//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)
{
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)
fprintf(f, "** Error while processing '%s'\n", info);
exit(c);
@ -57,6 +58,7 @@ int main(int argc, char **argv)
const char *standard = "DVB-S2";
int modcod = -1;
int max_trials = DEFAULT_TRIALS;
int batch_size = DEFAULT_BATCH_SIZE;
bool shortframes = false;
for (int i = 1; i < argc; ++i)
@ -67,6 +69,8 @@ int main(int argc, char **argv)
modcod = atoi(argv[++i]);
else if (!strcmp(argv[i], "--trials") && i + 1 < argc)
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"))
shortframes = true;
else if (!strcmp(argv[i], "-h"))
@ -123,7 +127,7 @@ int main(int argc, char **argv)
decode.init(ldpc);
int BLOCKS = 32;
int BLOCKS = batch_size;
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);
ldpctool::simd_type *simd = reinterpret_cast<ldpctool::simd_type *>(aligned_buffer);
@ -172,6 +176,7 @@ int main(int argc, char **argv)
{
iterations += blocks * trials;
std::cerr << "ldpc_tool: decoder failed at converging to a code word in " << trials << " trials" << std::endl;
break;
}
else
{

View File

@ -393,7 +393,7 @@ struct s2_frame_transmitter : runnable
private:
pipereader<plslot<hard_ss>> in;
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.
void update_cstln(const modcod_info *mcinfo)
{
@ -445,13 +445,13 @@ struct s2_frame_receiver : runnable
sampler_interface<T> *_sampler,
pipebuf<complex<T>> &_in,
pipebuf<plslot<SOFTSYMB>> &_out,
pipebuf<float> *_freq_out = NULL,
pipebuf<float> *_ss_out = NULL,
pipebuf<float> *_mer_out = NULL,
pipebuf<complex<float>> *_cstln_out = NULL,
pipebuf<complex<float>> *_cstln_pls_out = NULL,
pipebuf<complex<float>> *_symbols_out = NULL,
pipebuf<int> *_state_out = NULL)
pipebuf<float> *_freq_out = nullptr,
pipebuf<float> *_ss_out = nullptr,
pipebuf<float> *_mer_out = nullptr,
pipebuf<complex<float>> *_cstln_out = nullptr,
pipebuf<complex<float>> *_cstln_pls_out = nullptr,
pipebuf<complex<float>> *_symbols_out = nullptr,
pipebuf<int> *_state_out = nullptr)
: runnable(sch, "S2 frame receiver"),
sampler(_sampler),
meas_decimation(1048576),
@ -459,7 +459,7 @@ struct s2_frame_receiver : runnable
strongpls(false),
in_power(0), ev_power(0), agc_gain(1), agc_bw(1e-3),
nsyncs(0),
cstln(NULL),
cstln(nullptr),
in(_in), out(_out, 1 + modcod_info::MAX_SLOTS_PER_FRAME),
meas_count(0),
freq_out(opt_writer(_freq_out)),
@ -612,7 +612,7 @@ struct s2_frame_receiver : runnable
if (cstln_out && cstln_out->writable() >= 1024)
psampled = cstln_out->wr();
else
psampled = NULL;
psampled = nullptr;
// Preserve float precision
phase16 -= 65536 * floor(phase16 / 65536);
@ -714,15 +714,15 @@ struct s2_frame_receiver : runnable
if (cstln_out && cstln_out->writable() >= 1024)
psampled = cstln_out->wr();
else
psampled = NULL;
psampled = nullptr;
complex<float> *psampled_pls;
if (cstln_pls_out && cstln_pls_out->writable() >= 1024)
psampled_pls = cstln_pls_out->wr();
else
psampled_pls = NULL;
psampled_pls = nullptr;
#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;
#endif
@ -1941,7 +1941,7 @@ struct s2_ldpc_engines
const fec_info *fi = &fec_infos[sf][fec];
if (!fi->ldpc)
{
ldpcs[sf][fec] = NULL;
ldpcs[sf][fec] = nullptr;
}
else
{
@ -2095,8 +2095,8 @@ struct s2_fecdec : runnable
int bitflips;
s2_fecdec(scheduler *sch,
pipebuf<fecframe<SOFTBYTE>> &_in, pipebuf<bbframe> &_out,
pipebuf<int> *_bitcount = NULL,
pipebuf<int> *_errcount = NULL)
pipebuf<int> *_bitcount = nullptr,
pipebuf<int> *_errcount = nullptr)
: runnable(sch, "S2 fecdec"),
bitflips(0),
in(_in), out(_out),
@ -2309,7 +2309,7 @@ private:
uint8_t bch_buf[64800 / 8]; // Temp storage for hardening before BCH
s2_bch_engines s2bch;
s2_bbscrambling bbscrambling;
};
}; // s2_fecdec_soft
// External LDPC decoder
// Spawns a user-specified command, FEC frames on stdin/stdout.
@ -2351,29 +2351,54 @@ struct s2_fecdec_helper : runnable
pipebuf<fecframe<SOFTBYTE>> &_in,
pipebuf<bbframe> &_out,
const char *_command,
pipebuf<int> *_bitcount = NULL,
pipebuf<int> *_errcount = NULL)
pipebuf<int> *_bitcount = nullptr,
pipebuf<int> *_errcount = nullptr)
: runnable(sch, "S2 fecdec io"),
batch_size(32),
batch_size(16),
nhelpers(1),
must_buffer(false),
in(_in), out(_out),
command(_command),
writing_modulo(1),
zeros_count(0),
run_count(0),
bitcount(opt_writer(_bitcount, 1)),
errcount(opt_writer(_errcount, 1))
{
for (int mc = 0; mc < 32; ++mc)
for (int sf = 0; sf < 2; ++sf)
pools[mc][sf].procs = NULL;
pools[mc][sf].procs = nullptr;
}
void run()
{
// Send work until all helpers block.
while (in.readable() >= 1 && !jobs.full())
{
if (out.writable() >= 1)
{
if (bbframe_q.size() != 0)
{
bbframe *pout = out.wr();
pout->pls = bbframe_q.front().pls;
std::copy(bbframe_q.front().bytes, bbframe_q.front().bytes + (58192 / 8), pout->bytes);
bbframe_q.pop_front();
out.written(1);
}
else
{
fprintf(stderr, "s2_fecdec_helper::run: WARNING: bbframe queue is empty\n");
}
}
if ((bitcount_q.size() != 0) && opt_writable(bitcount, 1))
{
opt_write(bitcount, bitcount_q.front());
bitcount_q.pop_front();
}
if ((errcount_q.size() != 0) && opt_writable(errcount, 1))
{
opt_write(errcount, errcount_q.front());
errcount_q.pop_front();
}
if (!send_frame(in.rd())) {
break;
}
@ -2381,54 +2406,12 @@ struct s2_fecdec_helper : runnable
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 ((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();
pout->pls = bbframe_q.front().pls;
std::copy(bbframe_q.front().bytes, bbframe_q.front().bytes + (58192 / 8), pout->bytes);
bbframe_q.pop_front();
out.written(1);
zeros_count = 0;
}
else
{
zeros_count++;
}
if ((bitcount_q.size() != 0) && opt_writable(bitcount, 1))
{
opt_write(bitcount, bitcount_q.front());
bitcount_q.pop_front();
}
if ((errcount_q.size() != 0) && opt_writable(errcount, 1))
{
opt_write(errcount, errcount_q.front());
errcount_q.pop_front();
}
run_count++;
}
private:
@ -2442,7 +2425,7 @@ struct s2_fecdec_helper : runnable
};
struct pool
{
helper_instance *procs; // NULL or [nprocs]
helper_instance *procs; // nullptr or [nprocs]
int nprocs;
} pools[32][2]; // [modcod][sf]
struct helper_job
@ -2533,7 +2516,10 @@ struct s2_fecdec_helper : runnable
fprintf(stderr, "*** Throughput will be suboptimal.\n");
}
#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)
{
// Child process
@ -2543,16 +2529,19 @@ struct s2_fecdec_helper : runnable
dup2(rx[1], 1);
char mc_arg[16];
sprintf(mc_arg, "%d", pls->modcod);
const char *sf_arg = pls->sf ? "--shortframes" : NULL;
const char *argv[] = {command, "--trials", "10", "--modcod", mc_arg, sf_arg, NULL};
execve(command, (char *const *)argv, NULL);
char batch_size_arg[16];
sprintf(batch_size_arg, "%d", batch_size);
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);
}
h->fd_tx = tx[1];
close(tx[0]);
h->fd_rx = rx[0];
close(rx[1]);
h->batch_size = 32; // TBD
h->batch_size = batch_size; // TBD
h->b_in = h->b_out = 0;
int flags = fcntl(h->fd_tx, F_GETFL);
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<int> bitcount_q;
std::deque<int> errcount_q;
unsigned int writing_modulo;
unsigned int zeros_count;
unsigned int run_count;
pipewriter<int> *bitcount, *errcount;
}; // s2_fecdec_helper
@ -2714,8 +2700,8 @@ struct s2_framer : runnable
struct s2_deframer : runnable
{
s2_deframer(scheduler *sch, pipebuf<bbframe> &_in, pipebuf<tspacket> &_out,
pipebuf<int> *_state_out = NULL,
pipebuf<unsigned long> *_locktime_out = NULL)
pipebuf<int> *_state_out = nullptr,
pipebuf<unsigned long> *_locktime_out = nullptr)
: runnable(sch, "S2 deframer"),
missing(-1),
in(_in), out(_out, MAX_TS_PER_BBFRAME),
@ -2767,7 +2753,9 @@ struct s2_deframer : runnable
syncd > dfl || (dfl & 7) || (syncd & 7))
{
// Note: Maybe accept syncd=65535
fprintf(stderr, "Bad bbframe\n");
if (sch->debug) {
fprintf(stderr, "Bad bbframe\n");
}
missing = -1;
info_unlocked();
return;
@ -2778,7 +2766,9 @@ struct s2_deframer : runnable
{
// Skip unusable data at beginning of bbframe
pos = syncd / 8;
fprintf(stderr, "Start TS at %d\n", pos);
if (sch->debug) {
fprintf(stderr, "Start TS at %d\n", pos);
}
missing = 0;
}
else
@ -2786,7 +2776,9 @@ struct s2_deframer : runnable
// Sanity check
if (syncd / 8 != missing)
{
fprintf(stderr, "Lost a bbframe ?\n");
if (sch->debug) {
fprintf(stderr, "Lost a bbframe ?\n");
}
missing = -1;
info_unlocked();
return;