SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
Classes | Public Member Functions | Public Attributes | Private Member Functions | Private Attributes | List of all members
leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE > Struct Template Reference

#include <dvbs2.h>

+ Inheritance diagram for leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >:
+ Collaboration diagram for leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >:

Classes

struct  helper_instance
 
struct  helper_job
 
struct  pool
 

Public Member Functions

 s2_fecdec_helper (scheduler *sch, pipebuf< fecframe< SOFTBYTE >> &_in, pipebuf< bbframe > &_out, const char *_command, pipebuf< int > *_bitcount=NULL, pipebuf< int > *_errcount=NULL)
 
void run ()
 
- Public Member Functions inherited from leansdr::runnable
 runnable (scheduler *_sch, const char *name)
 
- Public Member Functions inherited from leansdr::runnable_common
 runnable_common (const char *_name)
 
virtual ~runnable_common ()
 
virtual void shutdown ()
 

Public Attributes

int batch_size
 
int nhelpers
 
bool must_buffer
 
- Public Attributes inherited from leansdr::runnable_common
const char * name
 

Private Member Functions

bool send_frame (fecframe< SOFTBYTE > *pin)
 
poolget_pool (const s2_pls *pls)
 
void spawn_helper (helper_instance *h, const s2_pls *pls)
 
void receive_frame (const helper_job *job)
 

Private Attributes

struct leansdr::s2_fecdec_helper::pool pools [32][2]
 
simplequeue< helper_job, 1024 > jobs
 
pipereader< fecframe< SOFTBYTE > > in
 
pipewriter< bbframeout
 
const char * command
 
SOFTBYTE ldpc_buf [64800/8]
 
uint8_t bch_buf [64800/8]
 
s2_bch_engines s2bch
 
s2_bbscrambling bbscrambling
 
pipewriter< int > * bitcount
 
pipewriter< int > * errcount
 

Additional Inherited Members

- Protected Attributes inherited from leansdr::runnable
schedulersch
 

Detailed Description

template<typename SOFTBIT, typename SOFTBYTE>
struct leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >

Definition at line 2208 of file dvbs2.h.

Constructor & Destructor Documentation

◆ s2_fecdec_helper()

template<typename SOFTBIT , typename SOFTBYTE >
leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::s2_fecdec_helper ( scheduler sch,
pipebuf< fecframe< SOFTBYTE >> &  _in,
pipebuf< bbframe > &  _out,
const char *  _command,
pipebuf< int > *  _bitcount = NULL,
pipebuf< int > *  _errcount = NULL 
)
inline

Definition at line 2213 of file dvbs2.h.

2219  : runnable(sch, "S2 fecdec io"),
2220  batch_size(32),
2221  nhelpers(1),
2222  must_buffer(false),
2223  in(_in), out(_out),
2224  command(_command),
2225  bitcount(opt_writer(_bitcount, 1)),
2226  errcount(opt_writer(_errcount, 1))
2227  {
2228  for (int mc = 0; mc < 32; ++mc)
2229  for (int sf = 0; sf < 2; ++sf)
2230  pools[mc][sf].procs = NULL;
2231  }
const char * command
Definition: dvbs2.h:2419
runnable(scheduler *_sch, const char *name)
Definition: framework.h:193
pipewriter< bbframe > out
Definition: dvbs2.h:2418
pipewriter< int > * errcount
Definition: dvbs2.h:2424
pipewriter< T > * opt_writer(pipebuf< T > *buf, unsigned long min_write=1)
Definition: framework.h:329
struct leansdr::s2_fecdec_helper::pool pools[32][2]
pipewriter< int > * bitcount
Definition: dvbs2.h:2424
scheduler * sch
Definition: framework.h:199
pipereader< fecframe< SOFTBYTE > > in
Definition: dvbs2.h:2417

Member Function Documentation

◆ get_pool()

template<typename SOFTBIT , typename SOFTBYTE >
pool* leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::get_pool ( const s2_pls pls)
inlineprivate

Definition at line 2309 of file dvbs2.h.

References i, leansdr::s2_pls::modcod, leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::pool::nprocs, leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::pool::procs, and leansdr::s2_pls::sf.

2310  {
2311  pool *p = &pools[pls->modcod][pls->sf];
2312  if (!p->procs)
2313  {
2314  p->procs = new helper_instance[nhelpers];
2315  for (int i = 0; i < nhelpers; ++i)
2316  spawn_helper(&p->procs[i], pls);
2317  p->nprocs = nhelpers;
2318  }
2319  return p;
2320  }
void spawn_helper(helper_instance *h, const s2_pls *pls)
Definition: dvbs2.h:2322
helper_instance * procs
Definition: dvbs2.h:2270
int32_t i
Definition: decimators.h:244
struct leansdr::s2_fecdec_helper::pool pools[32][2]

