X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Faccess%2Fdvb%2Flinux_dvb.c;h=b98fd3a6f086761e1efd09f544504381ec0c38a7;hb=6ee1e193fd896ab9a4729fde14f009d9ce629815;hp=a00256410aa95c406aee340c5db95934542d43e4;hpb=23f5aa0231d283ab2b320670983fb0e513270bcc;p=vlc diff --git a/modules/access/dvb/linux_dvb.c b/modules/access/dvb/linux_dvb.c index a00256410a..b98fd3a6f0 100644 --- a/modules/access/dvb/linux_dvb.c +++ b/modules/access/dvb/linux_dvb.c @@ -5,7 +5,7 @@ * * Authors: Damien Lucas * Johan Bilien - * Jean-Paul Saman + * Jean-Paul Saman * Christopher Ross * Christophe Massiot * @@ -25,8 +25,7 @@ *****************************************************************************/ #include -#include - +#include #include #include @@ -83,6 +82,7 @@ static int FrontendInfo( access_t * ); static int FrontendSetQPSK( access_t * ); static int FrontendSetQAM( access_t * ); static int FrontendSetOFDM( access_t * ); +static int FrontendSetATSC( access_t * ); /***************************************************************************** * FrontendOpen : Determine frontend device information and capabilities @@ -118,8 +118,8 @@ int E_(FrontendOpen)( access_t *p_access ) if( b_probe ) { - char * psz_expected = NULL; - char * psz_real; + const char * psz_expected = NULL; + const char * psz_real; if( FrontendInfo( p_access ) < 0 ) { @@ -139,6 +139,9 @@ int E_(FrontendOpen)( access_t *p_access ) case FE_QPSK: psz_real = "DVB-S"; break; + case FE_ATSC: + psz_real = "ATSC"; + break; default: psz_real = "unknown"; } @@ -164,6 +167,13 @@ int E_(FrontendOpen)( access_t *p_access ) psz_expected = "DVB-T"; } + if( (!strncmp( p_access->psz_access, "usdigital", 9 ) || + !strncmp( p_access->psz_access, "atsc", 4 ) ) && + (p_frontend->info.type != FE_ATSC) ) + { + psz_expected = "ATSC"; + } + if( psz_expected != NULL ) { msg_Err( p_access, "the user asked for %s, and the tuner is %s", @@ -188,6 +198,9 @@ int E_(FrontendOpen)( access_t *p_access ) else if( !strncmp( p_access->psz_access, "terrestrial", 11 ) || !strncmp( p_access->psz_access, "dvb-t", 5 ) ) p_frontend->info.type = FE_OFDM; + else if( !strncmp( p_access->psz_access, "usdigital", 9 ) || + !strncmp( p_access->psz_access, "atsc", 4 ) ) + p_frontend->info.type = FE_ATSC; } return VLC_SUCCESS; @@ -245,6 +258,15 @@ int E_(FrontendSet)( access_t *p_access ) } break; + /* ATSC */ + case FE_ATSC: + if( FrontendSetATSC( p_access ) < 0 ) + { + msg_Err( p_access, "ATSC: tuning failed" ); + return VLC_EGENERIC; + } + break; + default: msg_Err( p_access, "Could not determine frontend type on %s", p_sys->p_frontend->info.name ); @@ -312,7 +334,7 @@ void E_(FrontendPoll)( access_t *p_access ) IF_UP( FE_HAS_LOCK ) { - int32_t i_value; + int32_t i_value = 0; msg_Dbg( p_access, "frontend has acquired lock" ); p_sys->i_frontend_timeout = 0; @@ -434,7 +456,9 @@ void E_(FrontendStatus)( access_t *p_access ) CHECK_CAPS( CAN_HIERARCHY_AUTO ); CHECK_CAPS( CAN_MUTE_TS ); CHECK_CAPS( CAN_RECOVER ); +#if 0 /* Disabled because of older distributions */ CHECK_CAPS( CAN_CLEAN_SETUP ); +#endif #undef CHECK_CAPS p += sprintf( p, "

