53 const QString &sistandard)
79 if ((reg ==
"DTS1") || (reg ==
"DTS2") || (reg ==
"DTS3"))
103 bool has_crc =
false;
246 LOG(VB_SIPARSER, LOG_ERR,
247 QString(
"PSIPTable: Failed CRC check 0x%1 != 0x%2 "
248 "for TableID = 0x%3")
264 bool ok = (
psipdata() + (pcnt << 2) + 3 < bufend);
267 LOG(VB_SIPARSER, LOG_ERR,
268 "PSIPTable: PAT: program list extends past end of buffer");
275 LOG(VB_SIPARSER, LOG_ERR,
"PSIPTable: PAT: All values at maximums");
286 LOG(VB_SIPARSER, LOG_ERR,
287 "PSIPTable: PMT: can't query program info length");
293 LOG(VB_SIPARSER, LOG_ERR,
294 "PSIPTable: PMT: reported length too large");
299 const unsigned char *proginfo =
psipdata() + 4;
300 const unsigned char *cpos = proginfo + proginfolen;
303 LOG(VB_SIPARSER, LOG_ERR,
304 "PSIPTable: PMT: program info extends past end of buffer");
308 const unsigned char *pos = cpos;
312 const unsigned char *ptr = pos;
313 if (pos + 4 > bufend)
315 LOG(VB_SIPARSER, LOG_ERR,
316 QString(
"PSIPTable: PMT: stream info %1 extends "
317 "past end of buffer").arg(i));
320 pos += 5 + (((ptr[3] << 8) | ptr[4]) & 0x0fff);
324 LOG(VB_SIPARSER, LOG_ERR,
325 QString(
"PSIPTable: PMT: last stream info %1 extends "
326 "past end of buffer").arg(i));
353 const std::vector<uint>& pnum,
const std::vector<uint>& pid)
355 const uint count = std::min(pnum.size(), pid.size());
364 LOG(VB_GENERAL, LOG_ERR,
365 "PAT::Create: Error, old PAT size exceeds maximum PAT size.");
371 for (
uint i = 0; i < count; i++)
374 pat->
pesdata()[offset++] = pnum[i]>>8;
375 pat->
pesdata()[offset++] = pnum[i] & 0xff;
377 pat->
pesdata()[offset++] = ((pid[i]>>8) & 0x1f) | 0xe0;
378 pat->
pesdata()[offset++] = pid[i] & 0xff;
413 std::vector<uint> pids, std::vector<uint>
types)
415 const uint count = std::min(pids.size(),
types.size());
424 for (
uint i=0; i<count; i++)
434 const std::vector<uint> &pids,
435 const std::vector<uint> &
types,
436 const std::vector<desc_list_t> &prog_desc)
438 const uint count = std::min(pids.size(),
types.size());
447 std::vector<unsigned char> gdesc;
448 for (
const auto *gd : global_desc)
450 uint len = gd[1] + 2;
451 gdesc.insert(gdesc.end(), gd, gd + len);
455 for (
uint i = 0; i < count; i++)
457 std::vector<unsigned char> pdesc;
458 for (
const auto *pd : prog_desc[i])
460 uint len = pd[1] + 2;
461 pdesc.insert(pdesc.end(), pd, pd + len);
468 LOG(VB_SIPARSER, LOG_INFO,
"Created PMT \n" + pmt->
toString());
477 auto *pos =
const_cast<unsigned char*
>(cpos);
483 LOG(VB_SIPARSER, LOG_DEBUG, QString(
"Parsing PMT(0x%1) i(%2) len(%3)")
489 LOG(VB_SIPARSER, LOG_DEBUG, QString(
"Parsed PMT(0x%1)\n%2")
490 .arg((uint64_t)
this, 0, 16) .arg(
toString()));
496 unsigned char* streamInfo,
uint infoLength)
578 QMap<uint,uint> encryption_system;
579 for (
auto & desc : descs)
588 LOG(VB_GENERAL, LOG_INFO,
"DTVsm: " + cad.
toString());
592 return encrypted != 0;
606 QMap<uint,uint> encryption_system;
607 for (
auto & desc : descs)
615 LOG(VB_GENERAL, LOG_INFO,
"DTVsm: " + cad.
toString());
619 return encrypted != 0;
624 static constexpr unsigned char kStillPictureFlag = 0x01;
632 ((
StreamInfo(i)[2] & kStillPictureFlag) != 0);
648 std::vector<uint> &pids,
649 const QString &sistandard)
const
684 std::vector<uint> &pids,
685 std::vector<uint> &
types,
686 const QString &sistandard,
687 bool normalize)
const
689 uint pids_start = pids.size();
728 for (
size_t i = pids_start; i < pids.size(); i++)
744 uint pid = desired_pid;
774 LOG(VB_GENERAL, LOG_ERR,
"Started PESPacket, but !payloadStart()");
792 str.append(QString(
" PSIP tableID(0x%1) length(%2) extension(0x%3)\n")
795 str.append(QString(
" version(%1) current(%2) "
796 "section(%3) last_section(%4)\n")
801 str.append(QString(
" atsc_protocol_version(%1)\n")
817 QString str = QString(
818 R
"(table_id="0x%1" length="%2")")
819 .arg(TableID(), 2, 16, QChar('0'))
824 str += QString(R
"( section="%4" last_section="%5")")
830 str += QString(
"\n%1version=\"%2\" current=\"%3\" "
831 "protocol_version=\"%4\" extension=\"0x%5\"")
844 str.append(QString(
"Program Association Section\n"));
847 str.append(QString(
"programCount(%1)\n").arg(
ProgramCount()));
865 str += QString(
" program number %1 has PID 0x%2\n")
872 str.append(QString(
" also contains %1 dummy programs\n")
873 .arg(cnt0 + cnt1fff));
884 QString str = QString(
885 "%1<ProgramAssociationSection tsid=\"0x%2\" program_count=\"%3\""
896 str += QString(
"%1<Program number=\"%2\" pid=\"0x%3\" %4/>\n")
900 .arg(dummy ?
"comment=\"Dummy Program\" " :
"");
903 return str + indent_0 +
"</ProgramAssociationSection>";
909 QString(
"Program Map Section"
911 " pnum(%2) pid(0x%3) pcrpid(0x%4)")
917 std::vector<const unsigned char*> desc =
919 for (
auto &
d : desc)
921 str.append(QString(
"\n %1")
927 str.append(QString(
"\n Stream #%1 pid(0x%2) type(0x%3 %4)")
932 for (
auto &
d : desc)
934 str.append(QString(
"\n %1")
946 QString str = QString(
947 "%1<ProgramMapSection pcr_pid=\"0x%2\" program_number=\"%3\"\n"
948 "%4program_info_length=\"%5\" stream_count=\"%7\"%8>\n")
957 std::vector<const unsigned char*> gdesc =
959 for (
auto & gd : gdesc)
967 str += QString(
"%1<Stream pid=\"0x%2\" type=\"0x%3\" "
968 "type_desc=\"%4\" stream_info_length=\"%5\"")
974 std::vector<const unsigned char*> ldesc =
976 str += (ldesc.empty()) ?
" />\n" :
">\n";
977 for (
auto & ld : ldesc)
983 str += indent_1 +
"</Stream>\n";
986 return str + indent_0 +
"</ProgramMapSection>";
995 return "video-mpeg2";
997 return "video-mpeg1";
999 return "video-mpeg4";
1001 return "video-h264";
1003 return "video-h265";
1005 return "video-opencable";
1011 return "audio-eac3";
1013 return "audio-mp2-layer[1,2,3]";
1015 return "audio-mp1-layer[1,2,3]";
1017 return "audio-aac-latm";
1025 return "private-sec";
1027 return "private-data";
1031 return "dsmcc-a encap";
1033 return "dsmcc-b std data";
1035 return "dsmcc-c NPD data";
1037 return "dsmcc-d data";
1048 return "extended channel name";
1050 return "service location";
1052 return "time-shifted service";
1054 return "component name";
1066 return "11172-2 MPEG-1 Video";
1068 return "13818-2 MPEG-2 Video";
1070 return "14492-2 MPEG-4 Video";
1072 return "H.264 Video";
1074 return "H.265 Video";
1076 return "OpenCable Video";
1078 return "VC-1 Video";
1082 return "11172-2 MPEG-1 Audio";
1084 return "13818-3 MPEG-2 Audio";
1086 return "13818-7 AAC MPEG-2 Audio";
1088 return "13818-3 AAC LATM MPEG-2 Audio";
1092 return "E-AC3 Audio";
1098 return "13818-1 DSM-CC";
1100 return "13818-6 DSM-CC Type A";
1102 return "13818-6 DSM-CC Type B";
1104 return "13818-6 DSM-CC Type C";
1106 return "13818-6 DSM-CC Type D";
1108 return "13818-6 Download";
1110 return "13818-6 Metadata in PES";
1112 return "13818-6 Metadata in Sections";
1114 return "13818-6 Metadata in Data Carousel";
1116 return "13818-6 Metadata in Obj Carousel";
1118 return "13818-6 Metadata in Download";
1122 return "13818-1 Private Sections";
1124 return "13818-3 Private Data";
1126 return "13522 MHEG";
1128 return "ITU H.222.1";
1130 return "13818-1 Aux & ITU H.222.0";
1132 return "14496-1 SL/FlexMux in PES";
1134 return "14496-1 SL/FlexMux in Sections";
1136 return "13818-10 IPMP";
1138 return "13818-10 IPMP2";
1196 if (!lang.isEmpty())
1197 desc += QString(
" (%1)").arg(lang);
1205 QString(
"Conditional Access Section %1")
1208 std::vector<const unsigned char*> gdesc =
1210 for (
auto & gd : gdesc)
1221 QString(
"%1<ConditionalAccessSection %3")
1225 std::vector<const unsigned char*> gdesc =
1227 str += (gdesc.empty()) ?
" />\n" :
">\n";
1228 for (
auto & gd : gdesc)
1234 str += indent_0 +
"</ConditionalAccessSection>\n";
1242 return {
"splice_time(N/A)"};
1244 int64_t abs_pts_time =
PTSTime();
1245 if ((first > 0) && (last > 0))
1247 int64_t elapsed = abs_pts_time - first;
1248 elapsed = (elapsed < 0) ? elapsed + 0x1000000000LL : elapsed;
1249 QTime abs = QTime(0,0,0,0).addMSecs(elapsed/90);
1251 elapsed = abs_pts_time - last;
1252 elapsed = (elapsed < 0) ? elapsed + 0x1000000000LL : elapsed;
1253 QTime rel = QTime(0,0,0,0).addMSecs(elapsed/90);
1255 return QString(
"splice_time(pts: %1 abs: %2, rel: +%3)")
1256 .arg(QString::number(abs_pts_time),
1257 abs.toString(
"hh:mm:ss.zzz"),
1258 rel.toString(
"hh:mm:ss.zzz"));
1261 return QString(
"splice_time(pts: %1)").arg(abs_pts_time);
1265 uint indent_level, int64_t first, int64_t last)
const
1270 return indent +
"<SpliceTime />";
1272 int64_t abs_pts_time =
PTSTime();
1277 int64_t elapsed = abs_pts_time - first;
1278 elapsed = (elapsed < 0) ? elapsed + 0x1000000000LL : elapsed;
1279 QTime abs = QTime(0,0,0,0).addMSecs(elapsed/90);
1280 abs_str = QString(
"absolute=\"%1\" ")
1281 .arg(abs.toString(
"hh:mm:ss.zzz"));
1287 int64_t elapsed = abs_pts_time - last;
1288 elapsed = (elapsed < 0) ? elapsed + 0x1000000000LL : elapsed;
1289 QTime rel = QTime(0,0,0,0).addMSecs(elapsed/90);
1290 rel_str = QString(
"relative=\"+%1\" ")
1291 .arg(rel.toString(
"hh:mm:ss.zzz"));
1294 return QString(
"%1<SpliceTime pts=\"%2\" %3%4/>")
1295 .arg(
indent,QString::number(abs_pts_time),abs_str,rel_str);
1333 const unsigned char *cur =
pesdata() + 15;
1334 for (
uint i = 0; i < splice_count; i++)
1337 bool event_cancel = (cur[4] & 0x80) != 0;
1344 bool program_slice = (cur[5] & 0x40) != 0;
1345 uint component_count = cur[6];
1346 m_ptrs1.push_back(cur + (program_slice ? 10 : 7 * component_count));
1350 bool duration = (
m_ptrs0.back()[5] & 0x2) != 0;
1361 bool splice_cancel = (
pesdata()[18] & 0x80) != 0;
1368 bool program_splice = (
pesdata()[19] & 0x40) != 0;
1369 bool duration = (
pesdata()[19] & 0x20) != 0;
1370 bool splice_immediate = (
pesdata()[19] & 0x10) != 0;
1371 const unsigned char *cur =
pesdata() + 20;
1372 if (program_splice && !splice_immediate)
1376 else if (!program_splice)
1380 for (
uint i = 0; i < component_count; i++)
1383 cur += (splice_immediate) ?
1388 m_ptrs1.push_back(cur + (duration ? 5 : 0));
1405 case kECB:
return "DES-ECB";
1406 case kCBC:
return "DES-CBC";
1407 case k3DES:
return "3DES";
1409 return QString((alg<32) ?
"Reserved(%1)" :
"Private(%1)").arg(alg);
1421 return "SpliceSchedule";
1423 return "SpliceInsert";
1425 return "TimeSignal";
1427 return "BandwidthReservation";
1431 return QString(
"Reserved(%1)").arg(
type);
1438 QString(
"SpliceInformationSection enc_alg(%1) pts_adj(%2)")
1442 str += QString(
" command_len(%1) command_type(%2) scte_pid(0x%3)")
1469 QString(
"eventid(0x%1) cancel(%2) "
1470 "out_of_network(%3) program_splice(%4) "
1471 "duration(%5) immediate(%6)\n ")
1482 str += QString(
" unique_program_id(%1)")
1485 str += QString(
" avail(%1/%2)")
1492 uint indent_level, int64_t first, int64_t last)
const
1496 QString cap_time =
"";
1499 cap_time = QString(
"pts=\"%1\" ").arg(first);
1502 QTime abs = QTime(0,0,0,0).addMSecs((last - first)/90);
1503 cap_time += QString(
"capture_time=\"%1\" ")
1504 .arg(abs.toString(
"hh:mm:ss.zzz"));
1508 QString str = QString(
1509 "%1<SpliceInformationSection %2 encryption_algorithm=\"%3\" "
1510 "pts_adjustment=\"%4\" code_word_index=\"%5\" command_type=\"%6\" scte_pid=\"0x%7\" >\n")
1520 return str +
indent +
"</SpliceInformationSection>";
1536 str +=
indent +
"</SpliceInformationSection>";
1541 uint indent_level, int64_t first, int64_t last)
const
1545 QString str = QString(
1546 "%1<SpliceInsert eventid=\"0x%2\" cancel=\"%3\"\n")
1552 "%1out_of_network=\"%2\" program_splice=\"%3\" duration=\"%4\"\n")
1559 "%1immediate=\"%2\" unique_program_id=\"%3\"\n"
1560 "%4avail_num=\"%5\" avails_expected=\"%6\">\n")
1573 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)