◆ receive_frame()

template<typename SOFTBIT , typename SOFTBYTE >
void leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::receive_frame ( const helper_job job)
inlineprivate

Definition at line 2373 of file dvbs2.h.

References leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::helper_instance::b_out, leansdr::bbframe::bytes, leansdr::check_modcod(), leansdr::bch_interface::decode(), leansdr::fatal(), leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::helper_instance::fd_rx, leansdr::s2_pls::framebits(), leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::helper_job::h, leansdr::s2_pls::modcod, leansdr::opt_write(), leansdr::bbframe::pls, leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::helper_job::pls, leansdr::modcod_info::rate, leansdr::s2_pls::sf, leansdr::softbytes_harden(), leansdr::pipewriter< T >::wr(), and leansdr::pipewriter< T >::written().

2374  {
2375  // Read corrected frame from helper
2376  const s2_pls *pls = &job->pls;
2377  size_t iosize = (pls->framebits() / 8) * sizeof(ldpc_buf[0]);
2378  int nr = read(job->h->fd_rx, ldpc_buf, iosize);
2379  if (nr < 0)
2380  fatal("read(LDPC helper)");
2381  if (nr != iosize)
2382  fatal("partial read(LDPC helper)");
2383  --job->h->b_out;
2384  // Decode BCH.
2385  const modcod_info *mcinfo = check_modcod(job->pls.modcod);
2386  const fec_info *fi = &fec_infos[job->pls.sf][mcinfo->rate];
2387  uint8_t *hardbytes = softbytes_harden(ldpc_buf, fi->kldpc / 8, bch_buf);
2388  size_t cwbytes = fi->kldpc / 8;
2389  size_t msgbytes = fi->Kbch / 8;
2390  size_t chkbytes = cwbytes - msgbytes;
2391  bch_interface *bch = s2bch.bchs[job->pls.sf][mcinfo->rate];
2392  int ncorr = bch->decode(hardbytes, cwbytes);
2393  if (sch->debug2)
2394  fprintf(stderr, "BCHCORR = %d\n", ncorr);
2395  bool corrupted = (ncorr < 0);
2396  // Report VBER
2397  opt_write(bitcount, fi->Kbch);
2398  opt_write(errcount, (ncorr >= 0) ? ncorr : fi->Kbch);
2399 #if 0
2400  // TBD Some decoders want the bad packets.
2401  if ( corrupted ) {
2402  fprintf(stderr, "Passing bad frame\n");
2403  corrupted = false;
2404  }
2405 #endif
2406  if (!corrupted)
2407  {
2408  // Descramble and output
2409  bbframe *pout = out.wr();
2410  pout->pls = job->pls;
2411  bbscrambling.transform(hardbytes, fi->Kbch / 8, pout->bytes);
2412  out.written(1);
2413  }
2414  if (sch->debug)
2415  fprintf(stderr, "%c", corrupted ? '!' : ncorr ? '.' : '_');
2416  }
virtual int decode(uint8_t *cw, size_t cwbytes)=0
uint8_t * softbytes_harden(hard_sb p[], int nbytes, uint8_t storage[])
Definition: softword.h:67
s2_bbscrambling bbscrambling
Definition: dvbs2.h:2423
bch_interface * bchs[2][FEC_COUNT]
Definition: dvbs2.h:1966
pipewriter< bbframe > out
Definition: dvbs2.h:2418
unsigned char uint8_t
Definition: rtptypes_win.h:42
void opt_write(pipewriter< T > *p, T val)
Definition: framework.h:341
pipewriter< int > * errcount
Definition: dvbs2.h:2424
pipewriter< int > * bitcount
Definition: dvbs2.h:2424
void transform(const uint8_t *in, int bbsize, uint8_t *out)
Definition: dvbs2.h:186
void fatal(const char *s)
Definition: framework.cpp:6
s2_bch_engines s2bch
Definition: dvbs2.h:2422
scheduler * sch
Definition: framework.h:199
uint8_t bch_buf[64800/8]
Definition: dvbs2.h:2421
const modcod_info * check_modcod(int m)
Definition: dvbs2.h:285
SOFTBYTE ldpc_buf[64800/8]
Definition: dvbs2.h:2420
+ Here is the call graph for this function:

◆ run()

template<typename SOFTBIT , typename SOFTBYTE >
void leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::run ( )
inlinevirtual

Reimplemented from leansdr::runnable_common.

Definition at line 2232 of file dvbs2.h.

