MythTV  master
ts.cpp
Go to the documentation of this file.
1 /*
2  * ts.c: MPEG TS functions for replex
3  *
4  *
5  * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
6  * Metzler Brothers Systementwicklung GbR
7  * Changes to use MythTV logging
8  * Copyright (C) 2011 Gavin Hurlbut <ghurlbut@mythtv.org>
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * General Public License for more details.
20  *
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
26  *
27  */
28 
29 #include <array>
30 #include <cstdint>
31 #include <cstdio>
32 #include <cstdlib>
33 #include <cstring>
34 
35 #ifdef _WIN32
36 #include <winsock2.h>
37 #else
38 #include <netinet/in.h>
39 #endif
40 
41 #include "ts.h"
42 #include "element.h"
43 #include "pes.h"
44 
46 
47 uint16_t get_pid(const uint8_t *pid)
48 {
49  uint16_t pp = 0;
50 
51  pp = (pid[0] & PID_MASK_HI)<<8;
52  pp |= pid[1];
53 
54  return pp;
55 }
56 
57 int find_pids_pos(uint16_t *vpid, uint16_t *apid, uint16_t *ac3pid,uint8_t *buf, int len, int *vpos, int *apos, int *ac3pos)
58 {
59  int c=0;
60  int found=0;
61 
62  if (!vpid || !apid || !ac3pid || !buf || !len) return 0;
63 
64  *vpid = 0;
65  *apid = 0;
66  *ac3pid = 0;
67 
68  while ( c+TS_SIZE < len){
69  if (buf[c] == buf[c+TS_SIZE]) break;
70  c++;
71  }
72 
73  while(found<2 && c < len){
74  if (buf[c+1] & PAY_START) {
75  int off = 4;
76 
77  if ( buf[c+3] & ADAPT_FIELD) { // adaptation field?
78  off += buf[c+4] + 1;
79  }
80 
81  if (off < TS_SIZE-4){
82  if (!*vpid && (buf[c+off+3] & 0xF0) == 0xE0){
83  *vpid = get_pid(buf+c+1);
84  if (vpos) *vpos = c+off+3;
85  found++;
86  }
87  if (!*ac3pid && buf[c+off+3] == 0xBD){
88  int l=off+4;
89  int f=0;
90 
91  while ( l < TS_SIZE && f<2){
92  uint8_t b=buf[c+l];
93  switch(f){
94  case 0:
95  if ( b == 0x0b)
96  f = 1;
97  break;
98 
99  case 1:
100  if ( b == 0x77)
101  f = 2;
102  else if ( b != 0x0b)
103  f = 0;
104  }
105  l++;
106  }
107  if (f==2){
108  *ac3pid = get_pid(buf+c+1);
109  if (ac3pos) *ac3pos = c+off+3;
110  found++;
111  }
112  }
113  if (!*apid && ((buf[c+off+3] & 0xF0) == 0xC0 ||
114  (buf[c+off+3] & 0xF0) == 0xD0)){
115  *apid = get_pid(buf+c+1);
116  if (apos) *apos = c+off+3;
117  found++;
118  }
119  }
120  }
121  c+= TS_SIZE;
122  }
123  return found;
124 }
125 
126 
127 int find_pids(uint16_t *vpid, uint16_t *apid, uint16_t *ac3pid,uint8_t *buf, int len)
128 {
129  return find_pids_pos(vpid, apid, ac3pid, buf, len, nullptr, nullptr, nullptr);
130 }
131 
132 //taken and adapted from libdtv, (c) Rolf Hakenes
133 // CRC32 lookup table for polynomial 0x04c11db7
134 static const std::array <const uint32_t,256> crc_table {
135  0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
136  0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
137  0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
138  0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
139  0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
140  0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
141  0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
142  0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
143  0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
144  0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
145  0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
146  0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
147  0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
148  0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
149  0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
150  0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
151  0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
152  0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
153  0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
154  0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
155  0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
156  0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
157  0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
158  0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
159  0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
160  0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
161  0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
162  0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
163  0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
164  0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
165  0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
166  0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
167  0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
168  0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
169  0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
170  0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
171  0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
172  0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
173  0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
174  0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
175  0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
176  0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
177  0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4};
178 
179 static unsigned int crc32_04c11db7 (const unsigned char *d, int len, unsigned int crc)
180 {
181  const unsigned char *u = d; // Saves '& 0xff'
182 
183  for (int i=0; i<len; i++)
184  crc = (crc << 8) ^ crc_table[((crc >> 24) ^ *u++)];
185 
186  return crc;
187 }
188 
189 static int write_ts_header(uint16_t pid, int payload_start, int count,
190  int64_t SCR, uint8_t *obuf, int stuff)
191 {
192  int c = 0;
193 
194  obuf[c++] = 0x47;
195  obuf[c++] = (payload_start ? 0x40 : 0x00) | ((pid >> 8) & 0x1f);
196  obuf[c++] = pid & 0xff;
197  obuf[c++] = ((SCR >= 0 || stuff) ? 0x30 : 0x10) | count;
198  if (SCR >= 0|| stuff) {
199  if (stuff)
200  stuff--;
201  int size = stuff;
202  unsigned char flags = 0;
203  if(SCR >= 0) {
204  if(size < 7)
205  size = 7;
206  flags |= 0x10;
207  }
208  obuf[c++] = size;
209  if(size) {
210  obuf[c++] = flags;
211  size--;
212  }
213  if(SCR >= 0) {
214  auto lscr = (uint32_t) ((SCR/300ULL) & 0xFFFFFFFFULL);
215  uint8_t bit = (lscr & 0x01) << 7;
216  lscr = htonl(lscr >> 1);
217  auto *scr = (uint8_t *) &lscr;
218  auto scr_ext = (uint16_t) ((SCR%300ULL) & 0x1FFULL);
219  obuf[c++] = scr[0];
220  obuf[c++] = scr[1];
221  obuf[c++] = scr[2];
222  obuf[c++] = scr[3];
223  obuf[c++] = bit | 0x7e | (scr_ext >> 8);
224  obuf[c++] = scr_ext & 0xff;
225  size -= 6;
226  }
227  while(size-- > 0)
228  obuf[c++] = 0xff;
229  }
230  return c;
231 }
232 
233 int write_video_ts(uint64_t vpts, uint64_t vdts, uint64_t SCR, uint8_t *buf,
234  int *vlength, uint8_t ptsdts, ringbuffer *vrbuffer)
235 {
236 //Unlike program streams, we only do one PES per frame
237  static int s_count = 0;
238  int pos = 0;
239  int stuff = 0;
240  int length = *vlength;
241 
242  if (! length) return 0;
243  int p = 4;
244  if ( ptsdts ) {
245  p += PES_H_MIN + 8;
246 
247  if ( ptsdts == PTS_ONLY) {
248  p += 5;
249  } else if (ptsdts == PTS_DTS){
250  p += 10;
251  }
252  }
253  if ( length+p >= TS_SIZE){
254  length = TS_SIZE;
255  } else {
256  stuff = TS_SIZE - length - p;
257  length = TS_SIZE;
258  }
259  if(ptsdts) {
260 #if 0
261  LOG(VB_GENERAL, LOG_INFO, QString("SCR: %1 PTS: %2 DTS: %3")
262  .arg(SCR / 27000000.0, 0,'f')
263  .arg(vpts / 27000000.0, 0,'f')
264  .arg(vdts / 27000000.0, 0,'f'));
265 #endif
266  pos = write_ts_header(TS_VIDPID, 1, s_count, SCR, buf, stuff);
267  // always use length == 0 for video streams
268  pos += write_pes_header( 0xE0, 6, vpts, vdts, buf+pos,
269  0, ptsdts);
270  } else {
271  pos = write_ts_header(TS_VIDPID, 0, s_count, -1, buf, stuff);
272  }
273  s_count = (s_count+1) & 0x0f;
274 
275  if (length-pos > *vlength){
276  LOG(VB_GENERAL, LOG_ERR, QString("WHAT THE HELL %1 > %2\n")
277  .arg(length-pos).arg(*vlength));
278  }
279 
280  int add = ring_read( vrbuffer, buf+pos, length-pos);
281  *vlength = add;
282  if (add < 0) return -1;
283  pos += add;
284 
285  return pos;
286 }
287 
288 int write_audio_ts(int n, uint64_t pts, uint8_t *buf, int *alength,
289  uint8_t ptsdts, ringbuffer *arbuffer)
290 {
291  static std::array<int,32> s_count {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
292  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
293  int pos = 0;
294  int stuff = 0;
295  int length = *alength;
296 
297  if (!length) return 0;
298  int p = 4;
299 
300  if (ptsdts == PTS_ONLY){
301  p += PES_H_MIN + 5;
302  }
303 
304  if ( length+p >= TS_SIZE){
305  length = TS_SIZE;
306  } else {
307  stuff = TS_SIZE - length - p;
308  length = TS_SIZE;
309  }
310  if(ptsdts) {
311  pos = write_ts_header(TS_MP2PID+n, 1, s_count[n], -1, buf, stuff);
312  pos += write_pes_header( 0xC0+n, *alength + PES_H_MIN + 5, pts,
313  0, buf+pos, 0, ptsdts);
314  } else {
315  pos = write_ts_header(TS_MP2PID+n, 0, s_count[n], -1, buf, stuff);
316  }
317  s_count[n] = (s_count[n]+1) & 0x0f;
318  int add = ring_read( arbuffer, buf+pos, length-pos);
319  *alength = add;
320  if (add < 0) return -1;
321  pos += add;
322 
323  if (pos != TS_SIZE) {
324  LOG(VB_GENERAL, LOG_ERR, QString("apos: %1").arg(pos));
325  exit(1);
326  }
327 
328  return pos;
329 }
330 
331 int write_ac3_ts(int n, uint64_t pts, uint8_t *buf, int *alength,
332  uint8_t ptsdts, int nframes, ringbuffer *ac3rbuffer)
333 {
334  static std::array<int,32> s_count {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
335  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
336  int pos = 0;
337  int stuff = 0;
338  int length = *alength;
339 
340  if (!length) return 0;
341  int p = 4;
342 
343  if (ptsdts == PTS_ONLY){
344  p += PES_H_MIN + 5 + 4; //PES header + PTS + PS1
345  }
346 
347  if ( length+p >= TS_SIZE){
348  length = TS_SIZE;
349  } else {
350  stuff = TS_SIZE - length - p;
351  length = TS_SIZE;
352  }
353  if(ptsdts) {
354  pos = write_ts_header(TS_AC3PID+n, 1, s_count[n], -1, buf, stuff);
356  *alength + 4 + PES_H_MIN + 5,
357  pts, 0, buf+pos, 0, ptsdts);
358  buf[pos] = 0x80 + n;
359  buf[pos+1] = nframes;
360  buf[pos+2] = 0x00;
361  buf[pos+3] = 0x00;
362  pos += 4;
363  } else {
364  pos = write_ts_header(TS_AC3PID+n, 0, s_count[n], -1, buf, stuff);
365  }
366  s_count[n] = (s_count[n]+1) & 0x0f;
367 
368  int add = ring_read( ac3rbuffer, buf+pos, length-pos);
369  *alength = add;
370  if (add < 0) return -1;
371  pos += add;
372 
373  if (pos != TS_SIZE) {
374  LOG(VB_GENERAL, LOG_ERR, QString("apos: %1").arg(pos));
375  exit(1);
376  }
377 
378  return pos;
379 }
380 
381 void write_ts_patpmt(extdata_t *ext, int extcnt, uint8_t prog_num, uint8_t *buf)
382 {
383  static constexpr uint8_t PMTPID { 0x20 };
384  static int s_count = 0;
385  int pmtpos = 13;
386  //PMT Program number = 1
387  //PMT PID = 0x20
388  std::array<uint8_t,17> pat
389  {0x00, 0x00, 0xb0, 0x0d, 0xfe, 0xef, 0xc1, 0x00, 0x00,
390  0x00, 0x00, 0xe0, PMTPID, 0x00, 0x00, 0x00, 0x00};
391  std::array<uint8_t,184> pmt
392  {0x00, 0x02, 0xb0, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00,
393  0x00, 0x00, 0xf0, 0x00};
394 
395  //PAT
396  pat[10] = prog_num;
397  int pos = write_ts_header(0x00, 1, s_count, -1, buf, 0);
398  *(uint32_t *)(pat.data()+13)= htonl(crc32_04c11db7(pat.data()+1, 12, 0xffffffff));
399  memcpy(buf+pos, pat.data(), 17);
400  pos += 17;
401  memset(buf+pos, 0xff, TS_SIZE - pos);
402  pos = TS_SIZE;
403  //PMT
404  pos += write_ts_header(PMTPID, 1, s_count, -1, buf+pos, 0);
405  for(int i = 0; i <= extcnt; i++) {
406  uint8_t type = 0xFF;
407  uint32_t pid = 0x1FFF;
408  int n = ext[i-1].strmnum;
409  if(i == 0) {
410  type = 0x02;
411  pid = TS_VIDPID;
412  } else if(ext[i-1].type == MPEG_AUDIO) {
413  type = 0x04;
414  pid = TS_MP2PID + n;
415  } else if(ext[i-1].type == AC3) {
416  type = 0x81;
417  pid = TS_AC3PID + n;
418  } else {
419  type = 0xff;
420  pid = 0x1fff;
421  }
422  pmt[pmtpos++] = type;
423  pmt[pmtpos++] = 0xe0 | (0xff & (pid >> 8));
424  pmt[pmtpos++] = 0xff & pid;
425  pmt[pmtpos++] = 0xf0;
426  if(strlen(ext[i-1].language) == 3) {
427  pmt[pmtpos++] = 0x06;
428  pmt[pmtpos++] = 0x0a;
429  pmt[pmtpos++] = 0x04;
430  pmt[pmtpos++] = ext[i-1].language[0];
431  pmt[pmtpos++] = ext[i-1].language[1];
432  pmt[pmtpos++] = ext[i-1].language[2];
433  pmt[pmtpos++] = 0x00;
434  } else {
435  pmt[pmtpos++] = 0x00;
436  }
437  }
438  pmt[3] = pmtpos + 4/*crc*/ - 3 - 1/*pointer_field*/;
439  pmt[5] = prog_num;
440  pmt[9] = 0xf0 | (0xff & (TS_VIDPID >> 8));
441  pmt[10] = 0xff & TS_VIDPID;
442  *(uint32_t *)&pmt[pmtpos] = htonl(crc32_04c11db7(&pmt[1], pmtpos -1,
443  0xffffffff));
444  pmtpos+=4;
445  memcpy(buf+pos, pmt.data(), pmtpos);
446  pos += pmtpos;
447  memset(buf+pos, 0xff, 2*TS_SIZE - pos);
448 // pos = 2*TS_SIZE;
449  s_count = (s_count+1) & 0x0f;
450 }
PRIVATE_STREAM1
#define PRIVATE_STREAM1
Definition: pes.h:23
pes.h
ringbuffer
Definition: ringbuffer.h:39
extdata_t::strmnum
int strmnum
Definition: mpg_common.h:59
get_pid
uint16_t get_pid(const uint8_t *pid)
Definition: ts.cpp:47
write_ts_patpmt
void write_ts_patpmt(extdata_t *ext, int extcnt, uint8_t prog_num, uint8_t *buf)
Definition: ts.cpp:381
extdata_t::language
char language[4]
Definition: mpg_common.h:61
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MPEG_AUDIO
@ MPEG_AUDIO
Definition: element.h:84
TS_AC3PID
static constexpr uint16_t TS_AC3PID
Definition: ts.h:63
PES_H_MIN
#define PES_H_MIN
Definition: pes.h:16
mythlogging.h
hardwareprofile.config.p
p
Definition: config.py:33
PTS_ONLY
#define PTS_ONLY
Definition: pes.h:46
PAY_START
static constexpr uint8_t PAY_START
Definition: ts.h:35
TS_MP2PID
static constexpr uint16_t TS_MP2PID
Definition: ts.h:62
find_pids
int find_pids(uint16_t *vpid, uint16_t *apid, uint16_t *ac3pid, uint8_t *buf, int len)
Definition: ts.cpp:127
extdata_t
Definition: mpg_common.h:54
find_pids_pos
int find_pids_pos(uint16_t *vpid, uint16_t *apid, uint16_t *ac3pid, uint8_t *buf, int len, int *vpos, int *apos, int *ac3pos)
Definition: ts.cpp:57
TS_SIZE
static constexpr qint64 TS_SIZE
Definition: hlsstreamhandler.cpp:19
element.h
write_ts_header
static int write_ts_header(uint16_t pid, int payload_start, int count, int64_t SCR, uint8_t *obuf, int stuff)
Definition: ts.cpp:189
ADAPT_FIELD
static constexpr uint8_t ADAPT_FIELD
Definition: ts.h:42
crc32_04c11db7
static unsigned int crc32_04c11db7(const unsigned char *d, int len, unsigned int crc)
Definition: ts.cpp:179
ring_read
int ring_read(ringbuffer *rbuf, uint8_t *data, int count)
Definition: ringbuffer.cpp:202
AC3
@ AC3
Definition: element.h:84
crc_table
static const std::array< const uint32_t, 256 > crc_table
Definition: ts.cpp:134
write_audio_ts
int write_audio_ts(int n, uint64_t pts, uint8_t *buf, int *alength, uint8_t ptsdts, ringbuffer *arbuffer)
Definition: ts.cpp:288
write_pes_header
int write_pes_header(uint8_t id, int length, uint64_t PTS, uint64_t DTS, uint8_t *obuf, int stuffing, uint8_t ptsdts)
Definition: pes.cpp:602
mpeg::chrono::pts
std::chrono::duration< CHRONO_TYPE, std::ratio< 1, 90000 > > pts
Definition: mythchrono.h:55
uint16_t
unsigned short uint16_t
Definition: iso6937tables.h:3
d
static const iso6937table * d
Definition: iso6937tables.cpp:1025
TS_VIDPID
static constexpr uint16_t TS_VIDPID
Definition: ts.h:61
write_video_ts
int write_video_ts(uint64_t vpts, uint64_t vdts, uint64_t SCR, uint8_t *buf, int *vlength, uint8_t ptsdts, ringbuffer *vrbuffer)
Definition: ts.cpp:233
PTS_DTS
#define PTS_DTS
Definition: pes.h:47
PID_MASK_HI
static constexpr uint8_t PID_MASK_HI
Definition: ts.h:37
hardwareprofile.distros.mythtv_data.data_mythtv.pp
pp
Definition: data_mythtv.py:561
write_ac3_ts
int write_ac3_ts(int n, uint64_t pts, uint8_t *buf, int *alength, uint8_t ptsdts, int nframes, ringbuffer *ac3rbuffer)
Definition: ts.cpp:331
ts.h