All pastes #46382 Raw Edit

r9417+base+eit limit

public cpp v1 · immutable
#46382 ·published 2006-03-20 21:52 UTC
rendered paste body
Index: libs/libmythtv/dvbrecorder.cpp===================================================================--- libs/libmythtv/dvbrecorder.cpp      (revision 9417)+++ libs/libmythtv/dvbrecorder.cpp      (working copy)@@ -703,7 +703,7 @@     PIDInfo *info = _pid_infos[pid];     if (!info)        info = _pid_infos[pid] = new PIDInfo();-+/*     // track scrambled pids     if (tspacket.ScramplingControl())     {@@ -721,7 +721,7 @@                 QString("PID 0x%1 is no longer encrypted").arg(pid,0,16));         info->isEncrypted = false;     }-+*/     // Check continuity counter     if (tspacket.HasPayload())     {Index: libs/libmythtv/dbcheck.cpp===================================================================--- libs/libmythtv/dbcheck.cpp  (revision 9417)+++ libs/libmythtv/dbcheck.cpp  (working copy)@@ -12,11 +12,18 @@ /// This is the DB schema version expected by the running MythTV instance. const QString currentDatabaseVersion = "1132"; +/// This is the DB schema minor version used by supplementary patches                 +const QString currentDatabaseVersionMinor = "2";+ static bool UpdateDBVersionNumber(const QString &newnumber);+static bool UpdateDBVersionMinor( const QString &newminor); static bool performActualUpdate(const QString updates[], QString version,                                 QString &dbver);+static bool performMinorUpdate(const QString updates[], QString minor,+                                QString &dbminor); static bool InitializeDatabase(void); static bool doUpgradeTVDatabaseSchema(void);+static bool dbMinorUpdate(void);  /** \defgroup db_schema MythTV Database Schema @@ -352,6 +359,48 @@     return true; } +static bool UpdateDBVersionMinor(const QString &newminor)+{+    // delete old schema version+    MSqlQuery query(MSqlQuery::InitCon());     +   +    QString thequery = "DELETE FROM settings WHERE value='DBSchemaVerMinor';";+    query.prepare(thequery);+    query.exec();+     +    if (query.lastError().type() != QSqlError::None)+    {+        QString msg =+            QString("DB Error (Deleting old DB minor version number): \n"+                    "Query was: %1 \nError was: %2 \nnew version: %3")+            .arg(thequery)+            .arg(MythContext::DBErrorMessage(query.lastError()))+            .arg(newminor);+        VERBOSE(VB_IMPORTANT, msg);+        return false;+    }++    // set new schema minor+    thequery = QString("INSERT INTO settings (value, data, hostname) "+                       "VALUES ('DBSchemaVerMinor', %1, NULL);").arg(newminor);+    query.prepare(thequery);+    query.exec();++    if (query.lastError().type() != QSqlError::None)+    {+        QString msg =+            QString("DB Error (Setting new DB minor version number): \n"+                    "Query was: %1 \nError was: %2 \nnew minor version: %3")+            .arg(thequery)+            .arg(MythContext::DBErrorMessage(query.lastError()))+            .arg(newminor);+        VERBOSE(VB_IMPORTANT, msg);+        return false;+    }++    return true;+}+ /** \fn performActualUpdate(const QString updates[], QString, QString&)  *  \brief Runs a number of SQL commands, and updates the schema version.  *@@ -399,6 +448,44 @@     return true; } +static bool performMinorUpdate(const QString updates[], QString minor,+                                QString &dbminor)+{+    MSqlQuery query(MSqlQuery::InitCon());++    VERBOSE(VB_IMPORTANT, QString("Upgrading to schema minor ") + minor);++    int counter = 0;+    QString thequery = updates[counter];++    while (thequery != "")+    {+        query.prepare(thequery);+        query.exec();++        if (query.lastError().type() != QSqlError::None)+        {+            QString msg =+                QString("DB Error (Performing database upgrade): \n"+                        "Query was: %1 \nError was: %2 \nnew minor: %3")+                .arg(thequery)+                .arg(MythContext::DBErrorMessage(query.lastError()))+                .arg(minor);+            VERBOSE(VB_IMPORTANT, msg);+            return false;+        }++        counter++;+        thequery = updates[counter];+    }++    if (!UpdateDBVersionMinor(minor))+        return false;++    dbminor = minor;+    return true;             +}+ /** \fn UpgradeTVDatabaseSchema(void)  *  \brief This is the function called from outside dbcheck.cpp to update the schema.  *@@ -416,17 +503,22 @@ {     QString dbver = gContext->GetSetting("DBSchemaVer"); -    VERBOSE(VB_IMPORTANT, QString("Current Schema Version: %1").arg(dbver));+    QString dbminor = gContext->GetSetting("DBSchemaVerMinor"); -    if (dbver == currentDatabaseVersion)+    VERBOSE(VB_IMPORTANT, QString("Current Schema Version: %1.%2").arg(dbver)+                                                                  .arg(dbminor));++    if ((dbver == currentDatabaseVersion) &&+        (dbminor == currentDatabaseVersionMinor))         return true;      MSqlQuery chartype(MSqlQuery::InitCon());     chartype.prepare("ALTER DATABASE mythconverg DEFAULT CHARACTER SET latin1;");     chartype.exec(); -    VERBOSE(VB_IMPORTANT, QString("Newest Schema Version : %1")-                                  .arg(currentDatabaseVersion));+    VERBOSE(VB_IMPORTANT, QString("Newest Schema Version : %1.%2")+                                  .arg(currentDatabaseVersion)+                                  .arg(currentDatabaseVersionMinor));      MSqlQuery lockquery(MSqlQuery::InitCon()); @@ -458,7 +550,15 @@      bool ret = doUpgradeTVDatabaseSchema(); +    // Database version minor updates     if (ret)+        ret = dbMinorUpdate();++    VERBOSE(VB_IMPORTANT, QString("Newest Schema Version : %1.%2")+                                  .arg(currentDatabaseVersion)+                                  .arg(currentDatabaseVersionMinor));++    if (ret)         VERBOSE(VB_IMPORTANT, "Database Schema upgrade complete, unlocking.");     else         VERBOSE(VB_IMPORTANT, "Database Schema upgrade FAILED, unlocking.");@@ -2148,8 +2248,51 @@     return true; } +static bool dbMinorUpdate(void)+{+    QString dbminor = gContext->GetSetting("DBSchemaVerMinor");+    if (dbminor == currentDatabaseVersionMinor)+        return true;+    if ((dbminor == "") || (dbminor == "0"))+    {+        const QString updates[] = {+// Dish Network+"INSERT INTO dtv_privatetypes (sitype, networkid, private_type, private_value)"+" VALUES('dvb', 4102, 'force_guide_present', 'yes');",+"INSERT INTO dtv_privatetypes (sitype, networkid, private_type, private_value)"+" VALUES('dvb', 4102, 'extended_guide_tid', '229');",+// Bell ExpressVu+"INSERT INTO dtv_privatetypes (sitype, networkid, private_type, private_value)"+" VALUES('dvb', 256, 'force_guide_present', 'yes');",+"INSERT INTO dtv_privatetypes (sitype, networkid, private_type, private_value)"+" VALUES('dvb', 256, 'guide_on_single_tid', 'yes');",+"INSERT INTO dtv_privatetypes (sitype, networkid, private_type, private_value)"+" VALUES('dvb', 257, 'force_guide_present', 'yes');",+"INSERT INTO dtv_privatetypes (sitype, networkid, private_type, private_value)"+" VALUES('dvb', 257, 'guide_on_single_tid', 'yes');",+""+        };+        if (!performMinorUpdate(updates, "1", dbminor))+            return false;+    } +    if ((dbminor == "1"))+    {+        const QString updates[] = {+// Bell ExpressVu+"INSERT INTO dtv_privatetypes (sitype, networkid, private_type, private_value)"+" VALUES('dvb', 256, 'standard_guide_tid', '4');",+"INSERT INTO dtv_privatetypes (sitype, networkid, private_type, private_value)"+" VALUES('dvb', 257, 'standard_guide_tid', '102');",+""+        };+        if (!performMinorUpdate(updates, "2", dbminor))+            return false;+    } +    return true;+}+ bool InitializeDatabase(void) {     MSqlQuery query(MSqlQuery::InitCon());Index: libs/libmythtv/dvbcam.h===================================================================--- libs/libmythtv/dvbcam.h     (revision 9417)+++ libs/libmythtv/dvbcam.h     (working copy)@@ -47,6 +47,13 @@     bool            pmt_sent;     bool            pmt_updated;     bool            pmt_added;+    bool            exitSkThread;+    bool            skThreadRunning;+    pthread_t       externSoftkeyThread;+    int external_cam_fd;+    void sendExternalCam(const ProgramMapTable *pmt);+    bool useExternalCam();+    void stopExternalCam(); };  #endif // DVBCAM_HIndex: libs/libmythtv/dvbcam.cpp===================================================================--- libs/libmythtv/dvbcam.cpp   (revision 9417)+++ libs/libmythtv/dvbcam.cpp   (working copy)@@ -35,7 +35,7 @@  #include <qdatetime.h> #include <qvariant.h>-+#include <qdir.h> #include <iostream> #include <vector> #include <map>@@ -85,6 +85,8 @@  bool DVBCam::Start() {+    if(useExternalCam())+      return true;     if (numslots == 0)         return false; @@ -116,6 +118,7 @@  bool DVBCam::Stop() {    +    stopExternalCam();     if (ciThreadRunning)     {         exitCiThread = true;@@ -262,7 +265,7 @@ void DVBCam::SetPMT(const ProgramMapTable *pmt) {     VERBOSE(VB_CHANNEL, LOC + "SetPMT() program num #"<<pmt->ProgramNumber());-+    sendExternalCam(pmt);     QMutexLocker locker(&pmt_lock);     PMTList.clear();     PMTList.push_back(*pmt);@@ -376,3 +379,147 @@     }     return capmt; }++bool DVBCam::useExternalCam()+{+    skThreadRunning = false;+    exitSkThread = false;+    external_cam_fd = -1;+    QString extCam = QDir::homeDirPath() ++                     QString("/.mythtv/externcam_%1").arg(cardnum);+    if (QFileInfo(extCam).isDir())+    {+        QString cmd = gContext->GetSetting("ExternalCamApp","");+        if(cmd == "") {+            ERROR("CAM - No external app set in SQL db.");+            return false;+        }+        cmd += " --dir " + extCam + QString(" --card %1").arg(cardnum);++        QString keyFifo = QDir::homeDirPath() + +                          QString("/.mythtv/externcam_%1/keyfifo").arg(cardnum);+        unlink(keyFifo.ascii());+        bool spawn_thread = false;+        if(numslots==0 || QFileInfo(extCam + "/force_sw").isFile()) {+            cmd += " --writekey " + keyFifo;+            mkfifo(keyFifo.ascii(), 0600);+            spawn_thread = true;+        }+ +        int tmppid[2];+        if (pipe(tmppid) < 0)+        {+            perror("Failed to create pipe\n");+            return false;+        }+ +        int child = fork();+        if (child < 0)+        {+            perror("Failed to fork\n");+            return false;+        }+        if (child == 0)+        {+            dup2(tmppid[0],fileno(stdin));+            for(int i = 3; i < sysconf(_SC_OPEN_MAX) - 1; ++i)+                close(i);+            execl("/bin/sh", "sh", "-c", cmd.ascii(), NULL);+            perror("exec");+            _exit(1);+        }+        close(tmppid[0]);+        external_cam_fd=tmppid[1];+         //we need to fake ciThreadRunning in oreder to get PMTs+        ciThreadRunning = true;+        return true;+    }+    return false;+}+void DVBCam::sendExternalCam(const ProgramMapTable *pmt)+{+    if (external_cam_fd < 0)+        return;++    unsigned char newpmt[512];+    int hdr[34]; //Allow for up to 16 PIDs+    int pmtlen=0, hdrlen = 0;+    hdr[hdrlen++]=pmt->ProgramNumber();+    hdr[hdrlen++]=1; //Place holder for transportID (future)++    desc_list_t gdesc = MPEGDescriptor::ParseOnlyInclude(+        pmt->ProgramInfo(), pmt->ProgramInfoLength(),+        DescriptorID::conditional_access);++    for (desc_list_t::const_iterator it = gdesc.begin(); it != gdesc.end(); ++it)+    {+        ConditionalAccessDescriptor cad(*it);+        newpmt[pmtlen++] = 0x09;+        newpmt[pmtlen++] = cad.DataSize() + 4;+        newpmt[pmtlen++] = (cad.SystemID()) >> 8;+        newpmt[pmtlen++] = (cad.SystemID()) & 0xff;+        newpmt[pmtlen++] = (cad.PID()) >> 8;+        newpmt[pmtlen++] = (cad.PID()) & 0xff;+        const unsigned char* p_data = cad.Data();+        for (int x = 0; x < cad.DataSize(); x++)+            newpmt[pmtlen++] = p_data[x];+    }+    for (uint i = 0; i < pmt->StreamCount(); i++)+    {+        int type;+        if (StreamID::IsVideo(pmt->StreamType(i)))+            type = 0;+        else if (StreamID::IsAudio(pmt->StreamType(i)))+            type = 1;+        else+            type = 5;++        hdr[hdrlen++] = pmt->StreamPID(i); //pid+        hdr[hdrlen++] = type;     //stream type++        desc_list_t gdesc = MPEGDescriptor::ParseOnlyInclude(+            pmt->StreamInfo(i), pmt->StreamInfoLength(i),+            DescriptorID::conditional_access);++        for (desc_list_t::const_iterator it = gdesc.begin(); it != gdesc.end(); ++it)+        {+            ConditionalAccessDescriptor cad(*it);+            newpmt[pmtlen++] = 0x09;+            newpmt[pmtlen++] = cad.DataSize() + 4;+            newpmt[pmtlen++] = (cad.SystemID()) >> 8;+            newpmt[pmtlen++] = (cad.SystemID()) & 0xff;+            newpmt[pmtlen++] = (cad.PID()) >> 8;+            newpmt[pmtlen++] = (cad.PID()) & 0xff;+            const unsigned char* p_data = cad.Data();+            for (int x = 0; x < cad.DataSize(); x++)+              newpmt[pmtlen++] = p_data[x];+        }+    }+    if (pmtlen) {+        QString temp = QString("SID: %1 TID: %2").arg(hdr[0]).arg(hdr[1]);+        for (int x = 2; x < hdrlen; x += 2)+            temp += QString(" (%1 %2)").arg(hdr[x]).arg(hdr[x + 1]);+        GENERAL(temp);+        temp = QString("Found CA Descriptors: (%1)").arg(pmtlen);+        for (int x = 0; x < pmtlen; x++)+            temp += QString(" %1").arg(newpmt[x],2,16);+        GENERAL(temp);+        write(external_cam_fd, &hdrlen, sizeof(hdrlen));+        write(external_cam_fd, &hdr,    hdrlen * sizeof(int));+        write(external_cam_fd, &pmtlen, sizeof(pmtlen));+        write(external_cam_fd, &newpmt, pmtlen);+    }+}++void DVBCam::stopExternalCam()+{+    if(external_cam_fd != -1) {+        close(external_cam_fd);+        ciThreadRunning = false;+        if (skThreadRunning)+        {+            exitSkThread = true;+            pthread_join(externSoftkeyThread, NULL);+        }+    }+}Index: libs/libmythtv/eitscanner.h===================================================================--- libs/libmythtv/eitscanner.h (revision 9417)+++ libs/libmythtv/eitscanner.h (working copy)@@ -28,7 +28,7 @@     void StopPassiveScan(void);      void StartActiveScan(TVRec*, uint max_seconds_per_source,-                         bool ignore_source);+                         bool ignore_source, bool limit_transport=false);      void StopActiveScan(void);         Index: libs/libmythtv/tv_rec.cpp===================================================================--- libs/libmythtv/tv_rec.cpp   (revision 9417)+++ libs/libmythtv/tv_rec.cpp   (working copy)@@ -78,9 +78,6 @@ #define LOC QString("TVRec(%1): ").arg(cardid) #define LOC_ERR QString("TVRec(%1) Error: ").arg(cardid) -/// How many seconds after entering kState_None should we start EIT Scanner-const uint TVRec::kEITScanStartTimeout = 60; /* 1 minute */- /// How many milliseconds the signal monitor should wait between checks const uint TVRec::kSignalMonitoringRate = 50; /* msec */ @@ -768,7 +765,8 @@     {         // Add some randomness to avoid all cards starting         // EIT scanning at nearly the same time.-        uint timeout = kEITScanStartTimeout + random() % 59;+        uint idle_start = gContext->GetNumSetting("EITCrawIdleStart", 1);+        uint timeout = (idle_start * 60) + random() % 59;         eitScanStartTime = eitScanStartTime.addSecs(timeout);     }     else@@ -1207,7 +1205,8 @@      // Add some randomness to avoid all cards starting     // EIT scanning at nearly the same time.-    uint timeout = kEITScanStartTimeout + random() % 59;+    uint idle_start = gContext->GetNumSetting("EITCrawIdleStart", 1);+    uint timeout = (idle_start * 60) + random() % 59;     eitScanStartTime = QDateTime::currentDateTime().addSecs(timeout);      while (HasFlags(kFlagRunMainLoop))@@ -1342,8 +1341,11 @@             else             {                 uint ttMin = gContext->GetNumSetting("EITTransportTimeout", 5);+                +                uint tid_limit = gContext->GetNumSetting("EITCrawLimitTransports", 0);                 uint ignore = gContext->GetNumSetting("EITIgnoresSource", 0);-                scanner->StartActiveScan(this, ttMin * 60, ignore);+                scanner->StartActiveScan(this, ttMin * 60, ignore, (tid_limit ? true : false));+                 SetFlags(kFlagEITScannerRunning);                 eitScanStartTime = QDateTime::currentDateTime().addYears(1);             }Index: libs/libmythtv/eitscanner.cpp===================================================================--- libs/libmythtv/eitscanner.cpp       (revision 9417)+++ libs/libmythtv/eitscanner.cpp       (working copy)@@ -183,7 +183,7 @@ }  void EITScanner::StartActiveScan(TVRec *_rec, uint max_seconds_per_source,-                                 bool _ignore_source)+                                 bool _ignore_source, bool limit_transports) {     rec           = _rec;     ignore_source = _ignore_source;@@ -191,17 +191,42 @@     if (!activeScanChannels.size())     {         MSqlQuery query(MSqlQuery::InitCon());-        query.prepare(-            "SELECT channum, mplexid "-            "FROM channel, cardinput, capturecard, videosource "-            "WHERE cardinput.sourceid   = channel.sourceid AND "-            "      videosource.sourceid = channel.sourceid AND "-            "      capturecard.cardid   = cardinput.cardid AND "-            "      channel.mplexid        IS NOT NULL      AND "-            "      useonairguide        = 1                AND "-            "      useeit               = 1                AND "-            "      cardinput.cardid     = :CARDID "-            "ORDER BY cardinput.sourceid, atscsrcid");++        if (limit_transports)+            query.prepare(+                "SELECT MIN(channum), channel.mplexid                        "+                "FROM channel, dtv_multiplex, dtv_privatetypes, videosource, "+                "cardinput, capturecard                                      "+                "WHERE dtv_multiplex.networkid = dtv_privatetypes.networkid  "+                "AND videosource.sourceid      = channel.sourceid            "+                "AND cardinput.sourceid        = channel.sourceid            "+                "AND capturecard.cardid        = cardinput.cardid            "+                "AND (private_type             = 'extended_guide_tid'        "+                "OR   private_type             = 'standard_guide_tid')       "+                "AND private_value             = transportid                 "+                "AND channel.mplexid           = dtv_multiplex.mplexid       "+                "AND useonairguide             = 1                           "+                "AND useeit                    = 1                           "+                "AND cardinput.cardid          = :CARDID                     "+                "GROUP BY transportid");+        else+            query.prepare(+                "SELECT MIN(channum), channel.mplexid                         "+                "FROM channel,videosource,cardinput,capturecard,dtv_multiplex "+                "LEFT JOIN dtv_privatetypes                                   "+                "ON dtv_multiplex.networkid = dtv_privatetypes.networkid      "+                "AND (private_type             = 'extended_guide_tid'         "+                "OR   private_type             = 'standard_guide_tid')        "+                "AND private_value             = transportid                  "+                "WHERE videosource.sourceid      = channel.sourceid           "+                "AND cardinput.sourceid        = channel.sourceid             "+                "AND capturecard.cardid        = cardinput.cardid             "+                "AND channel.mplexid           = dtv_multiplex.mplexid        "+                "AND useonairguide             = 1                            "+                "AND useeit                    = 1                            "+                "AND cardinput.cardid          = :CARDID                      "+                "GROUP BY transportid");+         query.bindValue(":CARDID", rec->GetCaptureCardNum());          if (!query.exec() || !query.isActive())Index: libs/libmythtv/dtvsignalmonitor.cpp===================================================================--- libs/libmythtv/dtvsignalmonitor.cpp (revision 9417)+++ libs/libmythtv/dtvsignalmonitor.cpp (working copy)@@ -234,9 +234,9 @@      if (pmt->ProgramNumber() != (uint)programNumber)     {-        VERBOSE(VB_IMPORTANT, LOC_ERR +-                QString("Wrong PMT; pmt->pn(%1) desired(%2)")-                .arg(pmt->ProgramNumber()).arg(programNumber));+//        VERBOSE(VB_IMPORTANT, LOC_ERR ++//                QString("Wrong PMT; pmt->pn(%1) desired(%2)")+//                .arg(pmt->ProgramNumber()).arg(programNumber));         return; // Not the PMT we are looking for...     } Index: libs/libmythtv/tv_rec.h===================================================================--- libs/libmythtv/tv_rec.h     (revision 9417)+++ libs/libmythtv/tv_rec.h     (working copy)@@ -372,7 +372,6 @@     QString      rbFileExt;    public:-    static const uint kEITScanStartTimeout;     static const uint kSignalMonitoringRate;      // General State flagsIndex: setup/backendsettings.cpp===================================================================--- setup/backendsettings.cpp   (revision 9417)+++ setup/backendsettings.cpp   (working copy)@@ -73,6 +73,15 @@     return gc; }; +static GlobalLineEdit *ExternalCamApp()+{+    GlobalLineEdit *gc = new GlobalLineEdit("ExternalCamApp");+    gc->setLabel(QObject::tr("External Cam App"));+    gc->setValue("sasc");+    gc->setHelpText(QObject::tr("External Application for CAMless cards."));+    return gc;+};+ static GlobalComboBox *TVFormat() {     GlobalComboBox *gc = new GlobalComboBox("TVFormat");@@ -214,6 +223,30 @@     return gc; }; +static GlobalSpinBox *EITCrawIdleStart()+{+    GlobalSpinBox *gc = new GlobalSpinBox("EITCrawIdleStart", 1, 120, 1);+    gc->setLabel(QObject::tr("Backend Idle Before EIT Craw (mins)"));+    gc->setValue(1);+    QString helpText = QObject::tr(+        "The amount of time to wait after the backend becomes idle for a given "+        "capture card before the EIT craw starts.");+    gc->setHelpText(helpText);+    return gc;+}++static GlobalCheckBox *EITCrawLimitTransports()+{+    GlobalCheckBox *gc = new GlobalCheckBox("EITCrawLimitTransports");+    gc->setLabel(QObject::tr("EIT Craw Limits Transports"));+    gc->setValue(false);+    gc->setHelpText(QObject::tr("If set, EIT craw will scan only "+                                "those transports which have either "+                                "standard_guide_tid or extended_guide_tid "+                                "entries defined in dtv_privatetypes."));+    return gc;+};+ static GlobalSpinBox *EITTransportTimeout() {     GlobalSpinBox *gc = new GlobalSpinBox("EITTransportTimeout", 1, 15, 1);@@ -654,6 +687,7 @@     VerticalConfigurationGroup* group1 = new VerticalConfigurationGroup(false);     group1->setLabel(QObject::tr("Host-specific Backend Setup"));     group1->addChild(RecordFilePrefix());+    group1->addChild(ExternalCamApp());     addChild(group1);      VerticalConfigurationGroup* group2 = new VerticalConfigurationGroup(false);@@ -669,6 +703,8 @@     VerticalConfigurationGroup* group2a1 = new VerticalConfigurationGroup(false);     group2a1->setLabel(QObject::tr("EIT Scanner Options"));                     group2a1->addChild(EITTransportTimeout());+    group2a1->addChild(EITCrawIdleStart());+    group2a1->addChild(EITCrawLimitTransports());     group2a1->addChild(EITIgnoresSource());     addChild(group2a1);