[mythtv] Adding PLP support (DTV_STREAM_ID)

Torbjorn Jansson torbjorn.jansson at mbox200.swipnet.se
Sun Feb 4 12:35:07 UTC 2018


On 2018-02-03 16:55, Torbjorn Jansson wrote:
> On 2018-01-29 19:39, David Matthews wrote:
>> On 28/01/2018 17:49, Torbjorn Jansson wrote:
>>> On 2018-01-28 16:42, Peter Bennett wrote:
>>>>
>>>>
>>>> On 01/28/2018 08:12 AM, Torbjorn Jansson wrote:
>>>>> Hello.
>>>>>
>>>>> i have a few questions but first some background.
>>>>>
>>>>> several years ago i bought a usb based dvbt2 tuner with the intention to 
>>>>> replace my pcie card.
>>>>> i picked a TT CT2-4650 since it was supposed to have linux support already.
>>>>> turned out that was not true since i got a newer version of it with no 
>>>>> linux support, so with a bit of hacking on the drivers i was able to get 
>>>>> it working due to the similarities with other cards.
>>>>>
>>>>> but i quickly realized i could not tune to any dvb-t2 mux, after a lot of 
>>>>> troubleshooting i gave up and forgot about it.
>>>>>
>>>>> then a year or so later my dvb tv box broke down and i bought a new one 
>>>>> (vu+ solo4k) and to my surprise it had the exact same issue.
>>>>> after even more troubleshooting i found out i need to set PLP ID to 1 for 
>>>>> tuning to work on dvb-t2 muxes.
>>>>>
>>>>> so then i realized that must be the same problem with my ct2-4650 and it was.
>>>>> yesterday i got tvheadend working on the usb tuner successfully and thats 
>>>>> the first time i got the usb tuner to do something useful.
>>>>>
>>>>> BUT channel scanning is not working, so mux must be setup manualy, that 
>>>>> includes PLP ID and other paramters.
>>>>> so i think the drivers don't do auto detect like my pcie card does.
>>>>> and the downside of missing autodetect of plp is that most software dont 
>>>>> know how to handle plp and this applies to mythtv too.
>>>>>
>>>>>
>>>>>
>>>>> so for mythtv to work with this card i need to convince the backend to 
>>>>> specify plp when tuning.
>>>>> so a new mux paramter need to be added to database and then used during 
>>>>> tuning.
>>>>> as i understand it this is done with a property called: DTV_STREAM_ID and 
>>>>> i need to try to understand better how 
>>>>> libs/libmythtv/recorders/dvbchannel.cpp works.
>>>>>
>>>>> can someone give me any pointers about this?
>>>>> to start with i'm happy with a proof of concept hack that sets 
>>>>> DTV_STREAM_ID to 1 on all dvb-t2 tuning attempts, then if it works i can 
>>>>> try and get a proper patch for it.
>>>>>
>>>>> i probably wont be able to get the mux editor or settings working since 
>>>>> i'm not familiar with how the setup gui works.
>>>>> but if i get a new optional mux setting for plp in place then i'm happy.
>>>>>
>>
>> I wrote the original patch to add support for DVB-T2 
>> https://code.mythtv.org/trac/ticket/12342 .  In the UK we don't use PLP or it 
>> may have been that the tuner I had auto-detected but either way there was no 
>> need to add PLP support at the time.  If you follow that link it should 
>> indicate roughly where to add the DTV_STREAM_ID property.  It's a long time 
>> since I looked at this but let me know if I can help.
>>
>> David
> 
> thanks.
> see below for a quick proof of concept patch that's mostly a hack to check that 
> it works.
> with this i can get the hd channels to work.
> 
> now i need to make this into a proper patch by adding a new column to 
> dtv_multiplext table and reading that value in.
> plus make sure it defaults to off, for example by using -1 to indicate it 
> should not be used.
> 

attached is my first version of adding plp support.
currently it is in a "works for me" state, a few things that is missing:
channel scanning is not adjusted, mux editor don't know about this new setting 
and i haven't added the db update code needed.

so to test this you need to manually run:
ALTER TABLE dtv_multiplex ADD COLUMN plp_id SMALLINT;

the gui parts is not done because i haven't (yet) figured out how the settings 
and gui work.

