Statistics
| Branch: | Tag: | Revision:

dvbd / src / ctools.c @ fc92ba5f

History | View | Annotate | Download (46.6 KB)

1
/*
2
 *  mpegtools for the Siemens Fujitsu DVB PCI card
3
 *
4
 * Copyright (C) 2000, 2001 Marcus Metzler 
5
 *            for convergence integrated media GmbH
6
 * 
7
 * This program is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU General Public License
9
 * as published by the Free Software Foundation; either version 2
10
 * of the License, or (at your option) any later version.
11
 * 
12

13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 * 
18

19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
23
 * 
24

25
 * The author can be reached at marcus@convergence.de, 
26

27
 * the project's page is at http://linuxtv.org/dvb/
28
 */
29

    
30
#include "config.h"
31
#include "ctools.h"
32

    
33
#define MAX_SEARCH 1024 * 1024
34

    
35
/*
36

37
      PES
38
  
39
*/
40

    
41

    
42
void init_pes(pes_packet *p){
43
        p->stream_id = 0;
44
        p->llength[0] = 0;
45
        p->llength[1] = 0;
46
        p->length = 0;
47
        p->flags1 = 0x80;
48
        p->flags2 = 0;
49
        p->pes_hlength = 0;
50
        p->trick = 0;
51
        p->add_cpy = 0;
52
        p->priv_flags = 0;
53
        p->pack_field_length = 0;
54
        p->pack_header = (u8 *) NULL;
55
        p->pck_sqnc_cntr = 0;
56
        p->org_stuff_length = 0;
57
        p->pes_ext_lngth = 0;
58
        p->pes_ext = (u8 *) NULL;
59
        p->pes_pckt_data = (u8 *) NULL;
60
        p->padding = 0;
61
        p->mpeg = 2; // DEFAULT MPEG2
62
        p->mpeg1_pad = 0;
63
        p->mpeg1_headr = NULL;
64
        p->stuffing = 0;
65
}
66

    
67
void kill_pes(pes_packet *p){
68
        if (p->pack_header)
69
                free(p->pack_header);
70
        if (p->pes_ext)
71
                free(p->pes_ext);
72
        if (p->pes_pckt_data)
73
                free(p->pes_pckt_data);
74
        if (p->mpeg1_headr)
75
                free(p->mpeg1_headr);
76
        init_pes(p);
77
}
78

    
79
void setlength_pes(pes_packet *p){
80
         short *ll;
81
        ll = (short *) p->llength;
82
        p->length = ntohs(*ll);
83
}
84

    
85
static void setl_pes(pes_packet *p){
86
        setlength_pes(p);
87
        if (p->length)
88
                p->pes_pckt_data = (u8 *)malloc(p->length);
89
}
90

    
91
void nlength_pes(pes_packet *p){
92
        if (p->length <= 0xFFFF){
93
                short *ll = (short *) p->llength;
94
                short l = p->length;
95
                *ll = htons(l);
96
        } else {
97
                p->llength[0] =0x00;
98
                p->llength[1] =0x00;
99
        }
100
}
101

    
102
static void nl_pes(pes_packet *p)
103
{
104
        nlength_pes(p);
105
        p->pes_pckt_data = (u8 *) malloc(p->length);
106
}
107

    
108
void pts2pts(u8 *av_pts, u8 *pts)
109
{
110
  
111
        av_pts[0] = ((pts[0] & 0x06) << 5) | 
112
                ((pts[1] & 0xFC) >> 2); 
113
        av_pts[1] = ((pts[1] & 0x03) << 6) |
114
                ((pts[2] & 0xFC) >> 2); 
115
        av_pts[2] = ((pts[2] & 0x02) << 6) |
116
                        ((pts[3] & 0xFE) >> 1);
117
        av_pts[3] = ((pts[3] & 0x01) << 7) |
118
                ((pts[4] & 0xFE) >> 1);
119
        
120
}
121

    
122

    
123
int cwrite_pes(u8 *buf, pes_packet *p, long length){
124
        int count,i;
125
        u8 dummy;
126
        int more = 0;
127
        u8 headr[3] = { 0x00, 0x00 , 0x01};
128

    
129
        if (length <  p->length+p->pes_hlength){
130
                fprintf(stderr,"Wrong buffer size in cwrite_pes\n");
131
                exit(1);
132
        }
133

    
134

    
135
        memcpy(buf,headr,3);
136
        count = 3;
137
        buf[count] = p->stream_id;
138
        count++;
139

    
140
        switch ( p->stream_id ) {
141
                                
142
        case PROG_STREAM_MAP:
143
        case PRIVATE_STREAM2:
144
        case PROG_STREAM_DIR:
145
        case ECM_STREAM     :
146
        case EMM_STREAM     :
147
        case PADDING_STREAM :
148
                buf[count] = p->llength[0];
149
                count++;
150
                buf[count] = p->llength[1];
151
                count++;
152
                memcpy(buf+count,p->pes_pckt_data,p->length);
153
                count += p->length;
154
                break;
155
        case DSM_CC_STREAM  :
156
        case ISO13522_STREAM:
157
        case PRIVATE_STREAM1:
158
        case AUDIO_STREAM_S ... AUDIO_STREAM_E:
159
        case VIDEO_STREAM_S ... VIDEO_STREAM_E:
160
                buf[count] = p->llength[0];
161
                count++;
162
                buf[count] = p->llength[1];
163
                count++;
164
                more = 1;
165
                break;
166
        }        
167
        
168

    
169
        if ( more ) {
170
                if ( p->mpeg == 2 ){
171
                        memcpy(buf+count,&p->flags1,1);
172
                        count++;
173
                        memcpy(buf+count,&p->flags2,1);
174
                        count++;
175
                        memcpy(buf+count,&p->pes_hlength,1);
176
                        count++;
177
                        
178
                        if ((p->flags2 & PTS_DTS_FLAGS) == PTS_ONLY){
179
                                memcpy(buf+count,p->pts,5);
180
                                count += 5;
181
                        } else 
182
                                if ((p->flags2 & PTS_DTS_FLAGS) == PTS_DTS){
183
                                        memcpy(buf+count,p->pts,5);
184
                                        count += 5;
185
                                        memcpy(buf+count,p->dts,5);
186
                                        count += 5;
187
                                }
188
                        if (p->flags2 & ESCR_FLAG){
189
                                memcpy(buf+count,p->escr,6);
190
                                count += 6;
191
                        }
192
                        if (p->flags2 & ES_RATE_FLAG){
193
                                memcpy(buf+count,p->es_rate,3);
194
                                count += 3;
195
                        }
196
                        if (p->flags2 & DSM_TRICK_FLAG){
197
                                memcpy(buf+count,&p->trick,1);
198
                                count++;
199
                        }
200
                        if (p->flags2 & ADD_CPY_FLAG){
201
                                memcpy(buf+count,&p->add_cpy,1);
202
                                count++;
203
                        }
204
                        if (p->flags2 & PES_CRC_FLAG){
205
                                memcpy(buf+count,p->prev_pes_crc,2);
206
                                count += 2;
207
                        }
208
                        if (p->flags2 & PES_EXT_FLAG){
209
                                memcpy(buf+count,&p->priv_flags,1);
210
                                count++;
211

    
212
                                if (p->priv_flags & PRIVATE_DATA){
213
                                        memcpy(buf+count,p->pes_priv_data,16);
214
                                        count += 16;
215
                                }
216
                                if (p->priv_flags & HEADER_FIELD){
217
                                        memcpy(buf+count,&p->pack_field_length,
218
                                               1);
219
                                        count++;
220
                                        memcpy(buf+count,p->pack_header,
221
                                                     p->pack_field_length);
222
                                        count += p->pack_field_length;
223

    
224
                                }
225
                                
226
                                if ( p->priv_flags & PACK_SEQ_CTR){
227
                                        memcpy(buf+count,&p->pck_sqnc_cntr,1);
228
                                        count++;
229
                                        memcpy(buf+count,&p->org_stuff_length,
230
                                               1);
231
                                        count++;
232
                                }
233
                                
234
                                if ( p->priv_flags & P_STD_BUFFER){
235
                                        memcpy(buf+count,p->p_std,2);
236
                                        count += 2;
237
                                }
238
                                if ( p->priv_flags & PES_EXT_FLAG2){
239
                                        memcpy(buf+count,&p->pes_ext_lngth,1);
240
                                        count++;
241
                                        memcpy(buf+count,p->pes_ext,
242
                                                     p->pes_ext_lngth);
243
                                        count += p->pes_ext_lngth;
244
                                }
245
                        }
246
                        dummy = 0xFF;
247
                        for (i=0;i<p->stuffing;i++) {
248
                                memcpy(buf+count,&dummy,1);
249
                                count++;
250
                        }
251
                } else {
252
                        if (p->mpeg1_pad){
253
                                memcpy(buf+count,p->mpeg1_headr,p->mpeg1_pad);
254
                                count += p->mpeg1_pad;
255
                        }
256
                        if ((p->flags2 & PTS_DTS_FLAGS) == PTS_ONLY){
257
                                memcpy(buf+count,p->pts,5);
258
                                count += 5;
259
                        }
260
                        else if ((p->flags2 & PTS_DTS_FLAGS) == 
261
                                 PTS_DTS){
262
                                memcpy(buf+count,p->pts,5);
263
                                        count += 5;
264
                                memcpy(buf+count,p->dts,5);
265
                                        count += 5;
266
                        }
267
                }                        
268
                memcpy(buf+count,p->pes_pckt_data,p->length);
269
                count += p->length;
270
        }
271

    
272
        return count;
273

    
274
}
275

    
276
void write_pes(int fd, pes_packet *p){
277
        long length;
278
        u8 *buf;
279
        int l = p->length+p->pes_hlength;
280
        
281
        buf = (u8 *) malloc(l);
282
        length = cwrite_pes(buf,p,l);
283
        write(fd,buf,length);
284
        free(buf);
285
}
286

    
287
static unsigned int find_length(int f){
288
        uint64_t p = 0;
289
        uint64_t start = 0;
290
        uint64_t q = 0;
291
        int found = 0;
292
        u8 sync4[4];
293
        int neof = 1;
294

    
295
        start = lseek(f,0,SEEK_CUR);
296
        start -=2;
297
        lseek(f,start,SEEK_SET);
298
        while ( neof > 0 && !found ){
299
                p = lseek(f,0,SEEK_CUR);
300
                neof = read(f,&sync4,4);
301
                if (sync4[0] == 0x00 && sync4[1] == 0x00 && sync4[2] == 0x01) {
302
                        switch ( sync4[3] ) {
303
                                
304
                        case PROG_STREAM_MAP:
305
                        case PRIVATE_STREAM2:
306
                        case PROG_STREAM_DIR:
307
                        case ECM_STREAM     :
308
                        case EMM_STREAM     :
309
                        case PADDING_STREAM :
310
                        case DSM_CC_STREAM  :
311
                        case ISO13522_STREAM:
312
                        case PRIVATE_STREAM1:
313
                        case AUDIO_STREAM_S ... AUDIO_STREAM_E:
314
                        case VIDEO_STREAM_S ... VIDEO_STREAM_E:
315
                                found = 1;
316
                                break;
317
                        default:
318
                                q = lseek(f,0,SEEK_CUR);
319
                                break;
320
                        }        
321
                } 
322
        }
323
        q = lseek(f,0,SEEK_CUR);
324
        lseek(f,start+2,SEEK_SET);
325
        if (found) return (unsigned int)(q-start)-4-2;
326
        else return (unsigned int)(q-start-2);
327
        
328
}
329

    
330

    
331
void cread_pes(char *buf, pes_packet *p){
332
        
333
        u8 count, dummy, check;
334
        int i;
335
        uint64_t po = 0;
336
        int c=0;
337

    
338
        switch ( p->stream_id ) {
339
                
340
        case PROG_STREAM_MAP:
341
        case PRIVATE_STREAM2:
342
        case PROG_STREAM_DIR:
343
        case ECM_STREAM     :
344
        case EMM_STREAM     :
345
                memcpy(p->pes_pckt_data,buf+c,p->length);
346
                return;
347
                break;
348
        case PADDING_STREAM :
349
                p->padding = p->length;
350
                memcpy(p->pes_pckt_data,buf+c,p->length);
351
                return;
352
                break;                        
353
        case DSM_CC_STREAM  :
354
        case ISO13522_STREAM:
355
        case PRIVATE_STREAM1:
356
        case AUDIO_STREAM_S ... AUDIO_STREAM_E:
357
        case VIDEO_STREAM_S ... VIDEO_STREAM_E:
358
                break;
359
        default:
360
                return;
361
                break;
362
        }        
363
        
364
        po = c;
365
        memcpy(&p->flags1,buf+c,1);
366
        c++;
367
        if ( (p->flags1 & 0xC0) == 0x80 ) p->mpeg = 2;
368
        else p->mpeg = 1;
369
        
370
        if ( p->mpeg == 2 ){
371
                memcpy(&p->flags2,buf+c,1);
372
                c++;
373
                memcpy(&p->pes_hlength,buf+c,1);
374
                c++;
375
                
376
                p->length -=p->pes_hlength+3;
377
                count = p->pes_hlength;
378
                
379
                if ((p->flags2 & PTS_DTS_FLAGS) == PTS_ONLY){
380
                        memcpy(p->pts,buf+c,5);
381
                        c += 5;
382
                        count -=5;
383
                } else 
384
                        if ((p->flags2 & PTS_DTS_FLAGS) == PTS_DTS){
385
                                memcpy(p->pts,buf+c,5);
386
                                c += 5;
387
                                memcpy(p->dts,buf+c,5);
388
                                c += 5;
389
                                count -= 10;
390
                        }
391
                
392
                if (p->flags2 & ESCR_FLAG){
393
                        memcpy(p->escr,buf+c,6);
394
                        c += 6;
395
                        count -= 6;
396
                }
397
                
398
                if (p->flags2 & ES_RATE_FLAG){
399
                        memcpy(p->es_rate,buf+c,3);
400
                        c += 6;
401
                        count -= 6;
402
                }
403

    
404
                if (p->flags2 & DSM_TRICK_FLAG){
405
                        memcpy(&p->trick,buf+c,1);
406
                        c += 6;
407
                        count -= 1;
408
                }
409
                
410
                if (p->flags2 & ADD_CPY_FLAG){
411
                        memcpy(&p->add_cpy,buf+c,1);
412
                        c++;
413
                        count -= 1;
414
                }
415
                
416
                if (p->flags2 & PES_CRC_FLAG){
417
                        memcpy(p->prev_pes_crc,buf+c,2);
418
                        c += 2;
419
                        count -= 2;
420
                }                        
421
                
422
                if (p->flags2 & PES_EXT_FLAG){
423
                        memcpy(&p->priv_flags,buf+c,1);
424
                        c++;
425
                        count -= 1;
426
                        
427
                        if (p->priv_flags & PRIVATE_DATA){
428
                                memcpy(p->pes_priv_data,buf+c,16);
429
                                c += 16;
430
                                count -= 16;
431
                        }
432
                        
433
                        if (p->priv_flags & HEADER_FIELD){
434
                                memcpy(&p->pack_field_length,buf+c,1);
435
                                c++;
436
                                p->pack_header = (u8 *)
437
                                        malloc(p->pack_field_length);
438
                                memcpy(p->pack_header,buf+c,
439
                                       p->pack_field_length);
440
                                c += p->pack_field_length;
441
                                count -= 1+p->pack_field_length;
442
                        }
443
                        
444
                        if ( p->priv_flags & PACK_SEQ_CTR){
445
                                memcpy(&p->pck_sqnc_cntr,buf+c,1);
446
                                c++;
447
                                memcpy(&p->org_stuff_length,buf+c,1);
448
                                c++;
449
                                count -= 2;
450
                        }
451
                        
452
                        if ( p->priv_flags & P_STD_BUFFER){
453
                                memcpy(p->p_std,buf+c,2);
454
                                c += 2;
455
                                count -= 2;
456
                        }
457

    
458
                        if ( p->priv_flags & PES_EXT_FLAG2){
459
                                memcpy(&p->pes_ext_lngth,buf+c,1);
460
                                c++;
461
                                p->pes_ext = (u8 *)
462
                                        malloc(p->pes_ext_lngth);
463
                                memcpy(p->pes_ext,buf+c,
464
                                       p->pes_ext_lngth);
465
                                c += p->pes_ext_lngth;
466
                                count -= 1+p->pes_ext_lngth;
467
                        }
468
                }
469
                p->stuffing = count;
470
                for(i = 0; i< count ;i++){ 
471
                        memcpy(&dummy,buf+c,1);
472
                        c++;
473
                }
474
        } else {
475
                p->mpeg1_pad = 1;
476
                 check = p->flags1;
477
                while (check == 0xFF){
478
                        memcpy(&check,buf+c,1);
479
                        c++;
480
                        p->mpeg1_pad++;
481
                }
482
                
483
                if ( (check & 0xC0) == 0x40){
484
                        memcpy(&check,buf+c,1);
485
                        c++;
486
                        p->mpeg1_pad++;
487
                        memcpy(&check,buf+c,1);
488
                        c++;
489
                        p->mpeg1_pad++;
490
                }
491
                p->flags2 = 0;
492
                p->length -= p->mpeg1_pad;
493
                
494
                c = po;
495
                if ( (check & 0x30)){
496
                        p->length ++;
497
                        p->mpeg1_pad --;
498
                        
499
                        if (check == p->flags1){
500
                                p->pes_hlength = 0;
501
                        } else {
502
                                p->mpeg1_headr = (u8 *)
503
                                        malloc(p->mpeg1_pad);
504
                                p->pes_hlength = p->mpeg1_pad;
505
                                memcpy(p->mpeg1_headr,buf+c,
506
                                       p->mpeg1_pad);
507
                                c += p->mpeg1_pad;
508
                        }
509
                        
510
                        p->flags2 = (check & 0xF0) << 2;
511
                        if ((p->flags2 & PTS_DTS_FLAGS) == PTS_ONLY){
512
                                memcpy(p->pts,buf+c,5);
513
                                c += 5;
514
                                p->length -= 5;
515
                                p->pes_hlength += 5;
516
                        }
517
                        else if ((p->flags2 & PTS_DTS_FLAGS) == 
518
                                 PTS_DTS){
519
                                memcpy(p->pts,buf+c,5);
520
                                c += 5;
521
                                memcpy(p->dts,buf+c,5);
522
                                c += 5;
523
                                p->length -= 10;
524
                                p->pes_hlength += 10;
525
                        }
526
                } else {
527
                        p->mpeg1_headr = (u8 *) malloc(p->mpeg1_pad);
528
                        p->pes_hlength = p->mpeg1_pad;
529
                        memcpy(p->mpeg1_headr,buf+c,
530
                               p->mpeg1_pad);
531
                        c += p->mpeg1_pad;
532
                }
533
        }
534
        memcpy(p->pes_pckt_data,buf+c,p->length);
535
}
536

    
537

    
538
int read_pes(int f, pes_packet *p){
539
        
540
        u8 sync4[4];
541
        int found=0;
542
        uint64_t po = 0;
543
        int neof = 1;
544
        u8 *buf;
545

    
546
        while (neof > 0 && !found) {
547
                po = lseek(f,0,SEEK_CUR);
548
                if (po < 0) return -1;
549
                if ((neof = read(f,&sync4,4)) < 4) return -1;
550
                if (sync4[0] == 0x00 && sync4[1] == 0x00 && sync4[2] == 0x01) {
551
                        p->stream_id = sync4[3];
552
                        switch ( sync4[3] ) {
553
                                
554
                        case PROG_STREAM_MAP:
555
                        case PRIVATE_STREAM2:
556
                        case PROG_STREAM_DIR:
557
                        case ECM_STREAM     :
558
                        case EMM_STREAM     :
559
                        case PADDING_STREAM :
560
                        case DSM_CC_STREAM  :
561
                        case ISO13522_STREAM:
562
                        case PRIVATE_STREAM1:
563
                        case AUDIO_STREAM_S ... AUDIO_STREAM_E:
564
                        case VIDEO_STREAM_S ... VIDEO_STREAM_E:
565
                                if((neof = read(f,p->llength,2)) < 2)
566
                                        return -1;
567
                                setl_pes(p);
568
                                if (!p->length){ 
569
                                        p->length = find_length(f);
570
                                        nl_pes(p);
571
                                }
572
                                found = 1;
573
                                break;
574
                                
575
                        default:
576
                                if (lseek(f,po+1,SEEK_SET) < po+1) return -1;
577
                        break;
578
                        }        
579
                } else if(lseek(f,po+1,SEEK_SET) < po+1) return -1;
580
        }
581

    
582
        if (!found || !p->length) return 0;
583
        
584
        if (p->length >0){
585
                buf = (u8 *) malloc(p->length);
586
                if((neof = read(f,buf,p->length))< p->length) return -1;
587
                cread_pes((char *)buf,p);
588
                free(buf);
589
        } else return 0;
590

    
591
        return neof;
592
}
593

    
594
/*
595

596
   Transport Stream
597

598
*/
599

    
600
void init_ts(ts_packet *p){
601
        p->pid[0] = 0;
602
        p->pid[1] = 0;
603
        p->flags = 0;
604
        p->count = 0;
605
        p->adapt_length = 0;
606
        p->adapt_flags = 0;
607
        p->splice_count = 0;
608
        p->priv_dat_len = 0;
609
        p->priv_dat = NULL;
610
        p->adapt_ext_len = 0;
611
        p->adapt_eflags = 0;
612
        p->rest = 0;
613
        p->stuffing = 0;
614
}
615

    
616
void kill_ts(ts_packet *p){
617
        if (p->priv_dat)
618
                free(p->priv_dat);
619
        init_ts(p);
620
}
621

    
622

    
623

    
624
unsigned short pid_ts(ts_packet *p)
625
{
626
  return get_pid(p->pid);
627
}
628

    
629
int cwrite_ts(u8 *buf, ts_packet *p, long length){
630
        long count,i;
631
        u8 sync,dummy;
632

    
633
        sync = 0x47;
634
        memcpy(buf,&sync,1);
635
        count = 1;
636
        memcpy(buf+count,p->pid,2);
637
        count += 2;
638
        memcpy(buf+count,&p->flags,1);
639
        count++;
640

    
641
         
642
        if (! (p->flags & ADAPT_FIELD) && (p->flags & PAYLOAD)){
643
                memcpy(buf+count,p->data,184);
644
                count += 184;
645
        } else {
646
                memcpy(buf+count,&p->adapt_length,1);
647
                count++;
648
                memcpy(buf+count,&p->adapt_flags,1);
649
                count++;
650

    
651
                if ( p->adapt_flags & PCR_FLAG ){
652
                        memcpy(buf+count, p->pcr,6);
653
                        count += 6;
654
                }
655
                if ( p->adapt_flags & OPCR_FLAG ){
656
                        memcpy(buf+count, p->opcr,6);
657
                        count += 6;
658
                }
659
                if ( p->adapt_flags & SPLICE_FLAG ){
660
                        memcpy(buf+count, &p->splice_count,1);
661
                        count++;
662
                }
663
                if( p->adapt_flags & TRANS_PRIV){
664
                        memcpy(buf+count,&p->priv_dat_len,1);
665
                        count++;
666
                        memcpy(buf+count,p->priv_dat,p->priv_dat_len);
667
                        count += p->priv_dat_len;
668
                }
669
                        
670
                if( p->adapt_flags & ADAP_EXT_FLAG){
671
                        memcpy(buf+count,&p->adapt_ext_len,1);
672
                        count++;
673
                        memcpy(buf+count,&p->adapt_eflags,1);
674
                        count++;
675
                
676
                        if( p->adapt_eflags & LTW_FLAG){
677
                                memcpy(buf+count,p->ltw,2);
678
                                count += 2;
679
                        }
680
                        if( p->adapt_eflags & PIECE_RATE){
681
                                memcpy(buf+count,p->piece_rate,3);
682
                                count += 3;
683
                        }
684
                        if( p->adapt_eflags & SEAM_SPLICE){
685
                                memcpy(buf+count,p->dts,5);
686
                                count += 5;
687
                        }
688
                }
689
                dummy = 0xFF;
690
                for(i=0; i < p->stuffing ; i++){
691
                        memcpy(buf+count,&dummy,1);
692
                        count++;
693
                }
694
                if (p->flags & PAYLOAD){
695
                        memcpy(buf+count,p->data,p->rest);
696
                        count += p->rest;
697
                }
698
        } 
699

    
700

    
701
        return count;
702
}
703

    
704
void write_ts(int fd, ts_packet *p){
705
        long length;
706
        u8 buf[TS_SIZE];
707

    
708
        length = cwrite_ts(buf,p,TS_SIZE);
709
        write(fd,buf,length);
710
}
711

    
712
int read_ts (int f, ts_packet *p){
713
        u8 sync;
714
        int found=0;
715
        uint64_t po,q;
716
        int neof = 1;
717

    
718
        sync=0;
719
        while (neof > 0 && !found) {
720
                neof = read(f,&sync,1);
721
                if (sync == 0x47) 
722
                        found = 1;
723
        }
724
        neof = read(f,p->pid,2);
725
        neof = read(f,&p->flags,1);
726
        p->count = p->flags & COUNT_MASK;
727
         
728
        if (!(p->flags & ADAPT_FIELD) && (p->flags & PAYLOAD)){
729
                //no adapt. field only payload
730
                neof = read(f,p->data,184);
731
                p->rest = 184;
732
                return neof;
733
        } 
734

    
735
        if ( p->flags & ADAPT_FIELD ) {
736
                // adaption field
737
                neof = read(f,&p->adapt_length,1);
738
                po = lseek(f,0,SEEK_CUR);
739
                neof = read(f,&p->adapt_flags,1);
740

    
741
                if ( p->adapt_flags & PCR_FLAG )
742
                        neof = read(f, p->pcr,6);
743

    
744
                if ( p->adapt_flags & OPCR_FLAG )
745
                        neof = read(f, p->opcr,6);
746

    
747
                if ( p->adapt_flags & SPLICE_FLAG )
748
                        neof = read(f, &p->splice_count,1);
749

    
750
                if( p->adapt_flags & TRANS_PRIV){
751
                        neof = read(f,&p->priv_dat_len,1);
752
                        p->priv_dat = (u8 *) malloc(p->priv_dat_len);
753
                        neof = read(f,p->priv_dat,p->priv_dat_len);
754
                }
755
                        
756
                if( p->adapt_flags & ADAP_EXT_FLAG){
757
                        neof = read(f,&p->adapt_ext_len,1);
758
                        neof = read(f,&p->adapt_eflags,1);
759
                        if( p->adapt_eflags & LTW_FLAG)
760
                                neof = read(f,p->ltw,2);
761
                        
762
                        if( p->adapt_eflags & PIECE_RATE)
763
                                neof = read(f,p->piece_rate,3);
764
                        
765
                        if( p->adapt_eflags & SEAM_SPLICE)
766
                                neof = read(f,p->dts,5);
767
                }
768
                q = lseek(f,0,SEEK_CUR);
769
                p->stuffing = p->adapt_length -(q-po);
770
                p->rest = 183-p->adapt_length;
771
                lseek(f,q+p->stuffing,SEEK_SET);
772
                if (p->flags & PAYLOAD) // payload
773
                        neof = read(f,p->data,p->rest);
774
                else 
775
                        lseek(f,q+p->rest,SEEK_SET);
776
        }
777
        return neof;
778
}
779

    
780
void cread_ts (char *buf, ts_packet *p, long length){
781
        u8 sync;
782
        int found=0;
783
        uint64_t po,q;
784
        long count=0;
785
        
786
        sync=0;
787
        while (count < length  && !found) {
788
                sync=buf[count];
789
                count++;
790
                if (sync == 0x47) 
791
                        found = 1;
792
        }
793
        memcpy(p->pid,buf+count,2);
794
        count += 2;
795
        p->flags = buf[count];
796
        count++;
797
        p->count = p->flags & COUNT_MASK;
798
         
799
        if (!(p->flags & ADAPT_FIELD) && (p->flags & PAYLOAD)){
800
                //no adapt. field only payload
801
                memcpy(p->data,buf+count,184);
802
                p->rest = 184;
803
                return;
804
        } 
805

    
806
        if ( p->flags & ADAPT_FIELD ) {
807
                // adaption field
808
                p->adapt_length = buf[count];
809
                count++;
810
                po = count;
811
                memcpy(&p->adapt_flags,buf+count,1);
812
                count++;
813

    
814
                if ( p->adapt_flags & PCR_FLAG ){
815
                        memcpy( p->pcr,buf+count,6);
816
                        count += 6;
817
                }
818
                if ( p->adapt_flags & OPCR_FLAG ){
819
                        memcpy( p->opcr,buf+count,6);
820
                        count += 6;
821
                }
822
                if ( p->adapt_flags & SPLICE_FLAG ){
823
                        memcpy( &p->splice_count,buf+count,1);
824
                        count++;
825
                }
826
                if( p->adapt_flags & TRANS_PRIV){
827
                        memcpy(&p->priv_dat_len,buf+count,1);
828
                        count++;
829
                        p->priv_dat = (u8 *) malloc(p->priv_dat_len);
830
                        memcpy(p->priv_dat,buf+count,p->priv_dat_len);
831
                        count += p->priv_dat_len;
832
                }
833
                        
834
                if( p->adapt_flags & ADAP_EXT_FLAG){
835
                        memcpy(&p->adapt_ext_len,buf+count,1);
836
                        count++;
837
                        memcpy(&p->adapt_eflags,buf+count,1);
838
                        count++;
839
                        if( p->adapt_eflags & LTW_FLAG){
840
                                memcpy(p->ltw,buf+count,2);
841
                                count += 2;
842
                        }
843
                        if( p->adapt_eflags & PIECE_RATE){
844
                                memcpy(p->piece_rate,buf+count,3);
845
                                count += 3;
846
                        }
847
                        if( p->adapt_eflags & SEAM_SPLICE){
848
                                memcpy(p->dts,buf+count,5);
849
                                count += 5;
850
                        }
851
                }
852
                q = count;
853
                p->stuffing = p->adapt_length -(q-po);
854
                p->rest = 183-p->adapt_length;
855
                count = q+p->stuffing;
856
                if (p->flags & PAYLOAD){ // payload
857
                        memcpy(p->data,buf+count,p->rest);
858
                        count += p->rest;
859
                } else 
860
                        count = q+p->rest;
861
        }
862
}
863

    
864

    
865
/*
866

867
   Program Stream
868

869
*/
870

    
871

    
872
void init_ps(ps_packet *p)
873
{
874
        p->stuff_length=0xF8;
875
        p->data = NULL;
876
        p->sheader_length = 0;
877
        p->audio_bound = 0;
878
        p->video_bound = 0;
879
        p->npes = 0;
880
        p->mpeg = 2;
881
}
882

    
883
void kill_ps(ps_packet *p)
884
{
885
        if (p->data)
886
                free(p->data);
887
        init_ps(p);
888
}
889

    
890
void setlength_ps(ps_packet *p)
891
{
892
        short *ll;
893
        ll = (short *) p->sheader_llength;
894
        if (p->mpeg == 2)
895
                p->sheader_length = ntohs(*ll) - 6;
896
        else 
897
                p->sheader_length = ntohs(*ll);
898
}        
899

    
900
static void setl_ps(ps_packet *p)
901
{
902
        setlength_ps(p);
903
        p->data = (u8 *) malloc(p->sheader_length);
904
}
905

    
906
int mux_ps(ps_packet *p)
907
{
908
        u32 mux = 0;
909
        u8 *i = (u8 *)&mux;
910

    
911
        i[1] = p->mux_rate[0];
912
        i[2] = p->mux_rate[1];
913
        i[3] = p->mux_rate[2];
914
        mux = ntohl(mux);
915
        mux = (mux >>2);
916
        return mux;
917
}
918

    
919
int rate_ps(ps_packet *p)
920
{
921
        u32 rate=0;
922
        u8 *i= (u8 *) &rate;
923

    
924
        i[1] = p->rate_bound[0] & 0x7F;
925
        i[2] = p->rate_bound[1];
926
        i[3] = p->rate_bound[2];
927
        
928
        rate = ntohl(rate);
929
        rate = (rate >> 1);
930
        return rate;
931
}
932

    
933

    
934
u32 scr_base_ps(ps_packet *p) // only 32 bit!!
935
{
936
        u32 base = 0;
937
        u8 *buf = (u8 *)&base;
938
        
939
        buf[0] |= (long int)((p->scr[0] & 0x18) << 3);
940
        buf[0] |= (long int)((p->scr[0] & 0x03) << 4);
941
        buf[0] |= (long int)((p->scr[1] & 0xF0) >> 4);
942
                 
943
        buf[1] |= (long int)((p->scr[1] & 0x0F) << 4);
944
        buf[1] |= (long int)((p->scr[2] & 0xF0) >> 4);
945

    
946
        buf[2] |= (long int)((p->scr[2] & 0x08) << 4);
947
        buf[2] |= (long int)((p->scr[2] & 0x03) << 5);
948
        buf[2] |= (long int)((p->scr[3] & 0xF8) >> 3);
949

    
950
        buf[3] |= (long int)((p->scr[3] & 0x07) << 5);
951
        buf[3] |= (long int)((p->scr[4] & 0xF8) >> 3);
952

    
953
        base = ntohl(base);
954
        return base;
955
}
956

    
957
u16 scr_ext_ps(ps_packet *p)
958
{
959
        short ext = 0;
960

    
961
        ext = (short)(p->scr[5] >> 1);
962
        ext += (short) (p->scr[4] &  0x03) * 128;
963

    
964
        return ext;
965
}
966

    
967
int cwrite_ps(u8 *buf, ps_packet *p, long length)
968
{
969
        long count,i;
970
        u8 headr1[4] = {0x00, 0x00, 0x01, 0xBA };
971
        u8 headr2[4] = {0x00, 0x00, 0x01, 0xBB };
972
        u8 buffy = 0xFF;
973

    
974
        
975
        memcpy(buf,headr1,4);
976
        count = 4;
977
        if (p->mpeg == 2){
978
                memcpy(buf+count,p->scr,6);
979
                count += 6;
980
                memcpy(buf+count,p->mux_rate,3);
981
                count += 3;
982
                memcpy(buf+count,&p->stuff_length,1);
983
                count++;
984
                for(i=0; i< (p->stuff_length & 3); i++){
985
                        memcpy(buf+count,&buffy,1);
986
                        count++;
987
                }
988
        } else {
989
                memcpy(buf+count,p->scr,5);
990
                count += 5;
991
                memcpy(buf+count,p->mux_rate,3);
992
                count += 3;
993
        }
994
        if (p->sheader_length){
995
                memcpy(buf+count,headr2,4);
996
                count += 4;
997
                memcpy(buf+count,p->sheader_llength,2);
998
                count += 2;
999
                if ( p->mpeg == 2){
1000
                        memcpy(buf+count,p->rate_bound,3);
1001
                        count += 3;
1002
                        memcpy(buf+count,&p->audio_bound,1);
1003
                        count++;
1004
                        memcpy(buf+count,&p->video_bound,1);
1005
                        count++;
1006
                        memcpy(buf+count,&p->reserved,1);
1007
                        count++;
1008
                }
1009
                memcpy(buf+count,p->data,p->sheader_length);
1010
                count += p->sheader_length;
1011
        }
1012

    
1013
        return count;
1014
}
1015

    
1016
void write_ps(int fd, ps_packet *p){
1017
        long length;
1018
        u8 buf[PS_MAX];
1019

    
1020
        length = cwrite_ps(buf,p,PS_MAX);
1021
        write(fd,buf,length);
1022
}
1023

    
1024
int read_ps (int f, ps_packet *p){
1025
        u8 headr[4];
1026
        pes_packet pes;
1027
        int i,done;
1028
        int found=0;
1029
        uint64_t po = 0;
1030
        uint64_t q = 0;
1031
        long count = 0;
1032
        int neof = 1;
1033

    
1034
        po = lseek(f,0,SEEK_CUR);
1035
        while (neof > 0 && !found && count < MAX_SEARCH) {
1036
                neof = read(f,&headr,4);
1037
                if (headr[0] == 0x00 && headr[1] == 0x00 && headr[2] == 0x01){
1038
                        if ( headr[3] == 0xBA ) 
1039
                                found = 1;
1040
                        else 
1041
                                if ( headr[3] == 0xB9 ) break;
1042
                                else lseek(f,po+1,SEEK_SET);
1043
                }
1044
                count++;
1045
        }
1046
        
1047
        if (found){
1048
                neof = read(f,p->scr,6);
1049
                if (p->scr[0] & 0x40)
1050
                        p->mpeg = 2;
1051
                else
1052
                        p->mpeg = 1;
1053

    
1054
                if (p->mpeg == 2){
1055
                        neof = read(f,p->mux_rate,3);
1056
                        neof = read(f,&p->stuff_length,1);
1057
                        po = lseek(f,0,SEEK_CUR);
1058
                        lseek(f,po+(p->stuff_length & 3),SEEK_SET);
1059
                } else {
1060
                        p->mux_rate[0] = p->scr[5]; //mpeg1 scr is only 5 bytes
1061
                        neof = read(f,p->mux_rate+1,2);
1062
                }
1063
                        
1064
                po = lseek(f,0,SEEK_CUR);
1065
                neof = read(f,headr,4);
1066
                if (headr[0] == 0x00 && headr[1] == 0x00 && 
1067
                    headr[2] == 0x01 && headr[3] == 0xBB ) {
1068
                        neof = read(f,p->sheader_llength,2);
1069
                        setl_ps(p);
1070
                        if (p->mpeg == 2){
1071
                                neof = read(f,p->rate_bound,3);
1072
                                neof = read(f,&p->audio_bound,1);
1073
                                neof = read(f,&p->video_bound,1);
1074
                                neof = read(f,&p->reserved,1);
1075
                        }
1076
                        neof = read(f,p->data,p->sheader_length);
1077
                } else {
1078
                        lseek(f,po,SEEK_SET);
1079
                        p->sheader_length = 0;
1080
                }
1081

    
1082
                i = 0;
1083
                done = 0;
1084
                q = lseek(f,0,SEEK_CUR);
1085
                do {
1086
                        po = lseek(f,0,SEEK_CUR);
1087
                        neof = read(f,headr,4);
1088
                        lseek(f,po,SEEK_SET);
1089
                        if ( headr[0] == 0x00 && headr[1] == 0x00 
1090
                             && headr[2] == 0x01 && headr[3] != 0xBA){
1091
                                init_pes(&pes);
1092
                                neof = read_pes(f,&pes);
1093
                                i++;
1094
                        } else done = 1;
1095
                        kill_pes(&pes);
1096
                } while ( neof > 0 && !done);
1097
                p->npes = i;
1098
                lseek(f,q,SEEK_SET);
1099
        } 
1100
        return neof;
1101
}
1102

    
1103
void cread_ps (char *buf, ps_packet *p, long length){
1104
        u8 *headr;
1105
        pes_packet pes;
1106
        int i,done;
1107
        int found=0;
1108
        uint64_t po = 0;
1109
        uint64_t q = 0;
1110
        long count = 0;
1111
        long c = 0;
1112
        
1113
        po = c;
1114
        while ( count < length && !found && count < MAX_SEARCH) {
1115
                headr = (u8 *)buf+c;
1116
                c += 4;
1117
                if (headr[0] == 0x00 && headr[1] == 0x00 && headr[2] == 0x01){
1118
                        if ( headr[3] == 0xBA ) 
1119
                                found = 1;
1120
                        else 
1121
                                if ( headr[3] == 0xB9 ) break;
1122
                                else c = po+1;
1123
                }
1124
                count++;
1125
        }
1126
        
1127
        if (found){
1128
                memcpy(p->scr,buf+c,6);
1129
                c += 6;
1130
                if (p->scr[0] & 0x40)
1131
                        p->mpeg = 2;
1132
                else
1133
                        p->mpeg = 1;
1134

    
1135
                if (p->mpeg == 2){
1136
                        memcpy(p->mux_rate,buf+c,3);
1137
                        c += 3;
1138
                        memcpy(&p->stuff_length,buf+c,1);
1139
                        c++;
1140
                        po = c;
1141
                        c = po+(p->stuff_length & 3);
1142
                } else {
1143
                        p->mux_rate[0] = p->scr[5]; //mpeg1 scr is only 5 bytes
1144
                        memcpy(p->mux_rate+1,buf+c,2);
1145
                        c += 2;
1146
                }
1147
                        
1148
                po = c;
1149
                headr = (u8 *)buf+c;
1150
                c += 4;
1151
                if (headr[0] == 0x00 && headr[1] == 0x00 && 
1152
                    headr[2] == 0x01 && headr[3] == 0xBB ) {
1153
                        memcpy(p->sheader_llength,buf+c,2);
1154
                        c += 2;
1155
                        setl_ps(p);
1156
                        if (p->mpeg == 2){
1157
                                memcpy(p->rate_bound,buf+c,3);
1158
                                c += 3;
1159
                                memcpy(&p->audio_bound,buf+c,1);
1160
                                c++;
1161
                                memcpy(&p->video_bound,buf+c,1);
1162
                                c++;
1163
                                memcpy(&p->reserved,buf+c,1);
1164
                                c++;
1165
                        }
1166
                        memcpy(p->data,buf+c,p->sheader_length);
1167
                        c += p->sheader_length;
1168
                } else {
1169
                        c = po;
1170
                        p->sheader_length = 0;
1171
                }
1172

    
1173
                i = 0;
1174
                done = 0;
1175
                q = c;
1176
                do {
1177
                        headr = (u8 *)buf+c;
1178
                        if ( headr[0] == 0x00 && headr[1] == 0x00 
1179
                             && headr[2] == 0x01 && headr[3] != 0xBA){
1180
                                init_pes(&pes);
1181
                                //        cread_pes(buf+c,&pes);
1182
                                i++;
1183
                        } else done = 1;
1184
                        kill_pes(&pes);
1185
                } while (c < length && !done);
1186
                p->npes = i;
1187
                c = q;
1188
        } 
1189
}
1190

    
1191

    
1192

    
1193

    
1194

    
1195

    
1196

    
1197
/*
1198
  conversion
1199
*/
1200

    
1201
void init_trans(trans *p)
1202
{
1203
        int i;
1204

    
1205
        p->found = 0;
1206
        p->pes = 0;
1207
        p->is_full = 0;
1208
        p->pes_start = 0;
1209
        p->pes_started = 0;
1210
        p->set = 0;
1211

    
1212
        for (i = 0; i < MASKL*MAXFILT ; i++){
1213
                p->mask[i] = 0;
1214
                p->filt[i] = 0;
1215
        }
1216
        for (i = 0; i < MAXFILT ; i++){
1217
                p->sec[i].found = 0;
1218
                p->sec[i].length = 0;
1219
        }        
1220
}
1221

    
1222
int set_trans_filt(trans *p, int filtn, u16 pid, u8 *mask, u8 *filt, int pes)
1223
{
1224
        int i;
1225
        int off;
1226

    
1227
        if ( filtn > MAXFILT-1 || filtn<0 ) return -1;
1228
        p->pid[filtn] = pid;
1229
        if (pes) p->pes |= (tflags)(1 << filtn);
1230
        else {
1231
                off = MASKL*filtn;
1232
                p->pes &= ~((tflags) (1 << filtn) );
1233
                for (i = 0; i < MASKL ; i++){
1234
                        p->mask[off+i] = mask[i];
1235
                        p->filt[off+i] = filt[i];
1236
                }
1237
        }                
1238
        p->set |= (tflags) (1 << filtn);
1239
        return 0;
1240
}
1241

    
1242
void clear_trans_filt(trans *p,int filtn)
1243
{
1244
        int i;
1245

    
1246
        p->set &= ~((tflags) (1 << filtn) );
1247
        p->pes &= ~((tflags) (1 << filtn) );
1248
        p->is_full &= ~((tflags) (1 << filtn) );
1249
        p->pes_start &= ~((tflags) (1 << filtn) );
1250
        p->pes_started &= ~((tflags) (1 << filtn) );
1251

    
1252
        for (i = MASKL*filtn; i < MASKL*(filtn+1) ; i++){
1253
                p->mask[i] = 0;
1254
                p->filt[i] = 0;
1255
        }
1256
        p->sec[filtn].found = 0;
1257
        p->sec[filtn].length = 0;
1258
}
1259

    
1260
int filt_is_set(trans *p, int filtn)
1261
{
1262
        if (p->set & ((tflags)(1 << filtn))) return 1;
1263
        return 0;
1264
}
1265

    
1266
int pes_is_set(trans *p, int filtn)
1267
{
1268
        if (p->pes & ((tflags)(1 << filtn))) return 1;
1269
        return 0;
1270
}
1271

    
1272
int pes_is_started(trans *p, int filtn)
1273
{
1274
        if (p->pes_started & ((tflags)(1 << filtn))) return 1;
1275
        return 0;
1276
}
1277

    
1278
int pes_is_start(trans *p, int filtn)
1279
{
1280
        if (p->pes_start & ((tflags)(1 << filtn))) return 1;
1281
        return 0;
1282
}
1283

    
1284
int filt_is_ready(trans *p,int filtn)
1285
{
1286
        if (p->is_full & ((tflags)(1 << filtn))) return 1;
1287
        return 0;
1288
}
1289

    
1290
void trans_filt(u8 *buf, int count, trans *p)
1291
{
1292
        int c=0;
1293
        //fprintf(stderr,"trans_filt\n");
1294
        
1295

    
1296
        while (c < count && p->found <1 ){
1297
                if ( buf[c] == 0x47) p->found = 1;
1298
                c++;
1299
                p->packet[0] = 0x47;
1300
        }
1301
        if (c == count) return;
1302
        
1303
        while( c < count && p->found < 188 && p->found > 0 ){
1304
                p->packet[p->found] = buf[c];
1305
                c++;
1306
                p->found++;
1307
        }
1308
        if (p->found == 188){
1309
                p->found = 0;
1310
                filter(p);
1311
        }
1312

    
1313
        if (c < count) trans_filt(buf+c,count-c,p);
1314
} 
1315

    
1316

    
1317
void filter(trans *p)
1318
{
1319
        int l,c;
1320
        int tpid;
1321
        u8 flag,flags;
1322
        u8 adapt_length = 0;
1323
        u8 cpid[2];
1324

    
1325

    
1326
        //        fprintf(stderr,"filter\n");
1327

    
1328
        cpid[0] = p->packet[1];
1329
        cpid[1] = p->packet[2];
1330
        tpid = get_pid(cpid);
1331

    
1332
        flag = cpid[0];
1333
        flags = p->packet[3];
1334
        
1335
        if ( flags & ADAPT_FIELD ) {
1336
                // adaption field
1337
                adapt_length = p->packet[4];
1338
        }
1339

    
1340
        c = 5 + adapt_length - (int)(!(flags & ADAPT_FIELD));
1341
        if (flags & PAYLOAD){
1342
                for ( l = 0; l < MAXFILT ; l++){
1343
                        if ( filt_is_set(p,l) ) {
1344
                                if ( p->pid[l] == tpid) {
1345
                                        if ( pes_is_set(p,l) ){
1346
                                                if (cpid[0] & PAY_START){
1347
                                                        p->pes_started |= 
1348
                                                                (tflags) 
1349
                                                                (1 << l);
1350
                                                        p->pes_start |= 
1351
                                                                (tflags) 
1352
                                                                (1 << l);
1353
                                                } else {
1354
                                                        p->pes_start &= ~ 
1355
                                                                ((tflags) 
1356
                                                                (1 << l));
1357
                                                }
1358
                                                pes_filter(p,l,c);
1359
                                        } else {
1360
                                                sec_filter(p,l,c);
1361
                                        }        
1362
                                }
1363
                        }
1364
                }
1365
        }
1366
}        
1367

    
1368

    
1369
void pes_filter(trans *p, int filtn, int off)
1370
{
1371
        int count,c;
1372
        u8 *buf;
1373

    
1374
        if (filtn < 0 || filtn >= MAXFILT) return; 
1375

    
1376
        count = 188 - off;
1377
        c = 188*filtn;
1378
        buf = p->packet+off;
1379
        if (pes_is_started(p,filtn)){
1380
                p->is_full |= (tflags) (1 << filtn);
1381
                memcpy(p->transbuf+c,buf,count);
1382
                p->transcount[filtn] = count;
1383
        }
1384
}
1385

    
1386
section *get_filt_sec(trans *p, int filtn)
1387
{
1388
        section *sec;
1389
        
1390
        sec = &p->sec[filtn];
1391
        p->is_full &= ~((tflags) (1 << filtn) );
1392
        return sec;
1393
}
1394

    
1395
int get_filt_buf(trans *p, int filtn,u8 **buf)
1396
{
1397
        *buf = p->transbuf+188*filtn;
1398
        p->is_full &= ~((tflags) (1 << filtn) );
1399
        return p->transcount[filtn];
1400
}
1401

    
1402

    
1403

    
1404

    
1405
void sec_filter(trans *p, int filtn, int off)
1406
{
1407
        int i,j;
1408
        int error;
1409
        int count,c;
1410
        u8 *buf, *secbuf;
1411
        section *sec;
1412

    
1413
        //        fprintf(stderr,"sec_filter\n");
1414

    
1415
        if (filtn < 0 || filtn >= MAXFILT) return; 
1416

    
1417
        count = 188 - off;
1418
        c = 0;
1419
        buf = p->packet+off;
1420
        sec = &p->sec[filtn];
1421
        secbuf = sec->payload;
1422
        if(!filt_is_ready(p,filtn)){
1423
                p->is_full &= ~((tflags) (1 << filtn) );
1424
                sec->found = 0;
1425
                sec->length = 0;
1426
        }
1427
                
1428
        if ( !sec->found ){
1429
                c = buf[c]+1;
1430
                if (c >= count) return;
1431
                sec->id = buf[c];
1432
                secbuf[0] = buf[c];
1433
                c++;
1434
                sec->found++;
1435
                sec->length = 0;
1436
        }
1437
        
1438
        while ( c < count && sec->found < 3){
1439
                secbuf[sec->found] = buf[c];
1440
                c++;
1441
                sec->found++;
1442
        }
1443
        if (c == count) return;
1444
        
1445
        if (!sec->length && sec->found == 3){
1446
                sec->length |= ((secbuf[1] & 0x0F) << 8); 
1447
                sec->length |= (secbuf[2] & 0xFF);
1448
        }
1449
        
1450
        while ( c < count && sec->found < sec->length+3){
1451
                secbuf[sec->found] = buf[c];
1452
                c++;
1453
                sec->found++;
1454
        }
1455

    
1456
        if ( sec->length && sec->found == sec->length+3 ){
1457
                error=0;
1458
                for ( i = 0; i < MASKL; i++){
1459
                        if (i > 0 ) j=2+i;
1460
                        else j = 0;
1461
                        error += (sec->payload[j]&p->mask[MASKL*filtn+i])^
1462
                                (p->filt[MASKL*filtn+i]&
1463
                                 p->mask[MASKL*filtn+i]);
1464
                }
1465
                if (!error){
1466
                        p->is_full |= (tflags) (1 << filtn);
1467
                }
1468
                if (buf[0]+1 < c ) c=count;
1469
        }
1470
        
1471
        if ( c < count ) sec_filter(p, filtn, off);
1472

    
1473
}
1474

    
1475
#define MULT 1024
1476

    
1477

    
1478
void write_ps_headr( ps_packet *p, u8 *pts,int fd)
1479
{
1480
        long  muxr = 37500;
1481
        u8    audio_bound = 1;
1482
        u8    fixed = 0;
1483
        u8    CSPS = 0;
1484
        u8    audio_lock = 1;
1485
        u8    video_lock = 1;
1486
        u8    video_bound = 1;
1487
        u8    stream1 = 0XC0;
1488
        u8    buffer1_scale = 1;
1489
        u32   buffer1_size = 32;
1490
        u8    stream2 = 0xE0;
1491
        u8    buffer2_scale = 1;
1492
        u32   buffer2_size = 230;
1493
                    
1494
        init_ps(p);
1495
        
1496
        p->mpeg = 2;
1497
// SCR = 0
1498
        p->scr[0] = 0x44;
1499
        p->scr[1] = 0x00;
1500
        p->scr[2] = 0x04;
1501
        p->scr[3] = 0x00;
1502
        p->scr[4] = 0x04;
1503
        p->scr[5] = 0x01;
1504
        
1505
// SCR = PTS
1506
        p->scr[0] = 0x44 | ((pts[0] >> 3)&0x18) | ((pts[0] >> 4)&0x03);
1507
        p->scr[1] = 0x00 | ((pts[0] << 4)&0xF0) | ((pts[1] >> 4)&0x0F);
1508
        p->scr[2] = 0x04 | ((pts[1] << 4)&0xF0) | ((pts[2] >> 4)&0x08)
1509
                | ((pts[2] >> 5)&0x03);
1510
        p->scr[3] = 0x00 | ((pts[2] << 3)&0xF8) | ((pts[3] >> 5)&0x07);
1511
        p->scr[4] = 0x04 | ((pts[3] << 3)&0xF8);
1512
        p->scr[5] = 0x01;
1513
        
1514
        p->mux_rate[0] = (u8)(muxr >> 14);
1515
        p->mux_rate[1] = (u8)(0xff & (muxr >> 6));
1516
        p->mux_rate[2] = (u8)(0x03 | ((muxr & 0x3f) << 2));
1517

    
1518
        p->stuff_length = 0xF8;
1519
        
1520
        p->sheader_llength[0] = 0x00;
1521
        p->sheader_llength[1] = 0x0c;
1522

    
1523
        setl_ps(p);
1524
        
1525
        p->rate_bound[0] = (u8)(0x80 | (muxr >>15));
1526
        p->rate_bound[1] = (u8)(0xff & (muxr >> 7));
1527
        p->rate_bound[2] = (u8)(0x01 | ((muxr & 0x7f)<<1));
1528
        
1529
        
1530
        p->audio_bound = (u8)((audio_bound << 2)|(fixed << 1)|CSPS);
1531
        p->video_bound = (u8)((audio_lock << 7)|
1532
                              (video_lock << 6)|0x20|video_bound);
1533
        p->reserved = (u8)(0xFF);
1534
        
1535
        p->data[0] =  stream2;
1536
        p->data[1] =  (u8) (0xc0 | (buffer2_scale << 5) | 
1537
                            (buffer2_size >> 8));
1538
        p->data[2] =  (u8) (buffer2_size & 0xff);
1539
        p->data[3] =  stream1;
1540
        p->data[4] =  (u8) (0xc0 | (buffer1_scale << 5) | 
1541
                            (buffer1_size >> 8));
1542
        p->data[5] =  (u8) (buffer1_size & 0xff);
1543
        
1544
        write_ps(fd, p);
1545
        kill_ps(p);
1546
}
1547

    
1548

    
1549

    
1550
void twrite(u8 const *buf)
1551
{
1552
        int l = TS_SIZE;
1553
        int c = 0;
1554
        int w;
1555

    
1556

    
1557
        while (l){
1558
                w = write(STDOUT_FILENO,buf+c,l);
1559
                if (w>=0){
1560
                        l-=w;
1561
                        c+=w;
1562
                }
1563
        }
1564
}
1565

    
1566
void init_p2t(p2t_t *p, void (*fkt)(u8 const *buf))
1567
{
1568
        memset(p->pes,0,TS_SIZE);
1569
        p->counter = 0;
1570
        p->pos = 0;
1571
        p->frags = 0;
1572
        if (fkt) p->t_out = fkt;
1573
        else p->t_out = twrite;
1574
}
1575

    
1576
void clear_p2t(p2t_t *p)
1577
{
1578
        memset(p->pes,0,TS_SIZE);
1579
        p->counter = 0;
1580
        p->pos = 0;
1581
        p->frags = 0;
1582
}
1583

    
1584

    
1585
long int find_pes_header(u8 const *buf, long int length, int *frags)
1586
{
1587
        int c = 0;
1588
        int found = 0;
1589

    
1590
        *frags = 0;
1591

    
1592
        while (c < length-3 && !found) {
1593
                if (buf[c] == 0x00 && buf[c+1] == 0x00 && 
1594
                    buf[c+2] == 0x01) {
1595
                        switch ( buf[c+3] ) {
1596
                        case 0xBA:
1597
                        case PROG_STREAM_MAP:
1598
                        case PRIVATE_STREAM2:
1599
                        case PROG_STREAM_DIR:
1600
                        case ECM_STREAM     :
1601
                        case EMM_STREAM     :
1602
                        case PADDING_STREAM :
1603
                        case DSM_CC_STREAM  :
1604
                        case ISO13522_STREAM:
1605
                        case PRIVATE_STREAM1:
1606
                        case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1607
                        case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1608
                                found = 1;
1609
                                break;
1610
                                
1611
                        default:
1612
                                c++;
1613
                                break;
1614
                        }        
1615
                } else c++;
1616
        }
1617
        if (c == length-3 && !found){
1618
                if (buf[length-1] == 0x00) *frags = 1;
1619
                if (buf[length-2] == 0x00 &&
1620
                    buf[length-1] == 0x00) *frags = 2;
1621
                if (buf[length-3] == 0x00 &&
1622
                    buf[length-2] == 0x00 &&
1623
                    buf[length-1] == 0x01) *frags = 3;
1624
                return -1;
1625
        }
1626

    
1627
        return c;
1628
}
1629

    
1630
void pes_to_ts( u8 const *buf, long int length, u16 pid, p2t_t *p)
1631
{
1632
        int c,c2,l,add;
1633
        int check,rest;
1634

    
1635
        c = 0;
1636
        c2 = 0;
1637
        if (p->frags){
1638
                check = 0;
1639
                switch(p->frags){
1640
                case 1:
1641
                        if ( buf[c] == 0x00 && buf[c+1] == 0x01 ){
1642
                                check = 1;
1643
                                c += 2;
1644
                        }
1645
                        break;
1646
                case 2:
1647
                        if ( buf[c] == 0x01 ){
1648
                                check = 1;
1649
                                c++;
1650
                        }
1651
                        break;
1652
                case 3:
1653
                        check = 1;
1654
                }
1655
                if(check){
1656
                        switch ( buf[c] ) {
1657
                                
1658
                        case PROG_STREAM_MAP:
1659
                        case PRIVATE_STREAM2:
1660
                        case PROG_STREAM_DIR:
1661
                        case ECM_STREAM     :
1662
                        case EMM_STREAM     :
1663
                        case PADDING_STREAM :
1664
                        case DSM_CC_STREAM  :
1665
                        case ISO13522_STREAM:
1666
                        case PRIVATE_STREAM1:
1667
                        case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1668
                        case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1669
                                p->pes[0] = 0x00;
1670
                                p->pes[1] = 0x00;
1671
                                p->pes[2] = 0x01;
1672
                                p->pes[3] = buf[c];
1673
                                p->pos=4;
1674
                                memcpy(p->pes+p->pos,buf+c,TS_SIZE-4-p->pos);
1675
                                c += TS_SIZE-4-p->pos;
1676
                                p_to_t(p->pes,TS_SIZE-4,pid,&p->counter,
1677
                                       p->t_out);
1678
                                clear_p2t(p);
1679
                                break;
1680
                                
1681
                        default:
1682
                                c=0;
1683
                                break;
1684
                        }
1685
                }
1686
                p->frags = 0;
1687
        }
1688
                
1689
        if (p->pos){
1690
                c2 = find_pes_header(buf+c,length-c,&p->frags);
1691
                if (c2 >= 0 && c2 < TS_SIZE-4-p->pos){
1692
                        l = c2+c;
1693
                } else l = TS_SIZE-4-p->pos;
1694
                memcpy(p->pes+p->pos,buf,l);
1695
                c += l;
1696
                p->pos += l;
1697
                p_to_t(p->pes,p->pos,pid,&p->counter,
1698
                       p->t_out);
1699
                clear_p2t(p);
1700
        }
1701
                        
1702
        add = 0;
1703
        while (c < length){
1704
                c2 = find_pes_header(buf+c+add,length-c-add,&p->frags);
1705
                if (c2 >= 0) {
1706
                        c2 += c+add;
1707
                        if (c2 > c){
1708
                                p_to_t(buf+c,c2-c,pid,&p->counter,
1709
                                       p->t_out);
1710
                                c = c2;
1711
                                clear_p2t(p);
1712
                                add = 0;
1713
                        } else add = 1;
1714
                } else {
1715
                        l = length-c;
1716
                        rest = l % (TS_SIZE-4);
1717
                        l -= rest;
1718
                        p_to_t(buf+c,l,pid,&p->counter,
1719
                               p->t_out);
1720
                        memcpy(p->pes,buf+c+l,rest);
1721
                        p->pos = rest;
1722
                        c = length;
1723
                }
1724
        }
1725
}
1726

    
1727

    
1728

    
1729
void p_to_t( u8 const *buf, long int length, u16 pid, u8 *counter, 
1730
            void (*ts_write)(u8 const *))