Current frontend status:\n" ); @@ -457,6 +481,8 @@ void E_(FrontendStatus)( access_t *p_access ) CHECK_STATUS( HAS_SYNC ); CHECK_STATUS( HAS_LOCK ); CHECK_STATUS( REINIT ); + if( i_status == 0 ) + p += sprintf( p, "\n" ); #undef CHECK_STATUS if ( i_status & FE_HAS_LOCK ) @@ -516,6 +542,9 @@ static int FrontendInfo( access_t *p_access ) case FE_OFDM: msg_Dbg( p_access, " type = OFDM (DVB-T)" ); break; + case FE_ATSC: + msg_Dbg( p_access, " type = ATSC (USA)" ); + break; #if 0 /* DVB_API_VERSION == 3 */ case FE_MEMORY: msg_Dbg(p_access, " type = MEMORY" ); @@ -595,6 +624,10 @@ static int FrontendInfo( access_t *p_access ) msg_Dbg(p_access, " card can mute TS"); if( p_frontend->info.caps & FE_CAN_RECOVER) msg_Dbg(p_access, " card can recover from a cable unplug"); + if( p_frontend->info.caps & FE_CAN_8VSB) + msg_Dbg(p_access, " card can do 8vsb"); + if( p_frontend->info.caps & FE_CAN_16VSB) + msg_Dbg(p_access, " card can do 16vsb"); msg_Dbg(p_access, "End of capability list"); return VLC_SUCCESS; @@ -651,28 +684,47 @@ static fe_code_rate_t DecodeFEC( access_t *p_access, int i_val ) return fe_fec; } -static fe_modulation_t DecodeModulation( access_t *p_access ) +static fe_modulation_t DecodeModulationQAM( access_t *p_access ) { - vlc_value_t val; - fe_modulation_t fe_modulation = 0; - - var_Get( p_access, "dvb-modulation", &val ); - - switch( val.i_int ) + switch( var_GetInteger( p_access, "dvb-modulation" ) ) { - case -1: fe_modulation = QPSK; break; - case 0: fe_modulation = QAM_AUTO; break; - case 16: fe_modulation = QAM_16; break; - case 32: fe_modulation = QAM_32; break; - case 64: fe_modulation = QAM_64; break; - case 128: fe_modulation = QAM_128; break; - case 256: fe_modulation = QAM_256; break; + case 0: return QAM_AUTO; + case 16: return QAM_16; + case 32: return QAM_32; + case 64: return QAM_64; + case 128: return QAM_128; + case 256: return QAM_256; default: - msg_Dbg( p_access, "terrestrial/cable dvb has constellation/modulation not set, using auto"); - fe_modulation = QAM_AUTO; - break; + msg_Dbg( p_access, "QAM modulation not set, using auto"); + return QAM_AUTO; + } +} +static fe_modulation_t DecodeModulationOFDM( access_t *p_access ) +{ + switch( var_GetInteger( p_access, "dvb-modulation" ) ) + { + case -1: return QPSK; + case 0: return QAM_AUTO; + case 16: return QAM_16; + case 32: return QAM_32; + case 64: return QAM_64; + case 128: return QAM_128; + case 256: return QAM_256; + default: + msg_Dbg( p_access, "OFDM modulation not set, using QAM auto"); + return QAM_AUTO; + } +} +static fe_modulation_t DecodeModulationATSC( access_t *p_access ) +{ + switch( var_GetInteger( p_access, "dvb-modulation" ) ) + { + case 8: return VSB_8; + case 16: return VSB_16; + default: + msg_Dbg( p_access, "ATSC modulation not set, using VSB 8"); + return VSB_8; } - return fe_modulation; } /***************************************************************************** @@ -969,7 +1021,7 @@ static int FrontendSetQAM( access_t *p_access ) var_Get( p_access, "dvb-fec", &val ); fep.u.qam.fec_inner = DecodeFEC( p_access, val.i_int ); - fep.u.qam.modulation = DecodeModulation( p_access ); + fep.u.qam.modulation = DecodeModulationQAM( p_access ); /* Empty the event queue */ for( ; ; ) @@ -1102,7 +1154,7 @@ static int FrontendSetOFDM( access_t * p_access ) fep.u.ofdm.code_rate_HP = DecodeFEC( p_access, val.i_int ); var_Get( p_access, "dvb-code-rate-lp", &val ); fep.u.ofdm.code_rate_LP = DecodeFEC( p_access, val.i_int ); - fep.u.ofdm.constellation = DecodeModulation( p_access ); + fep.u.ofdm.constellation = DecodeModulationOFDM( p_access ); fep.u.ofdm.transmission_mode = DecodeTransmission( p_access ); fep.u.ofdm.guard_interval = DecodeGuardInterval( p_access ); fep.u.ofdm.hierarchy_information = DecodeHierarchy( p_access ); @@ -1127,6 +1179,43 @@ static int FrontendSetOFDM( access_t * p_access ) return VLC_SUCCESS; } +/***************************************************************************** + * FrontendSetATSC : controls the FE device + *****************************************************************************/ +static int FrontendSetATSC( access_t *p_access ) +{ + access_sys_t *p_sys = p_access->p_sys; + struct dvb_frontend_parameters fep; + vlc_value_t val; + int i_ret; + + /* Prepare the fep structure */ + + var_Get( p_access, "dvb-frequency", &val ); + fep.frequency = val.i_int; + + fep.u.vsb.modulation = DecodeModulationATSC( p_access ); + + /* Empty the event queue */ + for( ; ; ) + { + struct dvb_frontend_event event; + if ( ioctl( p_sys->i_frontend_handle, FE_GET_EVENT, &event ) < 0 + && errno == EWOULDBLOCK ) + break; + } + + /* Now send it all to the frontend device */ + if( (i_ret = ioctl( p_sys->i_frontend_handle, FE_SET_FRONTEND, &fep )) < 0 ) + { + msg_Err( p_access, "ATSC: setting frontend failed (%d) %s", i_ret, + strerror(errno) ); + return VLC_EGENERIC; + } + + return VLC_SUCCESS; +} + /* * Demux @@ -1388,7 +1477,7 @@ int E_(CAMOpen)( access_t *p_access ) } /* Output CA capabilities */ - msg_Dbg( p_access, "CAMInit: CA interface with %d %s", caps.slot_num, + msg_Dbg( p_access, "CAMInit: CA interface with %d %s", caps.slot_num, caps.slot_num == 1 ? "slot" : "slots" ); if ( caps.slot_type & CA_CI ) msg_Dbg( p_access, "CAMInit: CI high level interface type" ); @@ -1418,10 +1507,16 @@ int E_(CAMOpen)( access_t *p_access ) return VLC_EGENERIC; } - p_sys->i_ca_type = caps.slot_type; - if ( !(caps.slot_type & CA_CI_LINK) && - !(caps.slot_type & CA_CI) ) + if( caps.slot_type & CA_CI_LINK ) { + p_sys->i_ca_type = CA_CI_LINK; + } + else if( caps.slot_type & CA_CI ) + { + p_sys->i_ca_type = CA_CI; + } + else { + p_sys->i_ca_type = -1; msg_Err( p_access, "CAMInit: incompatible CAM interface" ); close( p_sys->i_ca_handle ); p_sys->i_ca_handle = 0; @@ -1430,6 +1525,9 @@ int E_(CAMOpen)( access_t *p_access ) p_sys->i_nb_slots = caps.slot_num; memset( p_sys->pb_active_slot, 0, sizeof(vlc_bool_t) * MAX_CI_SLOTS ); + memset( p_sys->pb_slot_mmi_expected, 0, sizeof(vlc_bool_t) * MAX_CI_SLOTS ); + memset( p_sys->pb_slot_mmi_undisplayed, 0, + sizeof(vlc_bool_t) * MAX_CI_SLOTS ); return E_(en50221_Init)( p_access ); } @@ -1637,7 +1735,7 @@ void E_(CAMStatus)( access_t * p_access ) #define CHECK_TYPE( x, s ) \ if ( sinfo.type & (CA_##x) ) \ - p += sprintf( p, s ); + p += sprintf( p, "%s", s ); CHECK_TYPE( CI, "high level, " ); CHECK_TYPE( CI_LINK, "link layer level, " ); @@ -1729,8 +1827,9 @@ int E_(CAMSet)( access_t * p_access, dvbpsi_pmt_t *p_pmt ) { access_sys_t *p_sys = p_access->p_sys; - if ( p_sys->i_ca_handle == 0 ) + if( p_sys->i_ca_handle == 0 ) { + dvbpsi_DeletePMT( p_pmt ); return VLC_EGENERIC; }
Tuning failed