Ticket #8695: optimize_UpdateFiltersFromStreamData_v3.patch
File optimize_UpdateFiltersFromStreamData_v3.patch, 17.8 KB (added by , 14 years ago) |
---|
-
libs/libmythtv/dvbstreamhandler.cpp
146 146 147 147 _stream_data_list.push_back(data); 148 148 149 vector<uint> pids; 150 data->GetPIDs(pids); 151 vector<uint>::iterator it = pids.begin(); 152 for (; it != pids.end(); ++it) 153 { 154 AddPIDFilter(*it, StreamID::PrivSec,DMX_PES_OTHER); 155 } 156 149 157 _listener_lock.unlock(); 150 158 151 159 Start(); … … 184 192 { 185 193 _listener_lock.unlock(); 186 194 } 195 196 vector<uint> pids; 197 data->GetPIDs(pids); 198 vector<uint>::iterator pit = pids.begin(); 199 for (; pit != pids.end(); ++pit) 200 { 201 RemovePIDFilter(*pit); 202 } 187 203 188 204 VERBOSE(VB_RECORD, LOC + "RemoveListener("<<data<<") -- end"); 189 205 } … … 460 476 VERBOSE(VB_RECORD, LOC + "RunSR(): " + "end"); 461 477 } 462 478 463 bool DVBStreamHandler::AddPIDFilter( PIDInfo *info)479 bool DVBStreamHandler::AddPIDFilter(uint pid, uint stream_type, uint pes_type) 464 480 { 465 481 #ifdef DEBUG_PID_FILTERS 466 482 VERBOSE(VB_RECORD, LOC + QString("AddPIDFilter(0x%1) priority %2") 467 .arg( info->_pid, 0, 16).arg(GetPIDPriority(info->_pid)));483 .arg(pid, 0, 16).arg(GetPIDPriority(pid))); 468 484 #endif // DEBUG_PID_FILTERS 469 485 470 486 QMutexLocker writing_locker(&_pid_lock); 471 _pid_info[info->_pid] = info;487 PIDInfo *info = _pid_info[pid]; 472 488 473 CycleFiltersByPriority(); 489 if(info == NULL) 490 { 491 info = new PIDInfo(pid, stream_type, 492 pes_type); 493 _pid_info[pid] = info; 494 } 495 info->refcount++; 474 496 475 497 return true; 476 498 } … … 625 647 return false; 626 648 627 649 PIDInfo *tmp = *it; 650 651 if(--tmp->refcount) 652 { 653 return true; 654 } 655 628 656 _pid_info.erase(it); 629 657 630 658 bool ok = true; … … 632 660 { 633 661 ok = tmp->Close(_dvb_dev); 634 662 _open_pid_filters--; 635 636 CycleFiltersByPriority();637 663 } 638 664 639 665 delete tmp; … … 648 674 #ifdef DEBUG_PID_FILTERS 649 675 VERBOSE(VB_RECORD, LOC + "RemoveAllPIDFilters()"); 650 676 #endif // DEBUG_PID_FILTERS 651 652 vector<int> del_pids; 677 bool ok = true; 653 678 PIDInfoMap::iterator it = _pid_info.begin(); 654 679 for (; it != _pid_info.end(); ++it) 655 del_pids.push_back(it.key()); 680 { 681 PIDInfo *filter = *it; 656 682 657 bool ok = true;658 vector<int>::iterator dit = del_pids.begin();659 for (; dit != del_pids.end(); ++dit)660 ok &= RemovePIDFilter(*dit);683 if (filter->IsOpen()) 684 { 685 ok = filter->Close(_dvb_dev); 686 } 661 687 688 delete filter; 689 } 690 _pid_info.clear(); 691 _open_pid_filters = 0; 692 693 CycleFiltersByPriority(); 662 694 return ok; 663 695 } 664 696 … … 696 728 { 697 729 UpdateListeningForEIT(); 698 730 699 pid_map_t pids; 700 731 pidchanges_vec_t pidchanges; 701 732 { 702 733 QMutexLocker read_locker(&_listener_lock); 703 734 704 735 for (uint i = 0; i < _stream_data_list.size(); i++) 705 _stream_data_list[i]->GetPID s(pids);736 _stream_data_list[i]->GetPIDChanges(pidchanges); 706 737 } 707 738 708 QMap<uint, PIDInfo*> add_pids; 709 vector<uint> del_pids; 710 739 if( !pidchanges.empty() ) 711 740 { 712 QMutexLocker read_locker(&_pid_lock); 713 714 // PIDs that need to be added.. 715 pid_map_t::const_iterator lit = pids.constBegin(); 716 for (; lit != pids.constEnd(); ++lit) 741 bool ok = true; 742 pidchanges_vec_t::const_iterator it = pidchanges.begin(); 743 for (; it != pidchanges.end(); ++it) 717 744 { 718 if (*lit && (_pid_info.find(lit.key()) == _pid_info.end()))745 switch(it->change) 719 746 { 720 add_pids[lit.key()] = new PIDInfo( 721 lit.key(), StreamID::PrivSec, DMX_PES_OTHER); 747 case kPIDChangeAdd: 748 ok &= AddPIDFilter(it->pid, StreamID::PrivSec, 749 DMX_PES_OTHER); 750 break; 751 case kPIDChangeRemove: 752 ok &= RemovePIDFilter(it->pid); 722 753 } 723 754 } 724 755 725 // PIDs that need to be removed.. 726 PIDInfoMap::const_iterator fit = _pid_info.begin(); 727 for (; fit != _pid_info.end(); ++fit) 728 { 729 bool in_pids = pids.find(fit.key()) != pids.end(); 730 if (!in_pids) 731 del_pids.push_back(fit.key()); 732 } 756 CycleFiltersByPriority(); 757 return ok; 733 758 } 734 759 735 // Remove PIDs736 bool ok = true;737 vector<uint>::iterator dit = del_pids.begin();738 for (; dit != del_pids.end(); ++dit)739 ok &= RemovePIDFilter(*dit);740 741 // Add PIDs742 QMap<uint, PIDInfo*>::iterator ait = add_pids.begin();743 for (; ait != add_pids.end(); ++ait)744 ok &= AddPIDFilter(*ait);745 746 760 // Cycle filters if it's been a while 747 761 if (_cycle_timer.elapsed() > 1000) 748 762 CycleFiltersByPriority(); 749 763 750 return ok;764 return true; 751 765 } 752 766 753 767 void DVBStreamHandler::SetRetuneAllowed( … … 831 845 } 832 846 833 847 bool supports_ts = false; 834 if (AddPIDFilter( new PIDInfo(pat_pid)))848 if (AddPIDFilter(pat_pid)) 835 849 { 836 850 supports_ts = true; 837 851 RemovePIDFilter(pat_pid); -
libs/libmythtv/dvbstreamhandler.h
27 27 { 28 28 public: 29 29 PIDInfo() : 30 _pid(0xffffffff), filter_fd(-1), streamType(0), pesType(-1) {;} 30 _pid(0xffffffff), filter_fd(-1), streamType(0), pesType(-1), 31 refcount(0) {;} 31 32 PIDInfo(uint pid) : 32 _pid(pid), filter_fd(-1), streamType(0), pesType(-1) {;} 33 _pid(pid), filter_fd(-1), streamType(0), pesType(-1), 34 refcount(0) {;} 33 35 PIDInfo(uint pid, uint stream_type, uint pes_type) : 34 36 _pid(pid), filter_fd(-1), 35 streamType(stream_type), pesType(pes_type) {;} 37 streamType(stream_type), pesType(pes_type), 38 refcount(0) {;} 36 39 37 40 bool Open(const QString &dvb_dev, bool use_section_reader); 38 41 bool Close(const QString &dvb_dev); … … 42 45 int filter_fd; ///< Input filter file descriptor 43 46 uint streamType; ///< StreamID 44 47 int pesType; ///< PESStreamID 48 uint refcount; ///< Count of listeners on this pid. 45 49 }; 46 50 typedef QMap<uint,PIDInfo*> PIDInfoMap; 47 51 … … 83 87 84 88 void UpdateListeningForEIT(void); 85 89 bool UpdateFiltersFromStreamData(void); 86 bool AddPIDFilter( PIDInfo *info);90 bool AddPIDFilter(uint pid, uint stream_type=0, uint pes_type=-1); 87 91 bool RemovePIDFilter(uint pid); 88 92 bool RemoveAllPIDFilters(void); 89 93 void CycleFiltersByPriority(void); -
libs/libmythtv/mpeg/mpegstreamdata.cpp
54 54 /** \fn MPEGStreamData::MPEGStreamData(int, bool) 55 55 * \brief Initializes MPEGStreamData. 56 56 * 57 * This adds the PID of the PAT table to "_pids _listening"57 * This adds the PID of the PAT table to "_pids (type=listening)" 58 58 * 59 59 * \param desiredProgram If you want rewritten PAT and PMTs, for 60 60 * a desired program set this to a value > -1 … … 184 184 DeletePartialPES(it.key()); 185 185 _partial_pes_packet_cache.clear(); 186 186 187 _pids_listening.clear(); 188 _pids_notlistening.clear(); 189 _pids_writing.clear(); 190 _pids_audio.clear(); 187 RemoveAllPIDs(); 191 188 192 _pid_ video_single_program = _pid_pmt_single_program = 0xffffffff;189 _pid_pmt_single_program = 0xffffffff; 193 190 194 191 _pat_version.clear(); 195 192 _pat_section_seen.clear(); … … 618 615 return false; 619 616 } 620 617 621 _pids_audio.clear();618 RemoveAllAudioPIDs(); 622 619 for (uint i = 0; i < audioPIDs.size(); i++) 623 620 AddAudioPID(audioPIDs[i]); 624 621 622 RemoveAllVideoPIDs(); 625 623 if (videoPIDs.size() >= 1) 626 _pid_video_single_program = videoPIDs[0];624 AddVideoPID(videoPIDs[0]); 627 625 for (uint i = 1; i < videoPIDs.size(); i++) 628 626 AddWritingPID(videoPIDs[i]); 629 627 … … 985 983 return true; 986 984 } 987 985 988 if (IsAudioPID(tspacket.PID())) 986 PIDType type = GetPIDType(tspacket.PID()); 987 switch (type) 989 988 { 989 case kPIDTypeAudio: 990 990 for (uint j = 0; j < _ts_av_listeners.size(); j++) 991 991 _ts_av_listeners[j]->ProcessAudioTSPacket(tspacket); 992 992 993 993 return true; 994 }995 994 996 if (IsWritingPID(tspacket.PID()) && _ts_writing_listeners.size()) 997 { 995 case kPIDTypeWriting: 998 996 for (uint j = 0; j < _ts_writing_listeners.size(); j++) 999 997 _ts_writing_listeners[j]->ProcessTSPacket(tspacket); 1000 }1001 998 1002 if (IsListeningPID(tspacket.PID())) 1003 { 999 return true; 1000 1001 case kPIDTypeListening: 1004 1002 HandleTSTables(&tspacket); 1003 return true; 1004 1005 default:; 1005 1006 } 1006 1007 } 1007 1008 else if (!tspacket.ScramplingControl() && IsWritingPID(tspacket.PID())) … … 1034 1035 return pos; 1035 1036 } 1036 1037 1038 void MPEGStreamData::RemoveAllPIDs() 1039 { 1040 RemoveAllVideoPIDs(); 1041 1042 pid_map_t::const_iterator it = _pids.begin(); 1043 for (; it != _pids.end(); ++it) 1044 { 1045 AddPIDChange(PIDChange(kPIDChangeRemove, it.key())); 1046 } 1047 _pids.clear(); 1048 } 1049 1050 void MPEGStreamData::RemoveAllAudioPIDs() 1051 { 1052 pid_map_t::iterator it = _pids.begin(); 1053 while( it != _pids.end() ) 1054 { 1055 if (it->type == kPIDTypeAudio) 1056 { 1057 AddPIDChange(PIDChange(kPIDChangeRemove, it.key())); 1058 it = _pids.erase(it); 1059 continue; 1060 } 1061 it++; 1062 } 1063 } 1064 1065 void MPEGStreamData::RemoveAllVideoPIDs() 1066 { 1067 RemoveVideoPID(_pid_video_single_program); 1068 } 1069 1037 1070 bool MPEGStreamData::IsListeningPID(uint pid) const 1038 1071 { 1039 pid_map_t::const_iterator it = _pids _listening.find(pid);1040 return it != _pids _listening.end();1072 pid_map_t::const_iterator it = _pids.find(pid); 1073 return it != _pids.end() && it->type == kPIDTypeListening; 1041 1074 } 1042 1075 1043 1076 bool MPEGStreamData::IsNotListeningPID(uint pid) const 1044 1077 { 1045 pid_map_t::const_iterator it = _pids _notlistening.find(pid);1046 return it != _pids _notlistening.end();1078 pid_map_t::const_iterator it = _pids.find(pid); 1079 return it != _pids.end() && it->type == kPIDTypeNotListening; 1047 1080 } 1048 1081 1049 1082 bool MPEGStreamData::IsWritingPID(uint pid) const 1050 1083 { 1051 pid_map_t::const_iterator it = _pids _writing.find(pid);1052 return it != _pids _writing.end();1084 pid_map_t::const_iterator it = _pids.find(pid); 1085 return it != _pids.end() && it->type == kPIDTypeWriting; 1053 1086 } 1054 1087 1055 1088 bool MPEGStreamData::IsAudioPID(uint pid) const 1056 1089 { 1057 pid_map_t::const_iterator it = _pids _audio.find(pid);1058 return it != _pids _audio.end();1090 pid_map_t::const_iterator it = _pids.find(pid); 1091 return it != _pids.end() && it->type == kPIDTypeAudio; 1059 1092 } 1060 1093 1061 uint MPEGStreamData::GetPIDs( pid_map_t&pids) const1094 uint MPEGStreamData::GetPIDs(vector<uint> &pids) const 1062 1095 { 1063 uint sz = pids.size(); 1096 if (_pid_video_single_program != 0xffffffff) 1097 { 1098 pids.push_back(_pid_video_single_program); 1099 } 1100 pid_map_t::const_iterator it = _pids.begin(); 1101 for (; it != _pids.end(); ++it) 1102 { 1103 pids.push_back(it.key()); 1104 } 1105 return 0; 1106 } 1064 1107 1065 if (_pid_video_single_program < 0x1fff) 1066 pids[_pid_video_single_program] = kPIDPriorityHigh; 1108 PIDType MPEGStreamData::GetPIDType(uint pid) const 1109 { 1110 pid_map_t::const_iterator it = _pids.find(pid); 1111 1112 if (it != _pids.end()) 1113 { 1114 return it->type; 1115 } 1067 1116 1068 pid_map_t::const_iterator it = _pids_listening.begin(); 1069 for (; it != _pids_listening.end(); ++it) 1070 pids[it.key()] = max(pids[it.key()], *it); 1071 1072 it = _pids_audio.begin(); 1073 for (; it != _pids_audio.end(); ++it) 1074 pids[it.key()] = max(pids[it.key()], *it); 1075 1076 it = _pids_writing.begin(); 1077 for (; it != _pids_writing.end(); ++it) 1078 pids[it.key()] = max(pids[it.key()], *it); 1079 1080 return pids.size() - sz; 1117 return kPIDTypeNone; 1081 1118 } 1082 1119 1083 1120 PIDPriority MPEGStreamData::GetPIDPriority(uint pid) const … … 1085 1122 if (_pid_video_single_program == pid) 1086 1123 return kPIDPriorityHigh; 1087 1124 1088 pid_map_t::const_iterator it; 1089 it = _pids_listening.find(pid); 1090 if (it != _pids_listening.end()) 1091 return *it; 1092 it = _pids_notlistening.find(pid); 1093 if (it != _pids_notlistening.end()) 1094 return *it; 1095 it = _pids_writing.find(pid); 1096 if (it != _pids_writing.end()) 1097 return *it; 1098 it = _pids_audio.find(pid); 1099 if (it != _pids_audio.end()) 1100 return *it; 1125 pid_map_t::const_iterator it = _pids.find(pid); 1126 1127 if (it != _pids.end()) 1128 { 1129 return it->priority; 1130 } 1101 1131 1102 1132 return kPIDPriorityNone; 1103 1133 } -
libs/libmythtv/mpeg/mpegstreamdata.h
81 81 kPIDPriorityNormal = 2, 82 82 kPIDPriorityHigh = 3, 83 83 } PIDPriority; 84 typedef QMap<uint, PIDPriority> pid_map_t;85 84 85 enum PIDType 86 { 87 kPIDTypeNone, 88 kPIDTypeListening, 89 kPIDTypeNotListening, 90 kPIDTypeWriting, 91 kPIDTypeAudio, 92 }; 93 94 struct PIDDesc 95 { 96 PIDDesc(PIDType _type, PIDPriority _priority) 97 : type(_type), priority(_priority) {} 98 99 PIDType type; 100 PIDPriority priority; 101 }; 102 typedef QMap<uint, PIDDesc> pid_map_t; 103 104 enum ChangeAction 105 { 106 kPIDChangeAdd = 0, 107 kPIDChangeRemove = 1, 108 }; 109 110 struct PIDChange 111 { 112 PIDChange(ChangeAction _change, uint32_t _pid) 113 : change(_change) 114 , pid(_pid) 115 {} 116 117 ChangeAction change; 118 uint32_t pid; 119 }; 120 121 typedef vector<PIDChange> pidchanges_vec_t; 122 86 123 class MPEGStreamData : public EITSource 87 124 { 88 125 public: … … 118 155 // Listening 119 156 virtual void AddListeningPID( 120 157 uint pid, PIDPriority priority = kPIDPriorityNormal) 121 { _pids_listening[pid] = priority; } 158 { AddPID(pid, kPIDTypeListening, priority); } 159 122 160 virtual void AddNotListeningPID(uint pid) 123 { _pids_notlistening[pid] = kPIDPriorityNormal; } 161 { AddPID(pid, kPIDTypeNotListening, kPIDPriorityNormal); } 162 124 163 virtual void AddWritingPID( 125 164 uint pid, PIDPriority priority = kPIDPriorityHigh) 126 { _pids_writing[pid] = priority; } 165 { AddPID(pid, kPIDTypeWriting, priority); } 166 127 167 virtual void AddAudioPID( 128 168 uint pid, PIDPriority priority = kPIDPriorityHigh) 129 { _pids_audio[pid] = priority; }169 { AddPID(pid, kPIDTypeAudio, priority); } 130 170 131 virtual void RemoveListeningPID(uint pid) { _pids_listening.remove(pid); } 132 virtual void RemoveNotListeningPID(uint pid) 133 { _pids_notlistening.remove(pid); } 134 virtual void RemoveWritingPID(uint pid) { _pids_writing.remove(pid); } 135 virtual void RemoveAudioPID(uint pid) { _pids_audio.remove(pid); } 171 void AddPID(uint pid, PIDType type, 172 PIDPriority priority = kPIDPriorityHigh) 173 { 174 _pids.insert(pid, PIDDesc(type, priority)); 175 AddPIDChange(PIDChange(kPIDChangeAdd, pid)); 176 } 136 177 178 virtual void AddVideoPID(uint pid) 179 { 180 _pid_video_single_program = pid; 181 AddPIDChange(PIDChange(kPIDChangeAdd, pid)); 182 } 183 184 virtual void RemoveListeningPID(uint pid) { RemovePID(pid); } 185 virtual void RemoveNotListeningPID(uint pid) { RemovePID(pid); } 186 virtual void RemoveWritingPID(uint pid) { RemovePID(pid); } 187 virtual void RemoveAudioPID(uint pid) { RemovePID(pid); } 188 189 void RemovePID(uint pid) 190 { 191 _pids.remove(pid); 192 AddPIDChange(PIDChange(kPIDChangeRemove, pid)); 193 } 194 195 virtual void RemoveVideoPID(uint pid) 196 { 197 if (_pid_video_single_program == pid && pid != 0xffffffff) 198 { 199 AddPIDChange(PIDChange(kPIDChangeRemove, pid)); 200 _pid_video_single_program = 0xffffffff; 201 } 202 } 203 204 void AddPIDChange(const PIDChange &pidChange) 205 { 206 pidchanges_vec_t::iterator it = _pidchanges.begin(); 207 for (; it != _pidchanges.end(); ++it) 208 { 209 if (it->pid == pidChange.pid) 210 { 211 if (it->change != pidChange.change) 212 { 213 _pidchanges.erase(it); 214 } 215 return; 216 } 217 } 218 _pidchanges.push_back(pidChange); 219 } 220 221 virtual void RemoveAllPIDs(); 222 virtual void RemoveAllAudioPIDs(); 223 virtual void RemoveAllVideoPIDs(); 224 137 225 virtual bool IsListeningPID(uint pid) const; 138 226 virtual bool IsNotListeningPID(uint pid) const; 139 227 virtual bool IsWritingPID(uint pid) const; … … 141 229 { return _pid_video_single_program == pid; } 142 230 virtual bool IsAudioPID(uint pid) const; 143 231 144 const pid_map_t& ListeningPIDs(void) const 145 { return _pids_listening; } 146 const pid_map_t& AudioPIDs(void) const 147 { return _pids_audio; } 148 const pid_map_t& WritingPIDs(void) const 149 { return _pids_writing; } 232 uint GetPIDs(pid_map_t &pids) const {return 0; } 233 uint GetPIDs(vector<uint> &pids) const; 234 uint GetPIDChanges(pidchanges_vec_t &changes) 235 { 236 uint size = _pidchanges.size(); 237 changes.insert(changes.begin(), _pidchanges.begin(), _pidchanges.end()); 238 _pidchanges.clear(); 239 return size; 240 } 150 241 151 uint GetPIDs(pid_map_t&) const; 152 242 PIDType GetPIDType(uint pid) const; 153 243 // PID Priorities 154 244 PIDPriority GetPIDPriority(uint pid) const; 155 245 … … 327 417 float _eit_rate; 328 418 329 419 // Listening 330 pid_map_t _pids_listening; 331 pid_map_t _pids_notlistening; 332 pid_map_t _pids_writing; 333 pid_map_t _pids_audio; 420 pid_map_t _pids; 421 pidchanges_vec_t _pidchanges; 334 422 335 423 // Encryption monitoring 336 424 mutable QMutex _encryption_lock;