MythTV  master
pes.c
Go to the documentation of this file.
1 /*
2  * pes.c: MPEG PES 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 <stdlib.h>
30 #include <stdio.h>
31 #include <string.h>
32 
33 #ifdef _WIN32
34 #include <winsock2.h>
35 #else
36 #include <netinet/in.h>
37 #endif
38 
39 #include "pes.h"
40 #include "mythlogging.h"
41 
42 void printpts(int64_t pts)
43 {
44  int negative = 0;
45  if (pts < 0){
46  negative = 1;
47  pts = -pts;
48  }
49  pts = pts/300;
50  pts &= (MAX_PTS-1);
51  LOG(VB_GENERAL, LOG_INFO, "%s%2d:%02d:%02d.%04d",
52  (negative ? "-" : ""),
53  (unsigned int)(pts/90000.0)/3600,
54  ((unsigned int)(pts/90000.0)%3600)/60,
55  ((unsigned int)(pts/90000.0)%3600)%60,
56  (((unsigned int)(pts/9.0)%36000000)%600000)%10000);
57 }
58 
59 void printptss(int64_t pts)
60 {
61  int negative = 0;
62  if (pts < 0){
63  negative = 0;
64  pts = -pts;
65  }
66  pts = pts/300;
67  pts &= (MAX_PTS-1);
68  LOG(VB_GENERAL, LOG_INFO, "%s%2d:%02d:%02d.%03d",
69  (negative ? "-" : ""),
70  (unsigned int)(pts/90000.0)/3600,
71  ((unsigned int)(pts/90000.0)%3600)/60,
72  ((unsigned int)(pts/90000.0)%3600)%60,
73  (((unsigned int)(pts/90.0)%3600000)%60000)%1000
74  );
75 }
76 
77 /* use if you know that ptss are close and may overflow */
78 int64_t ptsdiff(uint64_t pts1, uint64_t pts2)
79 {
80  switch (ptscmp(pts1, pts2)){
81  case 0:
82  return 0;
83  break;
84 
85  case 1:
86  case -2:
87  return (pts1 -pts2);
88  break;
89 
90  case 2:
91  return (pts1 + MAX_PTS2 -pts2);
92  break;
93 
94  case -1:
95  return (pts1 - (pts2+ MAX_PTS2));
96  break;
97 
98  }
99 
100  return 0;
101 }
102 
103 /* use, if you need an unsigned result in pts range */
104 uint64_t uptsdiff(uint64_t pts1, uint64_t pts2)
105 {
106  int64_t diff = pts1 - pts2;
107 
108  if (diff < 0){
109  diff = MAX_PTS2 +diff;
110  }
111  return diff;
112 }
113 
114 int ptscmp(uint64_t pts1, uint64_t pts2)
115 {
116  int ret = -1;
117 
118  if (pts1 > pts2){
119  if ((pts1 - pts2) > MAX_PTS2/2)
120  ret = -1;
121  else
122  ret = 1;
123  } else if (pts1 == pts2) ret = 0;
124  else {
125  if ((pts2 - pts1) > MAX_PTS2/2)
126  ret = 2;
127  else
128  ret = -2;
129  }
130 #if 0
131  LOG(VB_GENERAL, LOG_INFO, "PTSCMP: %lli %lli %d\n", pts1, pts2, ret);
132  printpts(pts1);
133  printpts(pts2);
134 #endif
135  return ret;
136 }
137 
138 uint64_t ptsadd(uint64_t pts1, uint64_t pts2)
139 {
140  ptsinc(&pts1,pts2);
141  return pts1;
142 
143 }
144 
145 void init_pes_in(pes_in_t *p, int t, ringbuffer *rb, int wi){
146  p->type = t;
147  p->found = 0;
148  p->cid = 0;
149  p->mpeg = 0;
150  p->withbuf = wi;
151 
152  if (p->withbuf && !p->buf){
153  p->buf = malloc(MAX_PLENGTH*sizeof(uint8_t));
154  memset(p->buf,0,MAX_PLENGTH*sizeof(uint8_t));
155  } else if (rb) p->rbuf = rb;
156  if (p->rbuf) p->ini_pos = ring_wpos(p->rbuf);
157  p->done = 0;
158  memset(p->pts, 0 , 5);
159  memset(p->dts, 0 , 5);
160 }
161 
162 
163 void get_pes (pes_in_t *p, uint8_t *buf, int count, void (*func)(pes_in_t *p))
164 {
165  unsigned short *pl = NULL;
166  int done = 1;
167 
168  uint8_t headr[3] = { 0x00, 0x00, 0x01} ;
169  do {
170  int c=0;
171  done = 1;
172  while (c < count && (!p->mpeg ||
173  (p->mpeg == 2 && p->found < 9))
174  && (p->found < 5 || !p->done)){
175  switch ( p->found ){
176  case 0:
177  case 1:
178  if (buf[c] == 0x00) p->found++;
179  else p->found = 0;
180  c++;
181  break;
182  case 2:
183  if (buf[c] == 0x01) p->found++;
184  else if (buf[c] == 0){
185  p->found = 2;
186  } else p->found = 0;
187  c++;
188  break;
189  case 3:
190  p->cid = 0;
191  switch (buf[c]){
192  case PROG_STREAM_MAP:
193  case PRIVATE_STREAM2:
194  case PROG_STREAM_DIR:
195  case ECM_STREAM :
196  case EMM_STREAM :
197  case PADDING_STREAM :
198  case DSM_CC_STREAM :
199  case ISO13522_STREAM:
200  p->done = 1;
201  case PRIVATE_STREAM1:
204  p->found++;
205  p->cid = buf[c];
206  c++;
207  break;
208  default:
209  case PACK_START:
210  case SYS_START:
211  p->found = 0;
212  c++;
213  break;
214  }
215  break;
216 
217 
218  case 4:
219  if (count-c > 1){
220  pl = (unsigned short *) (buf+c);
221  p->plength = ntohs(*pl);
222  p->plen[0] = buf[c];
223  c++;
224  p->plen[1] = buf[c];
225  c++;
226  p->found+=2;
227  } else {
228  p->plen[0] = buf[c];
229  p->found++;
230  return;
231  }
232  break;
233  case 5:
234  p->plen[1] = buf[c];
235  c++;
236  pl = (unsigned short *) p->plen;
237  p->plength = ntohs(*pl);
238  p->found++;
239  break;
240 
241 
242  case 6:
243  if (!p->done){
244  p->flag1 = buf[c];
245  c++;
246  p->found++;
247  if ( (p->flag1 & 0xC0) == 0x80 ) p->mpeg = 2;
248  else {
249  LOG(VB_GENERAL, LOG_ERR,
250  "Error: THIS IS AN MPEG1 FILE");
251  exit(1);
252  }
253  }
254  break;
255 
256  case 7:
257  if ( !p->done && p->mpeg == 2){
258  p->flag2 = buf[c];
259  c++;
260  p->found++;
261  }
262  break;
263 
264  case 8:
265  if ( !p->done && p->mpeg == 2){
266  p->hlength = buf[c];
267  c++;
268  p->found++;
269  }
270  break;
271 
272  default:
273 
274  break;
275  }
276  }
277 
278  if (!p->plength) p->plength = MMAX_PLENGTH-6;
279 
280 
281  if ( p->done || (p->mpeg == 2 && p->found >= 9) ){
282  switch (p->cid){
283 
284  case AUDIO_STREAM_S ... AUDIO_STREAM_E:
286  case PRIVATE_STREAM1:
287 
288  if (p->withbuf){
289  memcpy(p->buf, headr, 3);
290  p->buf[3] = p->cid;
291  memcpy(p->buf+4,p->plen,2);
292  } else {
293  memcpy(p->hbuf, headr, 3);
294  p->hbuf[3] = p->cid;
295  memcpy(p->hbuf+4,p->plen,2);
296  }
297 
298  if (p->found == 9){
299  if (p->withbuf){
300  p->buf[6] = p->flag1;
301  p->buf[7] = p->flag2;
302  p->buf[8] = p->hlength;
303  } else {
304  p->hbuf[6] = p->flag1;
305  p->hbuf[7] = p->flag2;
306  p->hbuf[8] = p->hlength;
307  }
308  }
309 
310  if ( (p->flag2 & PTS_ONLY) && p->found < 14){
311  while (c < count && p->found < 14){
312  p->pts[p->found-9] = buf[c];
313  if (p->withbuf)
314  p->buf[p->found] = buf[c];
315  else
316  p->hbuf[p->found] = buf[c];
317  c++;
318  p->found++;
319  }
320  if (c == count) return;
321  }
322 
323  if (((p->flag2 & PTS_DTS) == 0xC0) && p->found < 19){
324  while (c < count && p->found < 19){
325  p->dts[p->found-14] = buf[c];
326  if (p->withbuf)
327  p->buf[p->found] = buf[c];
328  else
329  p->hbuf[p->found] = buf[c];
330  c++;
331  p->found++;
332  }
333  if (c == count) return;
334  }
335 
336 
337  while (c < count && p->found < p->plength+6){
338  int l = count -c;
339  if (l+p->found > p->plength+6)
340  l = p->plength+6-p->found;
341  if (p->withbuf)
342  memcpy(p->buf+p->found, buf+c, l);
343  else {
344  if ( p->found <
345  (unsigned int)p->hlength+9 ){
346  int rest = p->hlength+9-p->found;
347  memcpy(p->hbuf+p->found, buf+c, rest);
348  if (ring_write(p->rbuf, buf+c+rest,
349  l-rest) <0){
350  exit(1);
351  }
352  } else {
353  if (ring_write(p->rbuf, buf+c, l)<0){
354  LOG(VB_GENERAL, LOG_ERR,
355  "ring buffer overflow %d",
356  p->rbuf->size);
357  exit(1);
358  }
359  }
360  }
361 
362  p->found += l;
363  c += l;
364  }
365  if(p->found == p->plength+6){
366  func(p);
367  }
368  break;
369  }
370 
371  if ( p->done ){
372  if( p->found + count - c < p->plength+6){
373  p->found += count-c;
374  c = count;
375  } else {
376  c += p->plength+6 - p->found;
377  p->found = p->plength+6;
378  }
379  }
380 
381  if (p->plength && p->found == p->plength+6) {
382  init_pes_in(p, p->type, NULL, p->withbuf);
383  if (c < count) {
384  done = 0;
385  count -= c;
386  buf += c;
387  }
388  }
389  }
390  } while(!done);
391 }
392 
393 
394 static uint32_t scr_base_ps(const uint8_t *scr)
395 {
396  uint32_t base = 0;
397  uint8_t *buf = (uint8_t *)&base;
398 
399  buf[0] |= (uint8_t)((scr[0] & 0x18) << 3);
400  buf[0] |= (uint8_t)((scr[0] & 0x03) << 4);
401  buf[0] |= (uint8_t)((scr[1] & 0xF0) >> 4);
402 
403  buf[1] |= (uint8_t)((scr[1] & 0x0F) << 4);
404  buf[1] |= (uint8_t)((scr[2] & 0xF0) >> 4);
405 
406  buf[2] |= (uint8_t)((scr[2] & 0x08) << 4);
407  buf[2] |= (uint8_t)((scr[2] & 0x03) << 5);
408  buf[2] |= (uint8_t)((scr[3] & 0xF8) >> 3);
409 
410  buf[3] |= (uint8_t)((scr[3] & 0x07) << 5);
411  buf[3] |= (uint8_t)((scr[4] & 0xF8) >> 3);
412 
413  base = ntohl(base);
414  return base;
415 }
416 
417 static uint16_t scr_ext_ps(const uint8_t *scr)
418 {
419  short ext = 0;
420 
421  ext = (short)(scr[5] >> 1);
422  ext += (short) (scr[4] & 0x03) * 128;
423 
424  return ext;
425 }
426 
427 
428 
429 static void init_ps(ps_packet *p)
430 {
431  p->stuff_length=0xF8;
432  p->data = NULL;
433  p->sheader_length = 0;
434  p->audio_bound = 0;
435  p->video_bound = 0;
436  p->npes = 0;
437 }
438 
439 static void kill_ps(ps_packet *p)
440 {
441  if (p->data)
442  free(p->data);
443  init_ps(p);
444 }
445 
446 static void setlength_ps(ps_packet *p)
447 {
448  short *ll = (short *) p->sheader_llength;
449  p->sheader_length = ntohs(*ll) - 6;
450 }
451 
452 static void setl_ps(ps_packet *p)
453 {
454  setlength_ps(p);
455  p->data = (uint8_t *) malloc(p->sheader_length);
456 }
457 
458 
459 static int cwrite_ps(uint8_t *buf, ps_packet *p, uint32_t length)
460 {
461  (void)length;
462  uint8_t headr1[4] = {0x00, 0x00, 0x01, PACK_START };
463  uint8_t headr2[4] = {0x00, 0x00, 0x01, SYS_START };
464  uint8_t buffy = 0xFF;
465 
466 
467  memcpy(buf,headr1,4);
468  long count = 4;
469  memcpy(buf+count,p->scr,6);
470  count += 6;
471  memcpy(buf+count,p->mux_rate,3);
472  count += 3;
473  memcpy(buf+count,&p->stuff_length,1);
474  count++;
475  for (long i=0; i< (p->stuff_length & 3); i++){
476  memcpy(buf+count,&buffy,1);
477  count++;
478  }
479 
480  if (p->sheader_length){
481  memcpy(buf+count,headr2,4);
482  count += 4;
483  memcpy(buf+count,p->sheader_llength,2);
484  count += 2;
485  memcpy(buf+count,p->rate_bound,3);
486  count += 3;
487  memcpy(buf+count,&p->audio_bound,1);
488  count++;
489  memcpy(buf+count,&p->video_bound,1);
490  count++;
491  memcpy(buf+count,&p->reserved,1);
492  count++;
493  memcpy(buf+count,p->data,p->sheader_length);
494  count += p->sheader_length;
495  }
496 
497  return count;
498 }
499 
500 
501 
502 static int write_ps_header(uint8_t *buf,
503  uint64_t SCR,
504  uint32_t muxr,
505  uint8_t audio_bound,
506  uint8_t fixed,
507  uint8_t CSPS,
508  uint8_t audio_lock,
509  uint8_t video_lock,
510  uint8_t video_bound,
511  uint8_t navpack)
512 {
513  ps_packet p;
514 
515  init_ps(&p);
516 
517  uint32_t lscr = htonl((uint32_t) ((SCR/300ULL) & 0x00000000FFFFFFFF));
518  uint8_t *scr = (uint8_t *) &lscr;
519  uint16_t scr_ext = (uint16_t) ((SCR%300ULL) & 0x00000000000001FF);
520 
521 // SCR = 0
522  p.scr[0] = 0x44;
523  p.scr[1] = 0x00;
524  p.scr[2] = 0x04;
525  p.scr[3] = 0x00;
526  p.scr[4] = 0x04;
527  p.scr[5] = 0x01;
528 
529  p.scr[0] = 0x44 | ((scr[0] >> 3)&0x18) | ((scr[0] >> 4)&0x03);
530  p.scr[1] = 0x00 | ((scr[0] << 4)&0xF0) | ((scr[1] >> 4)&0x0F);
531  p.scr[2] = 0x04 | ((scr[1] << 4)&0xF0) | ((scr[2] >> 4)&0x08)
532  | ((scr[2] >> 5)&0x03);
533  p.scr[3] = 0x00 | ((scr[2] << 3)&0xF8) | ((scr[3] >> 5)&0x07);
534  p.scr[4] = 0x04 | ((scr[3] << 3)&0xF8) | ((scr_ext >> 7)&0x03);
535  p.scr[5] = 0x01 | ((scr_ext << 1)&0xFF);
536 
537 
538  muxr = muxr/50;
539  p.mux_rate[0] = (uint8_t)(muxr >> 14);
540  p.mux_rate[1] = (uint8_t)(0xff & (muxr >> 6));
541  p.mux_rate[2] = (uint8_t)(0x03 | ((muxr & 0x3f) << 2));
542 
543  p.stuff_length = 0xF8;
544 
545  if (navpack){
546  p.sheader_llength[0] = 0x00;
547  p.sheader_llength[1] = 0x12;
548 
549  setl_ps(&p);
550 
551  p.rate_bound[0] = (uint8_t)(0x80 | (muxr >>15));
552  p.rate_bound[1] = (uint8_t)(0xff & (muxr >> 7));
553  p.rate_bound[2] = (uint8_t)(0x01 | ((muxr & 0x7f)<<1));
554 
555 
556  p.audio_bound = (uint8_t)((audio_bound << 2)|(fixed << 1)|CSPS);
557  p.video_bound = (uint8_t)((audio_lock << 7)|
558  (video_lock << 6)|0x20|video_bound);
559  p.reserved = (uint8_t)(0xFF >> 1);
560 
561  p.data[0] = 0xB9;
562  p.data[1] = 0xE0;
563  p.data[2] = 0xE8;
564  p.data[3] = 0xB8;
565  p.data[4] = 0xC0;
566  p.data[5] = 0x20;
567  p.data[6] = 0xbd;
568  p.data[7] = 0xe0;
569  p.data[8] = 0x3a;
570  p.data[9] = 0xBF;
571  p.data[10] = 0xE0;
572  p.data[11] = 0x02;
573 
574  cwrite_ps(buf, &p, PS_HEADER_L2);
575  kill_ps(&p);
576  return PS_HEADER_L2;
577  }
578  cwrite_ps(buf, &p, PS_HEADER_L1);
579  kill_ps(&p);
580  return PS_HEADER_L1;
581 }
582 
583 
584 static void get_pespts(const uint8_t *spts,uint8_t *pts)
585 {
586  //Make sure to set the 1st 4 bits properly
587  pts[0] = 0x01 |
588  ((spts[0] & 0xC0) >>5);
589  pts[1] = ((spts[0] & 0x3F) << 2) |
590  ((spts[1] & 0xC0) >> 6);
591  pts[2] = 0x01 | ((spts[1] & 0x3F) << 2) |
592  ((spts[2] & 0x80) >> 6);
593  pts[3] = ((spts[2] & 0x7F) << 1) |
594  ((spts[3] & 0x80) >> 7);
595  pts[4] = 0x01 | ((spts[3] & 0x7F) << 1);
596 }
597 
598 int write_pes_header(uint8_t id, int length , uint64_t PTS, uint64_t DTS,
599  uint8_t *obuf, int stuffing, uint8_t ptsdts)
600 {
601  uint8_t le[2];
602  uint8_t dummy[3];
603  uint8_t ppts[5];
604  uint8_t pdts[5];
605  uint8_t headr[3] = {0x00, 0x00, 0x01};
606 
607  uint32_t lpts = htonl((PTS/300ULL) & 0x00000000FFFFFFFFULL);
608  uint8_t *pts = (uint8_t *) &lpts;
609  get_pespts(pts,ppts);
610  if ((PTS/300ULL) & 0x0000000100000000ULL) ppts[0] |= 0x80;
611 
612  uint32_t ldts = htonl((DTS/300ULL) & 0x00000000FFFFFFFFULL);
613  uint8_t *dts = (uint8_t *) &ldts;
614  get_pespts(dts,pdts);
615  if ((DTS/300ULL) & 0x0000000100000000ULL) pdts[0] |= 0x80;
616 
617  int c = 0;
618  memcpy(obuf+c,headr,3);
619  c += 3;
620  memcpy(obuf+c,&id,1);
621  c++;
622 
623  le[0] = 0;
624  le[1] = 0;
625  length -= 6;
626 
627  le[0] |= ((uint8_t)(length >> 8) & 0xFF);
628  le[1] |= ((uint8_t)(length) & 0xFF);
629  memcpy(obuf+c,le,2);
630  c += 2;
631 
632  if (id == PADDING_STREAM){
633  memset(obuf+c,0xff,length);
634  c+= length;
635  return c;
636  }
637 
638  dummy[0] = 0x80;
639  dummy[1] = 0;
640  dummy[2] = stuffing;
641 
642  if (ptsdts == PTS_ONLY){
643  dummy[2] += 5;
644  dummy[1] |= PTS_ONLY;
645  ppts[0] |= 0x20;
646  } else if (ptsdts == PTS_DTS){
647  dummy[2] += 10;
648  dummy[1] |= PTS_DTS;
649  ppts[0] |= 0x30;
650  pdts[0] |= 0x10;
651  }
652 
653 
654  memcpy(obuf+c,dummy,3);
655  c += 3;
656 
657  if (ptsdts == PTS_ONLY){
658  memcpy(obuf+c,ppts,5);
659  c += 5;
660  } else if ( ptsdts == PTS_DTS ){
661  memcpy(obuf+c,ppts,5);
662  c += 5;
663  memcpy(obuf+c,pdts,5);
664  c += 5;
665  }
666 
667  memset(obuf+c,0xFF,stuffing);
668  c += stuffing;
669 
670  return c;
671 }
672 
673 void write_padding_pes( int pack_size, int extcnt,
674  uint64_t SCR, uint64_t muxr, uint8_t *buf)
675 {
676  int pos = 0;
677 
678  pos = write_ps_header(buf,SCR,muxr, extcnt, 0, 0, 1, 1, 1,
679  0);
680 
681  write_pes_header( PADDING_STREAM, pack_size-pos, 0, 0, buf+pos, 0, 0);
682 
683 }
684 
685 int write_video_pes( int pack_size, int extcnt, uint64_t vpts,
686  uint64_t vdts, uint64_t SCR, uint64_t muxr,
687  uint8_t *buf, int *vlength,
688  uint8_t ptsdts, ringbuffer *vrbuffer)
689 {
690  int stuff = 0;
691  int length = *vlength;
692 
693  if (! length) return 0;
694  int p = PS_HEADER_L1+PES_H_MIN;
695 
696  if ( ptsdts == PTS_ONLY){
697  p += 5;
698  } else if (ptsdts == PTS_DTS){
699  p += 10;
700  }
701 
702  if ( length+p >= pack_size){
703  length = pack_size;
704  } else {
705  if (pack_size - length - p <= PES_MIN){
706  stuff = pack_size - length-p;
707  length = pack_size;
708  } else
709  length = length+p;
710  }
711 
712  int pos = write_ps_header(buf,SCR,muxr, extcnt, 0, 0, 1, 1,
713  1, 0);
714 
715  pos += write_pes_header( 0xE0, length-pos, vpts, vdts, buf+pos,
716  stuff, ptsdts);
717  if (length-pos > *vlength){
718  LOG(VB_GENERAL, LOG_ERR, "WHAT THE HELL %d > %d", length-pos,
719  *vlength);
720  }
721 
722  int add = ring_read( vrbuffer, buf+pos, length-pos);
723  *vlength = add;
724  if (add < 0) return -1;
725  pos += add;
726 
727  if (pos+PES_MIN < pack_size){
728  write_pes_header( PADDING_STREAM, pack_size-pos, 0, 0,
729  buf+pos, 0, 0);
730  pos = pack_size;
731  }
732  return pos;
733 }
734 
735 int write_audio_pes( int pack_size, int extcnt, int n, uint64_t pts,
736  uint64_t SCR, uint32_t muxr, uint8_t *buf, int *alength,
737  uint8_t ptsdts, ringbuffer *arbuffer)
738 {
739  int stuff = 0;
740  int length = *alength;
741 
742  if (!length) return 0;
743  int p = PS_HEADER_L1+PES_H_MIN;
744 
745  if (ptsdts == PTS_ONLY){
746  p += 5;
747  }
748 
749  if ( length+p >= pack_size){
750  length = pack_size;
751  } else {
752  if (pack_size-length-p <= PES_MIN){
753  stuff = pack_size - length-p;
754  length = pack_size;
755  } else
756  length = length+p;
757  }
758  int pos = write_ps_header(buf,SCR,muxr, extcnt, 0, 0, 1, 1,
759  1, 0);
760  pos += write_pes_header( 0xC0+n, length-pos, pts, 0, buf+pos, stuff,
761  ptsdts);
762  int add = ring_read( arbuffer, buf+pos, length-pos);
763  *alength = add;
764  if (add < 0) return -1;
765  pos += add;
766 
767  if (pos+PES_MIN < pack_size){
768  write_pes_header( PADDING_STREAM, pack_size-pos, 0,0,
769  buf+pos, 0, 0);
770  pos = pack_size;
771  }
772  if (pos != pack_size) {
773  LOG(VB_GENERAL, LOG_ERR, "apos: %d", pos);
774  exit(1);
775  }
776 
777  return pos;
778 }
779 
780 int write_ac3_pes( int pack_size, int extcnt, int n,
781  uint64_t pts, uint64_t SCR,
782  uint32_t muxr, uint8_t *buf, int *alength, uint8_t ptsdts,
783  int nframes,int ac3_off, ringbuffer *ac3rbuffer)
784 {
785  int stuff = 0;
786  int length = *alength;
787 
788  if (!length) return 0;
789  int p = PS_HEADER_L1+PES_H_MIN+4;
790 
791  if (ptsdts == PTS_ONLY){
792  p += 5;
793  }
794 
795  if ( length+p >= pack_size){
796  length = pack_size;
797  } else {
798  if (pack_size-length-p <= PES_MIN){
799  stuff = pack_size - length-p;
800  length = pack_size;
801  } else
802  length = length+p;
803  }
804  int pos = write_ps_header(buf,SCR,muxr, extcnt, 0, 0, 1, 1,
805  1, 0);
806 
807  pos += write_pes_header( PRIVATE_STREAM1, length-pos, pts, 0,
808  buf+pos, stuff, ptsdts);
809  buf[pos] = 0x80 + n;
810  buf[pos+1] = nframes;
811  buf[pos+2] = (ac3_off >> 8)& 0xFF;
812  buf[pos+3] = (ac3_off)& 0xFF;
813  pos += 4;
814 
815  int add = ring_read( ac3rbuffer, buf+pos, length-pos);
816  *alength = add;
817  if (add < 0) return -1;
818  pos += add;
819 
820  if (pos+PES_MIN < pack_size){
821  write_pes_header( PADDING_STREAM, pack_size-pos, 0,0,
822  buf+pos, 0, 0);
823  pos = pack_size;
824  }
825  if (pos != pack_size) {
826  LOG(VB_GENERAL, LOG_ERR, "apos: %d", pos);
827  exit(1);
828  }
829 
830  return pos;
831 }
832 
833 int write_nav_pack(int pack_size, int extcnt, uint64_t SCR, uint32_t muxr,
834  uint8_t *buf)
835 {
836  int pos = 0;
837  uint8_t headr[5] = {0x00, 0x00, 0x01, PRIVATE_STREAM2, 0x03 };
838  (void)pack_size;
839 
840  pos = write_ps_header( buf, SCR, muxr, extcnt, 0, 0, 1, 1, 1, 1);
841  memcpy(buf+pos, headr, 5);
842  buf[pos+5] = 0xD4;
843  pos += 6;
844  memset(buf+pos, 0, 0x03d4);
845  pos += 0x03d4;
846 
847  memcpy(buf+pos, headr, 5);
848  buf[pos+5] = 0xFA;
849  pos += 6;
850  memset(buf+pos, 0, 0x03fA);
851  pos += 0x03fA;
852 
853  return pos;
854 }
int write_video_pes(int pack_size, int extcnt, uint64_t vpts, uint64_t vdts, uint64_t SCR, uint64_t muxr, uint8_t *buf, int *vlength, uint8_t ptsdts, ringbuffer *vrbuffer)
Definition: pes.c:685
#define SYS_START
Definition: pes.h:21
int64_t ptsdiff(uint64_t pts1, uint64_t pts2)
Definition: pes.c:78
static int cwrite_ps(uint8_t *buf, ps_packet *p, uint32_t length)
Definition: pes.c:459
#define PS_HEADER_L1
Definition: pes.h:13
#define MMAX_PLENGTH
Definition: pes.h:50
#define ISO13522_STREAM
Definition: pes.h:33
#define NULL
Definition: H264Parser.h:62
void init_pes_in(pes_in_t *p, int t, ringbuffer *rb, int wi)
Definition: pes.c:145
#define PADDING_STREAM
Definition: pes.h:24
#define MAX_PLENGTH
Definition: pes.h:49
#define MAX_PTS
Definition: pes.h:52
int ring_write(ringbuffer *rbuf, uint8_t *data, int count)
Definition: ringbuffer.c:89
#define AUDIO_STREAM_E
Definition: pes.h:27
static uint32_t scr_base_ps(const uint8_t *scr)
Definition: pes.c:394
#define VIDEO_STREAM_E
Definition: pes.h:29
static void setl_ps(ps_packet *p)
Definition: pes.c:452
void get_pes(pes_in_t *p, uint8_t *buf, int count, void(*func)(pes_in_t *p))
Definition: pes.c:163
#define PES_MIN
Definition: pes.h:15
#define PRIVATE_STREAM1
Definition: pes.h:23
#define PACK_START
Definition: pes.h:20
#define PTS_ONLY
Definition: pes.h:46
#define PRIVATE_STREAM2
Definition: pes.h:25
void printpts(int64_t pts)
Definition: pes.c:42
int ring_read(ringbuffer *rbuf, uint8_t *data, int count)
Definition: ringbuffer.c:179
int ptscmp(uint64_t pts1, uint64_t pts2)
Definition: pes.c:114
#define VIDEO_STREAM_S
Definition: pes.h:28
#define PROG_STREAM_MAP
Definition: pes.h:22
#define DSM_CC_STREAM
Definition: pes.h:32
static uint16_t scr_ext_ps(const uint8_t *scr)
Definition: pes.c:417
#define AUDIO_STREAM_S
Definition: pes.h:26
int write_ac3_pes(int pack_size, int extcnt, int n, uint64_t pts, uint64_t SCR, uint32_t muxr, uint8_t *buf, int *alength, uint8_t ptsdts, int nframes, int ac3_off, ringbuffer *ac3rbuffer)
Definition: pes.c:780
#define PROG_STREAM_DIR
Definition: pes.h:34
uint64_t uptsdiff(uint64_t pts1, uint64_t pts2)
Definition: pes.c:104
int write_nav_pack(int pack_size, int extcnt, uint64_t SCR, uint32_t muxr, uint8_t *buf)
Definition: pes.c:833
#define ECM_STREAM
Definition: pes.h:30
#define PES_H_MIN
Definition: pes.h:16
static void init_ps(ps_packet *p)
Definition: pes.c:429
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.c:598
Definition: pes.h:71
uint64_t ptsadd(uint64_t pts1, uint64_t pts2)
Definition: pes.c:138
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
unsigned short uint16_t
Definition: iso6937tables.h:1
void printptss(int64_t pts)
Definition: pes.c:59
static int ring_wpos(ringbuffer *rbuf)
int write_audio_pes(int pack_size, int extcnt, int n, uint64_t pts, uint64_t SCR, uint32_t muxr, uint8_t *buf, int *alength, uint8_t ptsdts, ringbuffer *arbuffer)
Definition: pes.c:735
static void get_pespts(const uint8_t *spts, uint8_t *pts)
Definition: pes.c:584
#define MAX_PTS2
Definition: pes.h:53
Definition: pes.h:55
#define EMM_STREAM
Definition: pes.h:31
static void setlength_ps(ps_packet *p)
Definition: pes.c:446
void write_padding_pes(int pack_size, int extcnt, uint64_t SCR, uint64_t muxr, uint8_t *buf)
Definition: pes.c:673
#define PS_HEADER_L2
Definition: pes.h:14
static int write_ps_header(uint8_t *buf, uint64_t SCR, uint32_t muxr, uint8_t audio_bound, uint8_t fixed, uint8_t CSPS, uint8_t audio_lock, uint8_t video_lock, uint8_t video_bound, uint8_t navpack)
Definition: pes.c:502
#define PTS_DTS
Definition: pes.h:47
static void kill_ps(ps_packet *p)
Definition: pes.c:439
static void ptsinc(uint64_t *pts1, uint64_t pts2)
Definition: pes.h:129