]> git.vomp.tv Git - vompserver.git/blob - libdvbmpeg/ctools.c
Initial import
[vompserver.git] / libdvbmpeg / ctools.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 mocm@metzlerbros.de, 
27  */
28
29 #include "ctools.h"
30
31 #define MAX_SEARCH 1024 * 1024
32
33
34 /*
35
36       PES
37   
38 */
39
40 ssize_t save_read(int fd, void *buf, size_t count)
41 {
42         ssize_t neof = 1;
43         size_t re = 0;
44         
45         while(neof >= 0 && re < count){
46                 neof = read(fd, buf+re, count - re);
47                 if (neof > 0) re += neof;
48                 else break;
49         }
50
51         if (neof < 0 && re == 0) return neof;
52         else return re;
53 }
54
55 void init_pes(pes_packet *p){
56         p->stream_id = 0;
57         p->llength[0] = 0;
58         p->llength[1] = 0;
59         p->length = 0;
60         p->flags1 = 0x80;
61         p->flags2 = 0;
62         p->pes_hlength = 0;
63         p->trick = 0;
64         p->add_cpy = 0;
65         p->priv_flags = 0;
66         p->pack_field_length = 0;
67         p->pack_header = (uint8_t *) NULL;
68         p->pck_sqnc_cntr = 0;
69         p->org_stuff_length = 0;
70         p->pes_ext_lngth = 0;
71         p->pes_ext = (uint8_t *) NULL;
72         p->pes_pckt_data = (uint8_t *) NULL;
73         p->padding = 0;
74         p->mpeg = 2; // DEFAULT MPEG2
75         p->mpeg1_pad = 0;
76         p->mpeg1_headr = NULL;
77         p->stuffing = 0;
78 }
79
80 void kill_pes(pes_packet *p){
81         if (p->pack_header)
82                 free(p->pack_header);
83         if (p->pes_ext)
84                 free(p->pes_ext);
85         if (p->pes_pckt_data)
86                 free(p->pes_pckt_data);
87         if (p->mpeg1_headr)
88                 free(p->mpeg1_headr);
89         init_pes(p);
90 }
91
92 void setlength_pes(pes_packet *p){
93         short *ll;
94         ll = (short *) p->llength;
95         p->length = ntohs(*ll);
96 }
97
98 static void setl_pes(pes_packet *p){
99         setlength_pes(p);
100         if (p->length)
101                 p->pes_pckt_data = (uint8_t *)malloc(p->length);
102 }
103
104 void nlength_pes(pes_packet *p){
105         if (p->length <= 0xFFFF){
106                 short *ll = (short *) p->llength;
107                 short l = p->length;
108                 *ll = htons(l);
109         } else {
110                 p->llength[0] =0x00;
111                 p->llength[1] =0x00;
112         }
113 }
114
115 static void nl_pes(pes_packet *p)
116 {
117         nlength_pes(p);
118         p->pes_pckt_data = (uint8_t *) malloc(p->length);
119 }
120
121 void pts2pts(uint8_t *av_pts, uint8_t *pts)
122 {
123   
124         av_pts[0] = ((pts[0] & 0x06) << 5) | 
125                 ((pts[1] & 0xFC) >> 2); 
126         av_pts[1] = ((pts[1] & 0x03) << 6) |
127                 ((pts[2] & 0xFC) >> 2); 
128         av_pts[2] = ((pts[2] & 0x02) << 6) |
129                         ((pts[3] & 0xFE) >> 1);
130         av_pts[3] = ((pts[3] & 0x01) << 7) |
131                 ((pts[4] & 0xFE) >> 1);
132         
133 }
134
135
136 int cwrite_pes(uint8_t *buf, pes_packet *p, long length){
137         int count,i;
138         uint8_t dummy;
139         int more = 0;
140         uint8_t headr[3] = { 0x00, 0x00 , 0x01};
141
142         if (length <  p->length+p->pes_hlength){
143                 fprintf(stderr,"Wrong buffer size in cwrite_pes\n");
144                 exit(1);
145         }
146
147
148         memcpy(buf,headr,3);
149         count = 3;
150         buf[count] = p->stream_id;
151         count++;
152
153         switch ( p->stream_id ) {
154                                 
155         case PROG_STREAM_MAP:
156         case PRIVATE_STREAM2:
157         case PROG_STREAM_DIR:
158         case ECM_STREAM     :
159         case EMM_STREAM     :
160         case PADDING_STREAM :
161                 buf[count] = p->llength[0];
162                 count++;
163                 buf[count] = p->llength[1];
164                 count++;
165                 memcpy(buf+count,p->pes_pckt_data,p->length);
166                 count += p->length;
167                 break;
168         case DSM_CC_STREAM  :
169         case ISO13522_STREAM:
170         case PRIVATE_STREAM1:
171         case AUDIO_STREAM_S ... AUDIO_STREAM_E:
172         case VIDEO_STREAM_S ... VIDEO_STREAM_E:
173                 buf[count] = p->llength[0];
174                 count++;
175                 buf[count] = p->llength[1];
176                 count++;
177                 more = 1;
178                 break;
179         }       
180         
181
182         if ( more ) {
183                 if ( p->mpeg == 2 ){
184                         memcpy(buf+count,&p->flags1,1);
185                         count++;
186                         memcpy(buf+count,&p->flags2,1);
187                         count++;
188                         memcpy(buf+count,&p->pes_hlength,1);
189                         count++;
190                         
191                         if ((p->flags2 & PTS_DTS_FLAGS) == PTS_ONLY){
192                                 memcpy(buf+count,p->pts,5);
193                                 count += 5;
194                         } else 
195                                 if ((p->flags2 & PTS_DTS_FLAGS) == PTS_DTS){
196                                         memcpy(buf+count,p->pts,5);
197                                         count += 5;
198                                         memcpy(buf+count,p->dts,5);
199                                         count += 5;
200                                 }
201                         if (p->flags2 & ESCR_FLAG){
202                                 memcpy(buf+count,p->escr,6);
203                                 count += 6;
204                         }
205                         if (p->flags2 & ES_RATE_FLAG){
206                                 memcpy(buf+count,p->es_rate,3);
207                                 count += 3;
208                         }
209                         if (p->flags2 & DSM_TRICK_FLAG){
210                                 memcpy(buf+count,&p->trick,1);
211                                 count++;
212                         }
213                         if (p->flags2 & ADD_CPY_FLAG){
214                                 memcpy(buf+count,&p->add_cpy,1);
215                                 count++;
216                         }
217                         if (p->flags2 & PES_CRC_FLAG){
218                                 memcpy(buf+count,p->prev_pes_crc,2);
219                                 count += 2;
220                         }
221                         if (p->flags2 & PES_EXT_FLAG){
222                                 memcpy(buf+count,&p->priv_flags,1);
223                                 count++;
224
225                                 if (p->priv_flags & PRIVATE_DATA){
226                                         memcpy(buf+count,p->pes_priv_data,16);
227                                         count += 16;
228                                 }
229                                 if (p->priv_flags & HEADER_FIELD){
230                                         memcpy(buf+count,&p->pack_field_length,
231                                                1);
232                                         count++;
233                                         memcpy(buf+count,p->pack_header,
234                                                      p->pack_field_length);
235                                         count += p->pack_field_length;
236
237                                 }
238                                 
239                                 if ( p->priv_flags & PACK_SEQ_CTR){
240                                         memcpy(buf+count,&p->pck_sqnc_cntr,1);
241                                         count++;
242                                         memcpy(buf+count,&p->org_stuff_length,
243                                                1);
244                                         count++;
245                                 }
246                                 
247                                 if ( p->priv_flags & P_STD_BUFFER){
248                                         memcpy(buf+count,p->p_std,2);
249                                         count += 2;
250                                 }
251                                 if ( p->priv_flags & PES_EXT_FLAG2){
252                                         memcpy(buf+count,&p->pes_ext_lngth,1);
253                                         count++;
254                                         memcpy(buf+count,p->pes_ext,
255                                                      p->pes_ext_lngth);
256                                         count += p->pes_ext_lngth;
257                                 }
258                         }
259                         dummy = 0xFF;
260                         for (i=0;i<p->stuffing;i++) {
261                                 memcpy(buf+count,&dummy,1);
262                                 count++;
263                         }
264                 } else {
265                         if (p->mpeg1_pad){
266                                 memcpy(buf+count,p->mpeg1_headr,p->mpeg1_pad);
267                                 count += p->mpeg1_pad;
268                         }
269                         if ((p->flags2 & PTS_DTS_FLAGS) == PTS_ONLY){
270                                 memcpy(buf+count,p->pts,5);
271                                 count += 5;
272                         }
273                         else if ((p->flags2 & PTS_DTS_FLAGS) == 
274                                  PTS_DTS){
275                                 memcpy(buf+count,p->pts,5);
276                                         count += 5;
277                                 memcpy(buf+count,p->dts,5);
278                                         count += 5;
279                         }
280                 }                       
281                 memcpy(buf+count,p->pes_pckt_data,p->length);
282                 count += p->length;
283         }
284
285         return count;
286
287 }
288
289 void write_pes(int fd, pes_packet *p){
290         long length;
291         uint8_t *buf;
292         int l = p->length+p->pes_hlength;
293         
294         buf = (uint8_t *) malloc(l);
295         length = cwrite_pes(buf,p,l);
296         write(fd,buf,length);
297         free(buf);
298 }
299
300 static unsigned int find_length(int f){
301         uint64_t p = 0;
302         uint64_t start = 0;
303         uint64_t q = 0;
304         int found = 0;
305         uint8_t sync4[4];
306         int neof = 1;
307
308         start = lseek(f,0,SEEK_CUR);
309         start -=2;
310         lseek(f,start,SEEK_SET);
311         while ( neof > 0 && !found ){
312                 p = lseek(f,0,SEEK_CUR);
313                 neof = save_read(f,&sync4,4);
314                 if (sync4[0] == 0x00 && sync4[1] == 0x00 && sync4[2] == 0x01) {
315                         switch ( sync4[3] ) {
316                                 
317                         case PROG_STREAM_MAP:
318                         case PRIVATE_STREAM2:
319                         case PROG_STREAM_DIR:
320                         case ECM_STREAM     :
321                         case EMM_STREAM     :
322                         case PADDING_STREAM :
323                         case DSM_CC_STREAM  :
324                         case ISO13522_STREAM:
325                         case PRIVATE_STREAM1:
326                         case AUDIO_STREAM_S ... AUDIO_STREAM_E:
327                         case VIDEO_STREAM_S ... VIDEO_STREAM_E:
328                                 found = 1;
329                                 break;
330                         default:
331                                 q = lseek(f,0,SEEK_CUR);
332                                 break;
333                         }       
334                 } 
335         }
336         q = lseek(f,0,SEEK_CUR);
337         lseek(f,start+2,SEEK_SET);
338         if (found) return (unsigned int)(q-start)-4-2;
339         else return (unsigned int)(q-start-2);
340         
341 }
342
343
344 void cread_pes(char *buf, pes_packet *p){
345         
346         uint8_t count, dummy, check;
347         int i;
348         uint64_t po = 0;
349         int c=0;
350
351         switch ( p->stream_id ) {
352                 
353         case PROG_STREAM_MAP:
354         case PRIVATE_STREAM2:
355         case PROG_STREAM_DIR:
356         case ECM_STREAM     :
357         case EMM_STREAM     :
358                 memcpy(p->pes_pckt_data,buf+c,p->length);
359                 return;
360                 break;
361         case PADDING_STREAM :
362                 p->padding = p->length;
363                 memcpy(p->pes_pckt_data,buf+c,p->length);
364                 return;
365                 break;                  
366         case DSM_CC_STREAM  :
367         case ISO13522_STREAM:
368         case PRIVATE_STREAM1:
369         case AUDIO_STREAM_S ... AUDIO_STREAM_E:
370         case VIDEO_STREAM_S ... VIDEO_STREAM_E:
371                 break;
372         default:
373                 return;
374                 break;
375         }       
376         
377         po = c;
378         memcpy(&p->flags1,buf+c,1);
379         c++;
380         if ( (p->flags1 & 0xC0) == 0x80 ) p->mpeg = 2;
381         else p->mpeg = 1;
382         
383         if ( p->mpeg == 2 ){
384                 memcpy(&p->flags2,buf+c,1);
385                 c++;
386                 memcpy(&p->pes_hlength,buf+c,1);
387                 c++;
388                 
389                 p->length -=p->pes_hlength+3;
390                 count = p->pes_hlength;
391                 
392                 if ((p->flags2 & PTS_DTS_FLAGS) == PTS_ONLY){
393                         memcpy(p->pts,buf+c,5);
394                         c += 5;
395                         count -=5;
396                 } else 
397                         if ((p->flags2 & PTS_DTS_FLAGS) == PTS_DTS){
398                                 memcpy(p->pts,buf+c,5);
399                                 c += 5;
400                                 memcpy(p->dts,buf+c,5);
401                                 c += 5;
402                                 count -= 10;
403                         }
404                 
405                 if (p->flags2 & ESCR_FLAG){
406                         memcpy(p->escr,buf+c,6);
407                         c += 6;
408                         count -= 6;
409                 }
410                 
411                 if (p->flags2 & ES_RATE_FLAG){
412                         memcpy(p->es_rate,buf+c,3);
413                         c += 3;
414                         count -= 3;
415                 }
416
417                 if (p->flags2 & DSM_TRICK_FLAG){
418                         memcpy(&p->trick,buf+c,1);
419                         c += 1;
420                         count -= 1;
421                 }
422                 
423                 if (p->flags2 & ADD_CPY_FLAG){
424                         memcpy(&p->add_cpy,buf+c,1);
425                         c++;
426                         count -= 1;
427                 }
428                 
429                 if (p->flags2 & PES_CRC_FLAG){
430                         memcpy(p->prev_pes_crc,buf+c,2);
431                         c += 2;
432                         count -= 2;
433                 }                       
434                 
435                 if (p->flags2 & PES_EXT_FLAG){
436                         memcpy(&p->priv_flags,buf+c,1);
437                         c++;
438                         count -= 1;
439                         
440                         if (p->priv_flags & PRIVATE_DATA){
441                                 memcpy(p->pes_priv_data,buf+c,16);
442                                 c += 16;
443                                 count -= 16;
444                         }
445                         
446                         if (p->priv_flags & HEADER_FIELD){
447                                 memcpy(&p->pack_field_length,buf+c,1);
448                                 c++;
449                                 p->pack_header = (uint8_t *)
450                                         malloc(p->pack_field_length);
451                                 memcpy(p->pack_header,buf+c,
452                                        p->pack_field_length);
453                                 c += p->pack_field_length;
454                                 count -= 1+p->pack_field_length;
455                         }
456                         
457                         if ( p->priv_flags & PACK_SEQ_CTR){
458                                 memcpy(&p->pck_sqnc_cntr,buf+c,1);
459                                 c++;
460                                 memcpy(&p->org_stuff_length,buf+c,1);
461                                 c++;
462                                 count -= 2;
463                         }
464                         
465                         if ( p->priv_flags & P_STD_BUFFER){
466                                 memcpy(p->p_std,buf+c,2);
467                                 c += 2;
468                                 count -= 2;
469                         }
470
471                         if ( p->priv_flags & PES_EXT_FLAG2){
472                                 memcpy(&p->pes_ext_lngth,buf+c,1);
473                                 c++;
474                                 p->pes_ext = (uint8_t *)
475                                         malloc(p->pes_ext_lngth);
476                                 memcpy(p->pes_ext,buf+c,
477                                        p->pes_ext_lngth);
478                                 c += p->pes_ext_lngth;
479                                 count -= 1+p->pes_ext_lngth;
480                         }
481                 }
482                 p->stuffing = count;
483                 for(i = 0; i< count ;i++){ 
484                         memcpy(&dummy,buf+c,1);
485                         c++;
486                 }
487         } else {
488                 p->mpeg1_pad = 1;
489                 check = p->flags1;
490                 while (check == 0xFF){
491                         memcpy(&check,buf+c,1);
492                         c++;
493                         p->mpeg1_pad++;
494                 }
495                 
496                 if ( (check & 0xC0) == 0x40){
497                         memcpy(&check,buf+c,1);
498                         c++;
499                         p->mpeg1_pad++;
500                         memcpy(&check,buf+c,1);
501                         c++;
502                         p->mpeg1_pad++;
503                 }
504                 p->flags2 = 0;
505                 p->length -= p->mpeg1_pad;
506                 
507                 c = po;
508                 if ( (check & 0x30)){
509                         p->length ++;
510                         p->mpeg1_pad --;
511                         
512                         if (check == p->flags1){
513                                 p->pes_hlength = 0;
514                         } else {
515                                 p->mpeg1_headr = (uint8_t *)
516                                         malloc(p->mpeg1_pad);
517                                 p->pes_hlength = p->mpeg1_pad;
518                                 memcpy(p->mpeg1_headr,buf+c,
519                                        p->mpeg1_pad);
520                                 c += p->mpeg1_pad;
521                         }
522                         
523                         p->flags2 = (check & 0xF0) << 2;
524                         if ((p->flags2 & PTS_DTS_FLAGS) == PTS_ONLY){
525                                 memcpy(p->pts,buf+c,5);
526                                 c += 5;
527                                 p->length -= 5;
528                                 p->pes_hlength += 5;
529                         }
530                         else if ((p->flags2 & PTS_DTS_FLAGS) == 
531                                  PTS_DTS){
532                                 memcpy(p->pts,buf+c,5);
533                                 c += 5;
534                                 memcpy(p->dts,buf+c,5);
535                                 c += 5;
536                                 p->length -= 10;
537                                 p->pes_hlength += 10;
538                         }
539                 } else {
540                         p->mpeg1_headr = (uint8_t *) malloc(p->mpeg1_pad);
541                         p->pes_hlength = p->mpeg1_pad;
542                         memcpy(p->mpeg1_headr,buf+c,
543                                p->mpeg1_pad);
544                         c += p->mpeg1_pad;
545                 }
546         }
547         memcpy(p->pes_pckt_data,buf+c,p->length);
548 }
549
550
551 int read_pes(int f, pes_packet *p){
552         
553         uint8_t sync4[4];
554         int found=0;
555         uint64_t po = 0;
556         int neof = 1;
557         uint8_t *buf;
558
559         while (neof > 0 && !found) {
560                 po = lseek(f,0,SEEK_CUR);
561                 if (po < 0) return -1;
562                 if ((neof = save_read(f,&sync4,4)) < 4) return -1;
563                 if (sync4[0] == 0x00 && sync4[1] == 0x00 && sync4[2] == 0x01) {
564                         p->stream_id = sync4[3];
565                         switch ( sync4[3] ) {
566                                 
567                         case PROG_STREAM_MAP:
568                         case PRIVATE_STREAM2:
569                         case PROG_STREAM_DIR:
570                         case ECM_STREAM     :
571                         case EMM_STREAM     :
572                         case PADDING_STREAM :
573                         case DSM_CC_STREAM  :
574                         case ISO13522_STREAM:
575                         case PRIVATE_STREAM1:
576                         case AUDIO_STREAM_S ... AUDIO_STREAM_E:
577                         case VIDEO_STREAM_S ... VIDEO_STREAM_E:
578                                 if((neof = save_read(f,p->llength,2)) < 2)
579                                         return -1;
580                                 setl_pes(p);
581                                 if (!p->length){ 
582                                         p->length = find_length(f);
583                                         nl_pes(p);
584                                 }
585                                 found = 1;
586                                 break;
587                                 
588                         default:
589                                 if (lseek(f,po+1,SEEK_SET) < po+1) return -1;
590                         break;
591                         }       
592                 } else if(lseek(f,po+1,SEEK_SET) < po+1) return -1;
593         }
594
595         if (!found || !p->length) return 0;
596         
597         if (p->length >0){
598                 buf = (uint8_t *) malloc(p->length);
599                 if((neof = save_read(f,buf,p->length))< p->length) return -1;
600                 cread_pes((char *)buf,p);
601                 free(buf);
602         } else return 0;
603
604         return neof;
605 }
606
607 /*
608
609    Transport Stream
610
611 */
612
613 void init_ts(ts_packet *p){
614         p->pid[0] = 0;
615         p->pid[1] = 0;
616         p->flags = 0;
617         p->count = 0;
618         p->adapt_length = 0;
619         p->adapt_flags = 0;
620         p->splice_count = 0;
621         p->priv_dat_len = 0;
622         p->priv_dat = NULL;
623         p->adapt_ext_len = 0;
624         p->adapt_eflags = 0;
625         p->rest = 0;
626         p->stuffing = 0;
627 }
628
629 void kill_ts(ts_packet *p){
630         if (p->priv_dat)
631                 free(p->priv_dat);
632         init_ts(p);
633 }
634
635
636
637 unsigned short pid_ts(ts_packet *p)
638 {
639   return get_pid(p->pid);
640 }
641
642 int cwrite_ts(uint8_t *buf, ts_packet *p, long length){
643         long count,i;
644         uint8_t sync,dummy;
645
646         sync = 0x47;
647         memcpy(buf,&sync,1);
648         count = 1;
649         memcpy(buf+count,p->pid,2);
650         count += 2;
651         memcpy(buf+count,&p->flags,1);
652         count++;
653
654          
655         if (! (p->flags & ADAPT_FIELD) && (p->flags & PAYLOAD)){
656                 memcpy(buf+count,p->data,184);
657                 count += 184;
658         } else {
659                 memcpy(buf+count,&p->adapt_length,1);
660                 count++;
661                 memcpy(buf+count,&p->adapt_flags,1);
662                 count++;
663
664                 if ( p->adapt_flags & PCR_FLAG ){
665                         memcpy(buf+count, p->pcr,6);
666                         count += 6;
667                 }
668                 if ( p->adapt_flags & OPCR_FLAG ){
669                         memcpy(buf+count, p->opcr,6);
670                         count += 6;
671                 }
672                 if ( p->adapt_flags & SPLICE_FLAG ){
673                         memcpy(buf+count, &p->splice_count,1);
674                         count++;
675                 }
676                 if( p->adapt_flags & TRANS_PRIV){
677                         memcpy(buf+count,&p->priv_dat_len,1);
678                         count++;
679                         memcpy(buf+count,p->priv_dat,p->priv_dat_len);
680                         count += p->priv_dat_len;
681                 }
682                         
683                 if( p->adapt_flags & ADAP_EXT_FLAG){
684                         memcpy(buf+count,&p->adapt_ext_len,1);
685                         count++;
686                         memcpy(buf+count,&p->adapt_eflags,1);
687                         count++;
688                 
689                         if( p->adapt_eflags & LTW_FLAG){
690                                 memcpy(buf+count,p->ltw,2);
691                                 count += 2;
692                         }
693                         if( p->adapt_eflags & PIECE_RATE){
694                                 memcpy(buf+count,p->piece_rate,3);
695                                 count += 3;
696                         }
697                         if( p->adapt_eflags & SEAM_SPLICE){
698                                 memcpy(buf+count,p->dts,5);
699                                 count += 5;
700                         }
701                 }
702                 dummy = 0xFF;
703                 for(i=0; i < p->stuffing ; i++){
704                         memcpy(buf+count,&dummy,1);
705                         count++;
706                 }
707                 if (p->flags & PAYLOAD){
708                         memcpy(buf+count,p->data,p->rest);
709                         count += p->rest;
710                 }
711         } 
712
713
714         return count;
715 }
716
717 void write_ts(int fd, ts_packet *p){
718         long length;
719         uint8_t buf[TS_SIZE];
720
721         length = cwrite_ts(buf,p,TS_SIZE);
722         write(fd,buf,length);
723 }
724
725 int read_ts (int f, ts_packet *p){
726         uint8_t sync;
727         int found=0;
728         uint64_t po,q;
729         int neof = 1;
730
731         sync=0;
732         while (neof > 0 && !found) {
733                 neof = save_read(f,&sync,1);
734                 if (sync == 0x47) 
735                         found = 1;
736         }
737         neof = save_read(f,p->pid,2);
738         neof = save_read(f,&p->flags,1);
739         p->count = p->flags & COUNT_MASK;
740          
741         if (!(p->flags & ADAPT_FIELD) && (p->flags & PAYLOAD)){
742                 //no adapt. field only payload
743                 neof = save_read(f,p->data,184);
744                 p->rest = 184;
745                 return neof;
746         } 
747
748         if ( p->flags & ADAPT_FIELD ) {
749                 // adaption field
750                 neof = save_read(f,&p->adapt_length,1);
751                 po = lseek(f,0,SEEK_CUR);
752                 neof = save_read(f,&p->adapt_flags,1);
753
754                 if ( p->adapt_flags & PCR_FLAG )
755                         neof = save_read(f, p->pcr,6);
756
757                 if ( p->adapt_flags & OPCR_FLAG )
758                         neof = save_read(f, p->opcr,6);
759
760                 if ( p->adapt_flags & SPLICE_FLAG )
761                         neof = save_read(f, &p->splice_count,1);
762
763                 if( p->adapt_flags & TRANS_PRIV){
764                         neof = save_read(f,&p->priv_dat_len,1);
765                         p->priv_dat = (uint8_t *) malloc(p->priv_dat_len);
766                         neof = save_read(f,p->priv_dat,p->priv_dat_len);
767                 }
768                         
769                 if( p->adapt_flags & ADAP_EXT_FLAG){
770                         neof = save_read(f,&p->adapt_ext_len,1);
771                         neof = save_read(f,&p->adapt_eflags,1);
772                         if( p->adapt_eflags & LTW_FLAG)
773                                 neof = save_read(f,p->ltw,2);
774                         
775                         if( p->adapt_eflags & PIECE_RATE)
776                                 neof = save_read(f,p->piece_rate,3);
777                         
778                         if( p->adapt_eflags & SEAM_SPLICE)
779                                 neof = save_read(f,p->dts,5);
780                 }
781                 q = lseek(f,0,SEEK_CUR);
782                 p->stuffing = p->adapt_length -(q-po);
783                 p->rest = 183-p->adapt_length;
784                 lseek(f,q+p->stuffing,SEEK_SET);
785                 if (p->flags & PAYLOAD) // payload
786                         neof = save_read(f,p->data,p->rest);
787                 else 
788                         lseek(f,q+p->rest,SEEK_SET);
789         }
790         return neof;
791 }
792
793 void cread_ts (char *buf, ts_packet *p, long length){
794         uint8_t sync;
795         int found=0;
796         uint64_t po,q;
797         long count=0;
798         
799         sync=0;
800         while (count < length  && !found) {
801                 sync=buf[count];
802                 count++;
803                 if (sync == 0x47) 
804                         found = 1;
805         }
806         memcpy(p->pid,buf+count,2);
807         count += 2;
808         p->flags = buf[count];
809         count++;
810         p->count = p->flags & COUNT_MASK;
811          
812         if (!(p->flags & ADAPT_FIELD) && (p->flags & PAYLOAD)){
813                 //no adapt. field only payload
814                 memcpy(p->data,buf+count,184);
815                 p->rest = 184;
816                 return;
817         } 
818
819         if ( p->flags & ADAPT_FIELD ) {
820                 // adaption field
821                 p->adapt_length = buf[count];
822                 count++;
823                 po = count;
824                 memcpy(&p->adapt_flags,buf+count,1);
825                 count++;
826
827                 if ( p->adapt_flags & PCR_FLAG ){
828                         memcpy( p->pcr,buf+count,6);
829                         count += 6;
830                 }
831                 if ( p->adapt_flags & OPCR_FLAG ){
832                         memcpy( p->opcr,buf+count,6);
833                         count += 6;
834                 }
835                 if ( p->adapt_flags & SPLICE_FLAG ){
836                         memcpy( &p->splice_count,buf+count,1);
837                         count++;
838                 }
839                 if( p->adapt_flags & TRANS_PRIV){
840                         memcpy(&p->priv_dat_len,buf+count,1);
841                         count++;
842                         p->priv_dat = (uint8_t *) malloc(p->priv_dat_len);
843                         memcpy(p->priv_dat,buf+count,p->priv_dat_len);
844                         count += p->priv_dat_len;
845                 }
846                         
847                 if( p->adapt_flags & ADAP_EXT_FLAG){
848                         memcpy(&p->adapt_ext_len,buf+count,1);
849                         count++;
850                         memcpy(&p->adapt_eflags,buf+count,1);
851                         count++;
852                         if( p->adapt_eflags & LTW_FLAG){
853                                 memcpy(p->ltw,buf+count,2);
854                                 count += 2;
855                         }
856                         if( p->adapt_eflags & PIECE_RATE){
857                                 memcpy(p->piece_rate,buf+count,3);
858                                 count += 3;
859                         }
860                         if( p->adapt_eflags & SEAM_SPLICE){
861                                 memcpy(p->dts,buf+count,5);
862                                 count += 5;
863                         }
864                 }
865                 q = count;
866                 p->stuffing = p->adapt_length -(q-po);
867                 p->rest = 183-p->adapt_length;
868                 count = q+p->stuffing;
869                 if (p->flags & PAYLOAD){ // payload
870                         memcpy(p->data,buf+count,p->rest);
871                         count += p->rest;
872                 } else 
873                         count = q+p->rest;
874         }
875 }
876
877
878 /*
879
880    Program Stream
881
882 */
883
884
885 void init_ps(ps_packet *p)
886 {
887         p->stuff_length=0xF8;
888         p->data = NULL;
889         p->sheader_length = 0;
890         p->audio_bound = 0;
891         p->video_bound = 0;
892         p->npes = 0;
893         p->mpeg = 2;
894 }
895
896 void kill_ps(ps_packet *p)
897 {
898         if (p->data)
899                 free(p->data);
900         init_ps(p);
901 }
902
903 void setlength_ps(ps_packet *p)
904 {
905         short *ll;
906         ll = (short *) p->sheader_llength;
907         if (p->mpeg == 2)
908                 p->sheader_length = ntohs(*ll) - 6;
909         else 
910                 p->sheader_length = ntohs(*ll);
911 }       
912
913 static void setl_ps(ps_packet *p)
914 {
915         setlength_ps(p);
916         p->data = (uint8_t *) malloc(p->sheader_length);
917 }
918
919 int mux_ps(ps_packet *p)
920 {
921         uint32_t mux = 0;
922         uint8_t *i = (uint8_t *)&mux;
923
924         i[1] = p->mux_rate[0];
925         i[2] = p->mux_rate[1];
926         i[3] = p->mux_rate[2];
927         mux = ntohl(mux);
928         mux = (mux >>2);
929         return mux;
930 }
931
932 int rate_ps(ps_packet *p)
933 {
934         uint32_t rate=0;
935         uint8_t *i= (uint8_t *) &rate;
936
937         i[1] = p->rate_bound[0] & 0x7F;
938         i[2] = p->rate_bound[1];
939         i[3] = p->rate_bound[2];
940         
941         rate = ntohl(rate);
942         rate = (rate >> 1);
943         return rate;
944 }
945
946
947 uint32_t scr_base_ps(ps_packet *p) // only 32 bit!!
948 {
949         uint32_t base = 0;
950         uint8_t *buf = (uint8_t *)&base;
951         
952         buf[0] |= (long int)((p->scr[0] & 0x18) << 3);
953         buf[0] |= (long int)((p->scr[0] & 0x03) << 4);
954         buf[0] |= (long int)((p->scr[1] & 0xF0) >> 4);
955                  
956         buf[1] |= (long int)((p->scr[1] & 0x0F) << 4);
957         buf[1] |= (long int)((p->scr[2] & 0xF0) >> 4);
958
959         buf[2] |= (long int)((p->scr[2] & 0x08) << 4);
960         buf[2] |= (long int)((p->scr[2] & 0x03) << 5);
961         buf[2] |= (long int)((p->scr[3] & 0xF8) >> 3);
962
963         buf[3] |= (long int)((p->scr[3] & 0x07) << 5);
964         buf[3] |= (long int)((p->scr[4] & 0xF8) >> 3);
965
966         base = ntohl(base);
967         return base;
968 }
969
970 uint16_t scr_ext_ps(ps_packet *p)
971 {
972         short ext = 0;
973
974         ext = (short)(p->scr[5] >> 1);
975         ext += (short) (p->scr[4] &  0x03) * 128;
976
977         return ext;
978 }
979
980 int cwrite_ps(uint8_t *buf, ps_packet *p, long length)
981 {
982         long count,i;
983         uint8_t headr1[4] = {0x00, 0x00, 0x01, 0xBA };
984         uint8_t headr2[4] = {0x00, 0x00, 0x01, 0xBB };
985         uint8_t buffy = 0xFF;
986
987         
988         memcpy(buf,headr1,4);
989         count = 4;
990         if (p->mpeg == 2){
991                 memcpy(buf+count,p->scr,6);
992                 count += 6;
993                 memcpy(buf+count,p->mux_rate,3);
994                 count += 3;
995                 memcpy(buf+count,&p->stuff_length,1);
996                 count++;
997                 for(i=0; i< (p->stuff_length & 3); i++){
998                         memcpy(buf+count,&buffy,1);
999                         count++;
1000                 }
1001         } else {
1002                 memcpy(buf+count,p->scr,5);
1003                 count += 5;
1004                 memcpy(buf+count,p->mux_rate,3);
1005                 count += 3;
1006         }
1007         if (p->sheader_length){
1008                 memcpy(buf+count,headr2,4);
1009                 count += 4;
1010                 memcpy(buf+count,p->sheader_llength,2);
1011                 count += 2;
1012                 if ( p->mpeg == 2){
1013                         memcpy(buf+count,p->rate_bound,3);
1014                         count += 3;
1015                         memcpy(buf+count,&p->audio_bound,1);
1016                         count++;
1017                         memcpy(buf+count,&p->video_bound,1);
1018                         count++;
1019                         memcpy(buf+count,&p->reserved,1);
1020                         count++;
1021                 }
1022                 memcpy(buf+count,p->data,p->sheader_length);
1023                 count += p->sheader_length;
1024         }
1025
1026         return count;
1027 }
1028
1029 void write_ps(int fd, ps_packet *p){
1030         long length;
1031         uint8_t buf[PS_MAX];
1032
1033         length = cwrite_ps(buf,p,PS_MAX);
1034         write(fd,buf,length);
1035 }
1036
1037 int read_ps (int f, ps_packet *p){
1038         uint8_t headr[4];
1039         pes_packet pes;
1040         int i,done;
1041         int found=0;
1042         uint64_t po = 0;
1043         uint64_t q = 0;
1044         long count = 0;
1045         int neof = 1;
1046
1047         po = lseek(f,0,SEEK_CUR);
1048         while (neof > 0 && !found && count < MAX_SEARCH) {
1049                 neof = save_read(f,&headr,4);
1050                 if (headr[0] == 0x00 && headr[1] == 0x00 && headr[2] == 0x01){
1051                         if ( headr[3] == 0xBA ) 
1052                                 found = 1;
1053                         else 
1054                                 if ( headr[3] == 0xB9 ) break;
1055                                 else lseek(f,po+1,SEEK_SET);
1056                 }
1057                 count++;
1058         }
1059         
1060         if (found){
1061                 neof = save_read(f,p->scr,6);
1062                 if (p->scr[0] & 0x40)
1063                         p->mpeg = 2;
1064                 else
1065                         p->mpeg = 1;
1066
1067                 if (p->mpeg == 2){
1068                         neof = save_read(f,p->mux_rate,3);
1069                         neof = save_read(f,&p->stuff_length,1);
1070                         po = lseek(f,0,SEEK_CUR);
1071                         lseek(f,po+(p->stuff_length & 3),SEEK_SET);
1072                 } else {
1073                         p->mux_rate[0] = p->scr[5]; //mpeg1 scr is only 5 bytes
1074                         neof = save_read(f,p->mux_rate+1,2);
1075                 }
1076                         
1077                 po = lseek(f,0,SEEK_CUR);
1078                 neof = save_read(f,headr,4);
1079                 if (headr[0] == 0x00 && headr[1] == 0x00 && 
1080                     headr[2] == 0x01 && headr[3] == 0xBB ) {
1081                         neof = save_read(f,p->sheader_llength,2);
1082                         setl_ps(p);
1083                         if (p->mpeg == 2){
1084                                 neof = save_read(f,p->rate_bound,3);
1085                                 neof = save_read(f,&p->audio_bound,1);
1086                                 neof = save_read(f,&p->video_bound,1);
1087                                 neof = save_read(f,&p->reserved,1);
1088                         }
1089                         neof = save_read(f,p->data,p->sheader_length);
1090                 } else {
1091                         lseek(f,po,SEEK_SET);
1092                         p->sheader_length = 0;
1093                 }
1094
1095                 i = 0;
1096                 done = 0;
1097                 q = lseek(f,0,SEEK_CUR);
1098                 do {
1099                         po = lseek(f,0,SEEK_CUR);
1100                         neof = save_read(f,headr,4);
1101                         lseek(f,po,SEEK_SET);
1102                         if ( headr[0] == 0x00 && headr[1] == 0x00 
1103                              && headr[2] == 0x01 && headr[3] != 0xBA){
1104                                 init_pes(&pes);
1105                                 neof = read_pes(f,&pes);
1106                                 i++;
1107                         } else done = 1;
1108                         kill_pes(&pes);
1109                 } while ( neof > 0 && !done);
1110                 p->npes = i;
1111                 lseek(f,q,SEEK_SET);
1112         } 
1113         return neof;
1114 }
1115
1116 void cread_ps (char *buf, ps_packet *p, long length){
1117         uint8_t *headr;
1118         pes_packet pes;
1119         int i,done;
1120         int found=0;
1121         uint64_t po = 0;
1122         uint64_t q = 0;
1123         long count = 0;
1124         long c = 0;
1125         
1126         po = c;
1127         while ( count < length && !found && count < MAX_SEARCH) {
1128                 headr = (uint8_t *)buf+c;
1129                 c += 4;
1130                 if (headr[0] == 0x00 && headr[1] == 0x00 && headr[2] == 0x01){
1131                         if ( headr[3] == 0xBA ) 
1132                                 found = 1;
1133                         else 
1134                                 if ( headr[3] == 0xB9 ) break;
1135                                 else c = po+1;
1136                 }
1137                 count++;
1138         }
1139         
1140         if (found){
1141                 memcpy(p->scr,buf+c,6);
1142                 c += 6;
1143                 if (p->scr[0] & 0x40)
1144                         p->mpeg = 2;
1145                 else
1146                         p->mpeg = 1;
1147
1148                 if (p->mpeg == 2){
1149                         memcpy(p->mux_rate,buf+c,3);
1150                         c += 3;
1151                         memcpy(&p->stuff_length,buf+c,1);
1152                         c++;
1153                         po = c;
1154                         c = po+(p->stuff_length & 3);
1155                 } else {
1156                         p->mux_rate[0] = p->scr[5]; //mpeg1 scr is only 5 bytes
1157                         memcpy(p->mux_rate+1,buf+c,2);
1158                         c += 2;
1159                 }
1160                         
1161                 po = c;
1162                 headr = (uint8_t *)buf+c;
1163                 c += 4;
1164                 if (headr[0] == 0x00 && headr[1] == 0x00 && 
1165                     headr[2] == 0x01 && headr[3] == 0xBB ) {
1166                         memcpy(p->sheader_llength,buf+c,2);
1167                         c += 2;
1168                         setl_ps(p);
1169                         if (p->mpeg == 2){
1170                                 memcpy(p->rate_bound,buf+c,3);
1171                                 c += 3;
1172                                 memcpy(&p->audio_bound,buf+c,1);
1173                                 c++;
1174                                 memcpy(&p->video_bound,buf+c,1);
1175                                 c++;
1176                                 memcpy(&p->reserved,buf+c,1);
1177                                 c++;
1178                         }
1179                         memcpy(p->data,buf+c,p->sheader_length);
1180                         c += p->sheader_length;
1181                 } else {
1182                         c = po;
1183                         p->sheader_length = 0;
1184                 }
1185
1186                 i = 0;
1187                 done = 0;
1188                 q = c;
1189                 do {
1190                         headr = (uint8_t *)buf+c;
1191                         if ( headr[0] == 0x00 && headr[1] == 0x00 
1192                              && headr[2] == 0x01 && headr[3] != 0xBA){
1193                                 init_pes(&pes);
1194                                 //      cread_pes(buf+c,&pes);
1195                                 i++;
1196                         } else done = 1;
1197                         kill_pes(&pes);
1198                 } while (c < length && !done);
1199                 p->npes = i;
1200                 c = q;
1201         } 
1202 }
1203
1204
1205
1206
1207
1208
1209
1210 /*
1211   conversion
1212 */
1213
1214 void init_trans(trans *p)
1215 {
1216         int i;
1217
1218         p->found = 0;
1219         p->pes = 0;
1220         p->is_full = 0;
1221         p->pes_start = 0;
1222         p->pes_started = 0;
1223         p->set = 0;
1224
1225         for (i = 0; i < MASKL*MAXFILT ; i++){
1226                 p->mask[i] = 0;
1227                 p->filt[i] = 0;
1228         }
1229         for (i = 0; i < MAXFILT ; i++){
1230                 p->sec[i].found = 0;
1231                 p->sec[i].length = 0;
1232         }       
1233 }
1234
1235 int set_trans_filt(trans *p, int filtn, uint16_t pid, uint8_t *mask, uint8_t *filt, int pes)
1236 {
1237         int i;
1238         int off;
1239
1240         if ( filtn > MAXFILT-1 || filtn<0 ) return -1;
1241         p->pid[filtn] = pid;
1242         if (pes) p->pes |= (tflags)(1 << filtn);
1243         else {
1244                 off = MASKL*filtn;
1245                 p->pes &= ~((tflags) (1 << filtn) );
1246                 for (i = 0; i < MASKL ; i++){
1247                         p->mask[off+i] = mask[i];
1248                         p->filt[off+i] = filt[i];
1249                 }
1250         }               
1251         p->set |= (tflags) (1 << filtn);
1252         return 0;
1253 }
1254
1255 void clear_trans_filt(trans *p,int filtn)
1256 {
1257         int i;
1258
1259         p->set &= ~((tflags) (1 << filtn) );
1260         p->pes &= ~((tflags) (1 << filtn) );
1261         p->is_full &= ~((tflags) (1 << filtn) );
1262         p->pes_start &= ~((tflags) (1 << filtn) );
1263         p->pes_started &= ~((tflags) (1 << filtn) );
1264
1265         for (i = MASKL*filtn; i < MASKL*(filtn+1) ; i++){
1266                 p->mask[i] = 0;
1267                 p->filt[i] = 0;
1268         }
1269         p->sec[filtn].found = 0;
1270         p->sec[filtn].length = 0;
1271 }
1272
1273 int filt_is_set(trans *p, int filtn)
1274 {
1275         if (p->set & ((tflags)(1 << filtn))) return 1;
1276         return 0;
1277 }
1278
1279 int pes_is_set(trans *p, int filtn)
1280 {
1281         if (p->pes & ((tflags)(1 << filtn))) return 1;
1282         return 0;
1283 }
1284
1285 int pes_is_started(trans *p, int filtn)
1286 {
1287         if (p->pes_started & ((tflags)(1 << filtn))) return 1;
1288         return 0;
1289 }
1290
1291 int pes_is_start(trans *p, int filtn)
1292 {
1293         if (p->pes_start & ((tflags)(1 << filtn))) return 1;
1294         return 0;
1295 }
1296
1297 int filt_is_ready(trans *p,int filtn)
1298 {
1299         if (p->is_full & ((tflags)(1 << filtn))) return 1;
1300         return 0;
1301 }
1302
1303 void trans_filt(uint8_t *buf, int count, trans *p)
1304 {
1305         int c=0;
1306         //fprintf(stderr,"trans_filt\n");
1307         
1308
1309         while (c < count && p->found <1 ){
1310                 if ( buf[c] == 0x47) p->found = 1;
1311                 c++;
1312                 p->packet[0] = 0x47;
1313         }
1314         if (c == count) return;
1315         
1316         while( c < count && p->found < 188 && p->found > 0 ){
1317                 p->packet[p->found] = buf[c];
1318                 c++;
1319                 p->found++;
1320         }
1321         if (p->found == 188){
1322                 p->found = 0;
1323                 tfilter(p);
1324         }
1325
1326         if (c < count) trans_filt(buf+c,count-c,p);
1327
1328
1329
1330 void tfilter(trans *p)
1331 {
1332         int l,c;
1333         int tpid;
1334         uint8_t flag,flags;
1335         uint8_t adapt_length = 0;
1336         uint8_t cpid[2];
1337
1338
1339         //      fprintf(stderr,"tfilter\n");
1340
1341         cpid[0] = p->packet[1];
1342         cpid[1] = p->packet[2];
1343         tpid = get_pid(cpid);
1344
1345         if ( p->packet[1]&0x80){
1346                 fprintf(stderr,"Error in TS for PID: %d\n", 
1347                         tpid);
1348         }
1349
1350         flag = cpid[0];
1351         flags = p->packet[3];
1352         
1353         if ( flags & ADAPT_FIELD ) {
1354                 // adaption field
1355                 adapt_length = p->packet[4];
1356         }
1357
1358         c = 5 + adapt_length - (int)(!(flags & ADAPT_FIELD));
1359         if (flags & PAYLOAD){
1360                 for ( l = 0; l < MAXFILT ; l++){
1361                         if ( filt_is_set(p,l) ) {
1362                                 if ( p->pid[l] == tpid) {
1363                                         if ( pes_is_set(p,l) ){
1364                                                 if (cpid[0] & PAY_START){
1365                                                         p->pes_started |= 
1366                                                                 (tflags) 
1367                                                                 (1 << l);
1368                                                         p->pes_start |= 
1369                                                                 (tflags) 
1370                                                                 (1 << l);
1371                                                 } else {
1372                                                         p->pes_start &= ~ 
1373                                                                 ((tflags) 
1374                                                                 (1 << l));
1375                                                 }
1376                                                 pes_filter(p,l,c);
1377                                         } else {
1378                                                 sec_filter(p,l,c);
1379                                         }       
1380                                 }
1381                         }
1382                 }
1383         }
1384 }       
1385
1386
1387 void pes_filter(trans *p, int filtn, int off)
1388 {
1389         int count,c;
1390         uint8_t *buf;
1391
1392         if (filtn < 0 || filtn >= MAXFILT) return; 
1393
1394         count = 188 - off;
1395         c = 188*filtn;
1396         buf = p->packet+off;
1397         if (pes_is_started(p,filtn)){
1398                 p->is_full |= (tflags) (1 << filtn);
1399                 memcpy(p->transbuf+c,buf,count);
1400                 p->transcount[filtn] = count;
1401         }
1402 }
1403
1404 section *get_filt_sec(trans *p, int filtn)
1405 {
1406         section *sec;
1407         
1408         sec = &p->sec[filtn];
1409         p->is_full &= ~((tflags) (1 << filtn) );
1410         return sec;
1411 }
1412
1413 int get_filt_buf(trans *p, int filtn,uint8_t **buf)
1414 {
1415         *buf = p->transbuf+188*filtn;
1416         p->is_full &= ~((tflags) (1 << filtn) );
1417         return p->transcount[filtn];
1418 }
1419
1420
1421
1422
1423 void sec_filter(trans *p, int filtn, int off)
1424 {
1425         int i,j;
1426         int error;
1427         int count,c;
1428         uint8_t *buf, *secbuf;
1429         section *sec;
1430
1431         //      fprintf(stderr,"sec_filter\n");
1432
1433         if (filtn < 0 || filtn >= MAXFILT) return; 
1434
1435         count = 188 - off;
1436         c = 0;
1437         buf = p->packet+off;
1438         sec = &p->sec[filtn];
1439         secbuf = sec->payload;
1440         if(!filt_is_ready(p,filtn)){
1441                 p->is_full &= ~((tflags) (1 << filtn) );
1442                 sec->found = 0;
1443                 sec->length = 0;
1444         }
1445                 
1446         if ( !sec->found ){
1447                 c = buf[c]+1;
1448                 if (c >= count) return;
1449                 sec->id = buf[c];
1450                 secbuf[0] = buf[c];
1451                 c++;
1452                 sec->found++;
1453                 sec->length = 0;
1454         }
1455         
1456         while ( c < count && sec->found < 3){
1457                 secbuf[sec->found] = buf[c];
1458                 c++;
1459                 sec->found++;
1460         }
1461         if (c == count) return;
1462         
1463         if (!sec->length && sec->found == 3){
1464                 sec->length |= ((secbuf[1] & 0x0F) << 8); 
1465                 sec->length |= (secbuf[2] & 0xFF);
1466         }
1467         
1468         while ( c < count && sec->found < sec->length+3){
1469                 secbuf[sec->found] = buf[c];
1470                 c++;
1471                 sec->found++;
1472         }
1473
1474         if ( sec->length && sec->found == sec->length+3 ){
1475                 error=0;
1476                 for ( i = 0; i < MASKL; i++){
1477                         if (i > 0 ) j=2+i;
1478                         else j = 0;
1479                         error += (sec->payload[j]&p->mask[MASKL*filtn+i])^
1480                                 (p->filt[MASKL*filtn+i]&
1481                                  p->mask[MASKL*filtn+i]);
1482                 }
1483                 if (!error){
1484                         p->is_full |= (tflags) (1 << filtn);
1485                 }
1486                 if (buf[0]+1 < c ) c=count;
1487         }
1488         
1489         if ( c < count ) sec_filter(p, filtn, off);
1490
1491 }
1492
1493 #define MULT 1024
1494
1495
1496 void write_ps_headr( ps_packet *p, uint8_t *pts,int fd)
1497 {
1498         long  muxr = 37500;
1499         uint8_t    audio_bound = 1;
1500         uint8_t    fixed = 0;
1501         uint8_t    CSPS = 0;
1502         uint8_t    audio_lock = 1;
1503         uint8_t    video_lock = 1;
1504         uint8_t    video_bound = 1;
1505         uint8_t    stream1 = 0XC0;
1506         uint8_t    buffer1_scale = 1;
1507         uint32_t   buffer1_size = 32;
1508         uint8_t    stream2 = 0xE0;
1509         uint8_t    buffer2_scale = 1;
1510         uint32_t   buffer2_size = 230;
1511                     
1512         init_ps(p);
1513         
1514         p->mpeg = 2;
1515 // SCR = 0
1516         p->scr[0] = 0x44;
1517         p->scr[1] = 0x00;
1518         p->scr[2] = 0x04;
1519         p->scr[3] = 0x00;
1520         p->scr[4] = 0x04;
1521         p->scr[5] = 0x01;
1522         
1523 // SCR = PTS
1524         p->scr[0] = 0x44 | ((pts[0] >> 3)&0x18) | ((pts[0] >> 4)&0x03);
1525         p->scr[1] = 0x00 | ((pts[0] << 4)&0xF0) | ((pts[1] >> 4)&0x0F);
1526         p->scr[2] = 0x04 | ((pts[1] << 4)&0xF0) | ((pts[2] >> 4)&0x08)
1527                 | ((pts[2] >> 5)&0x03);
1528         p->scr[3] = 0x00 | ((pts[2] << 3)&0xF8) | ((pts[3] >> 5)&0x07);
1529         p->scr[4] = 0x04 | ((pts[3] << 3)&0xF8);
1530         p->scr[5] = 0x01;
1531         
1532         p->mux_rate[0] = (uint8_t)(muxr >> 14);
1533         p->mux_rate[1] = (uint8_t)(0xff & (muxr >> 6));
1534         p->mux_rate[2] = (uint8_t)(0x03 | ((muxr & 0x3f) << 2));
1535
1536         p->stuff_length = 0xF8;
1537         
1538         p->sheader_llength[0] = 0x00;
1539         p->sheader_llength[1] = 0x0c;
1540
1541         setl_ps(p);
1542         
1543         p->rate_bound[0] = (uint8_t)(0x80 | (muxr >>15));
1544         p->rate_bound[1] = (uint8_t)(0xff & (muxr >> 7));
1545         p->rate_bound[2] = (uint8_t)(0x01 | ((muxr & 0x7f)<<1));
1546         
1547         
1548         p->audio_bound = (uint8_t)((audio_bound << 2)|(fixed << 1)|CSPS);
1549         p->video_bound = (uint8_t)((audio_lock << 7)|
1550                               (video_lock << 6)|0x20|video_bound);
1551         p->reserved = (uint8_t)(0xFF);
1552         
1553         p->data[0] =  stream2;
1554         p->data[1] =  (uint8_t) (0xc0 | (buffer2_scale << 5) | 
1555                             (buffer2_size >> 8));
1556         p->data[2] =  (uint8_t) (buffer2_size & 0xff);
1557         p->data[3] =  stream1;
1558         p->data[4] =  (uint8_t) (0xc0 | (buffer1_scale << 5) | 
1559                             (buffer1_size >> 8));
1560         p->data[5] =  (uint8_t) (buffer1_size & 0xff);
1561         
1562         write_ps(fd, p);
1563         kill_ps(p);
1564 }
1565
1566
1567
1568 void twrite(uint8_t const *buf)
1569 {
1570         int l = TS_SIZE;
1571         int c = 0;
1572         int w;
1573
1574
1575         while (l){
1576                 w = write(STDOUT_FILENO,buf+c,l);
1577                 if (w>=0){
1578                         l-=w;
1579                         c+=w;
1580                 }
1581         }
1582 }
1583
1584 void init_p2t(p2t_t *p, void (*fkt)(uint8_t const *buf))
1585 {
1586         memset(p->pes,0,TS_SIZE);
1587         p->counter = 0;
1588         p->pos = 0;
1589         p->frags = 0;
1590         if (fkt) p->t_out = fkt;
1591         else p->t_out = twrite;
1592 }
1593
1594 void clear_p2t(p2t_t *p)
1595 {
1596         memset(p->pes,0,TS_SIZE);
1597         p->counter = 0;
1598         p->pos = 0;
1599         p->frags = 0;
1600 }
1601
1602
1603 long int find_pes_header(uint8_t const *buf, long int length, int *frags)
1604 {
1605         int c = 0;
1606         int found = 0;
1607
1608         *frags = 0;
1609
1610         while (c < length-3 && !found) {
1611                 if (buf[c] == 0x00 && buf[c+1] == 0x00 && 
1612                     buf[c+2] == 0x01) {
1613                         switch ( buf[c+3] ) {
1614                         case 0xBA:
1615                         case PROG_STREAM_MAP:
1616                         case PRIVATE_STREAM2:
1617                         case PROG_STREAM_DIR:
1618                         case ECM_STREAM     :
1619                         case EMM_STREAM     :
1620                         case PADDING_STREAM :
1621                         case DSM_CC_STREAM  :
1622                         case ISO13522_STREAM:
1623                         case PRIVATE_STREAM1:
1624                         case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1625                         case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1626                                 found = 1;
1627                                 break;
1628                                 
1629                         default:
1630                                 c++;
1631                                 break;
1632                         }       
1633                 } else c++;
1634         }
1635         if (c == length-3 && !found){
1636                 if (buf[length-1] == 0x00) *frags = 1;
1637                 if (buf[length-2] == 0x00 &&
1638                     buf[length-1] == 0x00) *frags = 2;
1639                 if (buf[length-3] == 0x00 &&
1640                     buf[length-2] == 0x00 &&
1641                     buf[length-1] == 0x01) *frags = 3;
1642                 return -1;
1643         }
1644
1645         return c;
1646 }
1647
1648 void pes_to_ts( uint8_t const *buf, long int length, uint16_t pid, p2t_t *p)
1649 {
1650         int c,c2,l,add;
1651         int check,rest;
1652
1653         c = 0;
1654         c2 = 0;
1655         if (p->frags){
1656                 check = 0;
1657                 switch(p->frags){
1658                 case 1:
1659                         if ( buf[c] == 0x00 && buf[c+1] == 0x01 ){
1660                                 check = 1;
1661                                 c += 2;
1662                         }
1663                         break;
1664                 case 2:
1665                         if ( buf[c] == 0x01 ){
1666                                 check = 1;
1667                                 c++;
1668                         }
1669                         break;
1670                 case 3:
1671                         check = 1;
1672                 }
1673                 if(check){
1674                         switch ( buf[c] ) {
1675                                 
1676                         case PROG_STREAM_MAP:
1677                         case PRIVATE_STREAM2:
1678                         case PROG_STREAM_DIR:
1679                         case ECM_STREAM     :
1680                         case EMM_STREAM     :
1681                         case PADDING_STREAM :
1682                         case DSM_CC_STREAM  :
1683                         case ISO13522_STREAM:
1684                         case PRIVATE_STREAM1:
1685                         case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1686                         case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1687                                 p->pes[0] = 0x00;
1688                                 p->pes[1] = 0x00;
1689                                 p->pes[2] = 0x01;
1690                                 p->pes[3] = buf[c];
1691                                 p->pos=4;
1692                                 memcpy(p->pes+p->pos,buf+c,TS_SIZE-4-p->pos);
1693                                 c += TS_SIZE-4-p->pos;
1694                                 p_to_t(p->pes,TS_SIZE-4,pid,&p->counter,
1695                                        p->t_out);
1696                                 clear_p2t(p);
1697                                 break;
1698                                 
1699                         default:
1700                                 c=0;
1701                                 break;
1702                         }
1703                 }
1704                 p->frags = 0;
1705         }
1706                 
1707         if (p->pos){
1708                 c2 = find_pes_header(buf+c,length-c,&p->frags);
1709                 if (c2 >= 0 && c2 < TS_SIZE-4-p->pos){
1710                         l = c2+c;
1711                 } else l = TS_SIZE-4-p->pos;
1712                 memcpy(p->pes+p->pos,buf,l);
1713                 c += l;
1714                 p->pos += l;
1715                 p_to_t(p->pes,p->pos,pid,&p->counter,
1716                        p->t_out);
1717                 clear_p2t(p);
1718         }
1719                         
1720         add = 0;
1721         while (c < length){
1722                 c2 = find_pes_header(buf+c+add,length-c-add,&p->frags);
1723                 if (c2 >= 0) {
1724                         c2 += c+add;
1725                         if (c2 > c){
1726                                 p_to_t(buf+c,c2-c,pid,&p->counter,
1727                                        p->t_out);
1728                                 c = c2;
1729                                 clear_p2t(p);
1730                                 add = 0;
1731                         } else add = 1;
1732                 } else {
1733                         l = length-c;
1734                         rest = l % (TS_SIZE-4);
1735                         l -= rest;
1736                         p_to_t(buf+c,l,pid,&p->counter,
1737                                p->t_out);
1738                         memcpy(p->pes,buf+c+l,rest);
1739                         p->pos = rest;
1740                         c = length;
1741                 }
1742         }
1743 }
1744
1745
1746
1747 void p_to_t( uint8_t const *buf, long int length, uint16_t pid, uint8_t *counter, 
1748             void (*ts_write)(uint8_t const *))
1749 {
1750   
1751         int l, pes_start;
1752         uint8_t obuf[TS_SIZE];
1753         long int c = 0;
1754         pes_start = 0;
1755         if ( length > 3 && 
1756              buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x01 )
1757                 switch (buf[3]){
1758                         case PROG_STREAM_MAP:
1759                         case PRIVATE_STREAM2:
1760                         case PROG_STREAM_DIR:
1761                         case ECM_STREAM     :
1762                         case EMM_STREAM     :
1763                         case PADDING_STREAM :
1764                         case DSM_CC_STREAM  :
1765                         case ISO13522_STREAM:
1766                         case PRIVATE_STREAM1:
1767                         case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1768                         case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1769                                 pes_start = 1;
1770                                 break;
1771                                 
1772                         default:
1773                                 break;
1774                 }                       
1775
1776         while ( c < length ){
1777                 memset(obuf,0,TS_SIZE);
1778                 if (length - c >= TS_SIZE-4){
1779                         l = write_ts_header(pid, counter, pes_start
1780                                              , obuf, TS_SIZE-4);
1781                         memcpy(obuf+l, buf+c, TS_SIZE-l);
1782                         c += TS_SIZE-l;
1783                 } else { 
1784                         l = write_ts_header(pid, counter, pes_start
1785                                              , obuf, length-c);
1786                         memcpy(obuf+l, buf+c, TS_SIZE-l);
1787                         c = length;
1788                 }
1789                 ts_write(obuf);
1790                 pes_start = 0;
1791         }
1792 }
1793
1794
1795 int write_ps_header(uint8_t *buf, 
1796                     uint32_t   SCR, 
1797                     long  muxr,
1798                     uint8_t    audio_bound,
1799                     uint8_t    fixed,
1800                     uint8_t    CSPS,
1801                     uint8_t    audio_lock,
1802                     uint8_t    video_lock,
1803                     uint8_t    video_bound,
1804                     uint8_t    stream1,
1805                     uint8_t    buffer1_scale,
1806                     uint32_t   buffer1_size,
1807                     uint8_t    stream2,
1808                     uint8_t    buffer2_scale,
1809                     uint32_t   buffer2_size)                    
1810 {
1811         ps_packet p;
1812         uint8_t *pts;
1813         long lpts;
1814         init_ps(&p);
1815         
1816         lpts = htonl(SCR);
1817         pts = (uint8_t *) &lpts;
1818
1819         
1820         p.mpeg = 2;
1821 // SCR = 0
1822         p.scr[0] = 0x44;
1823         p.scr[1] = 0x00;
1824         p.scr[2] = 0x04;
1825         p.scr[3] = 0x00;
1826         p.scr[4] = 0x04;
1827         p.scr[5] = 0x01;
1828         
1829 // SCR = PTS
1830         p.scr[0] = 0x44 | ((pts[0] >> 3)&0x18) | ((pts[0] >> 4)&0x03);
1831         p.scr[1] = 0x00 | ((pts[0] << 4)&0xF0) | ((pts[1] >> 4)&0x0F);
1832         p.scr[2] = 0x04 | ((pts[1] << 4)&0xF0) | ((pts[2] >> 4)&0x08)
1833                 | ((pts[2] >> 5)&0x03);
1834         p.scr[3] = 0x00 | ((pts[2] << 3)&0xF8) | ((pts[3] >> 5)&0x07);
1835         p.scr[4] = 0x04 | ((pts[3] << 3)&0xF8);
1836         p.scr[5] = 0x01;
1837         
1838         p.mux_rate[0] = (uint8_t)(muxr >> 14);
1839         p.mux_rate[1] = (uint8_t)(0xff & (muxr >> 6));
1840         p.mux_rate[2] = (uint8_t)(0x03 | ((muxr & 0x3f) << 2));
1841
1842         p.stuff_length = 0xF8;
1843         
1844         if (stream1 && stream2){
1845                 p.sheader_llength[0] = 0x00;
1846                 p.sheader_llength[1] = 0x0c;
1847
1848                 setl_ps(&p);
1849                 
1850                 p.rate_bound[0] = (uint8_t)(0x80 | (muxr >>15));
1851                 p.rate_bound[1] = (uint8_t)(0xff & (muxr >> 7));
1852                 p.rate_bound[2] = (uint8_t)(0x01 | ((muxr & 0x7f)<<1));
1853
1854         
1855                 p.audio_bound = (uint8_t)((audio_bound << 2)|(fixed << 1)|CSPS);
1856                 p.video_bound = (uint8_t)((audio_lock << 7)|
1857                                      (video_lock << 6)|0x20|video_bound);
1858                 p.reserved = (uint8_t)(0xFF >> 1);
1859                 
1860                 p.data[0] =  stream2;
1861                 p.data[1] =  (uint8_t) (0xc0 | (buffer2_scale << 5) | 
1862                                    (buffer2_size >> 8));
1863                 p.data[2] =  (uint8_t) (buffer2_size & 0xff);
1864                 p.data[3] =  stream1;
1865                 p.data[4] =  (uint8_t) (0xc0 | (buffer1_scale << 5) | 
1866                                    (buffer1_size >> 8));
1867                 p.data[5] =  (uint8_t) (buffer1_size & 0xff);
1868                 
1869                 cwrite_ps(buf, &p, PS_HEADER_L2);
1870                 kill_ps(&p);
1871                 return PS_HEADER_L2;
1872         } else {
1873                 cwrite_ps(buf, &p, PS_HEADER_L1);
1874                 kill_ps(&p);
1875                 return PS_HEADER_L1;
1876         }
1877 }
1878
1879
1880
1881 #define MAX_BASE 80
1882 #define MAX_PATH 256
1883 #define MAX_EXT 10
1884
1885 int break_up_filename(char *name, char *base_name, char *path, char *ext)
1886 {
1887         int l,i,sstop,sstart;
1888
1889         l = strlen(name);
1890         sstop = l;
1891         sstart = -1;
1892         for( i= l-1; i >= 0; i--){
1893                 if (sstop == l && name[i] == '.') sstop = i;
1894                 if (sstart<0 && name[i] == '/') sstart = i+1;
1895         }
1896         if (sstart < 0) sstart = 0;
1897         if (sstop-sstart < MAX_BASE){
1898                 strncpy(base_name, name+sstart, sstop-sstart);
1899                 base_name[sstop-sstart]=0;
1900                 if(sstart > 0){
1901                         if( l - sstop + sstart < MAX_PATH){
1902                                 strncpy(path, name, sstart);
1903                                 path[sstart] = 0;
1904                         } else {
1905                                 fprintf(stderr,"PATH too long\n");
1906                                 return -1;
1907                         }
1908
1909                 } else {
1910                         strcpy(path, "./");
1911                 }
1912
1913                 if(sstop < l){
1914                         if( l - sstop -1 < MAX_EXT){
1915                                 strncpy(ext, name+sstop+1, l-sstop-1);
1916                                 ext[l-sstop-1]=0;
1917                         } else {
1918                                 fprintf(stderr,"Extension too long\n");
1919                                 return -1;
1920                         }
1921
1922                 } else {
1923                         strcpy(ext, "");
1924                 }
1925
1926         } else {
1927                 fprintf(stderr,"Name too long\n");
1928                 return -1;
1929         }
1930 /*
1931         printf("%d %d\n",sstart, sstop);
1932         printf("%s %d\n",name, strlen(name));
1933         printf("%s %d\n",base_name, strlen(base_name));
1934         printf("%s %d\n",path,strlen(path));
1935         printf("%s %d\n",ext,strlen(ext));
1936 */  
1937         return 0;
1938 }
1939
1940
1941 int seek_mpg_start(uint8_t *buf, int size)
1942 {
1943         int found = 0;
1944         int c=0;
1945         int seq = 0;
1946         int mpeg = 0;
1947         int mark = 0;
1948
1949         while ( !seq ){
1950                 while (found != 4){
1951                         switch (found) {
1952                         case 0:
1953                                 if ( buf[c] == 0x00 ) found++;
1954                                 c++;
1955                                 break;
1956                         case 1:
1957                                 if ( buf[c] == 0x00 ) found++;
1958                                 else found = 0;
1959                                 c++;
1960                                 break;                     
1961                         case 2:
1962                                 if ( buf[c] == 0x01 ) found++;
1963                                 else found = 0;
1964                                 if ( buf[c] == 0x00 ) found = 2;
1965                                 c++;
1966                                 break;
1967                         
1968                         case 3:
1969                                 if ( (buf[c] & 0xe0) == 0xe0 ) found++;
1970                                 else found = 0;
1971                                 c++;
1972                                 break;
1973                         }
1974                         if (c >= size) return -1;
1975                 }
1976                 
1977                 if (found == 4){
1978                         mark = c-4;
1979                         c+=2;
1980                         if (c >= size) return -1;
1981
1982                         if ( (buf[c] & 0xC0) == 0x80 ){
1983                                 mpeg = 2;
1984                                 c += 2;
1985                                 if (c >= size) return -1;
1986                                 c += buf[c]+1;
1987                                 if (c >= size) return -1;
1988                         } else {
1989                                 mpeg = 1;
1990                                 while( buf[c] == 0xFF ) {
1991                                         c++;
1992                                         if (c >= size) return -1;
1993                                 }
1994                                 if ( (buf[c] & 0xC0) == 0x40) c+=2;
1995                                 if (c >= size) return -1;
1996                                 if ( (buf[c] & 0x30) ){
1997                                         if ( (buf[c] & 0x30) == 0x20) c+=5;
1998                                         else c+=10;
1999                                 } else c++;
2000                                 if (c >= size) return -1;
2001                         }
2002
2003                         if ( buf[c] == 0x00 && 
2004                              buf[c+1] == 0x00 && 
2005                              buf[c+2] == 0x01 && 
2006                              buf[c+3] == 0xB3 ) 
2007                                 seq = 1;
2008                 }
2009                 found = 0;
2010         }
2011
2012         return size-mark;
2013 }
2014
2015
2016 void write_mpg(int fstart, uint64_t length, int fdin, int fdout)
2017 {
2018 //      uint8_t mpeg_end[4] = { 0x00, 0x00, 0x01, 0xB9 };
2019         uint8_t *buf;
2020         uint64_t l=0;
2021         uint64_t count = 0;
2022         struct stat sb;
2023         int buf_size;
2024
2025         fstat (fdout, &sb);
2026         buf_size =  sb.st_blksize;
2027
2028         buf = (char *) alloca (buf_size + sizeof (int));
2029         
2030         lseek(fdin, fstart, SEEK_SET);
2031
2032         while ( count < length && (l = read(fdin,buf,buf_size)) >= 0){
2033                 if (l > 0) count+=l;
2034                 write(fdout,buf,l);
2035                 printf("written %02.2f%%\r",(100.*count)/length);
2036         }
2037         printf("\n");
2038
2039         //write( fdout, mpeg_end, 4);
2040 }
2041
2042
2043 #define CHECKBUF (1024*1024)
2044 #define ONE_GIG  (1024UL*1024UL*1024UL)
2045 void split_mpg(char *name, uint64_t size)
2046 {
2047         char base_name[MAX_BASE];
2048         char path[MAX_PATH];
2049         char ext[MAX_EXT];
2050         char new_name[256];
2051         uint8_t buf[CHECKBUF];
2052         int fdin;
2053         int fdout;
2054         uint64_t length = 0;
2055         uint64_t last;
2056         int i;
2057         int mark, csize;
2058         struct stat sb;
2059
2060         if (break_up_filename(name,base_name,path,ext) < 0) exit(1);
2061
2062
2063         if ( (fdin = open(name, O_RDONLY|O_LARGEFILE)) < 0){
2064                 fprintf(stderr,"Can't open %s\n",name);
2065                 exit(1);
2066         }
2067
2068         fstat (fdin, &sb);
2069
2070         length = sb.st_size;
2071         if ( length < ONE_GIG )
2072                 printf("Filelength = %2.2f MB\n", length/1024./1024.);
2073         else
2074                 printf("Filelength = %2.2f GB\n", length/1024./1024./1024.);
2075
2076         if ( length < size ) length = size;
2077         
2078         printf("Splitting %s into Files with size <= %2.2f MB\n",name,
2079                size/1024./1024.);
2080         
2081         csize = CHECKBUF;
2082         read(fdin, buf, csize);
2083         if ( (mark = seek_mpg_start(buf,csize)) < 0){
2084                 fprintf(stderr,"Couldn't find sequence header\n");
2085                 exit(1);
2086         }
2087
2088         last = csize-mark;
2089
2090         for ( i = 0 ; i < length/size; i++){
2091                 csize = CHECKBUF;
2092                 
2093                 if (csize > length-last) csize = length-last;
2094                 lseek(fdin, last+size-csize, SEEK_SET);
2095                 read(fdin, buf, csize);
2096                 if ( (mark = seek_mpg_start(buf,csize)) < 0){
2097                         fprintf(stderr,"Couldn't find sequence header\n");
2098                         exit(1);
2099                 }
2100
2101                 sprintf(new_name,"%s-%03d.%s",base_name,i,ext);
2102                 printf("writing %s\n",new_name);
2103
2104                 if ( (fdout = open(new_name,O_WRONLY|O_CREAT|O_TRUNC
2105                                    |O_LARGEFILE,
2106                                    S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|
2107                                    S_IROTH|S_IWOTH)) < 0){
2108                         fprintf(stderr,"Can't open %s\n",new_name);
2109                         exit(1);
2110                 }
2111                 write_mpg(last, size-mark, fdin, fdout);
2112                 last = last + size - mark;
2113         }
2114         sprintf(new_name,"%s-%03d.%s",base_name,i,ext);
2115         printf("writing %s\n",new_name);
2116
2117         if ( (fdout = open(new_name,O_WRONLY|O_CREAT|O_TRUNC
2118                            |O_LARGEFILE,
2119                            S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|
2120                            S_IROTH|S_IWOTH)) < 0){
2121                 fprintf(stderr,"Can't open %s\n",new_name);
2122                 exit(1);
2123         }
2124         write_mpg(last, length-last, fdin, fdout);
2125 }
2126
2127
2128
2129
2130 void cut_mpg(char *name, uint64_t size)
2131 {
2132         char base_name[MAX_BASE];
2133         char path[MAX_PATH];
2134         char ext[MAX_EXT];
2135         char new_name[256];
2136         uint8_t buf[CHECKBUF];
2137         int fdin;
2138         int fdout;
2139         uint64_t length = 0;
2140         uint64_t last;
2141         int mark, csize;
2142         struct stat sb;
2143
2144         if (break_up_filename(name,base_name,path,ext) < 0) exit(1);
2145
2146
2147         if ( (fdin = open(name, O_RDONLY|O_LARGEFILE)) < 0){
2148                 fprintf(stderr,"Can't open %s\n",name);
2149                 exit(1);
2150         }
2151
2152         fstat (fdin, &sb);
2153
2154         length = sb.st_size;
2155         if ( length < ONE_GIG )
2156                 printf("Filelength = %2.2f MB\n", length/1024./1024.);
2157         else
2158                 printf("Filelength = %2.2f GB\n", length/1024./1024./1024.);
2159
2160         if ( length < size ) length = size;
2161         
2162         printf("Splitting %s into 2 Files with length %.2f MB and %.2f MB\n",
2163                name, size/1024./1024., (length-size)/1024./1024.);
2164         
2165         csize = CHECKBUF;
2166         read(fdin, buf, csize);
2167         if ( (mark = seek_mpg_start(buf,csize)) < 0){
2168                 fprintf(stderr,"Couldn't find sequence header\n");
2169                 exit(1);
2170         }
2171
2172         last = csize-mark;
2173
2174         if (csize > length-last) csize = length-last;
2175         lseek(fdin, last+size-csize, SEEK_SET);
2176         read(fdin, buf, csize);
2177         if ( (mark = seek_mpg_start(buf,csize)) < 0){
2178                 fprintf(stderr,"Couldn't find sequence header\n");
2179                 exit(1);
2180         }
2181
2182         sprintf(new_name,"%s-1.%s",base_name,ext);
2183         printf("writing %s\n",new_name);
2184
2185         if ( (fdout = open(new_name,O_WRONLY|O_CREAT|O_TRUNC
2186                            |O_LARGEFILE,
2187                            S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|
2188                            S_IROTH|S_IWOTH)) < 0){
2189                 fprintf(stderr,"Can't open %s\n",new_name);
2190                 exit(1);
2191         }
2192         write_mpg(last, size-mark, fdin, fdout);
2193         last = last + size - mark;
2194
2195         sprintf(new_name,"%s-2.%s",base_name,ext);
2196         printf("writing %s\n",new_name);
2197
2198         if ( (fdout = open(new_name,O_WRONLY|O_CREAT|O_TRUNC
2199                            |O_LARGEFILE,
2200                            S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|
2201                            S_IROTH|S_IWOTH)) < 0){
2202                 fprintf(stderr,"Can't open %s\n",new_name);
2203                 exit(1);
2204         }
2205         write_mpg(last, length-last, fdin, fdout);
2206 }
2207
2208
2209
2210
2211 void write_all (int fd, uint8_t *data, int length)
2212 {
2213         int r;
2214
2215         while (length) {
2216                 if ((r = write(fd, data, length)) > 0) {
2217                         data += r;
2218                         length -= r;
2219                 }
2220         }
2221 }
2222
2223
2224
2225 void read_all (int fd, uint8_t *data, int length)
2226 {
2227         int c = 0;
2228
2229         while(1) {
2230                 if( read(fd, data+c, 1) == 1) {
2231                         c++;
2232                         if(data[c-1] == '\n') {
2233                                 data[c] = 0;
2234                                 break;
2235                         }
2236                 }
2237                 else {
2238                         fprintf (stderr, "Error reading socket\n");
2239                         exit(1);
2240                 }
2241         }
2242 }
2243
2244
2245
2246 char *url2host (uint8_t *url, char **name, uint32_t *ip, uint32_t *port)
2247 {
2248         uint8_t *murl;
2249         struct hostent *hoste;
2250         struct in_addr haddr;
2251         int found_ip = 1;
2252         
2253         if (!(strncmp(url, "http://", 7)))
2254                 url += 7;
2255
2256         *name = strdup(url);
2257         if (!(*name)) {
2258                 *name = NULL;
2259                 return (NULL);
2260         }
2261
2262         murl = url;
2263         while (*murl && *murl != ':' && *murl != '/') {
2264                 if ((*murl < '0' || *murl > '9') && *murl != '.')
2265                         found_ip = 0;
2266                 murl++;
2267         }
2268
2269         (*name)[murl - url] = 0;
2270         if (found_ip) {
2271                 if ((*ip = inet_addr(*name)) == INADDR_NONE)
2272                         return (NULL);
2273         } else {
2274                 if (!(hoste = gethostbyname(*name)))
2275                         return (NULL);
2276                 memcpy (&haddr, hoste->h_addr, sizeof(haddr));
2277                 *ip = haddr.s_addr;
2278         }
2279
2280         if (!*murl || *murl == '/') {
2281                 *port = 80;
2282                 return (murl);
2283         }
2284         *port = atoi(++murl);
2285
2286         while (*murl && *murl != '/')
2287                 murl++;
2288         return (murl);
2289 }
2290
2291 #define ACCEPT "Accept: video/mpeg, video/x-mpegurl, */*\r\n"
2292
2293 int http_open (char *url)
2294 {
2295         char purl[1024], *host, req[1024], *sptr;
2296         uint32_t ip;
2297         uint32_t port;
2298         int sock;
2299         int reloc, relocnum = 0;
2300         struct sockaddr_in server;
2301         int mfd;
2302
2303         strncpy (purl, url, 1023);
2304         purl[1023] = '\0';
2305
2306         do {
2307                 host = NULL;
2308                 strcpy (req, "GET ");
2309                 if (!(sptr = url2host(purl, &host, &ip, &port))) {
2310                         fprintf (stderr, "Unknown host\n");
2311                         exit (1);
2312                 }
2313                 strcat (req, sptr);
2314                 sprintf (req + strlen(req),
2315                          " HTTP/1.0\r\nUser-Agent: %s/%s\r\n",
2316                          "whatever", "you want");
2317                 if (host) {
2318                         sprintf(req + strlen(req),
2319                                 "Host: %s:%u\r\n", host, port);
2320                         free (host);
2321                 }
2322
2323                 strcat (req, ACCEPT);
2324                 strcat (req, "\r\n");
2325                 
2326                 server.sin_port = htons(port);
2327                 server.sin_family = AF_INET;
2328                 server.sin_addr.s_addr = ip;
2329
2330                 if ((sock = socket(PF_INET, SOCK_STREAM, 6)) < 0) {
2331                         perror ("socket");
2332                         exit (1);
2333                 }
2334
2335                 if (connect(sock, (struct sockaddr *)&server, 
2336                             sizeof(server))) {
2337                         perror ("connect");
2338                         exit (1);
2339                 }
2340                 
2341                 write_all (sock, req, strlen(req));
2342                 if (!(mfd = fileno(fdopen(sock, "rb")))) {
2343                         perror ("open");
2344                         exit (1);
2345                 }
2346                 reloc = 0;
2347                 purl[0] = '\0';
2348                 read_all (mfd, req, 1023);
2349                 if ((sptr = strchr(req, ' '))) {
2350                         switch (sptr[1]) {
2351                                 case '2':
2352                                         break;
2353                                 case '3':
2354                                         reloc = 1;
2355                                 default:
2356                                         fprintf (stderr, "HTTP req failed:%s",
2357                                                 sptr+1); 
2358                                         exit (1);
2359                         }
2360                 }
2361                 do {
2362                         read_all (mfd,req, 1023);
2363                         if (!strncmp(req, "Location:", 9))
2364                                 strncpy (purl, req+10, 1023);
2365                 } while (req[0] != '\r' && req[0] != '\n');
2366         } while (reloc && purl[0] && relocnum++ < 3);
2367         if (reloc) {
2368                 fprintf (stderr, "Too many HTTP relocations.\n");
2369                 exit (1);
2370         }
2371
2372         return sock;
2373 }
2374
2375 extern int errno;
2376 const char * strerrno (void)
2377 {
2378         return strerror(errno);
2379 }