Statistics
| Branch: | Tag: | Revision:

dvbd / src / remux.c @ a24dbbce

History | View | Annotate | Download (26.1 KB)

1
#include "remux.h"
2

    
3
unsigned int bitrates[3][16] =
4
{{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0},
5
 {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0},
6
 {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}};
7

    
8
uint32_t freq[4] = {441, 480, 320, 0};
9
static uint32_t samples[4] = { 384, 1152, 0, 0};
10
char *frames[3] = {"I-Frame","P-Frame","B-Frame"};
11

    
12

    
13
void copy_ptslm(PTS_List *a, PTS_List *b)
14
{
15
        a->pos  = b->pos;
16
        a->PTS  = b->PTS;
17
        a->dts  = b->dts;
18
        a->spos = b->spos;
19
}
20

    
21
void clear_ptslm(PTS_List *a)
22
{
23
        a->pos  = 0;
24
        a->PTS  = 0;
25
        a->dts  = 0;
26
        a->spos = 0;        
27
}
28

    
29
void init_ptsl(PTS_List *ptsl)
30
{
31
        int i;
32
        for (i=0;i< MAX_PTS;i++){
33
                clear_ptslm(&ptsl[i]);
34
        }
35
}
36

    
37
int del_pts(PTS_List *ptsl, int pos, int nr)
38
{
39
        int i;
40
        int del = 0;
41

    
42
        for( i = 0; i < nr-1; i++){
43
                if(pos > ptsl[i].pos && pos >= ptsl[i+1].pos) del++;
44
        }
45

    
46
        if(del)
47
                for( i = 0; i < nr-del; i++){
48
                        copy_ptslm(&ptsl[i], &ptsl[i+del]);
49
                }
50

    
51
        return nr-del;
52
}
53

    
54
int del_ptss(PTS_List *ptsl, int pts, int *nb)
55
{
56
        int i;
57
        int del = 0;
58
        int sum = 0;
59
        int nr = *nb;
60

    
61
        for( i = 0; i < nr; i++){
62
                if(pts > ptsl[i].PTS){
63
                        del++;
64
                        sum += ptsl[i].pos;
65
                }
66
        }
67

    
68
        if(del)
69
                for( i = 0; i < nr-del; i++){
70
                        copy_ptslm(&ptsl[i], &ptsl[i+del]);
71
                }
72

    
73
        *nb = nr-del;
74
        return sum;
75
}
76

    
77
int add_pts(PTS_List *ptsl, uint32_t pts, int pos, int spos, int nr, uint32_t dts)
78
{
79
        int i;
80

    
81
        for ( i=0;i < nr; i++) if (spos &&  ptsl[i].pos == pos) return nr;
82
        if (nr == MAX_PTS) {
83
                nr = del_pts(ptsl, ptsl[1].pos+1, nr);
84
        } else nr++;
85
        i = nr-1;
86
        
87
        ptsl[i].pos  = pos;
88
        ptsl[i].spos = spos;
89
        ptsl[i].PTS  = pts;
90
        ptsl[i].dts  = dts;
91
        return nr;
92
}
93

    
94
void add_vpts(Remux *rem, uint8_t *pts)
95
{
96
        uint32_t PTS = ntohl(trans_pts_dts(pts));
97
        rem->vptsn = add_pts(rem->vpts_list, PTS, rem->vwrite, rem->awrite,
98
                             rem->vptsn, PTS);
99
}
100

    
101
void add_apts(Remux *rem, uint8_t *pts)
102
{
103
        uint32_t PTS = ntohl(trans_pts_dts(pts));
104
        rem->aptsn = add_pts(rem->apts_list, PTS, rem->awrite, rem->vwrite,
105
                             rem->aptsn, PTS);
106
}
107

    
108
void del_vpts(Remux *rem)
109
{
110
        rem->vptsn = del_pts(rem->vpts_list, rem->vread, rem->vptsn);
111
}
112

    
113
void del_apts(Remux *rem)
114
{
115
        rem->aptsn = del_pts(rem->apts_list, rem->aread, rem->aptsn);
116
}
117

    
118

    
119
void copy_framelm(FRAME_List *a, FRAME_List *b)
120
{
121
        a->type  = b->type;
122
        a->pos   = b->pos;
123
        a->FRAME = b->FRAME;
124
        a->time  = b->time;
125
        a->pts   = b->pts;
126
        a->dts   = b->dts;
127
}
128

    
129
void clear_framelm(FRAME_List *a)
130
{
131
        a->type  = 0;
132
        a->pos   = 0;
133
        a->FRAME = 0;
134
        a->time  = 0; 
135
        a->pts   = 0; 
136
        a->dts   = 0; 
137
}
138

    
139
void init_framel(FRAME_List *framel)
140
{
141
        int i;
142
        for (i=0;i< MAX_FRAME;i++){
143
                clear_framelm(&framel[i]);
144
        }
145
}
146

    
147
int del_frame(FRAME_List *framel, int pos, int nr)
148
{
149
        int i;
150
        int del = 0;
151

    
152
        for( i = 0; i < nr-1; i++){
153
                if(pos > framel[i].pos && pos >= framel[i+1].pos) del++;
154
        }
155

    
156
        if(del)
157
                for( i = 0; i < nr-del; i++){
158
                        copy_framelm(&framel[i], &framel[i+del]);
159
                }
160

    
161
        return nr-del;
162
}
163

    
164
int add_frame(FRAME_List *framel, uint32_t frame, int pos, int type, int nr, 
165
              uint32_t time, uint32_t pts, uint32_t dts)
