MythTV master
splicedescriptors.cpp
Go to the documentation of this file.
1// -*- Mode: c++ -*-
21#ifndef SPLICE_DESCRIPTOR_H
22#define SPLICE_DESCRIPTOR_H
23
24// C++ headers
25#include <algorithm>
26
27 // MythTV
29#include "splicedescriptors.h"
30
32 const unsigned char *data, uint len)
33{
34 desc_list_t tmp;
35 uint off = 0;
36 while (off < len)
37 {
38 tmp.push_back(data+off);
39 SpliceDescriptor desc(data+off, len-off);
40 if (!desc.IsValid())
41 {
42 tmp.pop_back();
43 break;
44 }
45 off += desc.size();
46 }
47 return tmp;
48}
49
51 const unsigned char *data, uint len, int excluded_descid)
52{
53 desc_list_t tmp;
54 uint off = 0;
55 while (off < len)
56 {
57 if ((data+off)[0] != excluded_descid)
58 tmp.push_back(data+off);
59 SpliceDescriptor desc(data+off, len-off);
60 if (!desc.IsValid())
61 {
62 if ((data+off)[0] != excluded_descid)
63 tmp.pop_back();
64 break;
65 }
66 off += desc.size();
67 }
68 return tmp;
69}
70
72 const unsigned char *data, uint len, int excluded_descid)
73{
74 desc_list_t tmp;
75 uint off = 0;
76 while (off < len)
77 {
78 if ((data+off)[0] == excluded_descid)
79 tmp.push_back(data+off);
80 SpliceDescriptor desc(data+off, len-off);
81 if (!desc.IsValid())
82 {
83 if ((data+off)[0] == excluded_descid)
84 tmp.pop_back();
85 break;
86 }
87 off += desc.size();
88 }
89 return tmp;
90}
91
92const unsigned char *SpliceDescriptor::Find(
93 const desc_list_t &parsed, uint desc_tag)
94{
95 auto sametag = [desc_tag](const auto *item){ return item[0] == desc_tag; };
96 auto it = std::ranges::find_if(parsed, sametag);
97 return (it != parsed.cend()) ? *it : nullptr;
98}
99
101{
102 desc_list_t tmp;
103 auto sametag = [desc_tag](const auto *item) { return item[0] == desc_tag; };
104 std::ranges::copy_if(parsed, std::back_inserter(tmp), sametag);
105 return tmp;
106}
107
109{
110 switch (DescriptorTag())
111 {
113 return {"Avail"};
115 return {"DTMF"};
117 return {"Segmentation"};
118 default:
119 return QString("Unknown(%1)").arg(DescriptorTag());
120 }
121}
122
123QString SpliceDescriptor::toString(void) const
124{
125 QString str;
126
127 if (!IsValid())
128 return "Invalid Splice Descriptor";
130 {
131 auto desc = AvailDescriptor(m_data);
132 if (desc.IsValid())
133 str = desc.toString();
134 }
136 {
137 auto desc = DTMFDescriptor(m_data);
138 if (desc.IsValid())
139 str = desc.toString();
140 }
142 {
143 auto desc = SegmentationDescriptor(m_data);
144 if (desc.IsValid())
145 str = desc.toString();
146 }
147 else
148 {
149 str.append(QString("%1 Splice Descriptor (0x%2)")
150 .arg(DescriptorTagString())
151 .arg(int(DescriptorTag()), 0, 16));
152 str.append(QString(" length(%1)").arg(int(DescriptorLength())));
153 for (uint i=0; i<DescriptorLength(); i++)
154 str.append(QString(" 0x%1").arg(int(m_data[i+2]), 0, 16));
155 }
156
157 return str.isEmpty() ? "Invalid Splice Descriptor" : str;
158}
159
163{
164 QString indent_0 = StringUtil::indentSpaces(level);
165 QString indent_1 = StringUtil::indentSpaces(level+1);
166 QString str;
167
168 str += indent_0 + "<DESCRIPTOR namespace=\"splice\">\n";
169 str += indent_1 + QString("<TAG>0x%1</TAG>\n")
170 .arg(DescriptorTag(),2,16,QChar('0'));
171 str += indent_1 + QString("<DESCRIPTION>%1</DESCRIPTION>\n")
172 .arg(DescriptorTagString());
173
174 str += indent_1 + "<DATA>";
175 for (uint i = 0; i < DescriptorLength(); i++)
176 str += QString("0x%1 ").arg(m_data[i+2],2,16,QChar('0'));
177 str = str.trimmed();
178 str += "</DATA>\n";
179
180 str += indent_1 + "<DECODED>" + toString() + "</DECODED>";
181
182 str += indent_0 + "</DESCRIPTOR>";
183
184 return str;
185}
186
187bool DTMFDescriptor::IsParsible(const unsigned char *data, uint safe_bytes)
188{
189 if (safe_bytes < 8)
190 return false;
191 if (data[0] != SpliceDescriptorID::dtmf)
192 return false;
193 uint len = data[1];
194 if (len + 2 > safe_bytes)
195 return false;
196 if (data[2] != 'C' || data[3] != 'U' ||
197 data[4] != 'E' || data[5] != 'I')
198 return false;
199 return len == (6 + uint(data[7]>>5));
200}
201
203{
204 _ptrs[0] = m_data + (IsProgramSegmentation() ? 12 : 13 + (ComponentCount() * 6));
205 _ptrs[1] = _ptrs[0] + (HasSegmentationDuration() ? 5 : 0);
206 _ptrs[2] = _ptrs[1] + 2 + SegmentationUPIDLength();
207 return true;
208}
209
211{
212 // TODO
213 return QString("Segmentation: id(%1)").arg(SegmentationEventIdString());
214}
215
216#endif // SPLICE_DESCRIPTOR_H
static bool IsParsible(const unsigned char *data, uint safe_bytes)
std::array< unsigned char const *, 3 > _ptrs
bool Parse(void) override
uint SegmentationUPIDLength(void) const
QString SegmentationEventIdString(void) const
QString toString(void) const override
bool IsProgramSegmentation(void) const
uint ComponentCount(void) const
bool HasSegmentationDuration(void) const
bool IsValid(void) const
static desc_list_t ParseAndExclude(const unsigned char *data, uint len, int excluded_descid)
uint DescriptorLength(void) const
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)
uint DescriptorTag(void) const
QString DescriptorTagString(void) const
static desc_list_t FindAll(const desc_list_t &parsed, uint desc_tag)
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: compat.h:60
std::vector< const unsigned char * > desc_list_t
QString indentSpaces(unsigned int level, unsigned int size=4)
Definition: stringutil.h:40