at a minimum the mux editor should have an option to set plp.
it should default to not setting plp by either leaving the column to NULL or 
set it to -1
plp is only valid for dvb-t2 so maybe this gui setting should be hidden if it 
is anything other than dvb-t2

according to the dvb api documentation apparently dvb-s2 also can use plp.
i have no way of testing this so it is not taken into account.


would be nice if someone can have a look at this patch because there are areas 
i'm a little unsure of.
and also would be nice if someone else can test it to make sure i haven't 
broken anything.
-------------- next part --------------
diff --git a/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp b/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp
index be20a270fb..b1db224a22 100644
--- a/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp
+++ b/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp
@@ -2013,7 +2013,8 @@ bool ChannelScanSM::ScanTransportsStartingOn(
             startChan["constellation"],  startChan["trans_mode"],
             startChan["guard_interval"], startChan["hierarchy"],
             startChan["modulation"],     startChan["bandwidth"],
-            startChan["mod_sys"],        startChan["rolloff"]);
+            startChan["mod_sys"],        startChan["rolloff"],
+            "-1");
     }
 
     if (ok)
diff --git a/mythtv/libs/libmythtv/dtvmultiplex.cpp b/mythtv/libs/libmythtv/dtvmultiplex.cpp
index 32c8394a3d..3270b3e1ca 100644
--- a/mythtv/libs/libmythtv/dtvmultiplex.cpp
+++ b/mythtv/libs/libmythtv/dtvmultiplex.cpp
@@ -23,7 +23,8 @@ DTVMultiplex::DTVMultiplex(const DTVMultiplex &other) :
     rolloff(other.rolloff),
     mplex(other.mplex),
     sistandard(other.sistandard),
-    iptv_tuning(other.iptv_tuning)
+    iptv_tuning(other.iptv_tuning),
+    plp_id(other.plp_id)
 {
 }
 
@@ -46,6 +47,7 @@ DTVMultiplex &DTVMultiplex::operator=(const DTVMultiplex &other)
     mplex          = other.mplex;
     sistandard     = other.sistandard;
     iptv_tuning    = other.iptv_tuning;
+    plp_id         = other.plp_id;
     return *this;
 }
 
@@ -64,7 +66,8 @@ bool DTVMultiplex::operator==(const DTVMultiplex &m) const
             (rolloff  == m.rolloff)  &&
             (polarity == m.polarity) &&
             (hierarchy == m.hierarchy) &&
-            (iptv_tuning == m.iptv_tuning)
+            (iptv_tuning == m.iptv_tuning) &&
+            (plp_id == m.plp_id)
             );
 }
 
@@ -83,6 +86,8 @@ QString DTVMultiplex::toString() const
         .arg(polarity.toString());
     ret += QString(" fec: %1 msys: %2 rolloff: %3")
         .arg(fec.toString()).arg(mod_sys.toString()).arg(rolloff.toString());
+    ret += QString(" plp: %1")
+        .arg(plp_id);
 
     return ret;
 }
