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