1731
{
1732
  
1733
        int l, pes_start;
1734
        u8 obuf[TS_SIZE];
1735
        long int c = 0;
1736
        pes_start = 0;
1737
        if ( length > 3 && 
1738
             buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x01 )
1739
                switch (buf[3]){
1740
                        case PROG_STREAM_MAP:
1741
                        case PRIVATE_STREAM2:
1742
                        case PROG_STREAM_DIR:
1743
                        case ECM_STREAM     :
1744
                        case EMM_STREAM     :
1745
                        case PADDING_STREAM :
1746
                        case DSM_CC_STREAM  :
1747
                        case ISO13522_STREAM:
1748
                        case PRIVATE_STREAM1:
1749
                        case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1750
                        case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1751
                                pes_start = 1;
1752
                                break;
1753
                                
1754
                        default:
1755
                                break;
1756
                }                        
1757

    
1758
        while ( c < length ){
1759
                memset(obuf,0,TS_SIZE);
1760
                if (length - c >= TS_SIZE-4){
1761
                        l = write_ts_header(pid, counter, pes_start
1762
                                             , obuf, TS_SIZE-4);
1763
                        memcpy(obuf+l, buf+c, TS_SIZE-l);
1764
                        c += TS_SIZE-l;
1765
                } else { 
1766
                        l = write_ts_header(pid, counter, pes_start
1767
                                             , obuf, length-c);
1768
                        memcpy(obuf+l, buf+c, TS_SIZE-l);
1769
                        c = length;
1770
                }
1771
                ts_write(obuf);
1772
                pes_start = 0;
1773
        }
1774
}
1775

    
1776

    
1777
int write_ps_header(uint8_t *buf, 
1778
                    uint32_t   SCR, 
1779
                    long  muxr,
1780
                    uint8_t    audio_bound,
1781
                    uint8_t    fixed,
1782
                    uint8_t    CSPS,
1783
                    uint8_t    audio_lock,
1784
                    uint8_t    video_lock,
1785
                    uint8_t    video_bound,
1786
                    uint8_t    stream1,
1787
                    uint8_t    buffer1_scale,
1788
                    uint32_t   buffer1_size,
1789
                    uint8_t    stream2,
1790
                    uint8_t    buffer2_scale,
1791
                    uint32_t   buffer2_size)                    
