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