1 /*
2 * replex.c
3 *
4 *
5 * Copyright (C) 2003 - 2006
6 * Marcus Metzler <mocm@metzlerbros.de>
7 * Metzler Brothers Systementwicklung GbR
8 * (C) 2006 Reel Multimedia
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * General Public License for more details.
20 *
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
26 *
27 */
28 //#define IN_DEBUG
29
30
31 #include <stdlib.h>
32 #include <getopt.h>
33 #include <stdio.h>
34 #include <inttypes.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <fcntl.h>
38 #include <string.h>
39 #include <unistd.h>
40
41 #include "replex.h"
42 #include "pes.h"
43
44 static int replex_all_set(struct replex *rx);
45
overflow_exit(struct replex * rx)46 void overflow_exit(struct replex *rx)
47 {
48 rx->overflows++;
49
50 if (rx->max_overflows &&
51 rx->overflows > rx->max_overflows){
52 fprintf(stderr,"exiting after %d overflows last video PTS: ", rx->overflows);
53 printpts(rx->last_vpts);
54 fprintf(stderr,"\n");
55 exit(1);
56 }
57 }
58
replex_check_id(struct replex * rx,uint16_t id)59 int replex_check_id(struct replex *rx, uint16_t id)
60 {
61 int i;
62
63 if (id==rx->vpid)
64 return 0;
65
66 for (i=0; i<rx->apidn; i++)
67 if (id==rx->apid[i])
68 return i+1;
69
70 for (i=0; i<rx->ac3n; i++)
71 if (id==rx->ac3_id[i])
72 return i+0x80;
73
74 return -1;
75 }
76
77
audio_jump(struct replex * rx)78 static int audio_jump(struct replex *rx)
79 {
80 int i;
81
82 for (i=0; i<rx->apidn; i++)
83 if (rx->audio_jump[i])
84 return 1;
85
86 for (i=0; i<rx->ac3n; i++)
87 if (rx->ac3_jump[i])
88 return 1;
89
90 return 0;
91 }
92
93
jump_finished(struct replex * rx)94 static int jump_finished(struct replex *rx)
95 {
96 int i;
97
98 if (!rx->video_jump) return 0;
99 for (i=0; i<rx->apidn; i++)
100 if (!rx->audio_jump[i])
101 return 0;
102
103 for (i=0; i<rx->ac3n; i++)
104 if (!rx->ac3_jump[i])
105 return 0;
106
107 return 1;
108 }
109
110
clear_jump(struct replex * rx)111 static void clear_jump(struct replex *rx)
112 {
113 int i;
114
115 rx->video_jump = 0;
116 for (i=0; i<rx->apidn; i++)
117 rx->audio_jump[i] = 0;
118
119 for (i=0; i<rx->ac3n; i++)
120 rx->ac3_jump[i] = 0;
121 }
122
123
create_fillframe1(ringbuffer * rbuf,int off,int * fsize,int type,uint8_t * fillframe,struct replex * rx)124 static void create_fillframe1(ringbuffer *rbuf, int off, int *fsize,
125 int type, uint8_t *fillframe, struct replex *rx)
126 {
127 int fs = *fsize;
128
129 if (fs > MAXFRAME) return;
130
131 if ( type == MPEG_AUDIO){
132 audio_frame_t afr;
133 get_audio_info(rbuf, &afr, off, fs,0);
134 fs = afr.framesize;
135 off += (*fsize-fs);
136 }
137 if (rx->fillzero && type == MPEG_AUDIO)
138 memset(fillframe+4, 0, MAXFRAME-4);
139 else
140 ring_peek (rbuf, fillframe, fs, off);
141 *fsize = fs;
142 }
143
create_fillframe2(ringbuffer * rbuf,int off,int * fsize,int type,uint8_t * fillframe,struct replex * rx)144 static void create_fillframe2(ringbuffer *rbuf, int off, int *fsize,
145 int type, uint8_t *fillframe, struct replex *rx)
146 {
147 int fs = *fsize;
148
149 if (fs > MAXFRAME) return;
150
151 if ( type == MPEG_AUDIO){
152 audio_frame_t afr;
153 get_audio_info(rbuf, &afr, off, fs,0);
154 fs = afr.framesize;
155 }
156 if (rx->fillzero && type == MPEG_AUDIO)
157 memset(fillframe+4, 0, MAXFRAME-4);
158 else
159 ring_peek (rbuf, fillframe, fs, off);
160
161 *fsize = fs;
162 }
163
164
fill_in_frames(ringbuffer * index_buf,int fc,audio_frame_t * aframe,uint64_t * acount,uint8_t * fillframe,int fsize,struct replex * rx)165 static void fill_in_frames(ringbuffer *index_buf, int fc, audio_frame_t *aframe,
166 uint64_t *acount, uint8_t *fillframe, int fsize, struct replex *rx)
167 {
168 index_unit iu;
169 int f;
170
171 for (f=0; f < fc; f++){
172 init_index(&iu);
173 iu.active = 1;
174 iu.pts = add_pts_audio(0, aframe,*acount);
175 iu.framesize = fsize;
176 iu.length = fsize;
177 iu.fillframe = fillframe;
178 iu.err = DUMMY_ERR;
179 if (ring_write(index_buf, (uint8_t *)&iu, sizeof(index_unit)) < 0){
180 fprintf(stderr,"audio ring buffer overrun error\n");
181 overflow_exit(rx);
182 }
183 *acount += 1;
184 }
185 }
186
analyze_audio_loop(pes_in_t * p,struct replex * rx,int type,audio_frame_t * aframe,index_unit * iu,ringbuffer * rbuf,ringbuffer * index_buf,uint64_t * acount,uint64_t * fpts,uint64_t * lpts,int bsize,int * apes_abort,uint64_t * ajump,uint64_t * aoff,uint64_t adelay,int n,int off,int c,int len,int pos,int * first,int * filled)187 static int analyze_audio_loop( pes_in_t *p, struct replex *rx, int type,
188 audio_frame_t *aframe, index_unit *iu,
189 ringbuffer *rbuf, ringbuffer *index_buf,
190 uint64_t *acount, uint64_t *fpts,
191 uint64_t *lpts, int bsize, int *apes_abort,
192 uint64_t *ajump, uint64_t *aoff,
193 uint64_t adelay, int n, int off,
194 int c, int len, int pos, int *first, int *filled)
195 {
196 int re=0;
197 uint8_t *fillframe=NULL;
198
199 switch( type ){
200 case AC3:
201 fillframe = rx->ac3fillframe[n];
202 break;
203 case MPEG_AUDIO:
204 fillframe = rx->afillframe[n];
205 break;
206 }
207 if (!aframe->set){
208 switch( type ){
209 case AC3:
210 re = get_ac3_info(rbuf, aframe,
211 pos+c+off,
212 len-c-pos,1);
213 break;
214 case MPEG_AUDIO:
215 re = get_audio_info(rbuf, aframe,
216 pos+c+off,
217 len-c-pos, 1);
218 break;
219 }
220 if ( re == -2){
221 *apes_abort = len -c;
222 return c;
223 }
224 if (re < 0) return c;
225
226 if (!rx->ignore_pts){
227 if ((p->flag2 & PTS_ONLY)){
228 *fpts = trans_pts_dts(p->pts);
229 fprintf(stderr,
230 "starting audio PTS: ");
231 printpts(*fpts);
232 fprintf(stderr,"\n");
233 } else {
234 aframe->set = 0;
235 ring_skip(rbuf,pos+c+off+re);
236 }
237 }
238
239 if (aframe->set && *first)
240 ring_skip(rbuf,pos+c);
241 } else {
242 int diff = ring_posdiff(rbuf, iu->start,
243 p->ini_pos + pos+c);
244
245 if ( (re =check_audio_header(rbuf, aframe,
246 pos+c+off,len-c-pos,
247 type)) < 0){
248
249 if ( re == -2){
250 *apes_abort = len -c;
251 return c;
252 }
253
254 if (aframe->framesize > diff){
255 if ( re == -3){
256 c+= pos+1;
257 return c;
258 }
259
260 c += pos+2;
261 #ifdef IN_DEBUG
262 fprintf(stderr,"WRONG HEADER1 %d\n", diff);
263 #endif
264 return c;
265 }
266 }
267 if (aframe->framesize > diff){
268 c += pos+2;
269 //fprintf(stderr,"WRONG HEADER2 %d\n", diff);
270 return c;
271 }
272 }
273
274
275 if (aframe->set){
276 if(iu->active){
277 iu->length = ring_posdiff(rbuf,
278 iu->start,
279 p->ini_pos +
280 pos+c);
281
282 if (fillframe && !*filled){
283 int fsize = aframe->framesize;
284 int pdiff = ring_posdiff(rbuf, ring_rpos(rbuf),iu->start);
285
286 create_fillframe2(rbuf, pdiff, &fsize, type, fillframe, rx);
287 *filled = 1;
288 }
289
290 if (iu->length != aframe->framesize){
291 iu->err= FRAME_ERR;
292 fprintf(stderr,"Wrong audio frame size: %d (%d)\n",
293 iu->length, aframe->framesize);
294 *acount -= 1;
295 }
296
297 if (ring_write(index_buf, (uint8_t *)iu, sizeof(index_unit)) < 0){
298 fprintf(stderr,"audio ring buffer overrun error\n");
299 overflow_exit(rx);
300 }
301 if (iu->err == JUMP_ERR) *acount -= 1;
302 *acount += 1;
303 }
304
305 init_index(iu);
306 iu->active = 1;
307 iu->pts = add_pts_audio(0, aframe,*acount);
308 iu->framesize = aframe->framesize;
309
310 if (!rx->ignore_pts && *first && (p->flag2 & PTS_ONLY)){
311 int64_t dpts;
312 int64_t diff;
313
314 dpts = ptsdiff(trans_pts_dts(p->pts), *fpts);
315 diff = ptsdiff(dpts, iu->pts);
316
317 if (rx->allow_jump &&
318 (int)diff > rx->allow_jump){
319
320 if (!(*ajump) && rx->video_jump){
321 int fc=0;
322 int fsize = 0;
323 uint64_t oldfpts = 0;
324 uint64_t ndpts = 0;
325
326 int pdiff = ring_posdiff(rbuf, ring_rpos(rbuf),p->ini_pos +
327 pos+c );
328
329 *ajump = diff;
330 oldfpts = *fpts;
331 *fpts += rx->video_jump;
332
333 fprintf(stderr,"found jump in audio PTS\n");
334 printpts(iu->pts);
335 printpts(diff);
336 fprintf(stderr,"\n");
337
338
339 ndpts = uptsdiff(trans_pts_dts(p->pts),*fpts);
340 fsize = aframe->framesize;
341 if (fillframe){
342 create_fillframe1(rbuf, pdiff-fsize, &fsize,
343 type, fillframe, rx);
344 *filled = 1;
345 }
346
347 if (iu->pts < ndpts){
348 fc = cfix_audio_count(aframe, ndpts, iu->pts);
349
350 if ( fc > 100) {
351 *acount+= fc;
352 fprintf(stderr,"need to fill in %d audio frames\n",fc);
353 fprintf(stderr,"this is too much, try re-cutting\n");
354 *fpts = oldfpts;
355 fc = 0; // just too broken
356 rx->video_jump=0;
357 } else fill_in_frames(index_buf, fc, aframe,
358 acount, fillframe, aframe->framesize, rx);
359 init_index(iu);
360 iu->active = 1;
361 iu->pts = add_pts_audio(0, aframe,*acount);
362 iu->framesize = aframe->framesize;
363
364 //iu->pts = uptsdiff(trans_pts_dts(p->pts),
365 // *fpts);
366 printpts(iu->pts);
367 fprintf(stderr," fixed %d frames\n", fc);
368
369 diff = 0;
370
371 } else {
372 fc = cfix_audio_count(aframe, iu->pts, ndpts);
373 fprintf(stderr,"need to drop %d audio frames: ",fc);
374 diff = ptsdiff(ndpts, iu->pts);
375 printpts(diff);
376 fprintf(stderr,"\n");
377 iu->pts = add_pts_audio(0, aframe,*acount);
378 }
379
380 }
381
382 if (!rx->video_jump && diff > 0){
383 uint64_t vadiff = ptsdiff(dpts, rx->last_vpts);
384 iu->err = JUMP_ERR;
385 *ajump = diff;
386
387 fprintf(stderr,"found jump in audio PTS without video jump\n");
388 printpts(iu->pts);
389 printpts(diff);
390 fprintf(stderr,"\n");
391
392 if (abs(vadiff) < 600 * CLOCK_MS){
393 int fc=0;
394 int fsize = 0;
395
396 int pdiff = ring_posdiff(rbuf, ring_rpos(rbuf),p->ini_pos +
397 pos+c );
398
399 *ajump = diff;
400 *fpts += rx->video_jump;
401
402 fprintf(stderr,"filling in audio frames\n");
403 printpts(iu->pts);
404 printpts(diff);
405 fprintf(stderr,"\n");
406
407
408 fc = cfix_audio_count(aframe,
409 uptsdiff(trans_pts_dts(p->pts),
410 *fpts), iu->pts);
411 fsize = aframe->framesize;
412 if (fillframe){
413 create_fillframe1(rbuf, pdiff-fsize, &fsize,
414 type, fillframe, rx);
415 *filled = 1;
416 }
417
418 fill_in_frames(index_buf, fc, aframe,
419 acount, fillframe, fsize, rx);
420
421 init_index(iu);
422 iu->active = 1;
423 iu->pts = add_pts_audio(0, aframe,*acount);
424 iu->framesize = aframe->framesize;
425 fprintf(stderr," fixed %d frames\n", fc);
426
427 diff = 0;
428 }
429 }
430
431 if (jump_finished(rx)) clear_jump(rx);
432 }
433
434
435 if ( diff < 0){
436 fprintf(stderr,"drop audio frame\n");
437 init_index(iu);
438 iu->err = JUMP_ERR;
439 iu->active = 1;
440 iu->pts = add_pts_audio(0, aframe,*acount);
441 iu->framesize = aframe->framesize;
442 }
443
444 if( iu->err!= JUMP_ERR && !rx->keep_pts && diff > 40*CLOCK_MS){
445 if (!rx->allow_jump || abs((int)diff) > rx->allow_jump){
446 fprintf(stderr,"audio PTS inconsistent: ");
447 printpts(dpts);
448 printpts(iu->pts);
449 fprintf(stderr,"diff: ");
450 printpts(diff);
451 fprintf(stderr,"\n");
452 }
453 }
454 if (rx->keep_pts){
455 fix_audio_count(acount, aframe,
456 uptsdiff(trans_pts_dts(
457 p->pts),
458 *fpts),
459 iu->pts);
460 iu->pts = uptsdiff(trans_pts_dts(p->pts),
461 *fpts);
462 if (*lpts && ptsdiff(iu->pts,*lpts)<0)
463 fprintf(stderr,
464 "Warning negative audio PTS increase!\n");
465 *lpts = iu->pts;
466 }
467 *first = 0;
468 }
469 if (rx->analyze >1){
470 if ((p->flag2 & PTS_ONLY)){
471 iu->pts = trans_pts_dts(p->pts);
472 } else {
473 iu->pts = 0;
474 }
475 }
476 iu->start = (p->ini_pos+pos+c)%bsize;
477 }
478 c += pos;
479 if (c + aframe->framesize > len){
480 // fprintf(stderr,"SHORT %d\n", len -c);
481 c = len;
482 } else {
483 c += aframe->framesize;
484 }
485 return c;
486 }
487
488
489
analyze_audio(pes_in_t * p,struct replex * rx,int len,int num,int type)490 void analyze_audio( pes_in_t *p, struct replex *rx, int len, int num, int type)
491 {
492 int c=0;
493 int pos=0;
494 audio_frame_t *aframe = NULL;
495 index_unit *iu = NULL;
496 ringbuffer *rbuf = NULL, *index_buf = NULL;
497 uint64_t *acount=NULL;
498 uint64_t *fpts=NULL;
499 uint64_t *lpts=NULL;
500 int bsize = 0;
501 uint64_t *ajump=NULL;
502 uint64_t *aoff=NULL;
503 uint8_t buf[7];
504 int off=0;
505 int *apes_abort=NULL;
506 uint64_t adelay=0;
507 int first = 1;
508 int *filled=NULL;
509
510 switch ( type ){
511 case AC3:
512 #ifdef IN_DEBUG
513 fprintf(stderr, "AC3\n");
514 #endif
515 aframe = &rx->ac3frame[num];
516 iu = &rx->current_ac3index[num];
517 rbuf = &rx->ac3rbuffer[num];
518 index_buf = &rx->index_ac3rbuffer[num];
519 acount = &rx->ac3frame_count[num];
520 fpts = &rx->first_ac3pts[num];
521 lpts = &rx->last_ac3pts[num];
522 bsize = rx->ac3buf;
523 apes_abort = &rx->ac3pes_abort[num];
524 ajump = &rx->ac3_jump[num];
525 aoff = &rx->ac3pts_off[num];
526 adelay = rx->ac3pts_off[num];
527 filled = &rx->ac3filled[num];
528 break;
529
530 case MPEG_AUDIO:
531 #ifdef IN_DEBUG
532 fprintf(stderr, "MPEG AUDIO\n");
533 #endif
534 aframe = &rx->aframe[num];
535 iu = &rx->current_aindex[num];
536 rbuf = &rx->arbuffer[num];
537 index_buf = &rx->index_arbuffer[num];
538 acount = &rx->aframe_count[num];
539 fpts = &rx->first_apts[num];
540 lpts = &rx->last_apts[num];
541 bsize = rx->audiobuf;
542 apes_abort = &rx->apes_abort[num];
543 ajump = &rx->audio_jump[num];
544 aoff = &rx->apts_off[num];
545 adelay = rx->apts_off[num];
546 filled = &rx->afilled[num];
547 break;
548 }
549
550 *apes_abort = 0;
551 off = ring_rdiff(rbuf, p->ini_pos);
552 while (c < len){
553 if ( (pos = find_audio_sync(rbuf, buf, c+off, type, len-c) )
554 >= 0 ){
555 c = analyze_audio_loop( p, rx, type, aframe, iu,
556 rbuf, index_buf, acount, fpts,
557 lpts, bsize, apes_abort,
558 ajump, aoff, adelay, num, off,
559 c, len, pos, &first, filled);
560 } else {
561 *apes_abort = len-c;
562 c=len;
563 }
564 }
565 }
566
567
analyze_video(pes_in_t * p,struct replex * rx,int len)568 void analyze_video( pes_in_t *p, struct replex *rx, int len)
569 {
570 uint8_t buf[8];
571 int c=0;
572 int pos=0;
573 uint8_t head;
574 int seq_end = 0;
575 uint8_t frame = 0;
576 uint64_t newpts = 0;
577 uint64_t newdts = 0;
578 index_unit *iu;
579 int off=0;
580 ringbuffer *rbuf;
581 ringbuffer *index_buf;
582 sequence_t *s;
583 int i;
584
585 uint16_t tempref = 0;
586 int seq_h = 0;
587 int gop = 0;
588 int frame_off = 0;
589 int gop_off = 0;
590 int seq_p = 0;
591 int flush=0;
592 int keep_now = 0;
593
594 rbuf = &rx->vrbuffer;
595 index_buf = &rx->index_vrbuffer;
596 iu = &rx->current_vindex;
597 s = &rx->seq_head;
598
599 rx->vpes_abort = 0;
600 off = ring_rdiff(rbuf, p->ini_pos);
601 #ifdef IN_DEBUG
602 fprintf(stderr, " ini pos %d\n",
603 (p->ini_pos)%rx->videobuf);
604 #endif
605
606
607 // fprintf(stderr, "len %d %d\n",len,off);
608 while (c < len){
609 if ((pos = ring_find_any_header( rbuf, &head, c+off, len-c))
610 >=0 ){
611 switch(head){
612 case SEQUENCE_HDR_CODE:
613 #ifdef IN_DEBUG
614 fprintf(stderr, " seq headr %d\n",
615 (p->ini_pos+c+pos)%rx->videobuf);
616 #endif
617
618 seq_h = 1;
619 seq_p = c+pos;
620
621
622 if (!s->set){
623 int re=0;
624 re = get_video_info(rbuf, &rx->seq_head,
625 pos+c+off, len -c -pos);
626
627 #ifdef IN_DEBUG
628 fprintf(stderr, " seq headr result %d\n",re);
629 #endif
630 if (re == -2){
631 rx->vpes_abort = len -(c+pos-1);
632 return;
633 }
634 if (s->set){
635 ring_skip(rbuf, pos+c);
636 off -= pos+c;
637 }
638 if (!rx->ignore_pts &&
639 !(p->flag2 & PTS_ONLY)) s->set = 0;
640 }
641 if (s->set){
642 flush = 1;
643 }
644 break;
645
646 case EXTENSION_START_CODE:{
647 int ext_id = 0;
648
649 #ifdef IN_DEBUG
650 fprintf(stderr," seq ext headr %d\n",
651 (p->ini_pos+c+pos)+rx->videobuf);
652 #endif
653 ext_id = get_video_ext_info(rbuf,
654 &rx->seq_head,
655 pos+c+off,
656 len -c -pos);
657 if (ext_id == -2){
658 rx->vpes_abort = len - (pos-1+c);
659 return;
660 }
661
662
663 if(ext_id == PICTURE_CODING_EXTENSION
664 && s->ext_set && iu->active){
665 if (!rx->ignore_pts &&
666 !rx->vframe_count &&
667 !rx->first_vpts){
668 rx->first_vpts = trans_pts_dts(
669 p->pts);
670
671 for (i = 0; i< s->current_tmpref;
672 i++) ptsdec(&rx->first_vpts,
673 SEC_PER);
674 fprintf(stderr,"starting with video PTS: ");
675 printpts(rx->first_vpts);
676 fprintf(stderr,"\n");
677 }
678
679 newpts = 0;
680 #ifdef IN_DEBUG
681
682 fprintf(stderr,"fcount %d gcount %d tempref %d %d\n",
683 (int)rx->vframe_count, (int)rx->vgroup_count,
684 (int)s->current_tmpref,
685 (int)(s->current_tmpref - rx->vgroup_count
686 + rx->vframe_count));
687 #endif
688 newdts = next_ptsdts_video(
689 &newpts,s, rx->vframe_count,
690 rx->vgroup_count);
691
692 if (!rx->ignore_pts &&
693 (p->flag2 & PTS_ONLY)){
694 int64_t diff;
695
696 diff = ptsdiff(iu->pts,
697 rx->first_vpts
698 + newpts);
699
700 if (rx->allow_jump &&
701 abs(diff) > rx->allow_jump)
702 {
703 if (audio_jump(rx)){
704 fprintf(stderr,"AUDIO JUMPED\n");
705 clear_jump(rx);
706 }
707 fprintf(stderr,"found jump in video PTS\n");
708 printpts(iu->pts);
709 printpts(diff);
710 fprintf(stderr,"\n");
711 rx->video_jump = diff;
712 rx->first_vpts += diff;
713 diff = 0;
714 } else {
715 keep_now = 1;
716 }
717
718 if (!rx->keep_pts &&
719 abs((int)(diff)) > 3*SEC_PER/2){
720 fprintf(stderr,"video PTS inconsistent: ");
721 printpts(trans_pts_dts(p->pts));
722 printpts(iu->pts);
723 printpts(newpts+rx->first_vpts);
724 printpts(newpts);
725 fprintf(stderr," diff: ");
726 printpts(diff);
727 fprintf(stderr,"\n");
728 }
729 }
730
731 if (!rx->ignore_pts &&
732 (p->flag2 & PTS_DTS) == PTS_DTS){
733 uint64_t diff;
734 diff = ptsdiff(iu->dts,
735 newdts +
736 rx->first_vpts);
737 if (!rx->keep_pts && !keep_now &&
738 abs((int)diff) > 3*SEC_PER/2){
739 fprintf(stderr,"video DTS inconsistent: ");
740 printpts(trans_pts_dts(p->dts));
741 printpts(iu->dts);
742 printpts(newdts+rx->first_vpts);
743 printpts(newdts);
744 fprintf(stderr,"diff: ");
745 printpts(diff);
746 fprintf(stderr,"\n");
747 }
748 }
749 if (!rx->keep_pts && !keep_now){
750 iu->pts = newpts;
751 iu->dts = newdts;
752 } else {
753 if (p->flag2 & PTS_DTS){
754 ptsdec(&iu->pts,
755 rx->first_vpts);
756
757 if ((p->flag2 & PTS_DTS) == PTS_DTS){
758 ptsdec(&iu->dts,
759 rx->first_vpts);
760 } else iu->dts = newdts;
761
762 fix_video_count(s,&rx->vframe_count,
763 iu->pts,newpts,
764 iu->dts,newdts);
765
766 } else {
767 iu->pts = newpts;
768 iu->dts = newdts;
769 }
770 }
771 if (rx->last_vpts &&
772 ptsdiff(iu->dts, rx->last_vpts) <0)
773 fprintf(stderr,
774 "Warning negative video PTS increase!\n");
775 rx->last_vpts = iu->dts;
776 }
777
778 if (rx->analyze){
779 if ((p->flag2 & PTS_DTS) == PTS_DTS){
780 iu->pts = trans_pts_dts(p->pts);
781 iu->dts = trans_pts_dts(p->dts);
782 } else if (p->flag2 & PTS_ONLY){
783 iu->pts = trans_pts_dts(p->pts);
784 iu->dts = 0;
785 } else {
786 iu->pts = 0;
787 iu->dts = 0;
788 }
789 }
790
791
792 break;
793 }
794
795 case SEQUENCE_END_CODE:
796 #ifdef IN_DEBUG
797 fprintf(stderr, " seq end %d\n",
798 (p->ini_pos+c+pos)%rx->videobuf);
799 #endif
800 if (s->set)
801 seq_end = 1;
802
803 break;
804
805 case GROUP_START_CODE:{
806 int hour, min, sec;
807 //#define ANA
808 #ifdef ANA
809 fprintf(stderr," %d", (int)rx->vgroup_count);
810 fprintf(stderr,"\n");
811
812 #endif
813 if (s->set){
814 if (!seq_h) flush = 1;
815 }
816 gop = 1;
817 gop_off = c+pos - seq_p;
818
819 if (ring_peek(rbuf, buf, 7, off+c+pos) < 0){
820 rx->vpes_abort = len -(c+pos-1);
821 return;
822 }
823 hour = (int)((buf[4]>>2)& 0x1F);
824 min = (int)(((buf[4]<<4)& 0x30)|
825 ((buf[5]>>4)& 0x0F));
826 sec = (int)(((buf[5]<<3)& 0x38)|
827 ((buf[6]>>5)& 0x07));
828 #ifdef IN_DEBUG
829 fprintf(stderr, " gop %02d:%02d.%02d %d\n",
830 hour,min,sec,
831 (p->ini_pos+c+pos)%rx->videobuf);
832 #endif
833 rx->vgroup_count = 0;
834
835 break;
836 }
837
838 case PICTURE_START_CODE:{
839 if (len-(c+pos) < 14){
840 rx->vpes_abort = len - (pos-1+c);
841 return;
842 }
843
844 if (ring_peek(rbuf, buf, 6, off+c+pos) < 0)
845 return;
846
847
848 frame = ((buf[5]&0x38) >>3);
849
850 if (frame == I_FRAME){
851 if( !rx->first_iframe){
852 if (s->set){
853 rx->first_iframe = 1;
854 } else {
855 s->set=0;
856 flush = 0;
857 break;
858 }
859 }
860 }
861
862 frame_off = c+pos - seq_p;
863 if (s->set){
864 if (!seq_h && !gop) flush = 1;
865 }
866 tempref = (buf[5]>>6) & 0x03;
867 tempref |= buf[4] << 2;
868
869 switch (frame){
870 case I_FRAME:
871 #ifdef ANA
872 fprintf(stderr,"I");
873 #endif
874 #ifdef IN_DEBUG
875 fprintf(stderr, " I-frame %d\n",
876 (p->ini_pos+c+pos)%rx->videobuf);
877 #endif
878 break;
879 case B_FRAME:
880 #ifdef ANA
881 fprintf(stderr,"B");
882 #endif
883 #ifdef IN_DEBUG
884 fprintf(stderr, " B-frame %d\n",
885 (p->ini_pos+c+pos)%rx->videobuf);
886 #endif
887 break;
888 case P_FRAME:
889 #ifdef ANA
890 fprintf(stderr,"P");
891 #endif
892 #ifdef IN_DEBUG
893 fprintf(stderr, " P-frame %d\n",
894 (p->ini_pos+c+pos)%rx->videobuf);
895 #endif
896 break;
897 }
898 s->current_frame = frame;
899 s->current_tmpref = tempref;
900
901 break;
902 }
903 default:
904 #ifdef IN_DEBUG
905 //fprintf(stderr,"other header 0x%02x (%d+%d)\n",head,c,pos);
906 #endif
907 break;
908 }
909
910 if (flush && s->set && rx->first_iframe){
911 if(iu->active){
912 rx->vframe_count++;
913 rx->vgroup_count++;
914
915 iu->length = ring_posdiff(rbuf,
916 iu->start,
917 p->ini_pos+
918 pos+c-frame_off);
919
920 if ( ring_write(index_buf, (uint8_t *)
921 &rx->current_vindex,
922 sizeof(index_unit))<0){
923 fprintf(stderr,"video ring buffer overrun error 1\n");
924 overflow_exit(rx);
925
926 }
927 }
928 init_index(&rx->current_vindex);
929 flush = 0;
930 iu->active = 1;
931 if (!rx->ignore_pts){
932 if ((p->flag2 & PTS_DTS) == PTS_DTS){
933 iu->pts = trans_pts_dts(p->pts);
934 iu->dts = trans_pts_dts(p->dts);
935 } else if (p->flag2 & PTS_ONLY){
936 iu->pts = trans_pts_dts(p->pts);
937 }
938 }
939 iu->start = (p->ini_pos+pos+c-frame_off)
940 %rx->videobuf;
941 #ifdef IN_DEBUG
942 fprintf(stderr,"START %d\n", iu->start);
943 #endif
944 }
945
946 if (s->set){
947 if (frame)
948 iu->frame = (frame&0xFF);
949 if (seq_h)
950 iu->seq_header = 1;
951 if (seq_end)
952 iu->seq_end = 1;
953 if (gop)
954 iu->gop = 1;
955 if (gop_off)
956 iu->gop_off = gop_off;
957 if (frame_off)
958 iu->frame_off = frame_off;
959 }
960 c+=pos+4;
961 } else {
962 if (pos == -2){
963 rx->vpes_abort = 4;
964
965 }
966 c = len;
967 }
968 }
969 }
970
es_out(pes_in_t * p)971 void es_out(pes_in_t *p)
972 {
973
974 struct replex *rx;
975 char t[80];
976 int len;
977
978 len = p->plength-3-p->hlength;
979
980 rx = (struct replex *) p->priv;
981
982 switch(p->type)
983 {
984 case 0xE0: {
985 sprintf(t, "Video ");
986 if (rx->vpes_abort){
987 p->ini_pos = (p->ini_pos - rx->vpes_abort)%rx->vrbuffer.size;
988 len += rx->vpes_abort;
989 }
990 analyze_video(p, rx, len);
991 if (!rx->seq_head.set){
992 ring_skip(&rx->vrbuffer, len);
993 }
994 break;
995 }
996
997 case 1 ... 32:{
998 int l;
999 l = p->type - 1;
1000 sprintf(t, "Audio%d ", l);
1001 if (rx->apes_abort[l]){
1002 p->ini_pos = (p->ini_pos - rx->apes_abort[l])
1003 %rx->arbuffer[l].size;
1004 len += rx->apes_abort[l];
1005 }
1006 analyze_audio(p, rx, len, l, MPEG_AUDIO);
1007 if (!rx->aframe[l].set)
1008 ring_skip(&rx->arbuffer[l], len);
1009
1010 break;
1011 }
1012
1013 case 0x80 ... 0x87:{
1014 int l;
1015 l = p->type - 0x80;
1016 sprintf(t, "AC3 %d ", p->type);
1017 if (rx->ac3pes_abort[l]){
1018 p->ini_pos = (p->ini_pos - rx->ac3pes_abort[l])
1019 %rx->ac3rbuffer[l].size;
1020 len += rx->ac3pes_abort[l];
1021 }
1022 analyze_audio(p, rx, len, l, AC3);
1023 if (!rx->ac3frame[l].set)
1024 ring_skip(&rx->ac3rbuffer[l], len);
1025 break;
1026 }
1027
1028 default:
1029 return;
1030
1031
1032 }
1033
1034 #ifdef IN_DEBUG
1035 fprintf(stderr,"%s PES\n", t);
1036 #endif
1037 }
1038
pes_es_out(pes_in_t * p)1039 void pes_es_out(pes_in_t *p)
1040 {
1041
1042 struct replex *rx = NULL;
1043 char t[80];
1044 int len = 0, i =0;
1045 int l=0;
1046
1047 len = p->plength-3-p->hlength;
1048 rx = (struct replex *) p->priv;
1049
1050 switch(p->cid){
1051 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1052 if (rx->vpid != p->cid) break;
1053 p->type = 0xE0;
1054 p->ini_pos = ring_wpos(&rx->vrbuffer);
1055
1056 if (ring_write(&rx->vrbuffer, p->buf+9+p->hlength, len)<0){
1057 fprintf(stderr,"video ring buffer overrun error 2\n");
1058 overflow_exit(rx);
1059 }
1060 if (rx->vpes_abort){
1061 p->ini_pos = (p->ini_pos - rx->vpes_abort)%rx->vrbuffer.size;
1062 len += rx->vpes_abort;
1063 }
1064 sprintf(t, "Video ");
1065 analyze_video(p, rx, len);
1066 if (!rx->seq_head.set){
1067 ring_skip(&rx->vrbuffer, len);
1068 }
1069 break;
1070
1071 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1072 p->type = p->cid - 0xc0 + 1;
1073 l = -1;
1074 for (i=0; i<rx->apidn; i++)
1075 if (p->cid == rx->apid[i])
1076 l = i;
1077 if (l < 0) break;
1078 p->ini_pos = ring_wpos(&rx->arbuffer[l]);
1079 if (ring_write(&rx->arbuffer[l], p->buf+9+p->hlength, len)<0){
1080 fprintf(stderr,"audio ring buffer overrun error\n");
1081 overflow_exit(rx);
1082 }
1083 if (rx->apes_abort[l]){
1084 p->ini_pos = (p->ini_pos - rx->apes_abort[l])
1085 %rx->arbuffer[l].size;
1086 len += rx->apes_abort[l];
1087 }
1088
1089 sprintf(t, "Audio%d ", l);
1090 analyze_audio(p, rx, len, l, MPEG_AUDIO);
1091 if (!rx->aframe[l].set)
1092 ring_skip(&rx->arbuffer[l], len);
1093
1094 break;
1095
1096 case PRIVATE_STREAM1:{
1097 int hl=4;
1098 if (rx->vdr){
1099 hl=0;
1100 p->type=0x80;
1101 l = 0;
1102 } else {
1103 uint16_t fframe;
1104
1105 fframe=0;
1106 fframe = p->buf[9+p->hlength+3];
1107 fframe |= (p->buf[9+p->hlength+2]<<8);
1108
1109 if (fframe > p->plength) break;
1110
1111 p->type = p->buf[9+p->hlength];
1112 l = -1;
1113 for (i=0; i<rx->ac3n; i++)
1114 if (p->type == rx->ac3_id[i])
1115 l = i;
1116 if (l < 0) break;
1117 }
1118 len -= hl;
1119 p->ini_pos = ring_wpos(&rx->ac3rbuffer[l]);
1120
1121 if (ring_write(&rx->ac3rbuffer[l], p->buf+9+hl+p->hlength, len)<0){
1122 fprintf(stderr,"ac3 ring buffer overrun error\n");
1123 overflow_exit(rx);
1124 }
1125 if (rx->ac3pes_abort[l]){
1126 p->ini_pos = (p->ini_pos - rx->ac3pes_abort[l])
1127 %rx->ac3rbuffer[l].size;
1128 len += rx->ac3pes_abort[l];
1129 }
1130
1131 sprintf(t, "AC3 %d ", p->type);
1132 analyze_audio(p, rx, len, l, AC3);
1133 sprintf(t,"%d",rx->ac3frame[l].set);
1134 if (!rx->ac3frame[l].set)
1135 ring_skip(&rx->ac3rbuffer[l], len);
1136 }
1137 break;
1138
1139 default:
1140 return;
1141 }
1142
1143 #ifdef IN_DEBUG
1144 fprintf(stderr,"%s PES %d\n", t,len);
1145 #endif
1146 }
1147
avi_es_out(pes_in_t * p)1148 void avi_es_out(pes_in_t *p)
1149 {
1150
1151 struct replex *rx;
1152 char t[80];
1153 int len;
1154
1155 len = p->plength;
1156
1157 rx = (struct replex *) p->priv;
1158
1159
1160 switch(p->type)
1161 {
1162 case 0xE0: {
1163 sprintf(t, "Video ");
1164 if (!len){
1165 rx->vframe_count++;
1166 break;
1167 }
1168 analyze_video(p, rx, len);
1169 if (!rx->seq_head.set){
1170 ring_skip(&rx->vrbuffer, len);
1171 }
1172 break;
1173 }
1174
1175 case 1 ... 32:{
1176 int l;
1177 l = p->type - 1;
1178 sprintf(t, "Audio%d ", l);
1179 if (!len){
1180 rx->aframe_count[l]++;
1181 break;
1182 }
1183 analyze_audio(p, rx, len, l, MPEG_AUDIO);
1184 if (!rx->aframe[l].set)
1185 ring_skip(&rx->arbuffer[l], len);
1186
1187 break;
1188 }
1189
1190 case 0x80 ... 0x87:{
1191 int l;
1192
1193 l = p->type - 0x80;
1194 sprintf(t, "AC3 %d ", p->type);
1195 if (!len){
1196 rx->ac3frame_count[l]++;
1197 break;
1198 }
1199 analyze_audio(p, rx, len, l, AC3);
1200 if (!rx->ac3frame[l].set)
1201 ring_skip(&rx->ac3rbuffer[l], len);
1202 break;
1203 }
1204
1205 default:
1206 return;
1207
1208
1209 }
1210 #ifdef IN_DEBUG
1211 fprintf(stderr,"%s PES\n", t);
1212 #endif
1213
1214 }
1215
1216
replex_tsp(struct replex * rx,uint8_t * tsp)1217 int replex_tsp(struct replex *rx, uint8_t *tsp)
1218 {
1219 uint16_t pid;
1220 int type;
1221 int off=0;
1222 pes_in_t *p=NULL;
1223
1224 pid = get_pid(tsp+1);
1225
1226 if ((type=replex_check_id(rx, pid))<0)
1227 return 0;
1228
1229 switch(type){
1230 case 0:
1231 p = &rx->pvideo;
1232 break;
1233
1234 case 1 ... 32:
1235 p = &rx->paudio[type-1];
1236 break;
1237
1238 case 0x80 ... 0x87:
1239 p = &rx->pac3[type-0x80];
1240 break;
1241 default:
1242 return 0;
1243
1244 }
1245
1246
1247 if ( tsp[1] & PAY_START){
1248 if (p->plength == MMAX_PLENGTH-6){
1249 p->plength = p->found-6;
1250 es_out(p);
1251 init_pes_in(p, p->type, NULL, 0);
1252 }
1253 }
1254
1255 if ( tsp[3] & ADAPT_FIELD){ // adaptation field?
1256 off = tsp[4] + 1;
1257 if (off+4 >= TS_SIZE) return 0;
1258 }
1259
1260 get_pes(p, tsp+4+off, TS_SIZE-4-off, es_out);
1261
1262 return 0;
1263 }
1264
1265
save_read(struct replex * rx,void * buf,size_t count)1266 ssize_t save_read(struct replex *rx, void *buf, size_t count)
1267 {
1268 ssize_t neof = 1;
1269 size_t re = 0;
1270 int fd = rx->fd_in;
1271
1272 if (rx->itype== REPLEX_AVI){
1273 int l = rx->inflength - rx->finread;
1274 if ( l <= 0) return 0;
1275 if ( count > l) count = l;
1276 }
1277 while(neof >= 0 && re < count){
1278 neof = read(fd, buf+re, count - re);
1279 if (neof > 0) re += neof;
1280 else break;
1281 }
1282 rx->finread += re;
1283 #ifndef OUT_DEBUG
1284 if (rx->inflength){
1285 uint8_t per=0;
1286
1287 per = (uint8_t)(rx->finread*100/rx->inflength);
1288 if (rx->lastper < per){
1289 fprintf(stderr,"read %3d%%\r", (int)per);
1290 rx->lastper = per;
1291 }
1292 if (rx->finread >= rx->inflength && rx->inputFiles && rx->inputFiles[rx->inputIdx + 1]) {
1293 close(rx->fd_in);
1294 rx->inputIdx ++;
1295 if ((rx->fd_in = open(rx->inputFiles[rx->inputIdx] ,O_RDONLY| O_LARGEFILE)) < 0) {
1296 fprintf(stderr,"Error opening input file %s",rx->inputFiles[rx->inputIdx] );
1297 exit(1);
1298 }
1299 fprintf(stderr,"Reading from %s\n", rx->inputFiles[rx->inputIdx]);
1300 rx->inflength = lseek(rx->fd_in, 0, SEEK_END);
1301 fprintf(stderr,"Input file length: %.2f MB\n",rx->inflength/1024./1024.);
1302 lseek(rx->fd_in,0,SEEK_SET);
1303 rx->lastper = 0;
1304 rx->finread = 0;
1305 }
1306 } else fprintf(stderr,"read %.2f MB\r", rx->finread/1024./1024.);
1307 #endif
1308 if (neof < 0 && re == 0) return neof;
1309 else return re;
1310 }
1311
guess_fill(struct replex * rx)1312 int guess_fill( struct replex *rx)
1313 {
1314 int vavail, aavail, ac3avail, i, fill;
1315
1316 vavail = 0;
1317 ac3avail =0;
1318 aavail = 0;
1319 fill =0;
1320
1321 #define LIMIT 3
1322 if ((vavail = ring_avail(&rx->index_vrbuffer)/sizeof(index_unit))
1323 < LIMIT)
1324 fill = ring_free(&rx->vrbuffer);
1325
1326 for (i=0; i<rx->apidn;i++){
1327 if ((aavail = ring_avail(&rx->index_arbuffer[i])
1328 /sizeof(index_unit)) < LIMIT)
1329 if (fill < ring_free(&rx->arbuffer[i]))
1330 fill = ring_free(&rx->arbuffer[i]);
1331 }
1332
1333 for (i=0; i<rx->ac3n;i++){
1334 if ((ac3avail = ring_avail(&rx->index_ac3rbuffer[i])
1335 /sizeof(index_unit)) < LIMIT)
1336 if (fill < ring_free(&rx->ac3rbuffer[i]))
1337 fill = ring_free(&rx->ac3rbuffer[i]);
1338 }
1339
1340 // fprintf(stderr,"free %d %d %d %d\n",fill, vavail, aavail, ac3avail);
1341
1342 if (!fill){
1343 if(vavail && (aavail || ac3avail)) return 0;
1344 else return -1;
1345 }
1346
1347 return fill/2;
1348 }
1349
1350
1351
1352 #define IN_SIZE (1000*TS_SIZE)
find_pids_file(struct replex * rx)1353 void find_pids_file(struct replex *rx)
1354 {
1355 uint8_t buf[IN_SIZE];
1356 int afound=0;
1357 int vfound=0;
1358 int count=0;
1359 int re=0;
1360 uint16_t vpid=0, apid=0, ac3pid=0;
1361
1362 fprintf(stderr,"Trying to find PIDs\n");
1363 while (!afound && !vfound && count < rx->inflength){
1364 if (rx->vpid) vfound = 1;
1365 if (rx->apidn) afound = 1;
1366 if ((re = save_read(rx,buf,IN_SIZE))<0)
1367 perror("reading");
1368 else
1369 count += re;
1370 if ( (re = find_pids(&vpid, &apid, &ac3pid, buf, re))){
1371 if (!rx->vpid && vpid){
1372 rx->vpid = vpid;
1373 fprintf(stderr,"vpid 0x%04x \n",
1374 (int)rx->vpid);
1375 vfound++;
1376 }
1377 if (!rx->apidn && apid){
1378 rx->apid[0] = apid;
1379 fprintf(stderr,"apid 0x%04x \n",
1380 (int)rx->apid[0]);
1381 rx->apidn++;
1382 afound++;
1383 }
1384 if (!rx->ac3n && ac3pid){
1385 rx->ac3_id[0] = ac3pid;
1386 fprintf(stderr,"ac3pid 0x%04x \n",
1387 (int)rx->ac3_id[0]);
1388 rx->ac3n++;
1389 afound++;
1390 }
1391
1392 }
1393
1394 }
1395
1396 lseek(rx->fd_in,0,SEEK_SET);
1397 if (!afound || !vfound){
1398 fprintf(stderr,"Couldn't find all pids\n");
1399 exit(1);
1400 }
1401
1402 }
1403
1404 #define MAXVPID 16
1405 #define MAXAPID 32
1406 #define MAXAC3PID 16
find_all_pids_file(struct replex * rx)1407 void find_all_pids_file(struct replex *rx)
1408 {
1409 uint8_t buf[IN_SIZE];
1410 int count=0;
1411 int j;
1412 int re=0;
1413 uint16_t vpid[MAXVPID], apid[MAXAPID], ac3pid[MAXAC3PID];
1414 int vn=0, an=0,ac3n=0;
1415 uint16_t vp,ap,cp;
1416 int vpos, apos, cpos;
1417
1418 memset (vpid , 0 , MAXVPID*sizeof(uint16_t));
1419 memset (apid , 0 , MAXAPID*sizeof(uint16_t));
1420 memset (ac3pid , 0 , MAXAC3PID*sizeof(uint16_t));
1421
1422 fprintf(stderr,"Trying to find PIDs\n");
1423 while (count < rx->inflength-IN_SIZE){
1424 if ((re = save_read(rx,buf,IN_SIZE))<0)
1425 perror("reading");
1426 else
1427 count += re;
1428 if ( (re = find_pids_pos(&vp, &ap, &cp, buf, re,
1429 &vpos, &apos, &cpos))){
1430 if (vp){
1431 int old=0;
1432 for (j=0; j < vn; j++){
1433 // printf("%d. %d\n",j+1,vpid[j]);
1434 if (vpid[j] == vp){
1435 old = 1;
1436 break;
1437 }
1438 }
1439 if (!old){
1440 vpid[vn]=vp;
1441
1442 printf("vpid %d: 0x%04x (%d) PES ID: 0x%02x\n",
1443 vn+1,
1444 (int)vpid[vn], (int)vpid[vn],
1445 buf[vpos]);
1446 if (vn+1 < MAXVPID) vn++;
1447 }
1448 }
1449
1450 if (ap){
1451 int old=0;
1452 for (j=0; j < an; j++)
1453 if (apid[j] == ap){
1454 old = 1;
1455 break;
1456 }
1457 if (!old){
1458 apid[an]=ap;
1459 printf("apid %d: 0x%04x (%d) PES ID: 0x%02x\n",
1460 an +1,
1461 (int)apid[an],(int)apid[an],
1462 buf[apos]);
1463 if (an+1 < MAXAPID) an++;
1464 }
1465 }
1466
1467 if (cp){
1468 int old=0;
1469 for (j=0; j < ac3n; j++)
1470 if (ac3pid[j] == cp){
1471 old = 1;
1472 break;
1473 }
1474 if (!old){
1475 ac3pid[ac3n]=cp;
1476 printf("ac3pid %d: 0x%04x (%d) \n",
1477 ac3n+1,
1478 (int)ac3pid[ac3n],
1479 (int)ac3pid[ac3n]);
1480 if (ac3n+1< MAXAC3PID) ac3n++;
1481 }
1482 }
1483 }
1484
1485 }
1486
1487 lseek(rx->fd_in,0,SEEK_SET);
1488 }
1489
find_pids_stdin(struct replex * rx,uint8_t * buf,int len)1490 void find_pids_stdin(struct replex *rx, uint8_t *buf, int len)
1491 {
1492 int afound=0;
1493 int vfound=0;
1494 uint16_t vpid=0, apid=0, ac3pid=0;
1495
1496 if (rx->vpid) vfound = 1;
1497 if (rx->apidn) afound = 1;
1498 fprintf(stderr,"Trying to find PIDs\n");
1499 if ( find_pids(&vpid, &apid, &ac3pid, buf, len) ){
1500 if (!rx->vpid && vpid){
1501 rx->vpid = vpid;
1502 vfound++;
1503 }
1504 if (!rx->apidn && apid){
1505 rx->apid[0] = apid;
1506 rx->apidn++;
1507 afound++;
1508 ring_init(&rx->arbuffer[0], rx->audiobuf);
1509 init_pes_in(&rx->paudio[0], 1, &rx->arbuffer[0], 0);
1510 rx->paudio[0].priv = (void *) rx;
1511 ring_init(&rx->index_arbuffer[0], INDEX_BUF);
1512 memset(&rx->aframe[0], 0, sizeof(audio_frame_t));
1513 init_index(&rx->current_aindex[0]);
1514 rx->aframe_count[0] = 0;
1515 rx->first_apts[0] = 0;
1516 }
1517
1518 if (!rx->ac3n && ac3pid){
1519 rx->ac3_id[0] = ac3pid;
1520 rx->ac3n++;
1521 afound++;
1522 ring_init(&rx->ac3rbuffer[0], rx->ac3buf);
1523 init_pes_in(&rx->pac3[0], 0x80, &rx->ac3rbuffer[0],0);
1524 rx->pac3[0].priv = (void *) rx;
1525 ring_init(&rx->index_ac3rbuffer[0], INDEX_BUF);
1526 memset(&rx->ac3frame[0], 0, sizeof(audio_frame_t));
1527 init_index(&rx->current_ac3index[0]);
1528 rx->ac3frame_count[0] = 0;
1529 rx->first_ac3pts[0] = 0;
1530 }
1531
1532 }
1533
1534 if (afound && vfound){
1535 fprintf(stderr,"found ");
1536 if (rx->vpid) fprintf(stderr,"vpid %d (0x%04x) ",
1537 rx->vpid, rx->vpid);
1538 if (rx->apidn) fprintf(stderr,"apid %d (0x%04x) ",
1539 rx->apid[0], rx->apid[0]);
1540 if (rx->ac3n) fprintf(stderr,"ac3pid %d (0x%04x) ",
1541 rx->ac3_id[0], rx->ac3_id[0]);
1542 fprintf(stderr,"\n");
1543 }
1544 else {
1545 fprintf(stderr,"Couldn't find pids\n");
1546 exit(1);
1547 }
1548
1549 }
1550
1551
pes_id_out(pes_in_t * p)1552 void pes_id_out(pes_in_t *p)
1553 {
1554
1555 struct replex *rx;
1556 int len;
1557
1558 len = p->plength-3-p->hlength;
1559 rx = (struct replex *) p->priv;
1560
1561 rx->scan_found=0;
1562 switch (p->cid){
1563 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1564 rx->scan_found=p->cid;
1565 break;
1566
1567 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1568 rx->scan_found=p->cid;
1569 break;
1570
1571 case PRIVATE_STREAM1:
1572 if (rx->vdr){
1573 rx->scan_found = 0x80;
1574 break;
1575 }
1576 else {
1577
1578 uint8_t id = p->buf[9+p->hlength];
1579 switch (id){
1580 case 0x80 ... 0x8f:
1581 {
1582 int c=0;
1583 uint16_t fframe;
1584
1585 fframe=0;
1586 fframe = p->buf[9+p->hlength+3];
1587 fframe |= (p->buf[9+p->hlength+2]<<8);
1588
1589 if (fframe < p->plength){
1590 if ((c=find_audio_s(p->buf,
1591 9+p->hlength+4+fframe,
1592 AC3, p->plength+6)) >= 0){
1593 rx->scan_found = id;
1594 //fprintf(stderr,"0x%04x 0x%04x \n",
1595 //c-9-p->hlength-4,fframe);
1596 // if (id>0x80)show_buf(p->buf+9+p->hlength,8);
1597 // if (id>0x80)show_buf(p->buf+c,8);
1598 }
1599 }
1600 break;
1601 }
1602 }
1603 break;
1604 }
1605 default:
1606 p->cid = 0;
1607 p->type = 0;
1608 rx->scan_found=0;
1609 memset(p->buf,0,MAX_PLENGTH*sizeof(uint8_t));
1610 return;
1611 }
1612 }
1613
find_pes_ids(struct replex * rx)1614 void find_pes_ids(struct replex *rx)
1615 {
1616 uint8_t buf[IN_SIZE];
1617 int count=0;
1618 int j;
1619 int re=0;
1620 uint16_t vpid[MAXVPID], apid[MAXAPID], ac3pid[MAXAC3PID];
1621 int vn=0, an=0,ac3n=0;
1622
1623 memset (vpid , 0 , MAXVPID*sizeof(uint16_t));
1624 memset (apid , 0 , MAXAPID*sizeof(uint16_t));
1625 memset (ac3pid , 0 , MAXAC3PID*sizeof(uint16_t));
1626
1627 fprintf(stderr,"Trying to find PES IDs\n");
1628 rx->scan_found=0;
1629 rx->pvideo.priv = rx ;
1630 while (count < 50000000 && count < rx->inflength-IN_SIZE){
1631 if ((re = save_read(rx,buf,IN_SIZE))<0)
1632 perror("reading");
1633 else
1634 count += re;
1635
1636 get_pes(&rx->pvideo, buf, re, pes_id_out);
1637
1638 if ( rx->scan_found ){
1639
1640 switch (rx->scan_found){
1641
1642 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1643 {
1644 int old=0;
1645 for (j=0; j < vn; j++){
1646 // printf("%d. %d\n",j+1,vpid[j]);
1647 if (vpid[j] == rx->scan_found){
1648 old = 1;
1649 break;
1650 }
1651 }
1652 if (!old){
1653 vpid[vn]=rx->scan_found;
1654
1655 printf("MPEG VIDEO %d: 0x%02x (%d)\n",
1656 vn+1,
1657 (int)vpid[vn], (int)vpid[vn]);
1658 if (vn+1 < MAXVPID) vn++;
1659 }
1660 }
1661 break;
1662
1663
1664 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1665 {
1666 int old=0;
1667 for (j=0; j < an; j++)
1668 if (apid[j] == rx->scan_found){
1669 old = 1;
1670 break;
1671 }
1672 if (!old){
1673 apid[an] = rx->apid[an] = rx->scan_found;
1674 printf("MPEG AUDIO %d: 0x%02x (%d)\n",
1675 an +1,
1676 (int)apid[an],(int)apid[an]);
1677 if (an+1 < MAXAPID) an++;
1678 }
1679 }
1680 break;
1681
1682 case 0x80 ... 0x8f:
1683 {
1684 int old=0;
1685 for (j=0; j < ac3n; j++)
1686 if (ac3pid[j] == rx->scan_found){
1687 old = 1;
1688 break;
1689 }
1690 if (!old){
1691 ac3pid[ac3n]=rx->ac3_id[ac3n]=rx->scan_found;
1692 if (rx->vdr){
1693 printf("possible AC3 AUDIO with private stream 1 pid (0xbd) \n");
1694 }
1695 else {
1696 printf("AC3 AUDIO %d: 0x%02x (%d) \n",
1697 ac3n+1,
1698 (int)ac3pid[ac3n],
1699 (int)ac3pid[ac3n]);
1700 }
1701 if (ac3n+1< MAXAC3PID) ac3n++;
1702 }
1703 rx->scan_found = 0;
1704 }
1705 break;
1706 }
1707 rx->scan_found = 0;
1708 }
1709 }
1710 rx->ac3n = ac3n;
1711 rx->apidn = an;
1712 }
1713
1714
1715
replex_finish(struct replex * rx)1716 void replex_finish(struct replex *rx)
1717 {
1718
1719 fprintf(stderr,"\n");
1720 if (!replex_all_set(rx)){
1721 fprintf(stderr,"Can't find all required streams\n");
1722 if (rx->itype == REPLEX_PS){
1723 fprintf(stderr,"Please check if audio and video have standard IDs (0xc0 or 0xe0)\n");
1724 }
1725 exit(1);
1726 }
1727
1728 if (!rx->demux)
1729 finish_mpg((multiplex_t *)rx->priv);
1730 exit(0);
1731 }
1732
replex_fill_buffers(struct replex * rx,uint8_t * mbuf)1733 int replex_fill_buffers(struct replex *rx, uint8_t *mbuf)
1734 {
1735 uint8_t buf[IN_SIZE];
1736 int i,j;
1737 int count=0;
1738 int fill;
1739 int re;
1740 int rsize;
1741 int tries = 0;
1742
1743 if (rx->finish) return 0;
1744 fill = guess_fill(rx);
1745 //fprintf(stderr,"trying to fill buffers with %d\n",fill);
1746 if (fill < 0) return -1;
1747
1748 memset(buf, 0, IN_SIZE);
1749
1750 switch(rx->itype){
1751 case REPLEX_TS:
1752 if (fill < IN_SIZE){
1753 rsize = fill - (fill%188);
1754 } else rsize = IN_SIZE;
1755
1756 // fprintf(stderr,"filling with %d\n",rsize);
1757
1758 if (!rsize) return 0;
1759
1760 memset(buf, 0, IN_SIZE);
1761
1762 if ( mbuf ){
1763 for ( i = 0; i < 188 ; i++){
1764 if ( mbuf[i] == 0x47 ) break;
1765 }
1766
1767 if ( i == 188){
1768 fprintf(stderr,"Not a TS\n");
1769 return -1;
1770 } else {
1771 memcpy(buf,mbuf+i,2*TS_SIZE-i);
1772 if ((count = save_read(rx,mbuf,i))<0)
1773 perror("reading");
1774 memcpy(buf+2*TS_SIZE-i,mbuf,i);
1775 i = 188;
1776 }
1777 } else i=0;
1778
1779
1780 #define MAX_TRIES 5
1781 while (count < rsize && tries < MAX_TRIES){
1782 if ((re = save_read(rx,buf+i,rsize-i)+i)<0)
1783 perror("reading");
1784 else
1785 count += re;
1786 tries++;
1787
1788 if (!rx->vpid || !(rx->apidn || rx->ac3n)){
1789 find_pids_stdin(rx, buf, re);
1790 }
1791
1792 for( j = 0; j < re; j+= TS_SIZE){
1793
1794 if ( re - j < TS_SIZE) break;
1795
1796 if ( replex_tsp( rx, buf+j) < 0){
1797 fprintf(stderr, "Error reading TS\n");
1798 exit(1);
1799 }
1800 }
1801 i=0;
1802 }
1803
1804 if (tries == MAX_TRIES)
1805 replex_finish(rx);
1806 return 0;
1807 break;
1808
1809 case REPLEX_PS:
1810 rsize = fill;
1811 if (fill > IN_SIZE) rsize = IN_SIZE;
1812 if (mbuf)
1813 get_pes(&rx->pvideo, mbuf, 2*TS_SIZE, pes_es_out);
1814
1815 while (count < rsize && tries < MAX_TRIES){
1816 if ((re = save_read(rx, buf, rsize))<0)
1817 perror("reading PS");
1818 else
1819 count += re;
1820
1821 get_pes(&rx->pvideo, buf, re, pes_es_out);
1822
1823 tries++;
1824
1825 }
1826
1827 if (tries == MAX_TRIES)
1828 replex_finish(rx);
1829 return 0;
1830 break;
1831
1832
1833 case REPLEX_AVI:
1834 rsize = fill;
1835 if (fill > IN_SIZE) rsize = IN_SIZE;
1836
1837 if (!(rx->ac.avih_flags & AVI_HASINDEX)){
1838
1839 if (mbuf){
1840 get_avi(&rx->pvideo, mbuf, rx->avi_rest, avi_es_out);
1841 }
1842
1843 while (count < rsize && tries < MAX_TRIES){
1844 if ((re = save_read(rx, buf, rsize))<0)
1845 perror("reading AVI");
1846 else
1847 count += re;
1848
1849 get_avi(&rx->pvideo, buf, re, avi_es_out);
1850
1851 tries++;
1852 }
1853 } else {
1854 if (get_avi_from_index(&rx->pvideo, rx->fd_in,
1855 &rx->ac, avi_es_out, rsize) < 0)
1856 tries = MAX_TRIES;
1857 }
1858
1859 if (tries == MAX_TRIES)
1860 replex_finish(rx);
1861 return 0;
1862 break;
1863 }
1864
1865 return -1;
1866 }
1867
fill_buffers(void * r,int finish)1868 int fill_buffers(void *r, int finish)
1869 {
1870 struct replex *rx = (struct replex *)r;
1871
1872 rx->finish = finish;
1873
1874 return replex_fill_buffers(rx, NULL);
1875 }
1876
1877
init_index(index_unit * iu)1878 void init_index(index_unit *iu)
1879 {
1880 memset(iu,0, sizeof(index_unit));
1881 iu->frame_start = 1;
1882 }
1883
replex_all_set(struct replex * rx)1884 static int replex_all_set(struct replex *rx)
1885 {
1886 int i;
1887 int set=0;
1888
1889 for (i=0; i < rx->ac3n ;i++){
1890 set += rx->ac3frame[i].set;
1891 }
1892 for (i=0; i<rx->apidn;i++){
1893 set += rx->aframe[i].set;
1894 }
1895 set += rx->seq_head.set;
1896
1897 if (set == (rx->ac3n+ rx->apidn + 1)) return 1;
1898 return 0;
1899 }
1900
1901
check_stream_type(struct replex * rx,uint8_t * buf,int len)1902 int check_stream_type(struct replex *rx, uint8_t * buf, int len)
1903 {
1904 int c=0;
1905 avi_context ac;
1906 uint8_t head;
1907
1908 if (rx->itype != REPLEX_TS) return rx->itype;
1909
1910 if (len< 2*TS_SIZE){
1911 fprintf(stderr,"cannot determine streamtype");
1912 exit(1);
1913 }
1914
1915 fprintf(stderr, "Checking for TS: ");
1916 while (c < len && buf[c]!=0x47) c++;
1917 if (c<len && len-c>=TS_SIZE){
1918 if (buf[c+TS_SIZE] == 0x47){
1919 fprintf(stderr,"confirmed\n");
1920 return REPLEX_TS;
1921 } else fprintf(stderr,"failed\n");
1922 } else fprintf(stderr,"failed\n");
1923
1924 fprintf(stderr, "Checking for AVI: ");
1925 if (check_riff(&ac, buf, len)>=0){
1926 fprintf(stderr,"confirmed\n");
1927 rx->itype = REPLEX_AVI;
1928 rx->vpid = 0xE0;
1929 rx->apidn = 1;
1930 rx->apid[0] = 0xC0;
1931 rx->ignore_pts =1;
1932 return REPLEX_AVI;
1933 } else fprintf(stderr,"failed\n");
1934
1935 fprintf(stderr, "Checking for PS: ");
1936 if (find_any_header(&head, buf, len) >= 0){
1937 fprintf(stderr,"confirmed(maybe)\n");
1938 } else {
1939 fprintf(stderr,"failed, trying it anyway\n");
1940 }
1941 rx->itype=REPLEX_PS;
1942 if (!rx->vpid) rx->vpid = 0xE0;
1943 if (!(rx->apidn || rx->ac3n)){
1944 rx->apidn = 1;
1945 rx->apid[0] = 0xC0;
1946 }
1947 return REPLEX_PS;
1948 }
1949
1950
init_replex(struct replex * rx,int bufsize)1951 void init_replex(struct replex *rx,int bufsize)
1952 {
1953 int i;
1954 uint8_t mbuf[2*TS_SIZE];
1955
1956 int VIDEO_BUF, AUDIO_BUF, AC3_BUF;
1957
1958 VIDEO_BUF = bufsize;
1959 AUDIO_BUF = (VIDEO_BUF/10);
1960 AC3_BUF = (VIDEO_BUF/10);
1961
1962 rx->analyze=0;
1963
1964 if (save_read(rx, mbuf, 2*TS_SIZE)<0)
1965 perror("reading");
1966
1967 check_stream_type(rx, mbuf, 2*TS_SIZE);
1968 if (rx->itype == REPLEX_TS){
1969 if (!rx->vpid || !(rx->apidn || rx->ac3n)){
1970 if (rx->inflength){
1971 find_pids_file(rx);
1972 }
1973 }
1974 }
1975
1976 if (rx->otype==REPLEX_HDTV){
1977 rx->videobuf = 4*VIDEO_BUF;
1978 } else {
1979 rx->videobuf = VIDEO_BUF;
1980 }
1981 rx->audiobuf = AUDIO_BUF;
1982 rx->ac3buf = AC3_BUF;
1983
1984 if (rx->itype == REPLEX_AVI){
1985 rx->videobuf = 4*VIDEO_BUF;
1986 rx->audiobuf = 2*rx->videobuf;
1987 }
1988
1989 rx->vpes_abort = 0;
1990 rx->first_iframe = 0;
1991 ring_init(&rx->vrbuffer, rx->videobuf);
1992 if (rx->itype == REPLEX_TS || rx->itype == REPLEX_AVI)
1993 init_pes_in(&rx->pvideo, 0xE0, &rx->vrbuffer, 0);
1994 else if (rx->itype == REPLEX_PS){
1995 init_pes_in(&rx->pvideo, 0, NULL, 1);
1996 // find_pes_in(rx);
1997 } else init_pes_in(&rx->pvideo, 0, NULL, 1);
1998
1999 rx->pvideo.priv = (void *) rx;
2000 ring_init(&rx->index_vrbuffer, INDEX_BUF);
2001 memset(&rx->seq_head, 0, sizeof(sequence_t));
2002 init_index(&rx->current_vindex);
2003 rx->vgroup_count = 0;
2004 rx->vframe_count = 0;
2005 rx->first_vpts = 0;
2006 rx->video_state = S_SEARCH;
2007 rx->last_vpts = 0;
2008
2009 for (i=0; i<rx->apidn;i++){
2010
2011 rx->apes_abort[i] = 0;
2012 rx->audio_state[i] = S_SEARCH;
2013 ring_init(&rx->arbuffer[i], rx->audiobuf);
2014
2015 if (rx->itype == REPLEX_TS){
2016 init_pes_in(&rx->paudio[i], i+1,
2017 &rx->arbuffer[i], 0);
2018 rx->paudio[i].priv = (void *) rx;
2019 }
2020 ring_init(&rx->index_arbuffer[i], INDEX_BUF);
2021 memset(&rx->aframe[i], 0, sizeof(audio_frame_t));
2022 init_index(&rx->current_aindex[i]);
2023 rx->aframe_count[i] = 0;
2024 rx->first_apts[i] = 0;
2025 rx->last_apts[i] = 0;
2026 }
2027
2028 for (i=0; i<rx->ac3n;i++){
2029 rx->ac3pes_abort[i] = 0;
2030 rx->ac3_state[i] = S_SEARCH;
2031 ring_init(&rx->ac3rbuffer[i], AC3_BUF);
2032 if (rx->itype == REPLEX_TS){
2033 init_pes_in(&rx->pac3[i], 0x80+i,
2034 &rx->ac3rbuffer[i],0);
2035 rx->pac3[i].priv = (void *) rx;
2036 }
2037 ring_init(&rx->index_ac3rbuffer[i], INDEX_BUF);
2038 memset(&rx->ac3frame[i], 0, sizeof(audio_frame_t));
2039 init_index(&rx->current_ac3index[i]);
2040 rx->ac3frame_count[i] = 0;
2041 rx->first_ac3pts[i] = 0;
2042 rx->last_ac3pts[i] = 0;
2043 }
2044
2045 if (rx->itype == REPLEX_TS){
2046 if (replex_fill_buffers(rx, mbuf)< 0){
2047 fprintf(stderr,"error filling buffer\n");
2048 exit(1);
2049 }
2050 } else if ( rx->itype == REPLEX_AVI){
2051 #define AVI_S 1024
2052 avi_context *ac;
2053 uint8_t buf[AVI_S];
2054 int re=0;
2055
2056 lseek(rx->fd_in, 0, SEEK_SET);
2057 ac = &rx->ac;
2058 memset(ac, 0, sizeof(avi_context));
2059 save_read(rx, buf, 12);
2060
2061 if (check_riff(ac, buf, 12) < 0){
2062 fprintf(stderr, "Wrong RIFF header\n");
2063 exit(1);
2064 } else {
2065 fprintf(stderr,"Found RIFF header\n");
2066 }
2067
2068 memset(ac, 0, sizeof(avi_context));
2069 re = read_avi_header(ac, rx->fd_in);
2070 if (avi_read_index(ac,rx->fd_in) < 0){
2071 fprintf(stderr, "Error reading index\n");
2072 exit(1);
2073 }
2074 // rx->aframe_count[0] = ac->ai[0].initial_frames;
2075 rx->vframe_count = ac->ai[0].initial_frames*ac->vi.fps/
2076 ac->ai[0].fps;
2077
2078 rx->inflength = lseek(rx->fd_in, 0, SEEK_CUR)+ac->movi_length;
2079
2080 fprintf(stderr,"AVI initial frames %d\n",
2081 (int)rx->vframe_count);
2082 if (!ac->done){
2083 fprintf(stderr,"Error reading AVI header\n");
2084 exit(1);
2085 }
2086
2087 if (replex_fill_buffers(rx, buf+re)< 0){
2088 fprintf(stderr,"error filling buffer\n");
2089 exit(1);
2090 }
2091 } else {
2092 if (replex_fill_buffers(rx, mbuf)< 0){
2093 fprintf(stderr,"error filling buffer\n");
2094 exit(1);
2095 }
2096 }
2097
2098 }
2099
2100
fix_audio(struct replex * rx,multiplex_t * mx)2101 void fix_audio(struct replex *rx, multiplex_t *mx)
2102 {
2103 int i;
2104 index_unit aiu;
2105 int size;
2106
2107 size = sizeof(index_unit);
2108
2109 for ( i = 0; i < rx->apidn; i++){
2110 do {
2111 while (ring_avail(&rx->index_arbuffer[i]) <
2112 sizeof(index_unit)){
2113 if (replex_fill_buffers(rx, 0)< 0){
2114 fprintf(stderr,
2115 "error in fix audio\n");
2116 exit(1);
2117 }
2118 }
2119 ring_peek(&rx->index_arbuffer[i], (uint8_t *)&aiu,
2120 size, 0);
2121 if ( ptscmp(aiu.pts + rx->first_apts[i], rx->first_vpts) < 0){
2122 ring_skip(&rx->index_arbuffer[i], size);
2123 ring_skip(&rx->arbuffer[i], aiu.length);
2124 } else break;
2125
2126 } while (1);
2127 mx->apts_off[i] = aiu.pts;
2128 rx->apts_off[i] = aiu.pts;
2129 mx->aframes[i] = aiu.framesize;
2130
2131 fprintf(stderr,"Audio%d offset: ",i);
2132 printpts(mx->apts_off[i]);
2133 printpts(rx->first_apts[i]+mx->apts_off[i]);
2134 fprintf(stderr,"\n");
2135 }
2136
2137 for ( i = 0; i < rx->ac3n; i++){
2138 do {
2139 while (ring_avail(&rx->index_ac3rbuffer[i]) <
2140 sizeof(index_unit)){
2141 if (replex_fill_buffers(rx, 0)< 0){
2142 fprintf(stderr,
2143 "error in fix audio\n");
2144 exit(1);
2145 }
2146 }
2147 ring_peek(&rx->index_ac3rbuffer[i],(uint8_t *) &aiu,
2148 size, 0);
2149 if ( ptscmp (aiu.pts+rx->first_ac3pts[i], rx->first_vpts) < 0){
2150 ring_skip(&rx->index_ac3rbuffer[i], size);
2151 ring_skip(&rx->ac3rbuffer[i], aiu.length);
2152 } else break;
2153 } while (1);
2154 mx->ac3pts_off[i] = aiu.pts;
2155 rx->ac3pts_off[i] = aiu.pts;
2156
2157 fprintf(stderr,"AC3%d offset: ",i);
2158 printpts(mx->ac3pts_off[i]);
2159 printpts(rx->first_ac3pts[i]+mx->ac3pts_off[i]);
2160 fprintf(stderr,"\n");
2161
2162 }
2163 }
2164
2165
2166
get_next_video_unit(struct replex * rx,index_unit * viu)2167 static int get_next_video_unit(struct replex *rx, index_unit *viu)
2168 {
2169 if (ring_avail(&rx->index_vrbuffer)){
2170 ring_read(&rx->index_vrbuffer, (uint8_t *)viu,
2171 sizeof(index_unit));
2172 return 1;
2173 }
2174 return 0;
2175 }
2176
get_next_audio_unit(struct replex * rx,index_unit * aiu,int i)2177 static int get_next_audio_unit(struct replex *rx, index_unit *aiu, int i)
2178 {
2179 if(ring_avail(&rx->index_arbuffer[i])){
2180 ring_read(&rx->index_arbuffer[i], (uint8_t *)aiu,
2181 sizeof(index_unit));
2182 return 1;
2183 }
2184 return 0;
2185 }
2186
get_next_ac3_unit(struct replex * rx,index_unit * aiu,int i)2187 static int get_next_ac3_unit(struct replex *rx, index_unit *aiu, int i)
2188 {
2189 if (ring_avail(&rx->index_ac3rbuffer[i])){
2190 ring_read(&rx->index_ac3rbuffer[i], (uint8_t *)aiu,
2191 sizeof(index_unit));
2192
2193 return 1;
2194 }
2195 return 0;
2196 }
2197
2198
do_analyze(struct replex * rx)2199 void do_analyze(struct replex *rx)
2200 {
2201 index_unit dummy;
2202 index_unit dummy2;
2203 int i;
2204 uint64_t lastvpts;
2205 uint64_t lastvdts;
2206 uint64_t lastapts[N_AUDIO];
2207 uint64_t lastac3pts[N_AC3];
2208 int av;
2209
2210 av = rx->analyze-1;
2211
2212 lastvpts = 0;
2213 lastvdts = 0;
2214 memset(lastapts, 0, N_AUDIO*sizeof(uint64_t));
2215 memset(lastac3pts, 0, N_AC3*sizeof(uint64_t));
2216
2217 fprintf(stderr,"STARTING ANALYSIS\n");
2218
2219
2220 while(!rx->finish){
2221 if (replex_fill_buffers(rx, 0)< 0){
2222 fprintf(stderr,"error in get next video unit\n");
2223 return;
2224 }
2225 for (i=0; i< rx->apidn; i++){
2226 while(get_next_audio_unit(rx, &dummy2, i)){
2227 ring_skip(&rx->arbuffer[i],
2228 dummy2.length);
2229 if (av>=1){
2230 fprintf(stdout,
2231 "MPG2 Audio%d unit: ",
2232 i);
2233 fprintf(stdout,
2234 " length %d PTS ",
2235 dummy2.length);
2236 printptss(dummy2.pts);
2237
2238 if (lastapts[i]){
2239 fprintf(stdout," diff:");
2240 printptss(ptsdiff(dummy2.pts,lastapts[i]));
2241 }
2242 lastapts[i] = dummy2.pts;
2243
2244 fprintf(stdout,"\n");
2245 }
2246 }
2247 }
2248
2249 for (i=0; i< rx->ac3n; i++){
2250 while(get_next_ac3_unit(rx, &dummy2, i)){
2251 ring_skip(&rx->ac3rbuffer[i],
2252 dummy2.length);
2253 if (av>=1){
2254 fprintf(stdout,
2255 "AC3 Audio%d unit: ",
2256 i);
2257 fprintf(stdout,
2258 " length %d PTS ",
2259 dummy2.length);
2260 printptss(dummy2.pts);
2261 if (lastac3pts[i]){
2262 fprintf(stdout," diff:");
2263 printptss(ptsdiff(dummy2.pts, lastac3pts[i]));
2264 }
2265 lastac3pts[i] = dummy2.pts;
2266
2267 fprintf(stdout,"\n");
2268 }
2269 }
2270 }
2271
2272 while (get_next_video_unit(rx, &dummy)){
2273 ring_skip(&rx->vrbuffer,
2274 dummy.length);
2275 if (av==0 || av==2){
2276 fprintf(stdout,
2277 "Video unit: ");
2278 if (dummy.seq_header){
2279 fprintf(stdout,"Sequence header ");
2280 }
2281 if (dummy.gop){
2282 fprintf(stdout,"GOP header ");
2283 }
2284 switch (dummy.frame){
2285 case I_FRAME:
2286 fprintf(stdout, "I-frame");
2287 break;
2288 case B_FRAME:
2289 fprintf(stdout, "B-frame");
2290 break;
2291 case P_FRAME:
2292 fprintf(stdout, "P-frame");
2293 break;
2294 }
2295 fprintf(stdout,
2296 " length %d PTS ",
2297 dummy.length);
2298 printptss(dummy.pts);
2299 if (lastvpts){
2300 fprintf(stdout," diff:");
2301 printptss(ptsdiff(dummy.pts, lastvpts));
2302 }
2303 lastvpts = dummy.pts;
2304
2305 fprintf(stdout,
2306 " DTS ");
2307 printptss(dummy.dts);
2308 if (lastvdts){
2309 fprintf(stdout," diff:");
2310 printptss(ptsdiff(dummy.dts,lastvdts));
2311 }
2312 lastvdts = dummy.dts;
2313
2314 fprintf(stdout,"\n");
2315 }
2316 }
2317 }
2318
2319
2320 }
2321
do_scan(struct replex * rx)2322 void do_scan(struct replex *rx)
2323 {
2324 uint8_t mbuf[2*TS_SIZE];
2325
2326 rx->analyze=0;
2327
2328 if (save_read(rx, mbuf, 2*TS_SIZE)<0)
2329 perror("reading");
2330
2331 fprintf(stderr,"STARTING SCAN\n");
2332
2333 check_stream_type(rx, mbuf, 2*TS_SIZE);
2334
2335 switch(rx->itype){
2336 case REPLEX_TS:
2337 find_all_pids_file(rx);
2338 break;
2339
2340 case REPLEX_PS:
2341 init_pes_in(&rx->pvideo, 0, NULL, 1);
2342 find_pes_ids(rx);
2343 break;
2344
2345 case REPLEX_AVI:
2346 break;
2347 }
2348
2349 }
2350
do_demux(struct replex * rx)2351 void do_demux(struct replex *rx)
2352 {
2353 index_unit dummy;
2354 index_unit dummy2;
2355 int i;
2356 multiplex_t mx;
2357 fprintf(stderr,"STARTING DEMUX\n");
2358
2359
2360 while (!replex_all_set(rx)){
2361 if (replex_fill_buffers(rx, 0)< 0){
2362 fprintf(stderr,"error filling buffer\n");
2363 exit(1);
2364 }
2365 }
2366
2367 fix_audio(rx, &mx);
2368
2369 while(!rx->finish){
2370 if (replex_fill_buffers(rx, 0)< 0){
2371 fprintf(stderr,"error in get next video unit\n");
2372 return;
2373 }
2374 for (i=0; i< rx->apidn; i++){
2375 while(get_next_audio_unit(rx, &dummy2, i)){
2376 switch(dummy2.err){
2377 case JUMP_ERR:
2378 ring_skip(&rx->arbuffer[i],dummy2.length);
2379 break;
2380 case DUMMY_ERR:
2381 write(rx->dmx_out[i+1],dummy.fillframe,dummy2.length);
2382 break;
2383 default:
2384 ring_read_file(&rx->arbuffer[i],
2385 rx->dmx_out[i+1],
2386 dummy2.length);
2387 }
2388 }
2389 }
2390
2391 for (i=0; i< rx->ac3n; i++){
2392 while(get_next_ac3_unit(rx, &dummy2, i)){
2393 switch(dummy2.err){
2394 case JUMP_ERR:
2395 ring_skip(&rx->ac3rbuffer[i],dummy2.length);
2396 break;
2397 case DUMMY_ERR:
2398 write(rx->dmx_out[i+1+rx->apidn],dummy.fillframe,dummy2.length);
2399 break;
2400 default:
2401 ring_read_file(&rx->ac3rbuffer[i],
2402 rx->dmx_out[i+1+rx->apidn],
2403 dummy2.length);
2404 }
2405 }
2406 }
2407
2408 while (get_next_video_unit(rx, &dummy)){
2409 ring_read_file(&rx->vrbuffer, rx->dmx_out[0],
2410 dummy.length);
2411 }
2412 }
2413 }
2414
2415
do_replex(struct replex * rx)2416 void do_replex(struct replex *rx)
2417 {
2418 int video_ok = 0;
2419 int audio_ok[N_AUDIO];
2420 int ac3_ok[N_AC3];
2421 int start=1;
2422 multiplex_t mx;
2423 int done = 0;
2424
2425
2426 fprintf(stderr,"STARTING REPLEX\n");
2427 memset(&mx, 0, sizeof(mx));
2428 memset(audio_ok, 0, N_AUDIO*sizeof(int));
2429 memset(ac3_ok, 0, N_AC3*sizeof(int));
2430
2431 while (!replex_all_set(rx)){
2432 if (replex_fill_buffers(rx, 0)< 0){
2433 fprintf(stderr,"error filling buffer\n");
2434 exit(1);
2435 }
2436 }
2437
2438 mx.priv = (void *) rx;
2439 rx->priv = (void *) &mx;
2440 init_multiplex(&mx, &rx->seq_head, rx->aframe, rx->ac3frame,
2441 rx->apidn, rx->ac3n, rx->video_delay,
2442 rx->audio_delay, rx->fd_out, fill_buffers,
2443 &rx->vrbuffer, &rx->index_vrbuffer,
2444 rx->arbuffer, rx->index_arbuffer,
2445 rx->ac3rbuffer, rx->index_ac3rbuffer, rx->otype);
2446
2447 if (!rx->ignore_pts){
2448 fix_audio(rx, &mx);
2449 }
2450 setup_multiplex(&mx);
2451
2452 do {
2453 check_times( &mx, &video_ok, audio_ok, ac3_ok, &start);
2454
2455 write_out_packs( &mx, video_ok, audio_ok, ac3_ok);
2456
2457 if (mx.max_reached) done = 1;
2458 if (mx.zero_write_count >100){
2459 fprintf(stderr,"Can`t continue, check input file\n");
2460 done=1;
2461 }
2462 } while (!done);
2463
2464 }
2465
2466
usage(char * progname)2467 void usage(char *progname)
2468 {
2469 printf ("usage: %s [options] <input files>\n\n",progname);
2470 printf ("options:\n");
2471 printf (" --help, -h : print help message\n");
2472 printf ("\n");
2473 printf (" --audio_pid, -a <integer> : audio PID for TS stream (also used for PS id, default 0xc0)\n");
2474 printf (" --ac3_id, -c <integer> : ID of AC3 audio for demux (also used for PS id, i.e. 0x80)\n");
2475 printf (" --video_delay, -d <integer> : video delay in ms\n");
2476 printf (" --audio_delay, -e <integer> : audio delay in ms\n");
2477 printf (" --ignore_PTS, -f : ignore all PTS information of original\n");
2478 printf (" --larger_buffer -g <integer> : video buffer in MB\n");
2479 printf (" --input_stream, -i <string> : set input stream type (string = TS(default), PS, AVI)\n");
2480 printf (" --allow_jump, -j : allow jump in the PTS and try repair\n");
2481 printf (" --keep_PTS, -k : keep and don't correct PTS information of original\n");
2482 printf (" --min_jump, -l <integer> : don't try to fix jumps in PTS larger than <int> but treat them as a cut (default 100ms)\n");
2483 printf (" --of, -o <filename> : set output file\n");
2484 printf (" --fillzero -p : fill audio frames with zeros (only MPEG AUDIO)\n");
2485 printf (" --max_overflow -q <integer> : max_number of overflows allowed (default: 100, 0=no restriction)\n");
2486 printf (" --scan, -s : scan for streams\n");
2487 printf (" --type, -t <string> : set output type (string = MPEG2, DVD, HDTV)\n");
2488 printf (" --video_pid, -v <integer> : video PID for TS stream (also used for PS id, default 0xe0)\n");
2489 printf (" --vdr, -x : handle AC3 for vdr input file\n");
2490 printf (" --analyze, -y <integer> : analyze (0=video,1=audio, 2=both)\n");
2491 printf (" --demux, -z : demux only (-o is basename)\n");
2492 exit(1);
2493 }
2494
main(int argc,char ** argv)2495 int main(int argc, char **argv)
2496 {
2497 int c;
2498 int analyze=0;
2499 int scan =0;
2500 char *filename = NULL;
2501 char *type = "SVCD";
2502 char *inpt = "TS";
2503 int bufsize = 6*1024*1024;
2504 uint64_t min_jump=0;
2505 int fillzero = 0;
2506
2507 struct replex rx;
2508
2509 fprintf(stderr,"replex version %s\n", VERSION);
2510
2511 memset(&rx, 0, sizeof(struct replex));
2512 rx.max_overflows = 100;
2513
2514 while (1){
2515 int option_index = 0;
2516 static struct option long_options[] = {
2517 {"audio_pid", required_argument, NULL, 'a'},
2518 {"ac3_id", required_argument, NULL, 'c'},
2519 {"video_delay", required_argument, NULL, 'd'},
2520 {"audio_delay", required_argument, NULL, 'e'},
2521 {"ignore_PTS",required_argument, NULL, 'f'},
2522 {"larger_buffer",required_argument, NULL, 'g'},
2523 {"help", no_argument , NULL, 'h'},
2524 {"input_stream", required_argument, NULL, 'i'},
2525 {"allow_jump",required_argument, NULL, 'j'},
2526 {"keep_PTS",required_argument, NULL, 'k'},
2527 {"min_jump",required_argument, NULL, 'l'},
2528 {"of",required_argument, NULL, 'o'},
2529 {"fillzero",required_argument, NULL, 'p'},
2530 {"max_overflow",required_argument, NULL, 'q'},
2531 {"scan",required_argument, NULL, 's'},
2532 {"type", required_argument, NULL, 't'},
2533 {"video_pid", required_argument, NULL, 'v'},
2534 {"vdr",required_argument, NULL, 'x'},
2535 {"analyze",required_argument, NULL, 'y'},
2536 {"demux",no_argument, NULL, 'z'},
2537 {0, 0, 0, 0}
2538 };
2539 c = getopt_long (argc, argv,
2540 "a:c:d:e:fg:hi:jkl:o:pq:st:v:xy:z",
2541 long_options, &option_index);
2542 if (c == -1)
2543 break;
2544
2545 switch (c){
2546 case 'a':
2547 if (rx.apidn==N_AUDIO){
2548 fprintf(stderr,"Too many audio PIDs\n");
2549 exit(1);
2550 }
2551 rx.apid[rx.apidn] = strtol(optarg,(char **)NULL, 0);
2552 rx.apidn++;
2553 break;
2554 case 'c':
2555 if (rx.ac3n==N_AC3){
2556 fprintf(stderr,"Too many audio PIDs\n");
2557 exit(1);
2558 }
2559 rx.ac3_id[rx.ac3n] = strtol(optarg,(char **)NULL, 0);
2560 rx.ac3n++;
2561 break;
2562 case 'd':
2563 rx.video_delay = strtol(optarg,(char **)NULL, 0)
2564 *CLOCK_MS;
2565 break;
2566 case 'e':
2567 rx.audio_delay = strtol(optarg,(char **)NULL, 0)
2568 *CLOCK_MS;
2569 break;
2570 case 'f':
2571 rx.ignore_pts =1;
2572 break;
2573 case 'g':
2574 bufsize = strtol(optarg,(char **)NULL, 0) *1024*1024;
2575 break;
2576 case 'i':
2577 inpt = optarg;
2578 break;
2579 case 'j':
2580 rx.allow_jump = MIN_JUMP;
2581 break;
2582 case 'k':
2583 rx.keep_pts =1;
2584 break;
2585 case 'l':
2586 min_jump = strtol(optarg,(char **)NULL, 0) *CLOCK_MS;
2587 break;
2588 case 'o':
2589 filename = optarg;
2590 break;
2591 case 'p':
2592 fillzero = 1;
2593 break;
2594 case 'q':
2595 rx.max_overflows = strtol(optarg,(char **)NULL, 0);
2596 break;
2597 case 's':
2598 scan = 1;
2599 break;
2600 case 't':
2601 type = optarg;
2602 break;
2603 case 'v':
2604 rx.vpid = strtol(optarg,(char **)NULL, 0);
2605 break;
2606 case 'x':
2607 rx.vdr=1;
2608 break;
2609 case 'y':
2610 analyze = strtol(optarg,(char **)NULL, 0);
2611 if (analyze>2) usage(argv[0]);
2612 analyze++;
2613 break;
2614 case 'z':
2615 rx.demux = 1;
2616 break;
2617 case 'h':
2618 case '?':
2619 default:
2620 usage(argv[0]);
2621 }
2622 }
2623
2624 if (rx.allow_jump && min_jump) rx.allow_jump = min_jump;
2625
2626 if (fillzero) rx.fillzero = 1;
2627 rx.inputFiles = NULL;
2628 if (optind < argc){
2629 int i = 0;
2630 rx.inputFiles = calloc( sizeof(char * ), argc - optind + 1);
2631 while (optind < argc) {
2632 if ((rx.fd_in = open(argv[optind] ,O_RDONLY| O_LARGEFILE)) < 0){
2633 fprintf(stderr,"Error opening input file %s",argv[optind] );
2634 exit(1);
2635 }
2636 close(rx.fd_in);
2637 rx.inputFiles[i] = argv[optind];
2638 i++;
2639 optind++;
2640 }
2641 rx.inputFiles[i] = NULL;
2642 rx.inputIdx = 0;
2643 if ((rx.fd_in = open(rx.inputFiles[0] ,O_RDONLY| O_LARGEFILE)) < 0) {
2644 fprintf(stderr,"Error opening input file %s",argv[optind] );
2645 exit(1);
2646 }
2647
2648 fprintf(stderr,"Reading from %s\n", argv[optind]);
2649 rx.inflength = lseek(rx.fd_in, 0, SEEK_END);
2650 fprintf(stderr,"Input file length: %.2f MB\n",rx.inflength/1024./1024.);
2651 lseek(rx.fd_in,0,SEEK_SET);
2652 rx.lastper = 0;
2653 rx.finread = 0;
2654 } else {
2655 fprintf(stderr,"using stdin as input\n");
2656 rx.fd_in = STDIN_FILENO;
2657 rx.inflength = 0;
2658 }
2659
2660 if (!rx.demux){
2661 if (filename){
2662 if ((rx.fd_out = open(filename,O_WRONLY|O_CREAT
2663 |O_TRUNC|O_LARGEFILE,
2664 S_IRUSR|S_IWUSR|S_IRGRP|
2665 S_IWGRP|
2666 S_IROTH|S_IWOTH)) < 0){
2667 perror("Error opening output file");
2668 exit(1);
2669 }
2670 fprintf(stderr,"Output File is: %s\n",
2671 filename);
2672 } else {
2673 rx.fd_out = STDOUT_FILENO;
2674 fprintf(stderr,"using stdout as output\n");
2675 }
2676 }
2677 if (scan){
2678 if (rx.fd_in == STDIN_FILENO){
2679 fprintf(stderr,"Can`t scan from pipe\n");
2680 exit(1);
2681 }
2682 do_scan(&rx);
2683 exit(0);
2684 }
2685
2686 if (!strncmp(type,"MPEG2",6))
2687 rx.otype=REPLEX_MPEG2;
2688 else if (!strncmp(type,"DVD",4))
2689 rx.otype=REPLEX_DVD;
2690 else if (!strncmp(type,"HDTV",4))
2691 rx.otype=REPLEX_HDTV;
2692 else if (!rx.demux && !analyze)
2693 usage(argv[0]);
2694
2695 if (!strncmp(inpt,"TS",3)){
2696 rx.itype=REPLEX_TS;
2697 } else if (!strncmp(inpt,"PS",3)){
2698 rx.itype=REPLEX_PS;
2699 if (!rx.vpid) rx.vpid = 0xE0;
2700 if (!(rx.apidn || rx.ac3n)){
2701 rx.apidn = 1;
2702 rx.apid[0] = 0xC0;
2703 }
2704 } else if (!strncmp(inpt,"AVI",4)){
2705 rx.itype=REPLEX_AVI;
2706 rx.vpid = 0xE0;
2707 rx.apidn = 1;
2708 rx.apid[0] = 0xC0;
2709 rx.ignore_pts =1;
2710 } else {
2711 usage(argv[0]);
2712 }
2713
2714 init_replex(&rx, bufsize);
2715 rx.analyze= analyze;
2716
2717 if (rx.demux){
2718 int i;
2719 char fname[256];
2720 if (!filename){
2721 filename = malloc(4);
2722 strcpy(filename,"out");
2723 }
2724 if (strlen(filename) > 250){
2725 fprintf(stderr,"Basename too long\n");
2726 exit(0);
2727 }
2728
2729 snprintf(fname,256,"%s.mv2",filename);
2730 if ((rx.dmx_out[0] = open(fname,O_WRONLY|
2731 O_CREAT|O_TRUNC|
2732 O_LARGEFILE,
2733 S_IRUSR|S_IWUSR|
2734 S_IRGRP|S_IWGRP|
2735 S_IROTH|S_IWOTH))
2736 < 0){
2737 perror("Error opening output file");
2738 exit(1);
2739 }
2740 fprintf(stderr,"Video output File is: %s\n",
2741 fname);
2742
2743 for (i=0; i < rx.apidn; i++){
2744 snprintf(fname,256,"%s%d.mp2",filename
2745 ,i);
2746 if ((rx.dmx_out[i+1] =
2747 open(fname,O_WRONLY|
2748 O_CREAT|O_TRUNC|
2749 O_LARGEFILE,
2750 S_IRUSR|S_IWUSR|
2751 S_IRGRP|S_IWGRP|
2752 S_IROTH|S_IWOTH))
2753 < 0){
2754 perror("Error opening output file");
2755 exit(1);
2756 }
2757 fprintf(stderr,"Audio%d output File is: %s\n",i,fname);
2758 }
2759
2760
2761 for (i=0; i < rx.ac3n; i++){
2762 snprintf(fname,256,"%s%d.ac3",filename
2763 ,i);
2764 if ((rx.dmx_out[i+1+rx.apidn] =
2765 open(fname,O_WRONLY|
2766 O_CREAT|O_TRUNC|
2767 O_LARGEFILE,
2768 S_IRUSR|S_IWUSR|
2769 S_IRGRP|S_IWGRP|
2770 S_IROTH|S_IWOTH))
2771 < 0){
2772 perror("Error opening output file");
2773 exit(1);
2774 }
2775 fprintf(stderr,"AC3%d output File is: %s\n",i,fname);
2776 }
2777 do_demux(&rx);
2778 } else if (analyze){
2779 rx.demux=1;
2780 do_analyze(&rx);
2781 } else {
2782 do_replex(&rx);
2783 }
2784
2785 return 0;
2786 }
2787