Ticket #2101: remove_RunTableMonitorTS.diff

File remove_RunTableMonitorTS.diff, 11.3 KB (added by Janne <janne-mythtv@…>, 15 years ago)
  • libs/libmythtv/dvbsignalmonitor.cpp

    old new DVBSignalMonitor::DVBSignalMonitor(int d 
    5757                        65535,  false,     0, 65535, 0),
    5858      rotorPosition    (tr("Rotor Progress"),     "pos",
    5959                        100,    true,      0,   100, 0),
    60       useSectionReader(false),
    6160      dtvMonitorRunning(false)
    6261{
    6362    // These two values should probably come from the database...
    bool DVBSignalMonitor::AddPIDFilter(uint 
    190189        return false;
    191190    }
    192191
    193     if (!useSectionReader)
    194     {
    195         struct dmx_pes_filter_params pesFilterParams;
    196         bzero(&pesFilterParams, sizeof(struct dmx_pes_filter_params));
    197         pesFilterParams.pid      = (__u16) pid;
    198         pesFilterParams.input    = DMX_IN_FRONTEND;
    199         pesFilterParams.output   = DMX_OUT_TS_TAP;
    200         pesFilterParams.flags    = DMX_IMMEDIATE_START;
    201         pesFilterParams.pes_type = DMX_PES_OTHER;
    202 
    203         if (ioctl(mux_fd, DMX_SET_PES_FILTER, &pesFilterParams) < 0)
    204         {
    205             VERBOSE(VB_IMPORTANT, LOC_ERR +
    206                     QString("Failed to set TS filter (pid %1)").arg(pid));
    207             close(mux_fd);
    208             return false;
    209         }
    210     }
    211     else
    212     {
    213         struct dmx_sct_filter_params sctFilterParams;
    214         bzero(&sctFilterParams, sizeof(struct dmx_sct_filter_params));
     192    struct dmx_sct_filter_params sctFilterParams;
     193    bzero(&sctFilterParams, sizeof(struct dmx_sct_filter_params));
    215194
    216         sctFilterParams.filter.mask[0]   = 0xff; // default
     195    sctFilterParams.filter.mask[0]   = 0xff; // default
    217196
    218         switch ( (__u16) pid )
    219         {
    220             case 0x0: // PAT
    221                 sctFilterParams.filter.filter[0] = 0;
    222                 break;
    223             case 0x0010: // assume this is for an NIT
    224                 // With this filter we can only ever get NIT for this network
    225                 // because other networks nit need a filter of 0x41
    226                 sctFilterParams.filter.filter[0] = 0x40;
    227                 break;
    228             case 0x0011: // assume this is for an SDT
    229                 sctFilterParams.filter.filter[0] = 0x42;
    230                 break;
    231             case 0x1ffb: // assume this is for a MGT or VCT
    232                 // MGT 0xc7, terrestrial VCT 0xc8, cable VCT 0xc9
    233                 sctFilterParams.filter.filter[0] = 0xc0;
    234                 sctFilterParams.filter.mask[0]   = 0xf0;
    235             default: // otherwise assume we are looking for a PMT or EIT
    236                 sctFilterParams.filter.filter[0] = 0x00;
    237                 sctFilterParams.filter.mask[0]   = 0x00;
    238                 break;
    239         }
    240         sctFilterParams.pid            = (__u16) pid;
    241         sctFilterParams.timeout        = 0;
    242         sctFilterParams.flags          = DMX_IMMEDIATE_START;
    243 
    244         if (ioctl(mux_fd, DMX_SET_FILTER, &sctFilterParams) < 0)
    245         {
    246             VERBOSE(VB_IMPORTANT, LOC_ERR +
    247                     "Failed to set \"section\" filter " +
    248                     QString("(pid %1) (filter %2)").arg(pid)
    249                     .arg(sctFilterParams.filter.filter[0]));
    250             close(mux_fd);
    251             return false;
    252         }
     197    switch ( (__u16) pid )
     198    {
     199        case 0x0: // PAT
     200            sctFilterParams.filter.filter[0] = 0;
     201            break;
     202        case 0x0010: // assume this is for an NIT
     203            // With this filter we can only ever get NIT for this network
     204            // because other networks nit need a filter of 0x41
     205            sctFilterParams.filter.filter[0] = 0x40;
     206            break;
     207        case 0x0011: // assume this is for an SDT
     208            sctFilterParams.filter.filter[0] = 0x42;
     209            break;
     210        case 0x1ffb: // assume this is for a MGT or VCT
     211            // MGT 0xc7, terrestrial VCT 0xc8, cable VCT 0xc9
     212            sctFilterParams.filter.filter[0] = 0xc0;
     213            sctFilterParams.filter.mask[0]   = 0xf0;
     214        default: // otherwise assume we are looking for a PMT or EIT
     215            sctFilterParams.filter.filter[0] = 0x00;
     216            sctFilterParams.filter.mask[0]   = 0x00;
     217            break;
     218    }
     219    sctFilterParams.pid            = (__u16) pid;
     220    sctFilterParams.timeout        = 0;
     221    sctFilterParams.flags          = DMX_IMMEDIATE_START;
     222
     223    if (ioctl(mux_fd, DMX_SET_FILTER, &sctFilterParams) < 0)
     224    {
     225        VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to set \"section\" filter " +
     226                QString("(pid %1) (filter %2)").arg(pid)
     227                .arg(sctFilterParams.filter.filter[0]));
     228        close(mux_fd);
     229        return false;
    253230    }
    254231
    255232    filters[pid] = mux_fd;
    bool DVBSignalMonitor::UpdateFiltersFrom 
    309286    return ok;
    310287}
    311288
    312 /** \fn DVBSignalMonitor::RunTableMonitorTS(void)
    313  *  \brief Uses TS filtering monitor to monitor a DVB device for tables
     289/** \fn DVBSignalMonitor::RunTableMonitor(void)
     290 *  \brief Uses "Section reader" to monitor a DVB device for tables
    314291 *
    315  *  This supports all types of MPEG based stream data, but is extreemely
    316  *  slow with DVB over USB 1.0 devices which for efficiency reasons buffer
    317  *  a stream until a full block transfer buffer full of the requested
    318  *  tables is available. This takes a very long time when you are just
    319  *  waiting for a PAT or PMT table, and the buffer is hundreds of packets
    320  *  in size.
    321292 */
    322 void DVBSignalMonitor::RunTableMonitorTS(void)
     293void DVBSignalMonitor::RunTableMonitor(void)
    323294{
    324     int remainder = 0;
    325     int buffer_size = TSPacket::SIZE * 15000;
    326     unsigned char *buffer = new unsigned char[buffer_size];
    327     if (!buffer)
    328         return;
    329     bzero(buffer, buffer_size);
    330 
    331     QString dvr_fname = CardUtil::GetDeviceName(DVB_DEV_DVR, GetDVBCardNum());
    332     int dvr_fd = open(dvr_fname.ascii(), O_RDONLY | O_NONBLOCK);
    333     if (dvr_fd < 0)
    334     {
    335         VERBOSE(VB_IMPORTANT, LOC +
    336                 QString("Failed to open DVR device %1 : %2")
    337                 .arg(dvr_fname).arg(strerror(errno)));
    338         delete[] buffer;
    339         return;
    340     }
    341 
    342     VERBOSE(VB_CHANNEL, LOC + "RunTableMonitorTS(): " +
    343             QString("begin (# of pids %1)")
    344             .arg(GetStreamData()->ListeningPIDs().size()));
    345 
    346     fd_set fd_select_set;
    347     FD_ZERO(        &fd_select_set);
    348     FD_SET (dvr_fd, &fd_select_set);
    349     while (dtvMonitorRunning && GetStreamData())
    350     {
    351         RetuneMonitor();
    352         UpdateFiltersFromStreamData();
    353 
    354         // timeout gets reset by select, so we need to create new one
    355         struct timeval timeout = { 0, 50 /* ms */ * 1000 /* -> usec */ };
    356         select(dvr_fd+1, &fd_select_set, NULL, NULL, &timeout);
    357 
    358         long long len = read(
    359             dvr_fd, &(buffer[remainder]), buffer_size - remainder);
    360 
    361         if ((0 == len) || (-1 == len))
    362         {
    363             usleep(100);
    364             continue;
    365         }
    366 
    367         len += remainder;
    368 
    369         if (len < 10) // 10 bytes = 4 bytes TS header + 6 bytes PES header
    370         {
    371             remainder = len;
    372             continue;
    373         }
    374 
    375         remainder = GetStreamData()->ProcessData(buffer, len);
    376         if (remainder > 0 && (len > remainder)) // leftover bytes
    377             memmove(buffer, &(buffer[len - remainder]), remainder);
    378     }
    379     VERBOSE(VB_CHANNEL, LOC + "RunTableMonitorTS(): " + "shutdown");
    380 
    381     if (GetStreamData())
    382     {
    383         vector<int> del_pids;
    384         FilterMap::iterator it = filters.begin();
    385         for (; it != filters.end(); ++it)
    386             del_pids.push_back(it.key());
    387 
    388         vector<int>::iterator dit = del_pids.begin();
    389         for (; dit != del_pids.end(); ++dit)
    390             RemovePIDFilter(*dit);
    391     }
    392 
    393     close(dvr_fd);
    394     delete[] buffer;
    395 
    396     VERBOSE(VB_CHANNEL, LOC + "RunTableMonitorTS(): " + "end");
    397 }
     295    dtvMonitorRunning = true;
    398296
    399 /** \fn DVBSignalMonitor::RunTableMonitorSR(void)
    400  *  \brief Uses "Section" monitor to monitor a DVB device for tables
    401  *
    402  *  This currently only supports DVB streams, ATSC and the raw MPEG
    403  *  streams used by some cable and satelite providers is not supported.
    404  */
    405 void DVBSignalMonitor::RunTableMonitorSR(void)
    406 {
    407297    int buffer_size = 4192;  // maximum size of Section we handle
    408298    unsigned char *buffer = new unsigned char[buffer_size];
    409299    if (!buffer)
    void DVBSignalMonitor::RunTableMonitorSR 
    457347    VERBOSE(VB_CHANNEL, LOC + "RunTableMonitorSR(): " + "end");
    458348}
    459349
    460 // for caching TS monitoring supported value.
    461 static QMap<uint,bool> _rec_supports_ts_monitoring;
    462 static QMutex          _rec_supports_ts_monitoring_lock;
    463 
    464 /** \fn DVBSignalMonitor::SupportsTSMonitoring(void)
    465  *  \brief Returns true if TS monitoring is supported.
    466  *
    467  *   NOTE: If you are using a DEC2000-t device you need to
    468  *   apply the patches provided by Peter Beutner for it, see
    469  *   http://www.gossamer-threads.com/lists/mythtv/dev/166172
    470  *   These patches should make it in to Linux 2.6.15 or 2.6.16.
    471  */
    472 bool DVBSignalMonitor::SupportsTSMonitoring(void)
    473 {
    474     const uint pat_pid = 0x0;
    475 
    476     {
    477         QMutexLocker locker(&_rec_supports_ts_monitoring_lock);
    478         QMap<uint,bool>::const_iterator it;
    479         it = _rec_supports_ts_monitoring.find(GetDVBCardNum());
    480         if (it != _rec_supports_ts_monitoring.end())
    481             return *it;
    482     }
    483 
    484     QString dvr_fname = CardUtil::GetDeviceName(DVB_DEV_DVR, GetDVBCardNum());
    485     int dvr_fd = open(dvr_fname.ascii(), O_RDONLY | O_NONBLOCK);
    486     if (dvr_fd < 0)
    487     {
    488         QMutexLocker locker(&_rec_supports_ts_monitoring_lock);
    489         _rec_supports_ts_monitoring[GetDVBCardNum()] = false;
    490         return false;
    491     }
    492 
    493     bool supports_ts = false;
    494     if (AddPIDFilter(pat_pid))
    495     {
    496         supports_ts = true;
    497         RemovePIDFilter(pat_pid);
    498     }
    499 
    500     close(dvr_fd);
    501 
    502     QMutexLocker locker(&_rec_supports_ts_monitoring_lock);
    503     _rec_supports_ts_monitoring[GetDVBCardNum()] = supports_ts;
    504     return supports_ts;
    505 }
    506 
    507350void DVBSignalMonitor::RetuneMonitor(void)
    508351{
    509352    DVBChannel *dvbchan = dynamic_cast<DVBChannel*>(channel);
    void DVBSignalMonitor::RetuneMonitor(voi 
    542385    }
    543386}
    544387
    545 void DVBSignalMonitor::RunTableMonitor(void)
    546 {
    547     dtvMonitorRunning = true;
    548 
    549     if (useSectionReader = !SupportsTSMonitoring())
    550         RunTableMonitorSR();
    551     else
    552         RunTableMonitorTS();
    553 }
    554 
    555388/** \fn DVBSignalMonitor::UpdateValues()
    556389 *  \brief Fills in frontend stats and emits status Qt signals.
    557390 *
  • libs/libmythtv/dvbsignalmonitor.h

    old new class DVBSignalMonitor: public DTVSignal 
    4646    void RetuneMonitor(void);
    4747    static void *TableMonitorThread(void *param);
    4848    void RunTableMonitor(void);
    49     void RunTableMonitorTS(void);
    50     void RunTableMonitorSR(void);
    5149    bool AddPIDFilter(uint pid);
    5250    bool RemovePIDFilter(uint pid);
    5351
    5452    int GetDVBCardNum(void) const;
    5553
    56     bool SupportsTSMonitoring(void);
    5754  protected:
    5855    SignalMonitorValue signalToNoise;
    5956    SignalMonitorValue bitErrorRate;
    6057    SignalMonitorValue uncorrectedBlocks;
    6158    SignalMonitorValue rotorPosition;
    6259
    63     bool               useSectionReader;
    6460    bool               dtvMonitorRunning;
    6561    pthread_t          table_monitor_thread;
    6662