|
MythTV
0.26-pre
|
00001 // -*- Mode: c++ -*- 00002 // Copyright (c) 2003-2004, Daniel Thor Kristjansson 00003 #include <algorithm> 00004 using namespace std; 00005 00006 #include "dvbstreamdata.h" 00007 #include "dvbtables.h" 00008 #include "premieretables.h" 00009 #include "eithelper.h" 00010 00011 #define PREMIERE_ONID 133 00012 #define FREESAT_EIT_PID 3842 00013 #define MCA_ONID 6144 00014 #define MCA_EIT_TSID 136 00015 #define MCA_EIT_PID 1018 00016 00017 // service_id is synonymous with the MPEG program number in the PMT. 00018 DVBStreamData::DVBStreamData(uint desired_netid, uint desired_tsid, 00019 int desired_program, bool cacheTables) 00020 : MPEGStreamData(desired_program, cacheTables), 00021 _desired_netid(desired_netid), _desired_tsid(desired_tsid), 00022 _dvb_eit_dishnet_long(false), 00023 _nit_version(-2), _nito_version(-2) 00024 { 00025 SetVersionNIT(-1,0); 00026 SetVersionNITo(-1,0); 00027 AddListeningPID(DVB_NIT_PID); 00028 AddListeningPID(DVB_SDT_PID); 00029 AddListeningPID(DVB_TDT_PID); 00030 } 00031 00032 DVBStreamData::~DVBStreamData() 00033 { 00034 Reset(_desired_netid, _desired_tsid, _desired_program); 00035 00036 QMutexLocker locker(&_listener_lock); 00037 _dvb_main_listeners.clear(); 00038 _dvb_other_listeners.clear(); 00039 _dvb_eit_listeners.clear(); 00040 _dvb_has_eit.clear(); 00041 } 00042 00043 void DVBStreamData::SetDesiredService(uint netid, uint tsid, int serviceid) 00044 { 00045 bool reset = true; 00046 00047 if (HasCachedAllSDT(tsid, true)) 00048 { 00049 const sdt_ptr_t first_sdt = GetCachedSDT(tsid, 0, true); 00050 uint networkID = first_sdt->OriginalNetworkID(); 00051 if (networkID == netid) 00052 { 00053 reset = false; 00054 _desired_netid = netid; 00055 _desired_tsid = tsid; 00056 uint last_section = first_sdt->LastSection(); 00057 ProcessSDT(_desired_tsid, first_sdt); 00058 ReturnCachedTable(first_sdt); 00059 for (uint i = 1; i <= last_section; ++i) 00060 { 00061 const sdt_ptr_t sdt = GetCachedSDT(_desired_tsid, i, true); 00062 ProcessSDT(_desired_tsid, sdt); 00063 ReturnCachedTable(sdt); 00064 } 00065 SetDesiredProgram(serviceid); 00066 } 00067 } 00068 00069 if (reset) 00070 Reset(netid, tsid, serviceid); 00071 } 00072 00073 00078 bool DVBStreamData::IsRedundant(uint pid, const PSIPTable &psip) const 00079 { 00080 if (MPEGStreamData::IsRedundant(pid, psip)) 00081 return true; 00082 00083 const int table_id = psip.TableID(); 00084 const int version = psip.Version(); 00085 00086 if (TableID::NIT == table_id) 00087 { 00088 if (VersionNIT() != version) 00089 return false; 00090 return NITSectionSeen(psip.Section()); 00091 } 00092 00093 if (TableID::SDT == table_id) 00094 { 00095 if (VersionSDT(psip.TableIDExtension()) != version) 00096 return false; 00097 return SDTSectionSeen(psip.TableIDExtension(), psip.Section()); 00098 } 00099 00100 if (TableID::TDT == table_id) 00101 return false; 00102 00103 if (TableID::BAT == table_id) 00104 { 00105 if (VersionBAT(psip.TableIDExtension()) != version) 00106 return false; 00107 return BATSectionSeen(psip.TableIDExtension(), psip.Section()); 00108 } 00109 00110 bool is_eit = false; 00111 if (DVB_EIT_PID == pid || FREESAT_EIT_PID == pid) 00112 { 00113 // Standard Now/Next Event Information Tables for this transport 00114 is_eit |= TableID::PF_EIT == table_id; 00115 // Standard Future Event Information Tables for this transport 00116 is_eit |= (TableID::SC_EITbeg <= table_id && 00117 TableID::SC_EITend >= table_id); 00118 } 00119 if (is_eit) 00120 { 00121 uint service_id = psip.TableIDExtension(); 00122 if (VersionEIT(table_id, service_id) != version) 00123 return false; 00124 return EITSectionSeen(table_id, service_id, psip.Section()); 00125 } 00126 00128 // Other transport tables 00129 00130 if (TableID::NITo == table_id) 00131 { 00132 if (VersionNITo() != version) 00133 return false; 00134 return NIToSectionSeen(psip.Section()); 00135 } 00136 00137 if (TableID::SDTo == table_id) 00138 { 00139 if (VersionSDTo(psip.TableIDExtension()) != version) 00140 return false; 00141 return SDToSectionSeen(psip.TableIDExtension(), psip.Section()); 00142 } 00143 00144 if (DVB_EIT_PID == pid || FREESAT_EIT_PID == pid || MCA_EIT_PID == pid) 00145 { 00146 // Standard Now/Next Event Information Tables for other transport 00147 is_eit |= TableID::PF_EITo == table_id; 00148 // Standard Future Event Information Tables for other transports 00149 is_eit |= (TableID::SC_EITbego <= table_id && 00150 TableID::SC_EITendo >= table_id); 00151 } 00152 if (DVB_DNLONG_EIT_PID == pid || DVB_BVLONG_EIT_PID == pid) 00153 { 00154 // Dish Network and Bev Long Term Future Event Information 00155 // for all transports 00156 is_eit |= (TableID::DN_EITbego <= table_id && 00157 TableID::DN_EITendo >= table_id); 00158 } 00159 if (is_eit) 00160 { 00161 uint service_id = psip.TableIDExtension(); 00162 if (VersionEIT(table_id, service_id) != version) 00163 return false; 00164 return EITSectionSeen(table_id, service_id, psip.Section()); 00165 } 00166 00167 if (((PREMIERE_EIT_DIREKT_PID == pid) || (PREMIERE_EIT_SPORT_PID == pid)) && 00168 TableID::PREMIERE_CIT == table_id) 00169 { 00170 uint content_id = PremiereContentInformationTable(psip).ContentID(); 00171 if (VersionCIT(content_id) != version) 00172 return false; 00173 return CITSectionSeen(content_id, psip.Section()); 00174 } 00175 00176 return false; 00177 } 00178 00179 void DVBStreamData::Reset(uint desired_netid, uint desired_tsid, 00180 int desired_serviceid) 00181 { 00182 MPEGStreamData::Reset(desired_serviceid); 00183 00184 _desired_netid = desired_netid; 00185 _desired_tsid = desired_tsid; 00186 00187 SetVersionNIT(-1,0); 00188 _sdt_versions.clear(); 00189 _sdt_section_seen.clear(); 00190 _eit_version.clear(); 00191 _eit_section_seen.clear(); 00192 _cit_version.clear(); 00193 _cit_section_seen.clear(); 00194 00195 SetVersionNITo(-1,0); 00196 _sdto_versions.clear(); 00197 _sdto_section_seen.clear(); 00198 _bat_versions.clear(); 00199 _bat_section_seen.clear(); 00200 00201 { 00202 _cache_lock.lock(); 00203 00204 nit_cache_t::iterator nit = _cached_nit.begin(); 00205 for (; nit != _cached_nit.end(); ++nit) 00206 DeleteCachedTable(*nit); 00207 _cached_nit.clear(); 00208 00209 sdt_cache_t::iterator sit = _cached_sdts.begin(); 00210 for (; sit != _cached_sdts.end(); ++sit) 00211 DeleteCachedTable(*sit); 00212 _cached_sdts.clear(); 00213 00214 _cache_lock.unlock(); 00215 } 00216 AddListeningPID(DVB_NIT_PID); 00217 AddListeningPID(DVB_SDT_PID); 00218 AddListeningPID(DVB_TDT_PID); 00219 } 00220 00225 bool DVBStreamData::HandleTables(uint pid, const PSIPTable &psip) 00226 { 00227 if (MPEGStreamData::HandleTables(pid, psip)) 00228 return true; 00229 00230 if (IsRedundant(pid, psip)) 00231 return true; 00232 00233 switch (psip.TableID()) 00234 { 00235 case TableID::NIT: 00236 { 00237 SetVersionNIT(psip.Version(), psip.LastSection()); 00238 SetNITSectionSeen(psip.Section()); 00239 00240 if (_cache_tables) 00241 { 00242 NetworkInformationTable *nit = 00243 new NetworkInformationTable(psip); 00244 CacheNIT(nit); 00245 QMutexLocker locker(&_listener_lock); 00246 for (uint i = 0; i < _dvb_main_listeners.size(); i++) 00247 _dvb_main_listeners[i]->HandleNIT(nit); 00248 } 00249 else 00250 { 00251 NetworkInformationTable nit(psip); 00252 QMutexLocker locker(&_listener_lock); 00253 for (uint i = 0; i < _dvb_main_listeners.size(); i++) 00254 _dvb_main_listeners[i]->HandleNIT(&nit); 00255 } 00256 00257 return true; 00258 } 00259 case TableID::SDT: 00260 { 00261 uint tsid = psip.TableIDExtension(); 00262 SetVersionSDT(tsid, psip.Version(), psip.LastSection()); 00263 SetSDTSectionSeen(tsid, psip.Section()); 00264 00265 if (_cache_tables) 00266 { 00267 ServiceDescriptionTable *sdt = 00268 new ServiceDescriptionTable(psip); 00269 CacheSDT(sdt); 00270 ProcessSDT(tsid, sdt); 00271 } 00272 else 00273 { 00274 ServiceDescriptionTable sdt(psip); 00275 ProcessSDT(tsid, &sdt); 00276 } 00277 00278 return true; 00279 } 00280 case TableID::TDT: 00281 { 00282 TimeDateTable tdt(psip); 00283 00284 UpdateTimeOffset(tdt.UTCUnix()); 00285 00286 QMutexLocker locker(&_listener_lock); 00287 for (uint i = 0; i < _dvb_main_listeners.size(); i++) 00288 _dvb_main_listeners[i]->HandleTDT(&tdt); 00289 00290 return true; 00291 } 00292 case TableID::NITo: 00293 { 00294 SetVersionNITo(psip.Version(), psip.LastSection()); 00295 SetNIToSectionSeen(psip.Section()); 00296 NetworkInformationTable nit(psip); 00297 00298 QMutexLocker locker(&_listener_lock); 00299 for (uint i = 0; i < _dvb_other_listeners.size(); i++) 00300 _dvb_other_listeners[i]->HandleNITo(&nit); 00301 00302 return true; 00303 } 00304 case TableID::SDTo: 00305 { 00306 uint tsid = psip.TableIDExtension(); 00307 SetVersionSDTo(tsid, psip.Version(), psip.LastSection()); 00308 SetSDToSectionSeen(tsid, psip.Section()); 00309 ServiceDescriptionTable sdt(psip); 00310 00311 // some providers send the SDT for the current multiplex as SDTo 00312 // this routine changes the TableID to SDT and recalculates the CRC 00313 if (_desired_netid == sdt.OriginalNetworkID() && 00314 _desired_tsid == tsid) 00315 { 00316 ServiceDescriptionTable *sdta = 00317 new ServiceDescriptionTable(psip); 00318 if (!sdta->Mutate()) 00319 { 00320 delete sdta; 00321 return true; 00322 } 00323 if (_cache_tables) 00324 { 00325 CacheSDT(sdta); 00326 ProcessSDT(tsid, sdta); 00327 } 00328 else 00329 { 00330 ProcessSDT(tsid, sdta); 00331 delete sdta; 00332 } 00333 return true; 00334 } 00335 00336 QMutexLocker locker(&_listener_lock); 00337 for (uint i = 0; i < _dvb_other_listeners.size(); i++) 00338 _dvb_other_listeners[i]->HandleSDTo(tsid, &sdt); 00339 00340 return true; 00341 } 00342 case TableID::BAT: 00343 { 00344 uint bid = psip.TableIDExtension(); 00345 SetVersionBAT(bid, psip.Version(), psip.LastSection()); 00346 SetBATSectionSeen(bid, psip.Section()); 00347 BouquetAssociationTable bat(psip); 00348 00349 QMutexLocker locker(&_listener_lock); 00350 for (uint i = 0; i < _dvb_other_listeners.size(); i++) 00351 _dvb_other_listeners[i]->HandleBAT(&bat); 00352 00353 return true; 00354 } 00355 } 00356 00357 if ((DVB_EIT_PID == pid || DVB_DNLONG_EIT_PID == pid || FREESAT_EIT_PID == pid || 00358 ((MCA_ONID == _desired_netid) && (MCA_EIT_TSID == _desired_tsid) && 00359 (MCA_EIT_PID == pid)) || DVB_BVLONG_EIT_PID == pid) && 00360 00361 DVBEventInformationTable::IsEIT(psip.TableID())) 00362 { 00363 QMutexLocker locker(&_listener_lock); 00364 if (!_dvb_eit_listeners.size() && !_eit_helper) 00365 return true; 00366 00367 uint service_id = psip.TableIDExtension(); 00368 SetVersionEIT(psip.TableID(), service_id, psip.Version(), psip.LastSection()); 00369 SetEITSectionSeen(psip.TableID(), service_id, psip.Section()); 00370 00371 DVBEventInformationTable eit(psip); 00372 for (uint i = 0; i < _dvb_eit_listeners.size(); i++) 00373 _dvb_eit_listeners[i]->HandleEIT(&eit); 00374 00375 if (_eit_helper) 00376 _eit_helper->AddEIT(&eit); 00377 00378 return true; 00379 } 00380 00381 if (_desired_netid == PREMIERE_ONID && 00382 (PREMIERE_EIT_DIREKT_PID == pid || PREMIERE_EIT_SPORT_PID == pid) && 00383 PremiereContentInformationTable::IsEIT(psip.TableID())) 00384 { 00385 QMutexLocker locker(&_listener_lock); 00386 if (!_dvb_eit_listeners.size() && !_eit_helper) 00387 return true; 00388 00389 PremiereContentInformationTable cit(psip); 00390 SetVersionCIT(cit.ContentID(), cit.Version()); 00391 SetCITSectionSeen(cit.ContentID(), cit.Section()); 00392 00393 for (uint i = 0; i < _dvb_eit_listeners.size(); i++) 00394 _dvb_eit_listeners[i]->HandleEIT(&cit); 00395 00396 if (_eit_helper) 00397 _eit_helper->AddEIT(&cit); 00398 00399 return true; 00400 } 00401 00402 return false; 00403 } 00404 00405 void DVBStreamData::ProcessSDT(uint tsid, const ServiceDescriptionTable *sdt) 00406 { 00407 QMutexLocker locker(&_listener_lock); 00408 00409 for (uint i = 0; i < sdt->ServiceCount(); i++) 00410 { 00411 if (sdt->HasEITSchedule(i) || sdt->HasEITPresentFollowing(i)) 00412 _dvb_has_eit[sdt->ServiceID(i)] = true; 00413 } 00414 00415 for (uint i = 0; i < _dvb_main_listeners.size(); i++) 00416 _dvb_main_listeners[i]->HandleSDT(tsid, sdt); 00417 } 00418 00419 bool DVBStreamData::HasEITPIDChanges(const uint_vec_t &in_use_pids) const 00420 { 00421 QMutexLocker locker(&_listener_lock); 00422 bool want_eit = (_eit_rate >= 0.5f) && HasAnyEIT(); 00423 bool has_eit = in_use_pids.size(); 00424 return want_eit != has_eit; 00425 } 00426 00427 bool DVBStreamData::GetEITPIDChanges(const uint_vec_t &cur_pids, 00428 uint_vec_t &add_pids, 00429 uint_vec_t &del_pids) const 00430 { 00431 QMutexLocker locker(&_listener_lock); 00432 00433 if ((_eit_rate >= 0.5f) && HasAnyEIT()) 00434 { 00435 if (find(cur_pids.begin(), cur_pids.end(), 00436 (uint) DVB_EIT_PID) == cur_pids.end()) 00437 { 00438 add_pids.push_back(DVB_EIT_PID); 00439 } 00440 00441 if (_dvb_eit_dishnet_long && 00442 find(cur_pids.begin(), cur_pids.end(), 00443 (uint) DVB_DNLONG_EIT_PID) == cur_pids.end()) 00444 { 00445 add_pids.push_back(DVB_DNLONG_EIT_PID); 00446 } 00447 00448 if (_dvb_eit_dishnet_long && 00449 find(cur_pids.begin(), cur_pids.end(), 00450 (uint) DVB_BVLONG_EIT_PID) == cur_pids.end()) 00451 { 00452 add_pids.push_back(DVB_BVLONG_EIT_PID); 00453 } 00454 00455 if (_desired_netid == PREMIERE_ONID && 00456 find(cur_pids.begin(), cur_pids.end(), 00457 (uint) PREMIERE_EIT_DIREKT_PID) == cur_pids.end()) 00458 { 00459 add_pids.push_back(PREMIERE_EIT_DIREKT_PID); 00460 } 00461 00462 if (_desired_netid == PREMIERE_ONID && 00463 find(cur_pids.begin(), cur_pids.end(), 00464 (uint) PREMIERE_EIT_SPORT_PID) == cur_pids.end()) 00465 { 00466 add_pids.push_back(PREMIERE_EIT_SPORT_PID); 00467 } 00468 00469 if (find(cur_pids.begin(), cur_pids.end(), 00470 (uint) FREESAT_EIT_PID) == cur_pids.end()) 00471 { 00472 add_pids.push_back(FREESAT_EIT_PID); 00473 } 00474 00475 if (MCA_ONID == _desired_netid && MCA_EIT_TSID == _desired_tsid && 00476 find(cur_pids.begin(), cur_pids.end(), 00477 (uint) MCA_EIT_PID) == cur_pids.end()) 00478 { 00479 add_pids.push_back(MCA_EIT_PID); 00480 } 00481 00482 } 00483 else 00484 { 00485 if (find(cur_pids.begin(), cur_pids.end(), 00486 (uint) DVB_EIT_PID) != cur_pids.end()) 00487 { 00488 del_pids.push_back(DVB_EIT_PID); 00489 } 00490 00491 if (_dvb_eit_dishnet_long && 00492 find(cur_pids.begin(), cur_pids.end(), 00493 (uint) DVB_DNLONG_EIT_PID) != cur_pids.end()) 00494 { 00495 del_pids.push_back(DVB_DNLONG_EIT_PID); 00496 } 00497 00498 if (_dvb_eit_dishnet_long && 00499 find(cur_pids.begin(), cur_pids.end(), 00500 (uint) DVB_BVLONG_EIT_PID) != cur_pids.end()) 00501 { 00502 del_pids.push_back(DVB_BVLONG_EIT_PID); 00503 } 00504 00505 if (_desired_netid == PREMIERE_ONID && 00506 find(cur_pids.begin(), cur_pids.end(), 00507 (uint) PREMIERE_EIT_DIREKT_PID) != cur_pids.end()) 00508 { 00509 del_pids.push_back(PREMIERE_EIT_DIREKT_PID); 00510 } 00511 00512 if (_desired_netid == PREMIERE_ONID && 00513 find(cur_pids.begin(), cur_pids.end(), 00514 (uint) PREMIERE_EIT_SPORT_PID) != cur_pids.end()) 00515 { 00516 del_pids.push_back(PREMIERE_EIT_SPORT_PID); 00517 } 00518 00519 if (find(cur_pids.begin(), cur_pids.end(), 00520 (uint) FREESAT_EIT_PID) == cur_pids.end()) 00521 { 00522 del_pids.push_back(FREESAT_EIT_PID); 00523 } 00524 00525 if (MCA_ONID == _desired_netid && MCA_EIT_TSID == _desired_tsid && 00526 find(cur_pids.begin(), cur_pids.end(), 00527 (uint) MCA_EIT_PID) != cur_pids.end()) 00528 { 00529 del_pids.push_back(MCA_EIT_PID); 00530 } 00531 } 00532 00533 return add_pids.size() || del_pids.size(); 00534 } 00535 00536 void DVBStreamData::SetNITSectionSeen(uint section) 00537 { 00538 _nit_section_seen[section>>3] |= bit_sel[section & 0x7]; 00539 } 00540 00541 bool DVBStreamData::NITSectionSeen(uint section) const 00542 { 00543 return (bool) (_nit_section_seen[section>>3] & bit_sel[section & 0x7]); 00544 } 00545 00546 bool DVBStreamData::HasAllNITSections(void) const 00547 { 00548 for (uint i = 0; i < 32; i++) 00549 if (_nit_section_seen[i] != 0xff) 00550 return false; 00551 return true; 00552 } 00553 00554 void DVBStreamData::SetNIToSectionSeen(uint section) 00555 { 00556 _nito_section_seen[section>>3] |= bit_sel[section & 0x7]; 00557 } 00558 00559 bool DVBStreamData::NIToSectionSeen(uint section) const 00560 { 00561 return (bool) (_nito_section_seen[section>>3] & bit_sel[section & 0x7]); 00562 } 00563 00564 bool DVBStreamData::HasAllNIToSections(void) const 00565 { 00566 for (uint i = 0; i < 32; i++) 00567 if (_nito_section_seen[i] != 0xff) 00568 return false; 00569 return true; 00570 } 00571 00572 void DVBStreamData::SetSDTSectionSeen(uint tsid, uint section) 00573 { 00574 sections_map_t::iterator it = _sdt_section_seen.find(tsid); 00575 if (it == _sdt_section_seen.end()) 00576 { 00577 _sdt_section_seen[tsid].resize(32, 0); 00578 it = _sdt_section_seen.find(tsid); 00579 } 00580 (*it)[section>>3] |= bit_sel[section & 0x7]; 00581 } 00582 00583 bool DVBStreamData::SDTSectionSeen(uint tsid, uint section) const 00584 { 00585 sections_map_t::const_iterator it = _sdt_section_seen.find(tsid); 00586 if (it == _sdt_section_seen.end()) 00587 return false; 00588 return (bool) ((*it)[section>>3] & bit_sel[section & 0x7]); 00589 } 00590 00591 bool DVBStreamData::HasAllSDTSections(uint tsid) const 00592 { 00593 sections_map_t::const_iterator it = _sdt_section_seen.find(tsid); 00594 if (it == _sdt_section_seen.end()) 00595 return false; 00596 for (uint i = 0; i < 32; i++) 00597 if ((*it)[i] != 0xff) 00598 return false; 00599 return true; 00600 } 00601 00602 void DVBStreamData::SetSDToSectionSeen(uint tsid, uint section) 00603 { 00604 sections_map_t::iterator it = _sdto_section_seen.find(tsid); 00605 if (it == _sdto_section_seen.end()) 00606 { 00607 _sdto_section_seen[tsid].resize(32, 0); 00608 it = _sdto_section_seen.find(tsid); 00609 } 00610 (*it)[section>>3] |= bit_sel[section & 0x7]; 00611 } 00612 00613 bool DVBStreamData::SDToSectionSeen(uint tsid, uint section) const 00614 { 00615 sections_map_t::const_iterator it = _sdto_section_seen.find(tsid); 00616 if (it == _sdto_section_seen.end()) 00617 return false; 00618 return (bool) ((*it)[section>>3] & bit_sel[section & 0x7]); 00619 } 00620 00621 bool DVBStreamData::HasAllSDToSections(uint tsid) const 00622 { 00623 sections_map_t::const_iterator it = _sdto_section_seen.find(tsid); 00624 if (it == _sdto_section_seen.end()) 00625 return false; 00626 for (uint i = 0; i < 32; i++) 00627 if ((*it)[i] != 0xff) 00628 return false; 00629 return true; 00630 } 00631 00632 void DVBStreamData::SetBATSectionSeen(uint bid, uint section) 00633 { 00634 sections_map_t::iterator it = _bat_section_seen.find(bid); 00635 if (it == _bat_section_seen.end()) 00636 { 00637 _bat_section_seen[bid].resize(32, 0); 00638 it = _bat_section_seen.find(bid); 00639 } 00640 (*it)[section>>3] |= bit_sel[section & 0x7]; 00641 } 00642 00643 bool DVBStreamData::BATSectionSeen(uint bid, uint section) const 00644 { 00645 sections_map_t::const_iterator it = _bat_section_seen.find(bid); 00646 if (it == _bat_section_seen.end()) 00647 return false; 00648 return (bool) ((*it)[section>>3] & bit_sel[section & 0x7]); 00649 } 00650 00651 bool DVBStreamData::HasAllBATSections(uint bid) const 00652 { 00653 sections_map_t::const_iterator it = _bat_section_seen.find(bid); 00654 if (it == _bat_section_seen.end()) 00655 return false; 00656 for (uint i = 0; i < 32; i++) 00657 if ((*it)[i] != 0xff) 00658 return false; 00659 return true; 00660 } 00661 00662 void DVBStreamData::SetEITSectionSeen(uint tableid, uint serviceid, 00663 uint section) 00664 { 00665 uint key = (tableid<<16) | serviceid; 00666 sections_map_t::iterator it = _eit_section_seen.find(key); 00667 if (it == _eit_section_seen.end()) 00668 { 00669 _eit_section_seen[key].resize(32, 0); 00670 it = _eit_section_seen.find(key); 00671 } 00672 (*it)[section>>3] |= bit_sel[section & 0x7]; 00673 } 00674 00675 bool DVBStreamData::EITSectionSeen(uint tableid, uint serviceid, 00676 uint section) const 00677 { 00678 uint key = (tableid<<16) | serviceid; 00679 sections_map_t::const_iterator it = _eit_section_seen.find(key); 00680 if (it == _eit_section_seen.end()) 00681 return false; 00682 return (bool) ((*it)[section>>3] & bit_sel[section & 0x7]); 00683 } 00684 00685 void DVBStreamData::SetCITSectionSeen(uint contentid, uint section) 00686 { 00687 sections_map_t::iterator it = _cit_section_seen.find(contentid); 00688 if (it == _cit_section_seen.end()) 00689 { 00690 _cit_section_seen[contentid].resize(32, 0); 00691 it = _cit_section_seen.find(contentid); 00692 } 00693 (*it)[section>>3] |= bit_sel[section & 0x7]; 00694 } 00695 00696 bool DVBStreamData::CITSectionSeen(uint contentid, uint section) const 00697 { 00698 sections_map_t::const_iterator it = _cit_section_seen.find(contentid); 00699 if (it == _cit_section_seen.end()) 00700 return false; 00701 return (bool) ((*it)[section>>3] & bit_sel[section & 0x7]); 00702 } 00703 00704 bool DVBStreamData::HasCachedAnyNIT(bool current) const 00705 { 00706 QMutexLocker locker(&_cache_lock); 00707 00708 if (!current) 00709 LOG(VB_GENERAL, LOG_WARNING, "Currently we ignore \'current\' param"); 00710 00711 return (bool)(_cached_nit.size()); 00712 } 00713 00714 bool DVBStreamData::HasCachedAllNIT(bool current) const 00715 { 00716 QMutexLocker locker(&_cache_lock); 00717 00718 if (!current) 00719 LOG(VB_GENERAL, LOG_WARNING, "Currently we ignore \'current\' param"); 00720 00721 if (_cached_nit.empty()) 00722 return false; 00723 00724 uint last_section = (*_cached_nit.begin())->LastSection(); 00725 if (!last_section) 00726 return true; 00727 00728 for (uint i = 0; i <= last_section; i++) 00729 if (_cached_nit.find(i) == _cached_nit.end()) 00730 return false; 00731 00732 return true; 00733 } 00734 00735 bool DVBStreamData::HasCachedAllSDT(uint tsid, bool current) const 00736 { 00737 QMutexLocker locker(&_cache_lock); 00738 00739 if (!current) 00740 LOG(VB_GENERAL, LOG_WARNING, "Currently we ignore \'current\' param"); 00741 00742 sdt_cache_t::const_iterator it = _cached_sdts.find(tsid << 8); 00743 if (it == _cached_sdts.end()) 00744 return false; 00745 00746 uint last_section = (*it)->LastSection(); 00747 if (!last_section) 00748 return true; 00749 00750 for (uint i = 1; i <= last_section; i++) 00751 if (_cached_sdts.find((tsid << 8) | i) == _cached_sdts.end()) 00752 return false; 00753 00754 return true; 00755 } 00756 00757 bool DVBStreamData::HasCachedAnySDT(uint tsid, bool current) const 00758 { 00759 QMutexLocker locker(&_cache_lock); 00760 00761 if (!current) 00762 LOG(VB_GENERAL, LOG_WARNING, "Currently we ignore \'current\' param"); 00763 00764 for (uint i = 0; i <= 255; i++) 00765 if (_cached_sdts.find((tsid << 8) | i) != _cached_sdts.end()) 00766 return true; 00767 00768 return false; 00769 } 00770 00771 bool DVBStreamData::HasCachedSDT(bool current) const 00772 { 00773 QMutexLocker locker(&_cache_lock); 00774 00775 if (_cached_nit.empty()) 00776 return false; 00777 00778 nit_cache_t::const_iterator it = _cached_nit.begin(); 00779 for (; it != _cached_nit.end(); ++it) 00780 { 00781 for (uint i = 0; i < (*it)->TransportStreamCount(); i++) 00782 { 00783 if (HasCachedAllSDT((*it)->TSID(i), current)) 00784 return true; 00785 } 00786 } 00787 00788 return false; 00789 } 00790 00791 bool DVBStreamData::HasCachedAnySDTs(bool current) const 00792 { 00793 QMutexLocker locker(&_cache_lock); 00794 return !_cached_sdts.empty(); 00795 } 00796 00797 bool DVBStreamData::HasCachedAllSDTs(bool current) const 00798 { 00799 QMutexLocker locker(&_cache_lock); 00800 00801 if (_cached_nit.empty()) 00802 return false; 00803 00804 nit_cache_t::const_iterator it = _cached_nit.begin(); 00805 for (; it != _cached_nit.end(); ++it) 00806 { 00807 if ((int)(*it)->TransportStreamCount() > _cached_sdts.size()) 00808 return false; 00809 00810 for (uint i = 0; i < (*it)->TransportStreamCount(); i++) 00811 if (!HasCachedAllSDT((*it)->TSID(i), current)) 00812 return false; 00813 } 00814 00815 return true; 00816 } 00817 00818 const nit_ptr_t DVBStreamData::GetCachedNIT( 00819 uint section_num, bool current) const 00820 { 00821 QMutexLocker locker(&_cache_lock); 00822 00823 if (!current) 00824 LOG(VB_GENERAL, LOG_WARNING, "Currently we ignore \'current\' param"); 00825 00826 nit_ptr_t nit = NULL; 00827 00828 nit_cache_t::const_iterator it = _cached_nit.find(section_num); 00829 if (it != _cached_nit.end()) 00830 IncrementRefCnt(nit = *it); 00831 00832 return nit; 00833 } 00834 00835 const nit_vec_t DVBStreamData::GetCachedNIT(bool current) const 00836 { 00837 QMutexLocker locker(&_cache_lock); 00838 00839 nit_vec_t nits; 00840 00841 for (uint i = 0; i < 256; i++) 00842 { 00843 nit_ptr_t nit = GetCachedNIT(i, current); 00844 if (nit) 00845 nits.push_back(nit); 00846 } 00847 00848 return nits; 00849 } 00850 00851 const sdt_ptr_t DVBStreamData::GetCachedSDT( 00852 uint tsid, uint section_num, bool current) const 00853 { 00854 QMutexLocker locker(&_cache_lock); 00855 00856 if (!current) 00857 LOG(VB_GENERAL, LOG_WARNING, "Currently we ignore \'current\' param"); 00858 00859 sdt_ptr_t sdt = NULL; 00860 00861 uint key = (tsid << 8) | section_num; 00862 sdt_cache_t::const_iterator it = _cached_sdts.find(key); 00863 if (it != _cached_sdts.end()) 00864 IncrementRefCnt(sdt = *it); 00865 00866 return sdt; 00867 } 00868 00869 const sdt_vec_t DVBStreamData::GetCachedSDTs(bool current) const 00870 { 00871 QMutexLocker locker(&_cache_lock); 00872 00873 if (!current) 00874 LOG(VB_GENERAL, LOG_WARNING, "Currently we ignore \'current\' param"); 00875 00876 sdt_vec_t sdts; 00877 00878 sdt_cache_t::const_iterator it = _cached_sdts.begin(); 00879 for (; it != _cached_sdts.end(); ++it) 00880 { 00881 IncrementRefCnt(*it); 00882 sdts.push_back(*it); 00883 } 00884 00885 return sdts; 00886 } 00887 00888 void DVBStreamData::ReturnCachedSDTTables(sdt_vec_t &sdts) const 00889 { 00890 for (sdt_vec_t::iterator it = sdts.begin(); it != sdts.end(); ++it) 00891 ReturnCachedTable(*it); 00892 sdts.clear(); 00893 } 00894 00895 bool DVBStreamData::DeleteCachedTable(PSIPTable *psip) const 00896 { 00897 if (!psip) 00898 return false; 00899 00900 uint tid = psip->TableIDExtension(); 00901 00902 QMutexLocker locker(&_cache_lock); 00903 if (_cached_ref_cnt[psip] > 0) 00904 { 00905 _cached_slated_for_deletion[psip] = 1; 00906 return false; 00907 } 00908 else if ((TableID::NIT == psip->TableID()) && 00909 _cached_nit[psip->Section()]) 00910 { 00911 _cached_nit[psip->Section()] = NULL; 00912 delete psip; 00913 } 00914 else if ((TableID::SDT == psip->TableID()) && 00915 _cached_sdts[tid << 8 | psip->Section()]) 00916 { 00917 _cached_sdts[tid << 8 | psip->Section()] = NULL; 00918 delete psip; 00919 } 00920 else 00921 { 00922 return MPEGStreamData::DeleteCachedTable(psip); 00923 } 00924 psip_refcnt_map_t::iterator it; 00925 it = _cached_slated_for_deletion.find(psip); 00926 if (it != _cached_slated_for_deletion.end()) 00927 _cached_slated_for_deletion.erase(it); 00928 00929 return true; 00930 } 00931 00932 void DVBStreamData::CacheNIT(NetworkInformationTable *nit) 00933 { 00934 QMutexLocker locker(&_cache_lock); 00935 00936 nit_cache_t::iterator it = _cached_nit.find(nit->Section()); 00937 if (it != _cached_nit.end()) 00938 DeleteCachedTable(*it); 00939 00940 _cached_nit[nit->Section()] = nit; 00941 } 00942 00943 void DVBStreamData::CacheSDT(ServiceDescriptionTable *sdt) 00944 { 00945 uint key = (sdt->TSID() << 8) | sdt->Section(); 00946 00947 QMutexLocker locker(&_cache_lock); 00948 00949 sdt_cache_t::iterator it = _cached_sdts.find(key); 00950 if (it != _cached_sdts.end()) 00951 DeleteCachedTable(*it); 00952 00953 _cached_sdts[key] = sdt; 00954 } 00955 00956 void DVBStreamData::AddDVBMainListener(DVBMainStreamListener *val) 00957 { 00958 QMutexLocker locker(&_listener_lock); 00959 00960 dvb_main_listener_vec_t::iterator it = _dvb_main_listeners.begin(); 00961 for (; it != _dvb_main_listeners.end(); ++it) 00962 if (((void*)val) == ((void*)*it)) 00963 return; 00964 00965 _dvb_main_listeners.push_back(val); 00966 } 00967 00968 void DVBStreamData::RemoveDVBMainListener(DVBMainStreamListener *val) 00969 { 00970 QMutexLocker locker(&_listener_lock); 00971 00972 dvb_main_listener_vec_t::iterator it = _dvb_main_listeners.begin(); 00973 for (; it != _dvb_main_listeners.end(); ++it) 00974 { 00975 if (((void*)val) == ((void*)*it)) 00976 { 00977 _dvb_main_listeners.erase(it); 00978 return; 00979 } 00980 } 00981 } 00982 00983 void DVBStreamData::AddDVBOtherListener(DVBOtherStreamListener *val) 00984 { 00985 QMutexLocker locker(&_listener_lock); 00986 00987 dvb_other_listener_vec_t::iterator it = _dvb_other_listeners.begin(); 00988 for (; it != _dvb_other_listeners.end(); ++it) 00989 if (((void*)val) == ((void*)*it)) 00990 return; 00991 00992 _dvb_other_listeners.push_back(val); 00993 } 00994 00995 void DVBStreamData::RemoveDVBOtherListener(DVBOtherStreamListener *val) 00996 { 00997 QMutexLocker locker(&_listener_lock); 00998 00999 dvb_other_listener_vec_t::iterator it = _dvb_other_listeners.begin(); 01000 for (; it != _dvb_other_listeners.end(); ++it) 01001 { 01002 if (((void*)val) == ((void*)*it)) 01003 { 01004 _dvb_other_listeners.erase(it); 01005 return; 01006 } 01007 } 01008 } 01009 01010 void DVBStreamData::AddDVBEITListener(DVBEITStreamListener *val) 01011 { 01012 QMutexLocker locker(&_listener_lock); 01013 01014 dvb_eit_listener_vec_t::iterator it = _dvb_eit_listeners.begin(); 01015 for (; it != _dvb_eit_listeners.end(); ++it) 01016 if (((void*)val) == ((void*)*it)) 01017 return; 01018 01019 _dvb_eit_listeners.push_back(val); 01020 } 01021 01022 void DVBStreamData::RemoveDVBEITListener(DVBEITStreamListener *val) 01023 { 01024 QMutexLocker locker(&_listener_lock); 01025 01026 dvb_eit_listener_vec_t::iterator it = _dvb_eit_listeners.begin(); 01027 for (; it != _dvb_eit_listeners.end(); ++it) 01028 { 01029 if (((void*)val) == ((void*)*it)) 01030 { 01031 _dvb_eit_listeners.erase(it); 01032 return; 01033 } 01034 } 01035 }
1.7.6.1