166
{
167
        int i;
168

    
169
        if (nr == MAX_FRAME) {
170
                nr = del_frame(framel, framel[1].pos+1, nr);
171
        } else nr++;
172
        i = nr-1;
173
        
174
        framel[i].type  = type;
175
        framel[i].pos   = pos;
176
        framel[i].FRAME = frame;
177
        framel[i].time  = time;
178
        framel[i].pts   = pts;
179
        framel[i].dts   = dts;
180
        return nr;
181
}
182

    
183
void add_vframe(Remux *rem, uint32_t frame, long int pos, int type, int time, 
184
                uint32_t pts, uint32_t dts)
185
{
186
        rem->vframen = add_frame(rem->vframe_list, frame, pos, type,
187
                                 rem->vframen, time, pts, dts);
188
}
189

    
190
void add_aframe(Remux *rem, uint32_t frame, long int pos, uint32_t pts)
191
{
192
        rem->aframen = add_frame(rem->aframe_list, frame, pos, 0, 
193
                                 rem->aframen, 0, pts, pts);
194
}
195

    
196
void del_vframe(Remux *rem)
197
{
198
        rem->vframen = del_frame(rem->vframe_list, rem->vread, rem->vframen);
199
}
200

    
201
void del_aframe(Remux *rem)
202
{
203
        rem->aframen = del_frame(rem->aframe_list, rem->aread, rem->aframen);
204
}
205

    
206

    
207
void printpts(uint32_t pts)
208
{
209
        fprintf(stderr,"%2d:%02d:%02d.%03d",
210
                (int)(pts/90000.)/3600,
211
                ((int)(pts/90000.)%3600)/60,
212
                ((int)(pts/90000.)%3600)%60,
213
                (((int)(pts/90.)%3600000)%60000)%1000
214
                );
215
}
216

    
217

    
218
void find_vframes( Remux *rem, uint8_t *buf, int l)
219
{
220
         int c = 0;
221
        int type;
222
        uint32_t time = 0;
223
        int hour;
224
        int min;
225
        int sec;
226
        u64 pts=0;
227
        u64 dts=0;
228
        uint32_t tempref = 0;
229

    
230
        while ( c < l - 6){
231
                if (buf[c] == 0x00 && 
232
                    buf[c+1] == 0x00 &&
233
                    buf[c+2] == 0x01 && 
234
                    buf[c+3] == 0xB8) {
235
                        c += 4;
236
                        hour = (int)((buf[c]>>2)& 0x1F);
237
                        min  = (int)(((buf[c]<<4)& 0x30)| 
238
                                     ((buf[c+1]>>4)& 0x0F));
239
                        sec  = (int)(((buf[c+1]<<3)& 0x38)|
240
                                      ((buf[c+2]>>5)& 0x07));
241
  
242
                        time = 3600*hour + 60*min + sec;
243
                        if ( rem->time_off){
244
                                time = (uint32_t)((u64)time - rem->time_off);
245
                                hour = time/3600;
246
                                min  = (time%3600)/60;
247
                                sec  = (time%3600)%60;
248
                                /*
249
                                buf[c]   |= (hour & 0x1F) << 2;
250
                                buf[c]   |= (min & 0x30) >> 4;
251
                                buf[c+1] |= (min & 0x0F) << 4;
252
                                buf[c+1] |= (sec & 0x38) >> 3;
253
                                buf[c+2] |= (sec & 0x07) >> 5;*/
254
                        }
255
                        rem->group++;
256
                        rem->groupframe = 0;
257
                }
258
                if ( buf[c] == 0x00 && 
259
                     buf[c+1] == 0x00 &&
260
                     buf[c+2] == 0x01 && 
261
                     buf[c+3] == 0x00) {
262
                        c += 4;
263
                        tempref = (buf[c+1]>>6) & 0x03;
264
                        tempref |= buf[c] << 2;
265
                        
266
                        type = ((buf[c+1]&0x38) >>3);
267
                        if ( rem->video_info.framerate){
268
                                pts = ((u64)rem->vframe + tempref + 1 
269
                                        - rem->groupframe ) * 90000ULL
270
                                            /rem->video_info.framerate 
271
                                        + rem->vpts_off;
272
                                dts = (u64)rem->vframe * 90000ULL/
273
                                        rem->video_info.framerate 
274
                                        + rem->vpts_off;
275
                        
276
                                /*        
277
fprintf(stderr,"MYPTS:");
278
printpts((uint32_t)pts-rem->vpts_off);
279
 fprintf(stderr,"   REALPTS:");
280
 printpts(rem->vpts_list[rem->vptsn-1].PTS-rem->vpts_off);
281
 fprintf(stderr,"   DIFF:");
282
 printpts(pts-(u64)rem->vpts_list[rem->vptsn-1].PTS);
283
 fprintf(stderr,"   DIST: %4d",-rem->vpts_list[rem->vptsn-1].pos+(rem->vwrite+c-4));
284
 //fprintf(stderr,"   ERR: %3f",(double)(-rem->vpts_list[rem->vptsn-1].PTS+pts)/(rem->vframe+1));
285
 fprintf(stderr,"\r");
286
                                */
287
                                
288
                                
289
                                rem->vptsn = add_pts(rem->vpts_list,(uint32_t)pts
290
                                                     ,rem->vwrite+c-4,
291
                                                     rem->awrite,
292
                                                     rem->vptsn,
293
                                                     (uint32_t)dts);
294

    
295
                                
296
                                
297
                        }
298
                        rem->vframe++;
299
                        rem->groupframe++;
300
                        add_vframe( rem, rem->vframe, rem->vwrite+c, type, 
301
                                    time, pts, dts);
302
                } else c++;
303
        }
304
}
305

    
306
void find_aframes( Remux *rem, uint8_t *buf, int l)
307
{
308
         int c = 0;
309
        u64 pts = 0;
310
        int sam;
311
        uint32_t fr;
312

    
313

    
314
        while ( c < l - 2){
315
                if ( buf[c] == 0xFF && 
316
                     (buf[c+1] & 0xF8) == 0xF8) {
317
                        c += 2;
318
                        if ( rem->audio_info.layer >= 0){
319
                                sam = samples[3-rem->audio_info.layer];
320
                                fr = freq[rem->audio_info.frequency] ;
321
                
322
                          pts = ( (u64)rem->aframe * sam * 900ULL)/fr
323
                                  + rem->apts_off;
324
                                
325
                          /*            
326
fprintf(stderr,"MYPTS:");
327
printpts((uint32_t)pts-rem->apts_off);
328
 fprintf(stderr," REALPTS:");
329
 printpts(rem->apts_list[rem->aptsn-1].PTS-rem->apts_off);
330
 fprintf(stderr," DIFF:");
331
 printpts((uint32_t)((u64)rem->apts_list[rem->aptsn-1].PTS-pts));
332
 fprintf(stderr," DIST: %4d",-rem->apts_list[rem->aptsn-1].pos+(rem->awrite+c-2));
333
 fprintf(stderr,"\r");
334
                          */
335
                          rem->aptsn = add_pts(rem->apts_list,(uint32_t)pts
336
                                             ,rem->awrite+c-2,
337
                                             rem->vwrite,
338
                                             rem->aptsn,
339
                                             (uint32_t)pts);
340
                }
341

    
342
                        rem->aframe++;
343
                        add_aframe( rem, rem->aframe, rem->awrite+c, pts);
344
                        
345
                } else c++;
346
        }
347
}
348

    
349
int refill_buffy(Remux *rem)
350
{
351
        pes_packet pes;
352
        int count = 0;
353
        int acount, vcount;
354
        ringbuffy *vbuf = &rem->vid_buffy;
355
        ringbuffy *abuf = &rem->aud_buffy;
356
        int fin = rem->fin;
357

    
358
        acount = abuf->size-ring_rest(abuf);
359
        vcount = vbuf->size-ring_rest(vbuf);
360
        
361
        
362
        while ( acount > MAX_PLENGTH && vcount > MAX_PLENGTH && count < 10){
363
                int neof;
364
                count++;
365
                init_pes(&pes);
366
                if ((neof = read_pes(fin,&pes)) <= 0) return -1;
367
                switch(pes.stream_id){
368
                case AUDIO_STREAM_S ... AUDIO_STREAM_E:
369
                        rem->apes++;
370
                        if( rem->audio_info.layer < 0 &&
371
                            (pes.flags2 & PTS_DTS) )
372
                                add_apts(rem, pes.pts);
373
                        find_aframes( rem, pes.pes_pckt_data, pes.length);
374
                        ring_write(abuf,(char *)pes.pes_pckt_data,pes.length);
375
                        rem->awrite += pes.length;
376
                        break;
377
                case VIDEO_STREAM_S ... VIDEO_STREAM_E:
378
                        rem->vpes++;
379
                        if( !rem->video_info.framerate &&
380
                            (pes.flags2 & PTS_DTS) )
381
                                add_vpts(rem, pes.pts);
382

    
383
                        find_vframes( rem, pes.pes_pckt_data, pes.length);
384

    
385
                        ring_write(vbuf,(char *)pes.pes_pckt_data,pes.length);
386
                        rem->vwrite += pes.length;
387
                        break;
388
                }
389
                acount = abuf->size-ring_rest(abuf);
390
                vcount = vbuf->size-ring_rest(vbuf);
391
                kill_pes(&pes);
392
        }
393
        if (count < 10)        return 0;
394
        return 1;
395
}
396

    
397
int vring_read( Remux *rem, uint8_t *buf, int l)
398
{
399
        int c = 0;
400
        int r = 0;
401

    
402
        if (ring_rest(&rem->vid_buffy) <= l)
403
                r = refill_buffy(rem);
404
        if (r) return -1;
405

    
406
        c = ring_read(&rem->vid_buffy, (char *) buf, l);
407
        rem->vread += c;
408
        del_vpts(rem);
409
        del_vframe(rem);
410
        return c;
411
}
412

    
413
int aring_read( Remux *rem, uint8_t *buf, int l)
414
{
415
        int c = 0;
416
        int r = 0;
417

    
418
        if (ring_rest(&rem->aud_buffy) <= l)
419
                r = refill_buffy(rem);
420
        if (r) return -1;
421
        
422
        c = ring_read(&rem->aud_buffy, (char *)buf, l);
423
        rem->aread += c;
424
        del_apts(rem);
425
        del_aframe(rem);
426
        return c;
427
}
428

    
429
int vring_peek( Remux *rem, uint8_t *buf, int l, long off)
430
{
431
        int c = 0;
432
        
433
        if (ring_rest(&rem->vid_buffy) <= l)
434
                refill_buffy(rem);
435

    
436
        c = ring_peek(&rem->vid_buffy, (char *) buf, l, off);
437
        return c;
438
}
439

    
440
int aring_peek( Remux *rem, uint8_t *buf, int l, long off)
441
{
442
        int c = 0;
443

    
444
        if (ring_rest(&rem->aud_buffy) <= l)
445
                refill_buffy(rem);
446

    
447
        c = ring_peek(&rem->aud_buffy, (char *)buf, l, off);
448
        return c;
449
}
450

    
451

    
452
int get_video_info(Remux *rem)
453
{
454
        uint8_t buf[12];
455
        uint8_t *headr;
456
        int found = 0;
457
        int sw;
458
        long off = 0;
459
        int form = -1;
460
        ringbuffy *vid_buffy = &rem->vid_buffy;
461
        VideoInfo *vi = &rem->video_info;
462

    
463
        while (found < 4 && ring_rest(vid_buffy)){
464
                uint8_t b[3];
465

    
466
                vring_peek( rem, b, 4, 0);
467
                if ( b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01
468
                     && b[3] == 0xb3) found = 4;
469
                else {
470
                        off++;
471
                        vring_read( rem, b, 1);
472
                }
473
        }
474
        rem->vframe = rem->vframen-1;
475

    
476
        if (! found) return -1;
477
        buf[0] = 0x00; buf[1] = 0x00; buf[2] = 0x01; buf[3] = 0xb3;
478
        headr = buf+4;
479
        if(vring_peek(rem, buf, 12, 0) < 12) return -1;
480

    
481
        vi->horizontal_size        = ((headr[1] &0xF0) >> 4) | (headr[0] << 4);
482
        vi->vertical_size        = ((headr[1] &0x0F) << 8) | (headr[2]);
483
    
484
        sw = (int)((headr[3]&0xF0) >> 4) ;
485

    
486
        switch( sw ){
487
        case 1:
488
                fprintf(stderr,"Videostream: ASPECT: 1:1");
489
                vi->aspect_ratio = 100;        
490
                break;
491
        case 2:
492
                fprintf(stderr,"Videostream: ASPECT: 4:3");
493
                vi->aspect_ratio = 133;        
494
                break;
495
        case 3:
496
                fprintf(stderr,"Videostream: ASPECT: 16:9");
497
                vi->aspect_ratio = 177;        
498
                break;
499
        case 4:
500
                fprintf(stderr,"Videostream: ASPECT: 2.21:1");
501
                vi->aspect_ratio = 221;        
502
                break;
503

    
504
        case 5 ... 15:
505
                fprintf(stderr,"Videostream: ASPECT: reserved");
506
                vi->aspect_ratio = 0;        
507
                break;
508

    
509
        default:
510
                vi->aspect_ratio = 0;        
511
                return -1;
512
        }
513

    
514
        fprintf(stderr,"  Size = %dx%d",vi->horizontal_size,vi->vertical_size);
515

    
516
        sw = (int)(headr[3]&0x0F);
517

    
518
        switch ( sw ) {
519
        case 1:
520
                fprintf(stderr,"  FRate: 23.976 fps");
521
                vi->framerate = 24000/1001.;
522
                form = -1;
523
                break;
524
        case 2:
525
                fprintf(stderr,"  FRate: 24 fps");
526
                vi->framerate = 24;
527
                form = -1;
528
                break;
529
        case 3:
530
                fprintf(stderr,"  FRate: 25 fps");
531
                vi->framerate = 25;
532
                form = VIDEO_MODE_PAL;
533
                break;
534
        case 4:
535
                fprintf(stderr,"  FRate: 29.97 fps");
536
                vi->framerate = 30000/1001.;
537
                form = VIDEO_MODE_NTSC;
538
                break;
539
        case 5:
540
                fprintf(stderr,"  FRate: 30 fps");
541
                vi->framerate = 30;
542
                form = VIDEO_MODE_NTSC;
543
                break;
544
        case 6:
545
                fprintf(stderr,"  FRate: 50 fps");
546
                vi->framerate = 50;
547
                form = VIDEO_MODE_PAL;
548
                break;
549
        case 7:
550
                fprintf(stderr,"  FRate: 60 fps");
551
                vi->framerate = 60;
552
                form = VIDEO_MODE_NTSC;
553
                break;
554
        }
555

    
556
        rem->dts_delay = (int)(7.0/vi->framerate/2.0*90000);
557

    
558
        vi->bit_rate = 400*(((headr[4] << 10) & 0x0003FC00UL) 
559
                            | ((headr[5] << 2) & 0x000003FCUL) | 
560
                            (((headr[6] & 0xC0) >> 6) & 0x00000003UL));
561
        
562
        fprintf(stderr,"  BRate: %.2f Mbit/s",(vi->bit_rate)/1000000.);
563
        
564
        fprintf(stderr,"\n");
565
        vi->video_format = form;
566

    
567
        /*
568
        marker_bit (&video_bs, 1);
569
        vi->vbv_buffer_size        = getbits (&video_bs, 10);
570
        vi->CSPF                = get1bit (&video_bs);
571
        */
572
        return form;
573
}
574

    
575

    
576
int get_audio_info( Remux *rem)
577
{
578
        uint8_t *headr;
579
        uint8_t buf[3];
580
        long off = 0;
581
        int found = 0;
582
        ringbuffy *aud_buffy = &rem->aud_buffy;
583
        AudioInfo *ai = &rem->audio_info;
584
        
585
        while(!ring_rest(aud_buffy) && !refill_buffy(rem));
586
        while (found < 2 && ring_rest(aud_buffy)){
587
                uint8_t b[2];
588
                refill_buffy(rem);
589
                aring_peek( rem, b, 2, 0);
590

    
591
                if ( b[0] == 0xff && (b[1] & 0xf8) == 0xf8)
592
                        found = 2;
593
                else {
594
                        off++;
595
                        aring_read( rem, b, 1);
596
                }
597
        }        
598

    
599
        if (!found) return -1;
600
        rem->aframe = rem->aframen-1;
601
        
602
        if (aring_peek(rem, buf, 3, 0) < 1) return -1;
603
        headr = buf+2;
604

    
605
        ai->layer = (buf[1] & 0x06) >> 1;
606

    
607
        fprintf(stderr,"Audiostream: Layer: %d", 4-ai->layer);
608

    
609

    
610
        ai->bit_rate = bitrates[(3-ai->layer)][(headr[0] >> 4 )]*1000;
611

    
612
        if (ai->bit_rate == 0)
613
                fprintf (stderr,"  Bit rate: free");
614
        else if (ai->bit_rate == 0xf)
615
                fprintf (stderr,"  BRate: reserved");
616
        else
617
                fprintf (stderr,"  BRate: %d kb/s", ai->bit_rate/1000);
618
        
619

    
620
        ai->frequency = (headr[0] & 0x0c ) >> 2;
621
        if (ai->frequency == 3)
622
                fprintf (stderr, "  Freq: reserved\n");
623
        else
624
                fprintf (stderr,"  Freq: %2.1f kHz\n", 
625
                         freq[ai->frequency]/10.);
626

    
627
        return 0;
628
}
629

    
630

    
631

    
632
void init_remux(Remux *rem, int fin, int fout, int mult)
633
{
634
        rem->video_info.framerate = 0;
635
        rem->audio_info.layer = -1;
636
        rem->fin = fin;
637
        rem->fout = fout;
638
        ring_init(&rem->vid_buffy, 40*BUFFYSIZE*mult);
639
        ring_init(&rem->aud_buffy, BUFFYSIZE*mult);
640
        init_ptsl(rem->vpts_list);
641
        init_ptsl(rem->apts_list);
642
        init_framel(rem->vframe_list);
643
        init_framel(rem->aframe_list);
644

    
645
        rem->vptsn     = 0;
646
        rem->aptsn     = 0;
647
        rem->vframen   = 0;
648
        rem->aframen   = 0;
649
        rem->vframe    = 0;
650
        rem->aframe    = 0;
651
        rem->vcframe   = 0;
652
        rem->acframe   = 0;
653
        rem->vpts      = 0;
654
        rem->vdts      = 0;
655
        rem->apts_off  = 0;
656
        rem->vpts_off  = 0;
657
        rem->apts_delay= 0;
658
        rem->vpts_delay= 0;
659
        rem->dts_delay = 0;
660
        rem->apts      = 0;
661
        rem->vpes      = 0;
662
        rem->apes      = 0;
663
        rem->vpts_old  = 0;
664
        rem->apts_old  = 0;
665
        rem->SCR       = 0;
666
        rem->vwrite    = 0;
667
        rem->awrite    = 0;
668
        rem->vread     = 0;
669
        rem->aread     = 0;
670
        rem->group     = 0;
671
        rem->groupframe= 0;
672
        rem->pack_size = 0;
673
        rem->muxr      = 0;
674
        rem->time_off  = 0;
675
}
676

    
677
uint32_t bytes2pts(int bytes, int rate)
678
{
679
        if (bytes < 0xFFFFFFFFUL/720000UL)
680
                return (uint32_t)(bytes*720000UL/rate);
681
        else
682
                return (uint32_t)(bytes/rate*720000UL);
683
}
684

    
685
long pts2bytes( uint32_t pts, int rate)
686
{
687
        if (pts < 0xEFFFFFFFUL/rate)
688
                return (pts*rate/720000);
689
        else 
690
                return (pts* (rate/720000));
691
}
692

    
693
int write_audio_pes( Remux *rem, uint8_t *buf, int *alength)
694
{
695
        int add;
696
        int pos = 0;
697
        int p   = 0;
698
        uint32_t pts = 0;
699
        int stuff = 0;
700
        int length = *alength;
701

    
702
        if (!length) return 0;
703
        p = PS_HEADER_L1+PES_H_MIN;
704

    
705
        if (rem->apts_old != rem->apts){
706
                pts = (uint32_t)((u64)rem->apts + rem->apts_delay - rem->apts_off);
707
                p += 5;
708
        }
709
        if ( length+p >= rem->pack_size){
710
                length = rem->pack_size;
711
        } else {
712
                if (rem->pack_size-length-p <= PES_MIN){
713
                        stuff = rem->pack_size - length;
714
                        length = rem->pack_size;
715
                } else 
716
                        length = length+p;
717
        }
718
        pos = write_ps_header(buf,rem->SCR,rem->muxr, 1, 0, 0, 1, 1, 1, 
719
                              0, 0, 0, 0, 0, 0);
720

    
721
        pos += write_pes_header( 0xC0, length-pos, pts, buf+pos, stuff);
722
        add = aring_read( rem, buf+pos, length-pos);
723
        *alength = add;
724
        if (add < 0) return -1;
725
        pos += add;
726
        rem->apts_old = rem->apts;
727
        rem->apts = rem->apts_list[0].PTS;
728

    
729
        if (pos+PES_MIN < rem->pack_size){
730
                pos += write_pes_header( PADDING_STREAM, rem->pack_size-pos, 0,
731
                                         buf+pos, 0);
732
                pos = rem->pack_size;
733
        }                
734
        if (pos != rem->pack_size) {
735
                fprintf(stderr,"apos: %d\n",pos);
736
                exit(1);
737
        }
738

    
739
        return pos;
740
}
741

    
742
int write_video_pes( Remux *rem, uint8_t *buf, int *vlength)
743
{
744
        int add;
745
        int pos = 0;
746
        int p   = 0;
747
        uint32_t pts = 0;
748
        uint32_t dts = 0;
749
        int stuff = 0;
750
        int length = *vlength;
751
        long diff = 0;
752

    
753
        if (! length) return 0;
754
        p = PS_HEADER_L1+PES_H_MIN;
755

    
756
        if (rem->vpts_old != rem->vpts){
757
                pts = (uint32_t)((u64)rem->vpts + rem->vpts_delay - rem->vpts_off);
758
                p += 5;
759
        }
760
        if ( length+p >= rem->pack_size){
761
                length = rem->pack_size;
762
        } else {
763
                if (rem->pack_size - length - p <= PES_MIN){
764
                        stuff = rem->pack_size - length;
765
                        length = rem->pack_size;
766
                } else 
767
                        length = length+p;
768
        }
769

    
770
        pos = write_ps_header(buf,rem->SCR,rem->muxr, 1, 0, 0, 1, 1, 1, 
771
                              0, 0, 0, 0, 0, 0);
772

    
773
        pos += write_pes_header( 0xE0, length-pos, pts, buf+pos, stuff);
774
        add = vring_read( rem, buf+pos, length-pos);
775
        *vlength = add;
776
        if (add < 0) return -1;
777
        pos += add;
778
        rem->vpts_old = rem->vpts;
779
        dts = rem->vdts;
780
        rem->vpts = rem->vpts_list[0].PTS;
781
        rem->vdts = rem->vpts_list[0].dts;
782
        if ( diff > 0) rem->SCR += diff;
783
        if (pos+PES_MIN < rem->pack_size){
784
                //  fprintf(stderr,"vstuffing: %d   \n",rem->pack_size-pos);
785
                pos += write_pes_header( PADDING_STREAM, rem->pack_size-pos, 0,
786
                                         buf+pos, 0);
787
                pos = rem->pack_size;
788
        }                
789
        return pos;
790
}
791

    
792
void print_info( Remux *rem , int ret)
793
{
794
        int newtime = 0;
795
        static int time = 0;
796
        int i = 0;
797

    
798
        while(! newtime && i < rem->vframen) {
799
                if( (newtime = rem->vframe_list[i].time)) break;
800
                i++;
801
        }
802
        if (newtime) time = newtime;
803
        
804
        fprintf(stderr,"SCR:");
805
        printpts(rem->SCR);
806
        fprintf(stderr," VDTS:");
807
        printpts((uint32_t)((u64)rem->vdts - rem->vpts_off + rem->vpts_delay));
808
        fprintf(stderr," APTS:");
809
        printpts((uint32_t)((u64)rem->apts - rem->apts_off + rem->apts_delay));
810
        fprintf(stderr," TIME:%2d:", time/3600);
811
        fprintf(stderr,"%02d:", (time%3600)/60);
812
        fprintf(stderr,"%02d", (time%3600)%60);
813
        if (ret) fprintf(stderr,"\n");
814
        else fprintf(stderr,"\r");
815
}
816

    
817
void remux(int fin, int fout, int pack_size, int mult)
818
{
819
        Remux rem;
820
        long ptsdiff;
821
        uint8_t buf[MAX_PACK_L];
822
        long pos = 0;
823
        int r = 0;
824
        int i, r1, r2;
825
        long packets = 0;
826
        uint8_t mpeg_end[4] = { 0x00, 0x00, 0x01, 0xB9 };
827
        uint32_t SCR_inc = 0;
828
        int data_size;
829
        long vbuf, abuf;
830
        long vbuf_max, abuf_max;
831
        PTS_List abufl[MAX_PTS];
832
        PTS_List vbufl[MAX_PTS];
833
        int abufn = 0;
834
        int vbufn = 0;
835
        u64 pts_d = 0;
836
        int ok_audio; 
837
        int ok_video; 
838
        uint32_t apos = 0;
839
        uint32_t vpos = 0;
840
        int vpack_size = 0;
841
        int apack_size = 0;
842

    
843
        init_ptsl(abufl);
844
        init_ptsl(vbufl);
845

    
846
        init_remux(&rem, fin, fout, mult);
847
        rem.pack_size = pack_size;
848
        data_size = pack_size - MAX_H_SIZE;
849
        fprintf(stderr,"pack_size: %d header_size: %d data size: %d\n",
850
                pack_size, MAX_H_SIZE, data_size);
851
        refill_buffy(&rem);
852
        fprintf(stderr,"Package size: %d\n",pack_size);
853
        
854
        if ( get_video_info(&rem) < 0 ){
855
                fprintf(stderr,"ERROR: Can't find valid video stream\n");
856
                exit(1);
857
        }
858

    
859
        i = 0;
860
        while(! rem.time_off && i < rem.vframen) {
861
                if( (rem.time_off = rem.vframe_list[i].time)) break;
862
                i++;
863
        }
864

    
865
        if ( get_audio_info(&rem) < 0 ){
866
                fprintf(stderr,"ERROR: Can't find valid audio stream\n");
867
                exit(1);
868
        }
869
        
870
        rem.vpts = rem.vpts_list[0].PTS;
871
        rem.vdts = rem.vpts;
872
        rem.vpts_off = rem.vpts;
873
        fprintf(stderr,"Video start PTS = %fs \n",rem.vpts_off/90000.);
874
        rem.apts = rem.apts_list[0].PTS;
875
        rem.apts_off = rem.apts;
876
        ptsdiff = rem.vpts - rem.apts;
877
        if (ptsdiff > 0) rem.vpts_off -= ptsdiff;
878
        else rem.apts_off -= -ptsdiff;
879
        fprintf(stderr,"Audio start PTS = %fs\n",rem.apts_off/90000.);
880
        fprintf(stderr,"Difference Video - Audio = %fs\n",ptsdiff/90000.);
881
        fprintf(stderr,"Time offset = %ds\n",rem.time_off);
882

    
883
        rem.muxr = (rem.video_info.bit_rate + 
884
                    rem.audio_info.bit_rate)/400;
885
        fprintf(stderr,"MUXRATE: %.2f Mb/sec\n",rem.muxr/2500.);
886
        SCR_inc = 1800 * pack_size / rem.muxr;
887
        
888
        r = 0;
889
        while ( rem.vptsn < 2 && !r) r = refill_buffy(&rem);
890
        r = 0;
891
        while ( rem.aptsn < 2 && !r) r = refill_buffy(&rem);
892

    
893
        //rem.vpts_delay =  (uint32_t)(2*90000ULL* (u64)pack_size/rem.muxr);
894
        rem.vpts_delay = rem.dts_delay;
895
        rem.apts_delay = rem.vpts_delay;
896

    
897
        vbuf_max = 29440;
898
        abuf_max = 4096;
899
        vbuf = 0;
900
        abuf = 0;
901
        pos = write_ps_header(buf,rem.SCR,rem.muxr, 1, 0, 0, 1, 1, 1, 
902
                              0xC0, 0, 32, 0xE0, 1, 230);
903
        pos += write_pes_header( PADDING_STREAM, pack_size-pos, 0, buf+pos,0);
904
        pos = rem.pack_size;
905
        write( fout, buf, pos);
906

    
907
        apos = rem.aread;
908
        vpos = rem.vread;
909
        print_info( &rem, 1 );
910

    
911
        while( ring_rest(&rem.aud_buffy) && ring_rest(&rem.vid_buffy) ){
912
                uint32_t next_apts;
913
                uint32_t next_vdts;
914
                int asize, vsize;
915

    
916
                r1 = 0;
917
                r2 = 0;
918
                while ( rem.aframen < 2 && !r1) 
919
                        r1 = refill_buffy(&rem);
920
                while ( rem.vframen < 2 && !r2) 
921
                        r2 = refill_buffy(&rem);
922
                if (r1 && r2) break;
923

    
924
                if ( !r1 && apos <= rem.aread)
925
                        apos = rem.aframe_list[1].pos;
926
                if ( !r2 && vpos <= rem.vread)
927
                        vpos = rem.vframe_list[1].pos;
928
                apack_size = apos - rem.aread; 
929
                vpack_size = vpos - rem.vread; 
930
                
931

    
932
                next_vdts = (uint32_t)((u64)rem.vdts + rem.vpts_delay 
933
                                  - rem.vpts_off) ;
934
                ok_video = ( rem.SCR < next_vdts);
935

    
936
                next_apts = (uint32_t)((u64)rem.apts + rem.apts_delay 
937
                                  - rem.apts_off) ;
938
                ok_audio = ( rem.SCR  < next_apts);
939

    
940
                asize = (apack_size > data_size ? data_size: apack_size);
941
                vsize = (vpack_size > data_size ? data_size: vpack_size);
942

    
943
                fprintf(stderr,"vframen: %d  aframen: %d  v_ok: %d  a_ok: %d  v_buf: %d  a_buf: %d vpacks: %d  apacks: %d\n",rem.vframen,rem.aframen, ok_video, ok_audio, (int)vbuf,(int)abuf,vsize, asize);
944
                
945

    
946
                if( vbuf+vsize  < vbuf_max && vsize && ok_audio ){
947
                        fprintf(stderr,"1 ");
948
                        pos = write_video_pes( &rem, buf, &vpack_size);
949
                        write( fout, buf, pos);
950
                        vbuf += vpack_size;
951
                        vbufn = add_pts( vbufl, rem.vdts, vpack_size, 
952
                                         0, vbufn, 0);
953
                        packets++;
954
                } else if ( abuf+asize < abuf_max && asize &&
955
                            ok_video  ){
956
                        fprintf(stderr,"2 ");
957
                        pos = write_audio_pes( &rem, buf, &apack_size);
958
                        write( fout, buf, pos);
959
                        abuf += apack_size;
960
                        abufn = add_pts( abufl, rem.apts, apack_size, 
961
                                         0, abufn, 0);
962
                        packets++;
963
                } else if ( abuf+asize < abuf_max && asize &&
964
                            !ok_audio){
965
                        fprintf(stderr,"3 ");
966
                        pos = write_audio_pes( &rem, buf, &apack_size);
967
                        write( fout, buf, pos);
968
                        abuf += apack_size;
969
                        abufn = add_pts( abufl, rem.apts, apack_size, 
970
                                         0, abufn, 0);
971
                        packets++;
972
                } else if (vbuf+vsize  < vbuf_max && vsize &&
973
                           !ok_video){
974
                        fprintf(stderr,"4 ");
975
                        pos = write_video_pes( &rem, buf, &vpack_size);
976
                        write( fout, buf, pos);
977
                        vbuf += vpack_size;
978
                        vbufn = add_pts( vbufl, rem.vdts, vpack_size, 
979
                                         0, vbufn, 0);
980
                        packets++;
981
                } else {
982
                fprintf(stderr,"5 ");
983
                        pos = write_ps_header(buf,rem.SCR,rem.muxr, 1, 0, 0, 
984
                                              1, 1, 1, 0, 0, 0, 0, 0, 0);
985

    
986
                        pos += write_pes_header( PADDING_STREAM, pack_size-pos,
987
                                                 0, buf+pos, 0);
988
                        write( fout, buf, pos);
989
                }
990

    
991

    
992
                //fprintf(stderr,"vbufn: %d  abufn: %d  ", vbufn,abufn);
993
                //fprintf(stderr,"vbuf: %5d  abuf: %4d\n", vbuf,abuf);
994

    
995
                if (rem.SCR > rem.vdts+rem.vpts_off -rem.vpts_delay) 
996
                        rem.SCR = rem.vdts-rem.vpts_off;
997
                rem.SCR = (uint32_t)((u64) rem.SCR + SCR_inc);
998

    
999
                if ( rem.apts_off + rem.SCR < rem.apts_delay ) pts_d = 0;
1000
                else pts_d = (u64) rem.SCR + rem.apts_off - rem.apts_delay;
1001
                abuf -= del_ptss( abufl, (uint32_t) pts_d, &abufn);
1002

    
1003
                if ( rem.vpts_off + rem.SCR < rem.vpts_delay ) pts_d = 0;
1004
                else pts_d = (u64) rem.SCR + rem.vpts_off - rem.vpts_delay;
1005
                vbuf -= del_ptss( vbufl, (uint32_t) pts_d, &vbufn);
1006

    
1007
                print_info( &rem, 1);
1008
                //fprintf(stderr,"vbufn: %d  abufn: %d  ", vbufn,abufn);
1009
                //fprintf(stderr,"vbuf: %5d  abuf: %4d\n\n", vbuf,abuf);
1010

    
1011

    
1012
        }
1013
        pos = write_ps_header(buf,rem.SCR,rem.muxr, 1, 0, 0, 1, 1, 1, 
1014
                              0, 0, 0, 0, 0, 0);
1015

    
1016
        pos += write_pes_header( PADDING_STREAM, pack_size-pos-4, 0, 
1017
                                 buf+pos, 0);
1018
        pos = rem.pack_size-4;
1019
        write( fout, buf, pos);
1020

    
1021
        write( fout, mpeg_end, 4);
1022
        fprintf(stderr,"\ndone\n");
1023
}
1024

    
1025

    
1026
typedef 
1027
struct pes_buffer_s{
1028
        ringbuffy   pes_buffy;
1029
        uint8_t     type;
1030
        PTS_List    pts_list[MAX_PTS];
1031
        FRAME_List  frame_list[MAX_FRAME];
1032
        int         pes_size;
1033
        uint64_t    written;
1034
        uint64_t    read;
1035
} PESBuffer;
1036

    
1037

    
1038
void init_PESBuffer(PESBuffer *pbuf, int pes_size, int buf_size, uint8_t type)
1039
{
1040
        init_framel( pbuf->frame_list);
1041
        init_ptsl( pbuf->pts_list);
1042
        ring_init( &pbuf->pes_buffy, buf_size);
1043
        pbuf->pes_size = pes_size;
1044
        pbuf->type = type; 
1045
        pbuf->written = 0;
1046
        pbuf->read = 0;
1047
}
1048
        
