00001
00002
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
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
00114 is_eit |= TableID::PF_EIT == table_id;
00115
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
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
00147 is_eit |= TableID::PF_EITo == table_id;
00148
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
00155
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
00312
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 }