Commit 4b814975 authored by Christophe Massiot's avatar Christophe Massiot

* demux.c: Implement a new watchdog mechanism (too many transport errors =>...

* demux.c: Implement a new watchdog mechanism (too many transport errors => tune again); fixed a filtering bug when the PCR PID changes in a PMT; * dvb.c: Implement a new watchdog mechanism (no DVR input => tune again); replaced tabs with spaces because it didn't look good in syslog.
parent 71f5b5d4
...@@ -77,6 +77,8 @@ static dvbpsi_handle p_eit_dvbpsi_handle; ...@@ -77,6 +77,8 @@ static dvbpsi_handle p_eit_dvbpsi_handle;
static dvbpsi_pat_t *p_current_pat = NULL; static dvbpsi_pat_t *p_current_pat = NULL;
static dvbpsi_sdt_t *p_current_sdt = NULL; static dvbpsi_sdt_t *p_current_sdt = NULL;
static int i_demux_fd; static int i_demux_fd;
static int i_nb_errors = 0;
static mtime_t i_last_error = 0;
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
...@@ -183,7 +185,21 @@ static void demux_Handle( block_t *p_ts ) ...@@ -183,7 +185,21 @@ static void demux_Handle( block_t *p_ts )
p_pids[i_pid].i_last_cc = i_cc; p_pids[i_pid].i_last_cc = i_cc;
if ( block_HasTransportError( p_ts ) ) if ( block_HasTransportError( p_ts ) )
{
msg_Warn( NULL, "transport_error_indicator" ); msg_Warn( NULL, "transport_error_indicator" );
i_nb_errors++;
i_last_error = i_wallclock;
}
else if ( i_wallclock > i_last_error + WATCHDOG_WAIT )
i_nb_errors = 0;
if ( i_nb_errors > MAX_ERRORS )
{
i_nb_errors = 0;
msg_Warn( NULL,
"too many transport errors, tuning again" );
dvb_Reset();
}
if ( p_pids[i_pid].i_refcount ) if ( p_pids[i_pid].i_refcount )
{ {
...@@ -1301,9 +1317,21 @@ static void PMTCallback( void *_unused, dvbpsi_pmt_t *p_pmt ) ...@@ -1301,9 +1317,21 @@ static void PMTCallback( void *_unused, dvbpsi_pmt_t *p_pmt )
if ( p_current_pmt != NULL ) if ( p_current_pmt != NULL )
{ {
if ( p_current_pmt->i_pcr_pid != p_pmt->i_pcr_pid if ( p_current_pmt->i_pcr_pid != p_pmt->i_pcr_pid
&& p_current_pmt->i_pcr_pid != PADDING_PID && p_current_pmt->i_pcr_pid != PADDING_PID )
&& p_current_pmt->i_pcr_pid != pp_sids[i_pmt]->i_pmt_pid ) {
UnselectPID( p_pmt->i_program_number, p_current_pmt->i_pcr_pid ); for( p_es = p_pmt->p_first_es; p_es != NULL;
p_es = p_es->p_next )
if ( p_es->i_pid == p_current_pmt->i_pcr_pid )
break;
if ( p_es == NULL )
{
msg_Dbg( NULL, " * removed pcr pid=%d",
p_current_pmt->i_pcr_pid );
UnselectPID( p_pmt->i_program_number,
p_current_pmt->i_pcr_pid );
}
}
for( p_current_es = p_current_pmt->p_first_es; p_current_es != NULL; for( p_current_es = p_current_pmt->p_first_es; p_current_es != NULL;
p_current_es = p_current_es->p_next ) p_current_es = p_current_es->p_next )
......
...@@ -51,12 +51,14 @@ ...@@ -51,12 +51,14 @@
* Local declarations * Local declarations
*****************************************************************************/ *****************************************************************************/
#define FRONTEND_LOCK_TIMEOUT 30000000 /* 30 s */ #define FRONTEND_LOCK_TIMEOUT 30000000 /* 30 s */
#define DVR_READ_TIMEOUT 30000000 /* 30 s */
#define MAX_READ_ONCE 50 #define MAX_READ_ONCE 50
#define DVR_BUFFER_SIZE 40*188*1024 /* bytes */ #define DVR_BUFFER_SIZE 40*188*1024 /* bytes */
static int i_frontend, i_dvr; static int i_frontend, i_dvr;
static fe_status_t i_last_status; static fe_status_t i_last_status;
static mtime_t i_frontend_timeout; static mtime_t i_frontend_timeout;
static mtime_t i_last_packet;
static mtime_t i_ca_next_event = 0; static mtime_t i_ca_next_event = 0;
static block_t *p_freelist = NULL; static block_t *p_freelist = NULL;
mtime_t i_ca_timeout = 0; mtime_t i_ca_timeout = 0;
...@@ -106,6 +108,14 @@ void dvb_Open( void ) ...@@ -106,6 +108,14 @@ void dvb_Open( void )
i_ca_next_event = mdate() + i_ca_timeout; i_ca_next_event = mdate() + i_ca_timeout;
} }
/*****************************************************************************
* dvb_Reset
*****************************************************************************/
void dvb_Reset( void )
{
FrontendSet();
}
/***************************************************************************** /*****************************************************************************
* dvb_Read * dvb_Read
*****************************************************************************/ *****************************************************************************/
...@@ -113,6 +123,8 @@ block_t *dvb_Read( void ) ...@@ -113,6 +123,8 @@ block_t *dvb_Read( void )
{ {
struct pollfd ufds[3]; struct pollfd ufds[3];
int i_ret, i_nb_fd = 2; int i_ret, i_nb_fd = 2;
mtime_t i_wallclock;
block_t *p_blocks = NULL;
memset( ufds, 0, sizeof(ufds) ); memset( ufds, 0, sizeof(ufds) );
ufds[0].fd = i_dvr; ufds[0].fd = i_dvr;
...@@ -135,17 +147,31 @@ block_t *dvb_Read( void ) ...@@ -135,17 +147,31 @@ block_t *dvb_Read( void )
return NULL; return NULL;
} }
if ( ufds[0].revents )
p_blocks = DVRRead();
i_wallclock = mdate();
if ( p_blocks != NULL )
i_last_packet = i_wallclock;
else if ( !i_frontend_timeout
&& i_wallclock > i_last_packet + DVR_READ_TIMEOUT )
{
msg_Warn( NULL, "no DVR output, tuning again" );
FrontendSet();
}
if ( i_ca_handle && i_ca_type == CA_CI_LINK if ( i_ca_handle && i_ca_type == CA_CI_LINK
&& mdate() > i_ca_next_event ) && i_wallclock > i_ca_next_event )
{ {
en50221_Poll(); en50221_Poll();
i_ca_next_event = mdate() + i_ca_timeout; i_wallclock = mdate();
i_ca_next_event = i_wallclock + i_ca_timeout;
} }
if ( ufds[1].revents ) if ( ufds[1].revents )
FrontendPoll(); FrontendPoll();
if ( i_frontend_timeout && mdate() > i_frontend_timeout ) if ( i_frontend_timeout && i_wallclock > i_frontend_timeout )
{ {
msg_Warn( NULL, "no lock, tuning again" ); msg_Warn( NULL, "no lock, tuning again" );
FrontendSet(); FrontendSet();
...@@ -154,10 +180,7 @@ block_t *dvb_Read( void ) ...@@ -154,10 +180,7 @@ block_t *dvb_Read( void )
if ( i_comm_fd != -1 && ufds[2].revents ) if ( i_comm_fd != -1 && ufds[2].revents )
comm_Read(); comm_Read();
if ( ufds[0].revents ) return p_blocks;
return DVRRead();
return NULL;
} }
/***************************************************************************** /*****************************************************************************
...@@ -315,6 +338,7 @@ static void FrontendPoll( void ) ...@@ -315,6 +338,7 @@ static void FrontendPoll( void )
int32_t i_value = 0; int32_t i_value = 0;
msg_Dbg( NULL, "frontend has acquired lock" ); msg_Dbg( NULL, "frontend has acquired lock" );
i_frontend_timeout = 0; i_frontend_timeout = 0;
i_last_packet = mdate();
/* Read some statistics */ /* Read some statistics */
if( ioctl( i_frontend, FE_READ_BER, &i_value ) >= 0 ) if( ioctl( i_frontend, FE_READ_BER, &i_value ) >= 0 )
...@@ -561,16 +585,16 @@ static void FrontendInfo( struct dvb_frontend_info info ) ...@@ -561,16 +585,16 @@ static void FrontendInfo( struct dvb_frontend_info info )
{ {
msg_Dbg( NULL, "Frontend \"%s\" type \"%s\" supports:", msg_Dbg( NULL, "Frontend \"%s\" type \"%s\" supports:",
info.name, GetFrontendTypeName(info.type) ); info.name, GetFrontendTypeName(info.type) );
msg_Dbg( NULL, "\tfrequency min: %d, max: %d, stepsize: %d, tolerance: %d", msg_Dbg( NULL, " frequency min: %d, max: %d, stepsize: %d, tolerance: %d",
info.frequency_min, info.frequency_max, info.frequency_min, info.frequency_max,
info.frequency_stepsize, info.frequency_tolerance ); info.frequency_stepsize, info.frequency_tolerance );
msg_Dbg( NULL, "\tsymbolrate min: %d, max: %d, tolerance: %d", msg_Dbg( NULL, " symbolrate min: %d, max: %d, tolerance: %d",
info.symbol_rate_min, info.symbol_rate_max, info.symbol_rate_tolerance); info.symbol_rate_min, info.symbol_rate_max, info.symbol_rate_tolerance);
msg_Dbg( NULL, "\tcapabilities:" ); msg_Dbg( NULL, " capabilities:" );
#define FRONTEND_INFO(caps,val,msg) \ #define FRONTEND_INFO(caps,val,msg) \
if ( caps & val ) \ if ( caps & val ) \
msg_Dbg( NULL, "\t\t%s", msg ); msg_Dbg( NULL, " %s", msg );
FRONTEND_INFO( info.caps, FE_IS_STUPID, "FE_IS_STUPID" ) FRONTEND_INFO( info.caps, FE_IS_STUPID, "FE_IS_STUPID" )
FRONTEND_INFO( info.caps, FE_CAN_INVERSION_AUTO, "INVERSION_AUTO" ) FRONTEND_INFO( info.caps, FE_CAN_INVERSION_AUTO, "INVERSION_AUTO" )
......
...@@ -158,6 +158,7 @@ void msleep( mtime_t delay ); ...@@ -158,6 +158,7 @@ void msleep( mtime_t delay );
void hexDump( uint8_t *p_data, uint32_t i_len ); void hexDump( uint8_t *p_data, uint32_t i_len );
void dvb_Open( void ); void dvb_Open( void );
void dvb_Reset( void );
block_t * dvb_Read( void ); block_t * dvb_Read( void );
int dvb_SetFilter( uint16_t i_pid ); int dvb_SetFilter( uint16_t i_pid );
void dvb_UnsetFilter( int i_fd, uint16_t i_pid ); void dvb_UnsetFilter( int i_fd, uint16_t i_pid );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment