From 2e8613ea81b96fe23b7beefbfd9150eead73f894 Mon Sep 17 00:00:00 2001
From: Karl Dietz <dekarl@users.sourceforge.net>
Date: Wed, 11 Jan 2012 20:13:01 +0100
Subject: [PATCH 1/5] unbreak the channels.conf importer for DVB

ChannelUtils knows the original_network_id and transport_id, but DTVMultiplex
ignored them completely...
Set SI standard to dvb as VDR style channels.conf we read are always DVB.
Also import symbol rate for DVB-C/S while here.
Fix frequency parsing for DVB-S.
---
 mythtv/libs/libmythtv/dtvconfparser.cpp |   40 +++++++++++++++++++++++++-----
 mythtv/libs/libmythtv/dtvmultiplex.cpp  |   19 +++++++++++---
 mythtv/libs/libmythtv/dtvmultiplex.h    |    4 ++-
 3 files changed, 51 insertions(+), 12 deletions(-)

diff --git a/mythtv/libs/libmythtv/dtvconfparser.cpp b/mythtv/libs/libmythtv/dtvconfparser.cpp
index e4bc862..ff659c0 100644
--- a/mythtv/libs/libmythtv/dtvconfparser.cpp
+++ b/mythtv/libs/libmythtv/dtvconfparser.cpp
@@ -108,11 +108,13 @@ DTVConfParser::return_t DTVConfParser::Parse(void)
 
         str = list[3];
 
-        if ((str == "T") || (str == "C") || (str == "S"))
+        // http://linuxtv.org/vdrwiki/index.php/Syntax_of_channels.conf
+        // e.g. C, T, S19.2E
+        if ((str == "T") || (str == "C") || (str[0] == 'S'))
         {
             if ((type == OFDM) && (str == "T"))
                 ok &= ParseVDR(list, channelNo);
-            else if ((type == QPSK || type == DVBS2) && (str == "S"))
+            else if ((type == QPSK || type == DVBS2) && (str[0] == 'S'))
                 ok &= ParseVDR(list, channelNo);
             else if ((type == QAM) && (str == "C"))
                 ok &= ParseVDR(list, channelNo);
@@ -230,9 +232,17 @@ bool DTVConfParser::ParseVDR(const QStringList &tokens, int channelNo)
 
 // BBC ONE:754166:I999B8C34D34M16T2G32Y0:T:27500:600:601, 602:0:0:4168:0:0:0
 
-    PARSE_SKIP(unknown);
+    PARSE_SKIP(unknown); // channel name; bouquet name
 
-    PARSE_UINT_1000(mux.frequency);
+    // FIXME http://linuxtv.org/vdrwiki/index.php/Syntax_of_channels.conf#Frequency
+    // should read the number and multiply by 1,000 until its bigger then 1,000,000
+    // to get frequency in Hz.
+    // But we have to return the frequency in Hz for DVB-C/T and kHz for DVB-S
+    long long frequency;
+    PARSE_UINT(frequency);
+    while ((frequency>0) && (frequency<1000000)) {
+        frequency *= 1000;
+    }
 
     if (it == tokens.end())
         return false;
@@ -286,10 +296,26 @@ bool DTVConfParser::ParseVDR(const QStringList &tokens, int channelNo)
         }
     }
 
-    for (uint i = 0; i < 6; i++)
-        PARSE_SKIP(unknown);
-
+    // http://linuxtv.org/vdrwiki/index.php/Syntax_of_channels.conf
+    QString source;
+    PARSE_STR(source); // source: C, S19.2E, T
+    if (source[0] == 'S') {
+        mux.frequency = frequency / 1000;
+    } else {
+        mux.frequency = frequency;
+    }
+    PARSE_UINT_1000(mux.symbolrate); // symbol rate / 1000
+    PARSE_SKIP(unknown); // video pid
+    PARSE_SKIP(unknown); // audio pid
+    PARSE_SKIP(unknown); // teletext pid
+    PARSE_SKIP(unknown); // conditional access
     PARSE_UINT(chan.serviceid);
+    PARSE_UINT(mux.original_network_id);
+    PARSE_UINT(mux.transport_id);
+    PARSE_SKIP(unknown); // radio_id <- VDR custom to make onid/tid/sid unique
+
+    // VDR is always DVB, it doesn't do ATSC/SCTE (it does analogue TV, but we should only end up here for digital tv)
+    mux.sistandard = "dvb";
 
     AddChannel(mux, chan);
 
diff --git a/mythtv/libs/libmythtv/dtvmultiplex.cpp b/mythtv/libs/libmythtv/dtvmultiplex.cpp
index 35b4666..4c4e25e 100644
--- a/mythtv/libs/libmythtv/dtvmultiplex.cpp
+++ b/mythtv/libs/libmythtv/dtvmultiplex.cpp
@@ -22,7 +22,9 @@ DTVMultiplex::DTVMultiplex(const DTVMultiplex &other) :
     mod_sys(other.mod_sys),
     rolloff(other.rolloff),
     mplex(other.mplex),
-    sistandard(other.sistandard)
+    sistandard(other.sistandard),
+    original_network_id(other.original_network_id),
+    transport_id(other.transport_id)
 {
 }
 
@@ -44,6 +46,8 @@ DTVMultiplex &DTVMultiplex::operator=(const DTVMultiplex &other)
     rolloff        = other.rolloff;
     mplex          = other.mplex;
     sistandard     = other.sistandard;
+    original_network_id = other.original_network_id;
+    transport_id        = other.transport_id;
     return *this;
 }
 
@@ -320,7 +324,8 @@ bool DTVMultiplex::FillFromDB(DTVTunerType type, uint mplexid)
         "       hp_code_rate,      lp_code_rate,   constellation, "
         "       transmission_mode, guard_interval, hierarchy, "
         "       modulation,        bandwidth,      sistandard, "
-        "       mod_sys,           rolloff "
+        "       mod_sys,           rolloff,        networkid, "
+        "       transportid "
         "FROM dtv_multiplex "
         "WHERE dtv_multiplex.mplexid = :MPLEXID");
     query.bindValue(":MPLEXID", mplexid);
@@ -342,6 +347,8 @@ bool DTVMultiplex::FillFromDB(DTVTunerType type, uint mplexid)
 
     mplex = mplexid;
     sistandard = query.value(13).toString();
+    original_network_id = query.value(16).toUInt();
+    transport_id = query.value(17).toUInt();
 
     // Parse the query into our DVBTuning class
     return ParseTuningParams(
@@ -503,7 +510,8 @@ uint ScanDTVTransport::SaveScan(uint scanid) const
         "    hp_code_rate,       lp_code_rate,    modulation, "
         "    transmission_mode,  guard_interval,  hierarchy,  "
         "    mod_sys,            rolloff,                     "
-        "    bandwidth,          sistandard,      tuner_type  "
+        "    bandwidth,          sistandard,      tuner_type, "
+        "    networkid,          transportid,                 "
         " ) "
         "VALUES "
         " ( :SCANID, "
@@ -512,7 +520,8 @@ uint ScanDTVTransport::SaveScan(uint scanid) const
         "   :HP_CODE_RATE,      :LP_CODE_RATE,   :MODULATION, "
         "   :TRANSMISSION_MODE, :GUARD_INTERVAL, :HIERARCHY,  "
         "   :MOD_SYS,           :ROLLOFF,                     "
-        "   :BANDWIDTH,         :SISTANDARD,     :TUNER_TYPE  "
+        "   :BANDWIDTH,         :SISTANDARD,     :TUNER_TYPE, "
+        "   :ONID,              :TID                          "
         " );");
 
     query.bindValue(":SCANID", scanid);
@@ -533,6 +542,8 @@ uint ScanDTVTransport::SaveScan(uint scanid) const
     query.bindValue(":BANDWIDTH", bandwidth.toString());
     query.bindValue(":SISTANDARD", sistandard);
     query.bindValue(":TUNER_TYPE", (uint)tuner_type);
+    query.bindValue(":ONID", original_network_id);
+    query.bindValue(":TID", transport_id);
 
     if (!query.exec())
     {
diff --git a/mythtv/libs/libmythtv/dtvmultiplex.h b/mythtv/libs/libmythtv/dtvmultiplex.h
index 273131c..5d07e55 100644
--- a/mythtv/libs/libmythtv/dtvmultiplex.h
+++ b/mythtv/libs/libmythtv/dtvmultiplex.h
@@ -23,7 +23,7 @@ class DTVMultiplex
 {
   public:
     DTVMultiplex()
-        : frequency(0), symbolrate(0), mplex(0), sistandard(QString::null) { }
+        : frequency(0), symbolrate(0), mplex(0), sistandard(QString::null), original_network_id(0), transport_id(0) { }
     DTVMultiplex(const DTVMultiplex &other);
     DTVMultiplex &operator=(const DTVMultiplex &other);
     virtual ~DTVMultiplex() { }
@@ -90,6 +90,8 @@ class DTVMultiplex
     // Optional additional info
     uint             mplex;
     QString          sistandard;
+    uint             original_network_id;
+    uint             transport_id;
 };
 
 class ScanDTVTransport : public DTVMultiplex
-- 
1.7.4.1

