Ticket #1945: dvbdevtree_signalmonitor.patch

File dvbdevtree_signalmonitor.patch, 6.0 KB (added by yeasah@…, 19 years ago)

Signal monitor changes -- retuning and monitoring

  • libs/libmythtv/dvbsignalmonitor.h

     
    1010
    1111typedef QMap<uint,int> FilterMap;
    1212
     13#define RETUNE_TIMEOUT 5000
     14
    1315class DVBSignalMonitor: public DTVSignalMonitor
    1416{
    1517    Q_OBJECT
     
    3032    void StatusSignalToNoise(const SignalMonitorValue&);
    3133    void StatusBitErrorRate(const SignalMonitorValue&);
    3234    void StatusUncorrectedBlocks(const SignalMonitorValue&);
     35    void StatusRotorPosition(const SignalMonitorValue&);
    3336
    3437  protected:
    3538    DVBSignalMonitor(void);
     
    3841    virtual void UpdateValues(void);
    3942    void EmitDVBSignals(void);
    4043
     44    void RetuneMonitor(void);
    4145    static void *TableMonitorThread(void *param);
    4246    void RunTableMonitor(void);
    4347    void RunTableMonitorTS(void);
     
    5256    SignalMonitorValue signalToNoise;
    5357    SignalMonitorValue bitErrorRate;
    5458    SignalMonitorValue uncorrectedBlocks;
     59    SignalMonitorValue rotorPosition;
    5560
    5661    bool               useSectionReader;
    5762    bool               dtvMonitorRunning;
    5863    pthread_t          table_monitor_thread;
    5964
    6065    FilterMap          filters; ///< PID filters for table monitoring
     66
     67    bool               is_rotor_done;
    6168};
    6269
    6370#endif // DVBSIGNALMONITOR_H
  • libs/libmythtv/signalmonitor.h

     
    5555    kDVBSigMon_WaitForSNR = 0x01000000,
    5656    kDVBSigMon_WaitForBER = 0x02000000,
    5757    kDVBSigMon_WaitForUB  = 0x04000000,
     58    kDVBSigMon_WaitForPos = 0x08000000, ///< Wait for rotor
    5859};
    5960
    6061inline QString sm_flags_to_string(uint);
  • libs/libmythtv/dvbsignalmonitor.cpp

     
    1919
    2020#include "dvbchannel.h"
    2121#include "dvbrecorder.h"
     22#include "dvbdevtree.h"
    2223
    2324#undef DBG_SM
    2425#define DBG_SM(FUNC, MSG) VERBOSE(VB_CHANNEL, \
     
    5455                        65535,  false,     0, 65535, 0),
    5556      uncorrectedBlocks(tr("Uncorrected Blocks"), "ucb",
    5657                        65535,  false,     0, 65535, 0),
     58      rotorPosition    (tr("Rotor Progress"), "pos",
     59                        100,  true,      0, 100, 0),
    5760      useSectionReader(false),
    58       dtvMonitorRunning(false)
     61      dtvMonitorRunning(false),
     62      is_rotor_done(true)
    5963{
    6064    // These two values should probably come from the database...
    6165    int wait = 3000; // timeout when waiting on signal
     
    151155        list<<bitErrorRate.GetName()<<bitErrorRate.GetStatus();
    152156    if (HasFlags(kDVBSigMon_WaitForUB))
    153157        list<<uncorrectedBlocks.GetName()<<uncorrectedBlocks.GetStatus();
     158    if (HasFlags(kDVBSigMon_WaitForPos))
     159        list<<rotorPosition.GetName()<<rotorPosition.GetStatus();
    154160    statusLock.unlock();
    155161    return list;
    156162}
     
    332338    FD_SET (dvr_fd, &fd_select_set);
    333339    while (dtvMonitorRunning && GetStreamData())
    334340    {
     341        RetuneMonitor();
    335342        UpdateFiltersFromStreamData();
    336343
    337344        // timeout gets reset by select, so we need to create new one
     
    391398
    392399    while (dtvMonitorRunning && GetStreamData())
    393400    {
     401        RetuneMonitor();
    394402        UpdateFiltersFromStreamData();
    395403
    396404        bool readSomething = false;
     
    479487    return supports_ts;
    480488}
    481489
     490void DVBSignalMonitor::RetuneMonitor(void)
     491{
     492    DVBChannel* dvbchan = dynamic_cast<DVBChannel*>(channel);
     493    int fd_frontend = dvbchan->GetFd();
     494
     495    // Get lock status
     496    bool is_locked = true;
     497    fe_status_t status;
     498    if(ioctl(fd_frontend, FE_READ_STATUS, &status) != -1)
     499    {
     500        is_locked = (status & FE_HAS_LOCK);
     501        signalLock.SetValue(is_locked ? 1 : 0);
     502    }
     503
     504    // Rotor position
     505    const DVBDevRotor* rotor = dvbchan->GetRotor();
     506    if(rotor)
     507    {
     508        if(rotor->IsPositionKnown())
     509        {
     510            double progress = rotor->Progress();
     511            if(progress >= 1.0 && !is_rotor_done)
     512            {
     513                DBG_SM("UpdateValues", "Retuning for rotor completion");
     514                dvbchan->Retune();
     515                is_rotor_done = true;
     516            }
     517            else if(progress < 1.0)
     518            {
     519                if(is_rotor_done)
     520                    DBG_SM("UpdateValues", "Rotor is moving");
     521                is_rotor_done = false;
     522            }
     523
     524            if (HasFlags(kDVBSigMon_WaitForPos))
     525                rotorPosition.SetValue((int)(progress * 100));
     526        }
     527    }
     528    else if (HasFlags(kDVBSigMon_WaitForPos))
     529        rotorPosition.SetValue(100);
     530
     531    // Periodically retune if card can't recover
     532    if(!dvbchan->CanRecover() && !is_locked &&
     533       dvbchan->ElapsedSinceTune() > RETUNE_TIMEOUT)
     534    {
     535        DBG_SM("UpdateValues", "Retuning for lock loss");
     536        dvbchan->Retune();
     537    }
     538}
     539
    482540void DVBSignalMonitor::RunTableMonitor(void)
    483541{
    484542    dtvMonitorRunning = true;
     
    515573        return;
    516574    }
    517575
     576    RetuneMonitor();
     577
    518578    bool wasLocked = false, isLocked = false;
    519579    // We use uint16_t for sig & snr because this is correct for DVB API 4.0,
    520580    // and works better than the correct int16_t for the 3.x API
     
    569629    // Start table monitoring if we are waiting on any table
    570630    // and we have a lock.
    571631    if (isLocked && GetStreamData() &&
     632        (!HasFlags(kDVBSigMon_WaitForPos) || rotorPosition.IsGood()) &&
    572633        HasAnyFlag(kDTVSigMon_WaitForPAT | kDTVSigMon_WaitForPMT |
    573634                   kDTVSigMon_WaitForMGT | kDTVSigMon_WaitForVCT |
    574635                   kDTVSigMon_WaitForNIT | kDTVSigMon_WaitForSDT))
     
    605666        EMIT(StatusBitErrorRate, bitErrorRate);
    606667    if (HasFlags(kDVBSigMon_WaitForUB))
    607668        EMIT(StatusUncorrectedBlocks, uncorrectedBlocks);
     669    if (HasFlags(kDVBSigMon_WaitForPos))
     670        EMIT(StatusRotorPosition, rotorPosition);
    608671}
    609672
    610673#undef EMIT