@@ -124,7 +129,8 @@ bool DTVMultiplex::IsEqual(DTVTunerType type, const DTVMultiplex &other,
                 guard_interval.IsCompatible(other.guard_interval) &&
                 trans_mode.IsCompatible(other.trans_mode)         &&
                 hierarchy.IsCompatible(other.hierarchy)           &&
-                (mod_sys == other.mod_sys);
+                (mod_sys == other.mod_sys)                        &&
+                (DTVTunerType::kTunerTypeDVBT2 == type ? (plp_id == other.plp_id) : true);
         return
             (inversion      == other.inversion)      &&
             (bandwidth      == other.bandwidth)      &&
@@ -134,7 +140,8 @@ bool DTVMultiplex::IsEqual(DTVTunerType type, const DTVMultiplex &other,
             (guard_interval == other.guard_interval) &&
             (trans_mode     == other.trans_mode)     &&
             (hierarchy      == other.hierarchy)      &&
-            (mod_sys        == other.mod_sys);
+            (mod_sys        == other.mod_sys)        &&
+            (DTVTunerType::kTunerTypeDVBT2 == type ? (plp_id  == other.plp_id) : true );
     }
 
     if (DTVTunerType::kTunerTypeATSC == type)
@@ -303,7 +310,8 @@ bool DTVMultiplex::ParseDVB_T2(
     const QString &_bandwidth,   const QString &_coderate_hp,
     const QString &_coderate_lp, const QString &_modulation,
     const QString &_trans_mode,  const QString &_guard_interval,
-    const QString &_hierarchy,   const QString &_mod_sys)
+    const QString &_hierarchy,   const QString &_mod_sys,
+    const QString &_plp_id)
 {
     bool ok = ParseDVB_T(_frequency, _inversion, _bandwidth,
                          _coderate_hp, _coderate_lp, _modulation,
@@ -327,6 +335,15 @@ bool DTVMultiplex::ParseDVB_T2(
         return false;
     }
 
+    if(!_plp_id.isEmpty())
+    {
+        plp_id = _plp_id.toInt(&ok);
+    }
+    else
+    {
+       plp_id = -1;
+    }
+
     return ok;
 }
 
@@ -337,7 +354,7 @@ bool DTVMultiplex::ParseTuningParams(
     QString _hp_code_rate, QString _lp_code_rate,   QString _ofdm_modulation,
     QString _trans_mode,   QString _guard_interval, QString _hierarchy,
     QString _modulation,   QString _bandwidth,
-    QString _mod_sys,      QString _rolloff)
+    QString _mod_sys,      QString _rolloff,        QString _plp_id)
 {
     if (DTVTunerType::kTunerTypeDVBT == type)
     {
@@ -368,7 +385,7 @@ bool DTVMultiplex::ParseTuningParams(
         return ParseDVB_T2(
             _frequency,       _inversion,       _bandwidth,    _hp_code_rate,
             _lp_code_rate,    _ofdm_modulation, _trans_mode,   _guard_interval,
-            _hierarchy, _mod_sys);
+            _hierarchy, _mod_sys, _plp_id);
     }
 
     if (DTVTunerType::kTunerTypeATSC == type)
@@ -392,7 +409,7 @@ 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,        plp_id "
         "FROM dtv_multiplex "
         "WHERE dtv_multiplex.mplexid = :MPLEXID");
     query.bindValue(":MPLEXID", mplexid);
@@ -425,7 +442,7 @@ bool DTVMultiplex::FillFromDB(DTVTunerType type, uint mplexid)
         query.value(8).toString(),  query.value(9).toString(),
         query.value(10).toString(), query.value(11).toString(),
         query.value(12).toString(), query.value(14).toString(),
-        query.value(15).toString());
+        query.value(15).toString(), query.value(16).toString());
 }
 
 
@@ -458,7 +475,8 @@ bool DTVMultiplex::FillFromDeliverySystemDesc(DTVTunerType type,
                     cd.BandwidthString(),               cd.CodeRateHPString(),
                     cd.CodeRateLPString(),              cd.ConstellationString(),
                     cd.TransmissionModeString(),        cd.GuardIntervalString(),
-                    cd.HierarchyString(),               "DVB-T");
+                    cd.HierarchyString(),               "DVB-T",
+                    "-1");
             }
 
             break;
@@ -657,5 +675,5 @@ bool ScanDTVTransport::ParseTuningParams(
         _hp_code_rate,  _lp_code_rate,    _ofdm_modulation,
         _trans_mode,    _guard_interval,  _hierarchy,
         _modulation,    _bandwidth,       _mod_sys,
-        _rolloff);
+        _rolloff, "-1");
 }
diff --git a/mythtv/libs/libmythtv/dtvmultiplex.h b/mythtv/libs/libmythtv/dtvmultiplex.h
index 11b168262b..2dc13495d1 100644
--- a/mythtv/libs/libmythtv/dtvmultiplex.h
+++ b/mythtv/libs/libmythtv/dtvmultiplex.h
@@ -25,7 +25,7 @@ class MTV_PUBLIC DTVMultiplex
 {
   public:
     DTVMultiplex()
-        : frequency(0), symbolrate(0), mplex(0), sistandard(QString::null) { }
+        : frequency(0), symbolrate(0), mplex(0), sistandard(QString::null), plp_id(-1) { }
     DTVMultiplex(const DTVMultiplex &other);
     DTVMultiplex &operator=(const DTVMultiplex &other);
     virtual ~DTVMultiplex() { }
@@ -66,7 +66,8 @@ class MTV_PUBLIC DTVMultiplex
         const QString &bandwidth,   const QString &coderate_hp,
         const QString &coderate_lp, const QString &constellation,
         const QString &trans_mode,  const QString &guard_interval,
-        const QString &hierarchy,   const QString &mod_sys);
+        const QString &hierarchy,   const QString &mod_sys,
+        const QString &plp_id);
 
     bool ParseTuningParams(
         DTVTunerType type,
@@ -75,7 +76,7 @@ class MTV_PUBLIC DTVMultiplex
         QString hp_code_rate, QString lp_code_rate,   QString constellation,
         QString trans_mode,   QString guard_interval, QString hierarchy,
         QString modulation,   QString bandwidth,      QString mod_sys,
-        QString rolloff);
+        QString rolloff,      QString plp_id);
 
     QString toString() const;
 
