mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-30 20:40:20 -04:00 
			
		
		
		
	DATV: enhancement and fixes to DVBS2 external LDPC tool process. Implements #804
This commit is contained in:
		
							parent
							
								
									c575c02791
								
							
						
					
					
						commit
						233f512f9c
					
				| @ -197,7 +197,7 @@ bool DATVDemodSettings::deserialize(const QByteArray& data) | |||||||
|         d.readS32(33, &m_maxBitflips, 0); |         d.readS32(33, &m_maxBitflips, 0); | ||||||
|         d.readString(34, &m_softLDPCToolPath, "/opt/install/sdrangel/bin/ldpctool"); |         d.readString(34, &m_softLDPCToolPath, "/opt/install/sdrangel/bin/ldpctool"); | ||||||
|         d.readS32(35, &tmp, 8); |         d.readS32(35, &tmp, 8); | ||||||
|         m_softLDPCMaxTrials = tmp < 1 ? 1 : tmp > 8 ? 8 : tmp; |         m_softLDPCMaxTrials = tmp < 1 ? 1 : tmp > m_softLDPCMaxMaxTrials ? m_softLDPCMaxMaxTrials : tmp; | ||||||
| 
 | 
 | ||||||
|         validateSystemConfiguration(); |         validateSystemConfiguration(); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -106,6 +106,7 @@ struct DATVDemodSettings | |||||||
|     uint16_t m_reverseAPIPort; |     uint16_t m_reverseAPIPort; | ||||||
|     uint16_t m_reverseAPIDeviceIndex; |     uint16_t m_reverseAPIDeviceIndex; | ||||||
|     uint16_t m_reverseAPIChannelIndex; |     uint16_t m_reverseAPIChannelIndex; | ||||||
|  |     static const int m_softLDPCMaxMaxTrials = 25; | ||||||
| 
 | 
 | ||||||
|     DATVDemodSettings(); |     DATVDemodSettings(); | ||||||
|     void resetToDefaults(); |     void resetToDefaults(); | ||||||
|  | |||||||
| @ -431,6 +431,10 @@ void DATVDemodSink::CleanUpDATVFramework(bool blnRelease) | |||||||
|         { |         { | ||||||
|             delete (leansdr::s2_fecdec_soft<leansdr::llr_t,leansdr::llr_sb>*) r_fecdecsoft; |             delete (leansdr::s2_fecdec_soft<leansdr::llr_t,leansdr::llr_sb>*) r_fecdecsoft; | ||||||
|         } |         } | ||||||
|  |         if(r_fecdechelper != nullptr) | ||||||
|  |         { | ||||||
|  |             delete (leansdr::s2_fecdec_helper<leansdr::llr_t,leansdr::llr_sb>*) r_fecdechelper; | ||||||
|  |         } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|         if(p_deframer != nullptr) |         if(p_deframer != nullptr) | ||||||
| @ -442,7 +446,7 @@ void DATVDemodSink::CleanUpDATVFramework(bool blnRelease) | |||||||
|         { |         { | ||||||
|             delete r_scope_symbols_dvbs2; |             delete r_scope_symbols_dvbs2; | ||||||
|         } |         } | ||||||
|     } |     } // blnRelease
 | ||||||
| 
 | 
 | ||||||
|     m_objScheduler=nullptr; |     m_objScheduler=nullptr; | ||||||
| 
 | 
 | ||||||
| @ -547,6 +551,7 @@ void DATVDemodSink::CleanUpDATVFramework(bool blnRelease) | |||||||
|     p_s2_deinterleaver = nullptr; |     p_s2_deinterleaver = nullptr; | ||||||
|     r_fecdec = nullptr; |     r_fecdec = nullptr; | ||||||
|     r_fecdecsoft = nullptr; |     r_fecdecsoft = nullptr; | ||||||
|  |     r_fecdechelper = nullptr; | ||||||
|     p_deframer = nullptr; |     p_deframer = nullptr; | ||||||
|     r_scope_symbols_dvbs2 = nullptr; |     r_scope_symbols_dvbs2 = nullptr; | ||||||
| } | } | ||||||
| @ -893,7 +898,7 @@ void DATVDemodSink::InitDATVS2Framework() | |||||||
| 
 | 
 | ||||||
