mythtv/libs/libmythtv/dvbrecorder.cpp | 93 ++++++++++++++++++---------------
mythtv/libs/libmythtv/dvbrecorder.h | 10 +++-
2 files changed, 59 insertions(+), 44 deletions(-)
diff --git a/mythtv/libs/libmythtv/dvbrecorder.cpp b/mythtv/libs/libmythtv/dvbrecorder.cpp
index d348359..24e0f00 100644
a
|
b
|
DVBRecorder::DVBRecorder(TVRec *rec, DVB
|
93 | 93 | dvbchannel(advbchannel), |
94 | 94 | _stream_data(NULL), |
95 | 95 | _reset_pid_filters(true), |
| 96 | _open_pid_filters(0), |
| 97 | _max_pid_filters(1<<13), |
96 | 98 | _pid_lock(true), |
97 | 99 | _input_pat(NULL), |
98 | 100 | _input_pmt(NULL), |
… |
… |
void DVBRecorder::CloseFilters(void)
|
314 | 316 | PIDInfoMap::iterator it; |
315 | 317 | for (it = _pid_infos.begin(); it != _pid_infos.end(); ++it) |
316 | 318 | { |
317 | | (*it)->Close(); |
| 319 | _open_pid_filters = (*it)->Close(_open_pid_filters); |
318 | 320 | delete *it; |
319 | 321 | } |
320 | 322 | _pid_infos.clear(); |
321 | 323 | _eit_pids.clear(); |
| 324 | _open_pid_filters = 0; |
| 325 | _max_pid_filters = 1<<13; |
322 | 326 | } |
323 | 327 | |
324 | 328 | int DVBRecorder::OpenFilterFd(uint pid, int pes_type, uint stream_type) |
325 | 329 | { |
| 330 | if (_open_pid_filters >= _max_pid_filters) |
| 331 | return -1; |
| 332 | |
326 | 333 | // bits per millisecond |
327 | 334 | uint bpms = (StreamID::IsVideo(stream_type)) ? 19200 : 500; |
328 | 335 | // msec of buffering we want |
… |
… |
int DVBRecorder::OpenFilterFd(uint pid,
|
378 | 385 | close(fd_tmp); |
379 | 386 | |
380 | 387 | VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to set demux filter." + ENO); |
| 388 | _max_pid_filters = _open_pid_filters; |
381 | 389 | return -1; |
382 | 390 | } |
383 | 391 | |
| 392 | _open_pid_filters++; |
384 | 393 | return fd_tmp; |
385 | 394 | } |
386 | 395 | |
… |
… |
bool DVBRecorder::OpenFilter(uint pid, i
|
404 | 413 | if (info->pesType == pes_type) |
405 | 414 | fd_tmp = info->filter_fd; |
406 | 415 | else |
407 | | info->Close(); |
| 416 | _open_pid_filters = info->Close(_open_pid_filters); |
| 417 | |
| 418 | _pid_infos.erase(it); |
| 419 | delete info; |
408 | 420 | } |
409 | 421 | |
410 | 422 | if (fd_tmp < 0) |
| 423 | { |
411 | 424 | fd_tmp = OpenFilterFd(pid, pes_type, stream_type); |
412 | 425 | |
413 | | // try to close a low priority filter |
414 | | if (fd_tmp < 0) |
415 | | { |
416 | | // no free filters available |
417 | | avail = false; |
418 | | PIDInfoMap::iterator lp_it = _pid_infos.begin(); |
419 | | for (;lp_it != _pid_infos.end(); ++lp_it) |
| 426 | if (fd_tmp < 0) |
420 | 427 | { |
421 | | if (lp_it != it && (*lp_it)->priority < kFilterPriorityHigh) |
| 428 | // no free filters, try to close a low priority filter |
| 429 | avail = false; |
| 430 | int min_priority = kFilterPriorityHigh; |
| 431 | PIDInfoMap::iterator min_it; |
| 432 | |
| 433 | PIDInfoMap::iterator lp_it = _pid_infos.begin(); |
| 434 | for (;lp_it != _pid_infos.end(); ++lp_it) |
| 435 | if ((*lp_it)->priority < kFilterPriorityHigh) |
| 436 | { |
| 437 | (*lp_it)->priority--; |
| 438 | if ((*lp_it)->priority < min_priority) |
| 439 | { |
| 440 | min_priority = (*lp_it)->priority; |
| 441 | min_it = lp_it; |
| 442 | } |
| 443 | } |
| 444 | |
| 445 | if (min_priority < kFilterPriorityHigh) |
422 | 446 | { |
423 | | (*lp_it)->Close(); |
424 | | break; |
| 447 | _open_pid_filters = (*min_it)->Close(_open_pid_filters); |
| 448 | VERBOSE(VB_RECORD, LOC + "Closing low priority PID filter " |
| 449 | + QString("on PID 0x%1.").arg(min_it.key(), 0, 16)); |
| 450 | // PMT PIDs are the only low priority pids |
| 451 | _pmt_monitoring_pids.push_back(min_it.key()); |
| 452 | delete *min_it; |
| 453 | _pid_infos.erase(min_it); |
| 454 | } |
| 455 | else |
| 456 | { |
| 457 | VERBOSE(VB_IMPORTANT, LOC_ERR + "Out of PID filters!"); |
| 458 | return false; |
425 | 459 | } |
426 | | } |
427 | | if (lp_it != _pid_infos.end()) |
428 | | { |
429 | | // PMT PIDs are the only low priority pids |
430 | | uint lp_pid = lp_it.key(); |
431 | | |
432 | | VERBOSE(VB_RECORD, LOC + "Closing low priority PID filter " + |
433 | | QString("on PID 0x%1.").arg(lp_pid, 0, 16)); |
434 | | |
435 | | _pmt_monitoring_pids.push_back(lp_pid); |
436 | | delete *lp_it; |
437 | | _pid_infos.erase(lp_it); |
438 | | |
439 | 460 | fd_tmp = OpenFilterFd(pid, pes_type, stream_type); |
440 | 461 | } |
441 | | else |
442 | | { |
443 | | VERBOSE(VB_RECORD, LOC_ERR + "Out of PID filters!"); |
444 | | } |
445 | 462 | } |
446 | 463 | |
447 | 464 | if (fd_tmp < 0) |
448 | | { |
449 | | if (info) |
450 | | { |
451 | | delete *it; |
452 | | _pid_infos.erase(it); |
453 | | } |
454 | | return avail; |
455 | | } |
456 | | |
457 | | if (!info) |
458 | | info = new PIDInfo(); |
| 465 | return false; |
| 466 | |
| 467 | info = new PIDInfo(); |
459 | 468 | |
460 | 469 | // Add the file descriptor to the filter list |
461 | 470 | info->filter_fd = fd_tmp; |
… |
… |
bool DVBRecorder::AdjustFilters(void)
|
565 | 574 | // Delete pids we are no longer interested in |
566 | 575 | _stream_data->RemoveListeningPID(it.key()); |
567 | 576 | _stream_data->RemoveWritingPID(it.key()); |
568 | | (*it)->Close(); |
| 577 | _open_pid_filters = (*it)->Close(_open_pid_filters); |
569 | 578 | delete *it; |
570 | 579 | _pid_infos.erase(it); |
571 | 580 | } |
… |
… |
void DVBRecorder::AdjustMonitoringPMTPID
|
640 | 649 | if (VB_RECORD & print_verbose_messages) |
641 | 650 | { |
642 | 651 | QString tmp0 = ""; |
643 | | QString tmp1 = QString("%1 PID filters open.").arg(_pid_infos.size()); |
| 652 | QString tmp1 = QString("%1 PID filters open.").arg(_open_pid_filters); |
644 | 653 | |
645 | 654 | int sz = _pmt_monitoring_pids.size(); |
646 | 655 | if (sz) |
diff --git a/mythtv/libs/libmythtv/dvbrecorder.h b/mythtv/libs/libmythtv/dvbrecorder.h
index f2ab97a..fbbc309 100644
a
|
b
|
class PIDInfo
|
43 | 43 | int priority; ///< filters with priority < 0 can be closed |
44 | 44 | // if a new filter can't be opened |
45 | 45 | |
46 | | inline void Close(void); |
| 46 | inline uint Close(uint open_filters); |
47 | 47 | inline bool CheckCC(uint cc); |
48 | 48 | }; |
49 | 49 | typedef QMap<uint,PIDInfo*> PIDInfoMap; |
… |
… |
class DVBRecorder : public DTVRecorder,
|
134 | 134 | /// Set when we want to generate a new filter set |
135 | 135 | MPEGStreamData *_stream_data; |
136 | 136 | bool _reset_pid_filters; |
| 137 | uint _open_pid_filters; |
| 138 | uint _max_pid_filters; |
137 | 139 | QMutex _pid_lock; |
138 | 140 | PIDInfoMap _pid_infos; |
139 | 141 | uint_vec_t _eit_pids; |
… |
… |
class DVBRecorder : public DTVRecorder,
|
186 | 188 | static const int kFilterPriorityLow; |
187 | 189 | }; |
188 | 190 | |
189 | | inline void PIDInfo::Close(void) |
| 191 | inline uint PIDInfo::Close(uint open_filters) |
190 | 192 | { |
191 | 193 | if (filter_fd >= 0) |
| 194 | { |
192 | 195 | close(filter_fd); |
| 196 | return open_filters-1; |
| 197 | } |
| 198 | return open_filters; |
193 | 199 | } |
194 | 200 | |
195 | 201 | inline bool PIDInfo::CheckCC(uint new_cnt) |