mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-31 04:50:29 -04: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" | ||||
| 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 | ||||
| 			{ | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user