@@ -100,6 +101,7 @@ class MTV_PUBLIC DTVMultiplex
     uint             mplex;
     QString          sistandard;
     IPTVTuningData   iptv_tuning;
+    int              plp_id;
 };
 
 class MTV_PUBLIC ScanDTVTransport : public DTVMultiplex
diff --git a/mythtv/libs/libmythtv/frequencytables.cpp b/mythtv/libs/libmythtv/frequencytables.cpp
index b26ee2efb5..5aca059844 100644
--- a/mythtv/libs/libmythtv/frequencytables.cpp
+++ b/mythtv/libs/libmythtv/frequencytables.cpp
@@ -81,7 +81,7 @@ TransportScanItem::TransportScanItem(uint                _sourceid,
         _tuning.trans_mode.toString(),       _tuning.guard_interval.toString(),
         _tuning.hierarchy.toString(),        _tuning.modulation.toString(),
         _tuning.bandwidth.toString(),        _tuning.mod_sys.toString(),
-        _tuning.rolloff.toString());
+        _tuning.rolloff.toString(),          QString::number(_tuning.plp_id));
 }
 
 TransportScanItem::TransportScanItem(uint sourceid,
diff --git a/mythtv/libs/libmythtv/recorders/dvbchannel.cpp b/mythtv/libs/libmythtv/recorders/dvbchannel.cpp
index dbdf7adc11..6b081b551a 100644
--- a/mythtv/libs/libmythtv/recorders/dvbchannel.cpp
+++ b/mythtv/libs/libmythtv/recorders/dvbchannel.cpp
@@ -553,7 +553,7 @@ static struct dtv_properties *dtvmultiplex_to_dtvproperties(
     if (!cmdseq)
         return NULL;
 
-    cmdseq->props = (struct dtv_property*) calloc(12, sizeof(*(cmdseq->props)));
+    cmdseq->props = (struct dtv_property*) calloc(13, sizeof(*(cmdseq->props)));
     if (!(cmdseq->props))
     {
         free(cmdseq);
@@ -609,6 +609,12 @@ static struct dtv_properties *dtvmultiplex_to_dtvproperties(
         cmdseq->props[c].cmd      = DTV_HIERARCHY;
         cmdseq->props[c++].u.data = tuning.hierarchy;
     }
+    //PLP
+    if (tuner_type == DTVTunerType::kTunerTypeDVBT2)
+    {
+        cmdseq->props[c].cmd      = DTV_STREAM_ID;
+        cmdseq->props[c++].u.data = tuning.plp_id >255 || tuning.plp_id<0 ? NO_STREAM_ID_FILTER : tuning.plp_id;
+    }
 
     if (tuning.mod_sys == DTVModulationSystem::kModulationSystem_DVBS2)
     {
diff --git a/mythtv/libs/libmythtv/scanwizard.cpp b/mythtv/libs/libmythtv/scanwizard.cpp
index 3ede79b058..2953b30698 100644
--- a/mythtv/libs/libmythtv/scanwizard.cpp
+++ b/mythtv/libs/libmythtv/scanwizard.cpp
@@ -158,7 +158,8 @@ void ScanWizard::Scan()
             start_chan["constellation"],  start_chan["trans_mode"],
             start_chan["guard_interval"], start_chan["hierarchy"],
             start_chan["modulation"],     start_chan["bandwidth"],
-            start_chan["mod_sys"],        start_chan["rolloff"]))
+            start_chan["mod_sys"],        start_chan["rolloff"],
+            "-1"))
     {
         ShowOkPopup(tr("Error parsing parameters"));
 


More information about the mythtv-dev mailing list