MythTV  master
mpegdescriptors.h
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 // Copyright (c) 2003-2004, Daniel Thor Kristjansson
3 #ifndef _MPEG_DESCRIPTORS_H_
4 #define _MPEG_DESCRIPTORS_H_
5 
6 // C++ headers
7 #include <vector>
8 using namespace std;
9 
10 // Qt headers
11 #include <QMutex>
12 #include <QString>
13 
14 // MythTV
15 #include "iso639.h"
16 #include "mythtvexp.h"
17 
18 typedef vector<const unsigned char*> desc_list_t;
19 
21 {
22  public:
23  enum
24  {
25  // MPEG
26  video = 0x02,
27  audio = 0x03,
28  hierarchy = 0x04,
29  registration = 0x05, /* implemented */
30  data_stream_alignment = 0x06,
31  target_background_grid = 0x07,
32  video_window = 0x08,
33  conditional_access = 0x09, /* implemented */
34  iso_639_language = 0x0A, /* implemented */
35  system_clock = 0x0B,
36  multiplex_buffer_utilization= 0x0C,
37  copyright = 0x0D,
38  maximum_bitrate = 0x0E,
39  private_data_indicator = 0x0F,
40  smoothing_buffer = 0x10,
41  std = 0x11,
42  ibp = 0x12,
43  carousel_identifier = 0x13,
44  association_tag = 0x14,
45  deferred_association_tag = 0x15,
46  /* RESERVED = 0x16, */
47  npt_reference = 0x17,
48  npt_endpoint = 0x18,
49  stream_mode = 0x19,
50  stream_event = 0x1A,
51  mpeg4_video = 0x1B,
52  mpeg4_audio = 0x1C,
53  iod = 0x1D,
54  sl = 0x1E,
55  fmc = 0x1F,
56  external_es_id = 0x20,
57  mux_code = 0x21,
58  fmx_buffer_size = 0x22,
59  multiplex_buffer = 0x23,
60  content_labeling = 0x24,
61  metadata_pointer = 0x25,
62  metadata = 0x26,
63  metadata_std = 0x27,
64  avc_video = 0x28, /* implemented */
65  ipmp = 0x29,
66  avc_timing_and_hrd = 0x2A, /* partial */
67  mpeg2_aac_audio = 0x2B,
68  flex_mux_timing = 0x2C,
69  hevc_video = 0x38,
70 
71  // DVB
72  network_name = 0x40, /* implemented */
73  service_list = 0x41, /* implemented */
74  dvb_stuffing = 0x42, /* implemented */
75  satellite_delivery_system = 0x43, /* implemented */
76  cable_delivery_system = 0x44, /* implemented */
77  vbi_data = 0x45, /* partial */
78  vbi_teletext = 0x46, /* partial */
79  bouquet_name = 0x47, /* implemented */
80  service = 0x48, /* implemented, toString lacking */
81  country_availability = 0x49, /* implemented */
82  linkage = 0x4A, /* partial */
83  nvod_reference = 0x4B, /* partial */
84  dvb_time_shifted_service = 0x4C, /* partial */
85  short_event = 0x4D, /* implemented */
86  extended_event = 0x4E, /* implemented */
87  time_shifted_event = 0x4F, /* partial */
88 
89  component = 0x50, /* implemented, toString lacking */
90  mosaic = 0x51, /* partial */
91  stream_identifier = 0x52, /* implemented */
92  ca_identifier = 0x53, /* partial */
93  content = 0x54, /* implemented */
94  parental_rating = 0x55, /* partial */
95  teletext = 0x56, /* partial */
96  telephone = 0x57, /* partial */
97  local_time_offset = 0x58,
98  subtitling = 0x59, /* partial */
99  terrestrial_delivery_system = 0x5A, /* implemented */
100  multilingual_network_name = 0x5B, /* partial */
101  multilingual_bouquet_name = 0x5C, /* partial */
102  multilingual_service_name = 0x5D, /* partial */
103  multilingual_component = 0x5E,
104  private_data_specifier = 0x5F, /* partial */
105 
106  service_move = 0x60, /* partial */
107  short_smoothing_buffer = 0x61, /* partial */
108  frequency_list = 0x62, /* implemented */
109  partial_transport_stream = 0x63, /* partial */
110  data_broadcast = 0x64, /* partial */
111  scrambling = 0x65, /* partial */
112  data_broadcast_id = 0x66, /* partial */
113  transport_stream = 0x67, /* partial */
114  dsng = 0x68, /* partial */
115  pdc = 0x69, /* partial */
116  ac3 = 0x6A, /* partial */
117  ancillary_data = 0x6B, /* partial */
118  cell_list = 0x6C, /* partial */
119  cell_frequency_link = 0x6D, /* partial */
120  announcement_support = 0x6E, /* partial */
121  application_signalling = 0x6F,
122 
123  adaptation_field_data = 0x70, /* partial */
124  service_identifier = 0x71,
125  service_availability = 0x72, /* partial */
126  default_authority = 0x73, /* implemented */
127  related_content = 0x74,
128  tva_id = 0x75,
129  dvb_content_identifier = 0x76, /* partial */
130  time_slice_fec_identifier = 0x77,
131  ecm_repetition_rate = 0x78,
132  s2_delivery_system = 0x79,
133  eac3 = 0x7A,
134  dts = 0x7B,
135  aac = 0x7C,
136 
137  // ATSC
138  atsc_stuffing = 0x80,
139  ac3_audio_stream = 0x81, /* partial */
140  atsc_program_identifier = 0x85,
141  caption_service = 0x86, /* implemented */
142  content_advisory = 0x87,
143  atsc_ca_descriptor = 0x88,
144  atsc_descriptor_tag = 0x89,
145 
146  // SCTE
147  scte_frame_rate = 0x82, /* implemented, also ATSC */
148  scte_extended_video = 0x83, /* implemented, also ATSC */
149  scte_component_name = 0x84, /* implemented, also ATSC */
150  scte_cue_identifier = 0x8A, /* implemented */
151  scte_frequency_spec = 0x90, /* implemented */
152  scte_modulation_params = 0x91, /* implemented */
153  scte_transport_stream_id = 0x92, /* implemented */
154  scte_revision_detection = 0x93, /* implemented */
155 
156  // ATSC
157  extended_channel_name = 0xA0, /* implemented */
158  service_location = 0xA1,
159  atsc_time_shifted_service = 0xA2,
160  component_name = 0xA3, /* implemented */
161  atsc_data_service = 0xA4,
162  atsc_pid_count = 0xA5,
163  atsc_download = 0xA6,
164  multiprotocol_encapsulation = 0xA7,
165  dcc_departing_request = 0xA8,
166  dcc_arriving_request = 0xA9,
167  drm_control = 0xAA,
168  atsc_genre = 0xAB,
169  atsc_private_information = 0xAD,
170 
171  atsc_content_identifier = 0xB6, /* partial */
172  };
173 };
174 
176 {
177  public:
178  enum
179  {
180  // These can conflict and should only be used
181  // on these specific networks.
182 
183  // Private -- UK
184  dvb_logical_channel_descriptor = 0x83, /* implemented */
185 
186  // Private -- Dish Network
187  dish_event_rights = 0x87,
188  dish_event_mpaa = 0x89, /* implemented */
189  dish_event_name = 0x91, /* implemented */
190  dish_event_description = 0x92, /* implemented */
191  dish_event_properties = 0x94, /* implemented */
192  dish_event_vchip = 0x95, /* implemented */
193  dish_event_tags = 0x96, /* implemented */
194 
195  // Private -- CH UPC Cablecom
196  upc_event_episode_title = 0xA7,
197 
198  // Private -- premiere.de
199  premiere_content_order = 0xF0,
200  premiere_parental_information = 0xF1,
201  premiere_content_transmission = 0xF2,
202  };
203 };
204 
205 /*
206  * Private_Data_Specifier_ID from http://www.dvbservices.com/identifiers/private_data_spec_id
207  */
209 {
210  public:
211  enum
212  {
213  /* UPC Cablecom */
214  UPC1 = 0x00000600,
215  };
216 };
217 
219 {
220  public:
221  operator const unsigned char*() const { return _data; }
222 
223  MPEGDescriptor(const unsigned char *data, int len = 300) : _data(data)
224  {
225  if ((len < 2) || (int(DescriptorLength()) + 2) > len)
226  _data = nullptr;
227  }
228  MPEGDescriptor(const unsigned char *data,
229  int len, uint tag) : _data(data)
230  {
231  if ((len < 2) || (int(DescriptorLength()) + 2) > len)
232  _data = nullptr;
233  else if (DescriptorTag() != tag)
234  _data = nullptr;
235  }
236  MPEGDescriptor(const unsigned char *data,
237  int len, uint tag, uint req_desc_len) : _data(data)
238  {
239  if ((len < 2) || (int(DescriptorLength()) + 2) > len)
240  _data = nullptr;
241  else if (DescriptorTag() != tag)
242  _data = nullptr;
243  else if (DescriptorLength() != req_desc_len)
244  _data = nullptr;
245  }
246  virtual ~MPEGDescriptor() = default;
247 
248  bool IsValid(void) const { return _data; }
249  uint size(void) const { return DescriptorLength() + 2; }
250 
251  uint DescriptorTag(void) const { return _data[0]; }
252  QString DescriptorTagString(void) const;
253  uint DescriptorLength(void) const { return _data[1]; }
254 
255  virtual QString toString(void) const;
256  virtual QString toStringXML(uint indent_level) const;
257 
258  static desc_list_t Parse(const unsigned char *data, uint len);
259  static desc_list_t ParseAndExclude(const unsigned char *data, uint len,
260  int descriptorid);
261  static desc_list_t ParseOnlyInclude(const unsigned char *data, uint len,
262  int descriptorid);
263 
264  static const unsigned char *Find(const desc_list_t &parsed, uint desc_tag);
265  static desc_list_t FindAll(const desc_list_t &parsed, uint desc_tag);
266 
267  static const unsigned char *FindBestMatch(
268  const desc_list_t &parsed, uint desc_tag, QMap<uint,uint> &langPref);
269  static desc_list_t FindBestMatches(
270  const desc_list_t &parsed, uint desc_tag, QMap<uint,uint> &langPref);
271 
272  protected:
273  const unsigned char *_data;
274  QString hexdump(void) const;
275 };
276 
277 // a_52a.pdf p119, Table A1
279 {
280  public:
281  RegistrationDescriptor(const unsigned char *data, int len = 300) :
282  MPEGDescriptor(data, len, DescriptorID::registration)
283  {
284  // The HD-PVR outputs a registration descriptor with a length
285  // of 8 rather than 4, so we accept any length >= 4, not just 4.
286  if (DescriptorLength() < 4)
287  _data = nullptr;
288  }
289 
290  uint FormatIdentifier(void) const
291  { return (_data[2]<<24) | (_data[3]<<16) | (_data[4]<<8) | _data[5]; }
292  QString FormatIdentifierString(void) const
293  {
294  return QString("") + QChar(_data[2]) + QChar(_data[3]) +
295  QChar(_data[4]) + QChar(_data[5]);
296  }
297  QString toString() const override; // MPEGDescriptor
298 
299  private:
300  static void InitializeDescriptionMap(void);
301  static QString GetDescription(const QString &fmt);
302 
303  private:
304  static QMutex description_map_lock;
306  static QMap<QString,QString> description_map;
307 };
308 
310 {
311  public:
312  ConditionalAccessDescriptor(const unsigned char *data, int len = 300) :
313  MPEGDescriptor(data, len, DescriptorID::conditional_access) { }
314 
315  uint SystemID(void) const { return _data[2] << 8 | _data[3]; }
316  uint PID(void) const { return (_data[4] & 0x1F) << 8 | _data[5]; }
317  uint DataSize(void) const { return DescriptorLength() - 4; }
318  const unsigned char *Data(void) const { return &_data[6]; }
319  QString toString() const override; // MPEGDescriptor
320 };
321 
323 {
324  public:
325  ISO639LanguageDescriptor(const unsigned char *data, int len = 300) :
326  MPEGDescriptor(data, len, DescriptorID::iso_639_language) { }
327 
328  const unsigned char* CodeRaw() const { return &_data[2]; }
329  uint AudioType() const { return _data[5]; }
330 
331  int LanguageKey(void) const
332  { return iso639_str3_to_key(&_data[2]); }
333  QString LanguageString(void) const
334  { return iso639_key_to_str3(LanguageKey()); }
335  int CanonicalLanguageKey(void) const
336  { return iso639_key_to_canonical_key(LanguageKey()); }
337  QString CanonicalLanguageString(void) const
338  { return iso639_key_to_str3(CanonicalLanguageKey()); }
339 
340  QString toString() const override; // MPEGDescriptor
341 };
342 
345 {
346  public:
347  AVCVideoDescriptor(const unsigned char *data, int len = 300) :
348  MPEGDescriptor(data, len, DescriptorID::avc_video) { }
349  // Name bits loc expected value
350  // descriptor_tag 8 0.0 0x
351  // descriptor_length 8 1.0
352  // profile_idc 8 2.0
353  uint ProfileIDC(void) const { return _data[2]; }
354  // constraint_set0_flag 1 3.0
355  bool ConstaintSet0(void) const { return _data[3]&0x80; }
356  // constraint_set1_flag 1 3.1
357  bool ConstaintSet1(void) const { return _data[3]&0x40; }
358  // constraint_set2_flag 1 3.2
359  bool ConstaintSet2(void) const { return _data[3]&0x20; }
360  // AVC_compatible_flags 5 3.3
361  uint AVCCompatible(void) const { return _data[3]&0x1f; }
362  // level_idc 8 4.0
363  uint LevelIDC(void) const { return _data[4]; }
364  // AVC_still_present 1 5.0
365  bool AVCStill(void) const { return _data[5]&0x80; }
366  // AVC_24_hour_picture_flag 1 5.1
367  bool AVC24HourPicture(void) const { return _data[5]&0x40; }
369  const { return _data[5]&0x20; }
370  // reserved 6 bslbf
371  QString toString() const override; // MPEGDescriptor
372 };
373 
376 {
377  public:
378  AVCTimingAndHRDDescriptor(const unsigned char *data, int len = 300) :
379  MPEGDescriptor(data, len, DescriptorID::avc_timing_and_hrd) { }
380  // Name bits loc expected value
381  // descriptor_tag 8 0.0 0x
382  // descriptor_length 8 1.0
383  // hrd_management_valid 1 2.0
384  bool HRDManagementValid(void) const { return _data[2]&0x80; }
385  // reserved 6 2.1
386  // picture_and_timing_info_present 1 2.7
387  bool HasPictureAndTimingInfo(void) const { return _data[2]&0x01;}
388  // if (picture_and_timing_info_present) {
389  // 90kHz_flag 1 3.0
390  // reserved 7 3.1
391  // if (90kHz_flag == '0') {
392  // N 32 4.0 uimsbf
393  // K 32 8.0 uimsbf
394  // }
395  // num_units_in_tick 32 (90khz)?4.0:12.0 uimsbf
396  // }
397  // fixed_frame_rate_flag 1 (pict_info)?((90khz)?8.0:16.0):3.0
398  // temporal_poc_flag 1 (pict_info)?((90khz)?8.1:16.1):3.1
399  // picture_to_display_conversion_flag 1 (pict_info)?((90khz)?8.2:16.2):3.2
400  // reserved 5 bslbf
401 };
402 
405 {
406  public:
407  HEVCVideoDescriptor(const unsigned char *data, int len = 300) :
408  MPEGDescriptor(data, len, DescriptorID::avc_video) { }
409  // Name bits loc expected value
410  // descriptor_tag 8 0.0 0x38
411  // descriptor_length 8 1.0
412 
413  // the encoding of the following is specified in Rec. ITU-T H.265 | ISO/IEC 23008-2
414  // profile_space 2 2.0
415  uint ProfileSpace(void) const { return _data[2]&0xC0 >> 6; }
416  // tier_flag 1 2.2
417  bool Tier(void) const { return _data[2]&0x20; }
418  // profile_idc 5 2.3
419  uint ProfileIDC(void) const { return _data[2] >> 3; }
420  // profile_compatibility_indication 32 3.0
421  // progressive_source_flag 1 7.0
422  // interlaced_source_flag 1 7.1
423  // non_packed_constraint_flag 1 7.2
424  // frame_only_constraint_flag 1 7.3
425  // reserved_zero_44bits 44 7.4
426  // level_idc 8 13.0
427 
428  // temporal_layer_subset_flag 1 14.0
429  // HEVC_still_present_flag 1 14.1
430  // HEVC_24hr_picture_present_flag 1 14.2
431  // reserved 5 14.3
432 
433  // if temporal_layer_subset_flag == true and
434  // descriptor_length == 17 instead of 15 then
435  // reserved 5 15.0
436  // temporal_id_min 3 15.5
437  // reserved 5 16.0
438  // temporal_id_max 3 16.5
439 
440  QString toString() const override; // MPEGDescriptor
441 };
442 
443 #endif // _MPEG_DESCRIPTORS_H_
uint FormatIdentifier(void) const
bool FramePackingSEINotPresentFlag(void) const
ISO 639-1 and ISO 639-2 support functions.
ISO 13818-1:2000/Amd.3:2004 page 12.
bool ConstaintSet0(void) const
QString toString(MarkTypes type)
QString CanonicalLanguageString(void) const
int LanguageKey(void) const
uint ProfileSpace(void) const
uint LevelIDC(void) const
bool AVCStill(void) const
uint DescriptorTag(void) const
bool HRDManagementValid(void) const
unsigned int uint
Definition: compat.h:140
static int iso639_str3_to_key(const unsigned char *iso639_2)
Definition: iso639.h:63
vector< const unsigned char * > desc_list_t
static bool description_map_initialized
int iso639_key_to_canonical_key(int iso639_2)
Definition: iso639.cpp:122
AVCTimingAndHRDDescriptor(const unsigned char *data, int len=300)
uint size(void) const
const unsigned char * CodeRaw() const
uint AVCCompatible(void) const
HEVCVideoDescriptor(const unsigned char *data, int len=300)
#define MTV_PUBLIC
Definition: mythtvexp.h:15
const unsigned char * Data(void) const
MPEGDescriptor(const unsigned char *data, int len=300)
ISO 13818-1:2000/Amd.3:2004 page 11.
static QMutex description_map_lock
bool HasPictureAndTimingInfo(void) const
ConditionalAccessDescriptor(const unsigned char *data, int len=300)
uint ProfileIDC(void) const
MPEGDescriptor(const unsigned char *data, int len, uint tag)
static QMap< QString, QString > description_map
ISO639LanguageDescriptor(const unsigned char *data, int len=300)
uint DescriptorLength(void) const
int CanonicalLanguageKey(void) const
ISO 13818-1:2013/FDAM 3 (E) page 7.
QString FormatIdentifierString(void) const
bool AVC24HourPicture(void) const
bool Tier(void) const
const unsigned char * _data
bool ConstaintSet1(void) const
RegistrationDescriptor(const unsigned char *data, int len=300)
static QString iso639_key_to_str3(int code)
Definition: iso639.h:46
MPEGDescriptor(const unsigned char *data, int len, uint tag, uint req_desc_len)
bool IsValid(void) const
bool ConstaintSet2(void) const
QString LanguageString(void) const
AVCVideoDescriptor(const unsigned char *data, int len=300)
uint ProfileIDC(void) const