AJA NTV2 SDK  17.5.0.1242
NTV2 SDK 17.5.0.1242
ntv2tshelper.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
8 #ifndef NTV2TSHELPER_H
9 #define NTV2TSHELPER_H
10 
11 #include <stdint.h>
12 #include <map>
13 
14 #define KIPDPRINT 0
15 
16 #if defined(MSWindows)
17 
18  #if (KIPDPRINT==0)
19  // no log
20  #define kipdprintf(...)
21 
22  #elif (KIPDPRINT==1)
23  // printf
24  #include <stdio.h>
25  #define kipdprintf(...) printf(__VA_ARGS__)
26 
27  #endif
28 
29 #elif defined(AJALinux)
30 
31  #if (KIPDPRINT==0)
32  // no log
33  #define kipdprintf(...)
34 
35  #elif (KIPDPRINT==1)
36  // printf
37  #include <stdio.h>
38  #define kipdprintf(...) printf(__VA_ARGS__)
39 
40  #endif
41 
42 #elif defined(AJAMac)
43 
44  #if (KIPDPRINT==0)
45  // no log
46  #define kipdprintf(_format_...)
47 
48  #elif (KIPDPRINT==1)
49  // printf
50  #include <stdio.h>
51  #define kipdprintf(_format_...) printf(_format_)
52  #endif
53 
54 #elif defined(AJABareMetal)
55 
56  #if (KIPDPRINT==0)
57  // no log
58  #define kipdprintf(_format_...)
59 
60  #elif (KIPDPRINT==1)
61  // printf
62  #include <stdio.h>
63  #define kipdprintf(_format_...) printf(_format_)
64  #endif
65 
66 #endif
67 
68 
69 typedef enum
70 {
74 
75 typedef enum
76 {
81 
82 typedef enum
83 {
90 
91 typedef enum
92 {
96 } TsEncapType;
97 
98 typedef struct TsEncapStreamData
99 {
101  uint32_t width;
102  uint32_t height;
103  uint32_t denFrameRate;
104  uint32_t numFrameRate;
106  uint32_t programPid;
107  uint32_t videoPid;
108  uint32_t pcrPid;
109  uint32_t audio1Pid;
112 
113 
114 typedef struct TsVideoStreamData
115 {
117  uint32_t width;
118  uint32_t height;
119  uint32_t denFrameRate;
120  uint32_t numFrameRate;
124 
126 {
127  public:
128  // Input
129  uint16_t _tsId;
130  uint8_t _version;
131  uint32_t _tableLength;
133 
134  // Generated packet
135  uint8_t _pkt8[188];
136  uint32_t _pkt32[188];
137 
138  public:
140  {
141  init();
142  initPacket();
143  }
144 
146  {
147  }
148 
149  void init()
150  {
151  _tsId = 1;
152  _version = 1;
153  _tableLength = 0;
155  }
156 
157  void initPacket()
158  {
159  for ( int i = 0; i < 188; i++ )
160  {
161  _pkt8[i] = 0xff;
162  _pkt32[i] = 0xffff;
163  }
164  }
165 
166  uint32_t chksum_crc32(unsigned char *data, int len)
167  {
168  uint32_t crc_table[256] =
169  {
170  0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
171  0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
172  0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
173  0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
174  0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
175  0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
176  0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
177  0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
178  0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
179  0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
180  0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
181  0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
182  0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
183  0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
184  0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
185  0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
186  0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
187  0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
188  0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
189  0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
190  0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
191  0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
192  0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
193  0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
194  0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
195  0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
196  0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
197  0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
198  0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
199  0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
200  0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
201  0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
202  0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
203  0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
204  0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
205  0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
206  0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
207  0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
208  0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
209  0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
210  0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
211  0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
212  0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
213  };
214 
215  int32_t i;
216  uint32_t crc = 0xffffffff;
217 
218  for (i=0; i<len; i++)
219  crc = (crc << 8) ^ crc_table[((crc >> 24) ^ *data++) & 0xff];
220 
221  return crc;
222  }
223 
224  void dump8()
225  {
226  for (uint32_t i=0; i<_tableLength; i++)
227  {
228  if (i % 16 == 15) {
229  kipdprintf("0x%02x\n", _pkt8[i]);
230  } else {
231  kipdprintf("0x%02x, ", _pkt8[i]);
232  }
233  }
234  kipdprintf("\n\n");
235  }
236 
237  void dump32()
238  {
239  for (uint32_t i=0; i<_tableLength; i++)
240  {
241  if (i % 16 == 15) {
242  kipdprintf("0x%04x\n", _pkt32[i]);
243  } else {
244  kipdprintf("0x%04x ", _pkt32[i]);
245  }
246  }
247  kipdprintf("\n\n");
248  }
249 
250  protected:
251  void put16( uint16_t val, int &pos )
252  {
253  _pkt8[pos++] = (uint8_t)(val>>8);
254  _pkt8[pos++] = (uint8_t)val;
255  }
256 
257  void put32( uint32_t val, int &pos )
258  {
259  _pkt8[pos++] = (uint8_t)(val>>24);
260  _pkt8[pos++] = (uint8_t)(val>>16);
261  _pkt8[pos++] = (uint8_t)(val>>8);
262  _pkt8[pos++] = (uint8_t)val;
263  }
264 };
265 
266 class PESGen : public TSGenerator
267 {
268 public:
270  std::map <uint16_t, uint16_t> _elemNumToPID;
271  uint64_t _pts; // these can be passed in and will be initialized to reaonsable values
272  int32_t _auf1;
273  int32_t _auf2;
274  uint32_t _bitRate;
275  int32_t _ptsOffset; // theses values are filled in by the generator
276  int32_t _j2kTsOffset;
277  int32_t _auf1Offset;
278  int32_t _auf2Offset;
279  int32_t _hh;
280  int32_t _mm;
281  int32_t _ss;
282  int32_t _ff;
283 
284 
285 public:
287  {
288  initLocal();
289  }
290 
292  {
293  }
294 
295  void initLocal()
296  {
297  _elemNumToPID.clear();
298  _pts = 0;
299  _auf1 = 0;
300  _auf2 = 0;
301  _bitRate = 75000000;
302  _hh = 0;
303  _mm = 0;
304  _ss = 0;
305  _ff = 0;
306  }
307 
309  {
310  initPacket();
311  int pos = 0;
312  _ptsOffset = 0xff; // For non-elsm streams these are all 0xff
313  _j2kTsOffset = 0xff; // for standard streams they will be filled in accordingly
314  _auf1Offset = 0xff;
315  _auf2Offset = 0xff;
316 
317  // Header
318  _pkt8[pos++] = 0x47; // sync byte
319  _pkt8[pos] = 1<<6; // payload unit start indicator
320  _pkt8[pos++] |= (uint8_t) ((_elemNumToPID[1] >> 8) & 0x1f); // PID for Video
321  _pkt8[pos++] = (uint8_t) (_elemNumToPID[1] & 0xff); // PID for Video
322  _pkt8[pos++] = 0x10; // Continuity Counter must increment when transmitted
323 
324  // generate PES data for AES streams
326  {
327  _pkt8[pos++] = 0; // packet_start_code_prefix
328  _pkt8[pos++] = 0;
329  _pkt8[pos++] = (uint8_t) (1 & 0xff);
330  _pkt8[pos++] = (uint8_t) (0xbd);
331 
332  _pkt8[pos++] = 0; // (packet_length >> 8) & 0xff
333  _pkt8[pos++] = 0; // packet_length & 0xff
334  _pkt8[pos++] = 0x80; // alignment
335  _pkt8[pos++] = 0x80; // 11
336  _pkt8[pos++] = 5; // 12
337 
338  _ptsOffset = pos;
339 
340  _pkt8[pos] = 0x21; // 13
341  _pkt8[pos++] |= (uint8_t) ((_pts >> 29) & 0xe);
342  _pkt8[pos] = 0x0; // 14
343  _pkt8[pos++] |= (uint8_t) ((_pts >> 22) & 0xff);
344  _pkt8[pos] = 0x1; // 15
345  _pkt8[pos++] |= (uint8_t) ((_pts >> 14) & 0xfe);
346  _pkt8[pos] = 0x0; // 16
347  _pkt8[pos++] |= (uint8_t) ((_pts >> 7) & 0xff);
348  _pkt8[pos] = 0x1; // 17
349  _pkt8[pos++] |= (uint8_t) ((_pts << 1) & 0xfe);
350 
351  _pkt8[pos++] = 0x0; // 18
352  _pkt8[pos++] = 0x0;
353 
354  // These two bytes are defined in Table 1 of ST302 spec starting with num channels
356  {
357  _pkt8[pos++] = 0x0; // 2 channels, 6 bits of channel ID
358  _pkt8[pos++] = 0x10; // two bits of channel ID, 20 bits per sample, alignment 0 reserved
359  }
360  else
361  {
362  _pkt8[pos++] = 0x0; // 2 channels, 6 bits of channel ID
363  _pkt8[pos++] = 0x20; // two bits of channel ID, 24 bits per sample, alignment 0 reserved
364  }
365 
366  _auf1Offset = 0x1000012;
367  _auf2Offset = 0x1000c08;
368 
369  }
370  else
371  {
372  // generate PES data for standard streams, for non-elsm just do the header
374  {
375  _pkt8[pos++] = 0; // packet_start_code_prefix
376  _pkt8[pos++] = 0;
377  _pkt8[pos++] = (uint8_t) (1 & 0xff);
378  _pkt8[pos++] = (uint8_t) (0xbd);
379 
380  _pkt8[pos++] = 0; // (packet_length >> 8) & 0xff
381  _pkt8[pos++] = 0; // packet_length & 0xff
382  _pkt8[pos++] = 0x84; // alignment
383  _pkt8[pos++] = 0x80; // 11
384  _pkt8[pos++] = 5; // 12
385 
386  _ptsOffset = pos;
387 
388  _pkt8[pos] = 0x21; // 13
389  _pkt8[pos++] |= (uint8_t) ((_pts >> 29) & 0xe);
390  _pkt8[pos] = 0x0; // 14
391  _pkt8[pos++] |= (uint8_t) ((_pts >> 22) & 0xff);
392  _pkt8[pos] = 0x1; // 15
393  _pkt8[pos++] |= (uint8_t) ((_pts >> 14) & 0xfe);
394  _pkt8[pos] = 0x0; // 16
395  _pkt8[pos++] |= (uint8_t) ((_pts >> 7) & 0xff);
396  _pkt8[pos] = 0x1; // 17
397  _pkt8[pos++] |= (uint8_t) ((_pts << 1) & 0xfe);
398 
399  _pkt8[pos++] = 0x65; // "e"
400  _pkt8[pos++] = 0x6c; // "l"
401  _pkt8[pos++] = 0x73; // "s"
402  _pkt8[pos++] = 0x6D; // "m"
403 
404  _pkt8[pos++] = 0x66; // "f"
405  _pkt8[pos++] = 0x72; // "r"
406  _pkt8[pos++] = 0x61; // "a"
407  _pkt8[pos++] = 0x74; // "t"
408 
409  _pkt8[pos++] = (uint8_t) ((_videoStreamData.denFrameRate >> 8) & 0xff);
410  _pkt8[pos++] = (uint8_t) (_videoStreamData.denFrameRate & 0xff);
411  _pkt8[pos++] = (uint8_t) ((_videoStreamData.numFrameRate >> 8) & 0xff);
412  _pkt8[pos++] = (uint8_t) (_videoStreamData.numFrameRate & 0xff);
413 
414  _pkt8[pos++] = 0x62; // "b"
415  _pkt8[pos++] = 0x72; // "r"
416  _pkt8[pos++] = 0x61; // "a"
417  _pkt8[pos++] = 0x74; // "t"
418 
419  _pkt8[pos++] = (uint8_t) (_bitRate >> 24); // 34
420  _pkt8[pos++] = (uint8_t) ((_bitRate >> 16) & 0xff);
421  _pkt8[pos++] = (uint8_t) ((_bitRate >> 8) & 0xff);
422  _pkt8[pos++] = (uint8_t) (_bitRate & 0xff);
423 
424  _auf1Offset = pos;
425 
426  _pkt8[pos++] = (uint8_t) (_auf1 >> 24); // 38
427  _pkt8[pos++] = (uint8_t) ((_auf1 >> 16) & 0xff);
428  _pkt8[pos++] = (uint8_t) ((_auf1 >> 8) & 0xff);
429  _pkt8[pos++] = (uint8_t) (_auf1 & 0xff);
430 
432  {
433  _auf2Offset = pos;
434 
435  _pkt8[pos++] = (uint8_t) (_auf2 >> 24); // 42
436  _pkt8[pos++] = (uint8_t) ((_auf2 >> 16) & 0xff);
437  _pkt8[pos++] = (uint8_t) ((_auf2 >> 8) & 0xff);
438  _pkt8[pos++] = (uint8_t) (_auf2 & 0xff);
439 
440  _pkt8[pos++] = 0x66; // "f"
441  _pkt8[pos++] = 0x69; // "i"
442  _pkt8[pos++] = 0x65; // "e"
443  _pkt8[pos++] = 0x6c; // "l"
444 
445  _pkt8[pos++] = (uint8_t) (2 & 0xff);
446  _pkt8[pos++] = (uint8_t) (1 & 0xff);
447 
448  _pkt8[pos++] = 0x74; // "t"
449  _pkt8[pos++] = 0x63; // "c"
450  _pkt8[pos++] = 0x6f; // "o"
451  _pkt8[pos++] = 0x64; // "d"
452 
453  _j2kTsOffset = pos;
454  _pkt8[pos++] = (uint8_t) (_hh & 0xff);
455  _pkt8[pos++] = (uint8_t) (_mm & 0xff);
456  _pkt8[pos++] = (uint8_t) (_ss & 0xff);
457  _pkt8[pos++] = (uint8_t) (_ff & 0xff);
458 
459  _pkt8[pos++] = 0x62; // "b"
460  _pkt8[pos++] = 0x63; // "c"
461  _pkt8[pos++] = 0x6f; // "o"
462  _pkt8[pos++] = 0x6c; // "l"
463 
464  _pkt8[pos++] = 3;
465  _pkt8[pos++] = 0x0;
466  }
467  else
468  {
469  _pkt8[pos++] = 0x74; // "t"
470  _pkt8[pos++] = 0x63; // "c"
471  _pkt8[pos++] = 0x6f; // "o"
472  _pkt8[pos++] = 0x64; // "d"
473 
474  _j2kTsOffset = pos;
475  _pkt8[pos++] = (uint8_t) (0 & 0xff); // hh
476  _pkt8[pos++] = (uint8_t) (0 & 0xff); // mm
477  _pkt8[pos++] = (uint8_t) (0 & 0xff); // ss
478  _pkt8[pos++] = (uint8_t) (0 & 0xff); // ff
479 
480  _pkt8[pos++] = 0x62; // "b"
481  _pkt8[pos++] = 0x63; // "c"
482  _pkt8[pos++] = 0x6f; // "o"
483  _pkt8[pos++] = 0x6c; // "l"
484 
485  _pkt8[pos++] = 3;
486  _pkt8[pos++] = 0xff;
487  }
488  }
489  }
490 
491  _tableLength = pos;
492  return pos;
493  }
494 
496  {
497  double d1, d2;
498 
499  // Next PAT / PMT Transmission Rate
500  d2 = 1.0 / 125000000; // Clock Period
501  d1 = 90e-3 / d2 - 1.0;
502  return (int32_t) d1;
503  }
504 };
505 
506 class PATGen : public TSGenerator
507 {
508  public:
509  // Input
510  std::map <uint16_t, uint16_t> _progNumToPID;
511 
512  public:
514  {
515  initLocal();
516  }
517 
519  {
520  }
521 
522  void initLocal()
523  {
524  _progNumToPID.clear();
525  }
526 
528  {
529  initPacket();
530  int pos = 0;
531 
532  // Header
533  _pkt8[pos++] = 0x47; // sync byte
534  _pkt8[pos++] = 1<<6; // payload unit start indicator
535  _pkt8[pos++] = 0; // PID for PAT = 0
536  _pkt8[pos++] = 0x10; // Continuity Counter must increment when transmitted
537  _pkt8[pos++] = 0; // pointer
538 
539  int crcStart = pos;
540 
541  _pkt8[pos++] = 0; // table id = 0
542 
543  int length = 9 + (4 * (int)_progNumToPID.size());
544  put16( (uint16_t)0xb000 + (length & 0x3ff), pos); // syntax indicator, reserved, length
545  put16( _tsId, pos );
546 
547  _pkt8[pos++] = 0xc1 + ((_version & 0x1f)<< 1); // version, current/next
548  put16( 0, pos ); // section number = last section number = 0
549 
550  std::map <uint16_t, uint16_t>::const_iterator it = _progNumToPID.begin();
551  while (it != _progNumToPID.end())
552  {
553  put16( it->first, pos );
554  put16( (uint16_t)0xe000 + (it->second & 0x1fff), pos );
555  it++;
556  }
557  int crcEnd = pos - 1;
558 
559  int crc = chksum_crc32(_pkt8 + crcStart, crcEnd - crcStart + 1 );
560  put32( crc, pos );
561 
562  _tableLength = pos;
563  return pos;
564  }
565 };
566 
567 class PMTGen : public TSGenerator
568 {
569  public:
571  std::map <uint16_t, uint16_t> _progNumToPID;
572  std::map <uint16_t, uint16_t> _pcrNumToPID;
573  std::map <uint16_t, uint16_t> _videoNumToPID;
574  std::map <uint16_t, uint16_t> _audioNumToPID;
575 
576  public:
578  {
579  initLocal();
580  }
581 
583  {
584  }
585 
586  void initLocal()
587  {
588  _progNumToPID.clear();
589  _pcrNumToPID.clear();
590  _videoNumToPID.clear();
591  _audioNumToPID.clear();
592  }
593 
595  {
596  initPacket();
597  int pos = 0;
598  int len, lengthPos, j2kLengthPos, audioLengthPos;
599 
600  // Header
601  _pkt8[pos++] = 0x47; // sync byte
602  _pkt8[pos] = 1<<6; // payload unit start indicator
603  _pkt8[pos++] |= (uint8_t) ((_progNumToPID[1] >> 8) & 0x1f); // PID for PMT
604  _pkt8[pos++] = (uint8_t) (_progNumToPID[1] & 0xff); // PID for PMT
605  _pkt8[pos++] = 0x10; // Continuity Counter must increment when transmitted
606  _pkt8[pos++] = 0; // pointer
607 
608  int crcStart = pos;
609 
610  _pkt8[pos++] = 2; // table id = 0
611  lengthPos = pos; // need to come back and fill in length so save position (assume < 256)
612  _pkt8[pos++] = 0xb0;
613  pos++;
614 
615  put16(0x01, pos); // program number
616 
617  _pkt8[pos++] = 0xc1 + ((_version & 0x1f)<< 1); // version, current/next
618  put16( 0, pos ); // section number = last section number = 0
619 
620  _pkt8[pos] = 0xe0; // PCR pid and reserved bits
621  _pkt8[pos++] |= (uint8_t) ((_pcrNumToPID[1] >> 8) & 0x1f);
622  _pkt8[pos++] = (uint8_t) (_pcrNumToPID[1] & 0xff);
623 
624  _pkt8[pos++] = 0xf0; // reserved bits and program info length
625  _pkt8[pos++] = 0x00; // reserved bits and program info length
626 
627  // Do the streams
628 
629  if (_videoNumToPID[1] != 0)
630  {
631  // J2K
632  _pkt8[pos++] = 0x21; // J2K Type
633  _pkt8[pos] = 0xe0; // elementary pid and reserved bits
634  _pkt8[pos++] |= (uint8_t) ((_videoNumToPID[1] >> 8) & 0x1f);
635  _pkt8[pos++] = (uint8_t) (_videoNumToPID[1] & 0xff);
636 
637  j2kLengthPos = pos; // need to come back and fill in descriptor length so save position
638  pos+=2;
639 
640  len = makeJ2kDescriptor(pos); // generate the J2K descriptor
641 
642  _pkt8[j2kLengthPos] = 0xf0; // fill in the length and reserved bits now
643  _pkt8[j2kLengthPos++] |= (uint8_t) ((len >> 8) & 0x1f);
644  _pkt8[j2kLengthPos] = (uint8_t) (len & 0xff);
645  }
646 
647  if ((_audioNumToPID[1] != 0) && (_videoStreamData.numAudioChannels != 0))
648  {
649  // Audio
650  _pkt8[pos++] = 0x06; // Audio Type
651  _pkt8[pos] = 0xe0; // audio pid and reserved bits
652  _pkt8[pos++] |= (uint8_t) ((_audioNumToPID[1] >> 8) & 0x1f);
653  _pkt8[pos++] = (uint8_t) (_audioNumToPID[1] & 0xff);
654 
655  audioLengthPos = pos; // need to come back and fill in descriptor length so save position
656  pos+=2;
657 
658  len = makeAudioDescriptor(pos); // generate the audio descriptor
659 
660  _pkt8[audioLengthPos] = 0xf0; // fill in the length and reserved bits now
661  _pkt8[audioLengthPos++] |= (uint8_t) ((len >> 8) & 0x1f);
662  _pkt8[audioLengthPos] = (uint8_t) (len & 0xff);
663  }
664 
665  // now we know the length so fill that in
666  _pkt8[lengthPos] = 0xb0;
667  _pkt8[lengthPos++] |= (uint8_t) (((pos-crcStart+1) >> 8) & 0x1f);
668  _pkt8[lengthPos] = (uint8_t) ((pos-crcStart+1) & 0xff);
669 
670  int crcEnd = pos - 1;
671 
672  int crc = chksum_crc32(_pkt8 + crcStart, crcEnd - crcStart + 1 );
673  put32( crc, pos );
674 
675  _tableLength = pos;
676  return pos;
677  }
678 
679  int makeJ2kDescriptor(int &pos)
680  {
681  int startPos = pos;
682  uint32_t profileLevel;
683  uint32_t maxBitRate;
684  uint32_t height;
685 
687  {
688  profileLevel = 0x102;
689  maxBitRate = 160000000;
690  }
691  else
692  {
693  profileLevel = 0x101;
694  maxBitRate = 213000000;
695  }
696 
698  else height = _videoStreamData.height;
699 
700  // Header
701  _pkt8[pos++] = 0x32; // descriptor tag
702  _pkt8[pos++] = 24; // descriptor length
703  put16( profileLevel, pos ); // profile level
704 
706  {
707  // Standard stream
708  put32( _videoStreamData.width, pos ); // width
709  put32( height, pos ); // height
710  put32( maxBitRate, pos ); // max bit rate
711  put32( 1250000, pos ); // max buffer size (constant for now)
712  put16( _videoStreamData.denFrameRate, pos ); // frame rate
714  _pkt8[pos++] = 3; // color spec
715  _pkt8[pos] = _videoStreamData.interlaced <<6; // interlaced and still mode
716  _pkt8[pos++] |= 0x3F; // reserved bits all 1's for standard streams
717  }
718  else
719  {
720  // Non-elsm stream
721  put16( 0x0100, pos );
722  put16( _videoStreamData.width, pos ); // width
723  put16( height, pos ); // height
725  put16( height, pos ); // height again for interlaced
726  else
727  put16( 0, pos ); // otherwise nothing
728  put32( maxBitRate, pos ); // max bit rate (constant for now)
729  _pkt8[pos++] = 0;
730  _pkt8[pos++] = 0;
731  _pkt8[pos++] = 0x05;
732  _pkt8[pos++] = 0x33;
733  put16( _videoStreamData.denFrameRate, pos ); // frame rate
735  _pkt8[pos++] = 0;
736  _pkt8[pos++] = 0;
737  }
738 
739  return pos-startPos;
740  }
741 
742  int makeAudioDescriptor(int &pos)
743  {
744  int startPos = pos;
745  // Header
746  _pkt8[pos++] = 0x0a; // descriptor tag
747  _pkt8[pos++] = 4; // descriptor length
748  _pkt8[pos++] = 0x45; // "E"
749  _pkt8[pos++] = 0x4e; // "N"
750  _pkt8[pos++] = 0x47; // "G"
751  _pkt8[pos++] = 0;
752 
753  _pkt8[pos++] = 0x05; // descriptor tag
755  _pkt8[pos++] = 6; // length non-elsm
756  else
757  _pkt8[pos++] = 4; // length standard stream (omitted ST302 channel spec)
758 
759  _pkt8[pos++] = 0x42; // "B"
760  _pkt8[pos++] = 0x53; // "S"
761  _pkt8[pos++] = 0x53; // "S"
762  _pkt8[pos++] = 0x44; // "D"
763 
764  // These two bytes are defined in Table 1 of ST302 spec starting with num channels, we dont add these for standard streams
766  {
767  _pkt8[pos++] = (_videoStreamData.numAudioChannels/2) - 1; // number of audio pairs (0 is 1 pair of audio), 6 bits of channel ID
768  _pkt8[pos++] = 0x20; // two bits of channel ID, 24 bits per sample, alignment 0 reserved
769  }
770 
771  return pos-startPos;
772  }
773 };
774 
775 class ADPGen : public TSGenerator
776 {
777 public:
778  std::map <uint16_t, uint16_t> _elemNumToPID;
779 
780 public:
782  {
783  initLocal();
784  }
785 
787  {
788  }
789 
790  void initLocal()
791  {
792  _elemNumToPID.clear();
793  }
794 
796  {
797  initPacket();
798  int pos = 0;
799 
800  // Header
801  _pkt32[pos++] = 0x47; // sync byte
802  _pkt32[pos++] = ((_elemNumToPID[1] >> 8) & 0x1f); // PID for stream
803  _pkt32[pos++] = (_elemNumToPID[1] & 0xff);
804 
806  {
807  _pkt32[pos++] = (2 << 4); // Continuity Counter must increment when transmitted
808  _pkt32[pos++] = 0; // pointer
809  _pkt32[pos++] = 0x10; // pointer
810 
811  _pkt32[pos++] = 0x800; // PCR
812  _pkt32[pos++] = 0x900;
813  _pkt32[pos++] = 0xa00;
814  _pkt32[pos++] = 0xb00;
815  _pkt32[pos++] = 0xc00;
816  _pkt32[pos++] = 0xd00;
817  }
818  else
819  {
820  _pkt32[pos++] = (3 << 4); // Continuity Counter must increment when transmitted
821  _pkt32[pos++] = 0; // pointer
822  _pkt32[pos++] = 0; // pointer
823  }
824 
825  _tableLength = pos;
826  return pos;
827  }
828 };
829 
830 #endif
kTsEncapTypeAes
@ kTsEncapTypeAes
Definition: ntv2tshelper.h:95
kJ2KChromaSubSamp_444
@ kJ2KChromaSubSamp_444
Definition: ntv2tshelper.h:77
kJ2KChromaSubSamp_422_Standard
@ kJ2KChromaSubSamp_422_Standard
Definition: ntv2tshelper.h:79
kJ2KStreamTypeStandard
@ kJ2KStreamTypeStandard
Definition: ntv2tshelper.h:71
TsEncapType
TsEncapType
Definition: ntv2tshelper.h:91
PESGen::_ptsOffset
int32_t _ptsOffset
Definition: ntv2tshelper.h:275
TSGenerator::_tableLength
uint32_t _tableLength
Definition: ntv2tshelper.h:131
kJ2KCodeBlocksize_32x64
@ kJ2KCodeBlocksize_32x64
Definition: ntv2tshelper.h:85
PMTGen::_videoStreamData
TsVideoStreamData _videoStreamData
Definition: ntv2tshelper.h:570
PESGen
Definition: ntv2tshelper.h:266
TSGenerator::put16
void put16(uint16_t val, int &pos)
Definition: ntv2tshelper.h:251
PESGen::calcPatPmtPeriod
int32_t calcPatPmtPeriod()
Definition: ntv2tshelper.h:495
J2KChromaSubSampling
J2KChromaSubSampling
Definition: ntv2tshelper.h:75
ADPGen::ADPGen
ADPGen()
Definition: ntv2tshelper.h:781
PESGen::_pts
uint64_t _pts
Definition: ntv2tshelper.h:271
PESGen::_ss
int32_t _ss
Definition: ntv2tshelper.h:281
PESGen::_auf2
int32_t _auf2
Definition: ntv2tshelper.h:273
TsEncapStreamData::width
uint32_t width
Definition: ntv2tshelper.h:101
PATGen::~PATGen
~PATGen()
Definition: ntv2tshelper.h:518
PESGen::_j2kTsOffset
int32_t _j2kTsOffset
Definition: ntv2tshelper.h:276
PESGen::_elemNumToPID
std::map< uint16_t, uint16_t > _elemNumToPID
Definition: ntv2tshelper.h:270
TSGenerator::initPacket
void initPacket()
Definition: ntv2tshelper.h:157
TsEncapStreamData::numFrameRate
uint32_t numFrameRate
Definition: ntv2tshelper.h:104
TSGenerator::chksum_crc32
uint32_t chksum_crc32(unsigned char *data, int len)
Definition: ntv2tshelper.h:166
PESGen::_auf1
int32_t _auf1
Definition: ntv2tshelper.h:272
PMTGen::makeAudioDescriptor
int makeAudioDescriptor(int &pos)
Definition: ntv2tshelper.h:742
TsEncapStreamData
struct TsEncapStreamData TsEncapStreamData
TsEncapStreamData::audio1Pid
uint32_t audio1Pid
Definition: ntv2tshelper.h:109
PATGen::makePacket
int makePacket()
Definition: ntv2tshelper.h:527
PESGen::_bitRate
uint32_t _bitRate
Definition: ntv2tshelper.h:274
kJ2KStreamTypeNonElsm
@ kJ2KStreamTypeNonElsm
Definition: ntv2tshelper.h:72
TsVideoStreamData::width
uint32_t width
Definition: ntv2tshelper.h:117
PESGen::makePacket
int makePacket()
Definition: ntv2tshelper.h:308
kJ2KCodeBlocksize_64x64
@ kJ2KCodeBlocksize_64x64
Definition: ntv2tshelper.h:87
TSGenerator
Definition: ntv2tshelper.h:125
PESGen::_ff
int32_t _ff
Definition: ntv2tshelper.h:282
TsVideoStreamData::denFrameRate
uint32_t denFrameRate
Definition: ntv2tshelper.h:119
kipdprintf
#define kipdprintf(_format_...)
Definition: ntv2tshelper.h:46
TsEncapStreamData::pcrPid
uint32_t pcrPid
Definition: ntv2tshelper.h:108
PMTGen::_progNumToPID
std::map< uint16_t, uint16_t > _progNumToPID
Definition: ntv2tshelper.h:571
TsEncapStreamData::height
uint32_t height
Definition: ntv2tshelper.h:102
PMTGen::initLocal
void initLocal()
Definition: ntv2tshelper.h:586
kTsEncapTypePcr
@ kTsEncapTypePcr
Definition: ntv2tshelper.h:94
PATGen::_progNumToPID
std::map< uint16_t, uint16_t > _progNumToPID
Definition: ntv2tshelper.h:510
PESGen::_auf1Offset
int32_t _auf1Offset
Definition: ntv2tshelper.h:277
TsVideoStreamData::numAudioChannels
uint32_t numAudioChannels
Definition: ntv2tshelper.h:121
kJ2KCodeBlocksize_64x32
@ kJ2KCodeBlocksize_64x32
Definition: ntv2tshelper.h:86
kJ2KChromaSubSamp_422_444
@ kJ2KChromaSubSamp_422_444
Definition: ntv2tshelper.h:78
ADPGen::makePacket
int makePacket()
Definition: ntv2tshelper.h:795
TsVideoStreamData
struct TsVideoStreamData TsVideoStreamData
TsEncapStreamData
Definition: ntv2tshelper.h:98
TsVideoStreamData::height
uint32_t height
Definition: ntv2tshelper.h:118
PESGen::initLocal
void initLocal()
Definition: ntv2tshelper.h:295
TsEncapStreamData::videoPid
uint32_t videoPid
Definition: ntv2tshelper.h:107
TsVideoStreamData::numFrameRate
uint32_t numFrameRate
Definition: ntv2tshelper.h:120
TSGenerator::dump32
void dump32()
Definition: ntv2tshelper.h:237
TsEncapStreamData::j2kStreamType
J2KStreamType j2kStreamType
Definition: ntv2tshelper.h:100
PMTGen::_videoNumToPID
std::map< uint16_t, uint16_t > _videoNumToPID
Definition: ntv2tshelper.h:573
TsVideoStreamData::j2kStreamType
J2KStreamType j2kStreamType
Definition: ntv2tshelper.h:116
TSGenerator::_tsEncapType
TsEncapType _tsEncapType
Definition: ntv2tshelper.h:132
PMTGen::PMTGen
PMTGen()
Definition: ntv2tshelper.h:577
TSGenerator::_pkt32
uint32_t _pkt32[188]
Definition: ntv2tshelper.h:136
PMTGen::makeJ2kDescriptor
int makeJ2kDescriptor(int &pos)
Definition: ntv2tshelper.h:679
PMTGen::_audioNumToPID
std::map< uint16_t, uint16_t > _audioNumToPID
Definition: ntv2tshelper.h:574
PESGen::~PESGen
~PESGen()
Definition: ntv2tshelper.h:291
TsEncapStreamData::interlaced
bool interlaced
Definition: ntv2tshelper.h:110
ADPGen
Definition: ntv2tshelper.h:775
J2KStreamType
J2KStreamType
Definition: ntv2tshelper.h:69
PESGen::_auf2Offset
int32_t _auf2Offset
Definition: ntv2tshelper.h:278
kTsEncapTypeJ2k
@ kTsEncapTypeJ2k
Definition: ntv2tshelper.h:93
PMTGen::_pcrNumToPID
std::map< uint16_t, uint16_t > _pcrNumToPID
Definition: ntv2tshelper.h:572
PATGen::initLocal
void initLocal()
Definition: ntv2tshelper.h:522
TSGenerator::_version
uint8_t _version
Definition: ntv2tshelper.h:130
TsVideoStreamData::interlaced
bool interlaced
Definition: ntv2tshelper.h:122
ADPGen::_elemNumToPID
std::map< uint16_t, uint16_t > _elemNumToPID
Definition: ntv2tshelper.h:778
J2KCodeBlocksize
J2KCodeBlocksize
Definition: ntv2tshelper.h:82
PESGen::_mm
int32_t _mm
Definition: ntv2tshelper.h:280
PMTGen::~PMTGen
~PMTGen()
Definition: ntv2tshelper.h:582
TSGenerator::init
void init()
Definition: ntv2tshelper.h:149
TsVideoStreamData
Definition: ntv2tshelper.h:114
TsEncapStreamData::denFrameRate
uint32_t denFrameRate
Definition: ntv2tshelper.h:103
TsEncapStreamData::numAudioChannels
uint32_t numAudioChannels
Definition: ntv2tshelper.h:105
TSGenerator::dump8
void dump8()
Definition: ntv2tshelper.h:224
PMTGen
Definition: ntv2tshelper.h:567
PESGen::_videoStreamData
TsVideoStreamData _videoStreamData
Definition: ntv2tshelper.h:269
kJ2KCodeBlocksize_128x32
@ kJ2KCodeBlocksize_128x32
Definition: ntv2tshelper.h:88
TSGenerator::_pkt8
uint8_t _pkt8[188]
Definition: ntv2tshelper.h:135
PESGen::_hh
int32_t _hh
Definition: ntv2tshelper.h:279
PATGen
Definition: ntv2tshelper.h:506
TSGenerator::put32
void put32(uint32_t val, int &pos)
Definition: ntv2tshelper.h:257
PATGen::PATGen
PATGen()
Definition: ntv2tshelper.h:513
ADPGen::~ADPGen
~ADPGen()
Definition: ntv2tshelper.h:786
TSGenerator::TSGenerator
TSGenerator()
Definition: ntv2tshelper.h:139
TSGenerator::_tsId
uint16_t _tsId
Definition: ntv2tshelper.h:129
PESGen::PESGen
PESGen()
Definition: ntv2tshelper.h:286
TSGenerator::~TSGenerator
~TSGenerator()
Definition: ntv2tshelper.h:145
TsEncapStreamData::programPid
uint32_t programPid
Definition: ntv2tshelper.h:106
kJ2KCodeBlocksize_32x32
@ kJ2KCodeBlocksize_32x32
Definition: ntv2tshelper.h:84
PMTGen::makePacket
int makePacket()
Definition: ntv2tshelper.h:594
ADPGen::initLocal
void initLocal()
Definition: ntv2tshelper.h:790