00001
00002
00003 #ifndef MPEGSTREAMDATA_H_
00004 #define MPEGSTREAMDATA_H_
00005
00006 #include <vector>
00007 using namespace std;
00008
00009 #include <qmap.h>
00010 #include <stdint.h>
00011 #include "tspacket.h"
00012 #include "util.h"
00013 #include "streamlisteners.h"
00014 #include "eitscanner.h"
00015
00016 class EITHelper;
00017 class PSIPTable;
00018 class RingBuffer;
00019 class PESPacket;
00020
00021 typedef vector<uint> uint_vec_t;
00022
00023 typedef QMap<unsigned int, PESPacket*> pid_pes_map_t;
00024 typedef QMap<const PSIPTable*, int> psip_refcnt_map_t;
00025
00026 typedef ProgramAssociationTable* pat_ptr_t;
00027 typedef vector<const ProgramAssociationTable*> pat_vec_t;
00028 typedef QMap<uint, pat_vec_t> pat_map_t;
00029 typedef QMap<uint, ProgramAssociationTable*> pat_cache_t;
00030
00031 typedef ProgramMapTable* pmt_ptr_t;
00032 typedef vector<const ProgramMapTable*> pmt_vec_t;
00033 typedef QMap<uint, pmt_vec_t> pmt_map_t;
00034 typedef QMap<uint, ProgramMapTable*> pmt_cache_t;
00035
00036 typedef vector<unsigned char> uchar_vec_t;
00037 typedef uchar_vec_t sections_t;
00038 typedef QMap<uint, sections_t> sections_map_t;
00039
00040 typedef vector<MPEGStreamListener*> mpeg_listener_vec_t;
00041 typedef vector<TSPacketListener*> ts_listener_vec_t;
00042 typedef vector<TSPacketListenerAV*> ts_av_listener_vec_t;
00043 typedef vector<MPEGSingleProgramStreamListener*> mpeg_sp_listener_vec_t;
00044
00045 typedef enum
00046 {
00047 kEncUnknown = 0,
00048 kEncDecrypted = 1,
00049 kEncEncrypted = 2,
00050 } CryptStatus;
00051
00052 class CryptInfo
00053 {
00054 public:
00055 CryptInfo() :
00056 status(kEncUnknown), encrypted_packets(0), decrypted_packets(0),
00057 encrypted_min(1000), decrypted_min(8) { }
00058 CryptInfo(uint e, uint d) :
00059 status(kEncUnknown), encrypted_packets(0), decrypted_packets(0),
00060 encrypted_min(e), decrypted_min(d) { }
00061
00062 public:
00063 CryptStatus status;
00064 uint encrypted_packets;
00065 uint decrypted_packets;
00066 uint encrypted_min;
00067 uint decrypted_min;
00068 };
00069
00070 void init_sections(sections_t §, uint last_section);
00071
00072 typedef enum
00073 {
00074 kPIDPriorityNone = 0,
00075 kPIDPriorityLow = 1,
00076 kPIDPriorityNormal = 2,
00077 kPIDPriorityHigh = 3,
00078 } PIDPriority;
00079 typedef QMap<uint, PIDPriority> pid_map_t;
00080
00081 class MPEGStreamData : public EITSource
00082 {
00083 public:
00084 MPEGStreamData(int desiredProgram, bool cacheTables);
00085 virtual ~MPEGStreamData();
00086
00087 void SetCaching(bool cacheTables) { _cache_tables = cacheTables; }
00088 virtual void Reset(void) { Reset(-1); }
00089 virtual void Reset(int desiredProgram);
00090
00092 double TimeOffset(void) const;
00093
00094
00095 virtual void SetEITHelper(EITHelper *eit_helper);
00096 virtual void SetEITRate(float rate);
00097 virtual bool HasEITPIDChanges(const uint_vec_t& ) const
00098 { return false; }
00099 virtual bool GetEITPIDChanges(const uint_vec_t& ,
00100 uint_vec_t& ,
00101 uint_vec_t& ) const
00102 { return false; }
00103
00104
00105 void SetIgnoreCRC(bool haveCRCbug) { _have_CRC_bug = haveCRCbug; }
00106 virtual bool IsRedundant(uint pid, const PSIPTable&) const;
00107 virtual bool HandleTables(uint pid, const PSIPTable &psip);
00108 virtual void HandleTSTables(const TSPacket* tspacket);
00109 virtual bool ProcessTSPacket(const TSPacket& tspacket);
00110 virtual int ProcessData(const unsigned char *buffer, int len);
00111 inline void HandleAdaptationFieldControl(const TSPacket* tspacket);
00112
00113
00114 virtual void AddListeningPID(
00115 uint pid, PIDPriority priority = kPIDPriorityNormal)
00116 { _pids_listening[pid] = priority; }
00117 virtual void AddNotListeningPID(uint pid)
00118 { _pids_notlistening[pid] = kPIDPriorityNormal; }
00119 virtual void AddWritingPID(
00120 uint pid, PIDPriority priority = kPIDPriorityHigh)
00121 { _pids_writing[pid] = priority; }
00122 virtual void AddAudioPID(
00123 uint pid, PIDPriority priority = kPIDPriorityHigh)
00124 { _pids_audio[pid] = priority; }
00125
00126 virtual void RemoveListeningPID(uint pid) { _pids_listening.erase(pid); }
00127 virtual void RemoveNotListeningPID(uint pid)
00128 { _pids_notlistening.erase(pid); }
00129 virtual void RemoveWritingPID(uint pid) { _pids_writing.erase(pid); }
00130 virtual void RemoveAudioPID(uint pid) { _pids_audio.erase(pid); }
00131
00132 virtual bool IsListeningPID(uint pid) const;
00133 virtual bool IsNotListeningPID(uint pid) const;
00134 virtual bool IsWritingPID(uint pid) const;
00135 bool IsVideoPID(uint pid) const
00136 { return _pid_video_single_program == pid; }
00137 virtual bool IsAudioPID(uint pid) const;
00138
00139 const pid_map_t& ListeningPIDs(void) const
00140 { return _pids_listening; }
00141 const pid_map_t& AudioPIDs(void) const
00142 { return _pids_audio; }
00143 const pid_map_t& WritingPIDs(void) const
00144 { return _pids_writing; }
00145
00146 uint GetPIDs(pid_map_t&) const;
00147
00148
00149 PIDPriority GetPIDPriority(uint pid) const;
00150
00151
00152 void SetVersionPAT(uint tsid, int version, uint last_section)
00153 {
00154 if (VersionPAT(tsid) == version)
00155 return;
00156 _pat_version[tsid] = version;
00157 init_sections(_pat_section_seen[tsid], last_section);
00158 }
00159 int VersionPAT(uint tsid) const
00160 {
00161 const QMap<uint, int>::const_iterator it = _pat_version.find(tsid);
00162 if (it == _pat_version.end())
00163 return -1;
00164 return *it;
00165 }
00166
00167 void SetVersionPMT(uint program_num, int version, uint last_section)
00168 {
00169 if (VersionPMT(program_num) == version)
00170 return;
00171 _pmt_version[program_num] = version;
00172 init_sections(_pmt_section_seen[program_num], last_section);
00173 }
00174 int VersionPMT(uint prog_num) const
00175 {
00176 const QMap<uint, int>::const_iterator it = _pmt_version.find(prog_num);
00177 if (it == _pmt_version.end())
00178 return -1;
00179 return *it;
00180 }
00181
00182
00183 void SetPATSectionSeen(uint tsid, uint section);
00184 bool PATSectionSeen( uint tsid, uint section) const;
00185 bool HasAllPATSections(uint tsid) const;
00186
00187 void SetPMTSectionSeen(uint prog_num, uint section);
00188 bool PMTSectionSeen( uint prog_num, uint section) const;
00189 bool HasAllPMTSections(uint prog_num) const;
00190
00191
00192 bool HasProgram(uint progNum) const;
00193
00194 bool HasCachedAllPAT(uint tsid) const;
00195 bool HasCachedAnyPAT(uint tsid) const;
00196 bool HasCachedAnyPAT(void) const;
00197
00198 bool HasCachedAllPMT(uint program_num) const;
00199 bool HasCachedAnyPMT(uint program_num) const;
00200 bool HasCachedAllPMTs(void) const;
00201
00202 const pat_ptr_t GetCachedPAT(uint tsid, uint section_num) const;
00203 pat_vec_t GetCachedPATs(void) const;
00204 pat_map_t GetCachedPATMap(void) const;
00205
00206 const pmt_ptr_t GetCachedPMT(uint program_num, uint section_num) const;
00207 pmt_vec_t GetCachedPMTs(void) const;
00208 pmt_map_t GetCachedPMTMap(void) const;
00209
00210 virtual void ReturnCachedTable(const PSIPTable *psip) const;
00211 virtual void ReturnCachedPATTables(pat_vec_t&) const;
00212 virtual void ReturnCachedPATTables(pat_map_t&) const;
00213 virtual void ReturnCachedPMTTables(pmt_vec_t&) const;
00214 virtual void ReturnCachedPMTTables(pmt_map_t&) const;
00215
00216
00217 void AddEncryptionTestPID(uint pnum, uint pid, bool isvideo);
00218 void RemoveEncryptionTestPIDs(uint pnum);
00219 bool IsEncryptionTestPID(uint pid) const;
00220
00221 void TestDecryption(const ProgramMapTable* pmt);
00222 void ResetDecryptionMonitoringState(void);
00223
00224 bool IsProgramDecrypted(uint pnum) const;
00225 bool IsProgramEncrypted(uint pnum) const;
00226
00227
00228 void AddMPEGListener(MPEGStreamListener*);
00229 void RemoveMPEGListener(MPEGStreamListener*);
00230 void UpdatePAT(const ProgramAssociationTable*);
00231 void UpdateCAT(const ConditionalAccessTable*);
00232 void UpdatePMT(uint program_num, const ProgramMapTable*);
00233
00234 void AddWritingListener(TSPacketListener*);
00235 void RemoveWritingListener(TSPacketListener*);
00236
00237
00238 void AddMPEGSPListener(MPEGSingleProgramStreamListener*);
00239 void RemoveMPEGSPListener(MPEGSingleProgramStreamListener*);
00240 void AddAVListener(TSPacketListenerAV*);
00241 void RemoveAVListener(TSPacketListenerAV*);
00242 void UpdatePATSingleProgram(ProgramAssociationTable*);
00243 void UpdatePMTSingleProgram(ProgramMapTable*);
00244
00245 public:
00246
00247 void SetDesiredProgram(int p);
00248 inline void SetPATSingleProgram(ProgramAssociationTable*);
00249 inline void SetPMTSingleProgram(ProgramMapTable*);
00250 void SetVideoStreamsRequired(uint num)
00251 { _pmt_single_program_num_video = num; }
00252 uint GetVideoStreamsRequired() const
00253 { return _pmt_single_program_num_video; }
00254 void SetAudioStreamsRequired(uint num)
00255 { _pmt_single_program_num_audio = num; }
00256 uint GetAudioStreamsRequired() const
00257 { return _pmt_single_program_num_audio; }
00258 void SetRecordingType(const QString &recording_type);
00259
00260
00261 int DesiredProgram(void) const { return _desired_program; }
00262 uint VideoPIDSingleProgram(void) const { return _pid_video_single_program; }
00263 QString GetRecordingType(void) const;
00264
00265 const ProgramAssociationTable* PATSingleProgram(void) const
00266 { return _pat_single_program; }
00267 const ProgramMapTable* PMTSingleProgram(void) const
00268 { return _pmt_single_program; }
00269
00270 ProgramAssociationTable* PATSingleProgram(void)
00271 { return _pat_single_program; }
00272 ProgramMapTable* PMTSingleProgram(void)
00273 { return _pmt_single_program; }
00274
00275
00276 int VersionPATSingleProgram(void) const;
00277 int VersionPMTSingleProgram(void) const;
00278
00279 bool CreatePATSingleProgram(const ProgramAssociationTable&);
00280 bool CreatePMTSingleProgram(const ProgramMapTable&);
00281
00282 protected:
00283
00284 PSIPTable* AssemblePSIP(const TSPacket* tspacket, bool& moreTablePackets);
00285 bool AssemblePSIP(PSIPTable& psip, TSPacket* tspacket);
00286 void SavePartialPES(uint pid, PESPacket* packet);
00287 PESPacket* GetPartialPES(uint pid)
00288 { return _partial_pes_packet_cache[pid]; }
00289 void ClearPartialPES(uint pid)
00290 { _partial_pes_packet_cache.remove(pid); }
00291 void DeletePartialPES(uint pid);
00292 void ProcessPAT(const ProgramAssociationTable *pat);
00293 void ProcessPMT(const ProgramMapTable *pmt);
00294 void ProcessEncryptedPacket(const TSPacket&);
00295
00296 static int ResyncStream(const unsigned char *buffer, int curr_pos, int len);
00297
00298 void UpdateTimeOffset(uint64_t si_utc_time);
00299
00300
00301 void IncrementRefCnt(const PSIPTable *psip) const;
00302 virtual void DeleteCachedTable(PSIPTable *psip) const;
00303 void CachePAT(const ProgramAssociationTable *pat);
00304 void CachePMT(const ProgramMapTable *pmt);
00305
00306 protected:
00307 QString _sistandard;
00308
00309 bool _have_CRC_bug;
00310
00311 int _local_utc_offset;
00312
00313 mutable QMutex _si_time_lock;
00314 uint _si_time_offset_cnt;
00315 uint _si_time_offset_indx;
00316 double _si_time_offsets[16];
00317
00318
00319 EITHelper *_eit_helper;
00320 float _eit_rate;
00321
00322
00323 pid_map_t _pids_listening;
00324 pid_map_t _pids_notlistening;
00325 pid_map_t _pids_writing;
00326 pid_map_t _pids_audio;
00327
00328
00329 mutable QMutex _encryption_lock;
00330 QMap<uint, CryptInfo> _encryption_pid_to_info;
00331 QMap<uint, uint_vec_t> _encryption_pnum_to_pids;
00332 QMap<uint, uint_vec_t> _encryption_pid_to_pnums;
00333 QMap<uint, CryptStatus> _encryption_pnum_to_status;
00334
00335
00336 mutable QMutex _listener_lock;
00337 mpeg_listener_vec_t _mpeg_listeners;
00338 mpeg_sp_listener_vec_t _mpeg_sp_listeners;
00339 ts_listener_vec_t _ts_writing_listeners;
00340 ts_av_listener_vec_t _ts_av_listeners;
00341
00342
00343 QMap<uint, int> _pat_version;
00344 QMap<uint, int> _pmt_version;
00345
00346 sections_map_t _pat_section_seen;
00347 sections_map_t _pmt_section_seen;
00348
00349
00350 pid_pes_map_t _partial_pes_packet_cache;
00351
00352
00353 bool _cache_tables;
00354 mutable QMutex _cache_lock;
00355 mutable pat_cache_t _cached_pats;
00356 mutable pmt_cache_t _cached_pmts;
00357 mutable psip_refcnt_map_t _cached_ref_cnt;
00358 mutable psip_refcnt_map_t _cached_slated_for_deletion;
00359
00360
00361 int _desired_program;
00362 QString _recording_type;
00363 bool _strip_pmt_descriptors;
00364 bool _normalize_stream_type;
00365 uint _pid_video_single_program;
00366 uint _pid_pmt_single_program;
00367 uint _pmt_single_program_num_video;
00368 uint _pmt_single_program_num_audio;
00369 ProgramAssociationTable *_pat_single_program;
00370 ProgramMapTable *_pmt_single_program;
00371
00372
00373 private:
00374 bool _invalid_pat_seen;
00375 bool _invalid_pat_warning;
00376 MythTimer _invalid_pat_timer;
00377
00378 protected:
00379 static const unsigned char bit_sel[8];
00380 };
00381
00382 #include "mpegtables.h"
00383
00384 inline void MPEGStreamData::SetPATSingleProgram(ProgramAssociationTable* pat)
00385 {
00386 if (_pat_single_program)
00387 delete _pat_single_program;
00388 _pat_single_program = pat;
00389 }
00390
00391 inline void MPEGStreamData::SetPMTSingleProgram(ProgramMapTable* pmt)
00392 {
00393 if (_pmt_single_program)
00394 delete _pmt_single_program;
00395 _pmt_single_program = pmt;
00396 }
00397
00398 inline int MPEGStreamData::VersionPATSingleProgram() const
00399 {
00400 return (_pat_single_program) ? int(_pat_single_program->Version()) : -1;
00401 }
00402
00403 inline int MPEGStreamData::VersionPMTSingleProgram() const
00404 {
00405 return (_pmt_single_program) ? int(_pmt_single_program->Version()) : -1;
00406 }
00407
00408 inline void MPEGStreamData::HandleAdaptationFieldControl(const TSPacket*)
00409 {
00410
00411
00412 }
00413
00414 #endif