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 #include "splicedescriptors.h"
25 #include "mythmiscutil.h" // for xml_indent
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 
88 const unsigned char *SpliceDescriptor::Find(
89  const desc_list_t &parsed, uint desc_tag)
90 {
91  desc_list_t::const_iterator it = parsed.begin();
92  for (; it != parsed.end(); ++it)
93  {
94  if ((*it)[0] == desc_tag)
95  return *it;
96  }
97  return nullptr;
98 }
99 
101 {
103  desc_list_t::const_iterator it = parsed.begin();
104  for (; it != parsed.end(); ++it)
105  {
106  if ((*it)[0] == desc_tag)
107  tmp.push_back(*it);
108  }
109  return tmp;
110 }
111 
113 {
114  switch (DescriptorTag())
115  {
117  return QString("Avail");
119  return QString("DTMF");
121  return QString("Segmentation");
122  default:
123  return QString("Unknown(%1)").arg(DescriptorTag());
124  }
125 }
126 
127 QString SpliceDescriptor::toString(void) const
128 {
129  QString str;
130 
131  if (!IsValid())
132  return "Invalid Splice Descriptor";
134  {
135  auto desc = AvailDescriptor(_data);
136  if (desc.IsValid())
137  str = desc.toString();
138  }
140  {
141  auto desc = DTMFDescriptor(_data);
142  if (desc.IsValid())
143  str = desc.toString();
144  }
146  {
147  auto desc = SegmentationDescriptor(_data);
148  if (desc.IsValid())
149  str = desc.toString();
150  }
151  else
152  {
153  str.append(QString("%1 Splice Descriptor (0x%2)")
154  .arg(DescriptorTagString())
155  .arg(int(DescriptorTag()), 0, 16));
156  str.append(QString(" length(%1)").arg(int(DescriptorLength())));
157  for (uint i=0; i<DescriptorLength(); i++)
158  str.append(QString(" 0x%1").arg(int(_data[i+2]), 0, 16));
159  }
160 
161  return str.isEmpty() ? "Invalid Splice Descriptor" : str;
162 }
163 
167 {
168  QString indent_0 = xml_indent(level);
169  QString indent_1 = xml_indent(level+1);
170  QString str;
171 
172  str += indent_0 + "<DESCRIPTOR namespace=\"splice\">\n";
173  str += indent_1 + QString("<TAG>0x%1</TAG>\n")
174  .arg(DescriptorTag(),2,16,QChar('0'));
175  str += indent_1 + QString("<DESCRIPTION>%1</DESCRIPTION>\n")
176  .arg(DescriptorTagString(),0,16);
177 
178  str += indent_1 + "<DATA>";
179  for (uint i = 0; i < DescriptorLength(); i++)
180  str += QString("0x%1 ").arg(_data[i+2],2,16,QChar('0'));
181  str = str.trimmed();
182  str += "</DATA>\n";
183 
184  str += indent_1 + "<DECODED>" + toString() + "</DECODED>";
185 
186  str += indent_0 + "</DESCRIPTOR>";
187 
188  return str;
189 }
190 
191 bool DTMFDescriptor::IsParsible(const unsigned char *data, uint safe_bytes)
192 {
193  if (safe_bytes < 8)
194  return false;
195  if (data[0] != SpliceDescriptorID::dtmf)
196  return false;
197  uint len = data[1];
198  if (len + 2 > safe_bytes)
199  return false;
200  if (data[2] != 'C' || data[3] != 'U' ||
201  data[4] != 'E' || data[5] != 'I')
202  return false;
203  return len == (6 + uint(data[7]>>5));
204 }
205 
207 {
208  _ptrs[0] = _data + (IsProgramSegmentation() ? 12 : 13 + ComponentCount() * 6);
209  _ptrs[1] = _ptrs[0] + (HasSegmentationDuration() ? 5 : 0);
210  _ptrs[2] = _ptrs[1] + 2 + SegmentationUPIDLength();
211  return true;
212 }
213 
215 {
216  // TODO
217  return QString("Segmentation: id(%1)").arg(SegmentationEventIdString());
218 }
219 
220 #endif // _SPLICE_DESCRIPTOR_H_
QString toString(void) const override
static desc_list_t ParseOnlyInclude(const unsigned char *data, uint len, int excluded_descid)
uint DescriptorLength(void) const
QString SegmentationEventIdString(void) const
unsigned int uint
Definition: compat.h:140
vector< const unsigned char * > desc_list_t
bool HasSegmentationDuration(void) const
static guint32 * tmp
Definition: goom_core.c:35
uint ComponentCount(void) const
static bool IsParsible(const unsigned char *data, uint safe_bytes)
QString DescriptorTagString(void) const
static const unsigned char * Find(const desc_list_t &parsed, uint desc_tag)
unsigned char const * _ptrs[3]
virtual bool Parse(void)
uint size(void) const
bool IsValid(void) const
virtual QString toString(void) const
virtual QString toStringXML(uint indent_level) const
Returns XML representation of string the TS Reader XML format.
static desc_list_t ParseAndExclude(const unsigned char *data, uint len, int excluded_descid)
uint SegmentationUPIDLength(void) const
const unsigned char * _data
bool IsProgramSegmentation(void) const
static desc_list_t FindAll(const desc_list_t &parsed, uint desc_tag)
bool Parse(void) override
uint DescriptorTag(void) const
QString xml_indent(uint level)