1049

    
1050
#define MAX_PBUF 4
1051

    
1052
typedef
1053
struct remux_s{
1054
        PESBuffer pbuf_list[MAX_PBUF];
1055
        int num_pbuf;
1056
} REMUX;
1057

    
1058

    
1059
void init_REMUX(REMUX *rem)
1060
{
1061
        rem->num_pbuf = 0;
1062
}
1063

    
1064

    
1065

    
1066
#define REPACK      2048 
1067
#define ABUF_SIZE   REPACK*1024
1068
#define VBUF_SIZE   REPACK*10240
1069

    
1070
void remux_main(uint8_t *buf, int count, p2p *p)
1071
{
1072
        int i, b;
1073
        int bufsize = 0;
1074
        PESBuffer *pbuf;
1075
        REMUX *rem = (REMUX *) p->data;
1076
        uint8_t type = buf[3];
1077
        int *npbuf = &(rem->num_pbuf);
1078

    
1079
        switch ( type ){
1080
        case PRIVATE_STREAM1:
1081
                bufsize = ABUF_SIZE;
1082
        case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1083
                if (!bufsize) bufsize = VBUF_SIZE;
1084
        case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1085
                if (!bufsize) bufsize = ABUF_SIZE;
1086
                b = -1;
1087
                for ( i = 0; i < *npbuf; i++){
1088
                        if ( type == rem->pbuf_list[i].type ){
1089
                                b = i;
1090
                                break;
1091
                        }
1092
                }
1093
                if (b < 0){
1094
                        if ( *npbuf < MAX_PBUF ){
1095
                                init_PESBuffer(&rem->pbuf_list[*npbuf], 
1096
                                               p->repack+6, bufsize, type);
1097
                                b = *npbuf;
1098
                                (*npbuf)++;
1099
                        } else {
1100
                                fprintf(stderr,"Not enough PES buffers\n");
1101
                                exit(1);
1102
                        }
1103
                }
1104
                break;
1105
        default:
1106
                return;
1107
        }
1108
        
1109
        pbuf = &(rem->pbuf_list[b]);
1110
        if (ring_write(&(pbuf->pes_buffy),(char *)buf,count) != count){
1111
                fprintf(stderr,"buffer overflow type 0x%2x\n",type);
1112
                exit(1);
1113
        } else {
1114
                pbuf->written += count;
1115
                if ((p->flag2 & PTS_DTS_FLAGS)){
1116
                        uint32_t PTS = ntohl(trans_pts_dts(p->pts));
1117
                        add_pts(pbuf->pts_list, PTS, pbuf->written, 
1118
                                pbuf->written, 0, 0);
1119
                }
1120
                p->flag2 = 0;
1121
        }
1122

    
1123
}
1124

    
1125
void output_mux(p2p *p) 
1126
{
1127
        int i, filling;
1128
        PESBuffer *pbuf;
1129
        ringbuffy   *pes_buffy;        
1130
        REMUX *rem = (REMUX *) p->data;
1131
        int repack = p->repack;
1132
        int npbuf = rem->num_pbuf;
1133

    
1134
        for ( i = 0; i < npbuf; i++){
1135
                pbuf = &(rem->pbuf_list[i]);
1136
                pes_buffy = &pbuf->pes_buffy;
1137
                filling = pes_buffy->size - ring_rest(pes_buffy);
1138
                if (filling/(2 *repack)){
1139
                        pbuf->read += ring_read_file(pes_buffy, p->fd1, 
1140
                                                     (filling/repack)*repack);
1141
                }
1142
        }
1143
}
1144

    
1145

    
1146

    
1147
#define SIZE 32768
1148

    
1149
void remux2(int fdin, int fdout)
1150
{
1151
        p2p p;
1152
        int count = 1;
1153
        uint8_t buf[SIZE];
1154
        uint64_t length = 0;
1155
        uint64_t l = 0;
1156
        int verb = 0;
1157
        REMUX rem;
1158
        
1159
        init_p2p(&p, remux_main, REPACK);
1160
        p.fd1 = fdout;
1161
        p.data = (void *) &rem;
1162
        
1163

    
1164
        if (fdin != STDIN_FILENO) verb = 1; 
1165

    
1166
        if (verb) {
1167
                length = lseek(fdin, 0, SEEK_END);
1168
                lseek(fdin,0,SEEK_SET);
1169
        }
1170

    
1171
        while (count > 0){
1172
                count = read(fdin,buf,SIZE);
1173
                l += count;
1174
                if (verb)
1175
                        fprintf(stderr,"Writing  %2.2f %%\r",
1176
                                100.*l/length);
1177

    
1178
                get_pes(buf,count,&p,pes_repack);
1179
                output_mux(&p);
1180
        }
1181
                
1182
}