1792
{
1793
        ps_packet p;
1794
        uint8_t *pts;
1795
        long lpts;
1796
        init_ps(&p);
1797
        
1798
        lpts = htonl(SCR);
1799
        pts = (uint8_t *) &lpts;
1800

    
1801
        
1802
        p.mpeg = 2;
1803
// SCR = 0
1804
        p.scr[0] = 0x44;
1805
        p.scr[1] = 0x00;
1806
        p.scr[2] = 0x04;
1807
        p.scr[3] = 0x00;
1808
        p.scr[4] = 0x04;
1809
        p.scr[5] = 0x01;
1810
        
1811
// SCR = PTS
1812
        p.scr[0] = 0x44 | ((pts[0] >> 3)&0x18) | ((pts[0] >> 4)&0x03);
1813
        p.scr[1] = 0x00 | ((pts[0] << 4)&0xF0) | ((pts[1] >> 4)&0x0F);
1814
        p.scr[2] = 0x04 | ((pts[1] << 4)&0xF0) | ((pts[2] >> 4)&0x08)
1815
                | ((pts[2] >> 5)&0x03);
1816
        p.scr[3] = 0x00 | ((pts[2] << 3)&0xF8) | ((pts[3] >> 5)&0x07);
1817
        p.scr[4] = 0x04 | ((pts[3] << 3)&0xF8);
1818
        p.scr[5] = 0x01;
1819
        
1820
        p.mux_rate[0] = (uint8_t)(muxr >> 14);
1821
        p.mux_rate[1] = (uint8_t)(0xff & (muxr >> 6));
1822
        p.mux_rate[2] = (uint8_t)(0x03 | ((muxr & 0x3f) << 2));
1823

    
1824
        p.stuff_length = 0xF8;
1825
        
1826
        if (stream1 && stream2){
1827
                p.sheader_llength[0] = 0x00;
1828
                p.sheader_llength[1] = 0x0c;
1829

    
1830
                setl_ps(&p);
1831
                
1832
                p.rate_bound[0] = (uint8_t)(0x80 | (muxr >>15));
1833
                p.rate_bound[1] = (uint8_t)(0xff & (muxr >> 7));
1834
                p.rate_bound[2] = (uint8_t)(0x01 | ((muxr & 0x7f)<<1));
1835

    
1836
        
1837
                p.audio_bound = (uint8_t)((audio_bound << 2)|(fixed << 1)|CSPS);
1838
                p.video_bound = (uint8_t)((audio_lock << 7)|
1839
                                     (video_lock << 6)|0x20|video_bound);
1840
                p.reserved = (uint8_t)(0xFF >> 1);
1841
                
1842
                p.data[0] =  stream2;
1843
                p.data[1] =  (uint8_t) (0xc0 | (buffer2_scale << 5) | 
1844
                                   (buffer2_size >> 8));
1845
                p.data[2] =  (uint8_t) (buffer2_size & 0xff);
1846
                p.data[3] =  stream1;
1847
                p.data[4] =  (uint8_t) (0xc0 | (buffer1_scale << 5) | 
1848
                                   (buffer1_size >> 8));
1849
                p.data[5] =  (uint8_t) (buffer1_size & 0xff);
1850
                
1851
                cwrite_ps(buf, &p, PS_HEADER_L2);
1852
                kill_ps(&p);
1853
                return PS_HEADER_L2;
1854
        } else {
1855
                cwrite_ps(buf, &p, PS_HEADER_L1);
1856
                kill_ps(&p);
1857
                return PS_HEADER_L1;
1858
        }
1859
}
1860

    
1861

    
1862

    
1863
#define MAX_BASE 80
1864
#define MAX_PATH 256
1865
#define MAX_EXT 10
1866

    
1867
int break_up_filename(char *name, char *base_name, char *path, char *ext)
1868
{
1869
        int l,i,sstop,sstart;
1870

    
1871
        l = strlen(name);
1872
        sstop = l;
1873
        sstart = -1;
1874
        for( i= l-1; i >= 0; i--){
1875
                if (sstop == l && name[i] == '.') sstop = i;
1876
                if (sstart<0 && name[i] == '/') sstart = i+1;
1877
        }
1878
        if (sstart < 0) sstart = 0;
1879
        if (sstop-sstart < MAX_BASE){
1880
                strncpy(base_name, name+sstart, sstop-sstart);
1881
                base_name[sstop-sstart]=0;
1882
                if(sstart > 0){
1883
                        if( l - sstop + sstart < MAX_PATH){
1884
                                strncpy(path, name, sstart);
1885
                                path[sstart] = 0;
1886
                        } else {
1887
                                fprintf(stderr,"PATH too long\n");
1888
                                return -1;
1889
                        }
1890

    
1891
                } else {
1892
                        strcpy(path, "./");
1893
                }
1894

    
1895
                if(sstop < l){
1896
                        if( l - sstop -1 < MAX_EXT){
1897
                                strncpy(ext, name+sstop+1, l-sstop-1);
1898
                                ext[l-sstop-1]=0;
1899
                        } else {
1900
                                fprintf(stderr,"Extension too long\n");
1901
                                return -1;
1902
                        }
1903

    
1904
                } else {
1905
                        strcpy(ext, "");
1906
                }
1907

    
1908
        } else {
1909
                fprintf(stderr,"Name too long\n");
1910
                return -1;
1911
        }
1912
/*
1913
        printf("%d %d\n",sstart, sstop);
1914
        printf("%s %d\n",name, strlen(name));
1915
        printf("%s %d\n",base_name, strlen(base_name));
1916
        printf("%s %d\n",path,strlen(path));
1917
        printf("%s %d\n",ext,strlen(ext));
1918
*/  
1919
        return 0;
1920
}
1921

    
1922

    
1923
int seek_mpg_start(uint8_t *buf, int size)
1924
{
1925
        int found = 0;
1926
        int c=0;
1927
        int seq = 0;
1928
        int mpeg = 0;
1929
        int mark = 0;
1930

    
1931
        while ( !seq ){
1932
                while (found != 4){
1933
                        switch (found) {
1934
                        case 0:
1935
                                if ( buf[c] == 0x00 ) found++;
1936
                                c++;
1937
                                break;
1938
                        case 1:
1939
                                if ( buf[c] == 0x00 ) found++;
1940
                                else found = 0;
1941
                                c++;
1942
                                break;                           
1943
                        case 2:
1944
                                if ( buf[c] == 0x01 ) found++;
1945
                                else found = 0;
1946
                                if ( buf[c] == 0x00 ) found = 2;
1947
                                c++;
1948
                                break;
1949
                        
1950
                        case 3:
1951
                                if ( (buf[c] & 0xe0) == 0xe0 ) found++;
1952
                                else found = 0;
1953
                                c++;
1954
                                break;
1955
                        }
1956
                        if (c >= size) return -1;
1957
                }
1958
                
1959
                if (found == 4){
1960
                        mark = c-4;
1961
                        c+=2;
1962
                        if (c >= size) return -1;
1963

    
1964
                        if ( (buf[c] & 0xC0) == 0x80 ){
1965
                                mpeg = 2;
1966
                                c += 2;
1967
                                if (c >= size) return -1;
1968
                                c += buf[c]+1;
1969
                                if (c >= size) return -1;
1970
                        } else {
1971
                                mpeg = 1;
1972
                                while( buf[c] == 0xFF ) {
1973
                                        c++;
1974
                                        if (c >= size) return -1;
1975
                                }
1976
                                if ( (buf[c] & 0xC0) == 0x40) c+=2;
1977
                                if (c >= size) return -1;
1978
                                if ( (buf[c] & 0x30) ){
1979
                                        if ( (buf[c] & 0x30) == 0x20) c+=5;
1980
                                        else c+=10;
1981
                                } else c++;
1982
                                if (c >= size) return -1;
1983
                        }
1984

    
1985
                        if ( buf[c] == 0x00 && 
1986
                             buf[c+1] == 0x00 && 
1987
                             buf[c+2] == 0x01 && 
1988
                             buf[c+3] == 0xB3 ) 
1989
                                seq = 1;
1990
                }
1991
                found = 0;
1992
        }
1993

    
1994
        return size-mark;
1995
}
1996

    
1997

    
1998
void write_mpg(int fstart, uint64_t length, int fdin, int fdout)
1999
{
2000
//        uint8_t mpeg_end[4] = { 0x00, 0x00, 0x01, 0xB9 };
2001
        uint8_t *buf;
2002
        uint64_t l=0;
2003
        uint64_t count = 0;
2004
        struct stat sb;
2005
        int buf_size;
2006

    
2007
        fstat (fdout, &sb);
2008
        buf_size =  sb.st_blksize;
2009

    
2010
        buf = (char *) alloca (buf_size + sizeof (int));
2011
        
2012
        lseek(fdin, fstart, SEEK_SET);
2013

    
2014
        while ( count < length && (l = read(fdin,buf,buf_size)) >= 0){
2015
                if (l > 0) count+=l;
2016
                write(fdout,buf,l);
2017
                printf("written %02.2f%%\r",(100.*count)/length);
2018
        }
2019
        printf("\n");
2020

    
2021
        //write( fdout, mpeg_end, 4);
2022
}
2023

    
2024

    
2025
#define CHECKBUF (1024*1024)
2026
#define ONE_GIG  (1024UL*1024UL*1024UL)
2027
void split_mpg(char *name, uint64_t size)
2028
{
2029
        char base_name[MAX_BASE];
2030
        char path[MAX_PATH];
2031
        char ext[MAX_EXT];
2032
        char new_name[256];
2033
        uint8_t buf[CHECKBUF];
2034
        int fdin;
2035
        int fdout;
2036
        uint64_t length = 0;
2037
        uint64_t last;
2038
        int i;
2039
        int mark, csize;
2040
        struct stat sb;
2041

    
2042
        if (break_up_filename(name,base_name,path,ext) < 0) exit(1);
2043

    
2044
        if ( (fdin = open(name, O_RDONLY|O_LARGEFILE)) < 0){
2045
                fprintf(stderr,"Can't open %s\n",name);
2046
                exit(1);
2047
        }
2048

    
2049
        fstat (fdin, &sb);
2050

    
2051
        length = sb.st_size;
2052
        if ( length < ONE_GIG )
2053
                printf("Filelength = %2.2f MB\n", length/1024./1024.);
2054
        else
2055
                printf("Filelength = %2.2f GB\n", length/1024./1024./1024.);
2056

    
2057
        if ( length < size ) length = size;
2058
        
2059
        printf("Splitting %s into Files with size <= %2.2f MB\n",name,
2060
               size/1024./1024.);
2061
        
2062
        csize = CHECKBUF;
2063
        read(fdin, buf, csize);
2064
        if ( (mark = seek_mpg_start(buf,csize)) < 0){
2065
                fprintf(stderr,"Couldn't find sequence header\n");
2066
                exit(1);
2067
        }
2068

    
2069
        last = csize-mark;
2070

    
2071
        for ( i = 0 ; i < length/size; i++){
2072
                csize = CHECKBUF;
2073
                
2074
                if (csize > length-last) csize = length-last;
2075
                lseek(fdin, last+size-csize, SEEK_SET);
2076
                read(fdin, buf, csize);
2077
                if ( (mark = seek_mpg_start(buf,csize)) < 0){
2078
                        fprintf(stderr,"Couldn't find sequence header\n");
2079
                        exit(1);
2080
                }
2081

    
2082
                sprintf(new_name,"%s-%03d.%s",base_name,i,ext);
2083
                printf("writing %s\n",new_name);
2084

    
2085
                if ( (fdout = open(new_name,O_WRONLY|O_CREAT|O_TRUNC
2086
                                   |O_LARGEFILE,
2087
                                   S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|
2088
                                   S_IROTH|S_IWOTH)) < 0){
2089
                        fprintf(stderr,"Can't open %s\n",new_name);
2090
                        exit(1);
2091
                }
2092
                write_mpg(last, size-mark, fdin, fdout);
2093
                last = last + size - mark;
2094
        }
2095
        sprintf(new_name,"%s-%03d.%s",base_name,i,ext);
2096
        printf("writing %s\n",new_name);
2097

    
2098
        if ( (fdout = open(new_name,O_WRONLY|O_CREAT|O_TRUNC
2099
                           |O_LARGEFILE,
2100
                           S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|
2101
                           S_IROTH|S_IWOTH)) < 0){
2102
                fprintf(stderr,"Can't open %s\n",new_name);
2103
                exit(1);
2104
        }
2105
        write_mpg(last, length-last, fdin, fdout);
2106
}
2107

    
2108

    
2109

    
2110

    
2111
void cut_mpg(char *name, uint64_t size)
2112
{
2113
        char base_name[MAX_BASE];
2114
        char path[MAX_PATH];
2115
        char ext[MAX_EXT];
2116
        char new_name[256];
2117
        uint8_t buf[CHECKBUF];
2118
        int fdin;
2119
        int fdout;
2120
        uint64_t length = 0;
2121
        uint64_t last;
2122
        int mark, csize;
2123
        struct stat sb;
2124

    
2125
        if (break_up_filename(name,base_name,path,ext) < 0) exit(1);
2126

    
2127

    
2128
        if ( (fdin = open(name, O_RDONLY|O_LARGEFILE)) < 0){
2129
                fprintf(stderr,"Can't open %s\n",name);
2130
                exit(1);
2131
        }
2132

    
2133
        fstat (fdin, &sb);
2134

    
2135
        length = sb.st_size;
2136
        if ( length < ONE_GIG )
2137
                printf("Filelength = %2.2f MB\n", length/1024./1024.);
2138
        else
2139
                printf("Filelength = %2.2f GB\n", length/1024./1024./1024.);
2140

    
2141
        if ( length < size ) length = size;
2142
        
2143
        printf("Splitting %s into 2 Files with length %.2f MB and %.2f MB\n",
2144
               name, size/1024./1024., (length-size)/1024./1024.);
2145
        
2146
        csize = CHECKBUF;
2147
        read(fdin, buf, csize);
2148
        if ( (mark = seek_mpg_start(buf,csize)) < 0){
2149
                fprintf(stderr,"Couldn't find sequence header\n");
2150
                exit(1);
2151
        }
2152

    
2153
        last = csize-mark;
2154

    
2155
        if (csize > length-last) csize = length-last;
2156
        lseek(fdin, last+size-csize, SEEK_SET);
2157
        read(fdin, buf, csize);
2158
        if ( (mark = seek_mpg_start(buf,csize)) < 0){
2159
                fprintf(stderr,"Couldn't find sequence header\n");
2160
                exit(1);
2161
        }
2162

    
2163
        sprintf(new_name,"%s-1.%s",base_name,ext);
2164
        printf("writing %s\n",new_name);
2165

    
2166
        if ( (fdout = open(new_name,O_WRONLY|O_CREAT|O_TRUNC
2167
                           |O_LARGEFILE,
2168
                           S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|
2169
                           S_IROTH|S_IWOTH)) < 0){
2170
                fprintf(stderr,"Can't open %s\n",new_name);
2171
                exit(1);
2172
        }
2173
        write_mpg(last, size-mark, fdin, fdout);
2174
        last = last + size - mark;
2175

    
2176
        sprintf(new_name,"%s-2.%s",base_name,ext);
2177
        printf("writing %s\n",new_name);
2178

    
2179
        if ( (fdout = open(new_name,O_WRONLY|O_CREAT|O_TRUNC
2180
                           |O_LARGEFILE,
2181
                           S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|
2182
                           S_IROTH|S_IWOTH)) < 0){
2183
                fprintf(stderr,"Can't open %s\n",new_name);
2184
                exit(1);
2185
        }
2186
        write_mpg(last, length-last, fdin, fdout);
2187
}
2188

    
2189

    
2190

    
2191

    
2192
void write_all (int fd, uint8_t *data, int length)
2193
{
2194
        int r;
2195

    
2196
        while (length) {
2197
                if ((r = write(fd, data, length)) > 0) {
2198
                        data += r;
2199
                        length -= r;
2200
                }
2201
        }
2202
}
2203

    
2204

    
2205

    
2206
void read_all (int fd, uint8_t *data, int length)
2207
{
2208
        int c = 0;
2209

    
2210
        while(1) {
2211
                if( read(fd, data+c, 1) == 1) {
2212
                        c++;
2213
                        if(data[c-1] == '\n') {
2214
                                data[c] = 0;
2215
                                break;
2216
                        }
2217
                }
2218
                else {
2219
                        fprintf (stderr, "Error reading socket\n");
2220
                        exit(1);
2221
                }
2222
        }
2223
}
2224

    
2225

    
2226

    
2227
char *url2host (uint8_t *url, char **name, uint32_t *ip, uint32_t *port)
2228
{
2229
        uint8_t *murl;
2230
        struct hostent *hoste;
2231
        struct in_addr haddr;
2232
        int found_ip = 1;
2233
        
2234
        if (!(strncmp(url, "http://", 7)))
2235
                url += 7;
2236

    
2237
        *name = strdup(url);
2238
        if (!(*name)) {
2239
                *name = NULL;
2240
                return (NULL);
2241
        }
2242

    
2243
        murl = url;
2244
        while (*murl && *murl != ':' && *murl != '/') {
2245
                if ((*murl < '0' || *murl > '9') && *murl != '.')
2246
                        found_ip = 0;
2247
                murl++;
2248
        }
2249

    
2250
        (*name)[murl - url] = 0;
2251
        if (found_ip) {
2252
                if ((*ip = inet_addr(*name)) == INADDR_NONE)
2253
                        return (NULL);
2254
        } else {
2255
                if (!(hoste = gethostbyname(*name)))
2256
                        return (NULL);
2257
                memcpy (&haddr, hoste->h_addr, sizeof(haddr));
2258
                *ip = haddr.s_addr;
2259
        }
2260

    
2261
        if (!*murl || *murl == '/') {
2262
                *port = 80;
2263
                return (murl);
2264
        }
2265
        *port = atoi(++murl);
2266

    
2267
        while (*murl && *murl != '/')
2268
                murl++;
2269
        return (murl);
2270
}
2271

    
2272
#define ACCEPT "Accept: video/mpeg, video/x-mpegurl, */*\r\n"
2273

    
2274
int http_open (char *url)
2275
{
2276
        char purl[1024], *host, req[1024], *sptr;
2277
        uint32_t ip;
2278
        uint32_t port;
2279
        int sock;
2280
        int reloc, relocnum = 0;
2281
        struct sockaddr_in server;
2282
        int mfd;
2283

    
2284
        strncpy (purl, url, 1023);
2285
        purl[1023] = '\0';
2286

    
2287
        do {
2288
                host = NULL;
2289
                strcpy (req, "GET ");
2290
                if (!(sptr = url2host(purl, &host, &ip, &port))) {
2291
                        fprintf (stderr, "Unknown host\n");
2292
                        exit (1);
2293
                }
2294
                strcat (req, sptr);
2295
                sprintf (req + strlen(req),
2296
                         " HTTP/1.0\r\nUser-Agent: %s/%s\r\n",
2297
                         "whatever", "you want");
2298
                if (host) {
2299
                        sprintf(req + strlen(req),
2300
                                "Host: %s:%u\r\n", host, port);
2301
                        free (host);
2302
                }
2303

    
2304
                strcat (req, ACCEPT);
2305
                strcat (req, "\r\n");
2306
                
2307
                server.sin_port = htons(port);
2308
                server.sin_family = AF_INET;
2309
                server.sin_addr.s_addr = ip;
2310

    
2311
                if ((sock = socket(PF_INET, SOCK_STREAM, 6)) < 0) {
2312
                        perror ("socket");
2313
                        exit (1);
2314
                }
2315

    
2316
                if (connect(sock, (struct sockaddr *)&server, 
2317
                            sizeof(server))) {
2318
                        perror ("connect");
2319
                        exit (1);
2320
                }
2321
                
2322
                write_all (sock, req, strlen(req));
2323
                if (!(mfd = fileno(fdopen(sock, "rb")))) {
2324
                        perror ("open");
2325
                        exit (1);
2326
                }
2327
                reloc = 0;
2328
                purl[0] = '\0';
2329
                read_all (mfd, req, 1023);
2330
                if ((sptr = strchr(req, ' '))) {
2331
                        switch (sptr[1]) {
2332
                                case '2':
2333
                                        break;
2334
                                case '3':
2335
                                        reloc = 1;
2336
                                default:
2337
                                        fprintf (stderr, "HTTP req failed:%s",
2338
                                                sptr+1); 
2339
                                        exit (1);
2340
                        }
2341
                }
2342
                do {
2343
                        read_all (mfd,req, 1023);
2344
                        if (!strncmp(req, "Location:", 9))
2345
                                strncpy (purl, req+10, 1023);
2346
                } while (req[0] != '\r' && req[0] != '\n');
2347
        } while (reloc && purl[0] && relocnum++ < 3);
2348
        if (reloc) {
2349
                fprintf (stderr, "Too many HTTP relocations.\n");
2350
                exit (1);
2351
        }
2352

    
2353
        return sock;
2354
}
2355