Statistics
| Branch: | Tag: | Revision:

dvbd / src / ctools.c @ a24dbbce

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

38
      PES
39
  
40
*/
41

    
42

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

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

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

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

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

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

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

    
123

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

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

    
135

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

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

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

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

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

    
273
        return count;
274

    
275
}
276

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

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

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

    
331

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

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

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

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

    
538

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

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

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

    
592
        return neof;
593
}
594

    
595
/*
596

597
   Transport Stream
598

599
*/
600

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

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

    
623

    
624

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

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

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

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

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

    
701

    
702
        return count;
703
}
704

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

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

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

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

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

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

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

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

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

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

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

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

    
865

    
866
/*
867

868
   Program Stream
869

870
*/
871

    
872

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

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

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

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

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

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

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

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

    
934

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

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

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

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

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

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

    
965
        return ext;
966
}
967

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

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

    
1014
        return count;
1015
}
1016

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

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

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

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

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

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

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

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

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

    
1192

    
1193

    
1194

    
1195

    
1196

    
1197

    
1198
/*
1199
  conversion
1200
*/
1201

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1317

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

    
1326

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

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

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

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

    
1369

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

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

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

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

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

    
1403

    
1404

    
1405

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

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

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

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

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

    
1474
}
1475

    
1476
#define MULT 1024
1477

    
1478

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

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

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

    
1549

    
1550

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

    
1557

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

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

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

    
1585

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

    
1591
        *frags = 0;
1592

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

    
1628
        return c;
1629
}
1630

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

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

    
1728

    
1729

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

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

    
1777

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

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

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

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

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

    
1862

    
1863

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

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

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

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

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

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

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

    
1923

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

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

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

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

    
1995
        return size-mark;
1996
}
1997

    
1998

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

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

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

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

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

    
2025

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

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

    
2045

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

    
2051
        fstat (fdin, &sb);
2052

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

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

    
2071
        last = csize-mark;
2072

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

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

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

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

    
2110

    
2111

    
2112

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

    
2127
        if (break_up_filename(name,base_name,path,ext) < 0) exit(1);
2128

    
2129

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

    
2135
        fstat (fdin, &sb);
2136

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

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

    
2155
        last = csize-mark;
2156

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

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

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

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

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

    
2191

    
2192

    
2193

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

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

    
2206

    
2207

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

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

    
2227

    
2228

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

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

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

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

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

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

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

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

    
2286
        strncpy (purl, url, 1023);
2287
        purl[1023] = '\0';
2288

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

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

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

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

    
2355
        return sock;
2356
}
2357