]> git.vomp.tv Git - vompserver.git/blob - libdvbmpeg/transform.c
Initial import
[vompserver.git] / libdvbmpeg / transform.c
1 /*
2  *  dvb-mpegtools for the Siemens Fujitsu DVB PCI card
3  *
4  * Copyright (C) 2000, 2001 Marcus Metzler 
5  *            for convergence integrated media GmbH
6  * Copyright (C) 2002  Marcus Metzler 
7  * 
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.
12  * 
13
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.
18  * 
19
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
24  * 
25
26  * The author can be reached at marcus@convergence.de, 
27
28  * the project's page is at http://linuxtv.org/dvb/
29  */
30
31
32 #include "transform.h"
33 #include <stdlib.h>
34 #include <string.h>
35 #include "ctools.h"
36
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
62 };
63
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
89 };
90
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
136 };
137
138 static uint32_t
139 calc_crc32 (const uint8_t *sec, uint8_t len)
140 {
141   int i;
142   uint32_t crc = 0xffffffff;
143
144   for (i = 0; i < len; i++)
145     crc = (crc << 8) ^ crc_table[((crc >> 24) ^ *sec++) & 0xff];
146
147   return crc;
148 }
149
150
151 uint64_t trans_pts_dts(uint8_t *pts)
152 {
153         uint64_t wts;
154         
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));
163         return wts;
164 }
165
166
167 void get_pespts(uint8_t *av_pts,uint8_t *pts)
168 {
169         
170         pts[0] = 0x21 | 
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);
179 }
180
181 uint16_t get_pid(uint8_t *pid)
182 {
183         uint16_t pp = 0;
184
185         pp = (pid[0] & PID_MASK_HI)<<8;
186         pp |= pid[1];
187
188         return pp;
189 }
190
191 int write_ts_header(uint16_t pid, uint8_t *counter, int pes_start, 
192                     uint8_t *buf, uint8_t length)
193 {
194         int i;
195         int c = 0;
196         int fill;
197         uint8_t tshead[4] = { 0x47, 0x00, 0x00, 0x10}; 
198         
199
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);
207         c+=4;
208
209
210         if (fill){
211                 buf[4] = fill-1;
212                 c++;
213                 if (fill >1){
214                         buf[5] = 0x00;
215                         c++;
216                 }
217                 for ( i = 6; i < fill+4; i++){
218                         buf[i] = 0xFF;
219                         c++;
220                 }
221         }
222
223         return c;
224 }
225
226
227 int write_pes_header(uint8_t id,int length , long PTS, uint8_t *obuf, 
228                      int stuffing)
229 {
230         uint8_t le[2];
231         uint8_t dummy[3];
232         uint8_t *pts;
233         uint8_t ppts[5];
234         long lpts;
235         int c;
236         uint8_t headr[3] = {0x00, 0x00, 0x01};
237         
238         lpts = htonl(PTS);
239         pts = (uint8_t *) &lpts;
240         
241         get_pespts(pts,ppts);
242
243         c = 0;
244         memcpy(obuf+c,headr,3);
245         c += 3;
246         memcpy(obuf+c,&id,1);
247         c++;
248
249         le[0] = 0;
250         le[1] = 0;
251         length -= 6+stuffing;
252
253         le[0] |= ((uint8_t)(length >> 8) & 0xFF); 
254         le[1] |= ((uint8_t)(length) & 0xFF); 
255         memcpy(obuf+c,le,2);
256         c += 2;
257
258         if (id == PADDING_STREAM){
259                 memset(obuf+c,0xff,length);
260                 c+= length;
261                 return c;
262         }
263
264         dummy[0] = 0x80;
265         dummy[1] = 0;
266         dummy[2] = 0;
267         if (PTS){
268                 dummy[1] |= PTS_ONLY;
269                 dummy[2] = 5+stuffing;
270         }
271         memcpy(obuf+c,dummy,3);
272         c += 3;
273         memset(obuf+c,0xFF,stuffing);
274
275         if (PTS){
276                 memcpy(obuf+c,ppts,5);
277                 c += 5;
278         }
279         
280         return c;
281 }
282
283
284 void init_p2p(p2p *p, void (*func)(uint8_t *buf, int count, void *p), 
285               int repack){
286         p->found = 0;
287         p->cid = 0;
288         p->mpeg = 0;
289         memset(p->buf,0,MMAX_PLENGTH);
290         p->done = 0;
291         p->fd1 = -1;
292         p->func = func;
293         p->bigend_repack = 0;
294         p->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));
299         } else {
300                 fprintf(stderr, "Repack size %d is out of range\n",repack);
301                 exit(1);
302         }
303 }
304
305
306
307 void pes_repack(p2p *p)
308 {
309         int count = 0;
310         int repack = p->repack;
311         int rest = p->plength;
312         uint8_t buf[MAX_PLENGTH];
313         int bfill = 0;
314         int diff;
315         uint16_t length;
316
317         if (rest < 0) {
318                 fprintf(stderr,"Error in repack\n");
319                 return;
320         }
321
322         if (!repack){
323                 fprintf(stderr,"forgot to set repack size\n");
324                 return;
325         }
326
327         if (p->plength == repack){
328                 memcpy(p->buf+4,(char *)&p->bigend_repack,2);
329                 p->func(p->buf, repack+6, p);
330                 return;
331         }
332
333         buf[0] = 0x00;
334         buf[1] = 0x00;
335         buf[2] = 0x01;
336         buf[3] = p->cid;
337         memcpy(buf+4,(char *)&p->bigend_repack,2);
338         memset(buf+6,0,MAX_PLENGTH-6);
339
340         if (p->mpeg == 2){
341
342                 if ( rest > repack){
343                         memcpy(p->buf+4,(char *)&p->bigend_repack,2);
344                         p->func(p->buf, repack+6, p);
345                         count += repack+6;
346                         rest -= repack;
347                 } else {
348                         memcpy(buf,p->buf,9+p->hlength);
349                         bfill = p->hlength;
350                         count += 9+p->hlength;
351                         rest -= p->hlength+3;
352                 }
353
354                 while (rest >= repack-3){
355                         memset(buf+6,0,MAX_PLENGTH-6);
356                         buf[6] = 0x80;
357                         buf[7] = 0x00;
358                         buf[8] = 0x00;
359                         memcpy(buf+9,p->buf+count,repack-3);
360                         rest -= repack-3;
361                         count += repack-3;
362                         p->func(buf, repack+6, p);
363                 }
364                 
365                 if (rest){
366                         diff = repack - 3 - rest - bfill;
367                         if (!bfill){
368                                 buf[6] = 0x80;
369                                 buf[7] = 0x00;
370                                 buf[8] = 0x00;
371                         }
372
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);
380                         } else {
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);
385                                 bfill += rest+9;
386                                 write_pes_header( PADDING_STREAM, diff, 0,
387                                                   buf+bfill, 0);
388                         }
389                         p->func(buf, repack+6, p);
390                 }
391         }       
392
393         if (p->mpeg == 1){
394
395                 if ( rest > repack){
396                         memcpy(p->buf+4,(char *)&p->bigend_repack,2);
397                         p->func(p->buf, repack+6, p);
398                         count += repack+6;
399                         rest -= repack;
400                 } else {
401                         memcpy(buf,p->buf,6+p->hlength);
402                         bfill = p->hlength;
403                         count += 6;
404                         rest -= p->hlength;
405                 }
406
407                 while (rest >= repack-1){
408                         memset(buf+6,0,MAX_PLENGTH-6);
409                         buf[6] = 0x0F;
410                         memcpy(buf+7,p->buf+count,repack-1);
411                         rest -= repack-1;
412                         count += repack-1;
413                         p->func(buf, repack+6, p);
414                 }
415                 
416
417                 if (rest){
418                         diff = repack - 1 - rest - bfill;
419
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);
425                                 if (!bfill){
426                                         buf[6+diff] = 0x0F;
427                                 }
428                                 memcpy(buf+7+diff,p->buf+count,rest+bfill);
429                         } else {
430                                 length = rest+ bfill+1; 
431                                 buf[4] = (uint8_t)((length & 0xFF00) >> 8);
432                                 buf[5] = (uint8_t)(length & 0x00FF);
433                                 if (!bfill){
434                                         buf[6] = 0x0F;
435                                         memcpy(buf+7,p->buf+count,rest);
436                                         bfill = rest+7;
437                                 } else {
438                                         memcpy(buf+6,p->buf+count,rest+bfill);
439                                         bfill += rest+6;
440                                 }
441                                 write_pes_header( PADDING_STREAM, diff, 0,
442                                                   buf+bfill, 0);
443                         }
444                         p->func(buf, repack+6, p);
445                 }
446         }       
447 }
448
449
450
451
452
453
454
455
456 int filter_pes (uint8_t *buf, int count, p2p *p, int (*func)(p2p *p))
457 {
458
459         int l;
460         unsigned short *pl;
461         int c=0;
462         int ret = 1;
463
464         uint8_t headr[3] = { 0x00, 0x00, 0x01} ;
465
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)){
470                 switch ( p->found ){
471                 case 0:
472                 case 1:
473                         if (buf[c] == 0x00) p->found++;
474                         else {
475                                 if (p->fd1 >= 0)
476                                         write(p->fd1,buf+c,1);
477                                 p->found = 0;
478                         }
479                         c++;
480                         break;
481                 case 2:
482                         if (buf[c] == 0x01) p->found++;
483                         else if (buf[c] == 0){
484                                 p->found = 2;
485                         } else {        
486                                 if (p->fd1 >= 0)
487                                         write(p->fd1,buf+c,1);
488                                 p->found = 0;
489                         }
490                         c++;
491                         break;
492                 case 3:
493                         p->cid = 0;
494                         switch (buf[c]){
495                         case PROG_STREAM_MAP:
496                         case PRIVATE_STREAM2:
497                         case PROG_STREAM_DIR:
498                         case ECM_STREAM     :
499                         case EMM_STREAM     :
500                         case PADDING_STREAM :
501                         case DSM_CC_STREAM  :
502                         case ISO13522_STREAM:
503                                 if (p->fd1 >= 0)
504                                         write(p->fd1,buf+c,1);
505                                 p->done = 1;
506                         case PRIVATE_STREAM1:
507                         case VIDEO_STREAM_S ... VIDEO_STREAM_E:
508                         case AUDIO_STREAM_S ... AUDIO_STREAM_E:
509                                 p->found++;
510                                 p->cid = buf[c];
511                                 c++;
512                                 break;
513                         default:
514                                 if (p->fd1 >= 0)
515                                         write(p->fd1,buf+c,1);
516                                 p->found = 0;
517                                 break;
518                         }
519                         break;
520                         
521
522                 case 4:
523                         if (count-c > 1){
524                                 pl = (unsigned short *) (buf+c);
525                                 p->plength =  ntohs(*pl);
526                                 p->plen[0] = buf[c];
527                                 c++;
528                                 p->plen[1] = buf[c];
529                                 c++;
530                                 p->found+=2;
531                         } else {
532                                 p->plen[0] = buf[c];
533                                 p->found++;
534                                 return 1;
535                         }
536                         break;
537                 case 5:
538                         p->plen[1] = buf[c];
539                         c++;
540                         pl = (unsigned short *) p->plen;
541                         p->plength = ntohs(*pl);
542                         p->found++;
543                         break;
544
545
546                 case 6:
547                         if (!p->done){
548                                 p->flag1 = buf[c];
549                                 c++;
550                                 p->found++;
551                                 if ( (p->flag1 & 0xC0) == 0x80 ) p->mpeg = 2;
552                                 else {
553                                         p->hlength = 0;
554                                         p->which = 0;
555                                         p->mpeg = 1;
556                                         p->flag2 = 0;
557                                 }
558                         }
559                         break;
560
561                 case 7:
562                         if ( !p->done && p->mpeg == 2){
563                                 p->flag2 = buf[c];
564                                 c++;
565                                 p->found++;
566                         }       
567                         break;
568
569                 case 8:
570                         if ( !p->done && p->mpeg == 2){
571                                 p->hlength = buf[c];
572                                 c++;
573                                 p->found++;
574                         }
575                         break;
576                         
577                 default:
578
579                         break;
580                 }
581         }
582
583         if (!p->plength) p->plength = MMAX_PLENGTH-6;
584
585
586         if ( p->done || ((p->mpeg == 2 && p->found >= 9)  || 
587              (p->mpeg == 1 && p->found >= 7)) ){
588                 switch (p->cid){
589                         
590                 case AUDIO_STREAM_S ... AUDIO_STREAM_E:                 
591                 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
592                 case PRIVATE_STREAM1:
593
594                         memcpy(p->buf, headr, 3);
595                         p->buf[3] = p->cid;
596                         memcpy(p->buf+4,p->plen,2);
597
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;
602                         }
603
604                         if (p->mpeg == 1 && p->found == 7){
605                                 p->buf[6] = p->flag1;
606                         }
607
608
609                         if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) &&  
610                             p->found < 14){
611                                 while (c < count && p->found < 14){
612                                         p->pts[p->found-9] = buf[c];
613                                         p->buf[p->found] = buf[c];
614                                         c++;
615                                         p->found++;
616                                 }
617                                 if (c == count) return 1;
618                         }
619
620                         if (p->mpeg == 1 && p->which < 2000){
621
622                                 if (p->found == 7) {
623                                         p->check = p->flag1;
624                                         p->hlength = 1;
625                                 }
626
627                                 while (!p->which && c < count && 
628                                        p->check == 0xFF){
629                                         p->check = buf[c];
630                                         p->buf[p->found] = buf[c];
631                                         c++;
632                                         p->found++;
633                                         p->hlength++;
634                                 }
635
636                                 if ( c == count) return 1;
637                                 
638                                 if ( (p->check & 0xC0) == 0x40 && !p->which){
639                                         p->check = buf[c];
640                                         p->buf[p->found] = buf[c];
641                                         c++;
642                                         p->found++;
643                                         p->hlength++;
644
645                                         p->which = 1;
646                                         if ( c == count) return 1;
647                                         p->check = buf[c];
648                                         p->buf[p->found] = buf[c];
649                                         c++;
650                                         p->found++;
651                                         p->hlength++;
652                                         p->which = 2;
653                                         if ( c == count) return 1;
654                                 }
655
656                                 if (p->which == 1){
657                                         p->check = buf[c];
658                                         p->buf[p->found] = buf[c];
659                                         c++;
660                                         p->found++;
661                                         p->hlength++;
662                                         p->which = 2;
663                                         if ( c == count) return 1;
664                                 }
665                                 
666                                 if ( (p->check & 0x30) && p->check != 0xFF){
667                                         p->flag2 = (p->check & 0xF0) << 2;
668                                         p->pts[0] = p->check;
669                                         p->which = 3;
670                                 } 
671
672                                 if ( c == count) return 1;
673                                 if (p->which > 2){
674                                         if ((p->flag2 & PTS_DTS_FLAGS)
675                                             == PTS_ONLY){
676                                                 while (c < count && 
677                                                        p->which < 7){
678                                                         p->pts[p->which-2] =
679                                                                 buf[c];
680                                                         p->buf[p->found] = 
681                                                                 buf[c];
682                                                         c++;
683                                                         p->found++;
684                                                         p->which++;
685                                                         p->hlength++;
686                                                 }
687                                                 if ( c == count) return 1;
688                                         } else if ((p->flag2 & PTS_DTS_FLAGS) 
689                                                    == PTS_DTS){
690                                                 while (c < count && 
691                                                        p->which< 12){
692                                                         if (p->which< 7)
693                                                                 p->pts[p->which
694                                                                       -2] =
695                                                                         buf[c];
696                                                         p->buf[p->found] = 
697                                                                 buf[c];
698                                                         c++;
699                                                         p->found++;
700                                                         p->which++;
701                                                         p->hlength++;
702                                                 }
703                                                 if ( c == count) return 1;
704                                         }
705                                         p->which = 2000;
706                                 }
707                                                         
708                         }
709
710                         while (c < count && p->found < p->plength+6){
711                                 l = count -c;
712                                 if (l+p->found > p->plength+6)
713                                         l = p->plength+6-p->found;
714                                 memcpy(p->buf+p->found, buf+c, l);
715                                 p->found += l;
716                                 c += l;
717                         }                       
718                         if(p->found == p->plength+6){
719                                 if (func(p)){ 
720                                         if (p->fd1 >= 0){
721                                                 write(p->fd1,p->buf,
722                                                       p->plength+6);
723                                         } 
724                                 } else ret = 0;
725                         }
726                         break;
727                 }
728
729
730                 if ( p->done ){
731                         if( p->found + count - c < p->plength+6){
732                                 p->found += count-c;
733                                 c = count;
734                         } else {
735                                 c += p->plength+6 - p->found;
736                                 p->found = p->plength+6;
737                         }
738                 }
739
740                 if (p->plength && p->found == p->plength+6) {
741                         p->found = 0;
742                         p->done = 0;
743                         p->plength = 0;
744                         memset(p->buf, 0, MAX_PLENGTH);
745                         if (c < count)
746                                 return filter_pes(buf+c, count-c, p, func);
747                 }
748         }
749         return ret;
750 }
751
752
753 #define SIZE 4096
754
755
756 int audio_pes_filt(p2p *p)
757 {
758         uint8_t off;
759
760         switch(p->cid){
761         case PRIVATE_STREAM1:
762                 if ( p->cid == p->filter) {
763                         off = 9+p->buf[8];
764                         if (p->buf[off] == p->subid){
765                                 return 1;
766                         }
767                 }
768                 break;
769         
770         case AUDIO_STREAM_S ... AUDIO_STREAM_E:                 
771                 if ( p->cid == p->filter)
772                         return 1;
773                 break;
774
775         default:
776                 return 1;
777                 break;
778         }
779         return 0;
780 }
781
782
783 void filter_audio_from_pes(int fdin, int fdout, uint8_t id, uint8_t subid)
784 {
785                 p2p p;
786                 int count = 1;
787                 uint8_t buf[2048];
788
789                 init_p2p(&p, NULL, 2048);
790                 p.fd1 = -1;
791                 p.filter = id;
792                 p.subid = subid;
793
794                 while (count > 0){
795                         count = read(fdin,buf,2048);
796                         if(filter_pes(buf,count,&p,audio_pes_filt))
797                                 write(fdout,buf,2048);
798                 }
799 }
800
801
802 void pes_filt(p2p *p)
803 {
804         int factor = p->mpeg-1;
805
806         if ( p->cid == p->filter) {
807                 if (p->es)
808                         write(p->fd1,p->buf+p->hlength+6+3*factor, 
809                               p->plength-p->hlength-3*factor);
810                 else
811                         write(p->fd1,p->buf,p->plength+6);
812         }
813 }
814
815 void extract_from_pes(int fdin, int fdout, uint8_t id, int es)
816 {
817                 p2p p;
818                 int count = 1;
819                 uint8_t buf[SIZE];
820
821                 init_p2p(&p, NULL, 2048);
822                 p.fd1 = fdout;
823                 p.filter = id;
824                 p.es = es;
825
826                 while (count > 0){
827                         count = read(fdin,buf,SIZE);
828                         get_pes(buf,count,&p,pes_filt);
829                 }
830 }
831
832
833 void pes_dfilt(p2p *p)
834 {
835         int factor = p->mpeg-1;
836         int fd =0;
837         int head=0;
838         int type = NOPES;
839         int streamid;
840         int c = 6+p->hlength+3*factor;
841         
842
843         switch ( p->cid ) {
844         case PRIVATE_STREAM1:
845                 streamid = p->buf[c];
846                 head = 4; 
847                 if ((streamid & 0xF8) == 0x80+p->es-1){
848                         fd = p->fd1;
849                         type = AC3;
850                 }
851                 break;
852         case AUDIO_STREAM_S ... AUDIO_STREAM_E:                 
853                 fd = p->fd1;
854                 type = AUDIO;
855                 break;
856         case VIDEO_STREAM_S ... VIDEO_STREAM_E:
857                 fd = p->fd2;
858                 type = VIDEO;
859                 break;
860         }
861         
862         if (p->es && !p->startv && type == VIDEO){
863                 int found = 0;
864                 
865                 if  ( p->flag2 & PTS_DTS ) 
866                         p->vpts = trans_pts_dts(p->pts); 
867                 else return;
868
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 &&
873                              p->buf[c+3] == 0xb3) 
874                                 found = 1;
875                         else c++;
876                 }
877                 if (found){
878                         p->startv = 1;
879                         write(fd, p->buf+c, p->plength+6-c);
880                 }
881                 fd = 0;
882         } 
883
884                 
885         if ( p->es && !p->starta && type == AUDIO){
886                 int found = 0;
887                 if  ( p->flag2 & PTS_DTS ) 
888                         p->apts = trans_pts_dts(p->pts);  
889                 else return;
890
891                 if (p->startv)
892                         while ( !found && c+1 < p->plength+6){
893                                 if ( p->buf[c] == 0xFF && 
894                                      (p->buf[c+1] & 0xF8) == 0xF8)
895                                         found = 1;
896                                 else c++;
897                         }
898                 if (found){
899                         p->starta = 1;
900                         write(fd, p->buf+c, p->plength+6-c);
901                 }
902                 fd = 0;
903         } 
904
905         if ( p->es && !p->starta && type == AC3){
906                 if  ( p->flag2 & PTS_DTS ) 
907                         p->apts = trans_pts_dts(p->pts);  
908                 else return;
909
910                 if (p->startv){
911                         c+= ((p->buf[c+2] << 8)| p->buf[c+3]);
912                         p->starta = 1;
913                         write(fd, p->buf+c, p->plength+6-c);
914                 }
915                 fd = 0;
916         } 
917
918
919         if (fd){
920                 if (p->es)
921                         write(fd,p->buf+p->hlength+6+3*factor+head, 
922                               p->plength-p->hlength-3*factor-head);
923                 else
924                         write(fd,p->buf,p->plength+6);
925         }
926
927
928 int64_t pes_dmx( int fdin, int fdouta, int fdoutv, int es)
929 {
930         p2p p;
931         int count = 1;
932         uint8_t buf[SIZE];
933         uint64_t length = 0;
934         uint64_t l = 0;
935         int verb = 0;
936         int percent, oldPercent = -1;
937         
938         init_p2p(&p, NULL, 2048);
939         p.fd1 = fdouta;
940         p.fd2 = fdoutv;
941         p.es = es;
942         p.startv = 0;
943         p.starta = 0;
944         p.apts=-1;
945         p.vpts=-1;
946         
947         if (fdin != STDIN_FILENO) verb = 1; 
948         
949         if (verb) {
950                 length = lseek(fdin, 0, SEEK_END);
951                 lseek(fdin,0,SEEK_SET);
952         }
953         
954         while (count > 0){
955                 count = read(fdin,buf,SIZE);
956                 l += count;
957                 if (verb){
958                         percent = 100 * l / length;
959                 
960                         if (percent != oldPercent) {
961                                 fprintf(stderr, "Demuxing %d %%\r", percent);
962                                 oldPercent = percent;
963                         }
964                 }
965                 get_pes(buf,count,&p,pes_dfilt);
966         }
967         
968         return (int64_t)p.vpts - (int64_t)p.apts;
969         
970 }
971
972
973 /* SV: made non-static */
974 void pes_in_ts(p2p *p)
975 {
976         int l, pes_start;
977         uint8_t obuf[TS_SIZE];
978         long int c = 0;
979         int length = p->plength+6;
980         uint16_t pid;
981         uint8_t *counter;
982         pes_start = 1;
983         switch ( p->cid ) {
984         case AUDIO_STREAM_S ... AUDIO_STREAM_E:                 
985                 pid = p->pida;
986                 counter = &p->acounter;
987                 break;
988         case VIDEO_STREAM_S ... VIDEO_STREAM_E:
989                 pid = p->pidv;
990                 counter = &p->acounter;
991
992                 tspid0[3] |= (p->count0++) 
993                         & 0x0F ;
994                 tspid1[3] |= (p->count1++) 
995                         & 0x0F ;
996         
997                 tspid1[24]  = p->pidv;
998                 tspid1[23] |= (p->pidv >> 8) & 0x3F;
999                 tspid1[29]  = p->pida;
1000                 tspid1[28] |= (p->pida >> 8) & 0x3F;
1001                 
1002                 p->func(tspid0,188,p);
1003                 p->func(tspid1,188,p);
1004                 break;
1005         default:
1006                 return;
1007         }
1008
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
1013                                              , obuf, TS_SIZE-4);
1014                         memcpy(obuf+l, p->buf+c, TS_SIZE-l);
1015                         c += TS_SIZE-l;
1016                 } else { 
1017                         l = write_ts_header(pid, counter, pes_start
1018                                              , obuf, length-c);
1019                         memcpy(obuf+l, p->buf+c, TS_SIZE-l);
1020                         c = length;
1021                 }
1022                 p->func(obuf,188,p);
1023                 pes_start = 0;
1024         }
1025 }
1026
1027 static
1028 void write_out(uint8_t *buf, int count,void  *p)
1029 {
1030         write(STDOUT_FILENO, buf, count);
1031 }
1032
1033
1034 void pes_to_ts2( int fdin, int fdout, uint16_t pida, uint16_t pidv)
1035 {
1036         p2p p;
1037         int count = 1;
1038         uint8_t buf[SIZE];
1039         uint64_t length = 0;
1040         uint64_t l = 0;
1041         int verb = 0;
1042         
1043         init_p2p(&p, NULL, 2048);
1044         p.fd1 = fdout;
1045         p.pida = pida;
1046         p.pidv = pidv;
1047         p.acounter = 0;
1048         p.vcounter = 0;
1049         p.count1 = 0;
1050         p.count0 = 0;
1051         p.func = write_out;
1052                 
1053         if (fdin != STDIN_FILENO) verb = 1; 
1054
1055         if (verb) {
1056                 length = lseek(fdin, 0, SEEK_END);
1057                 lseek(fdin,0,SEEK_SET);
1058         }
1059
1060         while (count > 0){
1061                 count = read(fdin,buf,SIZE);
1062                 l += count;
1063                 if (verb)
1064                         fprintf(stderr,"Writing TS  %2.2f %%\r",
1065                                 100.*l/length);
1066
1067                 get_pes(buf,count,&p,pes_in_ts);
1068         }
1069                 
1070 }
1071
1072
1073 #define IN_SIZE TS_SIZE*10
1074 void find_avpids(int fd, uint16_t *vpid, uint16_t *apid)
1075 {
1076         uint8_t buf[IN_SIZE];
1077         int count;
1078         int i;  
1079         int off =0;
1080
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){
1086                                         off = 0;
1087                                         if ( buf[3+i] & 0x20)//adapt field?
1088                                                 off = buf[4+i] + 1;
1089                                         switch(buf[i+7+off]){
1090                                         case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1091                                                 *vpid = get_pid(buf+i+1);
1092                                                 break;
1093                                         case PRIVATE_STREAM1:
1094                                         case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1095                                                 *apid = get_pid(buf+i+1);
1096                                                 break;
1097                                         }
1098                                 }
1099                                 i += 187;
1100                         }
1101                         if (*apid != 0 && *vpid != 0) break;
1102                 }
1103         }
1104 }
1105
1106 void find_bavpids(uint8_t *buf, int count, uint16_t *vpid, uint16_t *apid)
1107 {
1108         int i;  
1109         int founda = 0;
1110         int foundb = 0;
1111         int off = 0;
1112         
1113         *vpid = 0;
1114         *apid = 0;
1115         for (i = 0; i < count-7; i++){
1116                 if (buf[i] == 0x47){
1117                         if ((buf[i+1] & 0xF0) == 0x40){
1118                                 off = 0;
1119                                 if ( buf[3+i] & 0x20)  // adaptation field?
1120                                         off = buf[4+i] + 1;
1121                                 
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);
1128                                                 foundb=1;
1129                                                 break;
1130                                         case PRIVATE_STREAM1:
1131                                         case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1132                                                 *apid = get_pid(buf+i+1);
1133                                                 founda=1;
1134                                                 break;
1135                                         }
1136                                 }
1137                         }
1138                         i += 187;
1139                 }
1140                 if (founda && foundb) break;
1141         }
1142 }
1143
1144
1145 void ts_to_pes( int fdin, uint16_t pida, uint16_t pidv, int ps)
1146 {
1147         
1148         uint8_t buf[IN_SIZE];
1149         uint8_t mbuf[TS_SIZE];
1150         int i;
1151         int count = 1;
1152         uint16_t pid;
1153         uint16_t dummy;
1154         ipack pa, pv;
1155         ipack *p;
1156
1157         if (fdin != STDIN_FILENO && (!pida || !pidv))
1158                 find_avpids(fdin, &pidv, &pida);
1159
1160         init_ipack(&pa, IPACKS,write_out, ps);
1161         init_ipack(&pv, IPACKS,write_out, ps);
1162
1163         if ((count = save_read(fdin,mbuf,TS_SIZE))<0)
1164             perror("reading");
1165
1166         for ( i = 0; i < 188 ; i++){
1167                 if ( mbuf[i] == 0x47 ) break;
1168         }
1169         if ( i == 188){
1170                 fprintf(stderr,"Not a TS\n");
1171                 return;
1172         } else {
1173                 memcpy(buf,mbuf+i,TS_SIZE-i);
1174                 if ((count = save_read(fdin,mbuf,i))<0)
1175                         perror("reading");
1176                 memcpy(buf+TS_SIZE-i,mbuf,i);
1177                 i = 188;
1178         }
1179         count = 1;
1180         while (count > 0){
1181                 if ((count = save_read(fdin,buf+i,IN_SIZE-i)+i)<0)
1182                         perror("reading");
1183                 
1184
1185                 if (!pidv){
1186                         find_bavpids(buf+i, IN_SIZE-i, &pidv, &dummy);
1187                         if (pidv) fprintf(stderr, "vpid %d (0x%02x)\n",
1188                                           pidv,pidv);
1189                 } 
1190
1191                 if (!pida){
1192                         find_bavpids(buf+i, IN_SIZE-i, &dummy, &pida);
1193                         if (pida) fprintf(stderr, "apid %d (0x%02x)\n",
1194                                           pida,pida);
1195                 } 
1196
1197
1198                 for( i = 0; i < count; i+= TS_SIZE){
1199                         uint8_t off = 0;
1200
1201                         if ( count - i < TS_SIZE) break;
1202
1203                         pid = get_pid(buf+i+1);
1204                         if (!(buf[3+i]&0x10)) // no payload?
1205                                 continue;
1206                         if ( buf[1+i]&0x80){
1207                                 fprintf(stderr,"Error in TS for PID: %d\n", 
1208                                         pid);
1209                         }
1210                         if (pid == pidv){
1211                                 p = &pv;
1212                         } else {
1213                                 if (pid == pida){
1214                                         p = &pa;
1215                                 } else continue;
1216                         }
1217
1218                         if ( buf[1+i]&0x40) {
1219                                 if (p->plength == MMAX_PLENGTH-6){
1220                                         p->plength = p->found-6;
1221                                         p->found = 0;
1222                                         send_ipack(p);
1223                                         reset_ipack(p);
1224                                 }
1225                         }
1226
1227                         if ( buf[3+i] & 0x20) {  // adaptation field?
1228                                 off = buf[4+i] + 1;
1229                         }
1230         
1231                         instant_repack(buf+4+off+i, TS_SIZE-4-off, p);
1232                 }
1233                 i = 0;
1234
1235         }
1236
1237 }
1238
1239
1240 #define INN_SIZE 2*IN_SIZE
1241 void insert_pat_pmt( int fdin, int fdout)
1242 {
1243         
1244         uint8_t buf[INN_SIZE];
1245         uint8_t mbuf[TS_SIZE];
1246         int i;
1247         int count = 1;
1248         uint16_t pida = 0;
1249         uint16_t pidv = 0;
1250         int written,c;
1251         uint8_t c0 = 0;
1252         uint8_t c1 = 0;
1253         uint8_t pmt_len;
1254         uint32_t crc32;
1255
1256
1257         find_avpids(fdin, &pidv, &pida);
1258         
1259         count = save_read(fdin,mbuf,TS_SIZE);
1260         for ( i = 0; i < 188 ; i++){
1261                 if ( mbuf[i] == 0x47 ) break;
1262         }
1263         if ( i == 188){
1264                 fprintf(stderr,"Not a TS\n");
1265                 return;
1266         } else {
1267                 memcpy(buf,mbuf+i,TS_SIZE-i);
1268                 count = save_read(fdin,mbuf,i);
1269                 memcpy(buf+TS_SIZE-i,mbuf,i);
1270                 i = 188;
1271         }
1272         
1273         count = 1;
1274         /* length is not correct, but we only create a very small
1275          * PMT, so it doesn't matter :-)
1276          */
1277         pmt_len = tspid1[7] + 3;
1278         while (count > 0){
1279                 tspid1[24]  = pidv;
1280                 tspid1[23] |= (pidv >> 8) & 0x3F;
1281                 tspid1[29]  = pida;
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;
1288                 
1289                 write(fdout,tspid0,188);
1290                 write(fdout,tspid1,188);
1291
1292                 count = save_read(fdin,buf+i,INN_SIZE-i);
1293                 
1294                 written = 0;
1295                 while (written < IN_SIZE){
1296                         c = write(fdout,buf,INN_SIZE);
1297                         if (c>0) written += c;
1298                 }
1299                 tspid0[3] &= 0xF0 ;
1300                 tspid0[3] |= (c0++)& 0x0F ;
1301
1302                 tspid1[3] &= 0xF0 ;
1303                 tspid1[3] |= (c1++)& 0x0F ;
1304         
1305                 i=0;
1306         }
1307
1308 }
1309
1310 void get_pes (uint8_t *buf, int count, p2p *p, void (*func)(p2p *p))
1311 {
1312
1313         int l;
1314         unsigned short *pl;
1315         int c=0;
1316
1317         uint8_t headr[3] = { 0x00, 0x00, 0x01} ;
1318
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 ){
1324                 case 0:
1325                 case 1:
1326                         if (buf[c] == 0x00) p->found++;
1327                         else p->found = 0;
1328                         c++;
1329                         break;
1330                 case 2:
1331                         if (buf[c] == 0x01) p->found++;
1332                         else if (buf[c] == 0){
1333                                 p->found = 2;
1334                         } else p->found = 0;
1335                         c++;
1336                         break;
1337                 case 3:
1338                         p->cid = 0;
1339                         switch (buf[c]){
1340                         case PROG_STREAM_MAP:
1341                         case PRIVATE_STREAM2:
1342                         case PROG_STREAM_DIR:
1343                         case ECM_STREAM     :
1344                         case EMM_STREAM     :
1345                         case PADDING_STREAM :
1346                         case DSM_CC_STREAM  :
1347                         case ISO13522_STREAM:
1348                                 p->done = 1;
1349                         case PRIVATE_STREAM1:
1350                         case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1351                         case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1352                                 p->found++;
1353                                 p->cid = buf[c];
1354                                 c++;
1355                                 break;
1356                         default:
1357                                 p->found = 0;
1358                                 break;
1359                         }
1360                         break;
1361                         
1362
1363                 case 4:
1364                         if (count-c > 1){
1365                                 pl = (unsigned short *) (buf+c);
1366                                 p->plength =  ntohs(*pl);
1367                                 p->plen[0] = buf[c];
1368                                 c++;
1369                                 p->plen[1] = buf[c];
1370                                 c++;
1371                                 p->found+=2;
1372                         } else {
1373                                 p->plen[0] = buf[c];
1374                                 p->found++;
1375                                 return;
1376                         }
1377                         break;
1378                 case 5:
1379                         p->plen[1] = buf[c];
1380                         c++;
1381                         pl = (unsigned short *) p->plen;
1382                         p->plength = ntohs(*pl);
1383                         p->found++;
1384                         break;
1385
1386
1387                 case 6:
1388                         if (!p->done){
1389                                 p->flag1 = buf[c];
1390                                 c++;
1391                                 p->found++;
1392                                 if ( (p->flag1 & 0xC0) == 0x80 ) p->mpeg = 2;
1393                                 else {
1394                                         p->hlength = 0;
1395                                         p->which = 0;
1396                                         p->mpeg = 1;
1397                                         p->flag2 = 0;
1398                                 }
1399                         }
1400                         break;
1401
1402                 case 7:
1403                         if ( !p->done && p->mpeg == 2){
1404                                 p->flag2 = buf[c];
1405                                 c++;
1406                                 p->found++;
1407                         }       
1408                         break;
1409
1410                 case 8:
1411                         if ( !p->done && p->mpeg == 2){
1412                                 p->hlength = buf[c];
1413                                 c++;
1414                                 p->found++;
1415                         }
1416                         break;
1417                         
1418                 default:
1419
1420                         break;
1421                 }
1422         }
1423
1424         if (!p->plength) p->plength = MMAX_PLENGTH-6;
1425
1426
1427         if ( p->done || ((p->mpeg == 2 && p->found >= 9)  || 
1428              (p->mpeg == 1 && p->found >= 7)) ){
1429                 switch (p->cid){
1430                         
1431                 case AUDIO_STREAM_S ... AUDIO_STREAM_E:                 
1432                 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1433                 case PRIVATE_STREAM1:
1434
1435                         memcpy(p->buf, headr, 3);
1436                         p->buf[3] = p->cid;
1437                         memcpy(p->buf+4,p->plen,2);
1438
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;
1443                         }
1444
1445                         if (p->mpeg == 1 && p->found == 7){
1446                                 p->buf[6] = p->flag1;
1447                         }
1448
1449
1450                         if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) &&  
1451                             p->found < 14){
1452                                 while (c < count && p->found < 14){
1453                                         p->pts[p->found-9] = buf[c];
1454                                         p->buf[p->found] = buf[c];
1455                                         c++;
1456                                         p->found++;
1457                                 }
1458                                 if (c == count) return;
1459                         }
1460
1461                         if (p->mpeg == 1 && p->which < 2000){
1462
1463                                 if (p->found == 7) {
1464                                         p->check = p->flag1;
1465                                         p->hlength = 1;
1466                                 }
1467
1468                                 while (!p->which && c < count && 
1469                                        p->check == 0xFF){
1470                                         p->check = buf[c];
1471                                         p->buf[p->found] = buf[c];
1472                                         c++;
1473                                         p->found++;
1474                                         p->hlength++;
1475                                 }
1476
1477                                 if ( c == count) return;
1478                                 
1479                                 if ( (p->check & 0xC0) == 0x40 && !p->which){
1480                                         p->check = buf[c];
1481                                         p->buf[p->found] = buf[c];
1482                                         c++;
1483                                         p->found++;
1484                                         p->hlength++;
1485
1486                                         p->which = 1;
1487                                         if ( c == count) return;
1488                                         p->check = buf[c];
1489                                         p->buf[p->found] = buf[c];
1490                                         c++;
1491                                         p->found++;
1492                                         p->hlength++;
1493                                         p->which = 2;
1494                                         if ( c == count) return;
1495                                 }
1496
1497                                 if (p->which == 1){
1498                                         p->check = buf[c];
1499                                         p->buf[p->found] = buf[c];
1500                                         c++;
1501                                         p->found++;
1502                                         p->hlength++;
1503                                         p->which = 2;
1504                                         if ( c == count) return;
1505                                 }
1506                                 
1507                                 if ( (p->check & 0x30) && p->check != 0xFF){
1508                                         p->flag2 = (p->check & 0xF0) << 2;
1509                                         p->pts[0] = p->check;
1510                                         p->which = 3;
1511                                 } 
1512
1513                                 if ( c == count) return;
1514                                 if (p->which > 2){
1515                                         if ((p->flag2 & PTS_DTS_FLAGS)
1516                                             == PTS_ONLY){
1517                                                 while (c < count && 
1518                                                        p->which < 7){
1519                                                         p->pts[p->which-2] =
1520                                                                 buf[c];
1521                                                         p->buf[p->found] = 
1522                                                                 buf[c];
1523                                                         c++;
1524                                                         p->found++;
1525                                                         p->which++;
1526                                                         p->hlength++;
1527                                                 }
1528                                                 if ( c == count) return;
1529                                         } else if ((p->flag2 & PTS_DTS_FLAGS) 
1530                                                    == PTS_DTS){
1531                                                 while (c < count && 
1532                                                        p->which< 12){
1533                                                         if (p->which< 7)
1534                                                                 p->pts[p->which
1535                                                                       -2] =
1536                                                                         buf[c];
1537                                                         p->buf[p->found] = 
1538                                                                 buf[c];
1539                                                         c++;
1540                                                         p->found++;
1541                                                         p->which++;
1542                                                         p->hlength++;
1543                                                 }
1544                                                 if ( c == count) return;
1545                                         }
1546                                         p->which = 2000;
1547                                 }
1548                                                         
1549                         }
1550
1551                         while (c < count && p->found < p->plength+6){
1552                                 l = count -c;
1553                                 if (l+p->found > p->plength+6)
1554                                         l = p->plength+6-p->found;
1555                                 memcpy(p->buf+p->found, buf+c, l);
1556                                 p->found += l;
1557                                 c += l;
1558                         }                       
1559                         if(p->found == p->plength+6)
1560                                 func(p);
1561                         
1562                         break;
1563                 }
1564
1565
1566                 if ( p->done ){
1567                         if( p->found + count - c < p->plength+6){
1568                                 p->found += count-c;
1569                                 c = count;
1570                         } else {
1571                                 c += p->plength+6 - p->found;
1572                                 p->found = p->plength+6;
1573                         }
1574                 }
1575
1576                 if (p->plength && p->found == p->plength+6) {
1577                         p->found = 0;
1578                         p->done = 0;
1579                         p->plength = 0;
1580                         memset(p->buf, 0, MAX_PLENGTH);
1581                         if (c < count)
1582                                 get_pes(buf+c, count-c, p, func);
1583                 }
1584         }
1585         return;
1586 }
1587
1588
1589
1590
1591 void setup_pes2ts( p2p *p, uint32_t pida, uint32_t pidv, 
1592                    void (*ts_write)(uint8_t *buf, int count, void *p))
1593 {
1594         init_p2p( p, ts_write, 2048);
1595         p->pida = pida;
1596         p->pidv = pidv;
1597         p->acounter = 0;
1598         p->vcounter = 0;
1599         p->count1 = 0;
1600         p->count0 = 0;
1601 }
1602
1603 void kpes_to_ts( p2p *p,uint8_t *buf ,int count )
1604 {
1605         get_pes(buf,count, p,pes_in_ts);
1606 }
1607
1608
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))
1611 {
1612         init_p2p( pa, pes_write, 2048);
1613         init_p2p( pv, pes_write, 2048);
1614         pa->pid = pida;
1615         pv->pid = pidv;
1616 }
1617
1618 void kts_to_pes( p2p *p, uint8_t *buf) // don't need count (=188)
1619 {
1620         uint8_t off = 0;
1621         uint16_t pid = 0;
1622
1623         if (!(buf[3]&PAYLOAD)) // no payload?
1624                 return;
1625
1626         pid = get_pid(buf+1);
1627                         
1628         if (pid != p->pid) return;
1629         if ( buf[1]&0x80){
1630                 fprintf(stderr,"Error in TS for PID: %d\n", 
1631                         pid);
1632         }
1633
1634         if ( buf[1]&PAY_START) {
1635                 if (p->plength == MMAX_PLENGTH-6){
1636                         p->plength = p->found-6;
1637                         p->found = 0;
1638                         pes_repack(p);
1639                 }
1640         }
1641
1642         if ( buf[3] & ADAPT_FIELD) {  // adaptation field?
1643                 off = buf[4] + 1;
1644                 if (off+4 > 187) return;
1645         }
1646         
1647         get_pes(buf+4+off, TS_SIZE-4-off, p , pes_repack);
1648 }
1649
1650
1651
1652
1653 // instant repack
1654
1655
1656 void reset_ipack(ipack *p)
1657 {
1658         p->found = 0;
1659         p->cid = 0;
1660         p->plength = 0;
1661         p->flag1 = 0;
1662         p->flag2 = 0;
1663         p->hlength = 0;
1664         p->mpeg = 0;
1665         p->check = 0;
1666         p->which = 0;
1667         p->done = 0;
1668         p->count = 0;
1669         p->size = p->size_orig;
1670 }
1671
1672 void init_ipack(ipack *p, int size,
1673                 void (*func)(uint8_t *buf,  int size, void *priv), int ps)
1674 {
1675         if ( !(p->buf = malloc(size)) ){
1676                 fprintf(stderr,"Couldn't allocate memory for ipack\n");
1677                 exit(1);
1678         }
1679         p->ps = ps;
1680         p->size_orig = size;
1681         p->func = func;
1682         reset_ipack(p);
1683         p->has_ai = 0;
1684         p->has_vi = 0;
1685         p->start = 0;
1686 }
1687
1688 void free_ipack(ipack * p)
1689 {
1690         if (p->buf) free(p->buf);
1691 }
1692
1693
1694
1695 int get_vinfo(uint8_t *mbuf, int count, VideoInfo *vi, int pr)
1696 {
1697         uint8_t *headr;
1698         int found = 0;
1699         int sw;
1700         int form = -1;
1701         int c = 0;
1702
1703         while (found < 4 && c+4 < count){
1704                 uint8_t *b;
1705
1706                 b = mbuf+c;
1707                 if ( b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01
1708                      && b[3] == 0xb3) found = 4;
1709                 else {
1710                         c++;
1711                 }
1712         }
1713
1714         if (! found) return -1;
1715         c += 4;
1716         if (c+12 >= count) return -1;
1717         headr = mbuf+c;
1718
1719         vi->horizontal_size     = ((headr[1] &0xF0) >> 4) | (headr[0] << 4);
1720         vi->vertical_size       = ((headr[1] &0x0F) << 8) | (headr[2]);
1721     
1722         sw = (int)((headr[3]&0xF0) >> 4) ;
1723
1724         switch( sw ){
1725         case 1:
1726                 if (pr)
1727                         fprintf(stderr,"Videostream: ASPECT: 1:1");
1728                 vi->aspect_ratio = 100;        
1729                 break;
1730         case 2:
1731                 if (pr)
1732                         fprintf(stderr,"Videostream: ASPECT: 4:3");
1733                 vi->aspect_ratio = 133;        
1734                 break;
1735         case 3:
1736                 if (pr)
1737                         fprintf(stderr,"Videostream: ASPECT: 16:9");
1738                 vi->aspect_ratio = 177;        
1739                 break;
1740         case 4:
1741                 if (pr)
1742                         fprintf(stderr,"Videostream: ASPECT: 2.21:1");
1743                 vi->aspect_ratio = 221;        
1744                 break;
1745
1746         case 5 ... 15:
1747                 if (pr)
1748                         fprintf(stderr,"Videostream: ASPECT: reserved");
1749                 vi->aspect_ratio = 0;        
1750                 break;
1751
1752         default:
1753                 vi->aspect_ratio = 0;        
1754                 return -1;
1755         }
1756
1757         if (pr)
1758                 fprintf(stderr,"  Size = %dx%d",vi->horizontal_size,
1759                         vi->vertical_size);
1760
1761         sw = (int)(headr[3]&0x0F);
1762
1763         switch ( sw ) {
1764         case 1:
1765                 if (pr)
1766                         fprintf(stderr,"  FRate: 23.976 fps");
1767                 vi->framerate = 24000/1001.;
1768                 form = -1;
1769                 break;
1770         case 2:
1771                 if (pr)
1772                         fprintf(stderr,"  FRate: 24 fps");
1773                 vi->framerate = 24;
1774                 form = -1;
1775                 break;
1776         case 3:
1777                 if (pr)
1778                         fprintf(stderr,"  FRate: 25 fps");
1779                 vi->framerate = 25;
1780                 form = VIDEO_MODE_PAL;
1781                 break;
1782         case 4:
1783                 if (pr)
1784                         fprintf(stderr,"  FRate: 29.97 fps");
1785                 vi->framerate = 30000/1001.;
1786                 form = VIDEO_MODE_NTSC;
1787                 break;
1788         case 5:
1789                 if (pr)
1790                         fprintf(stderr,"  FRate: 30 fps");
1791                 vi->framerate = 30;
1792                 form = VIDEO_MODE_NTSC;
1793                 break;
1794         case 6:
1795                 if (pr)
1796                         fprintf(stderr,"  FRate: 50 fps");
1797                 vi->framerate = 50;
1798                 form = VIDEO_MODE_PAL;
1799                 break;
1800         case 7:
1801                 if (pr)
1802                         fprintf(stderr,"  FRate: 60 fps");
1803                 vi->framerate = 60;
1804                 form = VIDEO_MODE_NTSC;
1805                 break;
1806         }
1807
1808         vi->bit_rate = 400*(((headr[4] << 10) & 0x0003FC00UL) 
1809                             | ((headr[5] << 2) & 0x000003FCUL) | 
1810                             (((headr[6] & 0xC0) >> 6) & 0x00000003UL));
1811         
1812         if (pr){
1813                 fprintf(stderr,"  BRate: %.2f Mbit/s",(vi->bit_rate)/1000000.);
1814                 fprintf(stderr,"\n");
1815         }
1816         vi->video_format = form;
1817
1818         vi->off = c-4;
1819         return c-4;
1820 }
1821
1822 extern unsigned int bitrates[3][16];
1823 extern uint32_t freq[4];
1824
1825 int get_ainfo(uint8_t *mbuf, int count, AudioInfo *ai, int pr)
1826 {
1827         uint8_t *headr;
1828         int found = 0;
1829         int c = 0;
1830         int fr =0;
1831         
1832         while (!found && c < count){
1833                 uint8_t *b = mbuf+c;
1834
1835                 if ( b[0] == 0xff && (b[1] & 0xf8) == 0xf8)
1836                         found = 1;
1837                 else {
1838                         c++;
1839                 }
1840         }       
1841
1842         if (!found) return -1;
1843
1844         if (c+3 >= count) return -1;
1845         headr = mbuf+c;
1846
1847         ai->layer = (headr[1] & 0x06) >> 1;
1848
1849         if (pr)
1850                 fprintf(stderr,"Audiostream: Layer: %d", 4-ai->layer);
1851
1852
1853         ai->bit_rate = bitrates[(3-ai->layer)][(headr[2] >> 4 )]*1000;
1854
1855         if (pr){
1856                 if (ai->bit_rate == 0)
1857                         fprintf (stderr,"  Bit rate: free");
1858                 else if (ai->bit_rate == 0xf)
1859                         fprintf (stderr,"  BRate: reserved");
1860                 else
1861                         fprintf (stderr,"  BRate: %d kb/s", ai->bit_rate/1000);
1862         }
1863
1864         fr = (headr[2] & 0x0c ) >> 2;
1865         ai->frequency = freq[fr]*100;
1866         
1867         if (pr){
1868                 if (ai->frequency == 3)
1869                         fprintf (stderr, "  Freq: reserved\n");
1870                 else
1871                         fprintf (stderr,"  Freq: %2.1f kHz\n", 
1872                                  ai->frequency/1000.);
1873         }
1874         ai->off = c;
1875         return c;
1876 }
1877
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};
1881
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}}; 
1890
1891 int get_ac3info(uint8_t *mbuf, int count, AudioInfo *ai, int pr)
1892 {
1893         uint8_t *headr;
1894         int found = 0;
1895         int c = 0;
1896         uint8_t frame;
1897         int fr = 0;
1898
1899         while ( !found  && c < count){
1900                 uint8_t *b = mbuf+c;
1901                 if ( b[0] == 0x0b &&  b[1] == 0x77 )
1902                         found = 1;
1903                 else {
1904                         c++;
1905                 }
1906         }       
1907
1908
1909         if (!found){
1910                 return -1;
1911         }
1912         ai->off = c;
1913
1914         if (c+5 >= count) return -1;
1915
1916         ai->layer = 0;  // 0 for AC3
1917         headr = mbuf+c+2;
1918
1919         frame = (headr[2]&0x3f);
1920         ai->bit_rate = ac3_bitrates[frame>>1]*1000;
1921
1922         if (pr) fprintf (stderr,"  BRate: %d kb/s", ai->bit_rate/1000);
1923
1924         fr = (headr[2] & 0xc0 ) >> 6;
1925         ai->frequency = freq[fr]*100;
1926         if (pr) fprintf (stderr,"  Freq: %d Hz\n", ai->frequency);
1927
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);
1932
1933         return c;
1934 }
1935
1936
1937 void ps_pes(ipack *p)
1938 {
1939         int check;
1940         uint8_t pbuf[PS_HEADER_L2];
1941         static int muxr = 0;
1942         static int ai = 0;
1943         static int vi = 0;
1944         static int start = 0;
1945         static uint32_t SCR = 0;
1946
1947         if (p->mpeg == 2){
1948                 switch(p->buf[3]){
1949                 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1950                         if (!p->has_vi){
1951                                 if(get_vinfo(p->buf, p->count, &p->vi,1) >=0) {
1952                                         p->has_vi = 1;
1953                                         vi = p->vi.bit_rate;
1954                                 }
1955                         }                       
1956                         break;
1957
1958                 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1959                         if (!p->has_ai){
1960                                 if(get_ainfo(p->buf, p->count, &p->ai,1) >=0) {
1961                                         p->has_ai = 1;
1962                                         ai = p->ai.bit_rate;
1963                                 }
1964                         } 
1965                         break;
1966                 }
1967
1968                 if (p->has_vi && vi && !muxr){
1969                         muxr = (vi+ai)/400;
1970                 }
1971
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;
1975                         
1976                         check = write_ps_header(pbuf,
1977                                                 SCR,
1978                                                 muxr, 1, 0, 0, 1, 1, 1, 
1979                                                 0, 0, 0, 0, 0, 0);
1980
1981                         p->func(pbuf, check , p->data);
1982                 }
1983
1984                 if (muxr && !start && vi){
1985                         SCR = trans_pts_dts(p->pts)-3600;
1986                         check = write_ps_header(pbuf,
1987                                                 SCR, 
1988                                                 muxr, 1, 0, 0, 1, 1, 1, 
1989                                                 0xC0, 0, 64, 0xE0, 1, 460);
1990                         start = 1;
1991                         p->func(pbuf, check , p->data);
1992                 }
1993
1994                 if (start)
1995                         p->func(p->buf, p->count, p->data);
1996         }
1997 }
1998
1999 void send_ipack(ipack *p)
2000 {
2001         int streamid=0;
2002         int off;
2003         int ac3_off = 0;
2004         AudioInfo ai;
2005         int nframes= 0;
2006         int f=0;
2007
2008         if (p->count < 10) return;
2009         p->buf[3] = p->cid;
2010         p->buf[4] = (uint8_t)(((p->count-6) & 0xFF00) >> 8);
2011         p->buf[5] = (uint8_t)((p->count-6) & 0x00FF);
2012
2013         
2014         if (p->cid == PRIVATE_STREAM1){
2015
2016                 off = 9+p->buf[8];
2017                 streamid = p->buf[off];
2018                 if ((streamid & 0xF8) == 0x80){
2019                         ai.off = 0;
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);
2024                         if ( !f ){
2025                                 nframes = (p->count-off-3-ac3_off)/ 
2026                                         ai.framesize + 1;
2027                                 p->buf[off+1] = nframes;
2028                                 p->buf[off+2] = (ac3_off >> 8)& 0xFF;
2029                                 p->buf[off+3] = (ac3_off)& 0xFF;
2030                                 
2031                                 ac3_off +=  nframes * ai.framesize - p->count;
2032                         }
2033                 }
2034         } 
2035         
2036         if (p->ps) ps_pes(p);
2037         else p->func(p->buf, p->count, p->data);
2038
2039         switch ( p->mpeg ){
2040         case 2:         
2041                 
2042                 p->buf[6] = 0x80;
2043                 p->buf[7] = 0x00;
2044                 p->buf[8] = 0x00;
2045                 p->count = 9;
2046
2047                 if (p->cid == PRIVATE_STREAM1 && (streamid & 0xF8)==0x80 ){
2048                         p->count += 4;
2049                         p->buf[9] = streamid;
2050                         p->buf[10] = 0;
2051                         p->buf[11] = (ac3_off >> 8)& 0xFF;
2052                         p->buf[12] = (ac3_off)& 0xFF;
2053                 }
2054                 
2055                 break;
2056         case 1:
2057                 p->buf[6] = 0x0F;
2058                 p->count = 7;
2059                 break;
2060         }
2061
2062 }
2063
2064
2065 static void write_ipack(ipack *p, uint8_t *data, int count)
2066 {
2067         AudioInfo ai;
2068         uint8_t headr[3] = { 0x00, 0x00, 0x01} ;
2069         int diff =0;
2070
2071         if (p->count < 6){
2072                 if (trans_pts_dts(p->pts) > trans_pts_dts(p->last_pts))
2073                         memcpy(p->last_pts, p->pts, 5);
2074                 p->count = 0;
2075                 memcpy(p->buf+p->count, headr, 3);
2076                 p->count += 6;
2077         }
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){
2081                 
2082                         p->size = diff/2;
2083 //                      fprintf(stderr,"size: %d \n",p->size);
2084         }
2085
2086         if (p->cid == PRIVATE_STREAM1 && p->count == p->hlength+9){
2087                 if ((data[0] & 0xF8) != 0x80){
2088                         int ac3_off;
2089
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
2094                                                       - 4 - ac3_off)/ 
2095                                         ai.framesize + 1;
2096                                 p->buf[p->count+2] = (ac3_off >> 8)& 0xFF;
2097                                 p->buf[p->count+3] = (ac3_off)& 0xFF;
2098                                 p->count+=4;
2099                                 
2100                         }
2101                 }
2102         }
2103
2104         if (p->count + count < p->size){
2105                 memcpy(p->buf+p->count, data, count); 
2106                 p->count += count;
2107         } else {
2108                 int rest = p->size - p->count;
2109                 if (rest < 0) rest = 0;
2110                 memcpy(p->buf+p->count, data, rest);
2111                 p->count += rest;
2112 //              fprintf(stderr,"count: %d \n",p->count);
2113                 send_ipack(p);
2114                 if (count - rest > 0)
2115                         write_ipack(p, data+rest, count-rest);
2116         }
2117 }
2118
2119 void instant_repack (uint8_t *buf, int count, ipack *p)
2120 {
2121
2122         int l;
2123         unsigned short *pl;
2124         int c=0;
2125
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 ){
2131                 case 0:
2132                 case 1:
2133                         if (buf[c] == 0x00) p->found++;
2134                         else p->found = 0;
2135                         c++;
2136                         break;
2137                 case 2:
2138                         if (buf[c] == 0x01) p->found++;
2139                         else if (buf[c] == 0){
2140                                 p->found = 2;
2141                         } else p->found = 0;
2142                         c++;
2143                         break;
2144                 case 3:
2145                         p->cid = 0;
2146                         switch (buf[c]){
2147                         case PROG_STREAM_MAP:
2148                         case PRIVATE_STREAM2:
2149                         case PROG_STREAM_DIR:
2150                         case ECM_STREAM     :
2151                         case EMM_STREAM     :
2152                         case PADDING_STREAM :
2153                         case DSM_CC_STREAM  :
2154                         case ISO13522_STREAM:
2155                                 p->done = 1;
2156                         case PRIVATE_STREAM1:
2157                         case VIDEO_STREAM_S ... VIDEO_STREAM_E:
2158                         case AUDIO_STREAM_S ... AUDIO_STREAM_E:
2159                                 p->found++;
2160                                 p->cid = buf[c];
2161                                 c++;
2162                                 break;
2163                         default:
2164                                 p->found = 0;
2165                                 break;
2166                         }
2167                         break;
2168                         
2169
2170                 case 4:
2171                         if (count-c > 1){
2172                                 pl = (unsigned short *) (buf+c);
2173                                 p->plength =  ntohs(*pl);
2174                                 p->plen[0] = buf[c];
2175                                 c++;
2176                                 p->plen[1] = buf[c];
2177                                 c++;
2178                                 p->found+=2;
2179                         } else {
2180                                 p->plen[0] = buf[c];
2181                                 p->found++;
2182                                 return;
2183                         }
2184                         break;
2185                 case 5:
2186                         p->plen[1] = buf[c];
2187                         c++;
2188                         pl = (unsigned short *) p->plen;
2189                         p->plength = ntohs(*pl);
2190                         p->found++;
2191                         break;
2192
2193
2194                 case 6:
2195                         if (!p->done){
2196                                 p->flag1 = buf[c];
2197                                 c++;
2198                                 p->found++;
2199                                 if ( (p->flag1 & 0xC0) == 0x80 ) p->mpeg = 2;
2200                                 else {
2201                                         p->hlength = 0;
2202                                         p->which = 0;
2203                                         p->mpeg = 1;
2204                                         p->flag2 = 0;
2205                                 }
2206                         }
2207                         break;
2208
2209                 case 7:
2210                         if ( !p->done && p->mpeg == 2){
2211                                 p->flag2 = buf[c];
2212                                 c++;
2213                                 p->found++;
2214                         }       
2215                         break;
2216
2217                 case 8:
2218                         if ( !p->done && p->mpeg == 2){
2219                                 p->hlength = buf[c];
2220                                 c++;
2221                                 p->found++;
2222                         }
2223                         break;
2224                         
2225                 default:
2226
2227                         break;
2228                 }
2229         }
2230
2231
2232         if (c == count) return;
2233
2234         if (!p->plength) p->plength = MMAX_PLENGTH-6;
2235
2236
2237         if ( p->done || ((p->mpeg == 2 && p->found >= 9)  || 
2238              (p->mpeg == 1 && p->found >= 7)) ){
2239                 switch (p->cid){
2240                         
2241                 case AUDIO_STREAM_S ... AUDIO_STREAM_E:                 
2242                 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
2243                 case PRIVATE_STREAM1:
2244                         
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);
2249                         }
2250
2251                         if (p->mpeg == 1 && p->found == 7){
2252                                 write_ipack(p, &p->flag1, 1);
2253                         }
2254
2255
2256                         if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) &&  
2257                             p->found < 14){
2258                                 while (c < count && p->found < 14){
2259                                         p->pts[p->found-9] = buf[c];
2260                                         write_ipack(p, buf+c, 1);
2261                                         c++;
2262                                         p->found++;
2263                                 }
2264                                 if (c == count) return;
2265                         }
2266                         
2267                         if (p->mpeg == 1 && p->which < 2000){
2268
2269                                 if (p->found == 7) {
2270                                         p->check = p->flag1;
2271                                         p->hlength = 1;
2272                                 }
2273
2274                                 while (!p->which && c < count && 
2275                                        p->check == 0xFF){
2276                                         p->check = buf[c];
2277                                         write_ipack(p, buf+c, 1);
2278                                         c++;
2279                                         p->found++;
2280                                         p->hlength++;
2281                                 }
2282
2283                                 if ( c == count) return;
2284                                 
2285                                 if ( (p->check & 0xC0) == 0x40 && !p->which){
2286                                         p->check = buf[c];
2287                                         write_ipack(p, buf+c, 1);
2288                                         c++;
2289                                         p->found++;
2290                                         p->hlength++;
2291
2292                                         p->which = 1;
2293                                         if ( c == count) return;
2294                                         p->check = buf[c];
2295                                         write_ipack(p, buf+c, 1);
2296                                         c++;
2297                                         p->found++;
2298                                         p->hlength++;
2299                                         p->which = 2;
2300                                         if ( c == count) return;
2301                                 }
2302
2303                                 if (p->which == 1){
2304                                         p->check = buf[c];
2305                                         write_ipack(p, buf+c, 1);
2306                                         c++;
2307                                         p->found++;
2308                                         p->hlength++;
2309                                         p->which = 2;
2310                                         if ( c == count) return;
2311                                 }
2312                                 
2313                                 if ( (p->check & 0x30) && p->check != 0xFF){
2314                                         p->flag2 = (p->check & 0xF0) << 2;
2315                                         p->pts[0] = p->check;
2316                                         p->which = 3;
2317                                 } 
2318
2319                                 if ( c == count) return;
2320                                 if (p->which > 2){
2321                                         if ((p->flag2 & PTS_DTS_FLAGS)
2322                                             == PTS_ONLY){
2323                                                 while (c < count && 
2324                                                        p->which < 7){
2325                                                         p->pts[p->which-2] =
2326                                                                 buf[c];
2327                                                         write_ipack(p,buf+c,1);
2328                                                         c++;
2329                                                         p->found++;
2330                                                         p->which++;
2331                                                         p->hlength++;
2332                                                 }
2333                                                 if ( c == count) return;
2334                                         } else if ((p->flag2 & PTS_DTS_FLAGS) 
2335                                                    == PTS_DTS){
2336                                                 while (c < count && 
2337                                                        p->which< 12){
2338                                                         if (p->which< 7)
2339                                                                 p->pts[p->which
2340                                                                       -2] =
2341                                                                         buf[c];
2342                                                         write_ipack(p,buf+c,1);
2343                                                         c++;
2344                                                         p->found++;
2345                                                         p->which++;
2346                                                         p->hlength++;
2347                                                 }
2348                                                 if ( c == count) return;
2349                                         }
2350                                         p->which = 2000;
2351                                 }
2352                                                         
2353                         }
2354
2355                         while (c < count && p->found < p->plength+6){
2356                                 l = count -c;
2357                                 if (l+p->found > p->plength+6)
2358                                         l = p->plength+6-p->found;
2359                                 write_ipack(p, buf+c, l);
2360                                 p->found += l;
2361                                 c += l;
2362                         }       
2363                 
2364                         break;
2365                 }
2366
2367
2368                 if ( p->done ){
2369                         if( p->found + count - c < p->plength+6){
2370                                 p->found += count-c;
2371                                 c = count;
2372                         } else {
2373                                 c += p->plength+6 - p->found;
2374                                 p->found = p->plength+6;
2375                         }
2376                 }
2377
2378                 if (p->plength && p->found == p->plength+6) {
2379                         send_ipack(p);
2380                         reset_ipack(p);
2381                         if (c < count)
2382                                 instant_repack(buf+c, count-c, p);
2383                 }
2384         }
2385         return;
2386 }
2387
2388 void write_out_es(uint8_t *buf, int count,void  *priv)
2389 {
2390         ipack *p = (ipack *) priv;
2391         uint8_t payl = buf[8]+9+p->start-1;
2392
2393         write(p->fd, buf+payl, count-payl);
2394         p->start = 1;
2395 }
2396
2397 void write_out_pes(uint8_t *buf, int count,void  *priv)
2398 {
2399         ipack *p = (ipack *) priv;
2400         write(p->fd, buf, count);
2401 }
2402
2403
2404
2405 int64_t ts_demux(int fdin, int fdv_out,int fda_out,uint16_t pida,
2406                   uint16_t pidv, int es)
2407 {
2408         uint8_t buf[IN_SIZE];
2409         uint8_t mbuf[TS_SIZE];
2410         int i;
2411         int count = 1;
2412         uint16_t pid;
2413         ipack pa, pv;
2414         ipack *p;
2415         uint8_t *sb;
2416         int64_t apts=0;
2417         int64_t vpts=0;
2418         int verb = 0;
2419         uint64_t length =0;
2420         uint64_t l=0;
2421         int perc =0;
2422         int last_perc =0;
2423
2424         if (fdin != STDIN_FILENO) verb = 1; 
2425
2426         if (verb) {
2427                 length = lseek(fdin, 0, SEEK_END);
2428                 lseek(fdin,0,SEEK_SET);
2429         }
2430
2431         if (!pida || !pidv)
2432                 find_avpids(fdin, &pidv, &pida);
2433
2434         if (es){
2435                 init_ipack(&pa, IPACKS,write_out_es, 0);
2436                 init_ipack(&pv, IPACKS,write_out_es, 0);
2437         } else {
2438                 init_ipack(&pa, IPACKS,write_out_pes, 0);
2439                 init_ipack(&pv, IPACKS,write_out_pes, 0);
2440         } 
2441         pa.fd = fda_out;
2442         pv.fd = fdv_out;
2443         pa.data = (void *)&pa;
2444         pv.data = (void *)&pv;
2445
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;
2450         }
2451         if ( i == 188){
2452                 fprintf(stderr,"Not a TS\n");
2453                 return 0;
2454         } else {
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);
2459                 i = 188;
2460         }
2461         
2462         count = 1;
2463         while (count > 0){
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);
2469                         last_perc = perc;
2470                 }
2471                 
2472                 for( i = 0; i < count; i+= TS_SIZE){
2473                         uint8_t off = 0;
2474
2475                         if ( count - i < TS_SIZE) break;
2476
2477                         pid = get_pid(buf+i+1);
2478                         if (!(buf[3+i]&0x10)) // no payload?
2479                                 continue;
2480                         if ( buf[1+i]&0x80){
2481                                 fprintf(stderr,"Error in TS for PID: %d\n", 
2482                                         pid);
2483                         }
2484                         if (pid == pidv){
2485                                 p = &pv;
2486                         } else {
2487                                 if (pid == pida){
2488                                         p = &pa;
2489                                 } else continue;
2490                         }
2491
2492                         if ( buf[3+i] & 0x20) {  // adaptation field?
2493                                 off = buf[4+i] + 1;
2494                         }
2495
2496                         if ( buf[1+i]&0x40) {
2497                                 if (p->plength == MMAX_PLENGTH-6){
2498                                         p->plength = p->found-6;
2499                                         p->found = 0;
2500                                         send_ipack(p);
2501                                         reset_ipack(p);
2502                                 }
2503                                 sb = buf+4+off+i;
2504                                 if( es && 
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];
2508                                         if ( pid == pidv &&   
2509                                              (p->start = 
2510                                               get_vinfo( pay, l,&p->vi,1)+1) >0
2511                                                 ){
2512                                                 vpts = trans_pts_dts(sb+9);
2513                                                 printf("vpts : %fs\n",
2514                                                        vpts/90000.);
2515                                         }
2516                                         if ( pid == pida && es==1 && 
2517                                              (p->start = 
2518                                               get_ainfo( pay, l,&p->ai,1)+1) >0
2519                                                 ){
2520                                                 apts = trans_pts_dts(sb+9);
2521                                                 printf("apts : %fs\n",
2522                                                        apts/90000.);
2523                                         }
2524                                         if ( pid == pida && es==2 && 
2525                                              (p->start = 
2526                                               get_ac3info( pay, l,&p->ai,1)+1) >0
2527                                                 ){
2528                                                 apts = trans_pts_dts(sb+9);
2529                                                 printf("apts : %fs\n",
2530                                                        apts/90000.);
2531                                         }
2532                                 }
2533                         }
2534
2535                         if (p->start)
2536                                 instant_repack(buf+4+off+i, TS_SIZE-4-off, p);
2537                 }
2538                 i = 0;
2539
2540         }
2541
2542         return (vpts-apts);
2543 }
2544
2545 void ts2es_opt(int fdin,  uint16_t pidv, ipack *p, int verb)
2546 {
2547         uint8_t buf[IN_SIZE];
2548         uint8_t mbuf[TS_SIZE];
2549         int i;
2550         int count = 1;
2551         uint64_t length =0;
2552         uint64_t l=0;
2553         int perc =0;
2554         int last_perc =0;
2555         uint16_t pid;
2556
2557         if (verb) {
2558                 length = lseek(fdin, 0, SEEK_END);
2559                 lseek(fdin,0,SEEK_SET);
2560         }
2561
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;
2566         }
2567         if ( i == 188){
2568                 fprintf(stderr,"Not a TS\n");
2569                 return;
2570         } else {
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);
2575                 i = 188;
2576         }
2577         
2578         count = 1;
2579         while (count > 0){
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);
2585                         last_perc = perc;
2586                 }
2587
2588                 for( i = 0; i < count; i+= TS_SIZE){
2589                         uint8_t off = 0;
2590
2591                         if ( count - i < TS_SIZE) break;
2592
2593                         pid = get_pid(buf+i+1);
2594                         if (!(buf[3+i]&0x10)) // no payload?
2595                                 continue;
2596                         if ( buf[1+i]&0x80){
2597                                 fprintf(stderr,"Error in TS for PID: %d\n", 
2598                                         pid);
2599                         }
2600                         if (pid != pidv){
2601                                 continue;
2602                         }
2603
2604                         if ( buf[3+i] & 0x20) {  // adaptation field?
2605                                 off = buf[4+i] + 1;
2606                         }
2607
2608                         if ( buf[1+i]&0x40) {
2609                                 if (p->plength == MMAX_PLENGTH-6){
2610                                         p->plength = p->found-6;
2611                                         p->found = 0;
2612                                         send_ipack(p);
2613                                         reset_ipack(p);
2614                                 }
2615                         }
2616
2617                         instant_repack(buf+4+off+i, TS_SIZE-4-off, p);
2618                 }
2619                 i = 0;
2620
2621         }
2622 }
2623
2624 void ts2es(int fdin,  uint16_t pidv)
2625 {
2626         ipack p;
2627         int verb = 0;
2628
2629         init_ipack(&p, IPACKS,write_out_es, 0);
2630         p.fd = STDOUT_FILENO;
2631         p.data = (void *)&p;
2632
2633         if (fdin != STDIN_FILENO) verb = 1; 
2634
2635         ts2es_opt(fdin, pidv, &p, verb);
2636 }
2637
2638
2639 void change_aspect(int fdin, int fdout, int aspect)
2640 {
2641         ps_packet ps;
2642         pes_packet pes;
2643         int neof,i;
2644
2645         do {
2646                 init_ps(&ps);
2647                 neof = read_ps(fdin,&ps);
2648                 write_ps(fdout,&ps);
2649                 for (i = 0; i < ps.npes; i++){
2650                         uint8_t *buf;
2651                         int c = 0;
2652                         int l;
2653
2654                         init_pes(&pes);
2655                         read_pes(fdin, &pes);
2656
2657                         buf = pes.pes_pckt_data;
2658
2659                         switch (pes.stream_id){
2660                         case VIDEO_STREAM_S ... VIDEO_STREAM_E:
2661                                 l=pes.length;
2662                                 break;
2663                         default:
2664                                 l = 0;
2665                                 break;
2666                         }
2667                         while ( c < l - 6){
2668                                 if (buf[c] == 0x00 && 
2669                                     buf[c+1] == 0x00 &&
2670                                     buf[c+2] == 0x01 && 
2671                                     buf[c+3] == 0xB3) {
2672                                         c += 4;
2673                                         buf[c+3] &= 0x0f;
2674                                         buf[c+3] |= aspect;
2675                                 }
2676                                 else c++;
2677                         }
2678                         write_pes(fdout,&pes);
2679                 }
2680         } while( neof > 0 );
2681 }