Statistics
| Branch: | Tag: | Revision:

dvbd / transform.c @ bfdb7446

History | View | Annotate | Download (44.1 KB)

1 bfdb7446 jak
/*
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 "transform.h"
32
#include <stdlib.h>
33
#include <string.h>
34
#include "ctools.h"
35
36
static uint8_t tspid0[TS_SIZE] = { 
37
        0x47, 0x40, 0x00, 0x10, 0x00, 0x00, 0xb0, 0x11, 
38
        0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, 0x00, 0xe0, 
39
        0x10, 0x00, 0x01, 0xe4, 0x00, 0x2a, 0xd6, 0x1a, 
40
        0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
41
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
42
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
43
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
44
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
45
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
46
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
47
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
48
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
49
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
50
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
51
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
52
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
53
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
54
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
55
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
56
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
57
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
58
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
59
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
60
        0xff, 0xff, 0xff, 0xff
61
};
62
63
static        uint8_t tspid1[TS_SIZE] = { 
64
        0x47, 0x44, 0x00, 0x10, 0x00, 0x02, 0xb0, 0x1c,
65
        0x00, 0x01, 0xcb, 0x00, 0x00, 0xe0, 0xa0, 0xf0, 
66
        0x05, 0x48, 0x03, 0x01, 0x00, 0x00, 0x02, 0xe0,
67
        0xa0, 0xf0, 0x00, 0x03, 0xe0, 0x50, 0xf0, 0x00, 
68
        0xae, 0xea, 0x4e, 0x48, 0xff, 0xff, 0xff, 0xff, 
69
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
70
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
71
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
72
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
73
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
74
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
75
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
76
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
77
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
78
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
79
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
80
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
81
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
82
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
83
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
84
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
85
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
86
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
87
        0xff, 0xff, 0xff, 0xff
88
};
89
90
uint32_t trans_pts_dts(uint8_t *pts)
91
{
92
        uint32_t wts;
93
        
94
        wts = (((pts[0] & 0x06) << 4) | 
95
               ((pts[1] & 0xFC) >> 2)) << 24; 
96
        wts |= (((pts[1] & 0x03) << 6) |
97
                ((pts[2] & 0xFC) >> 2)) << 16; 
98
        wts |= (((pts[2] & 0x02) << 6) |
99
                ((pts[3] & 0xFE) >> 1)) << 8;
100
        wts |= (((pts[3] & 0x01) << 7) |
101
                ((pts[4] & 0xFE) >> 1));
102
        return wts;
103
}
104
105
106
void get_pespts(uint8_t *av_pts,uint8_t *pts)
107
{
108
        
109
        pts[0] = 0x21 | 
110
                ((av_pts[0] & 0xC0) >>5);
111
        pts[1] = ((av_pts[0] & 0x3F) << 2) |
112
                ((av_pts[1] & 0xC0) >> 6);
113
        pts[2] = 0x01 | ((av_pts[1] & 0x3F) << 2) |
114
                ((av_pts[2] & 0x80) >> 6);
115
        pts[3] = ((av_pts[2] & 0x7F) << 1) |
116
                ((av_pts[3] & 0x80) >> 7);
117
        pts[4] = 0x01 | ((av_pts[3] & 0x7F) << 1);
118
}
119
120
uint16_t get_pid(uint8_t *pid)
121
{
122
        uint16_t pp = 0;
123
124
        pp = (pid[0] & PID_MASK_HI)<<8;
125
        pp |= pid[1];
126
127
        return pp;
128
}
129
130
int write_ts_header(uint16_t pid, uint8_t *counter, int pes_start, 
131
                    uint8_t *buf, uint8_t length)
132
{
133
        int i;
134
        int c = 0;
135
        int fill;
136
        uint8_t tshead[4] = { 0x47, 0x00, 0x00, 0x10}; 
137
        
138
139
        fill = TS_SIZE-4-length;
140
        if (pes_start) tshead[1] = 0x40;
141
        if (fill) tshead[3] = 0x30;
142
        tshead[1] |= (uint8_t)((pid & 0x1F00) >> 8);
143
        tshead[2] |= (uint8_t)(pid & 0x00FF);
144
        tshead[3] |= ((*counter)++ & 0x0F) ;
145
        memcpy(buf,tshead,4);
146
        c+=4;
147
148
149
        if (fill){
150
                buf[4] = fill-1;
151
                c++;
152
                if (fill >1){
153
                        buf[5] = 0x00;
154
                        c++;
155
                }
156
                for ( i = 6; i < fill+4; i++){
157
                        buf[i] = 0xFF;
158
                        c++;
159
                }
160
        }
161
162
        return c;
163
}
164
165
166
int write_pes_header(uint8_t id,int length , long PTS, uint8_t *obuf, 
167
                     int stuffing)
168
{
169
        uint8_t le[2];
170
        uint8_t dummy[3];
171
        uint8_t *pts;
172
        uint8_t ppts[5];
173
        long lpts;
174
        int c;
175
        uint8_t headr[3] = {0x00, 0x00, 0x01};
176
        
177
        lpts = htonl(PTS);
178
        pts = (uint8_t *) &lpts;
179
        
180
        get_pespts(pts,ppts);
181
182
        c = 0;
183
        memcpy(obuf+c,headr,3);
184
        c += 3;
185
        memcpy(obuf+c,&id,1);
186
        c++;
187
188
        le[0] = 0;
189
        le[1] = 0;
190
        length -= 6+stuffing;
191
192
        le[0] |= ((uint8_t)(length >> 8) & 0xFF); 
193
        le[1] |= ((uint8_t)(length) & 0xFF); 
194
        memcpy(obuf+c,le,2);
195
        c += 2;
196
197
        if (id == PADDING_STREAM){
198
                memset(obuf+c,0xff,length);
199
                c+= length;
200
                return c;
201
        }
202
203
        dummy[0] = 0x80;
204
        dummy[1] = 0;
205
        dummy[2] = 0;
206
        if (PTS){
207
                dummy[1] |= PTS_ONLY;
208
                dummy[2] = 5+stuffing;
209
        }
210
        memcpy(obuf+c,dummy,3);
211
        c += 3;
212
        memset(obuf+c,0xFF,stuffing);
213
214
        if (PTS){
215
                memcpy(obuf+c,ppts,5);
216
                c += 5;
217
        }
218
        
219
        return c;
220
}
221
222
223
void init_p2p(p2p *p, void (*func)(uint8_t *buf, int count, p2p *p), 
224
              int repack){
225
        p->found = 0;
226
        p->cid = 0;
227
        p->mpeg = 0;
228
        memset(p->buf,0,MMAX_PLENGTH);
229
        p->done = 0;
230
        p->fd1 = -1;
231
        p->func = func;
232
        p->bigend_repack = 0;
233
        p->repack = 0; 
234
        if ( repack < MAX_PLENGTH && repack > 265 ){
235
                p->repack = repack-6;
236
                p->bigend_repack = (uint16_t)htons((short)
237
                                                   ((repack-6) & 0xFFFF));
238
        } else {
239
                fprintf(stderr, "Repack size %d is out of range\n",repack);
240
                exit(1);
241
        }
242
}
243
244
245
246
void pes_repack(p2p *p)
247
{
248
        int count = 0;
249
        int repack = p->repack;
250
        int rest = p->plength;
251
        uint8_t buf[MAX_PLENGTH];
252
        int bfill = 0;
253
        int diff;
254
        uint16_t length;
255
256
        if (rest < 0) {
257
                fprintf(stderr,"Error in repack\n");
258
                return;
259
        }
260
261
        if (!repack){
262
                fprintf(stderr,"forgot to set repack size\n");
263
                return;
264
        }
265
266
        if (p->plength == repack){
267
                memcpy(p->buf+4,(char *)&p->bigend_repack,2);
268
                p->func(p->buf, repack+6, p);
269
                return;
270
        }
271
272
        buf[0] = 0x00;
273
        buf[1] = 0x00;
274
        buf[2] = 0x01;
275
        buf[3] = p->cid;
276
        memcpy(buf+4,(char *)&p->bigend_repack,2);
277
        memset(buf+6,0,MAX_PLENGTH-6);
278
279
        if (p->mpeg == 2){
280
281
                if ( rest > repack){
282
                        memcpy(p->buf+4,(char *)&p->bigend_repack,2);
283
                        p->func(p->buf, repack+6, p);
284
                        count += repack+6;
285
                        rest -= repack;
286
                } else {
287
                        memcpy(buf,p->buf,9+p->hlength);
288
                        bfill = p->hlength;
289
                        count += 9+p->hlength;
290
                        rest -= p->hlength+3;
291
                }
292
293
                while (rest >= repack-3){
294
                        memset(buf+6,0,MAX_PLENGTH-6);
295
                        buf[6] = 0x80;
296
                        buf[7] = 0x00;
297
                        buf[8] = 0x00;
298
                        memcpy(buf+9,p->buf+count,repack-3);
299
                        rest -= repack-3;
300
                        count += repack-3;
301
                        p->func(buf, repack+6, p);
302
                }
303
                
304
                if (rest){
305
                        diff = repack - 3 - rest - bfill;
306
                        if (!bfill){
307
                                buf[6] = 0x80;
308
                                buf[7] = 0x00;
309
                                buf[8] = 0x00;
310
                        }
311
312
                        if ( diff < PES_MIN){
313
                                length = rest+ diff + bfill+3; 
314
                                buf[4] = (uint8_t)((length & 0xFF00) >> 8);
315
                                buf[5] = (uint8_t)(length & 0x00FF);
316
                                buf[8] = (uint8_t)(bfill+diff);
317
                                memset(buf+9+bfill,0xFF,diff);
318
                                memcpy(buf+9+bfill+diff,p->buf+count,rest);
319
                        } else {
320
                                length = rest+ bfill+3; 
321
                                buf[4] = (uint8_t)((length & 0xFF00) >> 8);
322
                                buf[5] = (uint8_t)(length & 0x00FF);
323
                                memcpy(buf+9+bfill,p->buf+count,rest);
324
                                bfill += rest+9;
325
                                write_pes_header( PADDING_STREAM, diff, 0,
326
                                                  buf+bfill, 0);
327
                        }
328
                        p->func(buf, repack+6, p);
329
                }
330
        }        
331
332
        if (p->mpeg == 1){
333
334
                if ( rest > repack){
335
                        memcpy(p->buf+4,(char *)&p->bigend_repack,2);
336
                        p->func(p->buf, repack+6, p);
337
                        count += repack+6;
338
                        rest -= repack;
339
                } else {
340
                        memcpy(buf,p->buf,6+p->hlength);
341
                        bfill = p->hlength;
342
                        count += 6;
343
                        rest -= p->hlength;
344
                }
345
346
                while (rest >= repack-1){
347
                        memset(buf+6,0,MAX_PLENGTH-6);
348
                        buf[6] = 0x0F;
349
                        memcpy(buf+7,p->buf+count,repack-1);
350
                        rest -= repack-1;
351
                        count += repack-1;
352
                        p->func(buf, repack+6, p);
353
                }
354
                
355
356
                if (rest){
357
                        diff = repack - 1 - rest - bfill;
358
359
                        if ( diff < PES_MIN){
360
                                length = rest+ diff + bfill+1; 
361
                                buf[4] = (uint8_t)((length & 0xFF00) >> 8);
362
                                buf[5] = (uint8_t)(length & 0x00FF);
363
                                memset(buf+6,0xFF,diff);
364
                                if (!bfill){
365
                                        buf[6+diff] = 0x0F;
366
                                }
367
                                memcpy(buf+7+diff,p->buf+count,rest+bfill);
368
                        } else {
369
                                length = rest+ bfill+1; 
370
                                buf[4] = (uint8_t)((length & 0xFF00) >> 8);
371
                                buf[5] = (uint8_t)(length & 0x00FF);
372
                                if (!bfill){
373
                                        buf[6] = 0x0F;
374
                                        memcpy(buf+7,p->buf+count,rest);
375
                                        bfill = rest+7;
376
                                } else {
377
                                        memcpy(buf+6,p->buf+count,rest+bfill);
378
                                        bfill += rest+6;
379
                                }
380
                                write_pes_header( PADDING_STREAM, diff, 0,
381
                                                  buf+bfill, 0);
382
                        }
383
                        p->func(buf, repack+6, p);
384
                }
385
        }        
386
}
387
388
389
390
391
void pes_filt(p2p *p)
392
{
393
        int factor = p->mpeg-1;
394
395
        if ( p->cid == p->filter) {
396
                if (p->es)
397
                        write(p->fd1,p->buf+p->hlength+6+3*factor, 
398
                              p->plength-p->hlength-3*factor);
399
                else
400
                        write(p->fd1,p->buf,p->plength+6);
401
        }
402
}
403
404
#define SIZE 4096
405
void extract_from_pes(int fdin, int fdout, uint8_t id, int es)
406
{
407
                p2p p;
408
                int count = 1;
409
                uint8_t buf[SIZE];
410
411
                init_p2p(&p, NULL, 2048);
412
                p.fd1 = fdout;
413
                p.filter = id;
414
                p.es = es;
415
416
                while (count > 0){
417
                        count = read(fdin,buf,SIZE);
418
                        get_pes(buf,count,&p,pes_filt);
419
                }
420
}
421
422
423
void pes_dfilt(p2p *p)
424
{
425
        int factor = p->mpeg-1;
426
        int fd =0;
427
        int type = NOPES;
428
429
        switch ( p->cid ) {
430
                case AUDIO_STREAM_S ... AUDIO_STREAM_E:                        
431
                        fd = p->fd1;
432
                        type = AUDIO;
433
                        break;
434
                case VIDEO_STREAM_S ... VIDEO_STREAM_E:
435
                        fd = p->fd2;
436
                        type = VIDEO;
437
                        break;
438
        }
439
        
440
        if (p->es && !p->startv && type == VIDEO){
441
                int found = 0;
442
                int c = 6+p->hlength+3*factor;
443
                
444
                if  ( p->flag2 & PTS_DTS ) 
445
                        p->vpts =  ntohl(trans_pts_dts(p->pts)); 
446
                while ( !found && c+3 < p->plength+6 ){
447
                        if ( p->buf[c] == 0x00 && 
448
                             p->buf[c+1] == 0x00 && 
449
                             p->buf[c+2] == 0x01 &&
450
                             p->buf[c+3] == 0xb3) 
451
                                found = 1;
452
                        else c++;
453
                }
454
                if (found){
455
                        p->startv = 1;
456
                        write(fd, p->buf+c, p->plength+6-c);
457
                }
458
                fd = 0;
459
        } 
460
461
                
462
        if ( p->es && !p->starta && type == AUDIO){
463
                int found = 0;
464
                int c = 6+p->hlength+3*factor;
465
                if  ( p->flag2 & PTS_DTS ) 
466
                        p->apts =  ntohl(trans_pts_dts(p->pts));  
467
                if (p->startv)
468
                        while ( !found && c+1 < p->plength+6){
469
                                if ( p->buf[c] == 0xFF && 
470
                                     (p->buf[c+1] & 0xF8) == 0xF8)
471
                                        found = 1;
472
                                else c++;
473
                        }
474
                if (found){
475
                        p->starta = 1;
476
                        write(fd, p->buf+c, p->plength+6-c);
477
                }
478
                fd = 0;
479
        } 
480
481
482
        if (fd){
483
                if (p->es)
484
                        write(fd,p->buf+p->hlength+6+3*factor, 
485
                              p->plength-p->hlength-3*factor);
486
                else
487
                        write(fd,p->buf,p->plength+6);
488
        }
489
} 
490
491
int64_t pes_dmx( int fdin, int fdouta, int fdoutv, int es)
492
{
493
        p2p p;
494
        int count = 1;
495
        uint8_t buf[SIZE];
496
        uint64_t length = 0;
497
        uint64_t l = 0;
498
        int verb = 0;
499
        
500
        init_p2p(&p, NULL, 2048);
501
        p.fd1 = fdouta;
502
        p.fd2 = fdoutv;
503
        p.es = es;
504
        p.startv = 0;
505
        p.starta = 0;
506
        p.apts=-1;
507
        p.vpts=-1;
508
        
509
        if (fdin != STDIN_FILENO) verb = 1; 
510
        
511
        if (verb) {
512
                length = lseek(fdin, 0, SEEK_END);
513
                lseek(fdin,0,SEEK_SET);
514
        }
515
        
516
        while (count > 0){
517
                count = read(fdin,buf,SIZE);
518
                l += count;
519
                if (verb)
520
                        fprintf(stderr,"Demuxing %2.2f %%\r",
521
                                100.*l/length);
522
                
523
                get_pes(buf,count,&p,pes_dfilt);
524
        }
525
        
526
        return (int64_t)p.vpts - (int64_t)p.apts;
527
        
528
}
529
530
531
532
static void pes_in_ts(p2p *p)
533
{
534
        int l, pes_start;
535
        uint8_t obuf[TS_SIZE];
536
        long int c = 0;
537
        int length = p->plength+6;
538
        uint16_t pid;
539
        uint8_t *counter;
540
        pes_start = 1;
541
        switch ( p->cid ) {
542
        case AUDIO_STREAM_S ... AUDIO_STREAM_E:                        
543
                pid = p->pida;
544
                counter = &p->acounter;
545
                break;
546
        case VIDEO_STREAM_S ... VIDEO_STREAM_E:
547
                pid = p->pidv;
548
                counter = &p->acounter;
549
550
                tspid0[3] |= (p->count0++) 
551
                        & 0x0F ;
552
                tspid1[3] |= (p->count1++) 
553
                        & 0x0F ;
554
        
555
                tspid1[24]  = p->pidv;
556
                tspid1[23] |= (p->pidv >> 8) & 0x3F;
557
                tspid1[29]  = p->pida;
558
                tspid1[28] |= (p->pida >> 8) & 0x3F;
559
                
560
                p->func(tspid0,188,p);
561
                p->func(tspid1,188,p);
562
                break;
563
        default:
564
                return;
565
        }
566
567
        while ( c < length ){
568
                memset(obuf,0,TS_SIZE);
569
                if (length - c >= TS_SIZE-4){
570
                        l = write_ts_header(pid, counter, pes_start
571
                                             , obuf, TS_SIZE-4);
572
                        memcpy(obuf+l, p->buf+c, TS_SIZE-l);
573
                        c += TS_SIZE-l;
574
                } else { 
575
                        l = write_ts_header(pid, counter, pes_start
576
                                             , obuf, length-c);
577
                        memcpy(obuf+l, p->buf+c, TS_SIZE-l);
578
                        c = length;
579
                }
580
                p->func(obuf,188,p);
581
                pes_start = 0;
582
        }
583
}
584
585
586
587
void pes_to_ts2( int fdin, int fdout, uint16_t pida, uint16_t pidv)
588
{
589
        p2p p;
590
        int count = 1;
591
        uint8_t buf[SIZE];
592
        uint64_t length = 0;
593
        uint64_t l = 0;
594
        int verb = 0;
595
        
596
        init_p2p(&p, NULL, 2048);
597
        p.fd1 = fdout;
598
        p.pida = pida;
599
        p.pidv = pidv;
600
        p.acounter = 0;
601
        p.vcounter = 0;
602
        p.count1 = 0;
603
        p.count0 = 0;
604
                
605
        if (fdin != STDIN_FILENO) verb = 1; 
606
607
        if (verb) {
608
                length = lseek(fdin, 0, SEEK_END);
609
                lseek(fdin,0,SEEK_SET);
610
        }
611
612
        while (count > 0){
613
                count = read(fdin,buf,SIZE);
614
                l += count;
615
                if (verb)
616
                        fprintf(stderr,"Writing TS  %2.2f %%\r",
617
                                100.*l/length);
618
619
                get_pes(buf,count,&p,pes_in_ts);
620
        }
621
                
622
}
623
624
void write_out(uint8_t *buf, int count,void  *p)
625
{
626
        write(STDOUT_FILENO, buf, count);
627
}
628
629
630
#define IN_SIZE TS_SIZE*10
631
#define IPACKS 2048
632
void find_avpids(int fd, uint16_t *vpid, uint16_t *apid)
633
{
634
        uint8_t buf[IN_SIZE];
635
        int count;
636
        int i;  
637
        int off =0;
638
639
        while ( *apid == 0 || *vpid == 0){
640
                count = read(fd, buf, IN_SIZE);
641
                for (i = 0; i < count-7; i++){
642
                        if (buf[i] == 0x47){
643
                                if (buf[i+1] & 0x40){
644
                                        off = 0;
645
                                        if ( buf[3+i] & 0x20)//adapt field?
646
                                                off = buf[4+i] + 1;
647
                                        switch(buf[i+7+off]){
648
                                        case VIDEO_STREAM_S ... VIDEO_STREAM_E:
649
                                                *vpid = get_pid(buf+i+1);
650
                                                break;
651
                                        case PRIVATE_STREAM1:
652
                                        case AUDIO_STREAM_S ... AUDIO_STREAM_E:
653
                                                *apid = get_pid(buf+i+1);
654
                                                break;
655
                                        }
656
                                }
657
                                i += 187;
658
                        }
659
                        if (*apid != 0 && *vpid != 0) break;
660
                }
661
        }
662
}
663
664
void find_bavpids(uint8_t *buf, int count, uint16_t *vpid, uint16_t *apid)
665
{
666
        int i;  
667
        int founda = 0;
668
        int foundb = 0;
669
        int off = 0;
670
        
671
        *vpid = 0;
672
        *apid = 0;
673
        for (i = 0; i < count-7; i++){
674
                if (buf[i] == 0x47){
675
                        if ((buf[i+1] & 0xF0) == 0x40){
676
                                off = 0;
677
                                if ( buf[3+i] & 0x20)  // adaptation field?
678
                                        off = buf[4+i] + 1;
679
                                
680
                                if (buf[off+i+4] == 0x00 && 
681
                                    buf[off+i+5] == 0x00 &&
682
                                    buf[off+i+6] == 0x01){
683
                                        switch(buf[off+i+7]){
684
                                        case VIDEO_STREAM_S ... VIDEO_STREAM_E:
685
                                                *vpid = get_pid(buf+i+1);
686
                                                foundb=1;
687
                                                break;
688
                                        case PRIVATE_STREAM1:
689
                                        case AUDIO_STREAM_S ... AUDIO_STREAM_E:
690
                                                *apid = get_pid(buf+i+1);
691
                                                founda=1;
692
                                                break;
693
                                        }
694
                                }
695
                        }
696
                        i += 187;
697
                }
698
                if (founda && foundb) break;
699
        }
700
}
701
702
703
void ts_to_pes( int fdin, uint16_t pida, uint16_t pidv, int ps)
704
{
705
        
706
        uint8_t buf[IN_SIZE];
707
        uint8_t mbuf[TS_SIZE];
708
        int i;
709
        int count = 1;
710
        uint16_t pid;
711
        uint16_t dummy;
712
        ipack pa, pv;
713
        ipack *p;
714
715
        if (fdin != STDIN_FILENO && (!pida || !pidv))
716
                find_avpids(fdin, &pidv, &pida);
717
718
        init_ipack(&pa, IPACKS,write_out, ps);
719
        init_ipack(&pv, IPACKS,write_out, ps);
720
721
         if ((count = read(fdin,mbuf,TS_SIZE))<0)
722
            perror("reading");
723
724
        for ( i = 0; i < 188 ; i++){
725
                if ( mbuf[i] == 0x47 ) break;
726
        }
727
        if ( i == 188){
728
                fprintf(stderr,"Not a TS\n");
729
                return;
730
        } else {
731
                memcpy(buf,mbuf+i,TS_SIZE-i);
732
                if ((count = read(fdin,mbuf,i))<0)
733
                        perror("reading");
734
                memcpy(buf+TS_SIZE-i,mbuf,i);
735
                i = 188;
736
        }
737
        count = 1;
738
        while (count > 0){
739
                if ((count = read(fdin,buf+i,IN_SIZE-i))<0)
740
                        perror("reading");
741
                
742
743
                if (!pidv){
744
                        find_bavpids(buf+i, IN_SIZE-i, &pidv, &dummy);
745
                        if (pidv) fprintf(stderr, "vpid %d (0x%02x)\n",
746
                                          pidv,pidv);
747
                } 
748
749
                if (!pida){
750
                        find_bavpids(buf+i, IN_SIZE-i, &dummy, &pida);
751
                        if (pida) fprintf(stderr, "apid %d (0x%02x)\n",
752
                                          pida,pida);
753
                } 
754
755
756
                for( i = 0; i < count; i+= TS_SIZE){
757
                        uint8_t off = 0;
758
759
                        if ( count - i < TS_SIZE) break;
760
761
                        pid = get_pid(buf+i+1);
762
                        if (!(buf[3+i]&0x10)) // no payload?
763
                                continue;
764
                        if (pid == pidv){
765
                                p = &pv;
766
                        } else {
767
                                if (pid == pida){
768
                                        p = &pa;
769
                                } else continue;
770
                        }
771
772
                        if ( buf[1+i]&0x40) {
773
                                if (p->plength == MMAX_PLENGTH-6){
774
                                        p->plength = p->found-6;
775
                                        p->found = 0;
776
                                        send_ipack(p);
777
                                        reset_ipack(p);
778
                                }
779
                        }
780
781
                        if ( buf[3+i] & 0x20) {  // adaptation field?
782
                                off = buf[4+i] + 1;
783
                        }
784
        
785
                        instant_repack(buf+4+off+i, TS_SIZE-4-off, p);
786
                }
787
                i = 0;
788
789
        }
790
791
}
792
793
794
#define INN_SIZE 2*IN_SIZE
795
void insert_pat_pmt( int fdin, int fdout)
796
{
797
        
798
        uint8_t buf[INN_SIZE];
799
        uint8_t mbuf[TS_SIZE];
800
        int i;
801
        int count = 1;
802
        uint16_t pida = 0;
803
        uint16_t pidv = 0;
804
        int written,c;
805
        uint8_t c0 = 0;
806
        uint8_t c1 = 0;
807
808
809
        find_avpids(fdin, &pidv, &pida);
810
        
811
         count = read(fdin,mbuf,TS_SIZE);
812
        for ( i = 0; i < 188 ; i++){
813
                if ( mbuf[i] == 0x47 ) break;
814
        }
815
        if ( i == 188){
816
                fprintf(stderr,"Not a TS\n");
817
                return;
818
        } else {
819
                memcpy(buf,mbuf+i,TS_SIZE-i);
820
                count = read(fdin,mbuf,i);
821
                memcpy(buf+TS_SIZE-i,mbuf,i);
822
                i = 188;
823
        }
824
        
825
        count = 1;
826
        while (count > 0){
827
                tspid1[24]  = pidv;
828
                tspid1[23] |= (pidv >> 8) & 0x3F;
829
                tspid1[29]  = pida;
830
                tspid1[28] |= (pida >> 8) & 0x3F;
831
                
832
                write(fdout,tspid0,188);
833
                write(fdout,tspid1,188);
834
835
                count = read(fdin,buf+i,INN_SIZE-i);
836
                
837
                written = 0;
838
                while (written < IN_SIZE){
839
                        c = write(fdout,buf,INN_SIZE);
840
                        if (c>0) written += c;
841
                }
842
                tspid0[3] |= (c0++) 
843
                        & 0x0F ;
844
                tspid1[3] |= (c1++) 
845
                        & 0x0F ;
846
        
847
                i=0;
848
        }
849
850
}
851
852
void get_pes (uint8_t *buf, int count, p2p *p, void (*func)(p2p *p))
853
{
854
855
        int l;
856
        unsigned short *pl;
857
        int c=0;
858
859
        uint8_t headr[3] = { 0x00, 0x00, 0x01} ;
860
861
        while (c < count && (p->mpeg == 0 ||
862
                             (p->mpeg == 1 && p->found < 7) ||
863
                             (p->mpeg == 2 && p->found < 9))
864
               &&  (p->found < 5 || !p->done)){
865
                switch ( p->found ){
866
                case 0:
867
                case 1:
868
                        if (buf[c] == 0x00) p->found++;
869
                        else p->found = 0;
870
                        c++;
871
                        break;
872
                case 2:
873
                        if (buf[c] == 0x01) p->found++;
874
                        else if (buf[c] == 0){
875
                                p->found = 2;
876
                        } else p->found = 0;
877
                        c++;
878
                        break;
879
                case 3:
880
                        p->cid = 0;
881
                        switch (buf[c]){
882
                        case PROG_STREAM_MAP:
883
                        case PRIVATE_STREAM2:
884
                        case PROG_STREAM_DIR:
885
                        case ECM_STREAM     :
886
                        case EMM_STREAM     :
887
                        case PADDING_STREAM :
888
                        case DSM_CC_STREAM  :
889
                        case ISO13522_STREAM:
890
                                p->done = 1;
891
                        case PRIVATE_STREAM1:
892
                        case VIDEO_STREAM_S ... VIDEO_STREAM_E:
893
                        case AUDIO_STREAM_S ... AUDIO_STREAM_E:
894
                                p->found++;
895
                                p->cid = buf[c];
896
                                c++;
897
                                break;
898
                        default:
899
                                p->found = 0;
900
                                break;
901
                        }
902
                        break;
903
                        
904
905
                case 4:
906
                        if (count-c > 1){
907
                                pl = (unsigned short *) (buf+c);
908
                                p->plength =  ntohs(*pl);
909
                                p->plen[0] = buf[c];
910
                                c++;
911
                                p->plen[1] = buf[c];
912
                                c++;
913
                                p->found+=2;
914
                        } else {
915
                                p->plen[0] = buf[c];
916
                                p->found++;
917
                                return;
918
                        }
919
                        break;
920
                case 5:
921
                        p->plen[1] = buf[c];
922
                        c++;
923
                        pl = (unsigned short *) p->plen;
924
                        p->plength = ntohs(*pl);
925
                        p->found++;
926
                        break;
927
928
929
                case 6:
930
                        if (!p->done){
931
                                p->flag1 = buf[c];
932
                                c++;
933
                                p->found++;
934
                                if ( (p->flag1 & 0xC0) == 0x80 ) p->mpeg = 2;
935
                                else {
936
                                        p->hlength = 0;
937
                                        p->which = 0;
938
                                        p->mpeg = 1;
939
                                        p->flag2 = 0;
940
                                }
941
                        }
942
                        break;
943
944
                case 7:
945
                        if ( !p->done && p->mpeg == 2){
946
                                p->flag2 = buf[c];
947
                                c++;
948
                                p->found++;
949
                        }        
950
                        break;
951
952
                case 8:
953
                        if ( !p->done && p->mpeg == 2){
954
                                p->hlength = buf[c];
955
                                c++;
956
                                p->found++;
957
                        }
958
                        break;
959
                        
960
                default:
961
962
                        break;
963
                }
964
        }
965
966
        if (!p->plength) p->plength = MMAX_PLENGTH-6;
967
968
969
        if ( p->done || ((p->mpeg == 2 && p->found >= 9)  || 
970
             (p->mpeg == 1 && p->found >= 7)) ){
971
                switch (p->cid){
972
                        
973
                case AUDIO_STREAM_S ... AUDIO_STREAM_E:                        
974
                case VIDEO_STREAM_S ... VIDEO_STREAM_E:
975
                case PRIVATE_STREAM1:
976
977
                        memcpy(p->buf, headr, 3);
978
                        p->buf[3] = p->cid;
979
                        memcpy(p->buf+4,p->plen,2);
980
981
                        if (p->mpeg == 2 && p->found == 9){
982
                                p->buf[6] = p->flag1;
983
                                p->buf[7] = p->flag2;
984
                                p->buf[8] = p->hlength;
985
                        }
986
987
                        if (p->mpeg == 1 && p->found == 7){
988
                                p->buf[6] = p->flag1;
989
                        }
990
991
992
                        if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) &&  
993
                            p->found < 14){
994
                                while (c < count && p->found < 14){
995
                                        p->pts[p->found-9] = buf[c];
996
                                        p->buf[p->found] = buf[c];
997
                                        c++;
998
                                        p->found++;
999
                                }
1000
                                if (c == count) return;
1001
                        }
1002
1003
                        if (p->mpeg == 1 && p->which < 2000){
1004
1005
                                if (p->found == 7) {
1006
                                        p->check = p->flag1;
1007
                                        p->hlength = 1;
1008
                                }
1009
1010
                                while (!p->which && c < count && 
1011
                                       p->check == 0xFF){
1012
                                        p->check = buf[c];
1013
                                        p->buf[p->found] = buf[c];
1014
                                        c++;
1015
                                        p->found++;
1016
                                        p->hlength++;
1017
                                }
1018
1019
                                if ( c == count) return;
1020
                                
1021
                                if ( (p->check & 0xC0) == 0x40 && !p->which){
1022
                                        p->check = buf[c];
1023
                                        p->buf[p->found] = buf[c];
1024
                                        c++;
1025
                                        p->found++;
1026
                                        p->hlength++;
1027
1028
                                        p->which = 1;
1029
                                        if ( c == count) return;
1030
                                        p->check = buf[c];
1031
                                        p->buf[p->found] = buf[c];
1032
                                        c++;
1033
                                        p->found++;
1034
                                        p->hlength++;
1035
                                        p->which = 2;
1036
                                        if ( c == count) return;
1037
                                }
1038
1039
                                if (p->which == 1){
1040
                                        p->check = buf[c];
1041
                                        p->buf[p->found] = buf[c];
1042
                                        c++;
1043
                                        p->found++;
1044
                                        p->hlength++;
1045
                                        p->which = 2;
1046
                                        if ( c == count) return;
1047
                                }
1048
                                
1049
                                if ( (p->check & 0x30) && p->check != 0xFF){
1050
                                        p->flag2 = (p->check & 0xF0) << 2;
1051
                                        p->pts[0] = p->check;
1052
                                        p->which = 3;
1053
                                } 
1054
1055
                                if ( c == count) return;
1056
                                if (p->which > 2){
1057
                                        if ((p->flag2 & PTS_DTS_FLAGS)
1058
                                            == PTS_ONLY){
1059
                                                while (c < count && 
1060
                                                       p->which < 7){
1061
                                                        p->pts[p->which-2] =
1062
                                                                buf[c];
1063
                                                        p->buf[p->found] = 
1064
                                                                buf[c];
1065
                                                        c++;
1066
                                                        p->found++;
1067
                                                        p->which++;
1068
                                                        p->hlength++;
1069
                                                }
1070
                                                if ( c == count) return;
1071
                                        } else if ((p->flag2 & PTS_DTS_FLAGS) 
1072
                                                   == PTS_DTS){
1073
                                                while (c < count && 
1074
                                                       p->which< 12){
1075
                                                        if (p->which< 7)
1076
                                                                p->pts[p->which
1077
                                                                      -2] =
1078
                                                                        buf[c];
1079
                                                        p->buf[p->found] = 
1080
                                                                buf[c];
1081
                                                        c++;
1082
                                                        p->found++;
1083
                                                        p->which++;
1084
                                                        p->hlength++;
1085
                                                }
1086
                                                if ( c == count) return;
1087
                                        }
1088
                                        p->which = 2000;
1089
                                }
1090
                                                        
1091
                        }
1092
1093
                        while (c < count && p->found < p->plength+6){
1094
                                l = count -c;
1095
                                if (l+p->found > p->plength+6)
1096
                                        l = p->plength+6-p->found;
1097
                                memcpy(p->buf+p->found, buf+c, l);
1098
                                p->found += l;
1099
                                c += l;
1100
                        }                        
1101
                        if(p->found == p->plength+6)
1102
                                func(p);
1103
                        
1104
                        break;
1105
                }
1106
1107
1108
                if ( p->done ){
1109
                        if( p->found + count - c < p->plength+6){
1110
                                p->found += count-c;
1111
                                c = count;
1112
                        } else {
1113
                                c += p->plength+6 - p->found;
1114
                                p->found = p->plength+6;
1115
                        }
1116
                }
1117
1118
                if (p->plength && p->found == p->plength+6) {
1119
                        p->found = 0;
1120
                        p->done = 0;
1121
                        p->plength = 0;
1122
                        memset(p->buf, 0, MAX_PLENGTH);
1123
                        if (c < count)
1124
                                get_pes(buf+c, count-c, p, func);
1125
                }
1126
        }
1127
        return;
1128
}
1129
1130
1131
1132
1133
void setup_pes2ts( p2p *p, uint32_t pida, uint32_t pidv, 
1134
                   void (*ts_write)(uint8_t *buf, int count, p2p *p))
1135
{
1136
        init_p2p( p, ts_write, 2048);
1137
        p->pida = pida;
1138
        p->pidv = pidv;
1139
        p->acounter = 0;
1140
        p->vcounter = 0;
1141
        p->count1 = 0;
1142
        p->count0 = 0;
1143
}
1144
1145
void kpes_to_ts( p2p *p,uint8_t *buf ,int count )
1146
{
1147
        get_pes(buf,count, p,pes_in_ts);
1148
}
1149
1150
1151
void setup_ts2pes( p2p *pa, p2p *pv, uint32_t pida, uint32_t pidv, 
1152
                   void (*pes_write)(uint8_t *buf, int count, p2p *p))
1153
{
1154
        init_p2p( pa, pes_write, 2048);
1155
        init_p2p( pv, pes_write, 2048);
1156
        pa->pid = pida;
1157
        pv->pid = pidv;
1158
}
1159
1160
void kts_to_pes( p2p *p, uint8_t *buf) // don't need count (=188)
1161
{
1162
        uint8_t off = 0;
1163
        uint16_t pid = 0;
1164
1165
        if (!(buf[3]&PAYLOAD)) // no payload?
1166
                return;
1167
1168
        pid = get_pid(buf+1);
1169
                        
1170
        if (pid != p->pid) return;
1171
1172
        if ( buf[1]&PAY_START) {
1173
                if (p->plength == MMAX_PLENGTH-6){
1174
                        p->plength = p->found-6;
1175
                        p->found = 0;
1176
                        pes_repack(p);
1177
                }
1178
        }
1179
1180
        if ( buf[3] & ADAPT_FIELD) {  // adaptation field?
1181
                off = buf[4] + 1;
1182
                if (off+4 > 187) return;
1183
        }
1184
        
1185
        get_pes(buf+4+off, TS_SIZE-4-off, p , pes_repack);
1186
}
1187
1188
1189
1190
1191
// instant repack
1192
1193
1194
void reset_ipack(ipack *p)
1195
{
1196
        p->found = 0;
1197
        p->cid = 0;
1198
        p->plength = 0;
1199
        p->flag1 = 0;
1200
        p->flag2 = 0;
1201
        p->hlength = 0;
1202
        p->mpeg = 0;
1203
        p->check = 0;
1204
        p->which = 0;
1205
        p->done = 0;
1206
        p->count = 0;
1207
        p->size = p->size_orig;
1208
}
1209
1210
void init_ipack(ipack *p, int size,
1211
                void (*func)(uint8_t *buf,  int size, void *priv), int ps)
1212
{
1213
        if ( !(p->buf = malloc(size)) ){
1214
                fprintf(stderr,"Couldn't allocate memory for ipack\n");
1215
                exit(1);
1216
        }
1217
        p->ps = ps;
1218
        p->size_orig = size;
1219
        p->func = func;
1220
        reset_ipack(p);
1221
        p->has_ai = 0;
1222
        p->has_vi = 0;
1223
        p->start = 0;
1224
}
1225
1226
void free_ipack(ipack * p)
1227
{
1228
        if (p->buf) free(p->buf);
1229
}
1230
1231
1232
1233
int get_vinfo(uint8_t *mbuf, int count, VideoInfo *vi, int pr)
1234
{
1235
        uint8_t *headr;
1236
        int found = 0;
1237
        int sw;
1238
        int form = -1;
1239
        int c = 0;
1240
1241
        while (found < 4 && c+4 < count){
1242
                uint8_t *b;
1243
1244
                b = mbuf+c;
1245
                if ( b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01
1246
                     && b[3] == 0xb3) found = 4;
1247
                else {
1248
                        c++;
1249
                }
1250
        }
1251
1252
        if (! found) return -1;
1253
        c += 4;
1254
        if (c+12 >= count) return -1;
1255
        headr = mbuf+c;
1256
1257
        vi->horizontal_size        = ((headr[1] &0xF0) >> 4) | (headr[0] << 4);
1258
        vi->vertical_size        = ((headr[1] &0x0F) << 8) | (headr[2]);
1259
    
1260
        sw = (int)((headr[3]&0xF0) >> 4) ;
1261
1262
        switch( sw ){
1263
        case 1:
1264
                if (pr)
1265
                        fprintf(stderr,"Videostream: ASPECT: 1:1");
1266
                vi->aspect_ratio = 100;        
1267
                break;
1268
        case 2:
1269
                if (pr)
1270
                        fprintf(stderr,"Videostream: ASPECT: 4:3");
1271
                vi->aspect_ratio = 133;        
1272
                break;
1273
        case 3:
1274
                if (pr)
1275
                        fprintf(stderr,"Videostream: ASPECT: 16:9");
1276
                vi->aspect_ratio = 177;        
1277
                break;
1278
        case 4:
1279
                if (pr)
1280
                        fprintf(stderr,"Videostream: ASPECT: 2.21:1");
1281
                vi->aspect_ratio = 221;        
1282
                break;
1283
1284
        case 5 ... 15:
1285
                if (pr)
1286
                        fprintf(stderr,"Videostream: ASPECT: reserved");
1287
                vi->aspect_ratio = 0;        
1288
                break;
1289
1290
        default:
1291
                vi->aspect_ratio = 0;        
1292
                return -1;
1293
        }
1294
1295
        if (pr)
1296
                fprintf(stderr,"  Size = %dx%d",vi->horizontal_size,
1297
                        vi->vertical_size);
1298
1299
        sw = (int)(headr[3]&0x0F);
1300
1301
        switch ( sw ) {
1302
        case 1:
1303
                if (pr)
1304
                        fprintf(stderr,"  FRate: 23.976 fps");
1305
                vi->framerate = 24000/1001.;
1306
                form = -1;
1307
                break;
1308
        case 2:
1309
                if (pr)
1310
                        fprintf(stderr,"  FRate: 24 fps");
1311
                vi->framerate = 24;
1312
                form = -1;
1313
                break;
1314
        case 3:
1315
                if (pr)
1316
                        fprintf(stderr,"  FRate: 25 fps");
1317
                vi->framerate = 25;
1318
                form = VIDEO_MODE_PAL;
1319
                break;
1320
        case 4:
1321
                if (pr)
1322
                        fprintf(stderr,"  FRate: 29.97 fps");
1323
                vi->framerate = 30000/1001.;
1324
                form = VIDEO_MODE_NTSC;
1325
                break;
1326
        case 5:
1327
                if (pr)
1328
                        fprintf(stderr,"  FRate: 30 fps");
1329
                vi->framerate = 30;
1330
                form = VIDEO_MODE_NTSC;
1331
                break;
1332
        case 6:
1333
                if (pr)
1334
                        fprintf(stderr,"  FRate: 50 fps");
1335
                vi->framerate = 50;
1336
                form = VIDEO_MODE_PAL;
1337
                break;
1338
        case 7:
1339
                if (pr)
1340
                        fprintf(stderr,"  FRate: 60 fps");
1341
                vi->framerate = 60;
1342
                form = VIDEO_MODE_NTSC;
1343
                break;
1344
        }
1345
1346
        vi->bit_rate = 400*(((headr[4] << 10) & 0x0003FC00UL) 
1347
                            | ((headr[5] << 2) & 0x000003FCUL) | 
1348
                            (((headr[6] & 0xC0) >> 6) & 0x00000003UL));
1349
        
1350
        if (pr){
1351
                fprintf(stderr,"  BRate: %.2f Mbit/s",(vi->bit_rate)/1000000.);
1352
                fprintf(stderr,"\n");
1353
        }
1354
        vi->video_format = form;
1355
1356
        vi->off = c-4;
1357
        return c-4;
1358
}
1359
1360
extern unsigned int bitrates[3][16];
1361
extern uint32_t freq[4];
1362
1363
int get_ainfo(uint8_t *mbuf, int count, AudioInfo *ai, int pr)
1364
{
1365
        uint8_t *headr;
1366
        int found = 0;
1367
        int c = 0;
1368
        int fr =0;
1369
        
1370
        while (!found && c < count){
1371
                uint8_t *b = mbuf+c;
1372
1373
                if ( b[0] == 0xff && (b[1] & 0xf8) == 0xf8)
1374
                        found = 1;
1375
                else {
1376
                        c++;
1377
                }
1378
        }        
1379
1380
        if (!found) return -1;
1381
1382
        if (c+3 >= count) return -1;
1383
        headr = mbuf+c;
1384
1385
        ai->layer = (headr[1] & 0x06) >> 1;
1386
1387
        if (pr)
1388
                fprintf(stderr,"Audiostream: Layer: %d", 4-ai->layer);
1389
1390
1391
        ai->bit_rate = bitrates[(3-ai->layer)][(headr[2] >> 4 )]*1000;
1392
1393
        if (pr){
1394
                if (ai->bit_rate == 0)
1395
                        fprintf (stderr,"  Bit rate: free");
1396
                else if (ai->bit_rate == 0xf)
1397
                        fprintf (stderr,"  BRate: reserved");
1398
                else
1399
                        fprintf (stderr,"  BRate: %d kb/s", ai->bit_rate/1000);
1400
        }
1401
1402
        fr = (headr[2] & 0x0c ) >> 2;
1403
        ai->frequency = freq[fr]*100;
1404
        
1405
        if (pr){
1406
                if (ai->frequency == 3)
1407
                        fprintf (stderr, "  Freq: reserved\n");
1408
                else
1409
                        fprintf (stderr,"  Freq: %2.1f kHz\n", 
1410
                                 ai->frequency/1000.);
1411
        }
1412
        ai->off = c;
1413
        return c;
1414
}
1415
1416
unsigned int ac3_bitrates[32] =
1417
    {32,40,48,56,64,80,96,112,128,160,192,224,256,320,384,448,512,576,640,
1418
     0,0,0,0,0,0,0,0,0,0,0,0,0};
1419
1420
uint32_t ac3_freq[4] = {480, 441, 320, 0};
1421
uint32_t ac3_frames[3][32] =
1422
    {{64,80,96,112,128,160,192,224,256,320,384,448,512,640,768,896,1024,
1423
      1152,1280,0,0,0,0,0,0,0,0,0,0,0,0,0},
1424
     {69,87,104,121,139,174,208,243,278,348,417,487,557,696,835,975,1114,
1425
      1253,1393,0,0,0,0,0,0,0,0,0,0,0,0,0},
1426
     {96,120,144,168,192,240,288,336,384,480,576,672,768,960,1152,1344,
1427
      1536,1728,1920,0,0,0,0,0,0,0,0,0,0,0,0,0}}; 
1428
1429
int get_ac3info(uint8_t *mbuf, int count, AudioInfo *ai, int pr)
1430
{
1431
        uint8_t *headr;
1432
        int found = 0;
1433
        int c = 0;
1434
        uint8_t frame;
1435
        int fr = 0;
1436
1437
        while ( !found  && c < count){
1438
                uint8_t *b = mbuf+c;
1439
                if ( b[0] == 0x0b &&  b[1] == 0x77 )
1440
                        found = 1;
1441
                else {
1442
                        c++;
1443
                }
1444
        }        
1445
1446
1447
        if (!found){
1448
                return -1;
1449
        }
1450
        ai->off = c;
1451
1452
        if (c+5 >= count) return -1;
1453
1454
        ai->layer = 0;  // 0 for AC3
1455
        headr = mbuf+c+2;
1456
1457
        frame = (headr[2]&0x3f);
1458
        ai->bit_rate = ac3_bitrates[frame>>1]*1000;
1459
1460
        if (pr) fprintf (stderr,"  BRate: %d kb/s", ai->bit_rate/1000);
1461
1462
        fr = (headr[2] & 0xc0 ) >> 6;
1463
        ai->frequency = freq[fr]*100;
1464
        if (pr) fprintf (stderr,"  Freq: %d Hz\n", ai->frequency);
1465
1466
        ai->framesize = ac3_frames[fr][frame >> 1];
1467
        if ((frame & 1) &&  (fr == 1)) ai->framesize++;
1468
        ai->framesize = ai->framesize << 1;
1469
        if (pr) fprintf (stderr,"  Framesize %d\n", ai->framesize);
1470
1471
        return c;
1472
}
1473
1474
1475
void ps_pes(ipack *p)
1476
{
1477
        int check;
1478
        uint8_t pbuf[PS_HEADER_L2];
1479
        static int muxr = 0;
1480
        static int ai = 0;
1481
        static int vi = 0;
1482
        static int start = 0;
1483
        static uint32_t SCR = 0;
1484
1485
        if (p->mpeg == 2){
1486
                switch(p->buf[3]){
1487
                case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1488
                        if (!p->has_vi){
1489
                                if(get_vinfo(p->buf, p->count, &p->vi,1) >=0) {
1490
                                        p->has_vi = 1;
1491
                                        vi = p->vi.bit_rate;
1492
                                }
1493
                        }                         
1494
                        break;
1495
1496
                case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1497
                        if (!p->has_ai){
1498
                                if(get_ainfo(p->buf, p->count, &p->ai,1) >=0) {
1499
                                        p->has_ai = 1;
1500
                                        ai = p->ai.bit_rate;
1501
                                }
1502
                        } 
1503
                        break;
1504
                }
1505
1506
                if (p->has_vi && vi && !muxr){
1507
                        muxr = (vi+ai)/400;
1508
                }
1509
1510
                if ( start && muxr && (p->buf[7] & PTS_ONLY) && (p->has_ai || 
1511
                                       p->buf[9+p->buf[8]+4] == 0xb3)){  
1512
                        SCR = trans_pts_dts(p->pts)-3600;
1513
                        
1514
                        check = write_ps_header(pbuf,
1515
                                                SCR,
1516
                                                muxr, 1, 0, 0, 1, 1, 1, 
1517
                                                0, 0, 0, 0, 0, 0);
1518
1519
                        p->func(pbuf, check , p->data);
1520
                }
1521
1522
                if (muxr && !start && vi){
1523
                        SCR = trans_pts_dts(p->pts)-3600;
1524
                        check = write_ps_header(pbuf,
1525
                                                SCR, 
1526
                                                muxr, 1, 0, 0, 1, 1, 1, 
1527
                                                0xC0, 0, 64, 0xE0, 1, 460);
1528
                        start = 1;
1529
                        p->func(pbuf, check , p->data);
1530
                }
1531
1532
                if (start)
1533
                        p->func(p->buf, p->count, p->data);
1534
        }
1535
}
1536
1537
void send_ipack(ipack *p)
1538
{
1539
        int streamid=0;
1540
        int off;
1541
        int ac3_off = 0;
1542
        AudioInfo ai;
1543
        int nframes= 0;
1544
        int f=0;
1545
1546
        if (p->count < 10) return;
1547
        p->buf[3] = p->cid;
1548
        p->buf[4] = (uint8_t)(((p->count-6) & 0xFF00) >> 8);
1549
        p->buf[5] = (uint8_t)((p->count-6) & 0x00FF);
1550
1551
        
1552
        if (p->cid == PRIVATE_STREAM1){
1553
1554
                off = 9+p->buf[8];
1555
                streamid = p->buf[off];
1556
                if ((streamid & 0xF8) == 0x80){
1557
                        ai.off = 0;
1558
                        ac3_off = ((p->buf[off+2] << 8)| p->buf[off+3]);
1559
                        if (ac3_off < p->count)
1560
                                f=get_ac3info(p->buf+off+3+ac3_off, 
1561
                                              p->count-ac3_off, &ai,0);
1562
                        if ( !f ){
1563
                                nframes = (p->count-off-3-ac3_off)/ 
1564
                                        ai.framesize + 1;
1565
                                p->buf[off+2] = (ac3_off >> 8)& 0xFF;
1566
                                p->buf[off+3] = (ac3_off)& 0xFF;
1567
                                p->buf[off+1] = nframes;
1568
                                
1569
                                ac3_off +=  nframes * ai.framesize - p->count;
1570
                        }
1571
                }
1572
        } 
1573
        
1574
        if (p->ps) ps_pes(p);
1575
        else p->func(p->buf, p->count, p->data);
1576
1577
        switch ( p->mpeg ){
1578
        case 2:                
1579
                
1580
                p->buf[6] = 0x80;
1581
                p->buf[7] = 0x00;
1582
                p->buf[8] = 0x00;
1583
                p->count = 9;
1584
1585
                if (p->cid == PRIVATE_STREAM1 && (streamid & 0xF8)==0x80 ){
1586
                        p->count += 4;
1587
                        p->buf[9] = streamid;
1588
                        p->buf[10] = (ac3_off >> 8)& 0xFF;
1589
                        p->buf[11] = (ac3_off)& 0xFF;
1590
                        p->buf[12] = 0;
1591
                }
1592
                
1593
                break;
1594
        case 1:
1595
                p->buf[6] = 0x0F;
1596
                p->count = 7;
1597
                break;
1598
        }
1599
1600
}
1601
1602
1603
static void write_ipack(ipack *p, uint8_t *data, int count)
1604
{
1605
1606
        uint8_t headr[3] = { 0x00, 0x00, 0x01} ;
1607
        int diff =0;
1608
1609
        if (p->count < 6){
1610
                if (trans_pts_dts(p->pts) > trans_pts_dts(p->last_pts))
1611
                        memcpy(p->last_pts, p->pts, 5);
1612
                p->count = 0;
1613
                memcpy(p->buf+p->count, headr, 3);
1614
                p->count += 6;
1615
        }
1616
        if ( p->size == p->size_orig && p->plength &&
1617
             (diff = 6+p->plength - p->found + p->count +count) > p->size &&
1618
             diff < 3*p->size/2){
1619
                
1620
                        p->size = diff/2;
1621
//                        fprintf(stderr,"size: %d \n",p->size);
1622
        }
1623
        if (p->count + count < p->size){
1624
                memcpy(p->buf+p->count, data, count); 
1625
                p->count += count;
1626
        } else {
1627
                int rest = p->size - p->count;
1628
                if (rest < 0) rest = 0;
1629
                memcpy(p->buf+p->count, data, rest);
1630
                p->count += rest;
1631
//                fprintf(stderr,"count: %d \n",p->count);
1632
                send_ipack(p);
1633
                if (count - rest > 0)
1634
                        write_ipack(p, data+rest, count-rest);
1635
        }
1636
}
1637
1638
void instant_repack (uint8_t *buf, int count, ipack *p)
1639
{
1640
1641
        int l;
1642
        unsigned short *pl;
1643
        int c=0;
1644
1645
        while (c < count && (p->mpeg == 0 ||
1646
                             (p->mpeg == 1 && p->found < 7) ||
1647
                             (p->mpeg == 2 && p->found < 9))
1648
               &&  (p->found < 5 || !p->done)){
1649
                switch ( p->found ){
1650
                case 0:
1651
                case 1:
1652
                        if (buf[c] == 0x00) p->found++;
1653
                        else p->found = 0;
1654
                        c++;
1655
                        break;
1656
                case 2:
1657
                        if (buf[c] == 0x01) p->found++;
1658
                        else if (buf[c] == 0){
1659
                                p->found = 2;
1660
                        } else p->found = 0;
1661
                        c++;
1662
                        break;
1663
                case 3:
1664
                        p->cid = 0;
1665
                        switch (buf[c]){
1666
                        case PROG_STREAM_MAP:
1667
                        case PRIVATE_STREAM2:
1668
                        case PROG_STREAM_DIR:
1669
                        case ECM_STREAM     :
1670
                        case EMM_STREAM     :
1671
                        case PADDING_STREAM :
1672
                        case DSM_CC_STREAM  :
1673
                        case ISO13522_STREAM:
1674
                                p->done = 1;
1675
                        case PRIVATE_STREAM1:
1676
                        case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1677
                        case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1678
                                p->found++;
1679
                                p->cid = buf[c];
1680
                                c++;
1681
                                break;
1682
                        default:
1683
                                p->found = 0;
1684
                                break;
1685
                        }
1686
                        break;
1687
                        
1688
1689
                case 4:
1690
                        if (count-c > 1){
1691
                                pl = (unsigned short *) (buf+c);
1692
                                p->plength =  ntohs(*pl);
1693
                                p->plen[0] = buf[c];
1694
                                c++;
1695
                                p->plen[1] = buf[c];
1696
                                c++;
1697
                                p->found+=2;
1698
                        } else {
1699
                                p->plen[0] = buf[c];
1700
                                p->found++;
1701
                                return;
1702
                        }
1703
                        break;
1704
                case 5:
1705
                        p->plen[1] = buf[c];
1706
                        c++;
1707
                        pl = (unsigned short *) p->plen;
1708
                        p->plength = ntohs(*pl);
1709
                        p->found++;
1710
                        break;
1711
1712
1713
                case 6:
1714
                        if (!p->done){
1715
                                p->flag1 = buf[c];
1716
                                c++;
1717
                                p->found++;
1718
                                if ( (p->flag1 & 0xC0) == 0x80 ) p->mpeg = 2;
1719
                                else {
1720
                                        p->hlength = 0;
1721
                                        p->which = 0;
1722
                                        p->mpeg = 1;
1723
                                        p->flag2 = 0;
1724
                                }
1725
                        }
1726
                        break;
1727
1728
                case 7:
1729
                        if ( !p->done && p->mpeg == 2){
1730
                                p->flag2 = buf[c];
1731
                                c++;
1732
                                p->found++;
1733
                        }        
1734
                        break;
1735
1736
                case 8:
1737
                        if ( !p->done && p->mpeg == 2){
1738
                                p->hlength = buf[c];
1739
                                c++;
1740
                                p->found++;
1741
                        }
1742
                        break;
1743
                        
1744
                default:
1745
1746
                        break;
1747
                }
1748
        }
1749
1750
1751
        if (c == count) return;
1752
1753
        if (!p->plength) p->plength = MMAX_PLENGTH-6;
1754
1755
1756
        if ( p->done || ((p->mpeg == 2 && p->found >= 9)  || 
1757
             (p->mpeg == 1 && p->found >= 7)) ){
1758
                switch (p->cid){
1759
                        
1760
                case AUDIO_STREAM_S ... AUDIO_STREAM_E:                        
1761
                case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1762
                case PRIVATE_STREAM1:
1763
                        
1764
                        if (p->mpeg == 2 && p->found == 9){
1765
                                write_ipack(p, &p->flag1, 1);
1766
                                write_ipack(p, &p->flag2, 1);
1767
                                write_ipack(p, &p->hlength, 1);
1768
                        }
1769
1770
                        if (p->mpeg == 1 && p->found == 7){
1771
                                write_ipack(p, &p->flag1, 1);
1772
                        }
1773
1774
1775
                        if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) &&  
1776
                            p->found < 14){
1777
                                while (c < count && p->found < 14){
1778
                                        p->pts[p->found-9] = buf[c];
1779
                                        write_ipack(p, buf+c, 1);
1780
                                        c++;
1781
                                        p->found++;
1782
                                }
1783
                                if (c == count) return;
1784
                        }
1785
1786
                        if (p->mpeg == 1 && p->which < 2000){
1787
1788
                                if (p->found == 7) {
1789
                                        p->check = p->flag1;
1790
                                        p->hlength = 1;
1791
                                }
1792
1793
                                while (!p->which && c < count && 
1794
                                       p->check == 0xFF){
1795
                                        p->check = buf[c];
1796
                                        write_ipack(p, buf+c, 1);
1797
                                        c++;
1798
                                        p->found++;
1799
                                        p->hlength++;
1800
                                }
1801
1802
                                if ( c == count) return;
1803
                                
1804
                                if ( (p->check & 0xC0) == 0x40 && !p->which){
1805
                                        p->check = buf[c];
1806
                                        write_ipack(p, buf+c, 1);
1807
                                        c++;
1808
                                        p->found++;
1809
                                        p->hlength++;
1810
1811
                                        p->which = 1;
1812
                                        if ( c == count) return;
1813
                                        p->check = buf[c];
1814
                                        write_ipack(p, buf+c, 1);
1815
                                        c++;
1816
                                        p->found++;
1817
                                        p->hlength++;
1818
                                        p->which = 2;
1819
                                        if ( c == count) return;
1820
                                }
1821
1822
                                if (p->which == 1){
1823
                                        p->check = buf[c];
1824
                                        write_ipack(p, buf+c, 1);
1825
                                        c++;
1826
                                        p->found++;
1827
                                        p->hlength++;
1828
                                        p->which = 2;
1829
                                        if ( c == count) return;
1830
                                }
1831
                                
1832
                                if ( (p->check & 0x30) && p->check != 0xFF){
1833
                                        p->flag2 = (p->check & 0xF0) << 2;
1834
                                        p->pts[0] = p->check;
1835
                                        p->which = 3;
1836
                                } 
1837
1838
                                if ( c == count) return;
1839
                                if (p->which > 2){
1840
                                        if ((p->flag2 & PTS_DTS_FLAGS)
1841
                                            == PTS_ONLY){
1842
                                                while (c < count && 
1843
                                                       p->which < 7){
1844
                                                        p->pts[p->which-2] =
1845
                                                                buf[c];
1846
                                                        write_ipack(p,buf+c,1);
1847
                                                        c++;
1848
                                                        p->found++;
1849
                                                        p->which++;
1850
                                                        p->hlength++;
1851
                                                }
1852
                                                if ( c == count) return;
1853
                                        } else if ((p->flag2 & PTS_DTS_FLAGS) 
1854
                                                   == PTS_DTS){
1855
                                                while (c < count && 
1856
                                                       p->which< 12){
1857
                                                        if (p->which< 7)
1858
                                                                p->pts[p->which
1859
                                                                      -2] =
1860
                                                                        buf[c];
1861
                                                        write_ipack(p,buf+c,1);
1862
                                                        c++;
1863
                                                        p->found++;
1864
                                                        p->which++;
1865
                                                        p->hlength++;
1866
                                                }
1867
                                                if ( c == count) return;
1868
                                        }
1869
                                        p->which = 2000;
1870
                                }
1871
                                                        
1872
                        }
1873
1874
                        while (c < count && p->found < p->plength+6){
1875
                                l = count -c;
1876
                                if (l+p->found > p->plength+6)
1877
                                        l = p->plength+6-p->found;
1878
                                write_ipack(p, buf+c, l);
1879
                                p->found += l;
1880
                                c += l;
1881
                        }        
1882
                
1883
                        break;
1884
                }
1885
1886
1887
                if ( p->done ){
1888
                        if( p->found + count - c < p->plength+6){
1889
                                p->found += count-c;
1890
                                c = count;
1891
                        } else {
1892
                                c += p->plength+6 - p->found;
1893
                                p->found = p->plength+6;
1894
                        }
1895
                }
1896
1897
                if (p->plength && p->found == p->plength+6) {
1898
                        send_ipack(p);
1899
                        reset_ipack(p);
1900
                        if (c < count)
1901
                                instant_repack(buf+c, count-c, p);
1902
                }
1903
        }
1904
        return;
1905
}
1906
1907
void write_out_es(uint8_t *buf, int count,void  *priv)
1908
{
1909
        ipack *p = (ipack *) priv;
1910
        u8 payl = buf[8]+9+p->start-1;
1911
1912
        write(p->fd, buf+payl, count-payl);
1913
        p->start = 1;
1914
}
1915
1916
void write_out_pes(uint8_t *buf, int count,void  *priv)
1917
{
1918
        ipack *p = (ipack *) priv;
1919
        write(p->fd, buf, count);
1920
}
1921
1922
1923
1924
int64_t ts_demux(int fdin, int fdv_out,int fda_out,uint16_t pida,
1925
                  uint16_t pidv, int es)
1926
{
1927
        uint8_t buf[IN_SIZE];
1928
        uint8_t mbuf[TS_SIZE];
1929
        int i;
1930
        int count = 1;
1931
        uint16_t pid;
1932
        ipack pa, pv;
1933
        ipack *p;
1934
        u8 *sb;
1935
        int64_t apts=0;
1936
        int64_t vpts=0;
1937
        int verb = 0;
1938
        uint64_t length =0;
1939
        uint64_t l=0;
1940
        int perc =0;
1941
        int last_perc =0;
1942
1943
        if (fdin != STDIN_FILENO) verb = 1; 
1944
1945
        if (verb) {
1946
                length = lseek(fdin, 0, SEEK_END);
1947
                lseek(fdin,0,SEEK_SET);
1948
        }
1949
1950
        if (!pida || !pidv)
1951
                find_avpids(fdin, &pidv, &pida);
1952
1953
        if (es){
1954
                init_ipack(&pa, IPACKS,write_out_es, 0);
1955
                init_ipack(&pv, IPACKS,write_out_es, 0);
1956
        } else {
1957
                init_ipack(&pa, IPACKS,write_out_pes, 0);
1958
                init_ipack(&pv, IPACKS,write_out_pes, 0);
1959
        } 
1960
        pa.fd = fda_out;
1961
        pv.fd = fdv_out;
1962
        pa.data = (void *)&pa;
1963
        pv.data = (void *)&pv;
1964
1965
         count = read(fdin,mbuf,TS_SIZE);
1966
        if (count) l+=count;
1967
        for ( i = 0; i < 188 ; i++){
1968
                if ( mbuf[i] == 0x47 ) break;
1969
        }
1970
        if ( i == 188){
1971
                fprintf(stderr,"Not a TS\n");
1972
                return 0;
1973
        } else {
1974
                memcpy(buf,mbuf+i,TS_SIZE-i);
1975
                count = read(fdin,mbuf,i);
1976
                if (count) l+=count;
1977
                memcpy(buf+TS_SIZE-i,mbuf,i);
1978
                i = 188;
1979
        }
1980
        
1981
        count = 1;
1982
        while (count > 0){
1983
                count = read(fdin,buf+i,IN_SIZE-i);
1984
                if (count) l+=count;
1985
                if (verb && perc >last_perc){
1986
                        perc = (100*l)/length;
1987
                        fprintf(stderr,"Reading TS  %d %%\r",perc);
1988
                        last_perc = perc;
1989
                }
1990
                
1991
                for( i = 0; i < count; i+= TS_SIZE){
1992
                        uint8_t off = 0;
1993
1994
                        if ( count - i < TS_SIZE) break;
1995
1996
                        pid = get_pid(buf+i+1);
1997
                        if (!(buf[3+i]&0x10)) // no payload?
1998
                                continue;
1999
                        if (pid == pidv){
2000
                                p = &pv;
2001
                        } else {
2002
                                if (pid == pida){
2003
                                        p = &pa;
2004
                                } else continue;
2005
                        }
2006
2007
                        if ( buf[3+i] & 0x20) {  // adaptation field?
2008
                                off = buf[4+i] + 1;
2009
                        }
2010
2011
                        if ( buf[1+i]&0x40) {
2012
                                if (p->plength == MMAX_PLENGTH-6){
2013
                                        p->plength = p->found-6;
2014
                                        p->found = 0;
2015
                                        send_ipack(p);
2016
                                        reset_ipack(p);
2017
                                }
2018
                                sb = buf+4+off+i;
2019
                                if( es && 
2020
                                    !p->start && (sb[7] & PTS_DTS_FLAGS)){
2021
                                        uint8_t *pay = sb+sb[8]+9; 
2022
                                        int l = TS_SIZE - 13 - off - sb[8];
2023
                                        if ( pid == pidv &&   
2024
                                             (p->start = 
2025
                                              get_vinfo( pay, l,&p->vi,1)+1) >0
2026
                                                ){
2027
                                                vpts = trans_pts_dts(sb+9);
2028
                                                printf("vpts : %fs\n",
2029
                                                       vpts/90000.);
2030
                                        }
2031
                                        if ( pid == pida && 
2032
                                             (p->start = 
2033
                                              get_ainfo( pay, l,&p->ai,1)+1) >0
2034
                                                ){
2035
                                                apts = trans_pts_dts(sb+9);
2036
                                                printf("apts : %fs\n",
2037
                                                       apts/90000.);
2038
                                        }
2039
                                }
2040
                        }
2041
2042
                        if (p->start)
2043
                                instant_repack(buf+4+off+i, TS_SIZE-4-off, p);
2044
                }
2045
                i = 0;
2046
2047
        }
2048
2049
        return (vpts-apts);
2050
}
2051
2052
void ts2es(int fdin,  uint16_t pidv)
2053
{
2054
        uint8_t buf[IN_SIZE];
2055
        uint8_t mbuf[TS_SIZE];
2056
        int i;
2057
        int count = 1;
2058
        ipack p;
2059
        int verb = 0;
2060
        uint64_t length =0;
2061
        uint64_t l=0;
2062
        int perc =0;
2063
        int last_perc =0;
2064
        uint16_t pid;
2065
2066
        if (fdin != STDIN_FILENO) verb = 1; 
2067
2068
        if (verb) {
2069
                length = lseek(fdin, 0, SEEK_END);
2070
                lseek(fdin,0,SEEK_SET);
2071
        }
2072
2073
        init_ipack(&p, IPACKS,write_out_es, 0);
2074
2075
        p.fd = STDOUT_FILENO;
2076
        p.data = (void *)&p;
2077
2078
         count = read(fdin,mbuf,TS_SIZE);
2079
        if (count) l+=count;
2080
        for ( i = 0; i < 188 ; i++){
2081
                if ( mbuf[i] == 0x47 ) break;
2082
        }
2083
        if ( i == 188){
2084
                fprintf(stderr,"Not a TS\n");
2085
                return;
2086
        } else {
2087
                memcpy(buf,mbuf+i,TS_SIZE-i);
2088
                count = read(fdin,mbuf,i);
2089
                if (count) l+=count;
2090
                memcpy(buf+TS_SIZE-i,mbuf,i);
2091
                i = 188;
2092
        }
2093
        
2094
        count = 1;
2095
        while (count > 0){
2096
                count = read(fdin,buf+i,IN_SIZE-i);
2097
                if (count) l+=count;
2098
                if (verb && perc >last_perc){
2099
                        perc = (100*l)/length;
2100
                        fprintf(stderr,"Reading TS  %d %%\r",perc);
2101
                        last_perc = perc;
2102
                }
2103
2104
                for( i = 0; i < count; i+= TS_SIZE){
2105
                        uint8_t off = 0;
2106
2107
                        if ( count - i < TS_SIZE) break;
2108
2109
                        pid = get_pid(buf+i+1);
2110
                        if (!(buf[3+i]&0x10)) // no payload?
2111
                                continue;
2112
                        if (pid != pidv){
2113
                                continue;
2114
                        }
2115
2116
                        if ( buf[3+i] & 0x20) {  // adaptation field?
2117
                                off = buf[4+i] + 1;
2118
                        }
2119
2120
                        if ( buf[1+i]&0x40) {
2121
                                if (p.plength == MMAX_PLENGTH-6){
2122
                                        p.plength = p.found-6;
2123
                                        p.found = 0;
2124
                                        send_ipack(&p);
2125
                                        reset_ipack(&p);
2126
                                }
2127
                        }
2128
2129
                        instant_repack(buf+4+off+i, TS_SIZE-4-off, &p);
2130
                }
2131
                i = 0;
2132
2133
        }
2134
}
2135
2136
2137
void change_aspect(int fdin, int fdout, int aspect)
2138
{
2139
        ps_packet ps;
2140
        pes_packet pes;
2141
        int neof,i;
2142
2143
        do {
2144
                init_ps(&ps);
2145
                neof = read_ps(fdin,&ps);
2146
                write_ps(fdout,&ps);
2147
                for (i = 0; i < ps.npes; i++){
2148
                        u8 *buf;
2149
                        int c = 0;
2150
                        int l;
2151
2152
                        init_pes(&pes);
2153
                        read_pes(fdin, &pes);
2154
2155
                        buf = pes.pes_pckt_data;
2156
2157
                        switch (pes.stream_id){
2158
                        case VIDEO_STREAM_S ... VIDEO_STREAM_E:
2159
                                l=pes.length;
2160
                                break;
2161
                        default:
2162
                                l = 0;
2163
                                break;
2164
                        }
2165
                        while ( c < l - 6){
2166
                                if (buf[c] == 0x00 && 
2167
                                    buf[c+1] == 0x00 &&
2168
                                    buf[c+2] == 0x01 && 
2169
                                    buf[c+3] == 0xB3) {
2170
                                        c += 4;
2171
                                        buf[c+3] &= 0x0f;
2172
                                        buf[c+3] |= aspect;
2173
                                }
2174
                                else c++;
2175
                        }
2176
                        write_pes(fdout,&pes);
2177
                }
2178
        } while( neof > 0 );
2179
}