Ticket #10784: 0007-Handle-EIT-events-of-the-active-transport-without-lo.patch-v2

File 0007-Handle-EIT-events-of-the-active-transport-without-lo.patch-v2, 11.4 KB (added by dekarl@…, 8 years ago)

v2: actually accept any SDT when ONID/TSID are 0

Line 
1From d956395648a4dc0ee9c785cdf15115c49f6fc515 Mon Sep 17 00:00:00 2001
2From: Karl Dietz <dekarl@users.sourceforge.net>
3Date: Tue, 22 May 2012 23:30:38 +0200
4Subject: [PATCH 7/7] Handle EIT events of the active transport without looking at original_network_id or transport_id
5
6Refs #10217
7---
8 mythtv/libs/libmythtv/dtvsignalmonitor.cpp |   10 +++
9 mythtv/libs/libmythtv/eithelper.cpp        |  112 +++++++++++++++++++++++++---
10 mythtv/libs/libmythtv/eithelper.h          |    6 ++
11 mythtv/libs/libmythtv/eitscanner.cpp       |    3 +
12 mythtv/libs/libmythtv/tv_rec.cpp           |   10 +++
13 mythtv/libs/libmythtv/tv_rec.h             |    1 +
14 6 files changed, 130 insertions(+), 12 deletions(-)
15
16diff --git a/mythtv/libs/libmythtv/dtvsignalmonitor.cpp b/mythtv/libs/libmythtv/dtvsignalmonitor.cpp
17index 7ed61f3..e08f46f 100644
18--- a/mythtv/libs/libmythtv/dtvsignalmonitor.cpp
19+++ b/mythtv/libs/libmythtv/dtvsignalmonitor.cpp
20@@ -484,6 +484,16 @@ void DTVSignalMonitor::HandleSDT(uint, const ServiceDescriptionTable *sdt)
21     detectedNetworkID = sdt->OriginalNetworkID();
22     detectedTransportID = sdt->TSID();
23 
24+    // if the multiplex is not properly configured with ONID and TSID then take
25+    // whatever SDT we see first
26+    if ((networkID == 0) && (transportID == 0))
27+    {
28+        networkID = detectedNetworkID;
29+        transportID = detectedTransportID;
30+
31+        // FIXME assert if TableID == SDTo
32+    }
33+
34     if (sdt->OriginalNetworkID() != networkID || sdt->TSID() != transportID)
35     {
36         GetDVBStreamData()->SetVersionSDT(sdt->TSID(), -1, 0);
37diff --git a/mythtv/libs/libmythtv/eithelper.cpp b/mythtv/libs/libmythtv/eithelper.cpp
38index df145fc..dd82960 100644
39--- a/mythtv/libs/libmythtv/eithelper.cpp
40+++ b/mythtv/libs/libmythtv/eithelper.cpp
41@@ -25,10 +25,12 @@ using namespace std;
42 const uint EITHelper::kChunkSize = 20;
43 EITCache *EITHelper::eitcache = new EITCache();
44 
45-static uint get_chan_id_from_db(uint sourceid,
46-                                uint atscmajor, uint atscminor);
47-static uint get_chan_id_from_db(uint sourceid,  uint serviceid,
48-                                uint networkid, uint transportid);
49+static uint get_chan_id_from_db_atsc(uint sourceid,
50+                                     uint atscmajor, uint atscminor);
51+static uint get_chan_id_from_db_dvb(uint sourceid,  uint serviceid,
52+                                    uint networkid, uint transportid);
53+static uint get_chan_id_from_db_dtv(uint sourceid,
54+                                    uint programnumber, uint tunedchanid);
55 static void init_fixup(QMap<uint64_t,uint> &fix);
56 static int calc_eit_utc_offset(void);
57 
58@@ -37,7 +39,7 @@ static int calc_eit_utc_offset(void);
59 EITHelper::EITHelper() :
60     eitfixup(new EITFixUp()),
61     gps_offset(-1 * GPS_LEAP_SECONDS),          utc_offset(0),
62-    sourceid(0)
63+    sourceid(0), channelid(0)
64 {
65     init_fixup(fixup);
66 
67@@ -146,6 +148,12 @@ void EITHelper::SetSourceID(uint _sourceid)
68     sourceid = _sourceid;
69 }
70 
71+void EITHelper::SetChannelID(uint _channelid)
72+{
73+    QMutexLocker locker(&eitList_lock);
74+    channelid = _channelid;
75+}
76+
77 void EITHelper::AddEIT(uint atsc_major, uint atsc_minor,
78                        const EventInformationTable *eit)
79 {
80@@ -318,8 +326,18 @@ void EITHelper::AddEIT(const DVBEventInformationTable *eit)
81                   (uint64_t)eit->ServiceID());
82     fix |= EITFixUp::kFixGenericDVB;
83 
84-    uint chanid = GetChanID(eit->ServiceID(), eit->OriginalNetworkID(),
85-                            eit->TSID());
86+    uint chanid = 0;
87+    if ((eit->TableID() == TableID::PF_EIT) ||
88+        ((eit->TableID() >= TableID::SC_EITbeg) && (eit->TableID() <= TableID::SC_EITend)))
89+    {
90+        // EITa(ctive)
91+        chanid = GetChanID(eit->ServiceID());
92+    }
93+    else
94+    {
95+        // EITo(ther)
96+        chanid = GetChanID(eit->ServiceID(), eit->OriginalNetworkID(), eit->TSID());
97+    }
98     if (!chanid)
99         return;
100 
101@@ -684,7 +702,7 @@ uint EITHelper::GetChanID(uint atsc_major, uint atsc_minor)
102     if (it != srv_to_chanid.end())
103         return max(*it, 0);
104 
105-    uint chanid = get_chan_id_from_db(sourceid, atsc_major, atsc_minor);
106+    uint chanid = get_chan_id_from_db_atsc(sourceid, atsc_major, atsc_minor);
107     if (chanid)
108         srv_to_chanid[key] = chanid;
109 
110@@ -703,14 +721,32 @@ uint EITHelper::GetChanID(uint serviceid, uint networkid, uint tsid)
111     if (it != srv_to_chanid.end())
112         return max(*it, 0);
113 
114-    uint chanid = get_chan_id_from_db(sourceid, serviceid, networkid, tsid);
115+    uint chanid = get_chan_id_from_db_dvb(sourceid, serviceid, networkid, tsid);
116     if (chanid)
117         srv_to_chanid[key] = chanid;
118 
119     return chanid;
120 }
121 
122-static uint get_chan_id_from_db(uint sourceid,
123+uint EITHelper::GetChanID(uint program_number)
124+{
125+    uint64_t key;
126+    key  = ((uint64_t) sourceid);
127+    key |= ((uint64_t) program_number) << 16;
128+    key |= ((uint64_t) channelid)      << 32;
129+
130+    ServiceToChanID::const_iterator it = srv_to_chanid.find(key);
131+    if (it != srv_to_chanid.end())
132+        return max(*it, 0);
133+
134+    uint chanid = get_chan_id_from_db_dtv(sourceid, program_number, channelid);
135+    if (chanid)
136+        srv_to_chanid[key] = chanid;
137+
138+    return chanid;
139+}
140+
141+static uint get_chan_id_from_db_atsc(uint sourceid,
142                                 uint atsc_major, uint atsc_minor)
143 {
144     MSqlQuery query(MSqlQuery::InitCon());
145@@ -736,7 +772,7 @@ static uint get_chan_id_from_db(uint sourceid,
146 }
147 
148 // Figure out the chanid for this channel
149-static uint get_chan_id_from_db(uint sourceid, uint serviceid,
150+static uint get_chan_id_from_db_dvb(uint sourceid, uint serviceid,
151                                 uint networkid, uint transportid)
152 {
153     uint chanid = 0;
154@@ -769,7 +805,8 @@ static uint get_chan_id_from_db(uint sourceid, uint serviceid,
155             return useOnAirGuide ? chanid : 0;
156     }
157 
158-    if (query.size() > 1) {
159+    if (query.size() > 1)
160+    {
161         LOG(VB_EIT, LOG_INFO,
162             LOC + QString("found %1 channels for networdid %2, "
163                           "transportid %3, serviceid %4 but none "
164@@ -781,6 +818,57 @@ static uint get_chan_id_from_db(uint sourceid, uint serviceid,
165     return useOnAirGuide ? chanid : 0;
166 }
167 
168+/* Figure out the chanid for this channel from the sourceid,
169+ * program_number/service_id and the chanid of the channel we are tuned to
170+ *
171+ * TODO for SPTS (e.g. HLS / IPTV) it would be useful to match without an entry
172+ * in dtv_multiplex
173+ */
174+static uint get_chan_id_from_db_dtv(uint sourceid, uint serviceid,
175+                                uint tunedchanid)
176+{
177+    uint chanid = 0;
178+    bool useOnAirGuide = false;
179+    MSqlQuery query(MSqlQuery::InitCon());
180+
181+    // DVB Link to chanid
182+    QString qstr =
183+        "SELECT c1.chanid, c1.useonairguide, c1.sourceid "
184+        "FROM channel c1, dtv_multiplex m, channel c2 "
185+        "WHERE c1.serviceid        = :SERVICEID   AND "
186+        "      c1.mplexid  = m.mplexid AND "
187+        "      m.mplexid = c2.mplexid AND "
188+        "      c2.chanid = :CHANID";
189+
190+    query.prepare(qstr);
191+    query.bindValue(":SERVICEID",   serviceid);
192+    query.bindValue(":CHANID", tunedchanid);
193+
194+    if (!query.exec() || !query.isActive())
195+        MythDB::DBError("Looking up chanID", query);
196+
197+    while (query.next())
198+    {
199+        // Check to see if we are interested in this channel
200+        chanid        = query.value(0).toUInt();
201+        useOnAirGuide = query.value(1).toBool();
202+        if (sourceid == query.value(2).toUInt())
203+            return useOnAirGuide ? chanid : 0;
204+    }
205+
206+    if (query.size() > 1)
207+    {
208+        LOG(VB_EIT, LOG_INFO,
209+            LOC + QString("found %1 channels for multiplex of chanid %2, "
210+                          "serviceid %3 but none "
211+                          "for current sourceid %4.")
212+                .arg(query.size()).arg(tunedchanid)
213+                .arg(serviceid).arg(sourceid));
214+    }
215+
216+    return useOnAirGuide ? chanid : 0;
217+}
218+
219 static void init_fixup(QMap<uint64_t,uint> &fix)
220 {
221     ///////////////////////////////////////////////////////////////////////////
222diff --git a/mythtv/libs/libmythtv/eithelper.h b/mythtv/libs/libmythtv/eithelper.h
223index 6fca7d5..e83244a 100644
224--- a/mythtv/libs/libmythtv/eithelper.h
225+++ b/mythtv/libs/libmythtv/eithelper.h
226@@ -66,6 +66,7 @@ class EITHelper
227 
228     uint GetGPSOffset(void) const { return (uint) (0 - gps_offset); }
229 
230+    void SetChannelID(uint _channelid);
231     void SetGPSOffset(uint _gps_offset) { gps_offset = 0 - _gps_offset; }
232     void SetFixup(uint atsc_major, uint atsc_minor, uint eitfixup);
233     void SetLanguagePreferences(const QStringList &langPref);
234@@ -90,8 +91,12 @@ class EITHelper
235     void WriteEITCache(void);
236 
237   private:
238+    // only ATSC
239     uint GetChanID(uint atsc_major, uint atsc_minor);
240+    // only DVB
241     uint GetChanID(uint serviceid, uint networkid, uint transportid);
242+    // any DTV
243+    uint GetChanID(uint program_number);
244 
245     void CompleteEvent(uint atsc_major, uint atsc_minor,
246                        const ATSCEvent &event,
247@@ -107,6 +112,7 @@ class EITHelper
248     int                     gps_offset;
249     int                     utc_offset;
250     uint                    sourceid;
251+    uint                    channelid;
252     QMap<uint64_t,uint>     fixup;
253     ATSCSRCToEvents         incomplete_events;
254     ATSCSRCToETTs           unmatched_etts;
255diff --git a/mythtv/libs/libmythtv/eitscanner.cpp b/mythtv/libs/libmythtv/eitscanner.cpp
256index 2e42bd5..8acf7e9 100644
257--- a/mythtv/libs/libmythtv/eitscanner.cpp
258+++ b/mythtv/libs/libmythtv/eitscanner.cpp
259@@ -134,6 +134,8 @@ void EITScanner::run(void)
260             {
261                 eitHelper->WriteEITCache();
262                 rec->SetChannel(*activeScanNextChan, TVRec::kFlagEITScan);
263+                eitHelper->SetChannelID(ChannelUtil::GetChanID(rec->GetSourceID(),
264+                                                            *activeScanNextChan));
265                 LOG(VB_EIT, LOG_INFO,
266                     LOC_ID + QString("Now looking for EIT data on "
267                                      "multiplex of channel %1")
268@@ -204,6 +206,7 @@ void EITScanner::StartPassiveScan(ChannelBase *_channel,
269     eitHelper->SetSourceID(sourceid);
270     eitSource->SetEITHelper(eitHelper);
271     eitSource->SetEITRate(1.0f);
272+    eitHelper->SetChannelID(_channel->GetChanID());
273 
274     LOG(VB_EIT, LOG_INFO, LOC_ID + "Started passive scan.");
275 }
276diff --git a/mythtv/libs/libmythtv/tv_rec.cpp b/mythtv/libs/libmythtv/tv_rec.cpp
277index a5d4986..fc9e96c 100644
278--- a/mythtv/libs/libmythtv/tv_rec.cpp
279+++ b/mythtv/libs/libmythtv/tv_rec.cpp
280@@ -2934,6 +2934,16 @@ QString TVRec::GetInput(void) const
281     return QString::null;
282 }
283 
284+/** \fn TVRec::GetSourceID(void) const
285+ *  \brief Returns current source id.
286+ */
287+uint TVRec::GetSourceID(void) const
288+{
289+    if (channel)
290+        return channel->GetCurrentSourceID();
291+    return 0;
292+}
293+
294 /** \fn TVRec::SetInput(QString, uint)
295  *  \brief Changes to the specified input.
296  *
297diff --git a/mythtv/libs/libmythtv/tv_rec.h b/mythtv/libs/libmythtv/tv_rec.h
298index ce54bff..6c2aaf8 100644
299--- a/mythtv/libs/libmythtv/tv_rec.h
300+++ b/mythtv/libs/libmythtv/tv_rec.h
301@@ -192,6 +192,7 @@ class MTV_PUBLIC TVRec : public SignalMonitorListener, public QRunnable
302 
303     vector<InputInfo> GetFreeInputs(const vector<uint> &excluded_cards) const;
304     QString     GetInput(void) const;
305+    uint        GetSourceID(void) const;
306     QString     SetInput(QString input, uint requestType = kFlagDetect);
307 
308     /// Changes to a channel in the 'dir' channel change direction.
309--
3101.7.4.1
311