MythTV master
splicedescriptors.h
Go to the documentation of this file.
1// -*- Mode: c++ -*-
21#include <cstdint>
22
23#include <QByteArray>
24
25#include "mpegdescriptors.h"
26
27// These descriptors are not registered descriptors, but private
28// descriptors that should only be seen on an SpliceInformationTable
29
31{
32 // ANSI SCTE 35 2007
33 public:
34 enum : std::uint8_t
35 {
36 avail = 0x00,
37 dtmf = 0x01,
39 };
40};
41
43{
44 public:
45 explicit operator const unsigned char*(void) const { return m_data; }
46
47 SpliceDescriptor(const unsigned char *data, int len) : m_data(data)
48 {
49 if ((len < 2) || (int(DescriptorLength()) + 2) > len)
50 m_data = nullptr;
51 }
52 SpliceDescriptor(const unsigned char *data,
53 int len, uint tag) : m_data(data)
54 {
55 if ((len < 2) || ((int(DescriptorLength()) + 2) > len)
56 || (DescriptorTag() != tag))
57 m_data = nullptr;
58 }
59 virtual ~SpliceDescriptor(void) = default;
60
61 bool IsValid(void) const { return m_data; }
62 uint size(void) const { return DescriptorLength() + 2; }
63
64 // Name bits loc expected value
65 // splice_descriptor_tag 8 0.0 0x01
66 uint DescriptorTag(void) const { return m_data[0]; }
67 QString DescriptorTagString(void) const;
68 // descriptor_length 8 1.0
69 uint DescriptorLength(void) const { return m_data[1]; }
70 // identifier 32 2.0 0x43554549 "CUEI"
71 uint Identifier(void) const
72 {
73 return (m_data[2]<<24) | (m_data[3]<<16) | (m_data[4]<<8) | m_data[5];
74 }
75 QString IdentifierString(void) const
76 {
77 return QString(QChar(m_data[2])) + QChar(m_data[3]) +
78 QChar(m_data[4]) + QChar(m_data[5]);
79 }
80
81 virtual QString toString(void) const;
82 virtual QString toStringXML(uint indent_level) const;
83
84 static desc_list_t Parse(const unsigned char *data, uint len);
85 static desc_list_t ParseAndExclude(const unsigned char *data, uint len,
86 int excluded_descid);
87 static desc_list_t ParseOnlyInclude(const unsigned char *data, uint len,
88 int excluded_descid);
89
90 static const unsigned char *Find(const desc_list_t &parsed, uint desc_tag);
91 static desc_list_t FindAll(const desc_list_t &parsed, uint desc_tag);
92
93 protected:
94 virtual bool Parse(void) { return true; }
95
96 const unsigned char *m_data {nullptr};
97};
98
100{
101 public:
102 explicit AvailDescriptor(const unsigned char *data, int len = 300) :
103 SpliceDescriptor(data, len, SpliceDescriptorID::segmentation) { }
104 // Name bits loc expected value
105 // splice_descriptor_tag 8 0.0 0x00
106 // descriptor_length 8 1.0 0x08
107 // identifier 32 2.0 0x43554549 "CUEI"
108 // provider_avail_id 32 6.0
110 {
111 return (m_data[2]<<24) | (m_data[3]<<16) | (m_data[4]<<8) | m_data[5];
112 }
113 QString ProviderAvailIdString(void) const
114 {
115 return QString(QChar(m_data[6])) + QChar(m_data[7]) +
116 QChar(m_data[8]) + QChar(m_data[9]);
117 }
118
119 QString toString(void) const override // SpliceDescriptor
120 {
121 return QString("Splice Avail: id(%1)").arg(ProviderAvailId());
122 }
123};
124
126{
127 public:
128 explicit DTMFDescriptor(const unsigned char *data, int len = 300) :
129 SpliceDescriptor(data, len, SpliceDescriptorID::dtmf) { }
130
131 // Name bits loc expected value
132 // splice_descriptor_tag 8 0.0 0x01
133 // descriptor_length 8 1.0
134 // identifier 32 2.0 0x43554549 "CUEI"
135 // preroll 8 6.0
136 uint Preroll(void) const { return m_data[6]; }
137 // dtmf_count 3 7.0
138 uint DTMFCount(void) const { return m_data[7]>>5; }
139 // reserved 5 7.3
140 // for (i = 0; i < dtmf_count; i++)
141 // DTMF_char 8 8.0+i
142 char DTMFChar(uint i) const { return m_data[8+i]; }
143 QString DTMFString(void) const
144 {
145 QByteArray ba(reinterpret_cast<const char*>(m_data+8), DTMFCount());
146 return {ba};
147 }
148
149 static bool IsParsible(const unsigned char *data, uint safe_bytes);
150
151 QString toString(void) const override // SpliceDescriptor
152 {
153 return QString("Splice DTMF: %1").arg(DTMFString());
154 }
155};
156
158{
159 public:
160 explicit SegmentationDescriptor(const unsigned char *data, int len = 300) :
161 SpliceDescriptor(data, len, SpliceDescriptorID::segmentation)
162 {
163 _ptrs.fill(nullptr);
165 m_data = nullptr;
166 }
167
168 // Name bits loc expected value
169 // splice_descriptor_tag 8 0.0 0x01
170 // descriptor_length 8 1.0
171 // identifier 32 2.0 0x43554549 "CUEI"
172 // segmentation_event_id 32 6.0
174 {
175 return (m_data[2]<<24) | (m_data[3]<<16) | (m_data[4]<<8) | m_data[5];
176 }
177 QString SegmentationEventIdString(void) const
178 {
179 return QString(QChar(m_data[6])) + QChar(m_data[7]) +
180 QChar(m_data[8]) + QChar(m_data[9]);
181 }
182 // segmentation_event_cancel_indicator 1 10.0
183 bool IsSegmentationEventCancel(void) const { return ( m_data[10] & 0x80 ) != 0; }
184 // reserved 7 10.1
185 // if (segmentation_event_cancel_indicator == ‘0’) {
186 // program_seg_flag 1 11.0
187 bool IsProgramSegmentation(void) const { return ( m_data[11] & 0x80 ) != 0; }
188 // seg_duration_flag 1 11.1
189 bool HasSegmentationDuration(void) const { return ( m_data[11] & 0x40 ) != 0; }
190 // reserved 6 11.2
191 // if (program_segmentation_flag == ‘0’) {
192 // component_count 8 12
193 uint ComponentCount(void) const { return m_data[12]; }
194 // for (i = 0; i < component_count; i++) {
195 // component_tag 8 13 + i * 6
196 uint ComponentTag(uint i) const { return m_data[13 + (i * 6)]; }
197 // reserved 7 14.1 + i * 6
198 // pts_offset 33 14.7 + i * 6
199 uint64_t PTSOffset(uint i)
200 {
201 return ((uint64_t(m_data[14+(i*6)] & 0x1) << 32) |
202 (uint64_t(m_data[15+(i*6)]) << 24) |
203 (uint64_t(m_data[16+(i*6)]) << 16) |
204 (uint64_t(m_data[17+(i*6)]) << 8) |
205 (uint64_t(m_data[18+(i*6)])));
206 }
207 // }
208 // }
209 // if(segmentation_duration_flag == ‘1’)
210 // segmentation_duration 40 _ptrs[0]
211 uint64_t SegmentationDuration(void) const
212 {
213 return ((uint64_t(_ptrs[0][0]) << 32) |
214 (uint64_t(_ptrs[0][1]) << 24) |
215 (uint64_t(_ptrs[0][2]) << 16) |
216 (uint64_t(_ptrs[0][3]) << 8) |
217 (uint64_t(_ptrs[0][4])));
218 }
219 // segmentation_upid_type 8 _ptrs[1]
220 enum : std::uint8_t
221 {
222 kNotUsed = 0x0,
223 kVariable = 0x1,
224 kISCI = 0x2,
225 kAdID = 0x3,
226 kUMID = 0x4,
227 kISAN = 0x5,
228 kVISAN = 0x6,
229 kTID = 0x7,
230 kTI = 0x8,
231 kADI = 0x9,
232 };
233 uint SegmentationUPIDType(void) const { return _ptrs[1][0]; }
234 // segmentation_upid_length 8 _ptrs[1]+1
236 { return _ptrs[1][1]; }
237 // segmentation_upid() ? _ptrs[1]+2
238 const unsigned char *SegmentationUPID(void) const
239 {
240 // Access the array in two steps so cppcheck doesn't get confused.
241 unsigned char const *p = _ptrs[1];
242 return p+2;
243 }
244 QString SegmentationUPIDString(void) const
245 {
246 QByteArray ba(reinterpret_cast<const char*>(_ptrs[1]+2),
248 return {ba};
249 }
250
251 enum : std::uint8_t
252 {
270 };
271 // segmentation_type_id 8 _ptrs[2]
272 uint SegmentationTypeID(void) const { return _ptrs[2][0]; }
273 // segment_num 8 _ptrs[2]+1
274 uint SegmentNum(void) const { return _ptrs[2][1]; }
275 // segments_expected 8 _ptrs[2]+2
276 uint SegmentsExpected(void) const { return _ptrs[2][2]; }
277 // }
278
279 bool Parse(void) override; // SpliceDescriptor
280 QString toString(void) const override; // SpliceDescriptor
281
282 // _ptrs[0] = program_segmentation_flag ? 12 : 13 + component_count * 6
283 // _ptrs[1] = _ptrs[0] + HasSegmentationDuration() ? 5 : 0
284 // _ptrs[2] = _ptrs[1] + 2 + SegmentationUPIDLength()
285 std::array<unsigned char const *,3> _ptrs {};
286};
uint ProviderAvailId(void) const
QString toString(void) const override
QString ProviderAvailIdString(void) const
AvailDescriptor(const unsigned char *data, int len=300)
QString DTMFString(void) const
static bool IsParsible(const unsigned char *data, uint safe_bytes)
DTMFDescriptor(const unsigned char *data, int len=300)
uint DTMFCount(void) const
QString toString(void) const override
char DTMFChar(uint i) const
uint Preroll(void) const
std::array< unsigned char const *, 3 > _ptrs
uint SegmentNum(void) const
bool Parse(void) override
uint SegmentationUPIDLength(void) const
uint SegmentationTypeID(void) const
uint SegmentationEventId(void) const
uint ComponentTag(uint i) const
QString SegmentationEventIdString(void) const
const unsigned char * SegmentationUPID(void) const
uint SegmentationUPIDType(void) const
uint64_t PTSOffset(uint i)
QString toString(void) const override
bool IsProgramSegmentation(void) const
uint64_t SegmentationDuration(void) const
SegmentationDescriptor(const unsigned char *data, int len=300)
uint SegmentsExpected(void) const
QString SegmentationUPIDString(void) const
uint ComponentCount(void) const
bool HasSegmentationDuration(void) const
bool IsSegmentationEventCancel(void) const
@ kVISAN
versioned ISAN See ISO 15706-2
@ kTID
TMS ProgramID 2 alpha followed by 10 numeric.
@ kISAN
ISAN See ISO 15706.
@ kISCI
4 alpha + 4 numeric
@ kNotUsed
upid is not present in the descriptor
@ kADI
ADI See MD-SP-ADI2.0-AS-I03-070105.
@ kUMID
UMID See SMPTE 330M.
@ kAdID
4 alpha + 4 alphanumeric
@ kTI
Turner Identifier.
ANSI/SCTE 35 splice descriptor implementation Copyright (c) 2011, Digital Nirvana,...
SpliceDescriptor(const unsigned char *data, int len, uint tag)
bool IsValid(void) const
static desc_list_t ParseAndExclude(const unsigned char *data, uint len, int excluded_descid)
uint DescriptorLength(void) const
virtual ~SpliceDescriptor(void)=default
virtual QString toStringXML(uint indent_level) const
Returns XML representation of string the TS Reader XML format.
const unsigned char * m_data
static desc_list_t ParseOnlyInclude(const unsigned char *data, uint len, int excluded_descid)
QString IdentifierString(void) const
SpliceDescriptor(const unsigned char *data, int len)
uint DescriptorTag(void) const
QString DescriptorTagString(void) const
static desc_list_t FindAll(const desc_list_t &parsed, uint desc_tag)
uint Identifier(void) const
virtual QString toString(void) const
virtual bool Parse(void)
uint size(void) const
static const unsigned char * Find(const desc_list_t &parsed, uint desc_tag)
unsigned int uint
Definition: freesurround.h:24
std::vector< const unsigned char * > desc_list_t