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