2 * dvb-mpegtools for the Siemens Fujitsu DVB PCI card
4 * Copyright (C) 2000, 2001 Marcus Metzler
5 * for convergence integrated media GmbH
6 * Copyright (C) 2002 Marcus Metzler
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
26 * The author can be reached at marcus@convergence.de,
28 * the project's page is at http://linuxtv.org/dvb/
32 #include "transform.h"
37 static uint8_t tspid0[TS_SIZE] = {
38 0x47, 0x40, 0x00, 0x10, 0x00, 0x00, 0xb0, 0x11,
39 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, 0x00, 0xe0,
40 0x10, 0x00, 0x01, 0xe4, 0x00, 0x2a, 0xd6, 0x1a,
41 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
42 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
43 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
44 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
45 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
46 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
47 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
48 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
49 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
50 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
51 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
52 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
53 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
54 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
55 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
56 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
57 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
58 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
59 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
60 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
61 0xff, 0xff, 0xff, 0xff
64 static uint8_t tspid1[TS_SIZE] = {
65 0x47, 0x44, 0x00, 0x10, 0x00, 0x02, 0xb0, 0x1c,
66 0x00, 0x01, 0xcb, 0x00, 0x00, 0xe0, 0xa0, 0xf0,
67 0x05, 0x48, 0x03, 0x01, 0x00, 0x00, 0x02, 0xe0,
68 0xa0, 0xf0, 0x00, 0x03, 0xe0, 0x50, 0xf0, 0x00,
69 0xae, 0xea, 0x4e, 0x48, 0xff, 0xff, 0xff, 0xff,
70 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
71 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
72 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
73 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
74 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
75 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
76 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
77 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
78 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
79 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
80 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
81 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
82 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
83 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
84 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
85 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
86 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
87 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
88 0xff, 0xff, 0xff, 0xff
91 // CRC32 lookup table for polynomial 0x04c11db7
92 static const uint32_t crc_table[256] = {
93 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
94 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
95 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
96 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
97 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
98 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
99 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
100 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
101 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
102 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
103 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
104 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
105 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
106 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
107 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
108 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
109 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
110 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
111 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
112 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
113 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
114 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
115 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
116 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
117 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
118 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
119 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
120 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
121 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
122 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
123 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
124 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
125 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
126 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
127 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
128 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
129 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
130 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
131 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
132 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
133 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
134 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
135 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
139 calc_crc32 (const uint8_t *sec, uint8_t len)
142 uint32_t crc = 0xffffffff;
144 for (i = 0; i < len; i++)
145 crc = (crc << 8) ^ crc_table[((crc >> 24) ^ *sec++) & 0xff];
151 uint64_t trans_pts_dts(uint8_t *pts)
155 wts = ((uint64_t)((pts[0] & 0x0E) << 5) |
156 ((pts[1] & 0xFC) >> 2)) << 24;
157 wts |= (((pts[1] & 0x03) << 6) |
158 ((pts[2] & 0xFC) >> 2)) << 16;
159 wts |= (((pts[2] & 0x02) << 6) |
160 ((pts[3] & 0xFE) >> 1)) << 8;
161 wts |= (((pts[3] & 0x01) << 7) |
162 ((pts[4] & 0xFE) >> 1));
167 void get_pespts(uint8_t *av_pts,uint8_t *pts)
171 ((av_pts[0] & 0xC0) >>5);
172 pts[1] = ((av_pts[0] & 0x3F) << 2) |
173 ((av_pts[1] & 0xC0) >> 6);
174 pts[2] = 0x01 | ((av_pts[1] & 0x3F) << 2) |
175 ((av_pts[2] & 0x80) >> 6);
176 pts[3] = ((av_pts[2] & 0x7F) << 1) |
177 ((av_pts[3] & 0x80) >> 7);
178 pts[4] = 0x01 | ((av_pts[3] & 0x7F) << 1);
181 uint16_t get_pid(uint8_t *pid)
185 pp = (pid[0] & PID_MASK_HI)<<8;
191 int write_ts_header(uint16_t pid, uint8_t *counter, int pes_start,
192 uint8_t *buf, uint8_t length)
197 uint8_t tshead[4] = { 0x47, 0x00, 0x00, 0x10};
200 fill = TS_SIZE-4-length;
201 if (pes_start) tshead[1] = 0x40;
202 if (fill) tshead[3] = 0x30;
203 tshead[1] |= (uint8_t)((pid & 0x1F00) >> 8);
204 tshead[2] |= (uint8_t)(pid & 0x00FF);
205 tshead[3] |= ((*counter)++ & 0x0F) ;
206 memcpy(buf,tshead,4);
217 for ( i = 6; i < fill+4; i++){
227 int write_pes_header(uint8_t id,int length , long PTS, uint8_t *obuf,
236 uint8_t headr[3] = {0x00, 0x00, 0x01};
239 pts = (uint8_t *) &lpts;
241 get_pespts(pts,ppts);
244 memcpy(obuf+c,headr,3);
246 memcpy(obuf+c,&id,1);
251 length -= 6+stuffing;
253 le[0] |= ((uint8_t)(length >> 8) & 0xFF);
254 le[1] |= ((uint8_t)(length) & 0xFF);
258 if (id == PADDING_STREAM){
259 memset(obuf+c,0xff,length);
268 dummy[1] |= PTS_ONLY;
269 dummy[2] = 5+stuffing;
271 memcpy(obuf+c,dummy,3);
273 memset(obuf+c,0xFF,stuffing);
276 memcpy(obuf+c,ppts,5);
284 void init_p2p(p2p *p, void (*func)(uint8_t *buf, int count, void *p),
289 memset(p->buf,0,MMAX_PLENGTH);
293 p->bigend_repack = 0;
295 if ( repack < MAX_PLENGTH && repack > 265 ){
296 p->repack = repack-6;
297 p->bigend_repack = (uint16_t)htons((short)
298 ((repack-6) & 0xFFFF));
300 fprintf(stderr, "Repack size %d is out of range\n",repack);
307 void pes_repack(p2p *p)
310 int repack = p->repack;
311 int rest = p->plength;
312 uint8_t buf[MAX_PLENGTH];
318 fprintf(stderr,"Error in repack\n");
323 fprintf(stderr,"forgot to set repack size\n");
327 if (p->plength == repack){
328 memcpy(p->buf+4,(char *)&p->bigend_repack,2);
329 p->func(p->buf, repack+6, p);
337 memcpy(buf+4,(char *)&p->bigend_repack,2);
338 memset(buf+6,0,MAX_PLENGTH-6);
343 memcpy(p->buf+4,(char *)&p->bigend_repack,2);
344 p->func(p->buf, repack+6, p);
348 memcpy(buf,p->buf,9+p->hlength);
350 count += 9+p->hlength;
351 rest -= p->hlength+3;
354 while (rest >= repack-3){
355 memset(buf+6,0,MAX_PLENGTH-6);
359 memcpy(buf+9,p->buf+count,repack-3);
362 p->func(buf, repack+6, p);
366 diff = repack - 3 - rest - bfill;
373 if ( diff < PES_MIN){
374 length = rest+ diff + bfill+3;
375 buf[4] = (uint8_t)((length & 0xFF00) >> 8);
376 buf[5] = (uint8_t)(length & 0x00FF);
377 buf[8] = (uint8_t)(bfill+diff);
378 memset(buf+9+bfill,0xFF,diff);
379 memcpy(buf+9+bfill+diff,p->buf+count,rest);
381 length = rest+ bfill+3;
382 buf[4] = (uint8_t)((length & 0xFF00) >> 8);
383 buf[5] = (uint8_t)(length & 0x00FF);
384 memcpy(buf+9+bfill,p->buf+count,rest);
386 write_pes_header( PADDING_STREAM, diff, 0,
389 p->func(buf, repack+6, p);
396 memcpy(p->buf+4,(char *)&p->bigend_repack,2);
397 p->func(p->buf, repack+6, p);
401 memcpy(buf,p->buf,6+p->hlength);
407 while (rest >= repack-1){
408 memset(buf+6,0,MAX_PLENGTH-6);
410 memcpy(buf+7,p->buf+count,repack-1);
413 p->func(buf, repack+6, p);
418 diff = repack - 1 - rest - bfill;
420 if ( diff < PES_MIN){
421 length = rest+ diff + bfill+1;
422 buf[4] = (uint8_t)((length & 0xFF00) >> 8);
423 buf[5] = (uint8_t)(length & 0x00FF);
424 memset(buf+6,0xFF,diff);
428 memcpy(buf+7+diff,p->buf+count,rest+bfill);
430 length = rest+ bfill+1;
431 buf[4] = (uint8_t)((length & 0xFF00) >> 8);
432 buf[5] = (uint8_t)(length & 0x00FF);
435 memcpy(buf+7,p->buf+count,rest);
438 memcpy(buf+6,p->buf+count,rest+bfill);
441 write_pes_header( PADDING_STREAM, diff, 0,
444 p->func(buf, repack+6, p);
456 int filter_pes (uint8_t *buf, int count, p2p *p, int (*func)(p2p *p))
464 uint8_t headr[3] = { 0x00, 0x00, 0x01} ;
466 while (c < count && (p->mpeg == 0 ||
467 (p->mpeg == 1 && p->found < 7) ||
468 (p->mpeg == 2 && p->found < 9))
469 && (p->found < 5 || !p->done)){
473 if (buf[c] == 0x00) p->found++;
476 write(p->fd1,buf+c,1);
482 if (buf[c] == 0x01) p->found++;
483 else if (buf[c] == 0){
487 write(p->fd1,buf+c,1);
495 case PROG_STREAM_MAP:
496 case PRIVATE_STREAM2:
497 case PROG_STREAM_DIR:
500 case PADDING_STREAM :
502 case ISO13522_STREAM:
504 write(p->fd1,buf+c,1);
506 case PRIVATE_STREAM1:
507 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
508 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
515 write(p->fd1,buf+c,1);
524 pl = (unsigned short *) (buf+c);
525 p->plength = ntohs(*pl);
540 pl = (unsigned short *) p->plen;
541 p->plength = ntohs(*pl);
551 if ( (p->flag1 & 0xC0) == 0x80 ) p->mpeg = 2;
562 if ( !p->done && p->mpeg == 2){
570 if ( !p->done && p->mpeg == 2){
583 if (!p->plength) p->plength = MMAX_PLENGTH-6;
586 if ( p->done || ((p->mpeg == 2 && p->found >= 9) ||
587 (p->mpeg == 1 && p->found >= 7)) ){
590 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
591 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
592 case PRIVATE_STREAM1:
594 memcpy(p->buf, headr, 3);
596 memcpy(p->buf+4,p->plen,2);
598 if (p->mpeg == 2 && p->found == 9){
599 p->buf[6] = p->flag1;
600 p->buf[7] = p->flag2;
601 p->buf[8] = p->hlength;
604 if (p->mpeg == 1 && p->found == 7){
605 p->buf[6] = p->flag1;
609 if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) &&
611 while (c < count && p->found < 14){
612 p->pts[p->found-9] = buf[c];
613 p->buf[p->found] = buf[c];
617 if (c == count) return 1;
620 if (p->mpeg == 1 && p->which < 2000){
627 while (!p->which && c < count &&
630 p->buf[p->found] = buf[c];
636 if ( c == count) return 1;
638 if ( (p->check & 0xC0) == 0x40 && !p->which){
640 p->buf[p->found] = buf[c];
646 if ( c == count) return 1;
648 p->buf[p->found] = buf[c];
653 if ( c == count) return 1;
658 p->buf[p->found] = buf[c];
663 if ( c == count) return 1;
666 if ( (p->check & 0x30) && p->check != 0xFF){
667 p->flag2 = (p->check & 0xF0) << 2;
668 p->pts[0] = p->check;
672 if ( c == count) return 1;
674 if ((p->flag2 & PTS_DTS_FLAGS)
687 if ( c == count) return 1;
688 } else if ((p->flag2 & PTS_DTS_FLAGS)
703 if ( c == count) return 1;
710 while (c < count && p->found < p->plength+6){
712 if (l+p->found > p->plength+6)
713 l = p->plength+6-p->found;
714 memcpy(p->buf+p->found, buf+c, l);
718 if(p->found == p->plength+6){
731 if( p->found + count - c < p->plength+6){
735 c += p->plength+6 - p->found;
736 p->found = p->plength+6;
740 if (p->plength && p->found == p->plength+6) {
744 memset(p->buf, 0, MAX_PLENGTH);
746 return filter_pes(buf+c, count-c, p, func);
756 int audio_pes_filt(p2p *p)
761 case PRIVATE_STREAM1:
762 if ( p->cid == p->filter) {
764 if (p->buf[off] == p->subid){
770 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
771 if ( p->cid == p->filter)
783 void filter_audio_from_pes(int fdin, int fdout, uint8_t id, uint8_t subid)
789 init_p2p(&p, NULL, 2048);
795 count = read(fdin,buf,2048);
796 if(filter_pes(buf,count,&p,audio_pes_filt))
797 write(fdout,buf,2048);
802 void pes_filt(p2p *p)
804 int factor = p->mpeg-1;
806 if ( p->cid == p->filter) {
808 write(p->fd1,p->buf+p->hlength+6+3*factor,
809 p->plength-p->hlength-3*factor);
811 write(p->fd1,p->buf,p->plength+6);
815 void extract_from_pes(int fdin, int fdout, uint8_t id, int es)
821 init_p2p(&p, NULL, 2048);
827 count = read(fdin,buf,SIZE);
828 get_pes(buf,count,&p,pes_filt);
833 void pes_dfilt(p2p *p)
835 int factor = p->mpeg-1;
840 int c = 6+p->hlength+3*factor;
844 case PRIVATE_STREAM1:
845 streamid = p->buf[c];
847 if ((streamid & 0xF8) == 0x80+p->es-1){
852 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
856 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
862 if (p->es && !p->startv && type == VIDEO){
865 if ( p->flag2 & PTS_DTS )
866 p->vpts = trans_pts_dts(p->pts);
869 while ( !found && c+3 < p->plength+6 ){
870 if ( p->buf[c] == 0x00 &&
871 p->buf[c+1] == 0x00 &&
872 p->buf[c+2] == 0x01 &&
879 write(fd, p->buf+c, p->plength+6-c);
885 if ( p->es && !p->starta && type == AUDIO){
887 if ( p->flag2 & PTS_DTS )
888 p->apts = trans_pts_dts(p->pts);
892 while ( !found && c+1 < p->plength+6){
893 if ( p->buf[c] == 0xFF &&
894 (p->buf[c+1] & 0xF8) == 0xF8)
900 write(fd, p->buf+c, p->plength+6-c);
905 if ( p->es && !p->starta && type == AC3){
906 if ( p->flag2 & PTS_DTS )
907 p->apts = trans_pts_dts(p->pts);
911 c+= ((p->buf[c+2] << 8)| p->buf[c+3]);
913 write(fd, p->buf+c, p->plength+6-c);
921 write(fd,p->buf+p->hlength+6+3*factor+head,
922 p->plength-p->hlength-3*factor-head);
924 write(fd,p->buf,p->plength+6);
928 int64_t pes_dmx( int fdin, int fdouta, int fdoutv, int es)
936 int percent, oldPercent = -1;
938 init_p2p(&p, NULL, 2048);
947 if (fdin != STDIN_FILENO) verb = 1;
950 length = lseek(fdin, 0, SEEK_END);
951 lseek(fdin,0,SEEK_SET);
955 count = read(fdin,buf,SIZE);
958 percent = 100 * l / length;
960 if (percent != oldPercent) {
961 fprintf(stderr, "Demuxing %d %%\r", percent);
962 oldPercent = percent;
965 get_pes(buf,count,&p,pes_dfilt);
968 return (int64_t)p.vpts - (int64_t)p.apts;
973 /* SV: made non-static */
974 void pes_in_ts(p2p *p)
977 uint8_t obuf[TS_SIZE];
979 int length = p->plength+6;
984 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
986 counter = &p->acounter;
988 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
990 counter = &p->acounter;
992 tspid0[3] |= (p->count0++)
994 tspid1[3] |= (p->count1++)
997 tspid1[24] = p->pidv;
998 tspid1[23] |= (p->pidv >> 8) & 0x3F;
999 tspid1[29] = p->pida;
1000 tspid1[28] |= (p->pida >> 8) & 0x3F;
1002 p->func(tspid0,188,p);
1003 p->func(tspid1,188,p);
1009 while ( c < length ){
1010 memset(obuf,0,TS_SIZE);
1011 if (length - c >= TS_SIZE-4){
1012 l = write_ts_header(pid, counter, pes_start
1014 memcpy(obuf+l, p->buf+c, TS_SIZE-l);
1017 l = write_ts_header(pid, counter, pes_start
1019 memcpy(obuf+l, p->buf+c, TS_SIZE-l);
1022 p->func(obuf,188,p);
1028 void write_out(uint8_t *buf, int count,void *p)
1030 write(STDOUT_FILENO, buf, count);
1034 void pes_to_ts2( int fdin, int fdout, uint16_t pida, uint16_t pidv)
1039 uint64_t length = 0;
1043 init_p2p(&p, NULL, 2048);
1053 if (fdin != STDIN_FILENO) verb = 1;
1056 length = lseek(fdin, 0, SEEK_END);
1057 lseek(fdin,0,SEEK_SET);
1061 count = read(fdin,buf,SIZE);
1064 fprintf(stderr,"Writing TS %2.2f %%\r",
1067 get_pes(buf,count,&p,pes_in_ts);
1073 #define IN_SIZE TS_SIZE*10
1074 void find_avpids(int fd, uint16_t *vpid, uint16_t *apid)
1076 uint8_t buf[IN_SIZE];
1081 while ( *apid == 0 || *vpid == 0){
1082 count = read(fd, buf, IN_SIZE);
1083 for (i = 0; i < count-7; i++){
1084 if (buf[i] == 0x47){
1085 if (buf[i+1] & 0x40){
1087 if ( buf[3+i] & 0x20)//adapt field?
1089 switch(buf[i+7+off]){
1090 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1091 *vpid = get_pid(buf+i+1);
1093 case PRIVATE_STREAM1:
1094 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1095 *apid = get_pid(buf+i+1);
1101 if (*apid != 0 && *vpid != 0) break;
1106 void find_bavpids(uint8_t *buf, int count, uint16_t *vpid, uint16_t *apid)
1115 for (i = 0; i < count-7; i++){
1116 if (buf[i] == 0x47){
1117 if ((buf[i+1] & 0xF0) == 0x40){
1119 if ( buf[3+i] & 0x20) // adaptation field?
1122 if (buf[off+i+4] == 0x00 &&
1123 buf[off+i+5] == 0x00 &&
1124 buf[off+i+6] == 0x01){
1125 switch(buf[off+i+7]){
1126 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1127 *vpid = get_pid(buf+i+1);
1130 case PRIVATE_STREAM1:
1131 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1132 *apid = get_pid(buf+i+1);
1140 if (founda && foundb) break;
1145 void ts_to_pes( int fdin, uint16_t pida, uint16_t pidv, int ps)
1148 uint8_t buf[IN_SIZE];
1149 uint8_t mbuf[TS_SIZE];
1157 if (fdin != STDIN_FILENO && (!pida || !pidv))
1158 find_avpids(fdin, &pidv, &pida);
1160 init_ipack(&pa, IPACKS,write_out, ps);
1161 init_ipack(&pv, IPACKS,write_out, ps);
1163 if ((count = save_read(fdin,mbuf,TS_SIZE))<0)
1166 for ( i = 0; i < 188 ; i++){
1167 if ( mbuf[i] == 0x47 ) break;
1170 fprintf(stderr,"Not a TS\n");
1173 memcpy(buf,mbuf+i,TS_SIZE-i);
1174 if ((count = save_read(fdin,mbuf,i))<0)
1176 memcpy(buf+TS_SIZE-i,mbuf,i);
1181 if ((count = save_read(fdin,buf+i,IN_SIZE-i)+i)<0)
1186 find_bavpids(buf+i, IN_SIZE-i, &pidv, &dummy);
1187 if (pidv) fprintf(stderr, "vpid %d (0x%02x)\n",
1192 find_bavpids(buf+i, IN_SIZE-i, &dummy, &pida);
1193 if (pida) fprintf(stderr, "apid %d (0x%02x)\n",
1198 for( i = 0; i < count; i+= TS_SIZE){
1201 if ( count - i < TS_SIZE) break;
1203 pid = get_pid(buf+i+1);
1204 if (!(buf[3+i]&0x10)) // no payload?
1206 if ( buf[1+i]&0x80){
1207 fprintf(stderr,"Error in TS for PID: %d\n",
1218 if ( buf[1+i]&0x40) {
1219 if (p->plength == MMAX_PLENGTH-6){
1220 p->plength = p->found-6;
1227 if ( buf[3+i] & 0x20) { // adaptation field?
1231 instant_repack(buf+4+off+i, TS_SIZE-4-off, p);
1240 #define INN_SIZE 2*IN_SIZE
1241 void insert_pat_pmt( int fdin, int fdout)
1244 uint8_t buf[INN_SIZE];
1245 uint8_t mbuf[TS_SIZE];
1257 find_avpids(fdin, &pidv, &pida);
1259 count = save_read(fdin,mbuf,TS_SIZE);
1260 for ( i = 0; i < 188 ; i++){
1261 if ( mbuf[i] == 0x47 ) break;
1264 fprintf(stderr,"Not a TS\n");
1267 memcpy(buf,mbuf+i,TS_SIZE-i);
1268 count = save_read(fdin,mbuf,i);
1269 memcpy(buf+TS_SIZE-i,mbuf,i);
1274 /* length is not correct, but we only create a very small
1275 * PMT, so it doesn't matter :-)
1277 pmt_len = tspid1[7] + 3;
1280 tspid1[23] |= (pidv >> 8) & 0x3F;
1282 tspid1[28] |= (pida >> 8) & 0x3F;
1283 crc32 = calc_crc32 (&tspid1[5], pmt_len - 4);
1284 tspid1[5 + pmt_len - 4] = (crc32 & 0xff000000) >> 24;
1285 tspid1[5 + pmt_len - 3] = (crc32 & 0x00ff0000) >> 16;
1286 tspid1[5 + pmt_len - 2] = (crc32 & 0x0000ff00) >> 8;
1287 tspid1[5 + pmt_len - 1] = (crc32 & 0x000000ff) >> 0;
1289 write(fdout,tspid0,188);
1290 write(fdout,tspid1,188);
1292 count = save_read(fdin,buf+i,INN_SIZE-i);
1295 while (written < IN_SIZE){
1296 c = write(fdout,buf,INN_SIZE);
1297 if (c>0) written += c;
1300 tspid0[3] |= (c0++)& 0x0F ;
1303 tspid1[3] |= (c1++)& 0x0F ;
1310 void get_pes (uint8_t *buf, int count, p2p *p, void (*func)(p2p *p))
1317 uint8_t headr[3] = { 0x00, 0x00, 0x01} ;
1319 while (c < count && (p->mpeg == 0 ||
1320 (p->mpeg == 1 && p->found < 7) ||
1321 (p->mpeg == 2 && p->found < 9))
1322 && (p->found < 5 || !p->done)){
1323 switch ( p->found ){
1326 if (buf[c] == 0x00) p->found++;
1331 if (buf[c] == 0x01) p->found++;
1332 else if (buf[c] == 0){
1334 } else p->found = 0;
1340 case PROG_STREAM_MAP:
1341 case PRIVATE_STREAM2:
1342 case PROG_STREAM_DIR:
1345 case PADDING_STREAM :
1346 case DSM_CC_STREAM :
1347 case ISO13522_STREAM:
1349 case PRIVATE_STREAM1:
1350 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1351 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1365 pl = (unsigned short *) (buf+c);
1366 p->plength = ntohs(*pl);
1367 p->plen[0] = buf[c];
1369 p->plen[1] = buf[c];
1373 p->plen[0] = buf[c];
1379 p->plen[1] = buf[c];
1381 pl = (unsigned short *) p->plen;
1382 p->plength = ntohs(*pl);
1392 if ( (p->flag1 & 0xC0) == 0x80 ) p->mpeg = 2;
1403 if ( !p->done && p->mpeg == 2){
1411 if ( !p->done && p->mpeg == 2){
1412 p->hlength = buf[c];
1424 if (!p->plength) p->plength = MMAX_PLENGTH-6;
1427 if ( p->done || ((p->mpeg == 2 && p->found >= 9) ||
1428 (p->mpeg == 1 && p->found >= 7)) ){
1431 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1432 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1433 case PRIVATE_STREAM1:
1435 memcpy(p->buf, headr, 3);
1437 memcpy(p->buf+4,p->plen,2);
1439 if (p->mpeg == 2 && p->found == 9){
1440 p->buf[6] = p->flag1;
1441 p->buf[7] = p->flag2;
1442 p->buf[8] = p->hlength;
1445 if (p->mpeg == 1 && p->found == 7){
1446 p->buf[6] = p->flag1;
1450 if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) &&
1452 while (c < count && p->found < 14){
1453 p->pts[p->found-9] = buf[c];
1454 p->buf[p->found] = buf[c];
1458 if (c == count) return;
1461 if (p->mpeg == 1 && p->which < 2000){
1463 if (p->found == 7) {
1464 p->check = p->flag1;
1468 while (!p->which && c < count &&
1471 p->buf[p->found] = buf[c];
1477 if ( c == count) return;
1479 if ( (p->check & 0xC0) == 0x40 && !p->which){
1481 p->buf[p->found] = buf[c];
1487 if ( c == count) return;
1489 p->buf[p->found] = buf[c];
1494 if ( c == count) return;
1499 p->buf[p->found] = buf[c];
1504 if ( c == count) return;
1507 if ( (p->check & 0x30) && p->check != 0xFF){
1508 p->flag2 = (p->check & 0xF0) << 2;
1509 p->pts[0] = p->check;
1513 if ( c == count) return;
1515 if ((p->flag2 & PTS_DTS_FLAGS)
1519 p->pts[p->which-2] =
1528 if ( c == count) return;
1529 } else if ((p->flag2 & PTS_DTS_FLAGS)
1544 if ( c == count) return;
1551 while (c < count && p->found < p->plength+6){
1553 if (l+p->found > p->plength+6)
1554 l = p->plength+6-p->found;
1555 memcpy(p->buf+p->found, buf+c, l);
1559 if(p->found == p->plength+6)
1567 if( p->found + count - c < p->plength+6){
1568 p->found += count-c;
1571 c += p->plength+6 - p->found;
1572 p->found = p->plength+6;
1576 if (p->plength && p->found == p->plength+6) {
1580 memset(p->buf, 0, MAX_PLENGTH);
1582 get_pes(buf+c, count-c, p, func);
1591 void setup_pes2ts( p2p *p, uint32_t pida, uint32_t pidv,
1592 void (*ts_write)(uint8_t *buf, int count, void *p))
1594 init_p2p( p, ts_write, 2048);
1603 void kpes_to_ts( p2p *p,uint8_t *buf ,int count )
1605 get_pes(buf,count, p,pes_in_ts);
1609 void setup_ts2pes( p2p *pa, p2p *pv, uint32_t pida, uint32_t pidv,
1610 void (*pes_write)(uint8_t *buf, int count, void *p))
1612 init_p2p( pa, pes_write, 2048);
1613 init_p2p( pv, pes_write, 2048);
1618 void kts_to_pes( p2p *p, uint8_t *buf) // don't need count (=188)
1623 if (!(buf[3]&PAYLOAD)) // no payload?
1626 pid = get_pid(buf+1);
1628 if (pid != p->pid) return;
1630 fprintf(stderr,"Error in TS for PID: %d\n",
1634 if ( buf[1]&PAY_START) {
1635 if (p->plength == MMAX_PLENGTH-6){
1636 p->plength = p->found-6;
1642 if ( buf[3] & ADAPT_FIELD) { // adaptation field?
1644 if (off+4 > 187) return;
1647 get_pes(buf+4+off, TS_SIZE-4-off, p , pes_repack);
1656 void reset_ipack(ipack *p)
1669 p->size = p->size_orig;
1672 void init_ipack(ipack *p, int size,
1673 void (*func)(uint8_t *buf, int size, void *priv), int ps)
1675 if ( !(p->buf = malloc(size)) ){
1676 fprintf(stderr,"Couldn't allocate memory for ipack\n");
1680 p->size_orig = size;
1688 void free_ipack(ipack * p)
1690 if (p->buf) free(p->buf);
1695 int get_vinfo(uint8_t *mbuf, int count, VideoInfo *vi, int pr)
1703 while (found < 4 && c+4 < count){
1707 if ( b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01
1708 && b[3] == 0xb3) found = 4;
1714 if (! found) return -1;
1716 if (c+12 >= count) return -1;
1719 vi->horizontal_size = ((headr[1] &0xF0) >> 4) | (headr[0] << 4);
1720 vi->vertical_size = ((headr[1] &0x0F) << 8) | (headr[2]);
1722 sw = (int)((headr[3]&0xF0) >> 4) ;
1727 fprintf(stderr,"Videostream: ASPECT: 1:1");
1728 vi->aspect_ratio = 100;
1732 fprintf(stderr,"Videostream: ASPECT: 4:3");
1733 vi->aspect_ratio = 133;
1737 fprintf(stderr,"Videostream: ASPECT: 16:9");
1738 vi->aspect_ratio = 177;
1742 fprintf(stderr,"Videostream: ASPECT: 2.21:1");
1743 vi->aspect_ratio = 221;
1748 fprintf(stderr,"Videostream: ASPECT: reserved");
1749 vi->aspect_ratio = 0;
1753 vi->aspect_ratio = 0;
1758 fprintf(stderr," Size = %dx%d",vi->horizontal_size,
1761 sw = (int)(headr[3]&0x0F);
1766 fprintf(stderr," FRate: 23.976 fps");
1767 vi->framerate = 24000/1001.;
1772 fprintf(stderr," FRate: 24 fps");
1778 fprintf(stderr," FRate: 25 fps");
1780 form = VIDEO_MODE_PAL;
1784 fprintf(stderr," FRate: 29.97 fps");
1785 vi->framerate = 30000/1001.;
1786 form = VIDEO_MODE_NTSC;
1790 fprintf(stderr," FRate: 30 fps");
1792 form = VIDEO_MODE_NTSC;
1796 fprintf(stderr," FRate: 50 fps");
1798 form = VIDEO_MODE_PAL;
1802 fprintf(stderr," FRate: 60 fps");
1804 form = VIDEO_MODE_NTSC;
1808 vi->bit_rate = 400*(((headr[4] << 10) & 0x0003FC00UL)
1809 | ((headr[5] << 2) & 0x000003FCUL) |
1810 (((headr[6] & 0xC0) >> 6) & 0x00000003UL));
1813 fprintf(stderr," BRate: %.2f Mbit/s",(vi->bit_rate)/1000000.);
1814 fprintf(stderr,"\n");
1816 vi->video_format = form;
1822 extern unsigned int bitrates[3][16];
1823 extern uint32_t freq[4];
1825 int get_ainfo(uint8_t *mbuf, int count, AudioInfo *ai, int pr)
1832 while (!found && c < count){
1833 uint8_t *b = mbuf+c;
1835 if ( b[0] == 0xff && (b[1] & 0xf8) == 0xf8)
1842 if (!found) return -1;
1844 if (c+3 >= count) return -1;
1847 ai->layer = (headr[1] & 0x06) >> 1;
1850 fprintf(stderr,"Audiostream: Layer: %d", 4-ai->layer);
1853 ai->bit_rate = bitrates[(3-ai->layer)][(headr[2] >> 4 )]*1000;
1856 if (ai->bit_rate == 0)
1857 fprintf (stderr," Bit rate: free");
1858 else if (ai->bit_rate == 0xf)
1859 fprintf (stderr," BRate: reserved");
1861 fprintf (stderr," BRate: %d kb/s", ai->bit_rate/1000);
1864 fr = (headr[2] & 0x0c ) >> 2;
1865 ai->frequency = freq[fr]*100;
1868 if (ai->frequency == 3)
1869 fprintf (stderr, " Freq: reserved\n");
1871 fprintf (stderr," Freq: %2.1f kHz\n",
1872 ai->frequency/1000.);
1878 unsigned int ac3_bitrates[32] =
1879 {32,40,48,56,64,80,96,112,128,160,192,224,256,320,384,448,512,576,640,
1880 0,0,0,0,0,0,0,0,0,0,0,0,0};
1882 uint32_t ac3_freq[4] = {480, 441, 320, 0};
1883 uint32_t ac3_frames[3][32] =
1884 {{64,80,96,112,128,160,192,224,256,320,384,448,512,640,768,896,1024,
1885 1152,1280,0,0,0,0,0,0,0,0,0,0,0,0,0},
1886 {69,87,104,121,139,174,208,243,278,348,417,487,557,696,835,975,1114,
1887 1253,1393,0,0,0,0,0,0,0,0,0,0,0,0,0},
1888 {96,120,144,168,192,240,288,336,384,480,576,672,768,960,1152,1344,
1889 1536,1728,1920,0,0,0,0,0,0,0,0,0,0,0,0,0}};
1891 int get_ac3info(uint8_t *mbuf, int count, AudioInfo *ai, int pr)
1899 while ( !found && c < count){
1900 uint8_t *b = mbuf+c;
1901 if ( b[0] == 0x0b && b[1] == 0x77 )
1914 if (c+5 >= count) return -1;
1916 ai->layer = 0; // 0 for AC3
1919 frame = (headr[2]&0x3f);
1920 ai->bit_rate = ac3_bitrates[frame>>1]*1000;
1922 if (pr) fprintf (stderr," BRate: %d kb/s", ai->bit_rate/1000);
1924 fr = (headr[2] & 0xc0 ) >> 6;
1925 ai->frequency = freq[fr]*100;
1926 if (pr) fprintf (stderr," Freq: %d Hz\n", ai->frequency);
1928 ai->framesize = ac3_frames[fr][frame >> 1];
1929 if ((frame & 1) && (fr == 1)) ai->framesize++;
1930 ai->framesize = ai->framesize << 1;
1931 if (pr) fprintf (stderr," Framesize %d\n", ai->framesize);
1937 void ps_pes(ipack *p)
1940 uint8_t pbuf[PS_HEADER_L2];
1941 static int muxr = 0;
1944 static int start = 0;
1945 static uint32_t SCR = 0;
1949 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1951 if(get_vinfo(p->buf, p->count, &p->vi,1) >=0) {
1953 vi = p->vi.bit_rate;
1958 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1960 if(get_ainfo(p->buf, p->count, &p->ai,1) >=0) {
1962 ai = p->ai.bit_rate;
1968 if (p->has_vi && vi && !muxr){
1972 if ( start && muxr && (p->buf[7] & PTS_ONLY) && (p->has_ai ||
1973 p->buf[9+p->buf[8]+4] == 0xb3)){
1974 SCR = trans_pts_dts(p->pts)-3600;
1976 check = write_ps_header(pbuf,
1978 muxr, 1, 0, 0, 1, 1, 1,
1981 p->func(pbuf, check , p->data);
1984 if (muxr && !start && vi){
1985 SCR = trans_pts_dts(p->pts)-3600;
1986 check = write_ps_header(pbuf,
1988 muxr, 1, 0, 0, 1, 1, 1,
1989 0xC0, 0, 64, 0xE0, 1, 460);
1991 p->func(pbuf, check , p->data);
1995 p->func(p->buf, p->count, p->data);
1999 void send_ipack(ipack *p)
2008 if (p->count < 10) return;
2010 p->buf[4] = (uint8_t)(((p->count-6) & 0xFF00) >> 8);
2011 p->buf[5] = (uint8_t)((p->count-6) & 0x00FF);
2014 if (p->cid == PRIVATE_STREAM1){
2017 streamid = p->buf[off];
2018 if ((streamid & 0xF8) == 0x80){
2020 ac3_off = ((p->buf[off+2] << 8)| p->buf[off+3]);
2021 if (ac3_off < p->count)
2022 f=get_ac3info(p->buf+off+3+ac3_off,
2023 p->count-ac3_off, &ai,0);
2025 nframes = (p->count-off-3-ac3_off)/
2027 p->buf[off+1] = nframes;
2028 p->buf[off+2] = (ac3_off >> 8)& 0xFF;
2029 p->buf[off+3] = (ac3_off)& 0xFF;
2031 ac3_off += nframes * ai.framesize - p->count;
2036 if (p->ps) ps_pes(p);
2037 else p->func(p->buf, p->count, p->data);
2047 if (p->cid == PRIVATE_STREAM1 && (streamid & 0xF8)==0x80 ){
2049 p->buf[9] = streamid;
2051 p->buf[11] = (ac3_off >> 8)& 0xFF;
2052 p->buf[12] = (ac3_off)& 0xFF;
2065 static void write_ipack(ipack *p, uint8_t *data, int count)
2068 uint8_t headr[3] = { 0x00, 0x00, 0x01} ;
2072 if (trans_pts_dts(p->pts) > trans_pts_dts(p->last_pts))
2073 memcpy(p->last_pts, p->pts, 5);
2075 memcpy(p->buf+p->count, headr, 3);
2078 if ( p->size == p->size_orig && p->plength &&
2079 (diff = 6+p->plength - p->found + p->count +count) > p->size &&
2080 diff < 3*p->size/2){
2083 // fprintf(stderr,"size: %d \n",p->size);
2086 if (p->cid == PRIVATE_STREAM1 && p->count == p->hlength+9){
2087 if ((data[0] & 0xF8) != 0x80){
2090 ac3_off = get_ac3info(data, count, &ai,0);
2091 if (ac3_off>=0 && ai.framesize){
2092 p->buf[p->count] = 0x80;
2093 p->buf[p->count+1] = (p->size - p->count
2096 p->buf[p->count+2] = (ac3_off >> 8)& 0xFF;
2097 p->buf[p->count+3] = (ac3_off)& 0xFF;
2104 if (p->count + count < p->size){
2105 memcpy(p->buf+p->count, data, count);
2108 int rest = p->size - p->count;
2109 if (rest < 0) rest = 0;
2110 memcpy(p->buf+p->count, data, rest);
2112 // fprintf(stderr,"count: %d \n",p->count);
2114 if (count - rest > 0)
2115 write_ipack(p, data+rest, count-rest);
2119 void instant_repack (uint8_t *buf, int count, ipack *p)
2126 while (c < count && (p->mpeg == 0 ||
2127 (p->mpeg == 1 && p->found < 7) ||
2128 (p->mpeg == 2 && p->found < 9))
2129 && (p->found < 5 || !p->done)){
2130 switch ( p->found ){
2133 if (buf[c] == 0x00) p->found++;
2138 if (buf[c] == 0x01) p->found++;
2139 else if (buf[c] == 0){
2141 } else p->found = 0;
2147 case PROG_STREAM_MAP:
2148 case PRIVATE_STREAM2:
2149 case PROG_STREAM_DIR:
2152 case PADDING_STREAM :
2153 case DSM_CC_STREAM :
2154 case ISO13522_STREAM:
2156 case PRIVATE_STREAM1:
2157 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
2158 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
2172 pl = (unsigned short *) (buf+c);
2173 p->plength = ntohs(*pl);
2174 p->plen[0] = buf[c];
2176 p->plen[1] = buf[c];
2180 p->plen[0] = buf[c];
2186 p->plen[1] = buf[c];
2188 pl = (unsigned short *) p->plen;
2189 p->plength = ntohs(*pl);
2199 if ( (p->flag1 & 0xC0) == 0x80 ) p->mpeg = 2;
2210 if ( !p->done && p->mpeg == 2){
2218 if ( !p->done && p->mpeg == 2){
2219 p->hlength = buf[c];
2232 if (c == count) return;
2234 if (!p->plength) p->plength = MMAX_PLENGTH-6;
2237 if ( p->done || ((p->mpeg == 2 && p->found >= 9) ||
2238 (p->mpeg == 1 && p->found >= 7)) ){
2241 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
2242 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
2243 case PRIVATE_STREAM1:
2245 if (p->mpeg == 2 && p->found == 9){
2246 write_ipack(p, &p->flag1, 1);
2247 write_ipack(p, &p->flag2, 1);
2248 write_ipack(p, &p->hlength, 1);
2251 if (p->mpeg == 1 && p->found == 7){
2252 write_ipack(p, &p->flag1, 1);
2256 if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) &&
2258 while (c < count && p->found < 14){
2259 p->pts[p->found-9] = buf[c];
2260 write_ipack(p, buf+c, 1);
2264 if (c == count) return;
2267 if (p->mpeg == 1 && p->which < 2000){
2269 if (p->found == 7) {
2270 p->check = p->flag1;
2274 while (!p->which && c < count &&
2277 write_ipack(p, buf+c, 1);
2283 if ( c == count) return;
2285 if ( (p->check & 0xC0) == 0x40 && !p->which){
2287 write_ipack(p, buf+c, 1);
2293 if ( c == count) return;
2295 write_ipack(p, buf+c, 1);
2300 if ( c == count) return;
2305 write_ipack(p, buf+c, 1);
2310 if ( c == count) return;
2313 if ( (p->check & 0x30) && p->check != 0xFF){
2314 p->flag2 = (p->check & 0xF0) << 2;
2315 p->pts[0] = p->check;
2319 if ( c == count) return;
2321 if ((p->flag2 & PTS_DTS_FLAGS)
2325 p->pts[p->which-2] =
2327 write_ipack(p,buf+c,1);
2333 if ( c == count) return;
2334 } else if ((p->flag2 & PTS_DTS_FLAGS)
2342 write_ipack(p,buf+c,1);
2348 if ( c == count) return;
2355 while (c < count && p->found < p->plength+6){
2357 if (l+p->found > p->plength+6)
2358 l = p->plength+6-p->found;
2359 write_ipack(p, buf+c, l);
2369 if( p->found + count - c < p->plength+6){
2370 p->found += count-c;
2373 c += p->plength+6 - p->found;
2374 p->found = p->plength+6;
2378 if (p->plength && p->found == p->plength+6) {
2382 instant_repack(buf+c, count-c, p);
2388 void write_out_es(uint8_t *buf, int count,void *priv)
2390 ipack *p = (ipack *) priv;
2391 uint8_t payl = buf[8]+9+p->start-1;
2393 write(p->fd, buf+payl, count-payl);
2397 void write_out_pes(uint8_t *buf, int count,void *priv)
2399 ipack *p = (ipack *) priv;
2400 write(p->fd, buf, count);
2405 int64_t ts_demux(int fdin, int fdv_out,int fda_out,uint16_t pida,
2406 uint16_t pidv, int es)
2408 uint8_t buf[IN_SIZE];
2409 uint8_t mbuf[TS_SIZE];
2424 if (fdin != STDIN_FILENO) verb = 1;
2427 length = lseek(fdin, 0, SEEK_END);
2428 lseek(fdin,0,SEEK_SET);
2432 find_avpids(fdin, &pidv, &pida);
2435 init_ipack(&pa, IPACKS,write_out_es, 0);
2436 init_ipack(&pv, IPACKS,write_out_es, 0);
2438 init_ipack(&pa, IPACKS,write_out_pes, 0);
2439 init_ipack(&pv, IPACKS,write_out_pes, 0);
2443 pa.data = (void *)&pa;
2444 pv.data = (void *)&pv;
2446 count = save_read(fdin,mbuf,TS_SIZE);
2447 if (count) l+=count;
2448 for ( i = 0; i < 188 ; i++){
2449 if ( mbuf[i] == 0x47 ) break;
2452 fprintf(stderr,"Not a TS\n");
2455 memcpy(buf,mbuf+i,TS_SIZE-i);
2456 count = save_read(fdin,mbuf,i);
2457 if (count) l+=count;
2458 memcpy(buf+TS_SIZE-i,mbuf,i);
2464 count = save_read(fdin,buf+i,IN_SIZE-i)+i;
2465 if (count) l+=count;
2466 if (verb && perc >last_perc){
2467 perc = (100*l)/length;
2468 fprintf(stderr,"Reading TS %d %%\r",perc);
2472 for( i = 0; i < count; i+= TS_SIZE){
2475 if ( count - i < TS_SIZE) break;
2477 pid = get_pid(buf+i+1);
2478 if (!(buf[3+i]&0x10)) // no payload?
2480 if ( buf[1+i]&0x80){
2481 fprintf(stderr,"Error in TS for PID: %d\n",
2492 if ( buf[3+i] & 0x20) { // adaptation field?
2496 if ( buf[1+i]&0x40) {
2497 if (p->plength == MMAX_PLENGTH-6){
2498 p->plength = p->found-6;
2505 !p->start && (sb[7] & PTS_DTS_FLAGS)){
2506 uint8_t *pay = sb+sb[8]+9;
2507 int l = TS_SIZE - 13 - off - sb[8];
2510 get_vinfo( pay, l,&p->vi,1)+1) >0
2512 vpts = trans_pts_dts(sb+9);
2513 printf("vpts : %fs\n",
2516 if ( pid == pida && es==1 &&
2518 get_ainfo( pay, l,&p->ai,1)+1) >0
2520 apts = trans_pts_dts(sb+9);
2521 printf("apts : %fs\n",
2524 if ( pid == pida && es==2 &&
2526 get_ac3info( pay, l,&p->ai,1)+1) >0
2528 apts = trans_pts_dts(sb+9);
2529 printf("apts : %fs\n",
2536 instant_repack(buf+4+off+i, TS_SIZE-4-off, p);
2545 void ts2es_opt(int fdin, uint16_t pidv, ipack *p, int verb)
2547 uint8_t buf[IN_SIZE];
2548 uint8_t mbuf[TS_SIZE];
2558 length = lseek(fdin, 0, SEEK_END);
2559 lseek(fdin,0,SEEK_SET);
2562 count = save_read(fdin,mbuf,TS_SIZE);
2563 if (count) l+=count;
2564 for ( i = 0; i < 188 ; i++){
2565 if ( mbuf[i] == 0x47 ) break;
2568 fprintf(stderr,"Not a TS\n");
2571 memcpy(buf,mbuf+i,TS_SIZE-i);
2572 count = save_read(fdin,mbuf,i);
2573 if (count) l+=count;
2574 memcpy(buf+TS_SIZE-i,mbuf,i);
2580 count = save_read(fdin,buf+i,IN_SIZE-i)+i;
2581 if (count) l+=count;
2582 if (verb && perc >last_perc){
2583 perc = (100*l)/length;
2584 fprintf(stderr,"Reading TS %d %%\r",perc);
2588 for( i = 0; i < count; i+= TS_SIZE){
2591 if ( count - i < TS_SIZE) break;
2593 pid = get_pid(buf+i+1);
2594 if (!(buf[3+i]&0x10)) // no payload?
2596 if ( buf[1+i]&0x80){
2597 fprintf(stderr,"Error in TS for PID: %d\n",
2604 if ( buf[3+i] & 0x20) { // adaptation field?
2608 if ( buf[1+i]&0x40) {
2609 if (p->plength == MMAX_PLENGTH-6){
2610 p->plength = p->found-6;
2617 instant_repack(buf+4+off+i, TS_SIZE-4-off, p);
2624 void ts2es(int fdin, uint16_t pidv)
2629 init_ipack(&p, IPACKS,write_out_es, 0);
2630 p.fd = STDOUT_FILENO;
2631 p.data = (void *)&p;
2633 if (fdin != STDIN_FILENO) verb = 1;
2635 ts2es_opt(fdin, pidv, &p, verb);
2639 void change_aspect(int fdin, int fdout, int aspect)
2647 neof = read_ps(fdin,&ps);
2648 write_ps(fdout,&ps);
2649 for (i = 0; i < ps.npes; i++){
2655 read_pes(fdin, &pes);
2657 buf = pes.pes_pckt_data;
2659 switch (pes.stream_id){
2660 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
2668 if (buf[c] == 0x00 &&
2678 write_pes(fdout,&pes);
2680 } while( neof > 0 );