|     m_blnDVBInitialized = false; |     m_blnDVBInitialized = false; | ||||||
|     m_lngReadIQ = 0; |     m_lngReadIQ = 0; | ||||||
|     CleanUpDATVFramework(false); |     CleanUpDATVFramework(true); | ||||||
| 
 | 
 | ||||||
|     qDebug()  << "DATVDemodSink::InitDATVS2Framework:" |     qDebug()  << "DATVDemodSink::InitDATVS2Framework:" | ||||||
|         <<  " Standard: " << m_settings.m_standard |         <<  " Standard: " << m_settings.m_standard | ||||||
| @ -1185,7 +1190,7 @@ void DATVDemodSink::InitDATVS2Framework() | |||||||
|             *(leansdr::pipebuf< leansdr::fecframe<leansdr::llr_sb> > *) p_fecframes |             *(leansdr::pipebuf< leansdr::fecframe<leansdr::llr_sb> > *) p_fecframes | ||||||
|         ); |         ); | ||||||
|         // Decode FEC-protected frames into plain BB frames.
 |         // Decode FEC-protected frames into plain BB frames.
 | ||||||
|         r_fecdec = new leansdr::s2_fecdec_helper<leansdr::llr_t, leansdr::llr_sb>( |         r_fecdechelper = new leansdr::s2_fecdec_helper<leansdr::llr_t, leansdr::llr_sb>( | ||||||
|             m_objScheduler, |             m_objScheduler, | ||||||
|             *(leansdr::pipebuf< leansdr::fecframe<leansdr::llr_sb> > *) p_fecframes, |             *(leansdr::pipebuf< leansdr::fecframe<leansdr::llr_sb> > *) p_fecframes, | ||||||
|             *(leansdr::pipebuf<leansdr::bbframe> *) p_bbframes, |             *(leansdr::pipebuf<leansdr::bbframe> *) p_bbframes, | ||||||
| @ -1193,8 +1198,8 @@ void DATVDemodSink::InitDATVS2Framework() | |||||||
|             p_vbitcount, |             p_vbitcount, | ||||||
|             p_verrcount) |             p_verrcount) | ||||||
|         ; |         ; | ||||||
|         leansdr::s2_fecdec_helper<leansdr::llr_t, leansdr::llr_sb> *fecdec = (leansdr::s2_fecdec_helper<leansdr::llr_t, leansdr::llr_sb> *) r_fecdec; |         leansdr::s2_fecdec_helper<leansdr::llr_t, leansdr::llr_sb> *fecdec = (leansdr::s2_fecdec_helper<leansdr::llr_t, leansdr::llr_sb> *) r_fecdechelper; | ||||||
|         const int nhelpers = 2; |         const int nhelpers = 4; | ||||||
|         fecdec->nhelpers = nhelpers; |         fecdec->nhelpers = nhelpers; | ||||||
|         fecdec->must_buffer = false; |         fecdec->must_buffer = false; | ||||||
|         fecdec->max_trials = m_settings.m_softLDPCMaxTrials; |         fecdec->max_trials = m_settings.m_softLDPCMaxTrials; | ||||||
|  | |||||||
| @ -225,6 +225,7 @@ private: | |||||||
|     void *p_s2_deinterleaver; |     void *p_s2_deinterleaver; | ||||||
|     void *r_fecdec; |     void *r_fecdec; | ||||||
|     void *r_fecdecsoft; |     void *r_fecdecsoft; | ||||||
|  |     void *r_fecdechelper; | ||||||
|     void *p_deframer; |     void *p_deframer; | ||||||
| 
 | 
 | ||||||
|     //DECIMATION
 |     //DECIMATION
 | ||||||
|  | |||||||
| @ -19,6 +19,7 @@ | |||||||
| #include <QFileDialog> | #include <QFileDialog> | ||||||
| 
 | 
 | ||||||
| #include "datvdvbs2ldpcdialog.h" | #include "datvdvbs2ldpcdialog.h" | ||||||
|  | #include "datvdemodsettings.h" | ||||||
| #include "ui_datvdvbs2ldpcdialog.h" | #include "ui_datvdvbs2ldpcdialog.h" | ||||||
| 
 | 
 | ||||||
| DatvDvbS2LdpcDialog::DatvDvbS2LdpcDialog(QWidget* parent) : | DatvDvbS2LdpcDialog::DatvDvbS2LdpcDialog(QWidget* parent) : | ||||||
| @ -46,7 +47,8 @@ void DatvDvbS2LdpcDialog::setFileName(const QString& fileName) | |||||||
| 
 | 
 | ||||||
