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 <algorithm>
30 #include <array>
31 #include <cstdint>
32 #include <cstdio>
33 #include <cstdlib>
34 #include <cstring>
35 
36 #ifdef _WIN32
37 #include <winsock2.h>
38 #else
39 #include <netinet/in.h>
40 #endif
41 
42 #include "ts.h"
43 #include "element.h"
44 #include "pes.h"
45 
47 
48 uint16_t get_pid(const uint8_t *pid)
49 {
50  uint16_t pp = 0;
51 
52  pp = (pid[0] & PID_MASK_HI)<<8;
53  pp |= pid[1];
54 
55  return pp;
56 }
57 
58 int find_pids_pos(uint16_t *vpid, uint16_t *apid, uint16_t *ac3pid,uint8_t *buf, int len, int *vpos, int *apos, int *ac3pos)
59 {
60  int c=0;
61  int found=0;
62 
63  if (!vpid || !apid || !ac3pid || !buf || !len) return 0;
64 
65  *vpid = 0;
66  *apid = 0;
67  *ac3pid = 0;
68 
69  while ( c+TS_SIZE < len){
70  if (buf[c] == buf[c+TS_SIZE]) break;
71  c++;
72  }
73 
74  while(found<2 && c < len){
75  if (buf[c+1] & PAY_START) {
76  int off = 4;
77 
78  if ( buf[c+3] & ADAPT_FIELD) { // adaptation field?
79  off += buf[c+4] + 1;
80  }
81 
82  if (off < TS_SIZE-4){
83  if (!*vpid && (buf[c+off+3] & 0xF0) == 0xE0){
84  *vpid = get_pid(buf+c+1);
85  if (vpos) *vpos = c+off+3;
86  found++;
87  }
88  if (!*ac3pid && buf[c+off+3] == 0xBD){
89  int l=off+4;
90  int f=0;
91 
92  while ( l < TS_SIZE && f<2){
93  uint8_t b=buf[c+l];
94  switch(f){
95  case 0:
96  if ( b == 0x0b)
97  f = 1;
98  break;
99 
100  case 1:
101  if ( b == 0x77)
102  f = 2;
103  else if ( b != 0x0b)
104  f = 0;
105  }
106  l++;
107  }
108  if (f==2){
109  *ac3pid = get_pid(buf+c+1);
110  if (ac3pos) *ac3pos = c+off+3;
111  found++;
112  }
113  }
114  if (!*apid && ((buf[c+off+3] & 0xF0) == 0xC0 ||
115  (buf[c+off+3] & 0xF0) == 0xD0)){
116  *apid = get_pid(buf+c+1);
117  if (apos) *apos = c+off+3;
118  found++;
119  }
120  }
121  }
122  c+= TS_SIZE;
123  }
124  return found;
125 }
126 
127 
128 int find_pids(uint16_t *vpid, uint16_t *apid, uint16_t *ac3pid,uint8_t *buf, int len)
129 {
130  return find_pids_pos(vpid, apid, ac3pid, buf, len, nullptr, nullptr, nullptr);
131 }
132 
133 //taken and adapted from libdtv, (c) Rolf Hakenes
134 // CRC32 lookup table for polynomial 0x04c11db7
135 static const std::array <const uint32_t,256> crc_table {
136  0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
137  0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
138  0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
139  0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
140  0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
141  0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
142  0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
143  0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
144  0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
145  0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
146  0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
147  0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
148  0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
149  0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
150  0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
151  0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
152  0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
153  0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
154  0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
155  0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
156  0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
157  0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
158  0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
159  0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
160  0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
161  0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
162  0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
163  0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
164  0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
165  0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
166  0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
167  0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
168  0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
169  0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
170  0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
171  0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
172  0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
173  0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
174  0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
175  0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
176  0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
177  0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
178  0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4};
179 
180 static unsigned int crc32_04c11db7 (const unsigned char *d, int len, unsigned int crc)
181 {
182  const unsigned char *u = d; // Saves '& 0xff'
183 
184  for (int i=0; i<len; i++)
185  crc = (crc << 8) ^ crc_table[((crc >> 24) ^ *u++)];
186 
187  return crc;
188 }
189 
190 static int write_ts_header(uint16_t pid, int payload_start, int count,
191  int64_t SCR, uint8_t *obuf, int stuff)
192 {
193  int c = 0;
194 
195  obuf[c++] = 0x47;
196  obuf[c++] = (payload_start ? 0x40 : 0x00) | ((pid >> 8) & 0x1f);
197  obuf[c++] = pid & 0xff;
198  obuf[c++] = ((SCR >= 0 || stuff) ? 0x30 : 0x10) | count;
199  if (SCR >= 0|| stuff) {
200  if (stuff)
201  stuff--;
202  int size = stuff;
203  unsigned char flags = 0;
204  if(SCR >= 0) {
205  size = std::max(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:48
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
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:128
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:58
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:190
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:180
ring_read
int ring_read(ringbuffer *rbuf, uint8_t *data, int count)
Definition: ringbuffer.cpp:202
crc_table
static const std::array< const uint32_t, 256 > crc_table
Definition: ts.cpp:135
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:607
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
AC3
@ AC3
Definition: element.h:84
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
MPEG_AUDIO
@ MPEG_AUDIO
Definition: element.h:84