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 using desc_list_t = vector<const unsigned char *>;
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_satellite_delivery_system = 0x79,
133  eac3 = 0x7A,
134  dts = 0x7B,
135  aac = 0x7C,
136  xait_location = 0x7D,
137  fta_content_management = 0x7E,
138  t2_terrestrial_delivery_system = 0x7F,
139 
140  // ATSC
141  atsc_stuffing = 0x80,
142  ac3_audio_stream = 0x81, /* partial */
143  atsc_program_identifier = 0x85,
144  caption_service = 0x86, /* implemented */
145  content_advisory = 0x87,
146  atsc_ca_descriptor = 0x88,
147  atsc_descriptor_tag = 0x89,
148 
149  // SCTE
150  scte_frame_rate = 0x82, /* implemented, also ATSC */
151  scte_extended_video = 0x83, /* implemented, also ATSC */
152  scte_component_name = 0x84, /* implemented, also ATSC */
153  scte_cue_identifier = 0x8A, /* implemented */
154  scte_frequency_spec = 0x90, /* implemented */
155  scte_modulation_params = 0x91, /* implemented */
156  scte_transport_stream_id = 0x92, /* implemented */
157  scte_revision_detection = 0x93, /* implemented */
158 
159  // ATSC
160  extended_channel_name = 0xA0, /* implemented */
161  service_location = 0xA1,
162  atsc_time_shifted_service = 0xA2,
163  component_name = 0xA3, /* implemented */
164  atsc_data_service = 0xA4,
165  atsc_pid_count = 0xA5,
166  atsc_download = 0xA6,
167  multiprotocol_encapsulation = 0xA7,
168  dcc_departing_request = 0xA8,
169  dcc_arriving_request = 0xA9,
170  drm_control = 0xAA,
171  atsc_genre = 0xAB,
172  atsc_private_information = 0xAD,
173 
174  atsc_content_identifier = 0xB6, /* partial */
175  };
176 };
177 
179 {
180  public:
181  enum
182  {
183  // These can conflict and should only be used
184  // on these specific networks.
185 
186  // Private -- UK and NL
187  dvb_logical_channel_descriptor = 0x83, /* implemented */
188  dvb_simulcast_channel_descriptor = 0x88, /* implemented */
189 
190  // Private -- NL Casema
191  casema_video_on_demand = 0x87,
192 
193  // Private -- Dish Network
194  dish_event_rights = 0x87,
195  dish_event_mpaa = 0x89, /* implemented */
196  dish_event_name = 0x91, /* implemented */
197  dish_event_description = 0x92, /* implemented */
198  dish_event_properties = 0x94, /* implemented */
199  dish_event_vchip = 0x95, /* implemented */
200  dish_event_tags = 0x96, /* implemented */
201 
202  // Private -- CH UPC Cablecom
203  upc_event_episode_title = 0xA7,
204 
205  // Private -- Sky Astra-2 28.2E and other Sky satellites
206  sky_lcn_table = 0xb1, /* implemented */
207 
208  // Private -- FreeSat Astra-2 28.2E
209  freesat_lcn_table = 0xd3, /* implemented */
210  freesat_region_table = 0xd4, /* implemented */
211  freesat_chan_cat_mapping = 0xd5, /* todo */
212  freesat_d6_table = 0xd6, /* unknown */
213  freesat_d7_table = 0xd7, /* unknown */
214  freesat_category_table = 0xd8, /* todo */
215  freesat_callsign = 0xd9, /* partial */
216 
217  // Private -- premiere.de
218  premiere_content_order = 0xF0,
219  premiere_parental_information = 0xF1,
220  premiere_content_transmission = 0xF2,
221 
222  // Private -- OpenTV
223  opentv_titles_1 = 0xA0,
224  opentv_titles_2 = 0xA1,
225  opentv_titles_3 = 0xA2,
226  opentv_titles_4 = 0xA3,
227  opentv_summaries_1 = 0xA8,
228  opentv_summaries_2 = 0xA9,
229  opentv_summaries_3 = 0xAA,
230  opentv_summaries_4 = 0xAB,
231  opentv_channel_list = 0xB1, /* sky_lcn_table */
232  };
233 };
234 
235 /*
236  * Private_Data_Specifier_ID from http://www.dvbservices.com/identifiers/private_data_spec_id
237  */
239 {
240  public:
241  enum
242  {
243  BSB1 = 0x00000002, // UK Sky (Astra 28.2E), Sky New Zealand (Optus D1 160E0)
244  CASEMA = 0x00000016, // NL Casema
245  EACEM = 0x00000028, // NL Ziggo
246  NORDIG = 0x00000029, // EU Nordig
247  UPC1 = 0x00000600, // UPC Cablecom
248  ITC = 0x0000233A, // Independent Television Commission
249  FSAT = 0x46534154, // UK BBC FreeSat on Astra 28.2E
250  };
251 };
252 
253 /*
254  * Original_Network_ID from http://www.dvbservices.com/identifiers/original_network_id
255  */
257 {
258  public:
259  enum
260  {
261  SES2 = 0x0002, // Société Européenne des Satellites
262  BBC = 0x003B, // BBC / Freesat
263  TELENOR = 0x0046, // Telenor Norway
264  SKYNZ = 0x00A9, // Sky New Zealand / Sky Network Television Ltd (NDS)
265  NOZEMA = 0x2210, // Netherlands Digital Terrestrial Television
266  };
267 };
268 
270 {
271  public:
272  operator const unsigned char*() const { return m_data; }
273 
274  explicit MPEGDescriptor(const unsigned char *data, int len = 300) : m_data(data)
275  {
276  if ((len < 2) || (int(DescriptorLength()) + 2) > len)
277  m_data = nullptr;
278  }
279  MPEGDescriptor(const unsigned char *data,
280  int len, uint tag) : m_data(data)
281  {
282  if ((len < 2) || ((int(DescriptorLength()) + 2) > len)
283  || (DescriptorTag() != tag))
284  m_data = nullptr;
285  }
286  MPEGDescriptor(const unsigned char *data,
287  int len, uint tag, uint req_desc_len) : m_data(data)
288  {
289  if ((len < 2) || ((int(DescriptorLength()) + 2) > len)
290  || (DescriptorTag() != tag)
291  || (DescriptorLength() != req_desc_len))
292  m_data = nullptr;
293  }
294  virtual ~MPEGDescriptor() = default;
295 
296  bool IsValid(void) const { return m_data; }
297  uint size(void) const { return DescriptorLength() + 2; }
298 
299  uint DescriptorTag(void) const { return m_data[0]; }
300  QString DescriptorTagString(void) const;
301  uint DescriptorLength(void) const { return m_data[1]; }
302 
303  virtual QString toString(void) const;
304  virtual QString toStringPD(uint priv_dsid) const;
305  virtual QString toStringXML(uint indent_level) const;
306 
307  static desc_list_t Parse(const unsigned char *data, uint len);
308  static desc_list_t ParseAndExclude(const unsigned char *data, uint len,
309  int excluded_descid);
310  static desc_list_t ParseOnlyInclude(const unsigned char *data, uint len,
311  int excluded_descid);
312 
313  static const unsigned char *Find(const desc_list_t &parsed, uint desc_tag);
314  static desc_list_t FindAll(const desc_list_t &parsed, uint desc_tag);
315 
316  static const unsigned char *FindBestMatch(
317  const desc_list_t &parsed, uint desc_tag, QMap<uint,uint> &langPref);
318  static desc_list_t FindBestMatches(
319  const desc_list_t &parsed, uint desc_tag, QMap<uint,uint> &langPref);
320 
321  protected:
322  const unsigned char *m_data;
323 
324  public:
325  QString hexdump(void) const;
326  QString descrDump(const QString &name) const;
327 };
328 
329 // a_52a.pdf p119, Table A1
331 {
332  public:
333  explicit RegistrationDescriptor(const unsigned char *data, int len = 300) :
334  MPEGDescriptor(data, len, DescriptorID::registration)
335  {
336  // The HD-PVR outputs a registration descriptor with a length
337  // of 8 rather than 4, so we accept any length >= 4, not just 4.
338  if (IsValid() && DescriptorLength() < 4)
339  m_data = nullptr;
340  }
341 
342  uint FormatIdentifier(void) const
343  { return (m_data[2]<<24) | (m_data[3]<<16) | (m_data[4]<<8) | m_data[5]; }
344  QString FormatIdentifierString(void) const
345  {
346  return QString("") + QChar(m_data[2]) + QChar(m_data[3]) +
347  QChar(m_data[4]) + QChar(m_data[5]);
348  }
349  QString toString() const override; // MPEGDescriptor
350 
351  private:
352  static void InitializeDescriptionMap(void);
353  static QString GetDescription(const QString &fmt);
354 
355  private:
356  static QMutex description_map_lock;
358  static QMap<QString,QString> description_map;
359 };
360 
362 {
363  public:
364  explicit ConditionalAccessDescriptor(const unsigned char *data, int len = 300) :
365  MPEGDescriptor(data, len, DescriptorID::conditional_access) { }
366 
367  uint SystemID(void) const { return m_data[2] << 8 | m_data[3]; }
368  uint PID(void) const { return (m_data[4] & 0x1F) << 8 | m_data[5]; }
369  uint DataSize(void) const { return DescriptorLength() - 4; }
370  const unsigned char *Data(void) const { return &m_data[6]; }
371  QString toString() const override; // MPEGDescriptor
372 };
373 
375 {
376  public:
377  explicit ISO639LanguageDescriptor(const unsigned char *data, int len = 300) :
378  MPEGDescriptor(data, len, DescriptorID::iso_639_language) { }
379 
380  const unsigned char* CodeRaw() const { return &m_data[2]; }
381  uint AudioType() const { return m_data[5]; }
382 
383  int LanguageKey(void) const
384  { return iso639_str3_to_key(&m_data[2]); }
385  QString LanguageString(void) const
386  { return iso639_key_to_str3(LanguageKey()); }
387  int CanonicalLanguageKey(void) const
388  { return iso639_key_to_canonical_key(LanguageKey()); }
389  QString CanonicalLanguageString(void) const
390  { return iso639_key_to_str3(CanonicalLanguageKey()); }
391 
392  QString toString() const override; // MPEGDescriptor
393 };
394 
397 {
398  public:
399  explicit AVCVideoDescriptor(const unsigned char *data, int len = 300) :
400  MPEGDescriptor(data, len, DescriptorID::avc_video) { }
401  // Name bits loc expected value
402  // descriptor_tag 8 0.0 0x
403  // descriptor_length 8 1.0
404  // profile_idc 8 2.0
405  uint ProfileIDC(void) const { return m_data[2]; }
406  // constraint_set0_flag 1 3.0
407  bool ConstaintSet0(void) const { return ( m_data[3]&0x80 ) != 0; }
408  // constraint_set1_flag 1 3.1
409  bool ConstaintSet1(void) const { return ( m_data[3]&0x40 ) != 0; }
410  // constraint_set2_flag 1 3.2
411  bool ConstaintSet2(void) const { return ( m_data[3]&0x20 ) != 0; }
412  // AVC_compatible_flags 5 3.3
413  uint AVCCompatible(void) const { return m_data[3]&0x1f; }
414  // level_idc 8 4.0
415  uint LevelIDC(void) const { return m_data[4]; }
416  // AVC_still_present 1 5.0
417  bool AVCStill(void) const { return ( m_data[5]&0x80 ) != 0; }
418  // AVC_24_hour_picture_flag 1 5.1
419  bool AVC24HourPicture(void) const { return ( m_data[5]&0x40 ) != 0; }
421  const { return ( m_data[5]&0x20 ) != 0; }
422  // reserved 6 bslbf
423  QString toString() const override; // MPEGDescriptor
424 };
425 
428 {
429  public:
430  explicit AVCTimingAndHRDDescriptor(const unsigned char *data, int len = 300) :
431  MPEGDescriptor(data, len, DescriptorID::avc_timing_and_hrd) { }
432  // Name bits loc expected value
433  // descriptor_tag 8 0.0 0x
434  // descriptor_length 8 1.0
435  // hrd_management_valid 1 2.0
436  bool HRDManagementValid(void) const { return ( m_data[2]&0x80 ) != 0; }
437  // reserved 6 2.1
438  // picture_and_timing_info_present 1 2.7
439  bool HasPictureAndTimingInfo(void) const { return m_data[2]&0x01;}
440  // if (picture_and_timing_info_present) {
441  // 90kHz_flag 1 3.0
442  // reserved 7 3.1
443  // if (90kHz_flag == '0') {
444  // N 32 4.0 uimsbf
445  // K 32 8.0 uimsbf
446  // }
447  // num_units_in_tick 32 (90khz)?4.0:12.0 uimsbf
448  // }
449  // fixed_frame_rate_flag 1 (pict_info)?((90khz)?8.0:16.0):3.0
450  // temporal_poc_flag 1 (pict_info)?((90khz)?8.1:16.1):3.1
451  // picture_to_display_conversion_flag 1 (pict_info)?((90khz)?8.2:16.2):3.2
452  // reserved 5 bslbf
453 };
454 
457 {
458  public:
459  explicit HEVCVideoDescriptor(const unsigned char *data, int len = 300) :
460  MPEGDescriptor(data, len, DescriptorID::avc_video) { }
461  // Name bits loc expected value
462  // descriptor_tag 8 0.0 0x38
463  // descriptor_length 8 1.0
464 
465  // the encoding of the following is specified in Rec. ITU-T H.265 | ISO/IEC 23008-2
466  // profile_space 2 2.0
467  uint ProfileSpace(void) const { return m_data[2]&0xC0 >> 6; }
468  // tier_flag 1 2.2
469  bool Tier(void) const { return ( m_data[2]&0x20 ) != 0; }
470  // profile_idc 5 2.3
471  uint ProfileIDC(void) const { return m_data[2] >> 3; }
472  // profile_compatibility_indication 32 3.0
473  // progressive_source_flag 1 7.0
474  // interlaced_source_flag 1 7.1
475  // non_packed_constraint_flag 1 7.2
476  // frame_only_constraint_flag 1 7.3
477  // reserved_zero_44bits 44 7.4
478  // level_idc 8 13.0
479 
480  // temporal_layer_subset_flag 1 14.0
481  // HEVC_still_present_flag 1 14.1
482  // HEVC_24hr_picture_present_flag 1 14.2
483  // reserved 5 14.3
484 
485  // if temporal_layer_subset_flag == true and
486  // descriptor_length == 17 instead of 15 then
487  // reserved 5 15.0
488  // temporal_id_min 3 15.5
489  // reserved 5 16.0
490  // temporal_id_max 3 16.5
491 
492  QString toString() const override; // MPEGDescriptor
493 };
494 
495 #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
static int iso639_str3_to_key(const unsigned char *iso639_2)
Definition: iso639.h:63
static bool description_map_initialized
int iso639_key_to_canonical_key(int iso639_2)
Definition: iso639.cpp:120
AVCTimingAndHRDDescriptor(const unsigned char *data, int len=300)
uint size(void) const
const unsigned char * CodeRaw() const
vector< const unsigned char * > desc_list_t
uint AVCCompatible(void) const
const unsigned char * m_data
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
unsigned int uint
Definition: compat.h:140
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
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