Ticket #11870: mythtv_ChannelScanSM_simplify_locking_poc.patch
File mythtv_ChannelScanSM_simplify_locking_poc.patch, 24.4 KB (added by , 11 years ago) |
---|
-
mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp
diff --git a/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp b/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp index 3f02209..cbb685c 100644
a b void ChannelScanSM::SetAnalog(bool is_analog) 253 253 254 254 void ChannelScanSM::HandleAllGood(void) 255 255 { 256 QMutexLocker locker(&lock); 257 258 QString cur_chan = (*current).FriendlyName; 259 QStringList list = cur_chan.split(" ", QString::SkipEmptyParts); 260 QString freqid = (list.size() >= 2) ? list[1] : cur_chan; 261 262 bool ok = false; 263 264 QString msg = QObject::tr("Updated Channel %1").arg(cur_chan); 265 266 if (!ChannelUtil::FindChannel(sourceID, freqid)) 267 { 268 int chanid = ChannelUtil::CreateChanID(sourceID, freqid); 269 270 QString callsign = QString("%1-%2") 271 .arg(ChannelUtil::GetUnknownCallsign()).arg(chanid); 272 273 ok = ChannelUtil::CreateChannel( 274 0 /* mplexid */, 275 sourceID, 276 chanid, 277 callsign, 278 "" /* service name */, 279 freqid /* channum */, 280 0 /* service id */, 281 0 /* ATSC major channel */, 282 0 /* ATSC minor channel */, 283 false /* use on air guide */, 284 false /* hidden */, 285 false /* hidden in guide */, 286 freqid); 287 288 msg = (ok) ? 289 QObject::tr("Added Channel %1").arg(cur_chan) : 290 QObject::tr("Failed to add channel %1").arg(cur_chan); 291 } 292 else 293 { 294 // nothing to do here, XMLTV & DataDirect have better info 295 } 296 297 scan_monitor->ScanAppendTextToLog(msg); 298 299 // tell UI we are done with these channels 300 if (scanning) 301 { 302 UpdateScanPercentCompleted(); 303 waitingForTables = false; 304 nextIt = current.nextTransport(); 305 } 256 postEvent(Event(kEventReceivedAllGood)); 306 257 } 307 258 308 259 /** … … bool ChannelScanSM::ScanExistingTransports(uint sourceid, bool follow_nit) 360 311 361 312 void ChannelScanSM::HandlePAT(const ProgramAssociationTable *pat) 362 313 { 363 QMutexLocker locker(&lock); 364 365 LOG(VB_CHANSCAN, LOG_INFO, LOC + 366 QString("Got a Program Association Table for %1") 367 .arg((*current).FriendlyName) + "\n" + pat->toString()); 368 369 // Add pmts to list, so we can do MPEG scan properly. 370 ScanStreamData *sd = GetDTVSignalMonitor()->GetScanStreamData(); 371 for (uint i = 0; i < pat->ProgramCount(); i++) 372 { 373 if (pat->ProgramPID(i)) // don't add NIT "program", MPEG/ATSC safe. 374 sd->AddListeningPID(pat->ProgramPID(i)); 375 } 314 Event event(kEventReceivedPAT); 315 event.table = new ProgramAssociationTable(*pat); 316 postEvent(event); 376 317 } 377 318 378 319 void ChannelScanSM::HandlePMT(uint, const ProgramMapTable *pmt) 379 320 { 380 QMutexLocker locker(&lock); 381 382 LOG(VB_CHANSCAN, LOG_INFO, LOC + QString("Got a Program Map Table for %1") 383 .arg((*current).FriendlyName) + "\n" + pmt->toString()); 384 385 if (!currentTestingDecryption && pmt->IsEncrypted(GetDTVChannel()->GetSIStandard())) 386 currentEncryptionStatus[pmt->ProgramNumber()] = kEncUnknown; 321 Event event(kEventReceivedPMT); 322 event.table = new ProgramMapTable(*pmt); 323 postEvent(event); 387 324 } 388 325 389 326 void ChannelScanSM::HandleVCT(uint, const VirtualChannelTable *vct) 390 327 { 391 QMutexLocker locker(&lock); 328 Event event(kEventReceivedVCT); 329 switch( vct->TableID() ) 330 { 331 case TableID::TVCT: 332 event.table = new TerrestrialVirtualChannelTable(*vct); 333 break; 392 334 393 LOG(VB_CHANSCAN, LOG_INFO, LOC +394 QString("Got a Virtual Channel Table for %1")395 .arg((*current).FriendlyName) + "\n" + vct->toString());335 case TableID::CVCT: 336 event.table = new CableVirtualChannelTable(*vct); 337 break; 396 338 397 for (uint i = 0; !currentTestingDecryption && i < vct->ChannelCount(); i++) 398 { 399 if (vct->IsAccessControlled(i)) 400 { 401 currentEncryptionStatus[vct->ProgramNumber(i)] = kEncUnknown; 402 } 339 default: assert(0); 403 340 } 404 405 UpdateChannelInfo(true); 341 postEvent(event); 406 342 } 407 343 408 344 void ChannelScanSM::HandleMGT(const MasterGuideTable *mgt) 409 345 { 410 QMutexLocker locker(&lock); 411 412 LOG(VB_CHANSCAN, LOG_INFO, LOC + QString("Got the Master Guide for %1") 413 .arg((*current).FriendlyName) + "\n" + mgt->toString()); 414 415 UpdateChannelInfo(true); 346 Event event(kEventReceivedMGT); 347 event.table = new MasterGuideTable(*mgt); 348 postEvent(event); 416 349 } 417 350 418 351 void ChannelScanSM::HandleSDT(uint tsid, const ServiceDescriptionTable *sdt) 419 352 { 420 QMutexLocker locker(&lock); 421 422 LOG(VB_CHANSCAN, LOG_INFO, LOC + 423 QString("Got a Service Description Table for %1") 424 .arg((*current).FriendlyName) + "\n" + sdt->toString()); 425 426 // If this is Astra 28.2 add start listening for Freesat BAT and SDTo 427 if (!setOtherTables && (sdt->OriginalNetworkID() == 2 || 428 sdt->OriginalNetworkID() == 59)) 429 { 430 GetDTVSignalMonitor()->GetScanStreamData()-> 431 SetFreesatAdditionalSI(true); 432 setOtherTables = true; 433 // The whole BAT & SDTo group comes round in 10s 434 otherTableTimeout = 10000; 435 // Delay processing the SDT until we've seen BATs and SDTos 436 otherTableTime = timer.elapsed() + otherTableTimeout; 437 438 LOG(VB_CHANSCAN, LOG_INFO, LOC + 439 QString("SDT has OriginalNetworkID %1, look for " 440 "additional Freesat SI").arg(sdt->OriginalNetworkID())); 441 } 442 443 if ((uint)timer.elapsed() < otherTableTime) 444 { 445 // Set the version for the SDT so we see it again. 446 GetDTVSignalMonitor()->GetDVBStreamData()->SetVersionSDT(sdt->TSID(), -1, 0); 447 } 448 449 uint id = sdt->OriginalNetworkID() << 16 | sdt->TSID(); 450 ts_scanned.insert(id); 451 452 for (uint i = 0; !currentTestingDecryption && i < sdt->ServiceCount(); i++) 453 { 454 if (sdt->IsEncrypted(i)) 455 { 456 currentEncryptionStatus[sdt->ServiceID(i)] = kEncUnknown; 457 } 458 } 459 460 UpdateChannelInfo(true); 353 Event event(kEventReceivedSDT); 354 event.tsid = tsid; 355 event.table = new ServiceDescriptionTable(*sdt); 356 postEvent(event); 461 357 } 462 358 463 359 void ChannelScanSM::HandleNIT(const NetworkInformationTable *nit) 464 360 { 465 QMutexLocker locker(&lock); 466 467 LOG(VB_CHANSCAN, LOG_INFO, LOC + 468 QString("Got a Network Information Table for %1") 469 .arg((*current).FriendlyName) + "\n" + nit->toString()); 470 471 UpdateChannelInfo(true); 361 Event event(kEventReceivedNIT); 362 event.table = new NetworkInformationTable(*nit); 363 postEvent(event); 472 364 } 473 365 474 366 void ChannelScanSM::HandleBAT(const BouquetAssociationTable *bat) 475 367 { 476 QMutexLocker locker(&lock); 477 478 LOG(VB_CHANSCAN, LOG_INFO, LOC + "Got a Bouquet Association Table\n" + 479 bat->toString()); 480 481 otherTableTime = timer.elapsed() + otherTableTimeout; 482 483 for (uint i = 0; i < bat->TransportStreamCount(); i++) 484 { 485 uint tsid = bat->TSID(i); 486 uint netid = bat->OriginalNetworkID(i); 487 desc_list_t parsed = 488 MPEGDescriptor::Parse(bat->TransportDescriptors(i), 489 bat->TransportDescriptorsLength(i)); 490 // Look for default authority 491 const unsigned char *def_auth = 492 MPEGDescriptor::Find(parsed, DescriptorID::default_authority); 493 const unsigned char *serv_list = 494 MPEGDescriptor::Find(parsed, DescriptorID::service_list); 495 496 if (def_auth && serv_list) 497 { 498 DefaultAuthorityDescriptor authority(def_auth); 499 ServiceListDescriptor services(serv_list); 500 501 for (uint j = 0; j < services.ServiceCount(); j++) 502 { 503 // If the default authority is given in the SDT this 504 // overrides any definition in the BAT (or in the NIT) 505 LOG(VB_CHANSCAN, LOG_INFO, LOC + 506 QString("found default authority(BAT) for service %1 %2 %3") 507 .arg(netid).arg(tsid).arg(services.ServiceID(j))); 508 uint64_t index = ((uint64_t)netid << 32) | (tsid << 16) | 509 services.ServiceID(j); 510 if (! defAuthorities.contains(index)) 511 defAuthorities[index] = authority.DefaultAuthority(); 512 } 513 } 514 } 368 Event event(kEventReceivedBAT); 369 event.table = new BouquetAssociationTable(*bat); 370 postEvent(event); 515 371 } 516 372 517 373 void ChannelScanSM::HandleSDTo(uint tsid, const ServiceDescriptionTable *sdt) 518 374 { 519 QMutexLocker locker(&lock); 520 521 LOG(VB_CHANSCAN, LOG_INFO, LOC + 522 "Got a Service Description Table (other)\n" + sdt->toString()); 523 524 otherTableTime = timer.elapsed() + otherTableTimeout; 525 526 uint netid = sdt->OriginalNetworkID(); 527 528 for (uint i = 0; i < sdt->ServiceCount(); i++) 529 { 530 uint serviceId = sdt->ServiceID(i); 531 desc_list_t parsed = 532 MPEGDescriptor::Parse(sdt->ServiceDescriptors(i), 533 sdt->ServiceDescriptorsLength(i)); 534 // Look for default authority 535 const unsigned char *def_auth = 536 MPEGDescriptor::Find(parsed, DescriptorID::default_authority); 537 if (def_auth) 538 { 539 DefaultAuthorityDescriptor authority(def_auth); 540 LOG(VB_CHANSCAN, LOG_INFO, LOC + 541 QString("found default authority(SDTo) for service %1 %2 %3") 542 .arg(netid).arg(tsid).arg(serviceId)); 543 defAuthorities[((uint64_t)netid << 32) | (tsid << 16) | serviceId] = 544 authority.DefaultAuthority(); 545 } 546 } 375 Event event(kEventReceivedSDTo); 376 event.tsid = tsid; 377 event.table = new ServiceDescriptionTable(*sdt); 378 postEvent(event); 547 379 } 548 380 549 381 void ChannelScanSM::HandleEncryptionStatus(uint pnum, bool encrypted) 550 382 { 551 QMutexLocker locker(&lock); 552 553 currentEncryptionStatus[pnum] = encrypted ? kEncEncrypted : kEncDecrypted; 554 555 if (kEncDecrypted == currentEncryptionStatus[pnum]) 556 currentTestingDecryption = false; 557 558 UpdateChannelInfo(true); 383 Event event(kEventEncryptionStatus); 384 event.pnum = pnum; 385 event.encrypted = encrypted; 386 postEvent(event); 559 387 } 560 388 561 389 bool ChannelScanSM::TestNextProgramEncryption(void) … … void ChannelScanSM::run(void) 1478 1306 1479 1307 while (!threadExit) 1480 1308 { 1309 Event event; 1310 if( waitEvent(event, 50) ) 1311 { 1312 processEvent(event); 1313 } 1314 1481 1315 if (scanning) 1482 1316 HandleActiveScan(); 1483 1484 usleep(10 * 1000);1485 1317 } 1486 1318 1487 1319 LOG(VB_CHANSCAN, LOG_INFO, LOC + "run -- end"); … … bool ChannelScanSM::HasTimedOut(void) 1571 1403 */ 1572 1404 void ChannelScanSM::HandleActiveScan(void) 1573 1405 { 1574 QMutexLocker locker(&lock);1575 1576 1406 bool do_post_insertion = waitingForTables; 1577 1407 1578 1408 if (!HasTimedOut()) … … void ChannelScanSM::HandleActiveScan(void) 1585 1415 return; 1586 1416 1587 1417 // Stop signal monitor for previous transport 1588 locker.unlock();1589 1418 signalMonitor->Stop(); 1590 locker.relock();1591 1419 } 1592 1420 1593 1421 if (0 == nextIt.offset() && nextIt == scanTransports.begin()) … … bool ChannelScanSM::CheckImportedList( 2077 1905 2078 1906 return found; 2079 1907 } 1908 1909 void ChannelScanSM::postEvent(const Event &event) 1910 { 1911 { 1912 QMutexLocker locker(&eventLock); 1913 eventQueue.push_back(event); 1914 } 1915 eventSemaphore.release(); 1916 } 1917 1918 bool ChannelScanSM::waitEvent(Event &event, int32_t timeout) 1919 { 1920 if( eventSemaphore.tryAcquire(1, timeout) ) 1921 { 1922 QMutexLocker locker(&eventLock); 1923 event = eventQueue.front(); 1924 eventQueue.pop_front(); 1925 return true; 1926 } 1927 return false; 1928 } 1929 void ChannelScanSM::processEvent(Event &event) 1930 { 1931 if( !scanning ) 1932 { 1933 delete event.table; 1934 event.table = NULL; 1935 return; 1936 } 1937 1938 assert( event.type!=kEventInvalid ); 1939 switch( event.type ) 1940 { 1941 case kEventInvalid: 1942 //TODO:: print error or assert 1943 break; 1944 case kEventWakeup: 1945 UpdateChannelInfo(true); 1946 break; 1947 case kEventReceivedPAT: 1948 processPAT(static_cast<ProgramAssociationTable *>(event.table)); 1949 break; 1950 case kEventReceivedPMT: 1951 processPMT(static_cast<ProgramMapTable *>(event.table)); 1952 break; 1953 case kEventEncryptionStatus: 1954 processEncryptionStatus(event.pnum, event.encrypted); 1955 break; 1956 case kEventReceivedMGT: 1957 processMGT(static_cast<MasterGuideTable *>(event.table)); 1958 break; 1959 case kEventReceivedVCT: 1960 processVCT(event.tsid, static_cast<VirtualChannelTable *>(event.table)); 1961 break; 1962 case kEventReceivedNIT: 1963 processNIT(static_cast<NetworkInformationTable *>(event.table)); 1964 break; 1965 case kEventReceivedSDT: 1966 processSDT(event.tsid, static_cast<ServiceDescriptionTable *>(event.table)); 1967 break; 1968 case kEventReceivedSDTo: 1969 processSDTo(event.tsid, static_cast<ServiceDescriptionTable *>(event.table)); 1970 break; 1971 case kEventReceivedBAT: 1972 processBAT(static_cast<BouquetAssociationTable *>(event.table)); 1973 break; 1974 case kEventReceivedAllGood: 1975 processAllGood(); 1976 break; 1977 } 1978 1979 delete event.table; 1980 event.table = NULL; 1981 } 1982 1983 void ChannelScanSM::processPAT(const ProgramAssociationTable *pat) 1984 { 1985 LOG(VB_CHANSCAN, LOG_INFO, LOC + 1986 QString("Got a Program Association Table for %1") 1987 .arg((*current).FriendlyName) + "\n" + pat->toString()); 1988 1989 // Add pmts to list, so we can do MPEG scan properly. 1990 ScanStreamData *sd = GetDTVSignalMonitor()->GetScanStreamData(); 1991 for (uint i = 0; i < pat->ProgramCount(); i++) 1992 { 1993 if (pat->ProgramPID(i)) // don't add NIT "program", MPEG/ATSC safe. 1994 sd->AddListeningPID(pat->ProgramPID(i)); 1995 } 1996 } 1997 1998 void ChannelScanSM::processPMT(const ProgramMapTable*pmt) 1999 { 2000 LOG(VB_CHANSCAN, LOG_INFO, LOC + QString("Got a Program Map Table for %1") 2001 .arg((*current).FriendlyName) + "\n" + pmt->toString()); 2002 2003 if (!currentTestingDecryption && pmt->IsEncrypted(GetDTVChannel()->GetSIStandard())) 2004 currentEncryptionStatus[pmt->ProgramNumber()] = kEncUnknown; 2005 } 2006 2007 void ChannelScanSM::processEncryptionStatus(uint pnum, bool encrypted) 2008 { 2009 currentEncryptionStatus[pnum] = encrypted ? kEncEncrypted : kEncDecrypted; 2010 2011 if (kEncDecrypted == currentEncryptionStatus[pnum]) 2012 currentTestingDecryption = false; 2013 2014 UpdateChannelInfo(true); 2015 } 2016 2017 void ChannelScanSM::processMGT(const MasterGuideTable *mgt) 2018 { 2019 LOG(VB_CHANSCAN, LOG_INFO, LOC + QString("Got the Master Guide for %1") 2020 .arg((*current).FriendlyName) + "\n" + mgt->toString()); 2021 2022 UpdateChannelInfo(true); 2023 } 2024 2025 void ChannelScanSM::processVCT(uint tsid, const VirtualChannelTable *vct) 2026 { 2027 LOG(VB_CHANSCAN, LOG_INFO, LOC + 2028 QString("Got a Virtual Channel Table for %1") 2029 .arg((*current).FriendlyName) + "\n" + vct->toString()); 2030 2031 for (uint i = 0; !currentTestingDecryption && i < vct->ChannelCount(); i++) 2032 { 2033 if (vct->IsAccessControlled(i)) 2034 { 2035 currentEncryptionStatus[vct->ProgramNumber(i)] = kEncUnknown; 2036 } 2037 } 2038 2039 UpdateChannelInfo(true); 2040 } 2041 2042 void ChannelScanSM::processNIT(const NetworkInformationTable *nit) 2043 { 2044 LOG(VB_CHANSCAN, LOG_INFO, LOC + 2045 QString("Got a Network Information Table for %1") 2046 .arg((*current).FriendlyName) + "\n" + nit->toString()); 2047 2048 UpdateChannelInfo(true); 2049 } 2050 2051 void ChannelScanSM::processSDT(uint tsid, const ServiceDescriptionTable *sdt) 2052 { 2053 LOG(VB_CHANSCAN, LOG_INFO, LOC + 2054 QString("Got a Service Description Table for %1") 2055 .arg((*current).FriendlyName) + "\n" + sdt->toString()); 2056 2057 // If this is Astra 28.2 add start listening for Freesat BAT and SDTo 2058 if (!setOtherTables && (sdt->OriginalNetworkID() == 2 || 2059 sdt->OriginalNetworkID() == 59)) 2060 { 2061 GetDTVSignalMonitor()->GetScanStreamData()-> 2062 SetFreesatAdditionalSI(true); 2063 setOtherTables = true; 2064 // The whole BAT & SDTo group comes round in 10s 2065 otherTableTimeout = 10000; 2066 // Delay processing the SDT until we've seen BATs and SDTos 2067 otherTableTime = timer.elapsed() + otherTableTimeout; 2068 2069 LOG(VB_CHANSCAN, LOG_INFO, LOC + 2070 QString("SDT has OriginalNetworkID %1, look for " 2071 "additional Freesat SI").arg(sdt->OriginalNetworkID())); 2072 } 2073 2074 if ((uint)timer.elapsed() < otherTableTime) 2075 { 2076 // Set the version for the SDT so we see it again. 2077 GetDTVSignalMonitor()->GetDVBStreamData()->SetVersionSDT(sdt->TSID(), -1, 0); 2078 } 2079 2080 uint id = sdt->OriginalNetworkID() << 16 | sdt->TSID(); 2081 ts_scanned.insert(id); 2082 2083 for (uint i = 0; !currentTestingDecryption && i < sdt->ServiceCount(); i++) 2084 { 2085 if (sdt->IsEncrypted(i)) 2086 { 2087 currentEncryptionStatus[sdt->ServiceID(i)] = kEncUnknown; 2088 } 2089 } 2090 2091 UpdateChannelInfo(true); 2092 } 2093 2094 void ChannelScanSM::processSDTo(uint tsid, const ServiceDescriptionTable *sdt) 2095 { 2096 LOG(VB_CHANSCAN, LOG_INFO, LOC + 2097 "Got a Service Description Table (other)\n" + sdt->toString()); 2098 2099 otherTableTime = timer.elapsed() + otherTableTimeout; 2100 2101 uint netid = sdt->OriginalNetworkID(); 2102 2103 for (uint i = 0; i < sdt->ServiceCount(); i++) 2104 { 2105 uint serviceId = sdt->ServiceID(i); 2106 desc_list_t parsed = 2107 MPEGDescriptor::Parse(sdt->ServiceDescriptors(i), 2108 sdt->ServiceDescriptorsLength(i)); 2109 // Look for default authority 2110 const unsigned char *def_auth = 2111 MPEGDescriptor::Find(parsed, DescriptorID::default_authority); 2112 if (def_auth) 2113 { 2114 DefaultAuthorityDescriptor authority(def_auth); 2115 LOG(VB_CHANSCAN, LOG_INFO, LOC + 2116 QString("found default authority(SDTo) for service %1 %2 %3") 2117 .arg(netid).arg(tsid).arg(serviceId)); 2118 defAuthorities[((uint64_t)netid << 32) | (tsid << 16) | serviceId] = 2119 authority.DefaultAuthority(); 2120 } 2121 } 2122 } 2123 2124 void ChannelScanSM::processBAT(const BouquetAssociationTable *bat) 2125 { 2126 LOG(VB_CHANSCAN, LOG_INFO, LOC + "Got a Bouquet Association Table\n" + 2127 bat->toString()); 2128 2129 otherTableTime = timer.elapsed() + otherTableTimeout; 2130 2131 for (uint i = 0; i < bat->TransportStreamCount(); i++) 2132 { 2133 uint tsid = bat->TSID(i); 2134 uint netid = bat->OriginalNetworkID(i); 2135 desc_list_t parsed = 2136 MPEGDescriptor::Parse(bat->TransportDescriptors(i), 2137 bat->TransportDescriptorsLength(i)); 2138 // Look for default authority 2139 const unsigned char *def_auth = 2140 MPEGDescriptor::Find(parsed, DescriptorID::default_authority); 2141 const unsigned char *serv_list = 2142 MPEGDescriptor::Find(parsed, DescriptorID::service_list); 2143 2144 if (def_auth && serv_list) 2145 { 2146 DefaultAuthorityDescriptor authority(def_auth); 2147 ServiceListDescriptor services(serv_list); 2148 2149 for (uint j = 0; j < services.ServiceCount(); j++) 2150 { 2151 // If the default authority is given in the SDT this 2152 // overrides any definition in the BAT (or in the NIT) 2153 LOG(VB_CHANSCAN, LOG_INFO, LOC + 2154 QString("found default authority(BAT) for service %1 %2 %3") 2155 .arg(netid).arg(tsid).arg(services.ServiceID(j))); 2156 uint64_t index = ((uint64_t)netid << 32) | (tsid << 16) | 2157 services.ServiceID(j); 2158 if (! defAuthorities.contains(index)) 2159 defAuthorities[index] = authority.DefaultAuthority(); 2160 } 2161 } 2162 } 2163 } 2164 2165 void ChannelScanSM::processAllGood() 2166 { 2167 QString cur_chan = (*current).FriendlyName; 2168 QStringList list = cur_chan.split(" ", QString::SkipEmptyParts); 2169 QString freqid = (list.size() >= 2) ? list[1] : cur_chan; 2170 2171 bool ok = false; 2172 2173 QString msg = QObject::tr("Updated Channel %1").arg(cur_chan); 2174 2175 if (!ChannelUtil::FindChannel(sourceID, freqid)) 2176 { 2177 int chanid = ChannelUtil::CreateChanID(sourceID, freqid); 2178 2179 QString callsign = QString("%1-%2") 2180 .arg(ChannelUtil::GetUnknownCallsign()).arg(chanid); 2181 2182 ok = ChannelUtil::CreateChannel( 2183 0 /* mplexid */, 2184 sourceID, 2185 chanid, 2186 callsign, 2187 "" /* service name */, 2188 freqid /* channum */, 2189 0 /* service id */, 2190 0 /* ATSC major channel */, 2191 0 /* ATSC minor channel */, 2192 false /* use on air guide */, 2193 false /* hidden */, 2194 false /* hidden in guide */, 2195 freqid); 2196 2197 msg = (ok) ? 2198 QObject::tr("Added Channel %1").arg(cur_chan) : 2199 QObject::tr("Failed to add channel %1").arg(cur_chan); 2200 } 2201 else 2202 { 2203 // nothing to do here, XMLTV & DataDirect have better info 2204 } 2205 2206 scan_monitor->ScanAppendTextToLog(msg); 2207 2208 // tell UI we are done with these channels 2209 if (scanning) 2210 { 2211 UpdateScanPercentCompleted(); 2212 waitingForTables = false; 2213 nextIt = current.nextTransport(); 2214 } 2215 } -
mythtv/libs/libmythtv/channelscan/channelscan_sm.h
diff --git a/mythtv/libs/libmythtv/channelscan/channelscan_sm.h b/mythtv/libs/libmythtv/channelscan/channelscan_sm.h index 813113a..2c90a9b 100644
a b 37 37 #include <QPair> 38 38 #include <QMap> 39 39 #include <QSet> 40 #include <QSemaphore> 40 41 41 42 // MythTV includes 42 43 #include "frequencytables.h" … … class ChannelScanSM : public MPEGStreamListener, 154 155 void HandleBAT(const BouquetAssociationTable*); 155 156 156 157 private: 158 enum EventType 159 { 160 kEventInvalid, 161 kEventWakeup, 162 kEventReceivedPAT, 163 kEventReceivedPMT, 164 kEventEncryptionStatus, 165 kEventReceivedMGT, 166 kEventReceivedVCT, 167 kEventReceivedNIT, 168 kEventReceivedSDT, 169 kEventReceivedSDTo, 170 kEventReceivedBAT, 171 kEventReceivedAllGood, 172 }; 173 struct Event 174 { 175 Event() : type(kEventInvalid), tsid(0), table(NULL), encrypted(false) {} 176 Event(EventType type_) : type(type_), tsid(0), table(NULL), encrypted(false) {} 177 EventType type; 178 union 179 { 180 uint tsid; 181 uint pnum; 182 }; 183 PSIPTable *table; 184 bool encrypted; 185 }; 186 private: 157 187 // some useful gets 158 188 DTVChannel *GetDTVChannel(void); 159 189 const DTVChannel *GetDTVChannel(void) const; … … class ChannelScanSM : public MPEGStreamListener, 195 225 196 226 static QString loc(const ChannelScanSM*); 197 227 228 void postEvent(const Event &event); 229 bool waitEvent(Event &event, int32_t timeout); 230 231 void processEvent(Event &event); 232 void processPAT(const ProgramAssociationTable*); 233 void processPMT(const ProgramMapTable*); 234 void processEncryptionStatus(uint pnum, bool encrypted); 235 236 void processMGT(const MasterGuideTable*); 237 void processVCT(uint tsid, const VirtualChannelTable*); 238 void processNIT(const NetworkInformationTable*); 239 void processSDT(uint tsid, const ServiceDescriptionTable*); 240 void processSDTo(uint tsid, const ServiceDescriptionTable*); 241 void processBAT(const BouquetAssociationTable*); 242 void processAllGood(); 243 198 244 static const uint kDVBTableTimeout; 199 245 static const uint kATSCTableTimeout; 200 246 static const uint kMPEGTableTimeout; … … class ChannelScanSM : public MPEGStreamListener, 217 263 // Optional info 218 264 DTVTunerType scanDTVTunerType; 219 265 220 /// The big lock221 mutable QMutex lock;222 223 266 // State 224 267 bool scanning; 225 268 volatile bool threadExit; … … class ChannelScanSM : public MPEGStreamListener, 248 291 249 292 /// Scanner thread, runs ChannelScanSM::run() 250 293 MThread *scannerThread; 294 295 QSemaphore eventSemaphore; 296 QMutex eventLock; 297 QVector<Event> eventQueue; 298 251 299 }; 252 300 253 301 inline void ChannelScanSM::UpdateScanPercentCompleted(void)