| void DatvDvbS2LdpcDialog::setMaxTrials(int maxTrials) | void DatvDvbS2LdpcDialog::setMaxTrials(int maxTrials) | ||||||
| { | { | ||||||
|     m_maxTrials = maxTrials < 1 ? 1 : maxTrials > 8 ? 8 : maxTrials; |     m_maxTrials = maxTrials < 1 ? 1 : | ||||||
|  |         maxTrials > DATVDemodSettings::m_softLDPCMaxMaxTrials ? DATVDemodSettings::m_softLDPCMaxMaxTrials : maxTrials; | ||||||
|     ui->maxTrials->setValue(m_maxTrials); |     ui->maxTrials->setValue(m_maxTrials); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -31,11 +31,17 @@ | |||||||
|      </item> |      </item> | ||||||
|      <item> |      <item> | ||||||
|       <widget class="QSpinBox" name="maxTrials"> |       <widget class="QSpinBox" name="maxTrials"> | ||||||
|  |        <property name="minimumSize"> | ||||||
|  |         <size> | ||||||
|  |          <width>55</width> | ||||||
|  |          <height>0</height> | ||||||
|  |         </size> | ||||||
|  |        </property> | ||||||
|        <property name="minimum"> |        <property name="minimum"> | ||||||
|         <number>1</number> |         <number>1</number> | ||||||
|        </property> |        </property> | ||||||
|        <property name="maximum"> |        <property name="maximum"> | ||||||
|         <number>8</number> |         <number>25</number> | ||||||
|        </property> |        </property> | ||||||
|        <property name="displayIntegerBase"> |        <property name="displayIntegerBase"> | ||||||
|         <number>10</number> |         <number>10</number> | ||||||
|  | |||||||
| @ -136,6 +136,10 @@ int main(int argc, char **argv) | |||||||
| 	if (sizeof(ldpctool::code_type) != 1) | 	if (sizeof(ldpctool::code_type) != 1) | ||||||
| 		fail("Bug: Unsupported code_type"); | 		fail("Bug: Unsupported code_type"); | ||||||
| 
 | 
 | ||||||
|  | 	int trials_count = 0; | ||||||
|  | 	int max_count = 0; | ||||||
|  | 	int num_decodes = 0; | ||||||
|  | 
 | ||||||
| 	while (true) | 	while (true) | ||||||
| 	{ | 	{ | ||||||
| 		ssize_t iosize = BLOCKS * CODE_LEN * sizeof(*code); | 		ssize_t iosize = BLOCKS * CODE_LEN * sizeof(*code); | ||||||
| @ -153,8 +157,6 @@ int main(int argc, char **argv) | |||||||
| 			pos += nr; | 			pos += nr; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		int iterations = 0; |  | ||||||
| 		int num_decodes = 0; |  | ||||||
| 
 | 
 | ||||||
| 		for (int j = 0; j < BLOCKS; j += ldpctool::SIMD_WIDTH) | 		for (int j = 0; j < BLOCKS; j += ldpctool::SIMD_WIDTH) | ||||||
| 		{ | 		{ | ||||||
| @ -164,24 +166,31 @@ int main(int argc, char **argv) | |||||||
| 				for (int i = 0; i < CODE_LEN; ++i) | 				for (int i = 0; i < CODE_LEN; ++i) | ||||||
| 					reinterpret_cast<ldpctool::code_type *>(simd + i)[n] = code[(j + n) * CODE_LEN + i]; | 					reinterpret_cast<ldpctool::code_type *>(simd + i)[n] = code[(j + n) * CODE_LEN + i]; | ||||||
| 
 | 
 | ||||||
| 			int trials = max_trials; | 			int count = decode(simd, simd + DATA_LEN, max_trials, blocks); | ||||||
| 			int count = decode(simd, simd + DATA_LEN, trials, blocks); | 			num_decodes++; | ||||||
| 			++num_decodes; | 
 | ||||||
|  | 			if (count < 0) | ||||||
|  | 			{ | ||||||
|  | 				trials_count += max_trials; | ||||||
|  | 				max_count++; | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
|  | 				trials_count += max_trials - count; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (num_decodes == 20) | ||||||
|  | 			{ | ||||||
|  | 				fprintf(stderr, "ldpc_tool: trials: %d%% max: %d%% at converging to a code word\n", | ||||||
|  | 					(trials_count*100)/(num_decodes*max_trials), (max_count*100)/num_decodes); | ||||||
|  | 				trials_count = 0; | ||||||
|  | 				max_count = 0; | ||||||
|  | 				num_decodes = 0; | ||||||
|  | 			} | ||||||
| 
 | 
 | ||||||
| 			for (int n = 0; n < blocks; ++n) | 			for (int n = 0; n < blocks; ++n) | ||||||
| 				for (int i = 0; i < CODE_LEN; ++i) | 				for (int i = 0; i < CODE_LEN; ++i) | ||||||
| 					code[(j + n) * CODE_LEN + i] = reinterpret_cast<ldpctool::code_type *>(simd + i)[n]; | 					code[(j + n) * CODE_LEN + i] = reinterpret_cast<ldpctool::code_type *>(simd + i)[n]; | ||||||
| 
 |  | ||||||
| 			if (count < 0) |  | ||||||
| 			{ |  | ||||||
| 				iterations += blocks * trials; |  | ||||||
| 				std::cerr << "ldpc_tool: decoder failed at converging to a code word in " << trials << " trials" << std::endl; |  | ||||||
| 				break; |  | ||||||
| 			} |  | ||||||
| 			else |  | ||||||
| 			{ |  | ||||||
| 				iterations += blocks * (trials - count); |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for (int i = 0; i < BLOCKS * CODE_LEN; ++i) | 		for (int i = 0; i < BLOCKS * CODE_LEN; ++i) | ||||||
|  | |||||||
| @ -37,6 +37,8 @@ | |||||||
| #include "sdr.h" | #include "sdr.h" | ||||||
| 
 | 
 | ||||||
| #ifdef LINUX | #ifdef LINUX | ||||||
|  | #include <signal.h> | ||||||
|  | #include <sys/wait.h> | ||||||
| #include "ldpctool/layered_decoder.h" | #include "ldpctool/layered_decoder.h" | ||||||
| #include "ldpctool/testbench.h" | #include "ldpctool/testbench.h" | ||||||
| #include "ldpctool/algorithms.h" | #include "ldpctool/algorithms.h" | ||||||
| @ -2379,6 +2381,7 @@ struct s2_fecdec_helper : runnable | |||||||
|     ~s2_fecdec_helper() |     ~s2_fecdec_helper() | ||||||
|     { |     { | ||||||
|         free(command); |         free(command); | ||||||
|  |         killall(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void run() |     void run() | ||||||
| @ -2424,6 +2427,7 @@ struct s2_fecdec_helper : runnable | |||||||
|         int batch_size; // Latency
 |         int batch_size; // Latency
 | ||||||
|         int b_in;       // Jobs in input queue
 |         int b_in;       // Jobs in input queue
 | ||||||
|         int b_out;      // Jobs in output queue
 |         int b_out;      // Jobs in output queue
 | ||||||
|  |         int pid;        // PID of the child
 | ||||||
|     }; |     }; | ||||||
|     struct pool |     struct pool | ||||||
|     { |     { | ||||||
| @ -2451,10 +2455,13 @@ struct s2_fecdec_helper : runnable | |||||||
|             int nw = write(h->fd_tx, pin->bytes, iosize); |             int nw = write(h->fd_tx, pin->bytes, iosize); | ||||||
| 
 | 
 | ||||||
|             if (nw < 0 && errno == EWOULDBLOCK) |             if (nw < 0 && errno == EWOULDBLOCK) | ||||||
|  |             { | ||||||
|  |                 lseek(h->fd_tx, 0, SEEK_SET); // allow new writes on this worker
 | ||||||
|                 continue; // next worker
 |                 continue; // next worker
 | ||||||
|  |             } | ||||||
|             if (nw < 0) |             if (nw < 0) | ||||||
|                 fatal("write(LDPC helper"); |                 fatal("write(LDPC helper"); | ||||||
|             if (nw != iosize) |             else if (nw != iosize) | ||||||
|                 fatal("partial write(LDPC helper)"); |                 fatal("partial write(LDPC helper)"); | ||||||
| 
 | 
 | ||||||
|             helper_job *job = jobs.put(); |             helper_job *job = jobs.put(); | ||||||
| @ -2471,9 +2478,9 @@ struct s2_fecdec_helper : runnable | |||||||
|             return true; // done sent to worker
 |             return true; // done sent to worker
 | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         fprintf(stderr, "s2_fecdec_helper::send_frame: WARNING: all %d workers are busy: modcod=%d sf=%d)\n", |         fprintf(stderr, "s2_fecdec_helper::send_frame: WARNING: all %d workers were busy: modcod=%d sf=%d)\n", | ||||||
|             p->nprocs, pin->pls.modcod, pin->pls.sf); |             p->nprocs, pin->pls.modcod, pin->pls.sf); | ||||||
|         return false; // all workers are busy
 |         return false; // all workers were busy
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Return a pool of running helpers for a given modcod.
 |     // Return a pool of running helpers for a given modcod.
 | ||||||
| @ -2494,6 +2501,42 @@ struct s2_fecdec_helper : runnable | |||||||
|         return p; |         return p; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     void killall() | ||||||
|  |     { | ||||||
|  |         fprintf(stderr, "s2_fecdec_helper::killall\n"); | ||||||
|  | 
 | ||||||
|  |         for (int i = 0; i < 32; i++) // all MODCODs
 | ||||||
|  |         { | ||||||
|  |             for (int j = 0; j < 2; j++) // long and short frames
 | ||||||
|  |             { | ||||||
|  |                 pool *p = &pools[i][j]; | ||||||
|  | 
 | ||||||
|  |                 if (p->procs) | ||||||
|  |                 { | ||||||
|  |                     for (int i = 0; i < p->nprocs; ++i) | ||||||
|  |                     { | ||||||
|  |                         helper_instance *h = &p->procs[i]; | ||||||
|  |                         fprintf(stderr, "s2_fecdec_helper::killall: killing %d\n", h->pid); | ||||||
|  |                         int rc = kill(h->pid, SIGKILL); | ||||||
|  |                         if (rc < 0) { | ||||||
|  |                             fatal("s2_fecdec_helper::killall"); | ||||||
|  |                         } else { | ||||||
|  |                             int cs; | ||||||
|  |                             waitpid(h->pid, &cs, 0); | ||||||
|  |                         } | ||||||
|  |                         // reset pipes
 | ||||||
|  |                         lseek(h->fd_tx, 0, SEEK_SET); | ||||||
|  |                         lseek(h->fd_rx, 0, SEEK_SET); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     delete p->procs; | ||||||
|  |                     p->procs = nullptr; | ||||||
|  |                     p->nprocs = 0; | ||||||
|  |                 } | ||||||
|  |             } // long and short frames
 | ||||||
|  |         } // all MODCODs
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     // Spawn a helper process.
 |     // Spawn a helper process.
 | ||||||
|     void spawn_helper(helper_instance *h, const s2_pls *pls) |     void spawn_helper(helper_instance *h, const s2_pls *pls) | ||||||
|     { |     { | ||||||
| @ -2507,20 +2550,32 @@ struct s2_fecdec_helper : runnable | |||||||
| // macOS does not have F_SETPIPE_SZ and there
 | // macOS does not have F_SETPIPE_SZ and there
 | ||||||
| // is no way to change the buffer size
 | // is no way to change the buffer size
 | ||||||
| #ifndef __APPLE__ | #ifndef __APPLE__ | ||||||
|  |         long min_pipe_size = (long) fcntl(tx[0], F_GETPIPE_SZ); | ||||||
|  |         long pipe_size = (long) fcntl(rx[0], F_GETPIPE_SZ); | ||||||
|  |         min_pipe_size = std::min(min_pipe_size, pipe_size); | ||||||
|  |         pipe_size = (long) fcntl(tx[1], F_GETPIPE_SZ); | ||||||
|  |         min_pipe_size = std::min(min_pipe_size, pipe_size); | ||||||
|  |         pipe_size = (long) fcntl(rx[1], F_GETPIPE_SZ); | ||||||
|  |         min_pipe_size = std::min(min_pipe_size, pipe_size); | ||||||
|  | 
 | ||||||
|  |         if (min_pipe_size < pipesize) | ||||||
|  |         { | ||||||
|             if (fcntl(tx[0], F_SETPIPE_SZ, pipesize) < 0 || |             if (fcntl(tx[0], F_SETPIPE_SZ, pipesize) < 0 || | ||||||
|                 fcntl(rx[0], F_SETPIPE_SZ, pipesize) < 0 || |                 fcntl(rx[0], F_SETPIPE_SZ, pipesize) < 0 || | ||||||
|                 fcntl(tx[1], F_SETPIPE_SZ, pipesize) < 0 || |                 fcntl(tx[1], F_SETPIPE_SZ, pipesize) < 0 || | ||||||
|                 fcntl(rx[1], F_SETPIPE_SZ, pipesize) < 0) |                 fcntl(rx[1], F_SETPIPE_SZ, pipesize) < 0) | ||||||
|             { |             { | ||||||
|                 fprintf(stderr, |                 fprintf(stderr, | ||||||
|                     "*** Failed to increase pipe size.\n" |                         "*** Failed to increase pipe size from %ld.\n" | ||||||
|                         "*** Try echo %d > /proc/sys/fs/pipe-max-size\n", |                         "*** Try echo %d > /proc/sys/fs/pipe-max-size\n", | ||||||
|  |                         min_pipe_size, | ||||||
|                         pipesize); |                         pipesize); | ||||||
|                 if (must_buffer) |                 if (must_buffer) | ||||||
|                     fatal("F_SETPIPE_SZ"); |                     fatal("F_SETPIPE_SZ"); | ||||||
|                 else |                 else | ||||||
|                     fprintf(stderr, "*** Throughput will be suboptimal.\n"); |                     fprintf(stderr, "*** Throughput will be suboptimal.\n"); | ||||||
|             } |             } | ||||||
|  |         } | ||||||
| #endif | #endif | ||||||
|         // vfork() differs from fork(2) in that the calling thread is
 |         // vfork() differs from fork(2) in that the calling thread is
 | ||||||
|         // suspended until the child terminates
 |         // suspended until the child terminates
 | ||||||
| @ -2552,15 +2607,19 @@ struct s2_fecdec_helper : runnable | |||||||
|             fatal(command); |             fatal(command); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         h->pid = child; | ||||||
|         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 = batch_size; // 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_tx = fcntl(h->fd_tx, F_GETFL); | ||||||
|         if (fcntl(h->fd_tx, F_SETFL, flags | O_NONBLOCK)) |         if (fcntl(h->fd_tx, F_SETFL, flags_tx | O_NONBLOCK)) | ||||||
|             fatal("fcntl(helper)"); |             fatal("fcntl_tx(helper)"); | ||||||
|  |         int flags_rx = fcntl(h->fd_rx, F_GETFL); | ||||||
|  |         if (fcntl(h->fd_rx, F_SETFL, flags_rx | O_NONBLOCK)) | ||||||
|  |             fatal("fcntl_rx(helper)"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Receive a finished job.
 |     // Receive a finished job.
 | ||||||
| @ -2570,10 +2629,18 @@ struct s2_fecdec_helper : runnable | |||||||
|         const s2_pls *pls = &job->pls; |         const s2_pls *pls = &job->pls; | ||||||
|         int iosize = (pls->framebits() / 8) * sizeof(ldpc_buf[0]); |         int iosize = (pls->framebits() / 8) * sizeof(ldpc_buf[0]); | ||||||
|         int nr = read(job->h->fd_rx, ldpc_buf, iosize); |         int nr = read(job->h->fd_rx, ldpc_buf, iosize); | ||||||
|  | 
 | ||||||
|         if (nr < 0) |         if (nr < 0) | ||||||
|             fatal("read(LDPC helper)"); |         { | ||||||
|         if (nr != iosize) |             if (errno != EAGAIN) { // if no data then try again next time
 | ||||||
|             fatal("partial read(LDPC helper)"); |                 fatal("s2_fecdec_helper::receive_frame read error"); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else if (nr != iosize) | ||||||
|  |         { | ||||||
|  |             fprintf(stderr, "s2_fecdec_helper::receive_frame: %d bytes read vs %d", nr, iosize); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         --job->h->b_out; |         --job->h->b_out; | ||||||
|         // Decode BCH.
 |         // Decode BCH.
 | ||||||
|         const modcod_info *mcinfo = check_modcod(job->pls.modcod); |         const modcod_info *mcinfo = check_modcod(job->pls.modcod); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user