bool DVBStreamHandler::AddPIDFilter(PIDInfo *info) { #ifdef DEBUG_PID_FILTERS VERBOSE(VB_RECORD, LOC + QString("AddPIDFilter(0x%1) priority %2") .arg(info->_pid, 0, 16).arg(GetPIDPriority(info->_pid))); #endif // DEBUG_PID_FILTERS QMutexLocker writing_locker(&_pid_lock); _pid_info[info->_pid] = info; CycleFiltersByPriority(); return true; }
bool StreamHandler::AddPIDFilter(PIDInfo *info) { #ifdef DEBUG_PID_FILTERS LOG(VB_RECORD, LOG_DEBUG, LOC + QString("AddPIDFilter(0x%1)") .arg(info->_pid, 0, 16)); #endif // DEBUG_PID_FILTERS QMutexLocker writing_locker(&m_pid_lock); m_pid_info[info->_pid] = info; CycleFiltersByPriority(); return true; }
bool HDHRStreamHandler::AddPIDFilter(uint pid, bool do_update) { #ifdef DEBUG_PID_FILTERS VERBOSE(VB_RECORD, LOC + QString("AddPIDFilter(0x%1)") .arg(pid, 0, 16)); #endif // DEBUG_PID_FILTERS QMutexLocker writing_locker(&_pid_lock); vector<uint>::iterator it; it = lower_bound(_pid_info.begin(), _pid_info.end(), pid); if (it != _pid_info.end() && *it == pid) return true; _pid_info.insert(it, pid); if (do_update) return UpdateFilters(); return true; }
void DVBStreamHandler::CycleFiltersByPriority(void) { QMutexLocker writing_locker(&_pid_lock); QMap<PIDPriority, pid_list_t> priority_queue; QMap<PIDPriority, uint> priority_open_cnt; PIDInfoMap::const_iterator cit = _pid_info.begin(); for (; cit != _pid_info.end(); ++cit) { PIDPriority priority = GetPIDPriority((*cit)->_pid); priority_queue[priority].push_back(cit.key()); if ((*cit)->IsOpen()) priority_open_cnt[priority]++; } QMap<PIDPriority, pid_list_t>::iterator it = priority_queue.begin(); for (; it != priority_queue.end(); ++it) sort((*it).begin(), (*it).end()); for (PIDPriority i = kPIDPriorityHigh; i > kPIDPriorityNone; i = (PIDPriority)((int)i-1)) { while (priority_open_cnt[i] < priority_queue[i].size()) { // if we can open a filter, just do it // find first closed filter after first open an filter "k" pid_list_t::iterator open = find( _pid_info, priority_queue[i], priority_queue[i].begin(), priority_queue[i].end(), true); if (open == priority_queue[i].end()) open = priority_queue[i].begin(); pid_list_t::iterator closed = find( _pid_info, priority_queue[i], open, priority_queue[i].end(), false); if (closed == priority_queue[i].end()) break; // something is broken if (_pid_info[*closed]->Open(_dvb_dev, _using_section_reader)) { _open_pid_filters++; priority_open_cnt[i]++; continue; } // if we can't open a filter, try to close a lower priority one bool freed = false; for (PIDPriority j = (PIDPriority)((int)i - 1); (j > kPIDPriorityNone) && !freed; j = (PIDPriority)((int)j-1)) { if (!priority_open_cnt[j]) continue; for (uint k = 0; (k < priority_queue[j].size()) && !freed; k++) { PIDInfo *info = _pid_info[priority_queue[j][k]]; if (!info->IsOpen()) continue; if (info->Close(_dvb_dev)) freed = true; _open_pid_filters--; priority_open_cnt[j]--; } } if (freed) { // if we can open a filter, just do it if (_pid_info[*closed]->Open( _dvb_dev, _using_section_reader)) { _open_pid_filters++; priority_open_cnt[i]++; continue; } } // we have to cycle within our priority level if (_cycle_timer.elapsed() < 1000) break; // we don't want to cycle too often if (!_pid_info[*open]->IsOpen()) break; // nothing to close.. // close "open" bool ok = _pid_info[*open]->Close(_dvb_dev); _open_pid_filters--; priority_open_cnt[i]--; // open "closed" if (ok && _pid_info[*closed]-> Open(_dvb_dev, _using_section_reader)) { _open_pid_filters++; priority_open_cnt[i]++; } break; // we only want to cycle once per priority per run } } _cycle_timer.start(); }