From 60b8e825bb5bcbb6bd56063a62f14df91d541f1f Mon Sep 17 00:00:00 2001
From: carlpny
Date: Fri, 20 Nov 2015 00:07:26 -0800
Subject: [PATCH 1/2] Fix for EIT and ETT mismatch.
---
mythtv/libs/libmythtv/eithelper.cpp | 56 +++++++++++++++++++++++++++----------
mythtv/libs/libmythtv/eithelper.h | 45 ++++++++++++++++++++++-------
2 files changed, 77 insertions(+), 24 deletions(-)
diff --git a/mythtv/libs/libmythtv/eithelper.cpp b/mythtv/libs/libmythtv/eithelper.cpp
index ab14a71..04035ca 100644
a
|
b
|
void EITHelper::AddEIT(uint atsc_major, uint atsc_minor, |
159 | 159 | eit->title(i).GetBestMatch(languagePreferences), |
160 | 160 | eit->Descriptors(i), eit->DescriptorsLength(i)); |
161 | 161 | |
| 162 | // Look to see if there has been a recent ett message with the same event id. |
162 | 163 | EventIDToETT::iterator it = etts.find(eit->EventID(i)); |
163 | | |
| 164 | QString ett_text = QString::null; |
| 165 | bool found_matching_ett = false; |
164 | 166 | if (it != etts.end()) |
165 | 167 | { |
166 | | CompleteEvent(atsc_major, atsc_minor, ev, *it); |
| 168 | // Don't use an ett description if it was scanned long in the past. |
| 169 | if (!it->IsStale()) { |
| 170 | ett_text = it->ett_text; |
| 171 | found_matching_ett = true; |
| 172 | } |
167 | 173 | etts.erase(it); |
168 | 174 | } |
169 | | else if (!ev.etm) |
| 175 | |
| 176 | // Create an event immediately if a matching ett description was found, |
| 177 | // or if item is false, indicating that no ett description should be |
| 178 | // expected. |
| 179 | if (found_matching_ett || !ev.etm) |
170 | 180 | { |
171 | | CompleteEvent(atsc_major, atsc_minor, ev, QString::null); |
| 181 | CompleteEvent(atsc_major, atsc_minor, ev, ett_text); |
172 | 182 | } |
173 | 183 | else |
174 | 184 | { |
175 | 185 | unsigned char *tmp = new unsigned char[ev.desc_length]; |
176 | 186 | memcpy(tmp, eit->Descriptors(i), ev.desc_length); |
177 | 187 | ev.desc = tmp; |
178 | | events[eit->EventID(i)] = ev; |
| 188 | events.insert(eit->EventID(i), ev); |
179 | 189 | } |
180 | 190 | } |
181 | 191 | } |
… |
… |
void EITHelper::AddETT(uint atsc_major, uint atsc_minor, |
184 | 194 | const ExtendedTextTable *ett) |
185 | 195 | { |
186 | 196 | uint atsc_key = (atsc_major << 16) | atsc_minor; |
187 | | // Try to complete an Event |
| 197 | // Try to match up the ett with an eit event. |
188 | 198 | ATSCSRCToEvents::iterator eits_it = incomplete_events.find(atsc_key); |
189 | 199 | if (eits_it != incomplete_events.end()) |
190 | 200 | { |
191 | 201 | EventIDToATSCEvent::iterator it = (*eits_it).find(ett->EventID()); |
192 | 202 | if (it != (*eits_it).end()) |
193 | 203 | { |
194 | | CompleteEvent( |
195 | | atsc_major, atsc_minor, *it, |
196 | | ett->ExtendedTextMessage().GetBestMatch(languagePreferences)); |
| 204 | bool completed_event = false; |
| 205 | // Only consider eit events from the recent past. |
| 206 | if (!it->IsStale()) { |
| 207 | completed_event = true; |
| 208 | CompleteEvent( |
| 209 | atsc_major, atsc_minor, *it, |
| 210 | ett->ExtendedTextMessage().GetBestMatch(languagePreferences)); |
| 211 | } |
197 | 212 | |
198 | 213 | if ((*it).desc) |
199 | 214 | delete [] (*it).desc; |
200 | 215 | |
201 | 216 | (*eits_it).erase(it); |
202 | 217 | |
203 | | return; |
| 218 | if (completed_event) return; |
204 | 219 | } |
205 | 220 | } |
206 | 221 | |
207 | | // Couldn't find matching EIT. If not yet in unmatched ETT map, insert it. |
| 222 | // Report if an unmatched ett was previously noted and overwrite it. |
| 223 | // See also https://code.mythtv.org/trac/ticket/11739 |
208 | 224 | EventIDToETT &elist = unmatched_etts[atsc_key]; |
209 | | if (elist.find(ett->EventID()) == elist.end()) |
| 225 | EventIDToETT::iterator existing_unmatched_ett_it = |
| 226 | elist.find(ett->EventID()); |
| 227 | const QString next_ett_text = ett->ExtendedTextMessage() |
| 228 | .GetBestMatch(languagePreferences); |
| 229 | if (existing_unmatched_ett_it != elist.end() && |
| 230 | existing_unmatched_ett_it->ett_text != next_ett_text) |
210 | 231 | { |
211 | | elist[ett->EventID()] = ett->ExtendedTextMessage() |
212 | | .GetBestMatch(languagePreferences); |
| 232 | LOG(VB_EIT, LOG_INFO, LOC + |
| 233 | QString("Overwriting previously unmatched ett. stale: %1 major: %2 " |
| 234 | "minor: %3 old ett: %4 new ett: %5") |
| 235 | .arg(existing_unmatched_ett_it->IsStale()) |
| 236 | .arg(atsc_major) |
| 237 | .arg(atsc_minor) |
| 238 | .arg(existing_unmatched_ett_it->ett_text) |
| 239 | .arg(next_ett_text)); |
213 | 240 | } |
| 241 | elist.insert(ett->EventID(), ATSCEtt(next_ett_text)); |
214 | 242 | } |
215 | 243 | |
216 | 244 | static void parse_dvb_event_descriptors(desc_list_t list, uint fix, |
diff --git a/mythtv/libs/libmythtv/eithelper.h b/mythtv/libs/libmythtv/eithelper.h
index a60e5d5..903235e 100644
a
|
b
|
|
17 | 17 | |
18 | 18 | class MSqlQuery; |
19 | 19 | |
| 20 | // An entry from the EIT table containing event details. |
20 | 21 | class ATSCEvent |
21 | 22 | { |
22 | 23 | public: |
23 | | /// This empty constructor is needed for the QMap<> to work, it is |
24 | | /// not intended to be used to initialize an ATSC Event. |
25 | | /// Since we immediately initialize the value inserted into the |
26 | | /// QMap this is safe in that use. |
27 | | ATSCEvent() : start_time(0), length(0), etm(0), desc_length(0), desc(NULL) {} |
28 | | /// This is the only valid constructor for ATSCEvent. |
29 | 24 | ATSCEvent(uint a, uint b, uint c, QString d, |
30 | 25 | const unsigned char *e, uint f) |
31 | | : start_time(a), length(b), etm(c), desc_length(f), title(d), desc(e) |
32 | | { |
| 26 | : start_time(a), length(b), etm(c), desc_length(f), title(d), desc(e), |
| 27 | scan_time(time(NULL)) {} |
| 28 | |
| 29 | bool IsStale() const { |
| 30 | // The minimum recommended repetition time for EIT events according to |
| 31 | // http://atsc.org/wp-content/uploads/2015/03/Program-and-system-information-protocol-implementation-guidelines-for-broadcaster.pdf |
| 32 | // is one minute. Consider any EIT event seen > 2 minutes in the past as stale. |
| 33 | return scan_time + 2 * 60 < time(NULL); |
33 | 34 | } |
34 | 35 | |
35 | | public: |
36 | 36 | uint32_t start_time; |
37 | 37 | uint32_t length; |
38 | 38 | uint32_t etm; |
39 | 39 | uint32_t desc_length; |
40 | 40 | QString title; |
41 | 41 | const unsigned char *desc; |
| 42 | |
| 43 | private: |
| 44 | // The time the event was created. |
| 45 | time_t scan_time; |
42 | 46 | }; |
43 | 47 | |
| 48 | // An entry from the ETT table containing description text for an event. |
| 49 | class ATSCEtt |
| 50 | { |
| 51 | public: |
| 52 | explicit ATSCEtt(QString text) : ett_text(text), scan_time(time(NULL)) {} |
| 53 | |
| 54 | bool IsStale() const { |
| 55 | // The minimum recommended repetition time for ETT events according to |
| 56 | // http://atsc.org/wp-content/uploads/2015/03/Program-and-system-information-protocol-implementation-guidelines-for-broadcaster.pdf |
| 57 | // is one minute. Consider any ETT event seen > 2 minutes in the past as stale. |
| 58 | return scan_time + 2 * 60 < time(NULL); |
| 59 | } |
| 60 | |
| 61 | QString ett_text; |
| 62 | |
| 63 | private: |
| 64 | // The time the ETT was created. |
| 65 | time_t scan_time; |
| 66 | }; |
| 67 | |
| 68 | |
44 | 69 | typedef QMap<uint,ATSCEvent> EventIDToATSCEvent; |
45 | | typedef QMap<uint,QString> EventIDToETT; |
| 70 | typedef QMap<uint,ATSCEtt> EventIDToETT; |
46 | 71 | typedef QMap<uint,EventIDToATSCEvent> ATSCSRCToEvents; |
47 | 72 | typedef QMap<uint,EventIDToETT> ATSCSRCToETTs; |
48 | 73 | typedef QMap<unsigned long long,uint> ServiceToChanID; |
--
2.5.0
From ed9ccf18022f7d241209c25639408a582fed6a9e Mon Sep 17 00:00:00 2001
From: carlpny <carlpny@gmail.com>
Date: Fri, 20 Nov 2015 09:33:36 -0800
Subject: [PATCH 2/2] Change LOG to DEBUG.
---
mythtv/libs/libmythtv/eithelper.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mythtv/libs/libmythtv/eithelper.cpp b/mythtv/libs/libmythtv/eithelper.cpp
index 04035ca..58ea61f 100644
a
|
b
|
void EITHelper::AddETT(uint atsc_major, uint atsc_minor, |
229 | 229 | if (existing_unmatched_ett_it != elist.end() && |
230 | 230 | existing_unmatched_ett_it->ett_text != next_ett_text) |
231 | 231 | { |
232 | | LOG(VB_EIT, LOG_INFO, LOC + |
| 232 | LOG(VB_EIT, LOG_DEBUG, LOC + |
233 | 233 | QString("Overwriting previously unmatched ett. stale: %1 major: %2 " |
234 | 234 | "minor: %3 old ett: %4 new ett: %5") |
235 | 235 | .arg(existing_unmatched_ett_it->IsStale()) |