References leansdr::opt_writable(), leansdr::pipereader< T >::rd(), leansdr::pipereader< T >::read(), leansdr::pipereader< T >::readable(), and leansdr::pipewriter< T >::writable().

2233  {
2234  bool work_done = false;
2235  // Send work until all helpers block.
2236  bool all_blocked = false;
2237  while (in.readable() >= 1 && !jobs.full())
2238  {
2239  if (!send_frame(in.rd()))
2240  {
2241  all_blocked = true;
2242  break;
2243  }
2244  in.read(1);
2245  work_done = true;
2246  }
2247  // Risk blocking on read() only when we have nothing else to do
2248  // and we know a result is coming.
2249  while ((all_blocked || !work_done || jobs.full()) &&
2250  !jobs.empty() &&
2251  jobs.peek()->h->b_out &&
2252  out.writable() >= 1 &&
2254  {
2255  receive_frame(jobs.get());
2256  }
2257  }
bool send_frame(fecframe< SOFTBYTE > *pin)
Definition: dvbs2.h:2280
pipewriter< bbframe > out
Definition: dvbs2.h:2418
bool opt_writable(pipewriter< T > *p, int n=1)
Definition: framework.h:335
pipewriter< int > * errcount
Definition: dvbs2.h:2424
pipewriter< int > * bitcount
Definition: dvbs2.h:2424
void receive_frame(const helper_job *job)
Definition: dvbs2.h:2373
simplequeue< helper_job, 1024 > jobs
Definition: dvbs2.h:2278
pipereader< fecframe< SOFTBYTE > > in
Definition: dvbs2.h:2417
+ Here is the call graph for this function:

◆ send_frame()

template<typename SOFTBIT , typename SOFTBYTE >
bool leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::send_frame ( fecframe< SOFTBYTE > *  pin)
inlineprivate

Definition at line 2280 of file dvbs2.h.

References leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::helper_instance::b_in, leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::helper_instance::b_out, leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::helper_instance::batch_size, leansdr::fecframe< SOFTBYTE >::bytes, leansdr::fatal(), leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::helper_instance::fd_tx, leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::helper_job::h, i, leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::pool::nprocs, leansdr::fecframe< SOFTBYTE >::pls, leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::helper_job::pls, leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::pool::procs, and leansdr::simplequeue< T, _SIZE >::put().

2281  {
2282  pool *p = get_pool(&pin->pls);
2283  for (int i = 0; i < p->nprocs; ++i)
2284  {
2285  helper_instance *h = &p->procs[i];
2286  size_t iosize = (pin->pls.framebits() / 8) * sizeof(SOFTBYTE);
2287  // fprintf(stderr, "Writing %lu to fd %d\n", iosize, h->fd_tx);
2288  int nw = write(h->fd_tx, pin->bytes, iosize);
2289  if (nw < 0 && errno == EWOULDBLOCK)
2290  continue;
2291  if (nw < 0)
2292  fatal("write(LDPC helper");
2293  if (nw != iosize)
2294  fatal("partial write(LDPC helper)");
2295  helper_job *job = jobs.put();
2296  job->pls = pin->pls;
2297  job->h = h;
2298  ++h->b_in;
2299  if (h->b_in >= h->batch_size)
2300  {
2301  h->b_in -= h->batch_size;
2302  h->b_out += h->batch_size;
2303  }
2304  return true;
2305  }
2306  return false;
2307  }
int32_t i
Definition: decimators.h:244
void fatal(const char *s)
Definition: framework.cpp:6
simplequeue< helper_job, 1024 > jobs
Definition: dvbs2.h:2278
pool * get_pool(const s2_pls *pls)
Definition: dvbs2.h:2309
+ Here is the call graph for this function:

◆ spawn_helper()

template<typename SOFTBIT , typename SOFTBYTE >
void leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::spawn_helper ( helper_instance h,
const s2_pls pls 
)
inlineprivate

Definition at line 2322 of file dvbs2.h.

References leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::helper_instance::b_in, leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::helper_instance::b_out, leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::helper_instance::batch_size, leansdr::fatal(), leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::helper_instance::fd_rx, leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::helper_instance::fd_tx, leansdr::s2_pls::modcod, and leansdr::s2_pls::sf.

2323  {
2324  if (sch->debug)
2325  fprintf(stderr, "Spawning LDPC helper: modcod=%d sf=%d\n",
2326  pls->modcod, pls->sf);
2327  int tx[2], rx[2];
2328  if (pipe(tx) || pipe(rx))
2329  fatal("pipe");
2330  // Size the pipes so that the helper never runs out of work to do.
2331  int pipesize = 64800 * batch_size;
2332  if (fcntl(tx[0], F_SETPIPE_SZ, pipesize) < 0 ||
2333  fcntl(rx[0], F_SETPIPE_SZ, pipesize) < 0 ||
2334  fcntl(tx[1], F_SETPIPE_SZ, pipesize) < 0 ||
2335  fcntl(rx[1], F_SETPIPE_SZ, pipesize) < 0)
2336  {
2337  fprintf(stderr,
2338  "*** Failed to increase pipe size.\n"
2339  "*** Try echo %d > /proc/sys/fs/pipe-max-size\n",
2340  pipesize);
2341  if (must_buffer)
2342  fatal("F_SETPIPE_SZ");
2343  else
2344  fprintf(stderr, "*** Throughput will be suboptimal.\n");
2345  }
2346  int child = vfork();
2347  if (!child)
2348  {
2349  // Child process
2350  close(tx[1]);
2351  dup2(tx[0], 0);
2352  close(rx[0]);
2353  dup2(rx[1], 1);
2354  char mc_arg[16];
2355  sprintf(mc_arg, "%d", pls->modcod);
2356  const char *sf_arg = pls->sf ? "--shortframes" : NULL;
2357  const char *argv[] = {command, "--modcod", mc_arg, sf_arg, NULL};
2358  execve(command, (char *const *)argv, NULL);
2359  fatal(command);
2360  }
2361  h->fd_tx = tx[1];
2362  close(tx[0]);
2363  h->fd_rx = rx[0];
2364  close(rx[1]);
2365  h->batch_size = 32; // TBD
2366  h->b_in = h->b_out = 0;
2367  int flags = fcntl(h->fd_tx, F_GETFL);
2368  if (fcntl(h->fd_tx, F_SETFL, flags | O_NONBLOCK))
2369  fatal("fcntl(helper)");
2370  }
const char * command
Definition: dvbs2.h:2419
void fatal(const char *s)
Definition: framework.cpp:6
scheduler * sch
Definition: framework.h:199
+ Here is the call graph for this function:

Member Data Documentation

◆ batch_size

template<typename SOFTBIT , typename SOFTBYTE >
int leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::batch_size

Definition at line 2210 of file dvbs2.h.

◆ bbscrambling

template<typename SOFTBIT , typename SOFTBYTE >
s2_bbscrambling leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::bbscrambling
private

Definition at line 2423 of file dvbs2.h.

◆ bch_buf

template<typename SOFTBIT , typename SOFTBYTE >
uint8_t leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::bch_buf[64800/8]
private

Definition at line 2421 of file dvbs2.h.

◆ bitcount

template<typename SOFTBIT , typename SOFTBYTE >
pipewriter<int>* leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::bitcount
private

Definition at line 2424 of file dvbs2.h.

◆ command

template<typename SOFTBIT , typename SOFTBYTE >
const char* leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::command
private

Definition at line 2419 of file dvbs2.h.

◆ errcount

template<typename SOFTBIT , typename SOFTBYTE >
pipewriter<int> * leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::errcount
private

Definition at line 2424 of file dvbs2.h.

◆ in

template<typename SOFTBIT , typename SOFTBYTE >
pipereader<fecframe<SOFTBYTE> > leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::in
private

Definition at line 2417 of file dvbs2.h.

◆ jobs

template<typename SOFTBIT , typename SOFTBYTE >
simplequeue<helper_job, 1024> leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::jobs
private

Definition at line 2278 of file dvbs2.h.

◆ ldpc_buf

template<typename SOFTBIT , typename SOFTBYTE >
SOFTBYTE leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::ldpc_buf[64800/8]
private

Definition at line 2420 of file dvbs2.h.

◆ must_buffer

template<typename SOFTBIT , typename SOFTBYTE >
bool leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::must_buffer

Definition at line 2212 of file dvbs2.h.

◆ nhelpers

template<typename SOFTBIT , typename SOFTBYTE >
int leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::nhelpers

Definition at line 2211 of file dvbs2.h.

◆ out

template<typename SOFTBIT , typename SOFTBYTE >
pipewriter<bbframe> leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::out
private

Definition at line 2418 of file dvbs2.h.

◆ pools

template<typename SOFTBIT , typename SOFTBYTE >
struct leansdr::s2_fecdec_helper::pool leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::pools[32][2]
private

◆ s2bch

template<typename SOFTBIT , typename SOFTBYTE >
s2_bch_engines leansdr::s2_fecdec_helper< SOFTBIT, SOFTBYTE >::s2bch
private

Definition at line 2422 of file dvbs2.h.


The documentation for this struct was generated from the following file: