diff --git a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c index d7b01b00..b6e017d4 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c @@ -454,6 +454,8 @@ linuxdvb_frontend_monitor ( void *aux ) mpegts_pid_t *mp; fe_status_t fe_status; signal_state_t status; + struct dtv_property fe_properties[6]; + struct dtv_properties dtv_prop; lfe->mi_display_name((mpegts_input_t*)lfe, buf, sizeof(buf)); tvhtrace("linuxdvb", "%s - checking FE status", buf); @@ -536,14 +538,69 @@ linuxdvb_frontend_monitor ( void *aux ) } /* Statistics */ - if (!ioctl(lfe->lfe_fe_fd, FE_READ_SIGNAL_STRENGTH, &u16)) - mmi->mmi_stats.signal = u16; - if (!ioctl(lfe->lfe_fe_fd, FE_READ_BER, &u32)) - mmi->mmi_stats.ber = u32; - if (!ioctl(lfe->lfe_fe_fd, FE_READ_SNR, &u16)) - mmi->mmi_stats.snr = u16; - if (!ioctl(lfe->lfe_fe_fd, FE_READ_UNCORRECTED_BLOCKS, &u32)) - mmi->mmi_stats.unc = u32; + /* try the v5 API first */ + fe_properties[0].cmd = DTV_STAT_SIGNAL_STRENGTH; + /* BER */ + fe_properties[1].cmd = DTV_STAT_PRE_ERROR_BIT_COUNT; + fe_properties[2].cmd = DTV_STAT_PRE_TOTAL_BIT_COUNT; + fe_properties[3].cmd = DTV_STAT_CNR; + /* PER */ + fe_properties[4].cmd = DTV_STAT_ERROR_BLOCK_COUNT; + fe_properties[5].cmd = DTV_STAT_TOTAL_BLOCK_COUNT; + dtv_prop.num = 6; + dtv_prop.props = fe_properties; + + if(!ioctl(lfe->lfe_fe_fd, FE_GET_PROPERTY, &dtv_prop)) { + /* use v5 API */ + if(fe_properties[0].u.st.len > 0) { + if(fe_properties[0].u.st.stat[0].scale == FE_SCALE_RELATIVE) + mmi->mmi_stats.signal = (fe_properties[0].u.st.stat[0].uvalue * 100) / 0xffff; + /* TODO: handle other scales */ + } + /* Calculate BER from PRE_ERROR and TOTAL_BIT_COUNT */ + if(fe_properties[1].u.st.len > 0) { + if(fe_properties[1].u.st.stat[0].scale == FE_SCALE_COUNTER) + u16 = fe_properties[1].u.st.stat[0].uvalue; + } + if(fe_properties[2].u.st.len > 0) { + if(fe_properties[2].u.st.stat[0].scale == FE_SCALE_COUNTER) { + if(fe_properties[2].u.st.stat[0].uvalue > 0 ) + mmi->mmi_stats.ber = u16 / fe_properties[2].u.st.stat[0].uvalue; + else + mmi->mmi_stats.ber = 0; + } + } + if(fe_properties[3].u.st.len > 0) { + /* note that decibel scale means 1 = 0.0001 dB units here */ + if(fe_properties[3].u.st.stat[0].scale == FE_SCALE_DECIBEL) + mmi->mmi_stats.snr = fe_properties[3].u.st.stat[0].svalue * 0.0001; + /* TODO: handle other scales */ + } + /* Calculate PER from PRE_ERROR and TOTAL_BIT_COUNT */ + if(fe_properties[4].u.st.len > 0) { + if(fe_properties[4].u.st.stat[0].scale == FE_SCALE_COUNTER) + u16 = fe_properties[4].u.st.stat[0].uvalue; + } + if(fe_properties[5].u.st.len > 0) { + if(fe_properties[5].u.st.stat[0].scale == FE_SCALE_COUNTER) { + if(fe_properties[5].u.st.stat[0].uvalue > 0 ) + mmi->mmi_stats.unc = u16 / fe_properties[5].u.st.stat[0].uvalue; + else + mmi->mmi_stats.unc = 0; + } + } + } else { + /* use old v3 API */ + if (!ioctl(lfe->lfe_fe_fd, FE_READ_SIGNAL_STRENGTH, &u16)) + mmi->mmi_stats.signal = u16; + if (!ioctl(lfe->lfe_fe_fd, FE_READ_BER, &u32)) + mmi->mmi_stats.ber = u32; + if (!ioctl(lfe->lfe_fe_fd, FE_READ_SNR, &u16)) + mmi->mmi_stats.snr = u16; + if (!ioctl(lfe->lfe_fe_fd, FE_READ_UNCORRECTED_BLOCKS, &u32)) + mmi->mmi_stats.unc = u32; + } + } static void *