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