54 const QString &sistandard)
80 if ((reg ==
"DTS1") || (reg ==
"DTS2") || (reg ==
"DTS3"))
104 bool has_crc =
false;
247 LOG(VB_SIPARSER, LOG_ERR,
248 QString(
"PSIPTable: Failed CRC check 0x%1 != 0x%2 "
249 "for TableID = 0x%3")
265 bool ok = (
psipdata() + (pcnt << 2) + 3 < bufend);
268 LOG(VB_SIPARSER, LOG_ERR,
269 "PSIPTable: PAT: program list extends past end of buffer");
276 LOG(VB_SIPARSER, LOG_ERR,
"PSIPTable: PAT: All values at maximums");
287 LOG(VB_SIPARSER, LOG_ERR,
288 "PSIPTable: PMT: can't query program info length");
294 LOG(VB_SIPARSER, LOG_ERR,
295 "PSIPTable: PMT: reported length too large");
300 const unsigned char *proginfo =
psipdata() + 4;
301 const unsigned char *cpos = proginfo + proginfolen;
304 LOG(VB_SIPARSER, LOG_ERR,
305 "PSIPTable: PMT: program info extends past end of buffer");
309 const unsigned char *pos = cpos;
313 const unsigned char *ptr = pos;
314 if (pos + 4 > bufend)
316 LOG(VB_SIPARSER, LOG_ERR,
317 QString(
"PSIPTable: PMT: stream info %1 extends "
318 "past end of buffer").arg(i));
321 pos += 5 + (((ptr[3] << 8) | ptr[4]) & 0x0fff);
325 LOG(VB_SIPARSER, LOG_ERR,
326 QString(
"PSIPTable: PMT: last stream info %1 extends "
327 "past end of buffer").arg(i));
354 const std::vector<uint>& pnum,
const std::vector<uint>& pid)
356 const uint count = std::min(pnum.size(), pid.size());
365 LOG(VB_GENERAL, LOG_ERR,
366 "PAT::Create: Error, old PAT size exceeds maximum PAT size.");
372 for (
uint i = 0; i < count; i++)
375 pat->
pesdata()[offset++] = pnum[i]>>8;
376 pat->
pesdata()[offset++] = pnum[i] & 0xff;
378 pat->
pesdata()[offset++] = ((pid[i]>>8) & 0x1f) | 0xe0;
379 pat->
pesdata()[offset++] = pid[i] & 0xff;
414 std::vector<uint> pids, std::vector<uint>
types)
416 const uint count = std::min(pids.size(),
types.size());
425 for (
uint i=0; i<count; i++)
435 const std::vector<uint> &pids,
436 const std::vector<uint> &
types,
437 const std::vector<desc_list_t> &prog_desc)
439 const uint count = std::min(pids.size(),
types.size());
448 std::vector<unsigned char> gdesc;
449 for (
const auto *gd : global_desc)
451 uint len = gd[1] + 2;
452 gdesc.insert(gdesc.end(), gd, gd + len);
456 for (
uint i = 0; i < count; i++)
458 std::vector<unsigned char> pdesc;
459 for (
const auto *pd : prog_desc[i])
461 uint len = pd[1] + 2;
462 pdesc.insert(pdesc.end(), pd, pd + len);
469 LOG(VB_SIPARSER, LOG_INFO,
"Created PMT \n" + pmt->
toString());
478 auto *pos =
const_cast<unsigned char*
>(cpos);
484 LOG(VB_SIPARSER, LOG_DEBUG, QString(
"Parsing PMT(0x%1) i(%2) len(%3)")
490 LOG(VB_SIPARSER, LOG_DEBUG, QString(
"Parsed PMT(0x%1)\n%2")
491 .arg((uint64_t)
this, 0, 16) .arg(
toString()));
497 unsigned char* streamInfo,
uint infoLength)
579 QMap<uint,uint> encryption_system;
580 for (
auto & desc : descs)
589 LOG(VB_GENERAL, LOG_INFO,
"DTVsm: " + cad.
toString());
593 return encrypted != 0;
607 QMap<uint,uint> encryption_system;
608 for (
auto & desc : descs)
616 LOG(VB_GENERAL, LOG_INFO,
"DTVsm: " + cad.
toString());
620 return encrypted != 0;
625 static constexpr unsigned char kStillPictureFlag = 0x01;
633 ((
StreamInfo(i)[2] & kStillPictureFlag) != 0);
649 std::vector<uint> &pids,
650 const QString &sistandard)
const
685 std::vector<uint> &pids,
686 std::vector<uint> &
types,
687 const QString &sistandard,
688 bool normalize)
const
690 uint pids_start = pids.size();
729 for (
size_t i = pids_start; i < pids.size(); i++)
745 uint pid = desired_pid;
777 LOG(VB_GENERAL, LOG_ERR,
"Started PESPacket, but !payloadStart()");
795 str.append(QString(
" PSIP tableID(0x%1) length(%2) extension(0x%3)\n")
798 str.append(QString(
" version(%1) current(%2) "
799 "section(%3) last_section(%4)\n")
804 str.append(QString(
" atsc_protocol_version(%1)\n")
820 QString str = QString(
821 R
"(table_id="0x%1" length="%2")")
822 .arg(TableID(), 2, 16, QChar('0'))
827 str += QString(R
"( section="%4" last_section="%5")")
833 str += QString(
"\n%1version=\"%2\" current=\"%3\" "
834 "protocol_version=\"%4\" extension=\"0x%5\"")
847 str.append(QString(
"Program Association Section\n"));
850 str.append(QString(
"programCount(%1)\n").arg(
ProgramCount()));
868 str += QString(
" program number %1 has PID 0x%2\n")
875 str.append(QString(
" also contains %1 dummy programs\n")
876 .arg(cnt0 + cnt1fff));
887 QString str = QString(
888 "%1<ProgramAssociationSection tsid=\"0x%2\" program_count=\"%3\""
899 str += QString(
"%1<Program number=\"%2\" pid=\"0x%3\" %4/>\n")
903 .arg(dummy ?
"comment=\"Dummy Program\" " :
"");
906 return str + indent_0 +
"</ProgramAssociationSection>";
912 QString(
"Program Map Section"
914 " pnum(%2) pid(0x%3) pcrpid(0x%4)")
920 std::vector<const unsigned char*> desc =
922 for (
auto &
d : desc)
924 str.append(QString(
"\n %1")
930 str.append(QString(
"\n Stream #%1 pid(0x%2) type(0x%3 %4)")
935 for (
auto &
d : desc)
937 str.append(QString(
"\n %1")
949 QString str = QString(
950 "%1<ProgramMapSection pcr_pid=\"0x%2\" program_number=\"%3\"\n"
951 "%4program_info_length=\"%5\" stream_count=\"%7\"%8>\n")
960 std::vector<const unsigned char*> gdesc =
962 for (
auto & gd : gdesc)
970 str += QString(
"%1<Stream pid=\"0x%2\" type=\"0x%3\" "
971 "type_desc=\"%4\" stream_info_length=\"%5\"")
977 std::vector<const unsigned char*> ldesc =
979 str += (ldesc.empty()) ?
" />\n" :
">\n";
980 for (
auto & ld : ldesc)
986 str += indent_1 +
"</Stream>\n";
989 return str + indent_0 +
"</ProgramMapSection>";
998 return "video-mpeg2";
1000 return "video-mpeg1";
1002 return "video-mpeg4";
1004 return "video-h264";
1006 return "video-h265";
1008 return "video-opencable";
1014 return "audio-eac3";
1016 return "audio-mp2-layer[1,2,3]";
1018 return "audio-mp1-layer[1,2,3]";
1020 return "audio-aac-latm";
1028 return "private-sec";
1030 return "private-data";
1034 return "dsmcc-a encap";
1036 return "dsmcc-b std data";
1038 return "dsmcc-c NPD data";
1040 return "dsmcc-d data";
1051 return "extended channel name";
1053 return "service location";
1055 return "time-shifted service";
1057 return "component name";
1069 return "11172-2 MPEG-1 Video";
1071 return "13818-2 MPEG-2 Video";
1073 return "14492-2 MPEG-4 Video";
1075 return "H.264 Video";
1077 return "H.265 Video";
1079 return "OpenCable Video";
1081 return "VC-1 Video";
1085 return "11172-2 MPEG-1 Audio";
1087 return "13818-3 MPEG-2 Audio";
1089 return "13818-7 AAC MPEG-2 Audio";
1091 return "13818-3 AAC LATM MPEG-2 Audio";
1095 return "E-AC3 Audio";
1101 return "13818-1 DSM-CC";
1103 return "13818-6 DSM-CC Type A";
1105 return "13818-6 DSM-CC Type B";
1107 return "13818-6 DSM-CC Type C";
1109 return "13818-6 DSM-CC Type D";
1111 return "13818-6 Download";
1113 return "13818-6 Metadata in PES";
1115 return "13818-6 Metadata in Sections";
1117 return "13818-6 Metadata in Data Carousel";
1119 return "13818-6 Metadata in Obj Carousel";
1121 return "13818-6 Metadata in Download";
1125 return "13818-1 Private Sections";
1127 return "13818-3 Private Data";
1129 return "13522 MHEG";
1131 return "ITU H.222.1";
1133 return "13818-1 Aux & ITU H.222.0";
1135 return "14496-1 SL/FlexMux in PES";
1137 return "14496-1 SL/FlexMux in Sections";
1139 return "13818-10 IPMP";
1141 return "13818-10 IPMP2";
1199 if (!lang.isEmpty())
1200 desc += QString(
" (%1)").arg(lang);
1208 QString(
"Conditional Access Section %1")
1211 std::vector<const unsigned char*> gdesc =
1213 for (
auto & gd : gdesc)
1224 QString(
"%1<ConditionalAccessSection %3")
1228 std::vector<const unsigned char*> gdesc =
1230 str += (gdesc.empty()) ?
" />\n" :
">\n";
1231 for (
auto & gd : gdesc)
1237 str += indent_0 +
"</ConditionalAccessSection>\n";
1245 return {
"splice_time(N/A)"};
1247 int64_t abs_pts_time =
PTSTime();
1248 if ((first > 0) && (last > 0))
1250 int64_t elapsed = abs_pts_time - first;
1251 elapsed = (elapsed < 0) ? elapsed + 0x1000000000LL : elapsed;
1252 QTime abs = QTime(0,0,0,0).addMSecs(elapsed/90);
1254 elapsed = abs_pts_time - last;
1255 elapsed = (elapsed < 0) ? elapsed + 0x1000000000LL : elapsed;
1256 QTime rel = QTime(0,0,0,0).addMSecs(elapsed/90);
1258 return QString(
"splice_time(pts: %1 abs: %2, rel: +%3)")
1259 .arg(QString::number(abs_pts_time),
1260 abs.toString(
"hh:mm:ss.zzz"),
1261 rel.toString(
"hh:mm:ss.zzz"));
1264 return QString(
"splice_time(pts: %1)").arg(abs_pts_time);
1268 uint indent_level, int64_t first, int64_t last)
const
1273 return indent +
"<SpliceTime />";
1275 int64_t abs_pts_time =
PTSTime();
1280 int64_t elapsed = abs_pts_time - first;
1281 elapsed = (elapsed < 0) ? elapsed + 0x1000000000LL : elapsed;
1282 QTime abs = QTime(0,0,0,0).addMSecs(elapsed/90);
1283 abs_str = QString(
"absolute=\"%1\" ")
1284 .arg(abs.toString(
"hh:mm:ss.zzz"));
1290 int64_t elapsed = abs_pts_time - last;
1291 elapsed = (elapsed < 0) ? elapsed + 0x1000000000LL : elapsed;
1292 QTime rel = QTime(0,0,0,0).addMSecs(elapsed/90);
1293 rel_str = QString(
"relative=\"+%1\" ")
1294 .arg(rel.toString(
"hh:mm:ss.zzz"));
1297 return QString(
"%1<SpliceTime pts=\"%2\" %3%4/>")
1298 .arg(
indent,QString::number(abs_pts_time),abs_str,rel_str);
1336 const unsigned char *cur =
pesdata() + 15;
1337 for (
uint i = 0; i < splice_count; i++)
1340 bool event_cancel = (cur[4] & 0x80) != 0;
1347 bool program_slice = (cur[5] & 0x40) != 0;
1348 uint component_count = cur[6];
1349 m_ptrs1.push_back(cur + (program_slice ? 10 : 7 * component_count));
1353 bool duration = (
m_ptrs0.back()[5] & 0x2) != 0;
1364 bool splice_cancel = (
pesdata()[18] & 0x80) != 0;
1371 bool program_splice = (
pesdata()[19] & 0x40) != 0;
1372 bool duration = (
pesdata()[19] & 0x20) != 0;
1373 bool splice_immediate = (
pesdata()[19] & 0x10) != 0;
1374 const unsigned char *cur =
pesdata() + 20;
1375 if (program_splice && !splice_immediate)
1379 else if (!program_splice)
1383 for (
uint i = 0; i < component_count; i++)
1386 cur += splice_immediate ?
1391 m_ptrs1.push_back(cur + (duration ? 5 : 0));
1408 case kECB:
return "DES-ECB";
1409 case kCBC:
return "DES-CBC";
1410 case k3DES:
return "3DES";
1412 return QString((alg<32) ?
"Reserved(%1)" :
"Private(%1)").arg(alg);
1424 return "SpliceSchedule";
1426 return "SpliceInsert";
1428 return "TimeSignal";
1430 return "BandwidthReservation";
1434 return QString(
"Reserved(%1)").arg(
type);
1441 QString(
"SpliceInformationSection enc_alg(%1) pts_adj(%2)")
1445 str += QString(
" command_len(%1) command_type(%2) scte_pid(0x%3)")
1472 QString(
"eventid(0x%1) cancel(%2) "
1473 "out_of_network(%3) program_splice(%4) "
1474 "duration(%5) immediate(%6)\n ")
1485 str += QString(
" unique_program_id(%1)")
1488 str += QString(
" avail(%1/%2)")
1495 uint indent_level, int64_t first, int64_t last)
const
1499 QString cap_time =
"";
1502 cap_time = QString(
"pts=\"%1\" ").arg(first);
1505 QTime abs = QTime(0,0,0,0).addMSecs((last - first)/90);
1506 cap_time += QString(
"capture_time=\"%1\" ")
1507 .arg(abs.toString(
"hh:mm:ss.zzz"));
1511 QString str = QString(
1512 "%1<SpliceInformationSection %2 encryption_algorithm=\"%3\" "
1513 "pts_adjustment=\"%4\" code_word_index=\"%5\" command_type=\"%6\" scte_pid=\"0x%7\" >\n")
1523 return str +
indent +
"</SpliceInformationSection>";
1539 str +=
indent +
"</SpliceInformationSection>";
1544 uint indent_level, int64_t first, int64_t last)
const
1548 QString str = QString(
1549 "%1<SpliceInsert eventid=\"0x%2\" cancel=\"%3\"\n")
1555 "%1out_of_network=\"%2\" program_splice=\"%3\" duration=\"%4\"\n")
1562 "%1immediate=\"%2\" unique_program_id=\"%3\"\n"
1563 "%4avail_num=\"%5\" avails_expected=\"%6\">\n")
1576 str += indent_0 +
"</SpliceInsert>";
QString toString() const override
uint SystemID(void) const
uint DescriptorsLength(void) const
QString toStringXML(uint indent_level) const override
const unsigned char * Descriptors(void) const
QString toString(void) const override
QString LanguageString(void) const
QString CanonicalLanguageString(void) const
static desc_list_t Parse(const unsigned char *data, uint len)
static desc_list_t ParseOnlyInclude(const unsigned char *data, uint len, int excluded_descid)
static const unsigned char * Find(const desc_list_t &parsed, uint desc_tag)
virtual QString toStringXML(uint indent_level) const
Returns XML representation of string the TS Reader XML format.
virtual QString toString(void) const
bool VerifyCRC(void) const
void SetTotalLength(uint len)
unsigned char * m_pesData
Pointer to PES data in full buffer.
uint m_psiOffset
AFCOffset + StartOfFieldPointer.
const TSHeader * tsheader() const
uint m_allocSize
Total number of bytes we allocated.
bool m_badPacket
true if a CRC is not good yet
const unsigned char * pesdata() const
unsigned char * m_fullBuffer
Pointer to allocated data.
Contains Packet Identifier numeric values.
@ MPEG_NULL_PID
The all-ones PID value 0x1FFF indicates a Null TS Packet introduced to maintain a constant bit rate o...
A PSIP table is a variant of a PES packet containing an MPEG, ATSC or DVB table.
uint LastSection(void) const
bool HasCRC(void) const override
1 bit Cyclic Redundancy Check present
static PSIPTable View(const TSPacket &tspacket)
uint ATSCProtocolVersion(void) const
bool HasSectionNumber(void) const
static const uint kPsipOffset
const unsigned char * psipdata(void) const
QString XMLValues(uint indent_level) const
bool IsCurrent(void) const
void InitPESPacket(TSPacket &tspacket)
Only handles single TS packet PES packets, for PMT/PAT tables basically.
virtual QString toStringXML(uint indent_level) const
bool VerifyPSIP(bool verify_crc) const
virtual QString toString(void) const
uint TableIDExtension(void) const
uint SectionLength(void) const
void SetVersionNumber(uint ver)
The Program Association Table lists all the programs in a stream, and is always found on PID 0.
void SetTranportStreamID(uint gtsid)
QString toString(void) const override
static ProgramAssociationTable * CreateBlank(bool smallPacket=true)
uint ProgramCount(void) const
uint TransportStreamID(void) const
QString toStringXML(uint indent_level) const override
ProgramAssociationTable(const ProgramAssociationTable &table)
static ProgramAssociationTable * Create(uint tsid, uint version, const std::vector< uint > &pnum, const std::vector< uint > &pid)
uint ProgramNumber(uint i) const
uint ProgramPID(uint i) const
A PMT table maps a program described in the ProgramAssociationTable to various PID's which describe t...
bool IsEncrypted(const QString &sistandard) const
Returns true iff PMT contains CA descriptor for a vid/aud stream.
uint FindPIDs(uint type, std::vector< uint > &pids, const QString &sistandard) const
Finds all pids matching type.
uint FindUnusedPID(uint desired_pid=0x20) const
QString GetLanguage(uint i) const
Returns the canonical language if we find the iso639 descriptor.
void RemoveAllStreams(void)
uint GetAudioType(uint i) const
Returns the audio type from the iso 639 descriptor.
void SetStreamPID(uint i, uint pid)
bool IsProgramEncrypted(void) const
Returns true iff PMT's ProgramInfo contains CA descriptor.
QString toStringXML(uint indent_level) const override
uint StreamCount(void) const
bool IsStillPicture(const QString &sistandard) const
Returns true iff PMT contains a still-picture video stream.
void SetStreamType(uint i, uint type)
uint PCRPID(void) const
stream that contains program clock reference.
uint StreamPID(uint i) const
void SetStreamProgramInfo(uint i, unsigned char *streamInfo, uint infoLength)
std::vector< unsigned char * > m_ptrs
void SetProgramNumber(uint num)
QString toString(void) const override
uint StreamType(uint i) const
int FindPID(uint pid) const
Locates stream index of pid.
const unsigned char * ProgramInfo(void) const
const unsigned char * StreamInfo(uint i) const
uint ProgramNumber(void) const
QString StreamTypeString(uint i) const
Returns a string representation of type at stream index i.
void AppendStream(uint pid, uint type, unsigned char *streamInfo=nullptr, uint infoLength=0)
uint ProgramInfoLength(void) const
bool IsAudio(uint i, const QString &sistandard) const
Returns true iff the stream at index i is an audio stream.
bool IsVideo(uint i, const QString &sistandard) const
Returns true iff the stream at index i is a video stream.
uint StreamInfoLength(uint i) const
static ProgramMapTable * CreateBlank(bool smallPacket=true)
bool IsStreamEncrypted(uint pid) const
Returns true iff PMT contains CA descriptor.
ProgramMapTable(const ProgramMapTable &table)
void SetProgramInfo(unsigned char *streamInfo, uint infoLength)
static ProgramMapTable * Create(uint programNumber, uint basepid, uint pcrpid, uint version, std::vector< uint > pids, std::vector< uint > types)
QString StreamDescription(uint i, const QString &sistandard) const
Returns a better (and more expensive) string representation of type at stream index i than StreamType...
static const uint kPmtHeaderMinOffset
QString FormatIdentifierString(void) const
SpliceTimeView SpliceTime(void) const
bool IsSpliceImmediate(void) const
bool IsSpliceEventCancel(void) const
virtual QString toString(int64_t first, int64_t last) const
bool IsProgramSplice(void) const
uint AvailsExpected(void) const
uint SpliceEventID(void) const
virtual QString toStringXML(uint indent_level, int64_t first, int64_t last) const
bool IsOutOfNetwork(void) const
bool IsDuration(void) const
uint UniqueProgramID(void) const
uint AvailNum(void) const
virtual QString toStringXML(uint indent_level, int64_t first, int64_t last) const
bool IsTimeSpecified(void) const
virtual QString toString(int64_t first, int64_t last) const
uint64_t PTSTime(void) const
static uint Normalize(uint stream_id, const desc_list_t &desc, const QString &sistandard)
@ MetaDataOC
ISO 13818-6 Metadata in Object Carousel.
@ MPEG2Video
ISO 13818-2 & ITU H.262 (aka MPEG-2)
@ MetaDataDC
ISO 13818-6 Metadata in Data Carousel.
@ EAC3Audio
A/53 Part 3:2009 6.7.3.
@ PrivData
ISO 13818-1 PES private data & ITU H.222.0.
@ DSMCC_D
ISO 13818-6 type D Any DSMCC Data.
@ DSMCC_A
ISO 13818-6 type A Multi-protocol Encap.
@ DSMCC_B
ISO 13818-6 type B Std DSMCC Data.
@ FlexMuxSec
ISO 14496-1 SL/FlexMux in 14496_sections.
@ MetaDataDL
ISO 13818-6 Metadata in Download Protocol.
@ MPEG2AACAudio
ISO 13818-7 Audio w/ADTS syntax.
@ DSMCC_DL
ISO 13818-6 Download Protocol.
@ AC3Audio
A/53 Part 3:2009 6.7.1.
@ DSMCC
ISO 13818-1 Annex A DSM-CC & ITU H.222.0.
@ FlexMuxPES
ISO 14496-1 SL/FlexMux in PES packets.
@ MPEG2IPMP2
ISO 13818-10 Digital Restrictions Mangment.
@ MPEG2Aux
ISO 13818-1 auxiliary & ITU H.222.0.
@ DSMCC_C
ISO 13818-6 type C NPT DSMCC Data.
@ H265Video
ISO 23008-2 & ITU H.265 (aka HEVC, Ultra HD)
@ MetaDataSec
Meta data in metadata_section's.
@ VC1Video
SMPTE 421M video codec (aka VC1) in Blu-Ray.
@ MPEG4Video
ISO 14492-2 (aka MPEG-4)
@ PrivSec
ISO 13818-1 private tables & ITU H.222.0.
@ MPEG2IPMP
ISO 13818-10 Digital Restrictions Mangment.
@ Splice
ANSI/SCTE 35 2007.
@ MPEG2AudioAmd1
ISO 13818-3/AMD-1 Audio using LATM syntax.
@ MPEG1Video
ISO 11172-2 (aka MPEG-1)
@ MetaDataPES
Meta data in PES packets.
@ OpenCableVideo
Always MPEG-2??
@ H264Video
ISO 14492-10 & ITU H.264 (aka MPEG-4-AVC)
static const char * toString(uint streamID)
static QString GetDescription(uint stream_id)
static bool IsAudio(uint type)
Returns true iff audio is MPEG1/2, AAC, AC3 or DTS audio stream.
static bool IsVideo(uint type)
Returns true iff video is an MPEG1/2/3, H264 or open cable video stream.
Used to access the data of a Transport Stream packet.
static constexpr unsigned int kPayloadSize
unsigned int AFCOffset(void) const
static TSPacket * CreatePayloadOnlyPacket(void)
unsigned int StartOfFieldPointer(void) const
static const struct wl_interface * types[]
static const iso6937table * d
std::vector< const unsigned char * > desc_list_t
const std::array< const uint8_t, 8 > DEFAULT_PAT_HEADER
static const std::array< const uint, 4 > len_for_alloc
const std::array< const uint8_t, 12 > DEFAULT_PMT_HEADER
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
static QString indent(uint level)
MBASE_PUBLIC long long copy(QFile &dst, QFile &src, uint block_size=0)
Copies src file to dst file.
QString bool_to_string(bool val)
This is equivalent to QVariant(bool).toString()
QString indentSpaces(unsigned int level, unsigned int size=4)