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