Index: replex/ringbuffer.h
===================================================================
--- replex/ringbuffer.h	(revision 18755)
+++ replex/ringbuffer.h	(working copy)
@@ -2,7 +2,8 @@
  * ringbuffer.h
  *        
  *
- * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
+ * Copyright (C) 2003 - 2006
+ *                    Marcus Metzler <mocm@metzlerbros.de>
  *                    Metzler Brothers Systementwicklung GbR
  *
  * This program is free software; you can redistribute it and/or
@@ -40,12 +41,12 @@
 	typedef struct ringbuffer {
 		int read_pos;
 		int write_pos;
-		uint32_t size;
+		int size;
 		uint8_t *buffer;
 	} ringbuffer;
 
 
-#define DBUF_INDEX 10000
+#define DBUF_INDEX 1000
 
 	typedef struct dummy_buffer_s {
 		uint32_t size;
@@ -56,17 +57,13 @@
 
 
 	int  ring_init (ringbuffer *rbuf, int size);
-	int  ring_reinit (ringbuffer *rbuf, int size);
 	void ring_clear(ringbuffer *rbuf);
 	void ring_destroy(ringbuffer *rbuf);
 	int ring_write(ringbuffer *rbuf, uint8_t *data, int count);
 	int ring_read(ringbuffer *rbuf, uint8_t *data, int count);
 	int ring_write_file(ringbuffer *rbuf, int fd, int count);
 	int ring_read_file(ringbuffer *rbuf, int fd, int count);
-	int ring_peek(ringbuffer *rbuf, uint8_t *data, unsigned int count,
-                      uint32_t off);
-	int ring_poke(ringbuffer *rbuf, uint8_t *data, unsigned int count,
-                      uint32_t off);
+	int ring_peek(ringbuffer *rbuf, uint8_t *data, int count, long off);
 	int ring_skip(ringbuffer *rbuf, int count);
 
 	static inline int ring_wpos(ringbuffer *rbuf)
@@ -95,15 +92,15 @@
 		return ring_posdiff(rbuf, rbuf->read_pos,pos);
 	}
 
-	static inline unsigned int ring_free(ringbuffer *rbuf){
+	static inline int ring_free(ringbuffer *rbuf){
 		int free;
-		free = rbuf->read_pos - rbuf->write_pos;
+		free = rbuf->read_pos - rbuf->write_pos-1;
 		if (free <= 0) free += rbuf->size;
-		//Note: free is gauranteed to be >=1 from the above
-		return free - 1;
+		
+		return free;
 	}
 
-	static inline unsigned int ring_avail(ringbuffer *rbuf){
+	static inline int ring_avail(ringbuffer *rbuf){
 		int avail;
 		avail = rbuf->write_pos - rbuf->read_pos;
 		if (avail < 0) avail += rbuf->size;
@@ -121,8 +118,7 @@
 	int dummy_add(dummy_buffer *dbuf, uint64_t time, uint32_t size);
 	void dummy_clear(dummy_buffer *dbuf);
 	int dummy_init(dummy_buffer *dbuf, int s);
-        void dummy_destroy(dummy_buffer *dbuf);
-	void ring_show(ringbuffer *rbuf, unsigned int count, uint32_t off);
+	void ring_show(ringbuffer *rbuf, int count, long off);
 
 #ifdef __cplusplus
 }
Index: replex/element.h
===================================================================
--- replex/element.h	(revision 18755)
+++ replex/element.h	(working copy)
@@ -2,7 +2,8 @@
  * element.h
  *        
  *
- * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
+ * Copyright (C) 2003 - 2006
+ *                    Marcus Metzler <mocm@metzlerbros.de>
  *                    Metzler Brothers Systementwicklung GbR
  *
  * This program is free software; you can redistribute it and/or
@@ -51,9 +52,9 @@
 #define PICTURE_DISPLAY_EXTENSION    0x07
 
 #define I_FRAME 0x01
-#define P_FRAME 0x02
-#define B_FRAME 0x03
-#define D_FRAME 0x04
+#define B_FRAME 0x02
+#define P_FRAME 0x03
+#define D_FRAME 0x03
 
 #define OFF_SIZE 4
 #define FIRST_FIELD 0
@@ -74,13 +75,17 @@
 #define PULLDOWN32 1
 #define PULLDOWN23 2
 
+#define PROGRESSIVE 1
+#define ONE_FIELD 2
+#define TWO_FIELD 3
+
 #define CLOCK_MS        27000ULL
 #define CLOCK_PER    27000000000ULL
 #define SEC_PER      (CLOCK_PER/s->frame_rate)
 
 
 enum {
-	NONE=0,AC3, MPEG_AUDIO, LPCM, MAX_TYPES
+	NONE=0,AC3, MPEG_AUDIO, LPCM
 };
 
 typedef struct sequence_s{
@@ -109,32 +114,36 @@
 struct audio_frame_s{
 	int set;
 	int layer;
+	int padding;
+        int sample_rate;
+        int mpg25;
+        int lsf;
 	uint32_t bit_rate;
 	uint32_t frequency;
 	uint32_t mode;
 	uint32_t mode_extension;
 	uint32_t emphasis;
 	uint32_t framesize;
-	uint32_t frametime;
 	uint32_t off;
-	char     language[4];
+	
 } audio_frame_t;
 
 void pts2time(uint64_t pts, uint8_t *buf, int len);
-int find_audio_sync(ringbuffer *rbuf, uint8_t *buf, int off, int type, int le);
-int find_audio_s(uint8_t *rbuf, int off, int type, int le);
-int get_video_info(ringbuffer *rbuf, sequence_t *s, int off, int le);
-int get_audio_info(ringbuffer *rbuf, audio_frame_t *af, int off, int le); 
-int get_ac3_info(ringbuffer *rbuf, audio_frame_t *af, int off, int le);
+int find_audio_sync(ringbuffer *rbuf, uint8_t *buf, long off, int type, int le);
+int find_audio_s(uint8_t *rbuf, long off, int type, int le);
+int get_video_info(ringbuffer *rbuf, sequence_t *s, long off, int le);
+int get_audio_info(ringbuffer *rbuf, audio_frame_t *af, long off, int le, int verb); 
+int get_ac3_info(ringbuffer *rbuf, audio_frame_t *af, long off, int le, int verb);
 uint64_t add_pts_audio(uint64_t pts, audio_frame_t *aframe, uint64_t frames);
 uint64_t next_ptsdts_video(uint64_t *pts, sequence_t *s, uint64_t fcount, uint64_t gcount);
+int  cfix_audio_count(audio_frame_t *aframe, uint64_t origpts, uint64_t pts);
 void fix_audio_count(uint64_t *acount, audio_frame_t *aframe, 
 		     uint64_t origpts, uint64_t pts);
 void fix_video_count(sequence_t *s, uint64_t *frame, uint64_t origpts, 
 		     uint64_t pts, uint64_t origdts, uint64_t dts);
 
 int check_audio_header(ringbuffer *rbuf, audio_frame_t * af, 
-		       int  off, int le, int type);
-int get_video_ext_info(ringbuffer *rbuf, sequence_t *s, int off, int le);
+		       long  off, int le, int type);
+int get_video_ext_info(ringbuffer *rbuf, sequence_t *s, long off, int le);
 
 #endif /*_ELEMENT_H_*/
Index: replex/replex.c
===================================================================
--- replex/replex.c	(revision 18755)
+++ replex/replex.c	(working copy)
@@ -2,8 +2,10 @@
  * replex.c
  *        
  *
- * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
+ * Copyright (C) 2003 - 2006
+ *                    Marcus Metzler <mocm@metzlerbros.de>
  *                    Metzler Brothers Systementwicklung GbR
+ *           (C) 2006 Reel Multimedia
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -39,22 +41,21 @@
 #include "replex.h"
 #include "pes.h"
 
-#include "avcodec.h"
-#include "avformat.h"
+static int replex_all_set(struct replex *rx);
 
-#ifdef USING_MINGW
-# define S_IRGRP 0
-# define S_IWGRP 0
-# define S_IROTH 0
-# define S_IWOTH 0
-#endif
+void overflow_exit(struct replex *rx)
+{
+	rx->overflows++;
 
-#ifndef O_LARGEFILE
-#define O_LARGEFILE 0
-#endif
+	if (rx->max_overflows && 
+	    rx->overflows > rx->max_overflows){
+		fprintf(stderr,"exiting after %d overflows  last video PTS: ", rx->overflows);
+		printpts(rx->last_vpts);
+		fprintf(stderr,"\n");
+		exit(1);
+	}
+}
 
-static int replex_all_set(struct replex *rx);
-
 int replex_check_id(struct replex *rx, uint16_t id)
 {
 	int i;
@@ -73,65 +74,419 @@
 	return -1;
 }
 
-int encode_mp2_audio(audio_frame_t *aframe, uint8_t *buffer, int bufsize)
+
+static int audio_jump(struct replex *rx)
 {
-	AVCodec *codec;
-	AVCodecContext *c= NULL;
-	int frame_size, j, out_size;
-	short *samples;
+	int i;
+
+	for (i=0; i<rx->apidn; i++)
+		if (rx->audio_jump[i])
+			return 1;
+
+	for (i=0; i<rx->ac3n; i++)
+		if (rx->ac3_jump[i])
+			return 1;
+
+	return 0;
+}
+
+
+static int jump_finished(struct replex *rx)
+{
+	int i;
+
+	if (!rx->video_jump) return 0;
+	for (i=0; i<rx->apidn; i++)
+		if (!rx->audio_jump[i])
+			return 0;
+
+	for (i=0; i<rx->ac3n; i++)
+		if (!rx->ac3_jump[i])
+			return 0;
+
+	return 1;
+}
+
+
+static void clear_jump(struct replex *rx)
+{
+	int i;
+
+	rx->video_jump = 0;
+	for (i=0; i<rx->apidn; i++)
+		rx->audio_jump[i] = 0;
+
+	for (i=0; i<rx->ac3n; i++)
+		rx->ac3_jump[i] = 0;
+}
+
+
+static void create_fillframe1(ringbuffer *rbuf, int off, int *fsize, 
+			      int type, uint8_t *fillframe, struct replex *rx)
+{
+	int fs = *fsize;
 	
-	fprintf(stderr, "encoding an MP2 audio frame\n");
+	if (fs > MAXFRAME) return;
 
-	/* find the MP2 encoder */
-	codec = avcodec_find_encoder(CODEC_ID_MP2);
-	if (!codec) {
-		fprintf(stderr, "codec not found\n");
-		return 1;
+	if ( type == MPEG_AUDIO){
+		audio_frame_t afr;
+		get_audio_info(rbuf, &afr, off, fs,0);
+		fs = afr.framesize;
+		off += (*fsize-fs); 
 	}
- 
-	c = avcodec_alloc_context();
+	if (rx->fillzero && type == MPEG_AUDIO) 
+		memset(fillframe+4, 0, MAXFRAME-4);
+	else 
+		ring_peek (rbuf, fillframe, fs, off);
+	*fsize = fs;
+}
 
-	/* put sample parameters */
-	c->bit_rate = aframe->bit_rate;
-	c->sample_rate = aframe->frequency;
-	c->channels = 2;
-	 
-	/* open it */
-	if (avcodec_open(c, codec) < 0) {
-		fprintf(stderr, "could not open codec\n");
-		av_free(c);
-		return 1;
+static void create_fillframe2(ringbuffer *rbuf, int off, int *fsize, 
+			      int type, uint8_t *fillframe, struct replex *rx)
+{
+	int fs = *fsize;
+
+	if (fs > MAXFRAME) return;
+
+	if ( type == MPEG_AUDIO){
+		audio_frame_t afr;
+		get_audio_info(rbuf, &afr, off, fs,0);
+		fs = afr.framesize;
 	}
+	if (rx->fillzero && type == MPEG_AUDIO) 
+		memset(fillframe+4, 0, MAXFRAME-4);
+	else 
+		ring_peek (rbuf, fillframe, fs, off);
 
-	/* the codec gives us the frame size, in samples */
-	frame_size = c->frame_size;
-	samples = malloc(frame_size * 2 * c->channels);
+	*fsize = fs;
+}
+
+
+static void fill_in_frames(ringbuffer *index_buf, int fc, audio_frame_t *aframe, 
+			   uint64_t *acount, uint8_t *fillframe, int fsize, struct replex *rx)
+{								
+	index_unit iu;
+	int f;
+
+	for (f=0; f < fc; f++){
+		init_index(&iu);
+		iu.active = 1;
+		iu.pts = add_pts_audio(0, aframe,*acount);
+		iu.framesize = fsize;
+		iu.length = fsize;
+		iu.fillframe = fillframe;
+		iu.err = DUMMY_ERR;
+		if (ring_write(index_buf, (uint8_t *)&iu, sizeof(index_unit)) < 0){
+			fprintf(stderr,"audio ring buffer overrun error\n");
+			overflow_exit(rx);
+		}
+		*acount += 1;
+	}
+}
+
+static int 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)
+{
+	int re=0;
+	uint8_t *fillframe=NULL;
 	
-	/* create samples for a single blank frame */
-	for (j=0;j<frame_size;j++) {
-		samples[2*j] = 0;
-		samples[2*j+1] = 0;
+	switch( type ){
+	case AC3:
+		fillframe = rx->ac3fillframe[n];
+		break;
+	case MPEG_AUDIO:
+		fillframe = rx->afillframe[n];
+		break;
 	}
+	if (!aframe->set){
+		switch( type ){
+		case AC3:
+			re = get_ac3_info(rbuf, aframe, 
+					  pos+c+off,
+					  len-c-pos,1);
+			break;
+		case MPEG_AUDIO:
+			re = get_audio_info(rbuf, aframe, 
+					    pos+c+off,
+					    len-c-pos, 1);
+			break;
+		}
+		if ( re == -2){
+			*apes_abort = len -c;
+			return c;
+		}
+		if (re < 0) return c;
 		
-	/* encode the samples */
-	out_size = avcodec_encode_audio(c, buffer, bufsize, samples);
+		if (!rx->ignore_pts){
+			if ((p->flag2 & PTS_ONLY)){
+				*fpts = trans_pts_dts(p->pts);
+				fprintf(stderr,
+					"starting audio PTS: ");
+				printpts(*fpts);
+				fprintf(stderr,"\n");
+			} else {
+				aframe->set = 0;
+				ring_skip(rbuf,pos+c+off+re);
+			}
+		}
+		
+		if (aframe->set && *first)
+			ring_skip(rbuf,pos+c);
+	} else {
+		int diff = ring_posdiff(rbuf, iu->start, 
+					p->ini_pos + pos+c);
+		
+		if ( (re =check_audio_header(rbuf, aframe, 
+					     pos+c+off,len-c-pos,
+					     type)) < 0){
+			
+			if ( re == -2){
+				*apes_abort = len -c;
+				return c;
+			}
+			
+			if (aframe->framesize > diff){
+				if ( re == -3){
+					c+= pos+1;
+					return c;
+				}
+				
+				c += pos+2;
+#ifdef IN_DEBUG
+				fprintf(stderr,"WRONG HEADER1 %d\n", diff);
+#endif
+				return c;
+			}
+		}
+		if (aframe->framesize > diff){
+			c += pos+2;
+			//fprintf(stderr,"WRONG HEADER2 %d\n", diff);
+			return c;
+		}
+	}
 	
-	if (out_size != bufsize) {
-		fprintf(stderr, "frame size (%d) does not equal required size (%d)?\n",
-				out_size, bufsize);
-		free(samples);
-		avcodec_close(c);
-		av_free(c);
-		return 1;
-	}
+	
+	if (aframe->set){
+		if(iu->active){
+			iu->length = ring_posdiff(rbuf, 
+						  iu->start, 
+						  p->ini_pos + 
+						  pos+c);
 
-	free(samples);
-	avcodec_close(c);
-	av_free(c);
+			if (fillframe && !*filled){
+				int fsize = aframe->framesize;
+				int pdiff = ring_posdiff(rbuf, ring_rpos(rbuf),iu->start);
+				
+				create_fillframe2(rbuf, pdiff, &fsize, type, fillframe, rx);
+				*filled = 1;
+			}
+
+			if (iu->length != aframe->framesize){
+				iu->err= FRAME_ERR;
+				fprintf(stderr,"Wrong audio frame size: %d (%d)\n", 
+					iu->length, aframe->framesize);
+				*acount -= 1;
+			}
+			
+			if (ring_write(index_buf, (uint8_t *)iu, sizeof(index_unit)) < 0){
+				fprintf(stderr,"audio ring buffer overrun error\n");
+				overflow_exit(rx);
+			}
+			if (iu->err == JUMP_ERR) *acount -= 1;
+			*acount += 1;
+		} 
+		
+		init_index(iu);
+		iu->active = 1;
+		iu->pts = add_pts_audio(0, aframe,*acount);
+		iu->framesize = aframe->framesize;
+		
+		if (!rx->ignore_pts && *first && (p->flag2 & PTS_ONLY)){
+			int64_t dpts;
+			int64_t diff;
+			
+			dpts = ptsdiff(trans_pts_dts(p->pts), *fpts);
+			diff = ptsdiff(dpts, iu->pts);
+			
+			if (rx->allow_jump &&
+			    (int)diff > rx->allow_jump){
+				
+				if (!(*ajump) && rx->video_jump){
+					int fc=0;
+					int fsize = 0;
+					uint64_t oldfpts  = 0;
+					uint64_t ndpts = 0;
+			
+					int pdiff = ring_posdiff(rbuf, ring_rpos(rbuf),p->ini_pos + 
+								 pos+c );
+					
+					*ajump = diff; 
+					oldfpts = *fpts;
+					*fpts += rx->video_jump;
+
+					fprintf(stderr,"found jump in audio PTS\n");
+					printpts(iu->pts);
+					printpts(diff);
+					fprintf(stderr,"\n");
+					
+					
+					ndpts = uptsdiff(trans_pts_dts(p->pts),*fpts);
+					fsize = aframe->framesize;
+					if (fillframe){
+						create_fillframe1(rbuf, pdiff-fsize, &fsize, 
+								  type, fillframe, rx);
+						*filled = 1;
+					}
+					
+					if (iu->pts < ndpts){
+						fc = cfix_audio_count(aframe, ndpts, iu->pts);
+						
+						if ( fc > 100) {
+							*acount+= fc;
+							fprintf(stderr,"need to fill in %d audio frames\n",fc);
+							fprintf(stderr,"this is too much, try re-cutting\n");
+							*fpts = oldfpts;
+							fc = 0; // just too broken
+							rx->video_jump=0;
+						} else fill_in_frames(index_buf, fc, aframe, 
+								      acount, fillframe, aframe->framesize, rx);
+						init_index(iu);
+						iu->active = 1;
+						iu->pts = add_pts_audio(0, aframe,*acount);
+						iu->framesize = aframe->framesize;
+						
+						//iu->pts = uptsdiff(trans_pts_dts(p->pts),
+						//		   *fpts);
+						printpts(iu->pts);
+						fprintf(stderr,"  fixed %d frames\n", fc);
+						
+						diff = 0;
+						
+					} else {
+						fc = cfix_audio_count(aframe, iu->pts, ndpts);
+						fprintf(stderr,"need to drop %d audio frames: ",fc);
+						diff = ptsdiff(ndpts, iu->pts);
+						printpts(diff);
+						fprintf(stderr,"\n");
+						iu->pts = add_pts_audio(0, aframe,*acount);
+					}
+					
+				}
+
+				if (!rx->video_jump && diff > 0){ 
+					uint64_t vadiff = ptsdiff(dpts, rx->last_vpts);
+					iu->err = JUMP_ERR;
+					*ajump = diff;
+					
+					fprintf(stderr,"found jump in audio PTS without video jump\n");
+					printpts(iu->pts);
+					printpts(diff);
+					fprintf(stderr,"\n");
+
+					if (abs(vadiff) < 600 * CLOCK_MS){
+						int fc=0;
+						int fsize = 0;
+			
+						int pdiff = ring_posdiff(rbuf, ring_rpos(rbuf),p->ini_pos + 
+									 pos+c );
+					
+						*ajump = diff; 
+						*fpts += rx->video_jump;
+						
+						fprintf(stderr,"filling in audio frames\n");
+						printpts(iu->pts);
+						printpts(diff);
+						fprintf(stderr,"\n");
+					
+					
+						fc = cfix_audio_count(aframe,
+								      uptsdiff(trans_pts_dts(p->pts),
+									       *fpts), iu->pts);
+						fsize = aframe->framesize;
+						if (fillframe){
+							create_fillframe1(rbuf, pdiff-fsize, &fsize, 
+									  type, fillframe, rx);
+							*filled = 1;
+						}
+					
+						fill_in_frames(index_buf, fc, aframe, 
+							       acount, fillframe, fsize, rx);
+						
+						init_index(iu);
+						iu->active = 1;
+						iu->pts = add_pts_audio(0, aframe,*acount);
+						iu->framesize = aframe->framesize;
+						fprintf(stderr,"  fixed %d frames\n", fc);
 	
-	return 0;
-}
+						diff = 0;
+					}
+				}
 
+				if (jump_finished(rx)) clear_jump(rx);
+			}
+						
+
+			if ( diff < 0){
+				fprintf(stderr,"drop audio frame\n");
+				init_index(iu);
+				iu->err = JUMP_ERR;
+				iu->active = 1;
+				iu->pts = add_pts_audio(0, aframe,*acount);
+				iu->framesize = aframe->framesize;
+			}
+
+			if( iu->err!= JUMP_ERR && !rx->keep_pts && diff > 40*CLOCK_MS){
+					if (!rx->allow_jump || abs((int)diff) > rx->allow_jump){
+						fprintf(stderr,"audio PTS inconsistent: ");
+						printpts(dpts);
+						printpts(iu->pts);
+						fprintf(stderr,"diff: ");
+						printpts(diff);
+						fprintf(stderr,"\n");
+					} 
+			}	
+			if (rx->keep_pts){
+				fix_audio_count(acount, aframe, 
+						uptsdiff(trans_pts_dts(
+								 p->pts),
+							 *fpts),
+						iu->pts);
+				iu->pts = uptsdiff(trans_pts_dts(p->pts),
+						   *fpts);
+				if (*lpts && ptsdiff(iu->pts,*lpts)<0) 
+					fprintf(stderr, 
+						"Warning negative audio PTS increase!\n");
+				*lpts = iu->pts;
+			}
+			*first = 0;
+		}
+		if (rx->analyze >1){
+			if ((p->flag2 & PTS_ONLY)){
+				iu->pts = trans_pts_dts(p->pts);
+			} else {
+				iu->pts = 0;
+			}
+		}
+		iu->start = (p->ini_pos+pos+c)%bsize;
+	}
+	c += pos;
+	if (c + aframe->framesize > len){
+//				fprintf(stderr,"SHORT %d\n", len -c);
+		c = len;
+	} else {
+		c += aframe->framesize;
+	}
+	return c;
+}				
+
+
+
 void analyze_audio( pes_in_t *p, struct replex *rx, int len, int num, int type)
 {
 	int c=0;
@@ -143,11 +498,14 @@
 	uint64_t *fpts=NULL;
 	uint64_t *lpts=NULL;
 	int bsize = 0;
-	int first = 1;
+	uint64_t *ajump=NULL;
+	uint64_t *aoff=NULL;
 	uint8_t buf[7];
 	int off=0;
 	int *apes_abort=NULL;
-	int re=0;
+	uint64_t adelay=0;
+	int first = 1;
+	int *filled=NULL;
 	
 	switch ( type ){
 	case AC3:
@@ -163,6 +521,10 @@
 		lpts = &rx->last_ac3pts[num];
 		bsize = rx->ac3buf;
 		apes_abort = &rx->ac3pes_abort[num];
+		ajump = &rx->ac3_jump[num];
+		aoff = &rx->ac3pts_off[num];
+		adelay = rx->ac3pts_off[num];
+		filled = &rx->ac3filled[num];
 		break;
 
 	case MPEG_AUDIO:
@@ -178,6 +540,10 @@
 		lpts = &rx->last_apts[num];
 		bsize = rx->audiobuf;
 		apes_abort = &rx->apes_abort[num];
+		ajump = &rx->audio_jump[num];
+		aoff = &rx->apts_off[num];
+		adelay = rx->apts_off[num];
+	        filled = &rx->afilled[num];
 		break;
 	}
 	
@@ -186,207 +552,11 @@
 	while (c < len){
 		if ( (pos = find_audio_sync(rbuf, buf, c+off, type, len-c) ) 
 		     >= 0 ){
-			if (!aframe->set){
-				switch( type ){
-				case AC3:
-					re = get_ac3_info(rbuf, aframe, 
-							  pos+c+off,
-							  len-c-pos);
-					break;
-				case MPEG_AUDIO:
-					re = get_audio_info(rbuf, aframe, 
-							    pos+c+off,
-							    len-c-pos);
-					break;
-				}
-				if ( re == -2){
-					*apes_abort = len -c;
-					return;
-				}
-				if (re < 0) return;
-
-
-				if (!rx->ignore_pts){
-					if ((p->flag2 & PTS_ONLY)){
-						*fpts = trans_pts_dts(p->pts);
-						fprintf(stderr,
-							"starting audio PTS: ");
-						printpts(*fpts);
-						fprintf(stderr,"\n");
-					} else aframe->set = 0;
-				}
-
-				if (aframe->set && first)
-					ring_skip(rbuf,pos+c);
-				
-			} else {
-				int diff = ring_posdiff(rbuf, iu->start, 
-							p->ini_pos + pos+c);
-				
-				if ( (re = check_audio_header(rbuf, aframe, 
-							     pos+c+off,len-c-pos,
-							     type)) < 0){
-			
-					if ( re == -2){
-						*apes_abort = len -c;
-						return;
-					}
-					
-					if ((int) aframe->framesize > diff){
-						if ( re == -3){
-							c += pos+1;
-							continue;
-						}
-					
-						c += pos+2;
-#ifdef IN_DEBUG
-						fprintf(stderr,"WRONG HEADER1 %d\n", diff);
-#endif
-						continue;
-					}
-				}
-				if ((int) aframe->framesize > diff){
-					c += pos+2;
-					//fprintf(stderr,"WRONG HEADER2 %d\n", diff);
-					continue;
-				}
-			}
-			
-			// try to fix audio sync - only works for mpeg audio for now 
-			if (aframe->set && rx->fix_sync && first && type == MPEG_AUDIO){
-				int frame_time = aframe->frametime;
-				int64_t diff;
-				diff = ptsdiff(trans_pts_dts(p->pts), add_pts_audio(0, aframe,*acount + 1) + *fpts);
-				if (abs ((int)diff) >= frame_time){
-					fprintf(stderr,"fixing audio PTS inconsistency - diff: ");
-					printpts(abs(diff));
-
-					if (diff < 0){
-						diff = abs(diff);
-						int framesdiff = diff / frame_time;
-						fprintf(stderr, " - need to remove %d frame(s)\n", framesdiff);
-						
-						// FIXME can only remove one frame at a time for now
-						if (framesdiff > 1)
-							framesdiff = 1;
-						iu->pts = add_pts_audio(0, aframe, -framesdiff);
-						c += aframe->framesize;
-						continue;
-					} else {
-						int framesdiff = diff / frame_time;
-						fprintf(stderr, " - need to add %d frame(s)\n", framesdiff);
-						
-						// limit inserts to a maximum of 5 frames
-						if (framesdiff > 5)
-							framesdiff = 5;
-
-						// alloc memmory for  audio frame
-						uint8_t *framebuf;
-						if ( !(framebuf = (uint8_t *) malloc(sizeof(uint8_t) * aframe->framesize))) {
-							fprintf(stderr,"Not enough memory for audio frame\n");
-							exit(1);
-						}
-
-						// try to encode a blank frame
-						if (encode_mp2_audio(aframe, framebuf, sizeof(uint8_t) * aframe->framesize) != 0) {
-							// encode failed so just use a copy of the current frame
-							int res;
-							res = ring_peek(rbuf, framebuf, aframe->framesize, 0);
-							if (res != (int) aframe->framesize) {
-								fprintf(stderr,"ring buffer failed to peek frame res: %d\n", res);
-								exit(1);
-							}
-						}	
-						
-						// add each extra frame required direct to the output file
-						int x;
-						for (x = 0; x < framesdiff; x++){
-							if (type == AC3){
-								if (rx->dmx_out[num+1+rx->apidn])	
-									write(rx->dmx_out[num+1+rx->apidn], framebuf, aframe->framesize);
-							}else{
-								if (rx->dmx_out[num+1])
-									write(rx->dmx_out[num+1], framebuf, aframe->framesize);
-							}
-							*acount += 1;
-						}
-						
-						free(framebuf);
-					}
-				}
-			}
-
-			if (aframe->set){
-				if(iu->active){
-					iu->length = ring_posdiff(rbuf, 
-								  iu->start, 
-								  p->ini_pos + 
-								  pos+c);
-
-					if (iu->length < aframe->framesize ||
-					    iu->length > aframe->framesize+1){
-						fprintf(stderr,"Wrong audio frame size: %d\n", iu->length);
-						iu->err= FRAME_ERR;
-					}
-					if (ring_write(index_buf, 
-							(uint8_t *)iu,
-							sizeof(index_unit)) < 0){
-						fprintf(stderr,"audio ring buffer overrun error\n");
-						exit(1);
-					}
-					*acount += 1;
-				} 
-				
-				init_index(iu);
-				iu->active = 1;
-				iu->pts = add_pts_audio(0, aframe,*acount);
-				iu->framesize = aframe->framesize;
-
-				if (!rx->ignore_pts &&
-				    first && (p->flag2 & PTS_ONLY)){
-					int64_t diff;
-
-					diff = ptsdiff(trans_pts_dts(p->pts),
-							iu->pts + *fpts);
-					if( !rx->keep_pts && abs ((int)diff) > 40*CLOCK_MS){
-						fprintf(stderr,"audio PTS inconsistent: ");
-						printpts(trans_pts_dts(p->pts)-*fpts);
-						printpts(iu->pts);
-						fprintf(stderr,"diff: ");
-						printpts(abs(diff));
-						fprintf(stderr,"\n");
-					}	
-					if (rx->keep_pts){
-						fix_audio_count(acount, aframe, 
-								uptsdiff(trans_pts_dts(
-										 p->pts),
-									 *fpts),
-								iu->pts);
-						iu->pts = uptsdiff(trans_pts_dts(p->pts),
-								   *fpts);
-						if (*lpts && ptsdiff(iu->pts,*lpts)<0) 
-							fprintf(stderr, 
-								"Warning negative audio PTS increase!\n");
-						*lpts = iu->pts;
-					}
-					first = 0;
-				}
-				if (rx->analyze >1){
-					if ((p->flag2 & PTS_ONLY)){
-						iu->pts = trans_pts_dts(p->pts);
-					} else {
-						iu->pts = 0;
-					}
-				}
-				iu->start = (p->ini_pos+pos+c)%bsize;
-			}
-			c += pos;
-			if (c + (int) aframe->framesize > len){
-//				fprintf(stderr,"SHORT %d\n", len -c);
-				c = len;
-			} else {
-				c += aframe->framesize;
-			}
+			c = analyze_audio_loop( p, rx, type, aframe, iu, 
+						rbuf, index_buf, acount, fpts, 
+						lpts, bsize, apes_abort,
+						ajump, aoff, adelay, num, off,
+						c, len, pos, &first, filled);
 		} else {
 			*apes_abort = len-c;
 			c=len;
@@ -394,6 +564,7 @@
 	}	
 }
 
+
 void analyze_video( pes_in_t *p, struct replex *rx, int len)
 {
 	uint8_t buf[8];
@@ -418,6 +589,7 @@
 	int gop_off = 0;
 	int seq_p = 0;
 	int flush=0;
+	int keep_now = 0;
 
 	rbuf = &rx->vrbuffer;
 	index_buf = &rx->index_vrbuffer;
@@ -524,6 +696,24 @@
 						diff = ptsdiff(iu->pts, 
 							       rx->first_vpts 
 							       + newpts);
+						
+						if (rx->allow_jump &&  
+						    abs(diff) > rx->allow_jump)
+						{
+							if (audio_jump(rx)){
+								fprintf(stderr,"AUDIO JUMPED\n");
+								clear_jump(rx);
+							}
+							fprintf(stderr,"found jump in video PTS\n");
+							printpts(iu->pts);
+							printpts(diff);
+							fprintf(stderr,"\n");
+							rx->video_jump = diff;
+							rx->first_vpts += diff;
+							diff = 0;
+						} else {
+							keep_now = 1;
+						}
 
 						if (!rx->keep_pts &&
 						    abs((int)(diff)) > 3*SEC_PER/2){
@@ -533,7 +723,7 @@
 							printpts(newpts+rx->first_vpts);
 							printpts(newpts);
 							fprintf(stderr," diff: ");
-							printpts(abs((int)diff));
+							printpts(diff);
 							fprintf(stderr,"\n");
 						}
 					}
@@ -544,7 +734,7 @@
 						diff = ptsdiff(iu->dts, 
 							       newdts + 
 							       rx->first_vpts); 
-						if (!rx->keep_pts &&
+						if (!rx->keep_pts && !keep_now &&
 						    abs((int)diff) > 3*SEC_PER/2){
 							fprintf(stderr,"video DTS inconsistent: ");
 							printpts(trans_pts_dts(p->dts));
@@ -552,11 +742,11 @@
 							printpts(newdts+rx->first_vpts);
 							printpts(newdts);
 							fprintf(stderr,"diff: ");
-							printpts(abs((int)diff));
+							printpts(diff);
 							fprintf(stderr,"\n");
 						}
 					}
-					if (!rx->keep_pts){
+					if (!rx->keep_pts && !keep_now){
 						iu->pts = newpts;
 						iu->dts = newdts;
 					} else {
@@ -626,8 +816,7 @@
 				gop = 1;
 				gop_off = c+pos - seq_p;
 				
-				if (ring_peek(rbuf, (uint8_t *) buf, 7, 
-					      off+c+pos) < 0){
+				if (ring_peek(rbuf, buf, 7, off+c+pos) < 0){
 					rx->vpes_abort = len -(c+pos-1);
 					return;
 				}				
@@ -652,8 +841,8 @@
 					return;
 				}
 				
-				if (ring_peek(rbuf, (uint8_t *) buf, 6,
-                                              off+c+pos) < 0) return;
+				if (ring_peek(rbuf, buf, 6, off+c+pos) < 0) 
+					return;
 
 
 				frame = ((buf[5]&0x38) >>3);
@@ -731,8 +920,8 @@
 					if ( ring_write(index_buf, (uint8_t *)
 							 &rx->current_vindex,
 							 sizeof(index_unit))<0){
-						fprintf(stderr,"video ring buffer overrun error\n");
-						exit(1);
+						fprintf(stderr,"video ring buffer overrun error 1\n");
+						overflow_exit(rx);
 
 					}
 				} 
@@ -850,9 +1039,9 @@
 void pes_es_out(pes_in_t *p)
 {
 
-	struct replex *rx;
+	struct replex *rx = NULL;
 	char t[80];
-	int len, i;
+	int len = 0, i =0;
 	int l=0;
 
 	len = p->plength-3-p->hlength;
@@ -865,8 +1054,8 @@
 		p->ini_pos = ring_wpos(&rx->vrbuffer);
 
 		if (ring_write(&rx->vrbuffer, p->buf+9+p->hlength, len)<0){
-			fprintf(stderr,"video ring buffer overrun error\n");
-			exit(1);
+			fprintf(stderr,"video ring buffer overrun error 2\n");
+			overflow_exit(rx);
 		}
 		if (rx->vpes_abort){
 			p->ini_pos = (p->ini_pos - rx->vpes_abort)%rx->vrbuffer.size;
@@ -888,8 +1077,8 @@
 		if (l < 0) break;
 		p->ini_pos = ring_wpos(&rx->arbuffer[l]);
 		if (ring_write(&rx->arbuffer[l], p->buf+9+p->hlength, len)<0){
-			fprintf(stderr,"video ring buffer overrun error\n");
-			exit(1);
+			fprintf(stderr,"audio ring buffer overrun error\n");
+			overflow_exit(rx);
 		}
 		if (rx->apes_abort[l]){
 			p->ini_pos = (p->ini_pos - rx->apes_abort[l])
@@ -930,8 +1119,8 @@
 		p->ini_pos = ring_wpos(&rx->ac3rbuffer[l]);
 	
 		if (ring_write(&rx->ac3rbuffer[l], p->buf+9+hl+p->hlength, len)<0){
-			fprintf(stderr,"video ring buffer overrun error\n");
-			exit(1);
+			fprintf(stderr,"ac3 ring buffer overrun error\n");
+			overflow_exit(rx);
 		}
 		if (rx->ac3pes_abort[l]){
 			p->ini_pos = (p->ini_pos - rx->ac3pes_abort[l])
@@ -1055,7 +1244,7 @@
 	}
 
 	
-	if ( tsp[1] & PAY_START) {
+	if ( tsp[1] & PAY_START){
 		if (p->plength == MMAX_PLENGTH-6){
 			p->plength = p->found-6;
 			es_out(p);
@@ -1063,7 +1252,7 @@
 		}
 	}
 
-	if ( tsp[3] & ADAPT_FIELD) {  // adaptation field?
+	if ( tsp[3] & ADAPT_FIELD){  // adaptation field?
 		off = tsp[4] + 1;
 		if (off+4 >= TS_SIZE) return 0;
 	}
@@ -1100,6 +1289,20 @@
 			fprintf(stderr,"read %3d%%\r", (int)per);
 			rx->lastper = per;
 		}
+		if (rx->finread >= rx->inflength && rx->inputFiles && rx->inputFiles[rx->inputIdx + 1]) {
+			close(rx->fd_in);
+			rx->inputIdx ++;
+			if ((rx->fd_in = open(rx->inputFiles[rx->inputIdx] ,O_RDONLY| O_LARGEFILE)) < 0) {
+				fprintf(stderr,"Error opening input file %s",rx->inputFiles[rx->inputIdx] );
+				exit(1);
+			}
+			fprintf(stderr,"Reading from %s\n", rx->inputFiles[rx->inputIdx]);
+			rx->inflength = lseek(rx->fd_in, 0, SEEK_END);
+			fprintf(stderr,"Input file length: %.2f MB\n",rx->inflength/1024./1024.);
+			lseek(rx->fd_in,0,SEEK_SET);
+			rx->lastper = 0;
+			rx->finread = 0;
+		}
 	} else fprintf(stderr,"read %.2f MB\r", rx->finread/1024./1024.);
 #endif
 	if (neof < 0 && re == 0) return neof;
@@ -1123,14 +1326,14 @@
 	for (i=0; i<rx->apidn;i++){
 		if ((aavail = ring_avail(&rx->index_arbuffer[i])
 		     /sizeof(index_unit)) < LIMIT)
-			if (fill < (int) ring_free(&rx->arbuffer[i]))
+			if (fill < ring_free(&rx->arbuffer[i]))
 				fill = ring_free(&rx->arbuffer[i]);
 	}
 
 	for (i=0; i<rx->ac3n;i++){
 		if ((ac3avail = ring_avail(&rx->index_ac3rbuffer[i])
 		     /sizeof(index_unit)) < LIMIT)
-			if (fill < (int) ring_free(&rx->ac3rbuffer[i]))
+			if (fill < ring_free(&rx->ac3rbuffer[i]))
 				fill = ring_free(&rx->ac3rbuffer[i]);
 	}
 
@@ -1155,14 +1358,14 @@
 	int count=0;
 	int re=0;
 	uint16_t vpid=0, apid=0, ac3pid=0;
-		
+	
 	fprintf(stderr,"Trying to find PIDs\n");
-	while (!afound && !vfound && count < (int) rx->inflength){
+	while (!afound && !vfound && count < rx->inflength){
 		if (rx->vpid) vfound = 1;
 		if (rx->apidn) afound = 1;
 		if ((re = save_read(rx,buf,IN_SIZE))<0)
 			perror("reading");
-		else 
+		else
 			count += re;
 		if ( (re = find_pids(&vpid, &apid, &ac3pid, buf, re))){
 			if (!rx->vpid && vpid){
@@ -1186,7 +1389,7 @@
 				afound++;
 			}
 			
-		} 
+		}
 		
 	}
 	
@@ -1211,18 +1414,18 @@
 	int vn=0, an=0,ac3n=0;
 	uint16_t vp,ap,cp;
 	int vpos, apos, cpos;
-		
+	
 	memset (vpid , 0 , MAXVPID*sizeof(uint16_t));
 	memset (apid , 0 , MAXAPID*sizeof(uint16_t));
-    memset (ac3pid , 0 , MAXAC3PID*sizeof(uint16_t));
-
+	memset (ac3pid , 0 , MAXAC3PID*sizeof(uint16_t));
+	
 	fprintf(stderr,"Trying to find PIDs\n");
-	while (count < (int) rx->inflength-IN_SIZE){
+	while (count < rx->inflength-IN_SIZE){
 		if ((re = save_read(rx,buf,IN_SIZE))<0)
 			perror("reading");
-		else 
+		else
 			count += re;
-		if ( (re = find_pids_pos(&vp, &ap, &cp, buf, re, 
+		if ( (re = find_pids_pos(&vp, &ap, &cp, buf, re,
 					 &vpos, &apos, &cpos))){
 			if (vp){
 				int old=0;
@@ -1241,9 +1444,9 @@
 					       (int)vpid[vn], (int)vpid[vn],
 					       buf[vpos]);
 					if (vn+1 < MAXVPID) vn++;
-				} 				
+				}
 			}
-
+			
 			if (ap){
 				int old=0;
 				for (j=0; j < an; j++)
@@ -1258,9 +1461,9 @@
 					       (int)apid[an],(int)apid[an],
 					       buf[apos]);
 					if (an+1 < MAXAPID) an++;
-				}				
+				}
 			}
-
+			
 			if (cp){
 				int old=0;
 				for (j=0; j < ac3n; j++)
@@ -1270,14 +1473,14 @@
 					}
 				if (!old){
 					ac3pid[ac3n]=cp;
-					printf("ac3pid %d: 0x%04x (%d) \n", 
+					printf("ac3pid %d: 0x%04x (%d) \n",
 					       ac3n+1,
 					       (int)ac3pid[ac3n],
 					       (int)ac3pid[ac3n]);
 					if (ac3n+1< MAXAC3PID) ac3n++;
-				}				
+				}
 			}
-		} 
+		}
 		
 	}
 	
@@ -1289,7 +1492,7 @@
 	int afound=0;
 	int vfound=0;
 	uint16_t vpid=0, apid=0, ac3pid=0;
-		
+	
 	if (rx->vpid) vfound = 1;
 	if (rx->apidn) afound = 1;
 	fprintf(stderr,"Trying to find PIDs\n");
@@ -1305,18 +1508,18 @@
 			ring_init(&rx->arbuffer[0], rx->audiobuf);
 			init_pes_in(&rx->paudio[0], 1, &rx->arbuffer[0], 0);
 			rx->paudio[0].priv = (void *) rx;
-			ring_init(&rx->index_arbuffer[0], INDEX_BUF);	
+			ring_init(&rx->index_arbuffer[0], INDEX_BUF);
 			memset(&rx->aframe[0], 0, sizeof(audio_frame_t));
 			init_index(&rx->current_aindex[0]);
 			rx->aframe_count[0] = 0;
 			rx->first_apts[0] = 0;
 		}
-
+		
 		if (!rx->ac3n && ac3pid){
 			rx->ac3_id[0] = ac3pid;
 			rx->ac3n++;
 			afound++;
-			ring_init(&rx->ac3rbuffer[0], AC3_BUF);
+			ring_init(&rx->ac3rbuffer[0], rx->ac3buf);
 			init_pes_in(&rx->pac3[0], 0x80, &rx->ac3rbuffer[0],0);
 			rx->pac3[0].priv = (void *) rx;
 			ring_init(&rx->index_ac3rbuffer[0], INDEX_BUF);
@@ -1326,8 +1529,8 @@
 			rx->first_ac3pts[0] = 0;
 		}
 		
-	} 
-
+	}
+	
 	if (afound && vfound){
 		fprintf(stderr,"found ");
 		if (rx->vpid) fprintf(stderr,"vpid %d (0x%04x)  ",
@@ -1337,25 +1540,26 @@
 		if (rx->ac3n) fprintf(stderr,"ac3pid %d (0x%04x)  ",
 				      rx->ac3_id[0], rx->ac3_id[0]);
 		fprintf(stderr,"\n");
-	} else {
+	}
+	else {
 		fprintf(stderr,"Couldn't find pids\n");
 		exit(1);
 	}
-
+	
 }
 
 
 void pes_id_out(pes_in_t *p)
 {
-
+	
 	struct replex *rx;
 	int len;
-
+	
 	len = p->plength-3-p->hlength;
 	rx = (struct replex *) p->priv;
-
+	
 	rx->scan_found=0;
-	switch(p->cid){
+	switch (p->cid){
 	case VIDEO_STREAM_S ... VIDEO_STREAM_E:
 		rx->scan_found=p->cid;
 		break;
@@ -1368,13 +1572,14 @@
 		if (rx->vdr){
 			rx->scan_found = 0x80;
 			break;
-		} else {
+		}
+		else {
 			
 			uint8_t id = p->buf[9+p->hlength];
-			switch(id){
+			switch (id){
 			case 0x80 ... 0x8f:
-			{ 
-				int c=0; 
+			{
+				int c=0;
 				uint16_t fframe;
 				
 				fframe=0;
@@ -1383,7 +1588,7 @@
 				
 				if (fframe < p->plength){
 					if ((c=find_audio_s(p->buf,
-							    9+p->hlength+4+fframe, 
+							    9+p->hlength+4+fframe,
 							    AC3, p->plength+6)) >= 0){
 						rx->scan_found = id;
 						//fprintf(stderr,"0x%04x  0x%04x \n",
@@ -1414,24 +1619,24 @@
 	int re=0;
 	uint16_t vpid[MAXVPID], apid[MAXAPID], ac3pid[MAXAC3PID];
 	int vn=0, an=0,ac3n=0;
-		
+	
 	memset (vpid , 0 , MAXVPID*sizeof(uint16_t));
 	memset (apid , 0 , MAXAPID*sizeof(uint16_t));
 	memset (ac3pid , 0 , MAXAC3PID*sizeof(uint16_t));
-
+	
 	fprintf(stderr,"Trying to find PES IDs\n");
 	rx->scan_found=0;
 	rx->pvideo.priv = rx ;
-	while (count < (int) rx->inflength-IN_SIZE){
+	while (count < 50000000 && count < rx->inflength-IN_SIZE){
 		if ((re = save_read(rx,buf,IN_SIZE))<0)
 			perror("reading");
-		else 
+		else
 			count += re;
 		
 		get_pes(&rx->pvideo, buf, re, pes_id_out);
 		
 		if ( rx->scan_found ){
-
+			
 			switch (rx->scan_found){
 				
 			case VIDEO_STREAM_S ... VIDEO_STREAM_E:
@@ -1452,10 +1657,10 @@
 					       (int)vpid[vn], (int)vpid[vn]);
 					if (vn+1 < MAXVPID) vn++;
 				}
-			} 				
+			}
 			break;
-
 			
+			
 			case AUDIO_STREAM_S ... AUDIO_STREAM_E:
 			{
 				int old=0;
@@ -1465,15 +1670,15 @@
 						break;
 					}
 				if (!old){
-					apid[an]=rx->scan_found;
+					apid[an] = rx->apid[an] = rx->scan_found;
 					printf("MPEG AUDIO %d: 0x%02x (%d)\n",
 					       an +1,
 					       (int)apid[an],(int)apid[an]);
 					if (an+1 < MAXAPID) an++;
-				}				
+				}
 			}
 			break;
-
+			
 			case 0x80 ... 0x8f:
 			{
 				int old=0;
@@ -1483,17 +1688,18 @@
 						break;
 					}
 				if (!old){
-					ac3pid[ac3n]=rx->scan_found;
+					ac3pid[ac3n]=rx->ac3_id[ac3n]=rx->scan_found;
 					if (rx->vdr){
 						printf("possible AC3 AUDIO with private stream 1 pid (0xbd) \n");
-					}else{
-						printf("AC3 AUDIO %d: 0x%02x (%d) \n", 
+					}
+					else {
+						printf("AC3 AUDIO %d: 0x%02x (%d) \n",
 						       ac3n+1,
 						       (int)ac3pid[ac3n],
 						       (int)ac3pid[ac3n]);
 					}
 					if (ac3n+1< MAXAC3PID) ac3n++;
-				}				
+				}
 				rx->scan_found = 0;
 			}
 			break;
@@ -1501,13 +1707,15 @@
 			rx->scan_found = 0;
 		}
 	}
+	rx->ac3n = ac3n;
+	rx->apidn = an;
 }
 
 
 
 void replex_finish(struct replex *rx)
 {
-
+	
 	fprintf(stderr,"\n");
 	if (!replex_all_set(rx)){
 		fprintf(stderr,"Can't find all required streams\n");
@@ -1516,7 +1724,7 @@
 		}
 		exit(1);
 	}
-
+	
 	if (!rx->demux)
 		finish_mpg((multiplex_t *)rx->priv);
 	exit(0);
@@ -1740,11 +1948,17 @@
 }
 
 
-void init_replex(struct replex *rx)
+void init_replex(struct replex *rx,int bufsize)
 {
 	int i;
 	uint8_t mbuf[2*TS_SIZE];
 	
+	int VIDEO_BUF, AUDIO_BUF, AC3_BUF;
+
+	VIDEO_BUF = bufsize;
+	AUDIO_BUF = (VIDEO_BUF/10);
+	AC3_BUF   = (VIDEO_BUF/10);
+
 	rx->analyze=0;
 
 	if (save_read(rx, mbuf, 2*TS_SIZE)<0)
@@ -1757,9 +1971,8 @@
 				find_pids_file(rx);
 			}
 		}
-	}
+	}	
 
-	
 	if (rx->otype==REPLEX_HDTV){
 		rx->videobuf = 4*VIDEO_BUF;
 	} else {
@@ -1778,9 +1991,11 @@
 	ring_init(&rx->vrbuffer, rx->videobuf);
 	if (rx->itype == REPLEX_TS || rx->itype == REPLEX_AVI)
 		init_pes_in(&rx->pvideo, 0xE0, &rx->vrbuffer, 0);
-	else {
+	else if (rx->itype == REPLEX_PS){
 		init_pes_in(&rx->pvideo, 0, NULL, 1);
-	}
+//		find_pes_in(rx);
+	} else init_pes_in(&rx->pvideo, 0, NULL, 1);
+	
 	rx->pvideo.priv = (void *) rx;
 	ring_init(&rx->index_vrbuffer, INDEX_BUF);
 	memset(&rx->seq_head, 0, sizeof(sequence_t));
@@ -1828,7 +2043,7 @@
 	}	
 	
 	if (rx->itype == REPLEX_TS){
-		if (replex_fill_buffers(rx, mbuf)< 0) {
+		if (replex_fill_buffers(rx, mbuf)< 0){
 			fprintf(stderr,"error filling buffer\n");
 			exit(1);
 		}
@@ -1875,12 +2090,12 @@
 			exit(1);
 		}
 
-		if (replex_fill_buffers(rx, buf+re)< 0) {
+		if (replex_fill_buffers(rx, buf+re)< 0){
 			fprintf(stderr,"error filling buffer\n");
 			exit(1);
 		}
 	} else {
-		if (replex_fill_buffers(rx, mbuf)< 0) {
+		if (replex_fill_buffers(rx, mbuf)< 0){
 			fprintf(stderr,"error filling buffer\n");
 			exit(1);
 		}
@@ -1901,24 +2116,27 @@
 		do {
 			while (ring_avail(&rx->index_arbuffer[i]) < 
 			       sizeof(index_unit)){
-				if (replex_fill_buffers(rx, 0)< 0) {
+				if (replex_fill_buffers(rx, 0)< 0){
 					fprintf(stderr,
 						"error in fix audio\n");
 					exit(1);
 				}	
 			}
-			ring_peek(&rx->index_arbuffer[i], (uint8_t *)&aiu, size, 0);
+			ring_peek(&rx->index_arbuffer[i], (uint8_t *)&aiu, 
+				  size, 0);
 			if ( ptscmp(aiu.pts + rx->first_apts[i], rx->first_vpts) < 0){
 				ring_skip(&rx->index_arbuffer[i], size);
 				ring_skip(&rx->arbuffer[i], aiu.length);
 			} else break;
 
 		} while (1);
-		mx->ext[i].pts_off = aiu.pts;
+		mx->apts_off[i] = aiu.pts;
+		rx->apts_off[i] = aiu.pts;
+		mx->aframes[i] = aiu.framesize;
 		
 		fprintf(stderr,"Audio%d  offset: ",i);
-		printpts(mx->ext[i].pts_off);
-		printpts(rx->first_apts[i]+mx->ext[i].pts_off);
+		printpts(mx->apts_off[i]);
+		printpts(rx->first_apts[i]+mx->apts_off[i]);
 		fprintf(stderr,"\n");
 	}
 			  
@@ -1926,24 +2144,25 @@
 		do {
 			while (ring_avail(&rx->index_ac3rbuffer[i]) < 
 			       sizeof(index_unit)){
-				if (replex_fill_buffers(rx, 0)< 0) {
+				if (replex_fill_buffers(rx, 0)< 0){
 					fprintf(stderr,
 						"error in fix audio\n");
 					exit(1);
 				}	
 			}
-			ring_peek(&rx->index_ac3rbuffer[i], (uint8_t *)&aiu, 
+			ring_peek(&rx->index_ac3rbuffer[i],(uint8_t *) &aiu, 
 				  size, 0);
 			if ( ptscmp (aiu.pts+rx->first_ac3pts[i], rx->first_vpts) < 0){
 				ring_skip(&rx->index_ac3rbuffer[i], size);
 				ring_skip(&rx->ac3rbuffer[i], aiu.length);
 			} else break;
 		} while (1);
-		mx->ext[i].pts_off = aiu.pts;
+		mx->ac3pts_off[i] = aiu.pts;
+		rx->ac3pts_off[i] = aiu.pts;
 		
 		fprintf(stderr,"AC3%d  offset: ",i);
-		printpts(mx->ext[i].pts_off);
-		printpts(rx->first_ac3pts[i]+mx->ext[i].pts_off);
+		printpts(mx->ac3pts_off[i]);
+		printpts(rx->first_ac3pts[i]+mx->ac3pts_off[i]);
 		fprintf(stderr,"\n");
 
 	}
@@ -1973,7 +2192,7 @@
 
 static int get_next_ac3_unit(struct replex *rx, index_unit *aiu, int i)
 {
-	if (ring_avail(&rx->index_ac3rbuffer[i])) {
+	if (ring_avail(&rx->index_ac3rbuffer[i])){
 		ring_read(&rx->index_ac3rbuffer[i], (uint8_t *)aiu, 
 			  sizeof(index_unit));
 		
@@ -2005,7 +2224,7 @@
 	
 	
 	while(!rx->finish){
-		if (replex_fill_buffers(rx, 0)< 0) {
+		if (replex_fill_buffers(rx, 0)< 0){
 			fprintf(stderr,"error in get next video unit\n");
 			return;
 		}
@@ -2140,26 +2359,55 @@
 	index_unit dummy;
 	index_unit dummy2;
 	int i;
+	multiplex_t mx;
 	fprintf(stderr,"STARTING DEMUX\n");
+
+
+	while (!replex_all_set(rx)){
+		if (replex_fill_buffers(rx, 0)< 0){
+			fprintf(stderr,"error filling buffer\n");
+			exit(1);
+		}
+	}
+
+	fix_audio(rx, &mx);
 	
 	while(!rx->finish){
-		if (replex_fill_buffers(rx, 0)< 0) {
+		if (replex_fill_buffers(rx, 0)< 0){
 			fprintf(stderr,"error in get next video unit\n");
 			return;
 		}
 		for (i=0; i< rx->apidn; i++){
 			while(get_next_audio_unit(rx, &dummy2, i)){
-				ring_read_file(&rx->arbuffer[i], 
-					       rx->dmx_out[i+1], 
-					       dummy2.length);
+				switch(dummy2.err){
+				case JUMP_ERR:
+					ring_skip(&rx->arbuffer[i],dummy2.length);
+					break;
+				case DUMMY_ERR:
+					write(rx->dmx_out[i+1],dummy.fillframe,dummy2.length);
+					break; 
+				default:
+					ring_read_file(&rx->arbuffer[i], 
+						       rx->dmx_out[i+1], 
+						       dummy2.length);
+				}
 			}
 		}
 		
 		for (i=0; i< rx->ac3n; i++){
 			while(get_next_ac3_unit(rx, &dummy2, i)){
-				ring_read_file(&rx->ac3rbuffer[i], 
-					       rx->dmx_out[i+1+rx->apidn], 
-					       dummy2.length);
+				switch(dummy2.err){
+				case JUMP_ERR:
+					ring_skip(&rx->ac3rbuffer[i],dummy2.length);
+					break;
+				case DUMMY_ERR:
+					write(rx->dmx_out[i+1+rx->apidn],dummy.fillframe,dummy2.length);
+					break; 
+				default:
+					ring_read_file(&rx->ac3rbuffer[i], 
+						       rx->dmx_out[i+1+rx->apidn], 
+						       dummy2.length);
+				}
 			}
 		}
 		
@@ -2174,59 +2422,51 @@
 void do_replex(struct replex *rx)
 {
 	int video_ok = 0;
-	int ext_ok[N_AUDIO];
+	int audio_ok[N_AUDIO];
+	int ac3_ok[N_AC3];
 	int start=1;
 	multiplex_t mx;
+	int done = 0;
 
 
 	fprintf(stderr,"STARTING REPLEX\n");
 	memset(&mx, 0, sizeof(mx));
-	memset(ext_ok, 0, N_AUDIO*sizeof(int));
+	memset(audio_ok, 0, N_AUDIO*sizeof(int));
+	memset(ac3_ok, 0, N_AC3*sizeof(int));
 
 	while (!replex_all_set(rx)){
-		if (replex_fill_buffers(rx, 0)< 0) {
+		if (replex_fill_buffers(rx, 0)< 0){
 			fprintf(stderr,"error filling buffer\n");
 			exit(1);
 		}
 	}
 
- int i; 
-   for (i = 0; i < rx->apidn; i++){
-        rx->exttype[i] = 2;
-        rx->extframe[i] = rx->aframe[i];
-        rx->extrbuffer[i] = rx->arbuffer[i];
-        rx->index_extrbuffer[i] = rx->index_arbuffer[i];
-        rx->exttypcnt[i+1] = i;
-    }
-
-    int ac3Count = 1;
-    for (i = rx->apidn; i < rx->apidn + rx->ac3n; i++){
-        rx->exttype[i] = 1;
-        rx->extframe[i] = rx->ac3frame[i];
-        rx->extrbuffer[i] = rx->ac3rbuffer[i];
-        rx->index_extrbuffer[i] = rx->index_ac3rbuffer[i];
-        rx->exttypcnt[i] = ac3Count++;
-    }
-
-    mx.priv = (void *) rx;
+	mx.priv = (void *) rx;
 	rx->priv = (void *) &mx;
-    init_multiplex(&mx, &rx->seq_head, rx->extframe,
-                 rx->exttype, rx->exttypcnt, rx->video_delay, 
-                 rx->audio_delay, rx->fd_out, fill_buffers,
-                 &rx->vrbuffer, &rx->index_vrbuffer,  
-                 rx->extrbuffer, rx->index_extrbuffer,
-                 rx->otype);
+	init_multiplex(&mx, &rx->seq_head, rx->aframe, rx->ac3frame, 
+		       rx->apidn, rx->ac3n, rx->video_delay, 
+		       rx->audio_delay, rx->fd_out, fill_buffers,
+		       &rx->vrbuffer, &rx->index_vrbuffer,	
+		       rx->arbuffer, rx->index_arbuffer,
+		       rx->ac3rbuffer, rx->index_ac3rbuffer, rx->otype);
 
 	if (!rx->ignore_pts){ 
 		fix_audio(rx, &mx);
 	}
 	setup_multiplex(&mx);
 
-	while(1){
-		check_times( &mx, &video_ok, ext_ok, &start);
+	do {
+		check_times( &mx, &video_ok, audio_ok, ac3_ok, &start);
 
-		write_out_packs( &mx, video_ok, ext_ok);
-	}
+		write_out_packs( &mx, video_ok, audio_ok, ac3_ok);
+	
+		if (mx.max_reached) done = 1;
+		if (mx.zero_write_count >100){
+			fprintf(stderr,"Can`t continue, check input file\n");
+			done=1;
+		}
+	} while (!done);
+	
 }
 
 
@@ -2234,159 +2474,202 @@
 {
         printf ("usage: %s [options] <input files>\n\n",progname);
         printf ("options:\n");
-        printf ("  --help,             -h:  print help message\n");
-        printf ("  --type,             -t:  set output type (MPEG2, DVD, HDTV)\n");
-        printf ("  --of,               -o:  set output file\n");
-        printf ("  --input_stream,     -i:  set input stream type (TS(default), PS, AVI)\n");
-        printf ("  --audio_pid,        -a:  audio PID for TS stream (also used for PS id)\n");
-        printf ("  --ac3_id,           -c:  ID of AC3 audio for demux (also used for PS id)\n");
-        printf ("  --video_pid,        -v:  video PID for TS stream (also used for PS id)\n");
-        printf ("  --video_delay,      -d:  video delay in ms\n");
-        printf ("  --audio_delay,      -e:  audio delay in ms\n");
-        printf ("  --ignore_PTS,       -f:  ignore all PTS information of original\n");
-        printf ("  --keep_PTS,         -k:  keep and don't correct PTS information of original\n");
-        printf ("  --fix_sync,         -n:  try to fix audio sync while demuxing\n");
-        printf ("  --demux,            -z:  demux only (-o is basename)\n");
-        printf ("  --analyze,          -y:  analyze (0=video,1=audio, 2=both)\n");
-        printf ("  --scan,             -s:  scan for streams\n");
-        printf ("  --vdr,              -x:  handle AC3 for vdr input file\n");
+        printf ("  --help,             -h            :  print help message\n");
+        printf ("\n");
+        printf ("  --audio_pid,        -a <integer>  :  audio PID for TS stream (also used for PS id, default 0xc0)\n");
+        printf ("  --ac3_id,           -c <integer>  :  ID of AC3 audio for demux (also used for PS id, i.e. 0x80)\n");
+        printf ("  --video_delay,      -d <integer>  :  video delay in ms\n");
+        printf ("  --audio_delay,      -e <integer>  :  audio delay in ms\n");
+        printf ("  --ignore_PTS,       -f            :  ignore all PTS information of original\n");
+	printf ("  --larger_buffer     -g <integer>  :  video buffer in MB\n"); 
+        printf ("  --input_stream,     -i <string>   :  set input stream type (string = TS(default), PS, AVI)\n");
+        printf ("  --allow_jump,       -j            :  allow jump in the PTS and try repair\n");
+        printf ("  --keep_PTS,         -k            :  keep and don't correct PTS information of original\n");
+	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");
+        printf ("  --of,               -o <filename> :  set output file\n");
+	printf ("  --fillzero          -p            :  fill audio frames with zeros (only MPEG AUDIO)\n");
+	printf ("  --max_overflow      -q <integer>  :  max_number of overflows allowed (default: 100, 0=no restriction)\n");
+        printf ("  --scan,             -s            :  scan for streams\n");
+        printf ("  --type,             -t <string>   :  set output type (string = MPEG2, DVD, HDTV)\n");
+        printf ("  --video_pid,        -v <integer>  :  video PID for TS stream (also used for PS id, default 0xe0)\n");
+        printf ("  --vdr,              -x            :  handle AC3 for vdr input file\n");
+        printf ("  --analyze,          -y <integer>  :  analyze (0=video,1=audio, 2=both)\n");
+        printf ("  --demux,            -z            :  demux only (-o is basename)\n");
         exit(1);
 }
 
 int main(int argc, char **argv)
 {
-	int c;
+        int c;
 	int analyze=0;
 	int scan =0;
-	char *filename = NULL;
-	char *type = "SVCD";
-	char *inpt = "TS";
+        char *filename = NULL;
+        char *type = "SVCD";
+        char *inpt = "TS";
+	int bufsize = 6*1024*1024;
+	uint64_t min_jump=0;
+	int fillzero = 0;
 
 	struct replex rx;
 
+	fprintf(stderr,"replex version Myth-Internal");
+
 	memset(&rx, 0, sizeof(struct replex));
+	rx.max_overflows = 100;
 
-	while (1) {
-		int option_index = 0;
-		static struct option long_options[] = {
-			{"type", required_argument, NULL, 't'},
-			{"input_stream", required_argument, NULL, 'i'},
-			{"video_pid", required_argument, NULL, 'v'},
+        while (1){
+                int option_index = 0;
+                static struct option long_options[] = {
 			{"audio_pid", required_argument, NULL, 'a'},
+			{"ac3_id", required_argument, NULL, 'c'},
+			{"video_delay", required_argument, NULL, 'd'},
 			{"audio_delay", required_argument, NULL, 'e'},
-			{"video_delay", required_argument, NULL, 'd'},
-			{"ac3_id", required_argument, NULL, 'c'},
-			{"of",required_argument, NULL, 'o'},
 			{"ignore_PTS",required_argument, NULL, 'f'},
+			{"larger_buffer",required_argument, NULL, 'g'},
+			{"help", no_argument , NULL, 'h'},
+			{"input_stream", required_argument, NULL, 'i'},
+			{"allow_jump",required_argument, NULL, 'j'},
 			{"keep_PTS",required_argument, NULL, 'k'},
-			{"fix_sync",no_argument, NULL, 'n'},
-			{"demux",no_argument, NULL, 'z'},
-			{"analyze",required_argument, NULL, 'y'},
+			{"min_jump",required_argument, NULL, 'l'},
+			{"of",required_argument, NULL, 'o'},
+			{"fillzero",required_argument, NULL, 'p'},
+			{"max_overflow",required_argument, NULL, 'q'},
 			{"scan",required_argument, NULL, 's'},
+			{"type", required_argument, NULL, 't'},
+			{"video_pid", required_argument, NULL, 'v'},
 			{"vdr",required_argument, NULL, 'x'},
-			{"help", no_argument , NULL, 'h'},
+			{"analyze",required_argument, NULL, 'y'},
+			{"demux",no_argument, NULL, 'z'},
 			{0, 0, 0, 0}
 		};
-		c = getopt_long (argc, argv, 
-					"t:o:a:v:i:hp:q:d:c:n:fkd:e:zy:sx",
+                c = getopt_long (argc, argv, 
+				 "a:c:d:e:fg:hi:jkl:o:pq:st:v:xy:z",
                                  long_options, &option_index);
-		if (c == -1)
-    		break;
+                if (c == -1)
+                        break;
 
-		switch (c) {
-		case 't':
-			type = optarg;
-			break;
-		case 'i':
-			inpt = optarg;
-			break;
-		case 'd':
-			rx.video_delay = strtol(optarg,(char **)NULL, 0) 
-				*CLOCK_MS;
-			break;
-		case 'e':
-			rx.audio_delay = strtol(optarg,(char **)NULL, 0) 
-				*CLOCK_MS;
-			break;
-		case 'a':
+                switch (c){
+                case 'a':
 			if (rx.apidn==N_AUDIO){
 				fprintf(stderr,"Too many audio PIDs\n");
 				exit(1);
 			}
                         rx.apid[rx.apidn] = strtol(optarg,(char **)NULL, 0);
 			rx.apidn++;
-			break;
-		case 'v':
-			rx.vpid = strtol(optarg,(char **)NULL, 0);
-			break;
-		case 'c':
+                        break;
+                case 'c':
 			if (rx.ac3n==N_AC3){
 				fprintf(stderr,"Too many audio PIDs\n");
 				exit(1);
 			}
-			rx.ac3_id[rx.ac3n] = strtol(optarg,(char **)NULL, 0);
+                        rx.ac3_id[rx.ac3n] = strtol(optarg,(char **)NULL, 0);
 			rx.ac3n++;
+                        break;
+		case 'd':
+			rx.video_delay = strtol(optarg,(char **)NULL, 0) 
+				*CLOCK_MS;
 			break;
-		case 'o':
-			filename = optarg;
+		case 'e':
+			rx.audio_delay = strtol(optarg,(char **)NULL, 0) 
+				*CLOCK_MS;
 			break;
 		case 'f':
 			rx.ignore_pts =1;
 			break;
+		case 'g':
+			bufsize = strtol(optarg,(char **)NULL, 0) *1024*1024; 
+			break;
+                case 'i':
+                        inpt = optarg;
+                        break;
+                case 'j':
+                        rx.allow_jump = MIN_JUMP;
+                        break;
 		case 'k':
 			rx.keep_pts =1;
 			break;
-		case 'z':
-			rx.demux =1;
+		case 'l':
+			min_jump = strtol(optarg,(char **)NULL, 0) *CLOCK_MS; 
 			break;
-		case 'n':
-			rx.fix_sync =1;
+                case 'o':
+                        filename = optarg;
+                        break;
+		case 'p':
+			fillzero = 1;
 			break;
-		case 'y':
-			analyze = strtol(optarg,(char **)NULL, 0);
-			if (analyze>2) usage(argv[0]);
-			analyze++;
+		case 'q':
+			rx.max_overflows = strtol(optarg,(char **)NULL, 0); 
 			break;
 		case 's':
 			scan = 1;
 			break;
+                case 't':
+                        type = optarg;
+                        break;
+                case 'v':
+                        rx.vpid = strtol(optarg,(char **)NULL, 0);
+                        break;
 		case 'x':
 			rx.vdr=1;
 			break;
-		case 'h':
-		case '?':
-		default:
-			usage(argv[0]);
+		case 'y':
+			analyze = strtol(optarg,(char **)NULL, 0);
+			if (analyze>2) usage(argv[0]);
+			analyze++;
+			break;
+		case 'z':
+			rx.demux = 1;
+			break;
+                case 'h':
+                case '?':
+                default:
+                        usage(argv[0]);
+                }
+        }
+
+	if (rx.allow_jump && min_jump) rx.allow_jump = min_jump;
+
+	if (fillzero) rx.fillzero = 1;
+	rx.inputFiles = NULL;
+        if (optind < argc){
+		int i = 0;
+		rx.inputFiles = calloc( sizeof(char * ), argc - optind + 1);
+		while (optind < argc) {
+			if ((rx.fd_in = open(argv[optind] ,O_RDONLY| O_LARGEFILE)) < 0){
+				fprintf(stderr,"Error opening input file %s",argv[optind] );
+				exit(1);
+			}
+			close(rx.fd_in);
+			rx.inputFiles[i] = argv[optind];
+			i++;
+			optind++;
 		}
-	}
-
-	if (rx.fix_sync)
-		av_register_all();
-	
-	if (optind == argc-1) {
-		if ((rx.fd_in = open(argv[optind] ,O_RDONLY| O_LARGEFILE)) < 0) {
-			perror("Error opening input file ");
+		rx.inputFiles[i] = NULL;
+		rx.inputIdx = 0;
+		if ((rx.fd_in = open(rx.inputFiles[0] ,O_RDONLY| O_LARGEFILE)) < 0) {
+			fprintf(stderr,"Error opening input file %s",argv[optind] );
 			exit(1);
 		}
-		fprintf(stderr,"Reading from %s\n", argv[optind]);
+
+                fprintf(stderr,"Reading from %s\n", argv[optind]);
 		rx.inflength = lseek(rx.fd_in, 0, SEEK_END);
 		fprintf(stderr,"Input file length: %.2f MB\n",rx.inflength/1024./1024.);
 		lseek(rx.fd_in,0,SEEK_SET);
 		rx.lastper = 0;
 		rx.finread = 0;
-	} else {
+        } else {
 		fprintf(stderr,"using stdin as input\n");
 		rx.fd_in = STDIN_FILENO;
 		rx.inflength = 0;
-	}
+        }
 
 	if (!rx.demux){
 		if (filename){
 			if ((rx.fd_out = open(filename,O_WRONLY|O_CREAT
-					|O_TRUNC|O_LARGEFILE,
-					S_IRUSR|S_IWUSR|S_IRGRP|
-					S_IWGRP|
-					S_IROTH|S_IWOTH)) < 0){
+					      |O_TRUNC|O_LARGEFILE,
+					      S_IRUSR|S_IWUSR|S_IRGRP|
+					      S_IWGRP|
+					      S_IROTH|S_IWOTH)) < 0){
 				perror("Error opening output file");
 				exit(1);
 			}
@@ -2406,16 +2689,16 @@
 		exit(0);
 	}
 
-	if (!strncmp(type,"MPEG2",6))
+        if (!strncmp(type,"MPEG2",6))
 		rx.otype=REPLEX_MPEG2;
 	else if (!strncmp(type,"DVD",4))
 		rx.otype=REPLEX_DVD;
 	else if (!strncmp(type,"HDTV",4))
 		rx.otype=REPLEX_HDTV;
-	else if (!rx.demux)
-		usage(argv[0]);
+        else if (!rx.demux && !analyze)
+                usage(argv[0]);
 	
-	if (!strncmp(inpt,"TS",3)){
+        if (!strncmp(inpt,"TS",3)){
 		rx.itype=REPLEX_TS;
 	} else if (!strncmp(inpt,"PS",3)){
 		rx.itype=REPLEX_PS;
@@ -2431,13 +2714,13 @@
 		rx.apid[0] = 0xC0;
 		rx.ignore_pts =1;
 	} else {
-		usage(argv[0]);
+                usage(argv[0]);
 	}
 
-	init_replex(&rx);
+	init_replex(&rx, bufsize);
 	rx.analyze= analyze;
 
-	if (rx.demux) {
+	if (rx.demux){
 		int i;
 		char fname[256];
 		if (!filename){
@@ -2504,6 +2787,6 @@
 	} else {
 		do_replex(&rx);
 	}
-
+	
 	return 0;
 }
Index: replex/mpg_common.h
===================================================================
--- replex/mpg_common.h	(revision 18755)
+++ replex/mpg_common.h	(working copy)
@@ -2,8 +2,10 @@
  * mpg_common.h
  *        
  *
- * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
+ * Copyright (C) 2003 - 2006
+ *                    Marcus Metzler <mocm@metzlerbros.de>
  *                    Metzler Brothers Systementwicklung GbR
+ *           (C) 2006 Reel Multimedia
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -47,31 +49,22 @@
 	uint8_t  frame_off;
 	uint8_t  frame_start;
 	uint8_t  err;
-	uint32_t framesize;
-	uint64_t ptsrate;
+	int      framesize;
+	uint8_t  *fillframe;
 } index_unit;
 
-typedef struct extdata_s{
-	index_unit iu;
-	uint64_t pts;
-	uint64_t pts_off;
-        int type;
-        int strmnum;
-	int frmperpkt;
-	char language[4];
-	dummy_buffer dbuf;
-} extdata_t;
-
-
 #define NO_ERR    0
 #define FRAME_ERR 1
+#define PTS_ERR 2
+#define JUMP_ERR 3
+#define DUMMY_ERR 4
+#define DROP_ERR 5
 
-
 void show_buf(uint8_t *buf, int length);
 int find_mpg_header(uint8_t head, uint8_t *buf, int length);
 int find_any_header(uint8_t *head, uint8_t *buf, int length);
 uint64_t trans_pts_dts(uint8_t *pts);
-int mring_peek( ringbuffer *rbuf, uint8_t *buf, unsigned int l, uint32_t off);
+int mring_peek( ringbuffer *rbuf, uint8_t *buf, int l, long off);
 int ring_find_mpg_header(ringbuffer *rbuf, uint8_t head, int off, int le);
 int ring_find_any_header(ringbuffer *rbuf, uint8_t *head, int off, int le);
 
Index: replex/replex.h
===================================================================
--- replex/replex.h	(revision 18755)
+++ replex/replex.h	(working copy)
@@ -2,8 +2,10 @@
  * replex.h
  *        
  *
- * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
+ * Copyright (C) 2003 - 2006
+ *                    Marcus Metzler <mocm@metzlerbros.de>
  *                    Metzler Brothers Systementwicklung GbR
+ *           (C) 2006 Reel Multimedia
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -36,6 +38,8 @@
 #include "multiplex.h"
 
 enum { S_SEARCH, S_FOUND, S_ERROR };
+#define MIN_JUMP 100*CLOCK_MS;
+#define MAXFRAME 2000
 
 struct replex {
 #define REPLEX_TS  0
@@ -45,7 +49,7 @@
 	int otype;
 	int ignore_pts; 
 	int keep_pts;
-	int fix_sync;
+	uint64_t allow_jump;
 	uint64_t inflength;
 	uint64_t finread;
 	int lastper;
@@ -59,25 +63,19 @@
 	int analyze;
 	avi_context ac;
 	int vdr;
+	int fillzero;
+	int overflows;
+	int max_overflows;
 
 	uint64_t video_delay;
 	uint64_t audio_delay;
 
-#define VIDEO_BUF (6*1024*1024)
-#define AUDIO_BUF (VIDEO_BUF/10)
-#define AC3_BUF   (VIDEO_BUF/10)
 #define INDEX_BUF (32000*32)
+
 	int audiobuf;
 	int ac3buf;
 	int videobuf;
 
-    int ext_count;
-    int exttype[N_AUDIO];
-    int exttypcnt[N_AUDIO];
-    audio_frame_t extframe[N_AUDIO];
-    ringbuffer extrbuffer[N_AUDIO];
-    ringbuffer index_extrbuffer[N_AUDIO];
-
   //ac3 
 	int ac3n;
 	uint16_t ac3_id[N_AC3];
@@ -91,7 +89,12 @@
 	uint64_t first_ac3pts[N_AC3];
 	int ac3_state[N_AUDIO];
 	uint64_t last_ac3pts[N_AC3];
+	uint64_t ac3_jump[N_AUDIO];
+	uint64_t ac3pts_off[N_AC3];
+	uint8_t  ac3fillframe[N_AC3][MAXFRAME];
+	int  ac3filled[N_AC3];
 
+
 // mpeg audio
 	int apidn;
 	uint16_t apid[N_AUDIO];
@@ -105,6 +108,10 @@
 	uint64_t first_apts[N_AUDIO];
 	int audio_state[N_AUDIO];
 	uint64_t last_apts[N_AUDIO];
+	uint64_t audio_jump[N_AUDIO];
+	uint64_t apts_off[N_AUDIO];
+	uint8_t  afillframe[N_AC3][MAXFRAME];
+	int  afilled[N_AC3];
 
 //mpeg video
         uint16_t vpid;
@@ -120,9 +127,13 @@
 	uint64_t first_vpts;
 	int video_state;
 	uint64_t last_vpts;
+	uint64_t video_jump;
+	uint64_t vjump_pts;
 
 	void *priv;
 	int scan_found;
+        char **inputFiles;
+        int inputIdx;
 };
 
 void init_index(index_unit *iu);
Index: replex/README
===================================================================
--- replex/README	(revision 18755)
+++ replex/README	(working copy)
@@ -6,29 +6,36 @@
 usage: ./replex [options] <input files>
  
 options:
-  --help,             -h:  print help message
-  --type,             -t:  set output type (MPEG2, DVD, HDTV)
-  --of,               -o:  set output file
-  --input_stream,     -i:  set input stream type (TS(default), PS, AVI)
-  --audio_pid,        -a:  audio PID for TS stream (also used for PS id)
-  --ac3_id,           -c:  ID of AC3 audio for demux (also used for PS id)
-  --video_pid,        -v:  video PID for TS stream (also used for PS id)
-  --video_delay,      -d:  video delay in ms
-  --audio_delay,      -e:  audio delay in ms
-  --ignore_PTS,       -f:  ignore all PTS information of original
-  --keep_PTS,         -k:  keep and don't correct PTS information of original
-  --demux,            -z:  demux only (-o is basename)
-  --analyze,          -y:  analyze (0=video,1=audio, 2=both)
-  --scan,             -s:  scan for streams  
-  --vdr,              -x:  handle AC3 for vdr input file
+  --help,             -h            :  print help message
 
+  --audio_pid,        -a <integer>  :  audio PID for TS stream (also used for PS id, default 0xc0)
+  --ac3_id,           -c <integer>  :  ID of AC3 audio for demux (also used for PS id, i.e. 0x80)
+  --video_delay,      -d <integer>  :  video delay in ms
+  --audio_delay,      -e <integer>  :  audio delay in ms
+  --ignore_PTS,       -f            :  ignore all PTS information of original
+  --larger_buffer     -g <integer>  :  video buffer in MB
+  --input_stream,     -i <string>   :  set input stream type (string = TS(default), PS, AVI)
+  --allow_jump,       -j            :  allow jump in the PTS and try repair
+  --keep_PTS,         -k            :  keep and don't correct PTS information of original
+  --min_jump,         -l <integer>  :  don't try to fix jumps in PTS larger than <int> but treat them as a cut (default 100ms)
+  --of,               -o <filename> :  set output file
+  --fillzero          -p            :  fill audio frames with zeros (only MPEG AUDIO)
+  --max_overflow      -q <integer>  :  max_number of overflows allowed (default: 100, 0=no restriction)
+  --scan,             -s            :  scan for streams
+  --type,             -t <string>   :  set output type (string = MPEG2, DVD, HDTV)
+  --video_pid,        -v <integer>  :  video PID for TS stream (also used for PS id, default 0xe0)
+  --vdr,              -x            :  handle AC3 for vdr input file
+  --analyze,          -y <integer>  :  analyze (0=video,1=audio, 2=both)
+  --demux,            -z            :  demux only (-o is basename)
+
 A typical call would be
 replex -t DVD -o mynewps.mpg myoldts.ts
 
 Replex can guess the PIDs of your audio and video streams, but
 especially if you have more than one audio stream you should use the
 -v and -a or -c options. The -a and -c options can be used more than
-once to create multiple audio tracks.
+once to create multiple audio tracks. Use the -s option to find out 
+about the PIDs in your file
 
 The -k option means that replex tries to keep the original PTS spacing,
 which can be helpful in case of corrupt streams. Replex will ignore
@@ -39,4 +46,16 @@
 from t]he original and creates the PTS according to the frames that are
 found.
 
+The -j option lets replex jump over PTS discontiniuties like the ones
+you get from cutting an MPEG file. With -l you can set the minimum time 
+a jump has to have to get treated as cut. The default for that is 100ms.
+If you have video jumps without any audio jumps and they are larger than 
+100ms (usually > 2 frames) you can try increasing the min_jump setting.
+If you set it too high and you have real jumps, e.g. audio and video 
+jumps from a cut, they may not get fixed correctly.
+
+
+The -g option can be helpful if you get ringbuffer overflows, it increases
+the video buffer size. Default is 6MB.
+
 For questions and/or suggestions contact me at mocm@metzlerbros.de. 
Index: replex/avi.c
===================================================================
--- replex/avi.c	(revision 18755)
+++ replex/avi.c	(working copy)
@@ -2,7 +2,8 @@
  * avi.c: AVI container functions for replex
  *        
  *
- * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
+ * Copyright (C) 2003 - 2006
+ *                    Marcus Metzler <mocm@metzlerbros.de>
  *                    Metzler Brothers Systementwicklung GbR
  *
  * This program is free software; you can redistribute it and/or
Index: replex/multiplex.c
===================================================================
--- replex/multiplex.c	(revision 18755)
+++ replex/multiplex.c	(working copy)
@@ -1,3 +1,31 @@
+/*
+ * multiplex.c: multiplex functions for replex
+ *        
+ *
+ * Copyright (C) 2003 - 2006
+ *                    Marcus Metzler <mocm@metzlerbros.de>
+ *                    Metzler Brothers Systementwicklung GbR
+ *           (C) 2006 Reel Multimedia
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * General Public License for more details.
+ *
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
 #include <unistd.h>
 #include <string.h>
 #include <stdlib.h>
@@ -3,6 +31,24 @@
 
 #include "multiplex.h"
-#include "ts.h"
 
+
+static int mplx_write(multiplex_t *mx, uint8_t *buffer,int length)
+{
+	int k=0;
+
+	if ( mx->max_write && mx->total_written+ length >  
+	     mx-> max_write && !mx->max_reached){
+		mx->max_reached = 1;
+		fprintf(stderr,"Maximum file size %dKB reached\n", mx->max_write/1024);
+		return 0;
+	}
+	if ((k=write(mx->fd_out, buffer, length)) <= 0){
+		mx->zero_write_count++;
+	} else {
+		mx->total_written += k;
+	}
+	return k;
+}
+
 static int buffers_filled(multiplex_t *mx)
 {
@@ -11,15 +57,47 @@
 
 	vavail = ring_avail(mx->index_vrbuffer)/sizeof(index_unit);
 	
-	for (i=0; i<mx->extcnt;i++){
-		aavail += ring_avail(&mx->index_extrbuffer[i])/
-				     sizeof(index_unit);
+//	for (i=0; i<mx->extcnt;i++){
+//		aavail += ring_avail(&mx->index_extrbuffer[i])/
+//				     sizeof(index_unit);
+//	}
+	for (i=0; i<mx->apidn;i++){
+		aavail += ring_avail(&mx->index_arbuffer[i])/sizeof(index_unit);
+ 	}
+ 
+	for (i=0; i<mx->ac3n;i++){
+		aavail += ring_avail(&mx->index_ac3rbuffer[i])
+			/sizeof(index_unit);
 	}
 
 	if (aavail+vavail) return ((aavail+vavail));
 	return 0;
 }
 
+static int all_audio_ok(int *aok, int n)
+{
+       int ok=0,i;
+ 
+       if (!n) return 0;
+       for (i=0;  i < n ;i++){
+               if (aok[i]) ok++;
+       }
+       if (ok == n) return 1;
+       return 0;
+}
+static int rest_audio_ok(int j, int *aok, int n)
+{
+       int ok=0,i;
+ 
+       if (!(n-1)) return 0;
+       for (i=0;  i < n ;i++){
+               if (i!=j && aok[i]) ok++;
+       }
+       if (ok == n) return 1;
+       return 0;
+}
+
+/*
 static int use_video(uint64_t vpts, extdata_t *ext, int *aok, int n)
 {
 	int i;
@@ -28,6 +106,8 @@
 			return 0;
 	return 1;
 }
+*/
+/*
 static int which_ext(extdata_t *ext, int *aok, int n)
 {
 	int i;
@@ -47,7 +127,8 @@
 		}
 	return pos;
 }
-
+*/
+/*
 static int peek_next_video_unit(multiplex_t *mx, index_unit *viu)
 {
 	if (!ring_avail(mx->index_vrbuffer) && mx->finish) return 0;
@@ -59,6 +140,19 @@
 		}
 
 	ring_peek(mx->index_vrbuffer, (uint8_t *)viu, sizeof(index_unit),0);
+*/
+static int get_next_video_unit(multiplex_t *mx, index_unit *viu)
+{
+       if (!ring_avail(mx->index_vrbuffer) && mx->finish) return 0;
+ 
+       while (ring_avail(mx->index_vrbuffer) < sizeof(index_unit))
+               if (mx->fill_buffers(mx->priv, mx->finish)< 0) {
+                       fprintf(stderr,"error in get next video unit\n");
+                       return 0;
+               }
+ 
+       ring_read(mx->index_vrbuffer, (uint8_t *)viu, sizeof(index_unit));
+
 #ifdef OUT_DEBUG
 	fprintf(stderr,"video index start: %d  stop: %d  (%d)  rpos: %d\n", 
 		viu->start, (viu->start+viu->length),
@@ -67,136 +161,79 @@
 
 	return 1;
 }
-	
-static int get_next_video_unit(multiplex_t *mx, index_unit *viu)
+
+static int peek_next_video_unit(multiplex_t *mx, index_unit *viu)
 {
-	index_unit nviu;
 	if (!ring_avail(mx->index_vrbuffer) && mx->finish) return 0;
 
 	while (ring_avail(mx->index_vrbuffer) < sizeof(index_unit))
 		if (mx->fill_buffers(mx->priv, mx->finish)< 0) {
-			fprintf(stderr,"error in get next video unit\n");
+			fprintf(stderr,"error in peek next video unit\n");
 			return 0;
 		}
 
-	ring_read(mx->index_vrbuffer, (uint8_t *)viu, sizeof(index_unit));
+	ring_peek(mx->index_vrbuffer, (uint8_t *)viu, sizeof(index_unit),0);
 #ifdef OUT_DEBUG
 	fprintf(stderr,"video index start: %d  stop: %d  (%d)  rpos: %d\n", 
 		viu->start, (viu->start+viu->length),
 		viu->length, ring_rpos(mx->vrbuffer));
 #endif
-	if(! peek_next_video_unit(mx, &nviu))
-		return 1;
-	//left-shift by 8 to increase precision
-	viu->ptsrate = (uptsdiff(nviu.dts, viu->dts) << 8) / viu->length;
+
 	return 1;
 }
-
-static int peek_next_ext_unit(multiplex_t *mx, index_unit *extiu, int i)
+	
+static int get_next_audio_unit(multiplex_t *mx, index_unit *aiu, int i)
 {
-	if (!ring_avail(&mx->index_extrbuffer[i]) && mx->finish) return 0;
+	if (!ring_avail(&mx->index_arbuffer[i]) && mx->finish) return 0;
 
-	while (ring_avail(&mx->index_extrbuffer[i]) < sizeof(index_unit))
+	while(ring_avail(&mx->index_arbuffer[i]) < sizeof(index_unit))
 		if (mx->fill_buffers(mx->priv, mx->finish)< 0) {
-			fprintf(stderr,"error in peek next video unit\n");
+			fprintf(stderr,"error in get next audio unit\n");
 			return 0;
 		}
+	
+	ring_read(&mx->index_arbuffer[i], (uint8_t *)aiu, sizeof(index_unit));
 
-	ring_peek(&mx->index_extrbuffer[i], (uint8_t *)extiu,
-		  sizeof(index_unit),0);
 #ifdef OUT_DEBUG
-	fprintf(stderr,"ext index start: %d  stop: %d  (%d)  rpos: %d\n", 
-		extiu->start, (extiu->start+extiu->length),
-		extiu->length, ring_rpos(mx->extrbuffer));
+	fprintf(stderr,"audio index start: %d  stop: %d  (%d)  rpos: %d\n", 
+		aiu->start, (aiu->start+aiu->length),
+		aiu->length, ring_rpos(&mx->arbuffer[i]));
 #endif
-
 	return 1;
 }
-	
-static int get_next_ext_unit(multiplex_t *mx, index_unit *extiu, int i)
+
+static int get_next_ac3_unit(multiplex_t *mx, index_unit *aiu, int i)
 {
-	index_unit niu, *piu = extiu;
-	int j, length = 0;
-	for(j = 0; j < mx->ext[i].frmperpkt; j++) {
-		if (!ring_avail(&mx->index_extrbuffer[i]) && mx->finish)
-			break;
-
-		while(ring_avail(&mx->index_extrbuffer[i]) < sizeof(index_unit))
-			if (mx->fill_buffers(mx->priv, mx->finish)< 0) {
-				fprintf(stderr,"error in get next ext unit\n");
-				break;
-			}
+	if (!ring_avail(&mx->index_ac3rbuffer[i]) && mx->finish) return 0;
+	while(ring_avail(&mx->index_ac3rbuffer[i]) < sizeof(index_unit))
+		if (mx->fill_buffers(mx->priv, mx->finish)< 0) {
+			fprintf(stderr,"error in get next ac3 unit\n");
+			return 0;
+		}
 	
-		ring_read(&mx->index_extrbuffer[i], (uint8_t *)piu,
-			  sizeof(index_unit));
-		length += piu->length;
-		piu = &niu;
-	}
-	if (j == 0)
-		return 0;
-	extiu->length = length;
-	extiu->framesize = length;
-	if(! peek_next_ext_unit(mx, &niu, i))
-		return 1;
-	//left-shift by 8 to increase precision
-	extiu->ptsrate = (uptsdiff(niu.pts, extiu->pts) << 8) / extiu->length;
-
-#ifdef OUT_DEBUG
-	fprintf(stderr,"ext index start: %d  stop: %d  (%d)  rpos: %d\n", 
-		extiu->start, (extiu->start+extiu->length),
-		extiu->length, ring_rpos(&mx->extrbuffer[i]));
-#endif
+	ring_read(&mx->index_ac3rbuffer[i], (uint8_t *)aiu, sizeof(index_unit));
 	return 1;
 }
 
-static uint8_t get_ptsdts(multiplex_t *mx, index_unit *viu)
-{
-	uint8_t ptsdts = 0;
-	switch (mx->frame_timestamps){
-	case TIME_ALWAYS:
-		if (viu->frame == I_FRAME || viu->frame == P_FRAME)
-			ptsdts = PTS_DTS;
-		else 
-			ptsdts = PTS_ONLY;
-		break;
-
-	case TIME_IFRAME:
-		if (viu->frame == I_FRAME)
-			ptsdts = PTS_DTS;
-		break;
-	}
-	return ptsdts;
-}
-
 static void writeout_video(multiplex_t *mx)
 {  
 	uint8_t outbuf[3000];
 	int written=0;
 	uint8_t ptsdts=0;
-	unsigned int length;
+	int length;
 	int nlength=0;
-        int frame_len=0;
 	index_unit *viu = &mx->viu;
 
 #ifdef OUT_DEBUG
-	fprintf(stderr,"writing VIDEO pack\n");
+	fprintf(stderr,"writing VIDEO pack");
 #endif
-
-	if(viu->frame_start) {
-		ptsdts = get_ptsdts(mx, viu);
-                frame_len = viu->length;
-	}
-
+	
 	if (viu->frame_start && viu->seq_header && viu->gop && 
 	    viu->frame == I_FRAME){
-		if (!mx->startup && mx->is_ts){
-			write_ts_patpmt(mx->ext, mx->extcnt, 1, outbuf);
-			write(mx->fd_out, outbuf, mx->pack_size*2);
-			ptsinc(&mx->SCR, mx->SCRinc*2);
-		} else if (!mx->startup && mx->navpack){
-			write_nav_pack(mx->pack_size, mx->extcnt, 
+		if (!mx->startup && mx->navpack){
+			write_nav_pack(mx->pack_size, mx->apidn, mx->ac3n, 
 				       mx->SCR, mx->muxr, outbuf);
-			write(mx->fd_out, outbuf, mx->pack_size);
+			mplx_write(mx, outbuf, mx->pack_size);
 			ptsinc(&mx->SCR, mx->SCRinc);
 		} else mx->startup = 0;
 #ifdef OUT_DEBUG
@@ -207,46 +244,47 @@
 	if (mx->finish != 2 && dummy_space(&mx->vdbuf) < mx->data_size){
 		return;
 	}
+
 	length = viu->length;
-	while (!mx->is_ts && length  < mx->data_size){
+	if  (length  < mx->data_size )
+		dummy_add(&mx->vdbuf, uptsdiff(viu->dts+mx->video_delay,0)
+			  , length);
+
+	while (length  < mx->data_size ){
 		index_unit nviu;
-                int old_start = viu->frame_start;
-                int old_frame = viu->frame;
-                uint64_t old_pts = viu->pts;
-                uint64_t old_dts = viu->dts;
-		dummy_add(&mx->vdbuf, uptsdiff(viu->dts+mx->video_delay,0)
-			  , viu->length);
 		if ( peek_next_video_unit(mx, &nviu)){
 			if (!(nviu.seq_header && nviu.gop && 
 			      nviu.frame == I_FRAME)){
 				get_next_video_unit(mx, viu);
-                                frame_len = viu->length;
 				length += viu->length; 
-				if(old_start) {
-					viu->pts = old_pts;
-					viu->dts = old_dts;
-					viu->frame = old_frame;
-				} else {
-					ptsdts = get_ptsdts(mx, viu);
-				}
+				if  (length  < mx->data_size )
+					dummy_add(&mx->vdbuf, 
+						  uptsdiff(viu->dts+
+							   mx->video_delay,0)
+						  , viu->length);
 			} else break;
 		} else break;
 	}
 
 	if (viu->frame_start){
+		switch (mx->frame_timestamps){
+		case TIME_ALWAYS:
+			if (viu->frame == I_FRAME || viu->frame == P_FRAME)
+				ptsdts = PTS_DTS;
+			else 
+				ptsdts = PTS_ONLY;
+			break;
+
+		case TIME_IFRAME:
+			if (viu->frame == I_FRAME)
+				ptsdts = PTS_DTS;
+			break;
+		}
 		viu->frame_start=0;
-	if (viu->gop){
-                uint8_t gop[8];
-                frame_len=length-frame_len;
-                ring_peek(mx->vrbuffer, gop, 8, frame_len);
-		pts2time( viu->pts + mx->video_delay, gop, 8);
-                ring_poke(mx->vrbuffer, gop, 8, frame_len);
-                viu->gop=0;
-	}
 		if (mx->VBR) {
 			mx->extra_clock = ptsdiff(viu->dts + mx->video_delay, 
 						  mx->SCR + 500*CLOCK_MS);
-#ifdef OUT_DEBUG1
+#ifdef OUT_DEBUG
 			fprintf(stderr,"EXTRACLOCK2: %lli %lli %lli\n", viu->dts, mx->video_delay, mx->SCR);
 			fprintf(stderr,"EXTRACLOCK2: %lli ", mx->extra_clock);
 			printpts(mx->extra_clock);
@@ -259,7 +297,156 @@
 	}
 
 
-	nlength = length;
+       nlength = length;
+
+       written = write_video_pes( mx->pack_size, mx->apidn, mx->ac3n, 
+                                  viu->pts+mx->video_delay, 
+                                  viu->dts+mx->video_delay, 
+                                  mx->SCR, mx->muxr, outbuf, &nlength, ptsdts,
+                                  mx->vrbuffer);
+  
+      length -= nlength;
+      dummy_add(&mx->vdbuf, uptsdiff( viu->dts+mx->video_delay,0)
+                 , viu->length-length);
+      viu->length = length;
+      if (viu->gop){
+              pts2time( viu->pts + mx->video_delay, outbuf, written);
+      }
+  
+      mplx_write(mx, outbuf, written);
+      
+      if (viu->length == 0){
+              get_next_video_unit(mx, viu);
+      }
+  
+}
+ 
+#define INSIZE 6000
+int add_to_inbuf(uint8_t *inbuf,ringbuffer *arbuffer, int inbc, int off, int length)
+{  
+       int add;
+       
+       if (inbc + length > INSIZE) {
+               fprintf(stderr,"buffer too small in write_out_audio %d %d\n",inbc,length);
+               return 0;
+       }
+       add= ring_peek( arbuffer, inbuf+inbc, length, off);
+       if (add < length) {
+               fprintf(stderr,"error while peeking audio ring %d (%d)\n", add,length);
+               return 0;
+       }
+       return add;
+}
+ 
+ 
+ static void clear_audio(multiplex_t *mx, int type, int n)
+{
+       index_unit *aiu;
+       int g=0;
+       ringbuffer *arbuffer;
+ 
+       switch (type){
+               
+       case MPEG_AUDIO:
+#ifdef OUT_DEBUG
+               fprintf(stderr,"clear AUDIO%d pack\n",n);
+#endif
+               arbuffer = &mx->arbuffer[n];
+               aiu = &mx->aiu[n];
+               break;
+ 
+       case AC3:
+#ifdef OUT_DEBUG
+               fprintf(stderr,"clear AC3%d pack\n",n);
+#endif
+               arbuffer = &mx->ac3rbuffer[n];
+               aiu = &mx->ac3iu[n];
+               break;
+ 
+       default:
+               return;
+       }
+       while (aiu->err == JUMP_ERR){
+//            fprintf(stderr,"FOUND ONE\n");
+               ring_skip(arbuffer, aiu->length);               
+               if (type == MPEG_AUDIO)
+                       g = get_next_audio_unit(mx, aiu, n);
+               else
+                       g = get_next_ac3_unit(mx, aiu, n);              
+      }
+
+}
+static void my_memcpy(uint8_t *target, int offset, uint8_t *source, int length, int maxlength)
+{
+       uint8_t *targ = NULL;
+ 
+       targ = target + offset;
+       
+       if ( offset+length > maxlength){
+               fprintf(stderr,"WARNING: buffer overflow in my_memcopy \n");
+//            fprintf(stderr, "source 0x%x  offset %d target 0x%x  length %d maxlength %d\n"
+//                    , source, offset, target, length, maxlength);
+       }
+       memcpy(targ, source, length);
+}
+ 
+static void writeout_audio(multiplex_t *mx, int type, int n)
+{  
+       uint8_t outbuf[3000];
+       uint8_t inbuf[INSIZE];
+       int inbc=0;
+       int written=0;
+       int length=0;
+       dummy_buffer *dbuf;
+       ringbuffer *airbuffer;
+       ringbuffer *arbuffer;
+       int nlength=0;
+       uint64_t pts, dpts=0;
+       uint64_t adelay;
+       int aframesize;
+       int newpts=0;
+       int nframes=1;
+       int ac3_off=0;
+       int rest_data = 5;
+       uint64_t *apts;
+       index_unit *aiu;
+       int g=0;
+       int add, off=0;
+       int fakelength = 0;
+       int droplength = 0;
+  
+       switch (type){
+  
+       case MPEG_AUDIO:
+#ifdef OUT_DEBUG
+               fprintf(stderr,"writing AUDIO%d pack\n",n);
+#endif
+               airbuffer = &mx->index_arbuffer[n];
+               arbuffer = &mx->arbuffer[n];
+               dbuf = &mx->adbuf[n];
+               adelay = mx->apts_off[n];
+               aframesize = mx->aframes[n];    
+               apts = &mx->apts[n];
+               aiu = &mx->aiu[n];
+               break;
+  
+       case AC3:
+#ifdef OUT_DEBUG
+               fprintf(stderr,"writing AC3%d pack\n",n);
+#endif
+               airbuffer = &mx->index_ac3rbuffer[n];
+               arbuffer = &mx->ac3rbuffer[n];
+               dbuf = &mx->ac3dbuf[n];
+               adelay = mx->ac3pts_off[n];
+               aframesize = mx->ac3frames[n];  
+               rest_data = 1; // 4 bytes AC3 header
+               apts = &mx->ac3pts[n];
+               aiu = &mx->ac3iu[n];
+               break;
+ 
+       default:
+
+/*
 	if (mx->is_ts)
 		written = write_video_ts(  viu->pts+mx->video_delay, 
 					   viu->dts+mx->video_delay, 
@@ -336,6 +523,7 @@
 		break;
 
 	default:
+*/
 		return;
 	}
 	
@@ -346,10 +534,38 @@
 	pts = uptsdiff( aiu->pts + mx->audio_delay, adelay );
 	*apts = pts;
 	length = aiu->length;
-	if (length < aiu->framesize){
+
+	if (length <  aiu->framesize){
 		newpts = 1;
 		ac3_off = length;
+		nframes = 0;
+	} 
+
+	switch (aiu->err){
+		
+	case NO_ERR:
+		add = add_to_inbuf(inbuf, arbuffer, inbc, off, aiu->length);
+		off += add;
+		inbc += add;
+		break;
+	case PTS_ERR:
+		break;
+	case FRAME_ERR:
+	case JUMP_ERR: 
+		break;
+	case DUMMY_ERR:
+	  if (aiu->fillframe){
+//		  fprintf(stderr,"1. memcopy 0x%x\n",aiu->fillframe);
+			my_memcpy(inbuf, inbc
+			       , aiu->fillframe + aframesize - length
+				  , length, INSIZE);
+			inbc += length;
+			fakelength += length;
+		} else fprintf(stderr,"no fillframe \n");
+		
+		break;
 	}
+
 	dummy_add(dbuf, pts, aiu->length);
 
 #ifdef OUT_DEBUG
@@ -363,21 +579,53 @@
 	printpts(pts);
 	fprintf(stderr,"\n");
 #endif
-	while (!mx->is_ts && length  < mx->data_size + rest_data){
+	while (length  < mx->data_size + rest_data){
 		if (ring_read(airbuffer, (uint8_t *)aiu, sizeof(index_unit)) > 0){
+			
 			dpts = uptsdiff(aiu->pts +mx->audio_delay, adelay );
 			
 			if (newpts){
 				pts = dpts;
 				newpts=0;
 			}
+			
+			
+			switch(aiu->err)
+			{
+			case NO_ERR:
+				length += aiu->length;
+				add = add_to_inbuf(inbuf, arbuffer, inbc, off, aiu->length);
+				inbc += add;
+				off += add;
+				nframes++;
+				break;
 
-			length+= aiu->length;
+			case PTS_ERR:
+				break;
+			case FRAME_ERR:
+			case JUMP_ERR:
+				droplength += aiu->length;
+ 				off += aiu->length;
+				break;
+			case DUMMY_ERR:
+				length += aframesize;
+				if (aiu->fillframe){
+//					fprintf(stderr,"2. memcopy 0x%x\n",aiu->fillframe);
+					my_memcpy(inbuf, inbc, aiu->fillframe, aframesize, INSIZE);
+					inbc += aframesize;
+					fakelength += aframesize;
+					nframes++;
+				} else fprintf(stderr,"no fillframe \n");
+				
+				break;
+			} 
+
 			if (length < mx->data_size + rest_data)
 				dummy_add(dbuf, dpts, aiu->length);
 			
 			*apts = dpts;
-			nframes++;
+
+
 #ifdef OUT_DEBUG
 			fprintf(stderr,"start: %d  stop: %d (%d)  length %d ", 
 				aiu->start, (aiu->start+aiu->length),
@@ -391,13 +639,63 @@
 		} else if (mx->finish){
 			break;
 		} else if (mx->fill_buffers(mx->priv, mx->finish)< 0) {
-			fprintf(stderr,"error in writeout ext\n");
+			fprintf(stderr,"error in writeout audio\n");
 			exit(1);
 		}
 	}
 
 	nlength = length;
 
+/*
+       if (type == MPEG_AUDIO)
+               written = write_audio_pes( mx->pack_size, mx->apidn, mx->ac3n
+                                          , n, pts, mx->SCR, mx->muxr, 
+                                          outbuf, &nlength, PTS_ONLY,
+                                          arbuffer);
+       else 
+               written = write_ac3_pes( mx->pack_size, mx->apidn, mx->ac3n
+                                        , n, pts, mx->SCR, mx->muxr, 
+                                        outbuf, &nlength, PTS_ONLY,
+                                        nframes, ac3_off,
+                                        arbuffer, aiu->length);
+*/
+ 
+       if (type == MPEG_AUDIO)
+               written = bwrite_audio_pes( mx->pack_size, mx->apidn, mx->ac3n
+                                          , n, pts, mx->SCR, mx->muxr, 
+                                          outbuf, &nlength, PTS_ONLY,
+                                          inbuf, inbc);
+       else 
+               written = bwrite_ac3_pes( mx->pack_size, mx->apidn, mx->ac3n
+                                        , n, pts, mx->SCR, mx->muxr, 
+                                        outbuf, &nlength, PTS_ONLY,
+                                        nframes, ac3_off,
+                                        inbuf, inbc , aiu->length);
+       
+       if (aiu->err == DUMMY_ERR){
+               fakelength -= length-nlength;
+       }
+       length -= nlength;
+       mplx_write(mx, outbuf, written);
+       if (nlength-fakelength+droplength){
+               ring_skip(arbuffer, nlength-fakelength+droplength);
+       }
+
+       dummy_add(dbuf, dpts, aiu->length-length);
+       aiu->length = length;
+       aiu->start = ring_rpos(arbuffer);
+ 
+       if (aiu->length == 0){
+               if (type == MPEG_AUDIO)
+                       g = get_next_audio_unit(mx, aiu, n);
+               else
+                       g = get_next_ac3_unit(mx, aiu, n);
+       }
+ 
+ 
+       *apts = uptsdiff(aiu->pts + mx->audio_delay, adelay);
+
+/*
 	switch (type) {
 	case MPEG_AUDIO:
 		if(mx->is_ts)
@@ -443,8 +741,10 @@
 		aiu->pts = uptsdiff(aiu->pts + ((nlength*aiu->ptsrate)>>8), 0);
 	}
 	*apts = uptsdiff(aiu->pts + mx->audio_delay, adelay);
+*/
 #ifdef OUT_DEBUG
-	if ((int64_t)*apts < 0) fprintf(stderr,"SCHEISS ");
+	//if ((int64_t)*apts < 0) fprintf(stderr,"SCHEISS ");
+	if ((int64_t)*apts < 0) fprintf(stderr,"MIST ");
 	fprintf(stderr,"APTS");
 	printpts(*apts);
 	printpts(aiu->pts);
@@ -452,9 +752,19 @@
 	printpts(adelay);
 	fprintf(stderr,"\n");
 #endif
+	int lc=0;
+	while (aiu->err == JUMP_ERR && lc < 100){
+		lc++;
+		
+		ring_skip(arbuffer, aiu->length);		
+		if (type == MPEG_AUDIO)
+			g = get_next_audio_unit(mx, aiu, n);
+		else
+			g = get_next_ac3_unit(mx, aiu, n);		
+	}
 
 	if (mx->fill_buffers(mx->priv, mx->finish)< 0) {
-		fprintf(stderr,"error in writeout ext\n");
+		fprintf(stderr,"error in writeout audio\n");
 		exit(1);
 	}
 }
@@ -464,17 +774,18 @@
 	uint8_t outbuf[3000];
 	//fprintf(stderr,"writing PADDING pack\n");
 
-	write_padding_pes( mx->pack_size, mx->extcnt, mx->SCR, 
+	write_padding_pes( mx->pack_size, mx->apidn, mx->ac3n, mx->SCR, 
 			   mx->muxr, outbuf);
-	write(mx->fd_out, outbuf, mx->pack_size);
+	mplx_write(mx, outbuf, mx->pack_size);
 }
 
-void check_times( multiplex_t *mx, int *video_ok, int *ext_ok, int *start)
+void check_times( multiplex_t *mx, int *video_ok, int *audio_ok, int *ac3_ok,
+		  int *start)
 {
 	int i;
-	int set_ok = 0;
-
-	memset(ext_ok, 0, N_AUDIO*sizeof(int));
+	
+	memset(audio_ok, 0, N_AUDIO*sizeof(int));
+	memset(ac3_ok, 0, N_AC3*sizeof(int));
 	*video_ok = 0;
 	
 	if (mx->fill_buffers(mx->priv, mx->finish)< 0) {
@@ -489,7 +800,7 @@
 	} else *start = 0;
 	
 	if (mx->VBR) {
-#ifdef OUT_DEBUG1
+#ifdef OUT_DEBUG
 		fprintf(stderr,"EXTRACLOCK: %lli ", mx->extra_clock);
 		printpts(mx->extra_clock);
 		fprintf(stderr,"\n");
@@ -506,17 +817,28 @@
 		if (mx->extra_clock > 0.0) {
 			int64_t temp_scr = mx->extra_clock;
 			
-			for (i=0; i<mx->extcnt; i++){
+			for (i=0; i<mx->apidn; i++){
 				if (ptscmp(mx->SCR + temp_scr + 100*CLOCK_MS, 
-					   mx->ext[i].iu.pts) > 0) {
+					   mx->aiu[i].pts) > 0) {
 					while (ptscmp(mx->SCR + temp_scr 
 						      + 100*CLOCK_MS,
-						      mx->ext[i].iu.pts) > 0) 
+						      mx->aiu[i].pts) > 0) 
 						temp_scr -= mx->SCRinc;
 					temp_scr += mx->SCRinc;
 				}
 			}
 			
+			for (i=0; i<mx->ac3n; i++){
+				if (ptscmp(mx->SCR + temp_scr + 100*CLOCK_MS, 
+					   mx->ac3iu[i].pts) > 0) {
+					while (ptscmp(mx->SCR + temp_scr
+						      + 100*CLOCK_MS,
+						      mx->ac3iu[i].pts) > 0) 
+						temp_scr -= mx->SCRinc;
+					temp_scr += mx->SCRinc;
+				}
+			}
+			
 			if (temp_scr > 0.0) {
 				mx->SCR += temp_scr;
 				mx->extra_clock -= temp_scr;
@@ -524,60 +846,80 @@
 				mx->extra_clock = 0.0;
 		}
 	}
-	
+
+
 	/* clear decoder buffers up to SCR */
 	dummy_delete(&mx->vdbuf, mx->SCR);    
 	
-	for (i=0;i <mx->extcnt; i++)
-		dummy_delete(&mx->ext[i].dbuf, mx->SCR);
+	for (i=0;i <mx->apidn; i++){
+		dummy_delete(&mx->adbuf[i], mx->SCR);
+		clear_audio(mx, MPEG_AUDIO, i);
+	}
+	for (i=0;i <mx->ac3n; i++) {
+		dummy_delete(&mx->ac3dbuf[i], mx->SCR);
+		clear_audio(mx, AC3, i);
+	}
 	
+	
 	if (dummy_space(&mx->vdbuf) > mx->vsize && mx->viu.length > 0 &&
-	    (ptscmp(mx->viu.dts + mx->video_delay, 500*CLOCK_MS +mx->oldSCR)<0)
+	    (ptscmp(mx->viu.dts + mx->video_delay, 1000*CLOCK_MS +mx->oldSCR)<0)
 	    && ring_avail(mx->index_vrbuffer)){
 		*video_ok = 1;
-                set_ok = 1;
 	}
 	
-	for (i = 0; i < mx->extcnt; i++){
-		if (dummy_space(&mx->ext[i].dbuf) > mx->extsize && 
-		    mx->ext[i].iu.length > 0 &&
-		    ptscmp(mx->ext[i].pts, 500*CLOCK_MS + mx->oldSCR) < 0
-		    && ring_avail(&mx->index_extrbuffer[i])){
-			ext_ok[i] = 1;
-                        set_ok = 1;
+	for (i = 0; i < mx->apidn; i++){
+	        //fprintf(stdout, "0 check_times AC3 ptscmp: %d apidn: %d ac3n: %d \n",
+		//		ptscmp(mx->ac3pts[i], 200*CLOCK_MS + mx->oldSCR), mx->apidn, mx->ac3n);
+		if (dummy_space(&mx->adbuf[i]) > mx->asize && 
+		    mx->aiu[i].length > 0 &&
+		    ptscmp(mx->apts[i], 200*CLOCK_MS + mx->oldSCR) < 0
+		    && ring_avail(&mx->index_arbuffer[i])){
+			audio_ok[i] = 1;
 		}
 	}
-#ifdef OUT_DEBUG
-	if (set_ok) {
-		fprintf(stderr, "SCR");
-		printpts(mx->oldSCR);
-		fprintf(stderr, "VDTS");
-		printpts(mx->viu.dts);
-		fprintf(stderr, " (%d)", *video_ok);
-		fprintf(stderr, " EXT");
-		for (i = 0; i < mx->extcnt; i++){
-			fprintf(stderr, "%d:", mx->ext[i].type);
-			printpts(mx->ext[i].pts);
-			fprintf(stderr, " (%d)", ext_ok[i]);
+	for (i = 0; i < mx->ac3n; i++){
+	        //fprintf(stdout, "1 check_times AC3 ptscmp: %d \n", ptscmp(mx->ac3pts[i], 200*CLOCK_MS + mx->oldSCR));
+		if (dummy_space(&mx->ac3dbuf[i]) > mx->asize && 
+		    mx->ac3iu[i].length > 0 &&
+		    ptscmp(mx->ac3pts[i], 200*CLOCK_MS + mx->oldSCR) < 0
+		    && ring_avail(&mx->index_ac3rbuffer[i])){
+			ac3_ok[i] = 1;
 		}
-		fprintf(stderr, "\n");
+		//else
+	        //    fprintf(stdout, "2 check_times AC3 ptscmp: %d \n", ptscmp(mx->ac3pts[i], 200*CLOCK_MS + mx->oldSCR));
 	}
-#endif
 }
-void write_out_packs( multiplex_t *mx, int video_ok, int *ext_ok)
+
+void write_out_packs( multiplex_t *mx, int video_ok, 
+		      int *audio_ok, int *ac3_ok)
 {
 	int i;
 
-	if (video_ok && use_video(mx->viu.dts + mx->video_delay,
-	    mx->ext, ext_ok, mx->extcnt)) {
+	if (video_ok && /* !all_audio_ok(audio_ok, mx->apidn) &&  */
+	    !all_audio_ok(ac3_ok, mx->ac3n)) {
 		writeout_video(mx);  
 	} else { // second case(s): audio ok, video in time
-		i = which_ext(mx->ext, ext_ok, mx->extcnt);
 		int done=0;
-		if(i>=0) {
-			writeout_ext(mx, i);
-			done = 1;
+		for ( i = 0; i < mx->ac3n; i++){
+			if ( ac3_ok[i] && !rest_audio_ok(i,ac3_ok, mx->ac3n)
+			     && !all_audio_ok(audio_ok, mx->apidn)){
+
+				writeout_audio(mx, AC3, i);
+				done = 1;
+				break;
+			}
 		}
+
+		for ( i = 0; i < mx->apidn && !done; i++){
+			if ( audio_ok[i] && !rest_audio_ok(i, audio_ok, 
+							   mx->apidn)){
+				writeout_audio(mx, MPEG_AUDIO, i);
+				done = 1;
+				break;
+			}
+		}
+
+
 		if (!done && !mx->VBR){
 			writeout_padding(mx);
 		}
@@ -589,27 +931,29 @@
 {
 	int start=0;
 	int video_ok = 0;
-	int ext_ok[N_AUDIO];
+	int audio_ok[N_AUDIO];
+	int ac3_ok[N_AC3];
         int n,nn,old,i;
         uint8_t mpeg_end[4] = { 0x00, 0x00, 0x01, 0xB9 };
                                                                                 
-        memset(ext_ok, 0, N_AUDIO*sizeof(int));
+        memset(audio_ok, 0, N_AUDIO*sizeof(int));
+        memset(ac3_ok, 0, N_AC3*sizeof(int));
         mx->finish = 1;
                                                                                 
         old = 0;nn=0;
-        while ((n=buffers_filled(mx)) && nn<1000 ){
+        while ((n=buffers_filled(mx)) && nn<20 ){
                 if (n== old) nn++;
-                else  nn=0;
+                else if (nn) nn--;
                 old = n;
-                check_times( mx, &video_ok, ext_ok, &start);
-                write_out_packs( mx, video_ok, ext_ok);
+                check_times( mx, &video_ok, audio_ok, ac3_ok, &start);
+                write_out_packs( mx, video_ok, audio_ok, ac3_ok);
         }
 
         old = 0;nn=0;
 	while ((n=ring_avail(mx->index_vrbuffer)/sizeof(index_unit))
-	       && nn<1000){
+	       && nn<10){
 		if (n== old) nn++;
-		else nn= 0;
+		else if (nn) nn--;
 		old = n;
 		writeout_video(mx);  
 	}
@@ -617,61 +961,41 @@
 // flush the rest
         mx->finish = 2;
         old = 0;nn=0;
-	for (i = 0; i < mx->extcnt; i++){
-		while ((n=ring_avail(&mx->index_extrbuffer[i])/
-				     sizeof(index_unit)) && nn <100){
+	for (i = 0; i < mx->apidn; i++){
+		while ((n=ring_avail(&mx->index_arbuffer[i])/sizeof(index_unit))
+		       && nn <10){
 			if (n== old) nn++;
-			else nn = 0;
+			else if (nn) nn--;
 			old = n;
-			writeout_ext(mx, i);
+			writeout_audio(mx, MPEG_AUDIO, i);
 		}
 	}
 	
+        old = 0;nn=0;
+	for (i = 0; i < mx->ac3n; i++){
+		while ((n=ring_avail(&mx->index_ac3rbuffer[i])
+			/sizeof(index_unit))
+			&& nn<10){
+			if (n== old) nn++;
+			else if (nn) nn--;
+			old = n;
+			writeout_audio(mx, AC3, i);
+		}
+	}
+                        
+                          
 	if (mx->otype == REPLEX_MPEG2)
-		write(mx->fd_out, mpeg_end,4);
-
-	dummy_destroy(&mx->vdbuf);
-	for (i=0; i<mx->extcnt;i++)
-		dummy_destroy(&mx->ext[i].dbuf);
+		mplx_write(mx, mpeg_end,4);
 }
 
-static int get_ts_video_overhead(int pktsize, sequence_t *seq)
-{
-	uint32_t framesize;
-	uint32_t numpkt;
-	int pktdata = pktsize - TS_HEADER_MIN;
-	framesize = seq->bit_rate * 50 / seq->frame_rate; //avg bytes/frame
-	numpkt = (framesize + PES_H_MIN + 10 + pktdata -1) / pktdata;
-	return pktsize- ((pktsize * numpkt) - framesize + numpkt - 1) / numpkt;
-}
 
-static int get_ts_ext_overhead(int pktsize, audio_frame_t *extframe,
-				extdata_t *ext, int cnt)
-{
-	int i, max = 0;
-	int pktdata = pktsize - TS_HEADER_MIN;
-	for (i = 0; i < cnt; i++) {
-		int size, numpkt, overhead;
-		// 1/53 is approx 0.15 * 1/8 which allows us to calculate the
-		// # of packets in .15 seconds (which is the number of packets
-		// per PES.
-		ext[i].frmperpkt = extframe[i].bit_rate / 53 /
-					extframe[i].framesize;
-		size = extframe[i].framesize * ext[i].frmperpkt;
-		numpkt = (size + pktdata - 1) / pktdata;
-		overhead = (pktsize * numpkt - size + numpkt - 1) / numpkt;
-		if(overhead > max)
-			max = overhead;
-	}
-	return pktsize - max;
-}
-
-void init_multiplex( multiplex_t *mx, sequence_t *seq_head,
-                     audio_frame_t *extframe, int *exttype, int *exttypcnt,
+void init_multiplex( multiplex_t *mx, sequence_t *seq_head, audio_frame_t *aframe,
+		     audio_frame_t *ac3frame, int apidn, int ac3n, 
 		     uint64_t video_delay, uint64_t audio_delay, int fd,
 		     int (*fill_buffers)(void *p, int f),
 		     ringbuffer *vrbuffer, ringbuffer *index_vrbuffer,	
-		     ringbuffer *extrbuffer, ringbuffer *index_extrbuffer,
+		     ringbuffer *arbuffer, ringbuffer *index_arbuffer,
+		     ringbuffer *ac3rbuffer, ringbuffer *index_ac3rbuffer,
 		     int otype)
 {
 	int i;
@@ -682,6 +1006,10 @@
 	mx->audio_delay = audio_delay;
 	mx->fd_out = fd;
 	mx->otype = otype;
+	mx->total_written = 0;
+	mx->zero_write_count = 0;
+	mx->max_write = 0;
+	mx->max_reached = 0;
 
 	switch(mx->otype){
 
@@ -698,7 +1026,7 @@
 		mx->reset_clocks = 0;
 		mx->write_end_codes = 0;
 		mx->set_broken_link = 0;
-		mx->is_ts = 0;
+		//		mx->max_write = 1024*1024*1024; // 1GB max VOB length
 		break;
 
 
@@ -715,7 +1043,6 @@
 		mx->reset_clocks = 1;
 		mx->write_end_codes = 1;
 		mx->set_broken_link = 1;
-		mx->is_ts = 0;
 		break;
 
 	case REPLEX_HDTV:
@@ -731,84 +1058,43 @@
 		mx->reset_clocks = 1;
 		mx->write_end_codes = 1;
 		mx->set_broken_link = 1;
-		mx->is_ts = 0;
 		break;
+	}
 
-	case REPLEX_TS_SD:
-		mx->video_delay += 180*CLOCK_MS;
-		mx->audio_delay += 180*CLOCK_MS;
-		mx->pack_size = 188;
-		mx->audio_buffer_size = 4*1024;
-		mx->video_buffer_size = 232*1024;
-		mx->mux_rate = 1260000;
-		mx->navpack = 0;
-		mx->frame_timestamps = TIME_ALWAYS;
-		mx->VBR = 1;
-		mx->reset_clocks = 0;
-		mx->write_end_codes = 0;
-		mx->set_broken_link = 0;
-		mx->is_ts = 1;
-		break;
+	mx->apidn = apidn;
+	mx->ac3n = ac3n;
 
-	case REPLEX_TS_HD:
-		mx->video_delay += 180*CLOCK_MS;
-		mx->audio_delay += 180*CLOCK_MS;
-		mx->pack_size = 188;
-		mx->audio_buffer_size = 4*1024;
-		mx->video_buffer_size = 4*224*1024;
-		mx->mux_rate = 0;
-		mx->navpack = 0;
-		mx->frame_timestamps = TIME_ALWAYS;
-		mx->VBR = 1;
-		mx->reset_clocks = 0;
-		mx->write_end_codes = 0;
-		mx->set_broken_link = 0;
-		mx->is_ts = 1;
-		break;
-	}
 
-	for (mx->extcnt = 0, data_rate = 0, i = 0;
-			 i < N_AUDIO && exttype[i]; i++){
-		if (exttype[i] >= MAX_TYPES) {
-			fprintf(stderr, "Found illegal stream type %d\n",
-				exttype[i]);
-			exit(1);
-		}
-		mx->ext[i].type = exttype[i];
-		mx->ext[i].pts_off = 0;
-		mx->ext[i].frmperpkt = 1;
-		mx->ext[i].strmnum = exttypcnt[i];
-		strncpy(mx->ext[i].language, extframe[i].language, 4);
-		dummy_init(&mx->ext[i].dbuf, mx->audio_buffer_size);
-		data_rate += extframe[i].bit_rate;
-		mx->extcnt++;
-	}
-
 	mx->vrbuffer = vrbuffer;
 	mx->index_vrbuffer = index_vrbuffer;
-	mx->extrbuffer = extrbuffer;
-	mx->index_extrbuffer = index_extrbuffer;
+	mx->arbuffer = arbuffer;
+	mx->index_arbuffer = index_arbuffer;
+	mx->ac3rbuffer = ac3rbuffer;
+	mx->index_ac3rbuffer = index_ac3rbuffer;
 
 	dummy_init(&mx->vdbuf, mx->video_buffer_size);
+	for (i=0; i<mx->apidn;i++){
+		mx->apts_off[i] = 0;
+		dummy_init(&mx->adbuf[i],mx->audio_buffer_size);
+	}
+	for (i=0; i<mx->ac3n;i++){
+		mx->ac3pts_off[i] = 0;
+		dummy_init(&mx->ac3dbuf[i], mx->audio_buffer_size);
+	}
 
-	//NOTE: vpkt_hdr/extpkt_hdr are worst-case for PS streams, but
-	//best-guess for TS streams
-	if(mx->is_ts) {
-		//Use best guess for TS streams
-		mx->data_size = get_ts_video_overhead(mx->pack_size, seq_head);
-		mx->extsize = get_ts_ext_overhead(mx->pack_size, extframe,
-				mx->ext, mx->extcnt);
-		
-	} else {
-		//Use worst case for PS streams
-		mx->data_size = mx->pack_size - PES_H_MIN - PS_HEADER_L1 - 10;
-		mx->extsize = mx->data_size + 5; //one less DTS
-	}
+	mx->data_size = mx->pack_size - PES_H_MIN -10; 
 	mx->vsize = mx->data_size;
+	mx->asize = mx->data_size+5; // one less DTS
 	
-	data_rate += seq_head->bit_rate *400;
+	data_rate = seq_head->bit_rate *400;
+	for ( i = 0; i < mx->apidn; i++)
+		data_rate += aframe[i].bit_rate;
+	for ( i = 0; i < mx->ac3n; i++)
+		data_rate += ac3frame[i].bit_rate;
 
-	mx->muxr = ((uint64_t)data_rate / 8 * mx->pack_size) / mx->data_size; 
+	
+	mx->muxr = ((uint64_t)data_rate / 8 * mx->pack_size) / mx->data_size;
+//        mx->muxr = (data_rate / 8 * mx->pack_size) / mx->data_size; 
                                      // muxrate of payload in Byte/s
 
 	if (mx->mux_rate) {
@@ -825,35 +1111,31 @@
 
 void setup_multiplex(multiplex_t *mx)
 {
+	int packlen;
 	int i;
 
  	get_next_video_unit(mx, &mx->viu);
-	for (i=0; i < mx->extcnt; i++)
-        {
-		get_next_ext_unit(mx, &mx->ext[i].iu, i);
-		if (mx->ext[i].type == MPEG_AUDIO || mx->ext[i].type == AC3)
-			mx->ext[i].pts = uptsdiff(
-					mx->ext[i].iu.pts + mx->audio_delay, 
-					mx->ext[i].pts_off);
-		else
-			mx->ext[i].pts = uptsdiff(
-					mx->ext[i].iu.pts, mx->ext[i].pts_off);
+	for (i=0; i < mx->apidn; i++){
+		get_next_audio_unit(mx, &mx->aiu[i], i);
+		mx->apts[i] = uptsdiff(mx->aiu[i].pts +mx->audio_delay, 
+				       mx->apts_off[i]); 
 	}
+	for (i=0; i < mx->ac3n; i++){
+		get_next_ac3_unit(mx, &mx->ac3iu[i], i);
+		mx->ac3pts[i] = uptsdiff(mx->ac3iu[i].pts +mx->audio_delay, 
+					 mx->ac3pts_off[i]); 
+	}
 
+	packlen = mx->pack_size;
+
 	mx->SCR = 0;
 
 	// write first VOBU header
-	if (mx->is_ts) {
+	if (mx->navpack){
 		uint8_t outbuf[2048];
-		write_ts_patpmt(mx->ext, mx->extcnt, 1, outbuf);
-		write(mx->fd_out, outbuf, mx->pack_size*2);
-		ptsinc(&mx->SCR, mx->SCRinc*2);
-		mx->startup = 1;
-	} else if (mx->navpack){
-		uint8_t outbuf[2048];
-		write_nav_pack(mx->pack_size, mx->extcnt, 
+		write_nav_pack(mx->pack_size, mx->apidn, mx->ac3n, 
 			       mx->SCR, mx->muxr, outbuf);
-		write(mx->fd_out, outbuf, mx->pack_size);
+		mplx_write(mx, outbuf, mx->pack_size);
 		ptsinc(&mx->SCR, mx->SCRinc);
 		mx->startup = 1;
 	} else mx->startup = 0;
Index: replex/TODO
===================================================================
--- replex/TODO	(revision 18755)
+++ replex/TODO	(working copy)
@@ -1,12 +1,8 @@
-- check for dvdauthor audio PTS errors
+- fix/replace broken frames
 
-- check/fix/replace broken frames
-
 - split DVD output Files
 
 - use more than one input File
 
 - add cutting option
 
-- better handling of broken streams
-
Index: replex/avi.h
===================================================================
--- replex/avi.h	(revision 18755)
+++ replex/avi.h	(working copy)
@@ -2,7 +2,8 @@
  * avi.h
  *        
  *
- * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
+ * Copyright (C) 2003 - 2006
+ *                    Marcus Metzler <mocm@metzlerbros.de>
  *                    Metzler Brothers Systementwicklung GbR
  *
  * This program is free software; you can redistribute it and/or
Index: replex/ts.c
===================================================================
--- replex/ts.c	(revision 18755)
+++ replex/ts.c	(working copy)
@@ -2,7 +2,8 @@
  * ts.c: MPEG TS functions for replex
  *        
  *
- * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
+ * Copyright (C) 2003 - 2006
+ *                    Marcus Metzler <mocm@metzlerbros.de>
  *                    Metzler Brothers Systementwicklung GbR
  *
  * This program is free software; you can redistribute it and/or
@@ -24,20 +25,11 @@
  *
  */
 
-#include <stdlib.h>
 #include <stdint.h>
 #include <string.h>
 #include <stdio.h>
 
-#ifdef USING_MINGW
-#include <winsock2.h>
-#else
-#include <netinet/in.h>
-#endif
-
 #include "ts.h"
-#include "element.h"
-#include "pes.h"
 
 uint16_t get_pid(uint8_t *pid)
 {
@@ -49,6 +41,42 @@
 	return pp;
 }
 
+int write_ts_header(uint16_t pid, uint8_t *counter, int pes_start, 
+		    uint8_t *buf, uint8_t length)
+{
+	int i;
+	int c = 0;
+	int fill;
+	uint8_t tshead[4] = { 0x47, 0x00, 0x00, 0x10}; 
+        
+
+	fill = TS_SIZE-4-length;
+        if (pes_start) tshead[1] = 0x40;
+	if (fill) tshead[3] = 0x30;
+        tshead[1] |= (uint8_t)((pid & 0x1F00) >> 8);
+        tshead[2] |= (uint8_t)(pid & 0x00FF);
+        tshead[3] |= ((*counter)++ & 0x0F) ;
+        memcpy(buf,tshead,4);
+	c+=4;
+
+
+	if (fill){
+		buf[4] = fill-1;
+		c++;
+		if (fill >1){
+			buf[5] = 0x00;
+			c++;
+		}
+		for ( i = 6; i < fill+4; i++){
+			buf[i] = 0xFF;
+			c++;
+		}
+	}
+
+        return c;
+}
+
+
 int find_pids_pos(uint16_t *vpid, uint16_t *apid, uint16_t *ac3pid,uint8_t *buf, int len, int *vpos, int *apos, int *ac3pos)
 {
 	int c=0;
@@ -123,327 +151,3 @@
 {
 	return find_pids_pos(vpid, apid, ac3pid, buf, len, NULL, NULL, NULL);
 }
-
-//taken and adapted from libdtv, (c) Rolf Hakenes
-// CRC32 lookup table for polynomial 0x04c11db7
-static unsigned int crc_table[256] = {
-   0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
-   0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
-   0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
-   0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
-   0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
-   0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
-   0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
-   0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
-   0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
-   0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
-   0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
-   0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
-   0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
-   0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
-   0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
-   0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
-   0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
-   0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
-   0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
-   0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
-   0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
-   0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
-   0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
-   0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
-   0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
-   0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
-   0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
-   0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
-   0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
-   0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
-   0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
-   0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
-   0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
-   0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
-   0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
-   0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
-   0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
-   0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
-   0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
-   0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
-   0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
-   0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
-   0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4};
-
-unsigned int crc32_04c11db7 (const unsigned char *d, int len, unsigned int crc)
-{
-   register int i;
-   const unsigned char *u=(unsigned char*)d; // Saves '& 0xff'
-
-   for (i=0; i<len; i++)
-      crc = (crc << 8) ^ crc_table[((crc >> 24) ^ *u++)];
-
-   return crc;
-}
-
-static int write_ts_header(int pid, int payload_start, int count,
-		    int64_t SCR, uint8_t *obuf, int stuff)
-{
-	int c = 0;
-	uint8_t *scr;
-	uint32_t lscr;
-	uint16_t scr_ext = 0;
-
-	obuf[c++] = 0x47;
-	obuf[c++] = (payload_start ? 0x40 : 0x00) | ((pid >> 8) & 0x1f);
-	obuf[c++] = pid & 0xff;
-	obuf[c++] = ((SCR >= 0 || stuff) ? 0x30 : 0x10) | count;
-	if (SCR >= 0|| stuff) {
-		if (stuff)
-			stuff--;
-		int size = stuff;
-		unsigned char flags = 0;
-		if(SCR >= 0) {
-			if(size < 7)
-				size = 7;
-			flags |= 0x10;
-		}
-		obuf[c++] = size;
-		if(size) {
-			obuf[c++] = flags;
-			size--;
-		}
-		if(SCR >= 0) {
-			uint8_t bit;
-			lscr = (uint32_t) ((SCR/300ULL) & 0xFFFFFFFFULL);
-			bit = (lscr & 0x01) << 7;
-			lscr = htonl(lscr >> 1);
-			scr = (uint8_t *) &lscr;
-			scr_ext = (uint16_t) ((SCR%300ULL) & 0x1FFULL);
-			obuf[c++] = scr[0];
-			obuf[c++] = scr[1];
-			obuf[c++] = scr[2];
-			obuf[c++] = scr[3];
-			obuf[c++] = bit | 0x7e | (scr_ext >> 8);
-			obuf[c++] = scr_ext & 0xff;
-			size -= 6;
-		}
-		while(size-- > 0)
-			obuf[c++] = 0xff;
-	}
-	return c;
-}
-
-int write_video_ts(uint64_t vpts, uint64_t vdts, uint64_t SCR, uint8_t *buf,
-		   int *vlength, uint8_t ptsdts, ringbuffer *vrbuffer)
-{
-//Unlike program streams, we only do one PES per frame
-	static int count = 0;
-	int add;
-	int pos = 0;
-	int p   = 0;
-	int stuff = 0;
-	int length = *vlength;
-
-	if (! length) return 0;
-	p = 4;
-	if ( ptsdts ) {
-		p += PES_H_MIN + 8;
-
-		if ( ptsdts == PTS_ONLY) {
-			p += 5;
-		} else if (ptsdts == PTS_DTS){
-			p += 10;
-		}
-	}
-	if ( length+p >= TS_SIZE){
-		length = TS_SIZE;
-	} else {
-		stuff = TS_SIZE - length - p;
-		length = TS_SIZE;
-	}
-	if(ptsdts) {
-//printf("SCR: %f PTS: %f DTS: %f\n", SCR/27000000.0, vpts / 27000000.0, vdts / 27000000.0);
-		pos = write_ts_header(TS_VIDPID, 1, count, SCR, buf, stuff);
-		// always use length == 0 for video streams
-		pos += write_pes_header( 0xE0, 6, vpts, vdts, buf+pos, 
-					 0, ptsdts);
-	} else {
-		pos = write_ts_header(TS_VIDPID, 0, count, -1, buf, stuff);
-	}
-	count = (count+1) & 0x0f;
-
-	if (length-pos > *vlength){
-		fprintf(stderr,"WHAT THE HELL  %d > %d\n", length-pos,
-			*vlength);
-	}
-
-	add = ring_read( vrbuffer, buf+pos, length-pos);
-	*vlength = add;
-	if (add < 0) return -1;
-	pos += add;
-
-	return pos;
-}
-
-int write_audio_ts(int n, uint64_t pts, uint8_t *buf, int *alength,
-		   uint8_t ptsdts, ringbuffer *arbuffer)
-{
-	static int count[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-	                        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-	int add;
-	int pos = 0;
-	int p   = 0;
-	int stuff = 0;
-	int length = *alength;
-
-	if (!length) return 0;
-	p = 4;
-
-	if (ptsdts == PTS_ONLY){
-		p += PES_H_MIN + 5;
-	}
-
-	if ( length+p >= TS_SIZE){
-		length = TS_SIZE;
-	} else {
-		stuff = TS_SIZE - length - p;
-		length = TS_SIZE;
-	}
-	if(ptsdts) {
-		pos = write_ts_header(TS_MP2PID+n, 1, count[n], -1, buf, stuff);
-		pos += write_pes_header( 0xC0+n, *alength + PES_H_MIN + 5, pts,
-					 0, buf+pos, 0, ptsdts);
-	} else {
-		pos = write_ts_header(TS_MP2PID+n, 0, count[n], -1, buf, stuff);
-	}
-	count[n] = (count[n]+1) & 0x0f;
-	add = ring_read( arbuffer, buf+pos, length-pos);
-	*alength = add;
-	if (add < 0) return -1;
-	pos += add;
-
-	if (pos != TS_SIZE) {
-		fprintf(stderr,"apos: %d\n",pos);
-		exit(1);
-	}
-
-	return pos;
-}
-
-int write_ac3_ts(int n, uint64_t pts, uint8_t *buf, int *alength,
-	 uint8_t ptsdts, int nframes, ringbuffer *ac3rbuffer)
-{
-	static int count[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-	                        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-	int add;
-	int pos = 0;
-	int p   = 0;
-	int stuff = 0;
-	int length = *alength;
-
-	if (!length) return 0;
-	p = 4;
-
-	if (ptsdts == PTS_ONLY){
-		p += PES_H_MIN + 5 + 4; //PES header + PTS + PS1
-	}
-
-	if ( length+p >= TS_SIZE){
-		length = TS_SIZE;
-	} else {
-		stuff = TS_SIZE - length - p;
-		length = TS_SIZE;
-	}
-	if(ptsdts) {
-		pos = write_ts_header(TS_AC3PID+n, 1, count[n], -1, buf, stuff);
-		pos += write_pes_header( PRIVATE_STREAM1,
-					 *alength + 4 + PES_H_MIN + 5,
-					 pts, 0, buf+pos, 0, ptsdts);
-		buf[pos] = 0x80 + n;
-		buf[pos+1] = nframes;
-		buf[pos+2] = 0x00;
-		buf[pos+3] = 0x00;
-		pos += 4;
-	} else {
-		pos = write_ts_header(TS_AC3PID+n, 0, count[n], -1, buf, stuff);
-	}
-	count[n] = (count[n]+1) & 0x0f;
-
-	add = ring_read( ac3rbuffer, buf+pos, length-pos);
-	*alength = add;
-	if (add < 0) return -1;
-	pos += add;
-
-	if (pos != TS_SIZE) {
-		fprintf(stderr,"apos: %d\n",pos);
-		exit(1);
-	}
-
-	return pos;
-}
-
-void write_ts_patpmt(extdata_t *ext, int extcnt, uint8_t prog_num, uint8_t *buf)
-{
-#define PMTPID 0x20
-	static int count = 0;
-	int pos, i, pmtpos = 13;
-	//PMT Program number = 1
-	//PMT PID = 0x20
-	uint8_t pat[17] = {0x00, 0x00, 0xb0, 0x0d, 0xfe, 0xef, 0xc1, 0x00, 0x00,
-	                   0x00, 0x00, 0xe0, PMTPID, 0x00, 0x00, 0x00, 0x00};
-	uint8_t pmt[184] ={0x00, 0x02, 0xb0, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00,
-	                   0x00, 0x00, 0xf0, 0x00};
-
-	//PAT
-	pat[10] = prog_num;
-	pos = write_ts_header(0x00, 1, count, -1, buf, 0);
-	*(uint32_t *)(pat+13)= htonl(crc32_04c11db7(pat+1, 12, 0xffffffff));
-	memcpy(buf+pos, pat, 17);
-	pos += 17;
-	memset(buf+pos, 0xff, TS_SIZE - pos);
-	pos = TS_SIZE;
-	//PMT
-	pos += write_ts_header(PMTPID, 1, count, -1, buf+pos, 0);
-	for(i = 0; i <= extcnt; i++) {
-		uint8_t type;
-		uint32_t pid;
-		int n =  ext[i-1].strmnum;
-		if(i == 0) {
-			type = 0x02;
-			pid = TS_VIDPID;
-		} else if(ext[i-1].type == MPEG_AUDIO) {
-			type = 0x04;
-			pid = TS_MP2PID + n;
-		} else if(ext[i-1].type == AC3) {
-			type = 0x81;
-			pid = TS_AC3PID + n;
-		} else {
-			type = 0xff;
-			pid = 0x1fff;
-		}
-		pmt[pmtpos++] = type;
-		pmt[pmtpos++] = 0xe0 | (0xff & (pid >> 8));
-		pmt[pmtpos++] = 0xff & pid;
-		pmt[pmtpos++] = 0xf0;
-		if(strlen(ext[i-1].language) == 3) {
-			pmt[pmtpos++] = 0x06;
-			pmt[pmtpos++] = 0x0a;
-			pmt[pmtpos++] = 0x04;
-			pmt[pmtpos++] = ext[i-1].language[0];
-			pmt[pmtpos++] = ext[i-1].language[1];
-			pmt[pmtpos++] = ext[i-1].language[2];
-			pmt[pmtpos++] = 0x00;
-		} else {
-			pmt[pmtpos++] = 0x00;
-		}
-	}
-	pmt[3] = pmtpos + 4/*crc*/ - 3 - 1/*pointer_field*/;
-	pmt[5] = prog_num;
-	pmt[9] = 0xf0 | (0xff & (TS_VIDPID >> 8));
-	pmt[10] = 0xff & TS_VIDPID;
-	*(uint32_t *)&pmt[pmtpos] = htonl(crc32_04c11db7(&pmt[1], pmtpos -1,
-	                                  0xffffffff));
-	pmtpos+=4;
-	memcpy(buf+pos, pmt, pmtpos);
-	pos += pmtpos;
-	memset(buf+pos, 0xff, 2*TS_SIZE - pos);
-	pos = 2*TS_SIZE;
-	count = (count+1) & 0x0f;
-}
Index: replex/pes.c
===================================================================
--- replex/pes.c	(revision 18755)
+++ replex/pes.c	(working copy)
@@ -2,8 +2,10 @@
  * pes.c: MPEG PES functions for replex
  *        
  *
- * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
+ * Copyright (C) 2003 - 2006
+ *                    Marcus Metzler <mocm@metzlerbros.de>
  *                    Metzler Brothers Systementwicklung GbR
+ *           (C) 2006 Reel Multimedia
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -26,15 +28,13 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <netinet/in.h>
 #include <string.h>
 
-#ifdef USING_MINGW
-#include <winsock2.h>
-#else
-#include <netinet/in.h>
-#endif
+#include "pes.h"
 
-#include "pes.h"
+//#define PES_DEBUG
+
 void printpts(int64_t pts)
 {
 	if (pts < 0){
@@ -43,11 +43,11 @@
 	}
 	pts = pts/300;
 	pts &= (MAX_PTS-1);
-	fprintf(stderr,"%2d:%02d:%02d.%04d ",
+	fprintf(stderr,"%2d:%02d:%02d.%03d ",
 		(unsigned int)(pts/90000.)/3600,
 		((unsigned int)(pts/90000.)%3600)/60,
 		((unsigned int)(pts/90000.)%3600)%60,
-		(((unsigned int)(pts/9.)%36000000)%600000)%10000
+		(((unsigned int)(pts/90.)%3600000)%60000)%1000
 		);
 }
 
@@ -159,233 +159,231 @@
 void get_pes (pes_in_t *p, uint8_t *buf, int count, void (*func)(pes_in_t *p))
 {
 
-	int l;
-	unsigned short *pl;
-        int done;
+	int l=0;
+	unsigned short *pl=NULL;
+	int c=0;
 
 	uint8_t headr[3] = { 0x00, 0x00, 0x01} ;
-	do {
-		int c=0;
-		done = 1;
-		while (c < count && (!p->mpeg ||
-				     (p->mpeg == 2 && p->found < 9))
-	               &&  (p->found < 5 || !p->done)){
-			switch ( p->found ){
-			case 0:
-			case 1:
-				if (buf[c] == 0x00) p->found++;
-				else p->found = 0;
+	while (c < count && (!p->mpeg ||
+			     (p->mpeg == 2 && p->found < 9))
+	       &&  (p->found < 5 || !p->done)){
+		switch ( p->found ){
+		case 0:
+		case 1:
+			if (buf[c] == 0x00) p->found++;
+			else p->found = 0;
+			c++;
+			break;
+		case 2:
+			if (buf[c] == 0x01) p->found++;
+			else if (buf[c] == 0){
+				p->found = 2;
+			} else p->found = 0;
+			c++;
+			break;
+		case 3:
+			p->cid = 0;
+			switch (buf[c]){
+			case PROG_STREAM_MAP:
+			case PRIVATE_STREAM2:
+			case PROG_STREAM_DIR:
+			case ECM_STREAM     :
+			case EMM_STREAM     :
+			case PADDING_STREAM :
+			case DSM_CC_STREAM  :
+			case ISO13522_STREAM:
+				p->done = 1;
+			case PRIVATE_STREAM1:
+			case VIDEO_STREAM_S ... VIDEO_STREAM_E:
+			case AUDIO_STREAM_S ... AUDIO_STREAM_E:
+				p->found++;
+				p->cid = buf[c];
 				c++;
 				break;
-			case 2:
-				if (buf[c] == 0x01) p->found++;
-				else if (buf[c] == 0){
-					p->found = 2;
-				} else p->found = 0;
+			default:
+			case PACK_START:
+			case SYS_START:
+				p->found = 0;
 				c++;
 				break;
-			case 3:
-				p->cid = 0;
-				switch (buf[c]){
-				case PROG_STREAM_MAP:
-				case PRIVATE_STREAM2:
-				case PROG_STREAM_DIR:
-				case ECM_STREAM     :
-				case EMM_STREAM     :
-				case PADDING_STREAM :
-				case DSM_CC_STREAM  :
-				case ISO13522_STREAM:
-					p->done = 1;
-				case PRIVATE_STREAM1:
-				case VIDEO_STREAM_S ... VIDEO_STREAM_E:
-				case AUDIO_STREAM_S ... AUDIO_STREAM_E:
-					p->found++;
-					p->cid = buf[c];
-					c++;
-					break;
-				default:
-				case PACK_START:
-				case SYS_START:
-					p->found = 0;
-					c++;
-					break;
-				}
-				break;
+			}
+			break;
 			
 
-			case 4:
-				if (count-c > 1){
-					pl = (unsigned short *) (buf+c);
-					p->plength =  ntohs(*pl);
-					p->plen[0] = buf[c];
-					c++;
-					p->plen[1] = buf[c];
-					c++;
-					p->found+=2;
-				} else {
-					p->plen[0] = buf[c];
-					p->found++;
-					return;
-				}
-				break;
-			case 5:
+		case 4:
+			if (count-c > 1){
+				pl = (unsigned short *) (buf+c);
+				p->plength =  ntohs(*pl);
+				p->plen[0] = buf[c];
+				c++;
 				p->plen[1] = buf[c];
 				c++;
-				pl = (unsigned short *) p->plen;
-				p->plength = ntohs(*pl);
+				p->found+=2;
+			} else {
+				p->plen[0] = buf[c];
 				p->found++;
-				break;
+				return;
+			}
+			break;
+		case 5:
+			p->plen[1] = buf[c];
+			c++;
+			pl = (unsigned short *) p->plen;
+			p->plength = ntohs(*pl);
+			p->found++;
+			break;
 
 
-			case 6:
-				if (!p->done){
-					p->flag1 = buf[c];
-					c++;
-					p->found++;
-					if ( (p->flag1 & 0xC0) == 0x80 ) p->mpeg = 2;
-					else {
-						fprintf(stderr, 
-							"Error: THIS IS AN MPEG1 FILE\n");
-						exit(1);
-					}
+		case 6:
+			if (!p->done){
+				p->flag1 = buf[c];
+				c++;
+				p->found++;
+				if ( (p->flag1 & 0xC0) == 0x80 ) p->mpeg = 2;
+				else {
+					fprintf(stderr, "Error in PES Header 0x%2x\n",p->cid);
+					p->found = 0;
 				}
-				break;
+			}
+			break;
 
-			case 7:
-				if ( !p->done && p->mpeg == 2){
-					p->flag2 = buf[c];
-					c++;
-					p->found++;
-				}	
-				break;
+		case 7:
+			if ( !p->done && p->mpeg == 2){
+				p->flag2 = buf[c];
+				c++;
+				p->found++;
+			}	
+			break;
 
-			case 8:
-				if ( !p->done && p->mpeg == 2){
-					p->hlength = buf[c];
-					c++;
-					p->found++;
-				}
-				break;
+		case 8:
+			if ( !p->done && p->mpeg == 2){
+				p->hlength = buf[c];
+				c++;
+				p->found++;
+			}
+			break;
 			
-			default:
+		default:
 
-				break;
-			}
+			break;
 		}
+		if(p->plength && p->found == 9 && p->found > p->plength+6){
+			fprintf(stderr, "Error in PES Header 0x%2x\n",p->cid);
+			p->found = 0;
+		}
+	}
 
-		if (!p->plength) p->plength = MMAX_PLENGTH-6;
+	if (!p->plength) p->plength = MMAX_PLENGTH-6;
 
 
-		if ( p->done || (p->mpeg == 2 && p->found >= 9) ){
-			switch (p->cid){
+	if ( p->done || (p->mpeg == 2 && p->found >= 9) ){
+		switch (p->cid){
 			
-			case AUDIO_STREAM_S ... AUDIO_STREAM_E:			
-			case VIDEO_STREAM_S ... VIDEO_STREAM_E:
-			case PRIVATE_STREAM1:
+		case AUDIO_STREAM_S ... AUDIO_STREAM_E:			
+		case VIDEO_STREAM_S ... VIDEO_STREAM_E:
+		case PRIVATE_STREAM1:
 
+			if (p->withbuf){
+				memcpy(p->buf, headr, 3);
+				p->buf[3] = p->cid;
+				memcpy(p->buf+4,p->plen,2);
+			} else {
+				memcpy(p->hbuf, headr, 3);
+				p->hbuf[3] = p->cid;
+				memcpy(p->hbuf+4,p->plen,2);
+			}
+
+			if (p->found == 9){
 				if (p->withbuf){
-					memcpy(p->buf, headr, 3);
-					p->buf[3] = p->cid;
-					memcpy(p->buf+4,p->plen,2);
+					p->buf[6] = p->flag1;
+					p->buf[7] = p->flag2;
+					p->buf[8] = p->hlength;
 				} else {
-					memcpy(p->hbuf, headr, 3);
-					p->hbuf[3] = p->cid;
-					memcpy(p->hbuf+4,p->plen,2);
+					p->hbuf[6] = p->flag1;
+					p->hbuf[7] = p->flag2;
+					p->hbuf[8] = p->hlength;
 				}
+			}
 
-				if (p->found == 9){
-					if (p->withbuf){
-						p->buf[6] = p->flag1;
-						p->buf[7] = p->flag2;
-						p->buf[8] = p->hlength;
-					} else {
-						p->hbuf[6] = p->flag1;
-						p->hbuf[7] = p->flag2;
-						p->hbuf[8] = p->hlength;
-					}
+			if ( (p->flag2 & PTS_ONLY) &&  p->found < 14){
+				while (c < count && p->found < 14){
+					p->pts[p->found-9] = buf[c];
+					if (p->withbuf)
+						p->buf[p->found] = buf[c];
+					else 
+						p->hbuf[p->found] = buf[c];
+					c++;
+					p->found++;
 				}
+				if (c == count) return;
+			}
 
-				if ( (p->flag2 & PTS_ONLY) &&  p->found < 14){
-					while (c < count && p->found < 14){
-						p->pts[p->found-9] = buf[c];
-						if (p->withbuf)
-							p->buf[p->found] = buf[c];
-						else 
-							p->hbuf[p->found] = buf[c];
-						c++;
-						p->found++;
-					}
-					if (c == count) return;
+			if (((p->flag2 & PTS_DTS) == 0xC0) && p->found < 19){
+				while (c < count && p->found < 19){
+					p->dts[p->found-14] = buf[c];
+					if (p->withbuf)
+						p->buf[p->found] = buf[c];
+					else 
+						p->hbuf[p->found] = buf[c];
+					c++;
+					p->found++;
 				}
+				if (c == count) return;
+			}
 
-				if (((p->flag2 & PTS_DTS) == 0xC0) && p->found < 19){
-					while (c < count && p->found < 19){
-						p->dts[p->found-14] = buf[c];
-						if (p->withbuf)
-							p->buf[p->found] = buf[c];
-						else 
-							p->hbuf[p->found] = buf[c];
-						c++;
-						p->found++;
-					}
-					if (c == count) return;
-				}
 
-
-				while (c < count && p->found < p->plength+6){
-					l = count -c;
-					if (l+p->found > p->plength+6)
-						l = p->plength+6-p->found;
-					if (p->withbuf)
-						memcpy(p->buf+p->found, buf+c, l);
-					else {
-						if ( p->found < 
-                                                     (unsigned int)p->hlength+9 ){
-							int rest = p->hlength+9-p->found;
-							memcpy(p->hbuf+p->found, buf+c, rest);
-							if (ring_write(p->rbuf, buf+c+rest, 
-								       l-rest) <0){
-								exit(1);
-							}
-						} else {
-							if (ring_write(p->rbuf, buf+c, l)<0){
-								fprintf(stderr,
-									"ring buffer overflow %d\n"
-									,p->rbuf->size);
-								exit(1);
-							}
+			while (c < count && p->found < p->plength+6){
+				l = count -c;
+				if (l+p->found > p->plength+6)
+					l = p->plength+6-p->found;
+				if (p->withbuf)
+					memcpy(p->buf+p->found, buf+c, l);
+				else {
+					if ( p->found < p->hlength+9 ){
+						int rest = p->hlength+9-p->found;
+						memcpy(p->hbuf+p->found, buf+c, rest);
+						if (ring_write(p->rbuf, buf+c+rest, 
+							       l-rest) <0){
+							fprintf(stderr,
+								"ring buffer overflow in get_pes %d\n"
+								,p->rbuf->size);
+							exit(1);
 						}
+					} else {
+						if (ring_write(p->rbuf, buf+c, l)<0){
+							fprintf(stderr,
+								"ring buffer overflow in get_pes %d\n"
+								,p->rbuf->size);
+							exit(1);
+						}
 					}
+				}
 
-					p->found += l;
-					c += l;
-				}			
-				if(p->found == p->plength+6){
-					func(p);
-				}
-				break;
+				p->found += l;
+				c += l;
+			}			
+			if(p->found == p->plength+6){
+				func(p);
 			}
+			break;
+		}
 
-			if ( p->done ){
-				if( p->found + count - c < p->plength+6){
-					p->found += count-c;
-					c = count;
-				} else {
-					c += p->plength+6 - p->found;
-					p->found = p->plength+6;
-				}
+		if ( p->done ){
+			if( p->found + count - c < p->plength+6){
+				p->found += count-c;
+				c = count;
+			} else {
+				c += p->plength+6 - p->found;
+				p->found = p->plength+6;
 			}
+		}
 
-			if (p->plength && p->found == p->plength+6) {
-				init_pes_in(p, p->type, NULL, p->withbuf);
-				if (c < count) {
-					done = 0;
-					count -= c;
-					buf += c;
-				}
-			}
-		} 
-	} while(!done);
+		if (p->plength && p->found == p->plength+6) {
+			init_pes_in(p, p->type, NULL, p->withbuf);
+			if (c < count)
+				get_pes(p, buf+c, count-c, func);
+		}
+	}
 	return;
 }
 
@@ -459,7 +457,6 @@
 int cwrite_ps(uint8_t *buf, ps_packet *p, uint32_t length)
 {
         long count,i;
-        (void)length;
         uint8_t headr1[4] = {0x00, 0x00, 0x01, PACK_START };
         uint8_t headr2[4] = {0x00, 0x00, 0x01, SYS_START };
         uint8_t buffy = 0xFF;
@@ -556,7 +553,6 @@
 		p.rate_bound[1] = (uint8_t)(0xff & (muxr >> 7));
 		p.rate_bound[2] = (uint8_t)(0x01 | ((muxr & 0x7f)<<1));
 
-	
 		p.audio_bound = (uint8_t)((audio_bound << 2)|(fixed << 1)|CSPS);
 		p.video_bound = (uint8_t)((audio_lock << 7)|
 				     (video_lock << 6)|0x20|video_bound);
@@ -586,10 +582,10 @@
 }
 
 
-static void get_pespts(uint8_t *spts,uint8_t *pts)
+void get_pespts(uint8_t *spts,uint8_t *pts)
 {
-	//Make sure to set the 1st 4 bits properly
-        pts[0] = 0x01 |
+
+        pts[0] = 0x21 |
                 ((spts[0] & 0xC0) >>5);
         pts[1] = ((spts[0] & 0x3F) << 2) |
                 ((spts[1] & 0xC0) >> 6);
@@ -647,23 +643,22 @@
 
 	dummy[0] = 0x80;
 	dummy[1] = 0;
-	dummy[2] = stuffing;
+	dummy[2] = 0;
 	
 	if (ptsdts == PTS_ONLY){
-		dummy[2] += 5;
+		dummy[2] = 5 + stuffing;
 		dummy[1] |= PTS_ONLY;
-		ppts[0] |= 0x20;
 	} else 	if (ptsdts == PTS_DTS){
-		dummy[2] += 10;
+		dummy[2] = 10 + stuffing;
 		dummy[1] |= PTS_DTS;
-		ppts[0] |= 0x30;
-		pdts[0] |= 0x10;
 	}
-		
 
 	memcpy(obuf+c,dummy,3);
 	c += 3;
 
+	memset(obuf+c,0xFF,stuffing);
+	c += stuffing;
+
 	if (ptsdts == PTS_ONLY){
 		memcpy(obuf+c,ppts,5);
 		c += 5;
@@ -673,19 +668,15 @@
 		memcpy(obuf+c,pdts,5);
 		c += 5;
 	}
-
-	memset(obuf+c,0xFF,stuffing);
-	c += stuffing;
-
 	return c;
 }
 
-void write_padding_pes( int pack_size, int extcnt, 
+void write_padding_pes( int pack_size, int apidn, int ac3n, 
 			uint64_t SCR, uint64_t muxr, uint8_t *buf)
 {
 	int pos = 0;
 
-	pos = write_ps_header(buf,SCR,muxr, extcnt, 0, 0, 1, 1, 1,
+	pos = write_ps_header(buf,SCR,muxr, apidn+ ac3n, 0, 0, 1, 1, 1,
 			      0);
 
 	pos += write_pes_header( PADDING_STREAM, pack_size-pos, 0, 0, buf+pos,
@@ -693,7 +684,7 @@
 
 }
 
-int write_video_pes( int pack_size, int extcnt, uint64_t vpts, 
+int write_video_pes( int pack_size, int apidn, int ac3n, uint64_t vpts, 
 		     uint64_t vdts, uint64_t SCR, uint64_t muxr, 
 		     uint8_t *buf, int *vlength, 
 		     uint8_t ptsdts, ringbuffer *vrbuffer)
@@ -704,6 +695,11 @@
 	int stuff = 0;
 	int length = *vlength;
 
+#ifdef PES_DEBUG
+	fprintf(stderr,"write video PES ");
+	printpts(vdts);
+	fprintf(stderr,"\n");
+#endif
 	if (! length) return 0;
 	p = PS_HEADER_L1+PES_H_MIN;
 
@@ -723,7 +719,7 @@
 			length = length+p;
 	}
 
-	pos = write_ps_header(buf,SCR,muxr, extcnt, 0, 0, 1, 1, 
+	pos = write_ps_header(buf,SCR,muxr, apidn+ac3n, 0, 0, 1, 1, 
 			      1, 0);
 
 	pos += write_pes_header( 0xE0, length-pos, vpts, vdts, buf+pos, 
@@ -746,7 +742,7 @@
 	return pos;
 }
 
-int write_audio_pes(  int pack_size, int extcnt, int n, uint64_t pts, 
+int write_audio_pes(  int pack_size, int apidn, int ac3n, int n, uint64_t pts, 
 		      uint64_t SCR, uint32_t muxr, uint8_t *buf, int *alength, 
 		      uint8_t ptsdts, 	ringbuffer *arbuffer)
 {
@@ -756,6 +752,12 @@
 	int stuff = 0;
 	int length = *alength;
 
+#ifdef PES_DEBUG
+	fprintf(stderr,"write audio PES ");
+	printpts(pts);
+	fprintf(stderr,"\n");
+#endif
+
 	if (!length) return 0;
 	p = PS_HEADER_L1+PES_H_MIN;
 
@@ -772,7 +774,7 @@
 		} else 
 			length = length+p;
 	}
-	pos = write_ps_header(buf,SCR,muxr, extcnt, 0, 0, 1, 1, 
+	pos = write_ps_header(buf,SCR,muxr, apidn + ac3n, 0, 0, 1, 1, 
 			      1, 0);
 	pos += write_pes_header( 0xC0+n, length-pos, pts, 0, buf+pos, stuff, 
 				 ptsdts);
@@ -794,10 +796,12 @@
 	return pos;
 }
 
-int write_ac3_pes(  int pack_size, int extcnt, int n,
+
+
+int write_ac3_pes(  int pack_size, int apidn, int ac3n, int n,
 		    uint64_t pts, uint64_t SCR, 
 		    uint32_t muxr, uint8_t *buf, int *alength, uint8_t ptsdts,
-		    int nframes,int ac3_off, ringbuffer *ac3rbuffer)
+		    int nframes,int ac3_off, ringbuffer *ac3rbuffer, int framelength)
 {
 	int add;
 	int pos = 0;
@@ -805,14 +809,21 @@
 	int stuff = 0;
 	int length = *alength;
 
+#ifdef PES_DEBUG
+	fprintf(stderr,"write ac3 PES ");
+	printpts(pts);
+	fprintf(stderr,"\n");
+#endif
+
 	if (!length) return 0;
-	p = PS_HEADER_L1+PES_H_MIN+4;
+	p = PS_HEADER_L1+PES_H_MIN;
 
 	if (ptsdts == PTS_ONLY){
 		p += 5;
 	}
 
 	if ( length+p >= pack_size){
+		if (length+p -pack_size == framelength-4) nframes--;
 		length = pack_size;
 	} else {
 		if (pack_size-length-p <= PES_MIN){
@@ -821,12 +832,12 @@
 		} else 
 			length = length+p;
 	}
-	pos = write_ps_header(buf,SCR,muxr, extcnt, 0, 0, 1, 1, 
+	pos = write_ps_header(buf,SCR,muxr, apidn+ac3n, 0, 0, 1, 1, 
 			      1, 0);
 
 	pos += write_pes_header( PRIVATE_STREAM1, length-pos, pts, 0, 
 				 buf+pos, stuff, ptsdts);
-	buf[pos] = 0x80 + n;
+	buf[pos] = 0x80 + n +apidn;
 	buf[pos+1] = nframes;
 	buf[pos+2] = (ac3_off >> 8)& 0xFF;
 	buf[pos+3] = (ac3_off)& 0xFF;
@@ -850,14 +861,139 @@
 	return pos;
 }
 
-int write_nav_pack(int pack_size, int extcnt, uint64_t SCR, uint32_t muxr, 
+
+int bwrite_audio_pes(  int pack_size, int apidn, int ac3n, int n, uint64_t pts, 
+		      uint64_t SCR, uint32_t muxr, uint8_t *buf, int *alength, 
+		       uint8_t ptsdts, uint8_t *arbuffer, int bsize )
+{
+	int add;
+	int pos = 0;
+	int p   = 0;
+	int stuff = 0;
+	int length = *alength;
+
+#ifdef PES_DEBUG
+	fprintf(stderr,"write audio PES ");
+	printpts(pts);
+	fprintf(stderr,"\n");
+#endif
+
+	if (!length) return 0;
+	p = PS_HEADER_L1+PES_H_MIN;
+
+	if (ptsdts == PTS_ONLY){
+		p += 5;
+	}
+
+	if ( length+p >= pack_size){
+		length = pack_size;
+	} else {
+		if (pack_size-length-p <= PES_MIN){
+			stuff = pack_size - length-p;
+			length = pack_size;
+		} else 
+			length = length+p;
+	}
+	pos = write_ps_header(buf,SCR,muxr, apidn + ac3n, 0, 0, 1, 1, 
+			      1, 0);
+	pos += write_pes_header( 0xC0+n, length-pos, pts, 0, buf+pos, stuff, 
+				 ptsdts);
+
+	if (length -pos < bsize){
+		memcpy(buf+pos, arbuffer, length-pos);
+		add = length - pos;
+		*alength = add;
+	} else  return -1;
+	
+	pos += add;
+
+	if (pos+PES_MIN < pack_size){
+		pos += write_pes_header( PADDING_STREAM, pack_size-pos, 0,0,
+					 buf+pos, 0, 0);
+		pos = pack_size;
+	}		
+	if (pos != pack_size) {
+		fprintf(stderr,"apos: %d\n",pos);
+		exit(1);
+	}
+
+	return pos;
+}
+
+
+
+int bwrite_ac3_pes(  int pack_size, int apidn, int ac3n, int n,
+		    uint64_t pts, uint64_t SCR, 
+		    uint32_t muxr, uint8_t *buf, int *alength, uint8_t ptsdts,
+		     int nframes,int ac3_off, uint8_t *ac3rbuffer, int bsize, int framelength)
+{
+	int add;
+	int pos = 0;
+	int p   = 0;
+	int stuff = 0;
+	int length = *alength;
+
+#ifdef PES_DEBUG
+	fprintf(stderr,"write ac3 PES ");
+	printpts(pts);
+	fprintf(stderr,"\n");
+#endif
+	if (!length) return 0;
+	p = PS_HEADER_L1+PES_H_MIN;
+
+	if (ptsdts == PTS_ONLY){
+		p += 5;
+	}
+
+	if ( length+p >= pack_size){
+		if (length+p -pack_size == framelength-4) nframes--;
+		length = pack_size;
+	} else {
+		if (pack_size-length-p <= PES_MIN){
+			stuff = pack_size - length-p;
+			length = pack_size;
+		} else 
+			length = length+p;
+	}
+	pos = write_ps_header(buf,SCR,muxr, apidn+ac3n, 0, 0, 1, 1, 
+			      1, 0);
+
+	pos += write_pes_header( PRIVATE_STREAM1, length-pos, pts, 0, 
+				 buf+pos, stuff, ptsdts);
+	buf[pos] = 0x80 + n +apidn;
+	buf[pos+1] = nframes;
+	buf[pos+2] = (ac3_off >> 8)& 0xFF;
+	buf[pos+3] = (ac3_off)& 0xFF;
+	pos += 4;
+
+	if (length-pos <= bsize){
+		memcpy(buf+pos, ac3rbuffer, length-pos);
+		add = length-pos;
+		*alength = add;
+	} else return -1;
+	pos += add;
+
+	if (pos+PES_MIN < pack_size){
+		pos += write_pes_header( PADDING_STREAM, pack_size-pos, 0,0,
+					 buf+pos, 0, 0);
+		pos = pack_size;
+	}		
+	if (pos != pack_size) {
+		fprintf(stderr,"apos: %d\n",pos);
+		exit(1);
+	}
+
+	return pos;
+}
+
+
+int write_nav_pack(int pack_size, int apidn, int ac3n, uint64_t SCR, uint32_t muxr, 
 		   uint8_t *buf)
 {
 	int pos = 0;
         uint8_t headr[5] = {0x00, 0x00, 0x01, PRIVATE_STREAM2, 0x03 };
-        (void)pack_size;
 
-	pos = write_ps_header( buf, SCR, muxr, extcnt, 0, 0, 1, 1, 1, 1);
+	pos = write_ps_header( buf, SCR, muxr, apidn+ac3n, 0, 0, 1, 1, 1, 1);
 	memcpy(buf+pos, headr, 5);
 	buf[pos+5] = 0xD4;
 	pos += 6;
Index: replex/CHANGES
===================================================================
--- replex/CHANGES	(revision 18755)
+++ replex/CHANGES	(working copy)
@@ -1,3 +1,20 @@
+0.1.6
+DVB wants continuous numbering of audio streams, even for MP2 AC3 mix
+added handling of too few audio PTS in some streams
+added audio frame dropping, when video cut is larger than audio cut
+add the -j option to jump over PTS discontinuities and cuts
+add -l option to set the minimum time in ms a jump has to have 
+add -g option to set video buffer size in GB
+fixed MPEG2 and AC3 multiplexing
+add version information
+add -p option for filling MPEG audio frames with zero
+add -q options to set limit for overflow errors
+
+0.1.5
+various minor fixes 
+added better audio frame recognition
+fixed AC3 PTS problem for dvdauthor
+
 0.1.4
 fixed problem with audio PTS which ruined dvdauthor
 
Index: replex/multiplex.h
===================================================================
--- replex/multiplex.h	(revision 18755)
+++ replex/multiplex.h	(working copy)
@@ -2,8 +2,10 @@
  * multiplex.h
  *        
  *
- * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
+ * Copyright (C) 2003 - 2006
+ *                    Marcus Metzler <mocm@metzlerbros.de>
  *                    Metzler Brothers Systementwicklung GbR
+ *           (C) 2006 Reel Multimedia
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -33,13 +35,12 @@
 #define N_AUDIO 32
 #define N_AC3 8
 
+
 typedef struct multiplex_s{
 	int fd_out;
 #define REPLEX_MPEG2  0
 #define REPLEX_DVD    1
 #define REPLEX_HDTV   2
-#define REPLEX_TS_SD  3
-#define REPLEX_TS_HD  4
 	int otype;
 	int startup;
 	int finish;
@@ -48,7 +49,7 @@
 	uint64_t video_delay;
 	uint64_t audio_delay;
 	int pack_size;
-	unsigned int data_size;
+	int data_size;
 	uint32_t audio_buffer_size;
 	uint32_t video_buffer_size;
 	uint32_t mux_rate;
@@ -58,24 +59,44 @@
 #define TIME_IFRAME 2
 	int frame_timestamps;
 	int VBR;
-	int is_ts;
 	int reset_clocks;
 	int write_end_codes;
 	int set_broken_link;
-	unsigned int vsize, extsize;
+	int vsize, asize;
 	int64_t extra_clock;
+	uint64_t first_vpts;
+	uint64_t first_apts[N_AUDIO];
+	uint64_t first_ac3pts[N_AC3];
+	
 	uint64_t SCR;
 	uint64_t oldSCR;
 	uint64_t SCRinc;
 	index_unit viu;
+	index_unit aiu[N_AUDIO];
+	index_unit ac3iu[N_AC3];
+	uint64_t apts[N_AUDIO];
+	uint64_t ac3pts[N_AC3];
+	uint64_t ac3pts_off[N_AC3];
+	uint64_t apts_off[N_AUDIO];
+	int aframes[N_AUDIO];
+	int ac3frames[N_AUDIO];
+	int total_written;
+	int zero_write_count;
+	int max_write;
+	int max_reached;
 
+/* needed from replex */
+	int apidn;
+	int ac3n;
+
 	dummy_buffer vdbuf;
+	dummy_buffer adbuf[N_AUDIO];
+	dummy_buffer ac3dbuf[N_AC3];
 
-	extdata_t ext[N_AUDIO];
-	int extcnt;
-
-	ringbuffer *extrbuffer;
-	ringbuffer *index_extrbuffer;
+	ringbuffer *ac3rbuffer;
+	ringbuffer *index_ac3rbuffer;
+	ringbuffer *arbuffer;
+	ringbuffer *index_arbuffer;
 	ringbuffer *vrbuffer;
 	ringbuffer *index_vrbuffer;
 
@@ -83,15 +104,18 @@
 	void *priv;
 } multiplex_t;
 
-void check_times( multiplex_t *mx, int *video_ok, int *ext_ok, int *start);
-void write_out_packs( multiplex_t *mx, int video_ok, int *ext_ok);
+void check_times( multiplex_t *mx, int *video_ok, int *audio_ok, int *ac3_ok,
+		  int *start);
+void write_out_packs( multiplex_t *mx, int video_ok, 
+		      int *audio_ok, int *ac3_ok);
 void finish_mpg(multiplex_t *mx);
-void init_multiplex( multiplex_t *mx, sequence_t *seq_head,
-		     audio_frame_t *extframe, int *exttype, int *exttypcnt,
+void init_multiplex( multiplex_t *mx, sequence_t *seq_head, audio_frame_t *aframe,
+		     audio_frame_t *ac3frame, int apidn, int ac3n,	
 		     uint64_t video_delay, uint64_t audio_delay, int fd,
 		     int (*fill_buffers)(void *p, int f),
 		     ringbuffer *vrbuffer, ringbuffer *index_vrbuffer,	
-		     ringbuffer *extrbuffer, ringbuffer *index_extrbuffer,
+		     ringbuffer *arbuffer, ringbuffer *index_arbuffer,
+		     ringbuffer *ac3rbuffer, ringbuffer *index_ac3rbuffer,
 		     int otype);
 
 void setup_multiplex(multiplex_t *mx);
Index: replex/element.c
===================================================================
--- replex/element.c	(revision 18755)
+++ replex/element.c	(working copy)
@@ -2,8 +2,10 @@
  * element.c: MPEG ELEMENTARY STREAM functions for replex
  *        
  *
- * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
+ * Copyright (C) 2003 - 2006
+ *                    Marcus Metzler <mocm@metzlerbros.de>
  *                    Metzler Brothers Systementwicklung GbR
+ *           (C) 2006 Reel Multimedia
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -26,19 +28,27 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
 
 #include "element.h"
 #include "mpg_common.h"
 #include "pes.h"
 
 unsigned int slots [4] = {12, 144, 0, 0};
-unsigned int bitrates[3][16] =
-{{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0},
- {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0},
- {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}};
+const uint16_t bitrates[2][3][15] = {
+    { {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 },
+      {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 },
+      {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 } },
+    { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256},
+      {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160},
+      {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}
+    }
+};
 
-uint32_t freq[4] = {441, 480, 320, 0};
-static uint64_t samples[4] = { 384, 1152, 1152, 1536};
+const uint16_t freqs[3] = { 44100, 48000, 32000 };
+
+static uint32_t samples[4] = { 384, 1152, 1152, 1536};
+
 char *frames[3] = {"I-Frame","P-Frame","B-Frame"};
 
 unsigned int ac3_bitrates[32] =
@@ -58,16 +68,23 @@
 	return newpts>0 ? newpts%MAX_PTS2: MAX_PTS2+newpts;
 }
 
-void fix_audio_count(uint64_t *acount, audio_frame_t *aframe, uint64_t origpts, uint64_t pts)
+int  cfix_audio_count(audio_frame_t *aframe, uint64_t origpts, uint64_t pts)
 {
 	int64_t diff;
 	uint64_t di;
 	int c=0;
-
 	di = (samples [3-aframe->layer] * 27000000ULL);
 	diff = ptsdiff(origpts,pts);
 	c=(aframe->frequency * diff+di/2)/di;
-	if (c) fprintf(stderr,"fix audio frames %d\n",c);
+	return c;
+}
+
+
+void fix_audio_count(uint64_t *acount, audio_frame_t *aframe, uint64_t origpts, uint64_t pts)
+{
+	int c=0;
+
+	c = cfix_audio_count(aframe, origpts, pts);
 	*acount += c;
 }
 
@@ -79,8 +96,13 @@
 
 	
 	if ( s->pulldown == NOPULLDOWN ) {
-		newdts = ( (fcount-1) * SEC_PER + *pts);
-		newpts = ((fnum ) * SEC_PER + *pts);
+		if (s->progressive == TWO_FIELD){
+			newdts = ( (fcount-2) * SEC_PER*2 + *pts);
+			newpts = ((fnum-1 ) * SEC_PER*2 + *pts);
+		} else {
+			newdts = ( (fcount-1) * SEC_PER + *pts);
+			newpts = ((fnum ) * SEC_PER + *pts);
+		} 
 	} else {
 		uint64_t extra_time = 0;
 //		fprintf(stderr,"pulldown %d %d\n",(int) fcount-1, fnum-1);
@@ -144,10 +166,47 @@
 			  (int)fr/2);
 }
 
-	
+int FindPacketHeader(const uint8_t *Data, int s, int l);
+
+void inserttime(uint8_t *buf, uint8_t h, uint8_t m, uint8_t s)
+{
+	buf[4] &= ~(0x7F); 
+	buf[4] |= (h & 0x1F) << 2;
+	buf[4] |= (m & 0x30) >> 4;
+
+	buf[5] &= ~(0xF7);
+	buf[5] |= (m & 0x0F) << 4;
+	buf[5] |= (s & 0x38) >> 3;
+
+	buf[6] &= ~(0xE0);
+        buf[6] |= (s & 0x07) << 5;
+}
+
 void pts2time(uint64_t pts, uint8_t *buf, int len)
 {
 	uint8_t h,m,s;
+	int c=0,x;
+//	uint8_t *data=buf;
+
+	pts = (pts/300)%MAX_PTS;
+	h = (uint8_t)(pts/90000)/3600;
+	m = (uint8_t)((pts/90000)%3600)/60;
+	s = (uint8_t)((pts/90000)%3600)%60;
+
+	while(c+7 < len) {
+		x=FindPacketHeader(buf, c, len);
+		if (x==-1)
+			return;
+		if (buf[x+3]==GROUP_START_CODE && (buf[x+5] & 0x08)) {
+			inserttime(buf+x, h, m, s);
+		}
+		c=x+4;
+	}
+		
+}	
+void pts2timex(uint64_t pts, uint8_t *buf, int len)
+{
+	uint8_t h,m,s;
 	int c = 0;
 
 	pts = (pts/300)%MAX_PTS;
@@ -158,17 +217,7 @@
 	while (c+7 < len){
 		if (buf[c] == 0x00 && buf[c+1] == 0x00 && buf[c+2] == 0x01 && 
 		    buf[c+3] == GROUP_START_CODE && (buf[c+5] & 0x08)){
-			buf[c+4] &= ~(0x7F);
-			buf[c+4] |= (h & 0x1F) << 2;
-			buf[c+4] |= (m & 0x30) >> 4;
-
-			buf[c+5] &= ~(0xF7);
-			buf[c+5] |= (m & 0x0F) << 4;
-			buf[c+5] |= (s & 0x38) >> 3;
-
-			buf[c+6] &= ~(0xE0);
-			buf[c+6] |= (s & 0x07) << 5;
-
+			inserttime(buf+c,h,m,s);
 /* 1hhhhhmm|mmmm1sss|sss */
 /*
 			c+=4;
@@ -186,7 +235,7 @@
 }
 
 
-int get_video_info(ringbuffer *rbuf, sequence_t *s, int off, int le)
+int get_video_info(ringbuffer *rbuf, sequence_t *s, long off, int le)
 {
         uint8_t buf[150];
         uint8_t *headr;
@@ -311,7 +360,7 @@
 	return c;
 }
 
-int find_audio_sync(ringbuffer *rbuf, uint8_t *buf, int off, int type, int le)
+int find_audio_sync(ringbuffer *rbuf, uint8_t *buf, long off, int type, int le)
 {
 	int found = 0;
 	int c=0;
@@ -364,7 +413,7 @@
 	return -1;
 }
 
-int find_audio_s(uint8_t *rbuf, int off, int type, int le)
+int find_audio_s(uint8_t *rbuf, long off, int type, int le)
 {
 	int found = 0;
 	int c=0;
@@ -411,7 +460,31 @@
 	return -1;
 }
 
-int check_audio_header(ringbuffer *rbuf, audio_frame_t * af, int  off, int le, 
+static int calculate_mpg_framesize(audio_frame_t *af)
+{
+        int frame_size;
+
+        frame_size = af->bit_rate/1000;
+        if (!frame_size) return -1;
+        switch(af->layer) {
+        case 1:
+                frame_size = (frame_size * 12000) / af->sample_rate;
+                frame_size = (frame_size + af->padding) * 4;
+                break;
+        case 2:
+                frame_size = (frame_size * 144000) / af->sample_rate;
+                frame_size += af->padding;
+                break;
+        default:
+        case 3:
+                frame_size = (frame_size * 144000) / (af->sample_rate << af->lsf);
+                frame_size += af->padding;
+                break;
+        }
+        return frame_size;
+}
+
+int check_audio_header(ringbuffer *rbuf, audio_frame_t * af, long  off, int le, 
 		       int type)
 {
 	uint8_t headr[7];
@@ -432,7 +505,7 @@
 	switch (type){
 
 	case MPEG_AUDIO:
-		if ( af->layer != ((headr[1] & 0x06) >> 1) ){
+		if ( af->layer != 4 -((headr[1] & 0x06) >> 1) ){
 			if ( headr[1] == 0xff){
 				return -3;
 			} else {
@@ -442,13 +515,26 @@
 				return -1;
 			}
 		}
-		if ( af->bit_rate != 
-		     (bitrates[(3-af->layer)][(headr[2] >> 4 )]*1000)){
+                if ( af->bit_rate !=
+                     (  af->bit_rate = bitrates[af->lsf][af->layer-1][(headr[2] >> 4 )]*1000)){
 #ifdef IN_DEBUG
-			fprintf(stderr,"Wrong audio bit rate\n");
+                        fprintf(stderr,"Wrong audio bit rate\n");
 #endif
-			return -1;
-		}
+                        return -1;
+                }
+
+                if (af->padding != ((headr[2] >> 1) & 1)){
+			int fsize;
+			af->padding = (headr[2] >> 1) & 1;
+                        if ((fsize = calculate_mpg_framesize(af)) < 0 || 
+			     abs(fsize - af->framesize) >2) return -1;
+			af->framesize = fsize;
+#ifdef IN_DEBUG
+                        fprintf(stderr,"padding changed : %d\n",af->padding);
+#endif
+
+                }
+
 		break;
 		
 	case AC3:
@@ -476,26 +562,46 @@
 }
 
 
-int get_audio_info(ringbuffer *rbuf, audio_frame_t *af, int off, int le) 
+int get_audio_info(ringbuffer *rbuf, audio_frame_t *af, long off, int le, int verb) 
 {
 	int c = 0;
 	int fr =0;
-	uint8_t headr[7];
+	uint8_t headr[4];
+        int sample_rate_index;
 
 	af->set=0;
 
 	if ( (c = find_audio_sync(rbuf, headr, off, MPEG_AUDIO,le)) < 0 ) 
 		return c;
 
-	af->layer = (headr[1] & 0x06) >> 1;
+        af->layer = 4 - ((headr[1] & 0x06) >> 1);
+//        if (af->layer >3) return -1;
 
-        if (DEBUG)
-		fprintf(stderr,"Audiostream: layer: %d", 4-af->layer);
+        if (DEBUG && verb)
+		fprintf(stderr,"Audiostream: layer: %d", af->layer);
+        if (headr[1] & (1<<4)) {
+                af->lsf = (headr[1] & (1<<3)) ? 0 : 1;
+                af->mpg25 = 0;
+		if (DEBUG && verb)
+			fprintf(stderr,"  version: 1");
+        } else {
+                af->lsf = 1;
+                af->mpg25 = 1;
+		if (DEBUG && verb)
+			fprintf(stderr,"  version: 2");
+        }
+        /* extract frequency */
+        sample_rate_index = (headr[2] >> 2) & 3;
+        if (sample_rate_index > 2) return -1;
+        af->sample_rate = freqs[sample_rate_index] >> (af->lsf + af->mpg25);
 
+	af->padding = (headr[2] >> 1) & 1;
 
-	af->bit_rate = bitrates[(3-af->layer)][(headr[2] >> 4 )]*1000;
 
-	if (DEBUG){
+        af->bit_rate = bitrates[af->lsf][af->layer-1][(headr[2] >> 4 )]*1000;
+
+
+	if (DEBUG && verb){
 		if (af->bit_rate == 0)
 			fprintf (stderr,"  Bit rate: free");
 		else if (af->bit_rate == 0xf)
@@ -505,9 +611,10 @@
 	}
 
 	fr = (headr[2] & 0x0c ) >> 2;
-	af->frequency = freq[fr]*100;
-	
-	if (DEBUG){
+	af->frequency = freqs[fr];
+
+
+	if (DEBUG && verb){
 		if (af->frequency == 3)
 			fprintf (stderr, "  Freq: reserved");
 		else
@@ -516,20 +623,16 @@
 	}
 	af->off = c;
 	af->set = 1;
-
-	af->frametime = ((samples [3-af->layer] * 27000000ULL) / af->frequency);
-	af->framesize = af->bit_rate *slots [3-af->layer]/ af->frequency;
-	fprintf(stderr," frame size: %d (", af->framesize);
-	printpts(af->frametime);
-	fprintf(stderr,") ");
-
+	af->framesize = calculate_mpg_framesize(af);
+	//af->framesize = af->bit_rate *slots [3-af->layer]/ af->frequency;
+	if (DEBUG && verb) fprintf(stderr," frame size: %d \n", af->framesize);
 	return c;
 }
 
-int get_ac3_info(ringbuffer *rbuf, audio_frame_t *af, int off, int le)
+int get_ac3_info(ringbuffer *rbuf, audio_frame_t *af, long off, int le, int verb)
 {
 	int c=0;
-	uint8_t headr[7];
+	uint8_t headr[6];
 	uint8_t frame;
 	int half = 0;
 	int fr;
@@ -544,15 +647,15 @@
 
 	af->layer = 0;  // 0 for AC3
 
-	if (DEBUG) fprintf (stderr,"AC3 stream:");
+	if (DEBUG && verb) fprintf (stderr,"AC3 stream:");
 	frame = (headr[4]&0x3F);
 	af->bit_rate = ac3_bitrates[frame>>1]*1000;
 	half = ac3half[headr[5] >> 3];
-	if (DEBUG) fprintf (stderr,"  bit rate: %d kb/s", af->bit_rate/1000);
+	if (DEBUG && verb) fprintf (stderr,"  bit rate: %d kb/s", af->bit_rate/1000);
 	fr = (headr[4] & 0xc0) >> 6;
 	af->frequency = (ac3_freq[fr] *100) >> half;
 	
-	if (DEBUG) fprintf (stderr,"  freq: %d Hz\n", af->frequency);
+	if (DEBUG && verb) fprintf (stderr,"  freq: %d Hz\n", af->frequency);
 
 	switch (headr[4] & 0xc0) {
 	case 0:
@@ -568,19 +671,15 @@
 		break;
 	}
 
-	if (DEBUG) fprintf (stderr,"  frame size %d\n", af->framesize);
+	if (DEBUG && verb) fprintf (stderr,"  frame size %d\n", af->framesize);
 
 	af->off = c;
 	af->set = 1;
-
-	//FIXME calculate frametime
-	af->frametime = 0;
-
-    return c;
+	return c;
 }
 
 
-int get_video_ext_info(ringbuffer *rbuf, sequence_t *s, int off, int le)
+int get_video_ext_info(ringbuffer *rbuf, sequence_t *s, long off, int le)
 {
         uint8_t *headr;
         uint8_t buf[12];
@@ -612,8 +711,10 @@
 
 		if (DEBUG) fprintf(stderr,"Sequence Extension:");
 		s->profile = ((headr[0]&0x0F) << 4) | ((headr[1]&0xF0) >> 4);
-		if (headr[1]&0x08) s->progressive = 1;
-		else s->progressive = 0;
+		if (headr[1]&0x08){
+			s->progressive = 1;
+			if (DEBUG) fprintf(stderr," progressive sequence ");
+		} else s->progressive = 0;
 		s->chroma = (headr[1]&0x06)>>1;
 		if (DEBUG){
 			switch(s->chroma){
@@ -660,30 +761,41 @@
 		break;
 
 	case PICTURE_CODING_EXTENSION:{
-		int pulldown = 0;
+		int repeat_first = 0;
+		int top_field = 0;
+		int prog_frame = 0;
 
 		if (!s->set || s->pulldown_set) break;
 		if (ring_peek(rbuf, buf, 10, off) < 0) return -2;
 		headr=buf+4;
 		
 		if ( (headr[2]&0x03) != 0x03 ) break; // not frame picture
-		if ( (headr[3]&0x02) ) pulldown = 1; // repeat flag set => pulldown
+		if ( (headr[3]&0x02) ) repeat_first = 1; // repeat flag set => pulldown
+		if ( (headr[3]&0x80) ) top_field=1; 
+		if ( (headr[4]&0x80) ) prog_frame=1; 
+ 
+		if (repeat_first) {
+			if (!s->progressive){
+				if (s->current_tmpref)
+					s->pulldown = PULLDOWN23;
+				else
+					s->pulldown = PULLDOWN32;
+				s->pulldown_set = 1;
+			} else {
+				if(prog_frame && top_field)
+					s->progressive = TWO_FIELD;
+//				if (DEBUG) fprintf(stderr,"Picture Coding Extension: progressive tmp %d top %d prog %d rep %d\n", s->current_tmpref, top_field, prog_frame, repeat_first);
+			}
+		}
 
-		if (pulldown){
-			if (s->current_tmpref)
-				s->pulldown = PULLDOWN23;
-			else
-				s->pulldown = PULLDOWN32;
-			s->pulldown_set = 1;
-		} 
 		if (DEBUG){
 			switch (s->pulldown) {
 			case PULLDOWN32:
-				if (DEBUG) fprintf(stderr,"Picture Coding Extension:");
+				fprintf(stderr,"Picture Coding Extension:");
 				fprintf(stderr," 3:2 pulldown detected \n");
 				break;
 			case PULLDOWN23:
-				if (DEBUG) fprintf(stderr,"Picture Coding Extension:");
+				fprintf(stderr,"Picture Coding Extension:");
 				fprintf(stderr," 2:3 pulldown detected \n");
 				break;
 //			default:
Index: replex/ringbuffer.c
===================================================================
--- replex/ringbuffer.c	(revision 18755)
+++ replex/ringbuffer.c	(working copy)
@@ -2,8 +2,10 @@
  * ringbuffer.c
  *        
  *
- * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
+ * Copyright (C) 2003 - 2006
+ *                    Marcus Metzler <mocm@metzlerbros.de>
  *                    Metzler Brothers Systementwicklung GbR
+ *           (C) 2006 Reel Multimedia
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -30,6 +32,7 @@
 #include "pes.h"
 
 #define DEBUG 1
+// Initialize buffer
 int ring_init (ringbuffer *rbuf, int size)
 {
 	if (size > 0){
@@ -47,26 +50,7 @@
 	return 0;
 }
 
-int ring_reinit (ringbuffer *rbuf, int size)
-{
-	if (size > (int)(rbuf->size)) {
-		uint8_t *tmpalloc = (uint8_t *) realloc(rbuf->buffer,
-							sizeof(uint8_t)*size);
-		if (! tmpalloc)
-			return -1;
-		rbuf->buffer = tmpalloc;
-		if (rbuf->write_pos < rbuf->read_pos)
-		{
-			unsigned int delta = size - rbuf->size;
-			memmove(rbuf->buffer + rbuf->read_pos + delta,
-				rbuf->buffer + rbuf->read_pos,
-				rbuf->size - rbuf->read_pos);
-			rbuf->read_pos += delta;
-		}
-		rbuf->size = size;
-	}
-	return 0;
-}
+// reset buffer
 void ring_clear(ringbuffer *rbuf)
 {
 	rbuf->read_pos = 0;	
@@ -74,13 +58,14 @@
 }
 
 
-
+// delete buffer
 void ring_destroy(ringbuffer *rbuf)
 {
 	free(rbuf->buffer);
 }
 
 
+//write into buffer
 int ring_write(ringbuffer *rbuf, uint8_t *data, int count)
 {
 
@@ -92,9 +77,13 @@
 	free = ring_free(rbuf);
 
 	if ( free < count ){
-		if (DEBUG) fprintf(stderr,"ringbuffer overflow %d<%d %d\n", 
-				   free, count, rbuf->size);
-		return FULL_BUFFER;
+		if ( free > 0 ){
+			count = free;
+		} else {
+			if (DEBUG) fprintf(stderr,"ringbuffer overflow %d<%d %d\n", 
+					   free, count, rbuf->size);
+			return FULL_BUFFER;
+		}
 	}
 	
 	if (count >= rest){
@@ -112,10 +101,11 @@
 	return count;
 }
 
-int ring_peek(ringbuffer *rbuf, uint8_t *data, unsigned int count, uint32_t off)
+// peek into buffer
+int ring_peek(ringbuffer *rbuf, uint8_t *data, int count, long off)
 {
 
-	unsigned int avail, pos, rest;
+	int avail, pos, rest;
 
 	if (count <=0 || off+count > rbuf->size || off+count >ring_avail(rbuf)) return -1;
 	pos  = (rbuf->read_pos+off)%rbuf->size;
@@ -140,34 +130,8 @@
 	return count;
 }
 
-int ring_poke(ringbuffer *rbuf, uint8_t *data, unsigned int count, uint32_t off)
-{
 
-	unsigned int avail, pos, rest;
-
-	if (count <=0 || off+count > rbuf->size || off+count >ring_avail(rbuf)) return -1;
-	pos  = (rbuf->read_pos+off)%rbuf->size;
-	rest = rbuf->size - pos ;
-	avail = ring_avail(rbuf); 
-
-	
-	if ( avail < count ){
-//		if (DEBUG) fprintf(stderr,"ringbuffer peek underflow %d<%d %d %d\n", 
-//				   avail, count, pos, rbuf->write_pos);
-		return EMPTY_BUFFER;
-	}
-
-	if ( count < rest ){
-		memcpy(rbuf->buffer+pos, data, count);
-	} else {
-		memcpy(rbuf->buffer+pos, data, rest);
-		if ( count - rest)
-			memcpy(rbuf->buffer, data+rest, count - rest);
-	}
-
-	return count;
-}
-
+//read from buffer
 int ring_read(ringbuffer *rbuf, uint8_t *data, int count)
 {
 
@@ -199,6 +163,7 @@
 	return count;
 }
 
+//skip buffer
 int ring_skip(ringbuffer *rbuf, int count)
 {
 
@@ -226,7 +191,7 @@
 }
 
 
-
+// write from file into buffer
 int ring_write_file(ringbuffer *rbuf, int fd, int count)
 {
 
@@ -237,11 +202,13 @@
 	rest = rbuf->size - pos;
 	free = ring_free(rbuf);
 
-	if ( free < count ){
+	if ( !free ){
 		if (DEBUG) fprintf(stderr,"ringbuffer overflow %d<%d %d %d\n", 
 				   free, count, pos, rbuf->read_pos);
 		return FULL_BUFFER;
 	}
+
+	if ( count > free ) count = free;
 	
 	if (count >= rest){
 		rr = read (fd, rbuf->buffer+pos, rest);
@@ -262,6 +229,7 @@
 
 
 
+// write from buffer into file
 int ring_read_file(ringbuffer *rbuf, int fd, int count)
 {
 
@@ -296,7 +264,7 @@
 	return rr;
 }
 
-
+// print memory 
 static void show(uint8_t *buf, int length)
 {
 	int i,j,r;
@@ -329,10 +297,10 @@
 	}
 }
 
-void ring_show(ringbuffer *rbuf, unsigned int count, uint32_t off)
+void ring_show(ringbuffer *rbuf, int count, long off)
 {
 
-	unsigned int avail, pos, rest;
+	int avail, pos, rest;
 
 	if (count <=0 || off+count > rbuf->size || off+count >ring_avail(rbuf)) return;
 	pos  = (rbuf->read_pos+off)%rbuf->size;
@@ -368,12 +336,6 @@
 	return 0;
 }
 
-void dummy_destroy(dummy_buffer *dbuf)
-{
-        ring_destroy(&dbuf->time_index);
-        ring_destroy(&dbuf->data_index);
-}
-
 void dummy_clear(dummy_buffer *dbuf)
 {
 	dbuf->fill = 0;
@@ -423,6 +385,7 @@
 
 	return dsize;
 }
+/*
 void dummy_print(dummy_buffer *dbuf)
 {
    int i;
@@ -439,3 +402,4 @@
    }
    printf("Used: %d Free: %d data-free: %d\n", avail, 1000-avail, dbuf->size - dbuf->fill);
 }
+*/
Index: replex/mpg_common.c
===================================================================
--- replex/mpg_common.c	(revision 18755)
+++ replex/mpg_common.c	(working copy)
@@ -2,8 +2,10 @@
  * mpg_common.c: COMMON MPEG functions for replex
  *        
  *
- * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
+ * Copyright (C) 2003 - 2006
+ *                    Marcus Metzler <mocm@metzlerbros.de>
  *                    Metzler Brothers Systementwicklung GbR
+ *           (C) 2006 Reel Multimedia
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -61,11 +63,93 @@
 	}
 }
 
+//----------------------------------------------------------------------------
+#define CMP_CORE(offset) \
+        x=Data[i+1+offset]; \
+        if (x<2) { \
+                if (x==0) { \
+                        if ( Data[i+offset]==0 && Data[i+2+offset]==1) \
+                                return i+offset; \
+                        else if (Data[i+2+offset]==0 && Data[i+3+offset]==1) \
+                                return i+1+offset; \
+                } \
+                else if (x==1 && Data[i-1+offset]==0 && Data[i+offset]==0 && (i+offset)>0) \
+                         return i-1+offset; \
+         }
 
+int FindPacketHeader(const uint8_t *Data, int s, int l)
+{
+        int i;
+        uint8_t x;
 
-int find_mpg_header(uint8_t head, uint8_t *buf, int length)
+        if (l>12) {
+                for(i=s;i<l-12;i+=12) { 
+                        CMP_CORE(0);
+                        CMP_CORE(3);
+                        CMP_CORE(6);
+                        CMP_CORE(9);
+                }
+
+                for(; i<l-3; i+=3) {
+                        CMP_CORE(0);
+		}	       
+        }
+        else {
+                for(i=s; i<l-3; i+=3) {
+                        CMP_CORE(0);
+		}
+        }
+        return -1;
+}
+//----------------------------------------------------------------------------
+
+int find_mpg_header(uint8_t head, uint8_t *buf, int Count)
 {
+	int n=0;
+	uint8_t *Data=buf;
+        while(n<Count) {
+                int x;
+                x=FindPacketHeader(Data, 0, Count - n); // returns position of first 00
+                if (x!=-1) {
+                        Data+=x;
+                        n+=x;
+			if (Data[3]==head) {
+                                return n; 
+                        }
+                        n+=3;
+                        Data+=3;
+                        Count-=3;
+                }
+                else
+                        break;
+        }
+        return -1;
 
+}
+
+int find_any_header(uint8_t *head, uint8_t *buf, int Count)
+{
+	int n=0;
+	uint8_t *Data=buf;
+        while(n<Count) {
+                int x;
+                x=FindPacketHeader(Data, 0, Count - n); // returns position of first 00
+                if (x!=-1) {
+                        Data+=x;
+                        n+=x;
+			*head=Data[3];
+			return n; 
+                }
+                else
+                        break;
+        }
+        return -1;
+
+}
+
+int find_mpg_headerx(uint8_t head, uint8_t *buf, int length)
+{
+
 	int c = 0;
 	int found=0;
 
@@ -99,7 +183,7 @@
 }
 
 
-int find_any_header(uint8_t *head, uint8_t *buf, int length)
+int find_any_headerx(uint8_t *head, uint8_t *buf, int length)
 {
 
 	int c = 0;
@@ -153,7 +237,7 @@
 }
 
 
-int mring_peek( ringbuffer *rbuf, uint8_t *buf, unsigned int l, uint32_t off)
+int mring_peek( ringbuffer *rbuf, uint8_t *buf, int l, long off)
 {
         int c = 0;
 
@@ -205,9 +289,59 @@
 }
 
 
-int ring_find_any_header(ringbuffer *rbuf, uint8_t *head, int off, int le)
+#define PEEK_SIZE (512+1024)
+int ring_find_any_headery(ringbuffer *rbuf, uint8_t *head, int off, int le)
 {
+	uint8_t buf[PEEK_SIZE];
+//	int xoff;
+	int res,x;
+//	int found;
+	int n=off;
+	int peek_snip;
+//	printf("# %i %i\n",off,le);
+	while(le>0) {
+		if (le>PEEK_SIZE)
+			peek_snip=PEEK_SIZE;
+		else
+			peek_snip=le;
 
+		res=mring_peek(rbuf, buf, peek_snip, n);
+		if (res<0) {
+			peek_snip=ring_avail(rbuf);
+//			printf("PP %i\n",peek_snip);
+			if (peek_snip>PEEK_SIZE)
+				peek_snip=PEEK_SIZE;
+			if (peek_snip>le)
+				peek_snip=le;
+			res=mring_peek(rbuf,buf,peek_snip,n);
+			if (res<0)
+				return -1;
+		}
+//		printf("ZZ %i %i\n",peek_snip,n);
+		x=FindPacketHeader(buf, 0, peek_snip); // returns position of first 00
+                if (x!=-1 && x<=peek_snip-4) {
+                        n+=x-off;
+			
+			*head=buf[x+3];
+			return n; 
+                }
+		if (peek_snip<=4) {
+			int i;
+			for(i=0;i<peek_snip;i++)
+				if (buf[i]==0)
+					return -2;
+			return -1;
+		}
+
+		n+=peek_snip-4;
+		le-=peek_snip-4;
+	}
+	return -1; // Not found
+}
+
+int ring_find_any_headerx(ringbuffer *rbuf, uint8_t *head, int off, int le)
+{
+
 	int c = 0;
 	int found =0;
 
@@ -244,3 +378,19 @@
 	else return -1;
 }
 
+int ring_find_any_header(ringbuffer *rbuf, uint8_t *head, int off, int le)
+{
+	uint8_t a=0;
+//	uint8_t b=0;
+	int x;
+//	int y;
+
+	x=ring_find_any_headery(rbuf, &a, off, le);
+#if 0
+	y=ring_find_any_headery(rbuf, &b, off, le);
+	if (x!=y || a!=b)
+		printf("MY %i %i, ORG %i %i\n",y, b, x, a);
+#endif
+	*head=a;
+	return x;
+}
Index: replex/ts.h
===================================================================
--- replex/ts.h	(revision 18755)
+++ replex/ts.h	(working copy)
@@ -2,7 +2,8 @@
  * ts.h
  *        
  *
- * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
+ * Copyright (C) 2003 - 2006
+ *                    Marcus Metzler <mocm@metzlerbros.de>
  *                    Metzler Brothers Systementwicklung GbR
  *
  * This program is free software; you can redistribute it and/or
@@ -27,9 +28,6 @@
 #ifndef _TS_H_
 #define _TS_H_
 
-#include "ringbuffer.h"
-#include "mpg_common.h"
-
 #define TS_SIZE        188
 #define TRANS_ERROR    0x80
 #define PAY_START      0x40
@@ -58,19 +56,7 @@
 #define PIECE_RATE     0x40
 #define SEAM_SPLICE    0x20
 
-#define TS_VIDPID      4101
-#define TS_MP2PID      4201
-#define TS_AC3PID      4301
 uint16_t get_pid(uint8_t *pid);
 int find_pids(uint16_t *vpid, uint16_t *apid, uint16_t *ac3pid,uint8_t *buf, int len);
 int find_pids_pos(uint16_t *vpid, uint16_t *apid, uint16_t *ac3pid,uint8_t *buf, int len, int *vpos, int *apos, int *ac3pos);
-
-int write_video_ts(uint64_t vpts, uint64_t vdts, uint64_t SCR,
-	     uint8_t *buf, int *vlength, uint8_t ptsdts, ringbuffer *vrbuffer);
-int write_audio_ts(int n, uint64_t pts, 
-	     uint8_t *buf, int *alength, uint8_t ptsdts, ringbuffer *arbuffer);
-int write_ac3_ts(int n, uint64_t pts, uint8_t *buf, int *alength,
-	 uint8_t ptsdts, int nframes, ringbuffer *ac3rbuffer);
-void write_ts_patpmt(extdata_t *ext, int extcnt, uint8_t prog_num,
-			uint8_t *buf);
 #endif /*_TS_H_*/
Index: replex/pes.h
===================================================================
--- replex/pes.h	(revision 18755)
+++ replex/pes.h	(working copy)
@@ -1,7 +1,31 @@
-/* 
-    Copyright (C) 2003 Marcus Metzler (mocm@metzlerbros.de)
+/*
+ * pes.h: MPEG PES functions for replex
+ *        
+ *
+ * Copyright (C) 2003 - 2006
+ *                    Marcus Metzler <mocm@metzlerbros.de>
+ *                    Metzler Brothers Systementwicklung GbR
+ *           (C) 2006 Reel Multimedia
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * General Public License for more details.
+ *
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ */
 
-*/
 
 #ifndef _PES_H_
 #define _PES_H_
@@ -9,7 +33,6 @@
 #include <stdint.h>
 #include "ringbuffer.h"
 
-#define TS_HEADER_MIN	4
 #define PS_HEADER_L1    14
 #define PS_HEADER_L2    (PS_HEADER_L1+24)
 #define PES_MIN         7
@@ -71,7 +94,7 @@
 typedef
 struct pes_in_s{
 	int type;
-	unsigned int found;
+	int found;
 	int withbuf;
 	uint8_t *buf;
 	ringbuffer *rbuf;
@@ -102,25 +125,29 @@
 uint64_t ptsadd(uint64_t pts1, uint64_t pts2);
 
 
-int write_pes_header(uint8_t id, int length , uint64_t PTS, uint64_t DTS, 
-		     uint8_t *obuf, int stuffing, uint8_t ptsdts);
-void write_padding_pes( int pack_size, int extcnt, 
+void write_padding_pes( int pack_size, int apidn, int ac3n, 
 			uint64_t SCR, uint64_t muxr, uint8_t *buf);
-int write_ac3_pes(  int pack_size, int extcnt, int n, uint64_t pts, 
+int write_ac3_pes(  int pack_size, int apidn, int ac3n, int n, uint64_t pts, 
 		    uint64_t SCR, 
 		    uint32_t muxr, uint8_t *buf, int *alength, uint8_t ptsdts,
-		    int nframes,int ac3_off, ringbuffer *ac3rbuffer);
-int write_audio_pes(  int pack_size, int extcnt, int n, uint64_t pts, 
+		    int nframes,int ac3_off, ringbuffer *ac3rbuffer, int framelength);
+int bwrite_ac3_pes(  int pack_size, int apidn, int ac3n, int n, uint64_t pts, 
+		    uint64_t SCR, 
+		    uint32_t muxr, uint8_t *buf, int *alength, uint8_t ptsdts,
+		     int nframes,int ac3_off, uint8_t *ac3rbuffer, int bsize, int framelength);
+int write_audio_pes(  int pack_size, int apidn, int ac3n, int n, uint64_t pts, 
 		      uint64_t SCR, uint32_t muxr, uint8_t *buf, int *alength, 
 		      uint8_t ptsdts, 	ringbuffer *arbuffer);
-int write_video_pes( int pack_size, int extcnt, uint64_t vpts, 
+int bwrite_audio_pes(  int pack_size, int apidn, int ac3n, int n, uint64_t pts, 
+		      uint64_t SCR, uint32_t muxr, uint8_t *buf, int *alength, 
+		       uint8_t ptsdts, uint8_t *arbuffer, int bsize );
+int write_video_pes( int pack_size, int apidn, int ac3n, uint64_t vpts, 
 		     uint64_t vdts, uint64_t SCR, uint64_t muxr, 
 		     uint8_t *buf, int *vlength, 
 		     uint8_t ptsdts, ringbuffer *vrbuffer);
-int write_nav_pack(int pack_size, int extcnt, uint64_t SCR, uint32_t muxr, 
+int write_nav_pack(int pack_size, int apidn, int ac3n, uint64_t SCR, uint32_t muxr, 
 		   uint8_t *buf);
 
-
 static inline void ptsdec(uint64_t *pts1, uint64_t pts2)
 {
 	*pts1= uptsdiff(*pts1, pts2);
Index: mpeg2fix.cpp
===================================================================
--- mpeg2fix.cpp	(revision 18755)
+++ mpeg2fix.cpp	(working copy)
@@ -27,6 +27,8 @@
 #define O_LARGEFILE 0
 #endif
 
+#define DEBUG_AUDIO 1
+
 #define ATTR_ALIGN(align) __attribute__ ((__aligned__ (align)))
 
 #define SHOW_MSG(msg) (msg & print_verbose_messages)
@@ -237,6 +239,7 @@
     }
 
     ext_count = 0;
+    ac3_count = 0;
     vid_id = -1;
     mpeg2_malloc_hooks(my_malloc, NULL);
     header_decoder = mpeg2_init();
@@ -452,7 +455,10 @@
     memset(&index_vrbuf, 0, sizeof(ringbuffer));
     memset(&extrbuf, 0, sizeof(ringbuffer) * N_AUDIO);
     memset(&index_extrbuf, 0, sizeof(ringbuffer) * N_AUDIO);
+    memset(&ac3extrbuf, 0, sizeof(ringbuffer) * N_AUDIO);
+    memset(&index_ac3extrbuf, 0, sizeof(ringbuffer) * N_AUDIO);
     ext_count = 0;
+    ac3_count = 0;
 }
 
 MPEG2replex::~MPEG2replex()
@@ -485,6 +491,10 @@
             if (ring_avail(&index_extrbuf[i]) < sizeof(index_unit))
                 ok = 0;
 
+        for (i = 0; i < ac3_count; i++)
+            if (ring_avail(&index_ac3extrbuf[i]) < sizeof(index_unit))
+                ok = 0;
+
         if (ok || done)
             break;
 
@@ -518,6 +528,7 @@
     // note that although only 1 stream is currently supported, multiplex.c
     // expects the size to by N_AUDIO
     int ext_ok[N_AUDIO];
+    int ac3_ok[N_AC3];
     int video_ok = 0;
 
     //seq_head should be set only for the 1st sequence header.  If a new
@@ -529,6 +540,7 @@
 
     memset(&mx, 0, sizeof(mx));
     memset(ext_ok, 0, sizeof(ext_ok));
+    memset(ac3_ok, 0, sizeof(ac3_ok));
 
     mx.priv = (void *)this;
 
@@ -541,16 +553,27 @@
     pthread_mutex_unlock(&mutex);
 
     mplex = &mx;
-
+/*
     init_multiplex(&mx, &seq_head, extframe, exttype, exttypcnt,
                    video_delay, audio_delay, fd_out, fill_buffers,
                    &vrbuf, &index_vrbuf, extrbuf, index_extrbuf, otype);
+*/
+    init_multiplex(&mx, &seq_head, extframe, ac3frame, ext_count /*audio pids */, ac3_count /* ac3 streams */,
+                   video_delay, audio_delay, fd_out, fill_buffers,
+                   &vrbuf, &index_vrbuf, extrbuf, index_extrbuf,
+                   ac3extrbuf, index_ac3extrbuf,
+		   otype);
+
+    VERBOSE(MPF_RPLXQUEUE, QString("  Finished:  init_multiplex "));
     setup_multiplex(&mx);
+    VERBOSE(MPF_RPLXQUEUE, QString("  Finished:  setup_multiplex "));
 
     while (1)
     {
-        check_times( &mx, &video_ok, ext_ok, &start);
-        write_out_packs( &mx, video_ok, ext_ok);
+        check_times( &mx, &video_ok, ext_ok, ac3_ok, &start);
+        VERBOSE(MPF_RPLXQUEUE, QString("  vid_ok: %1 ext_ok: %2  ac3_ok: %3  ")
+			.arg(video_ok).arg(ext_ok[0]).arg(ac3_ok[0]));
+        write_out_packs( &mx, video_ok, ext_ok, ac3_ok);
     }
 }
 
@@ -569,28 +592,29 @@
 
     memset(rx.exttype, 0, sizeof(rx.exttype));
     memset(rx.exttypcnt, 0, sizeof(rx.exttypcnt));
-    int mp2_count = 0, ac3_count = 0;
     for (QMap<int, Q3PtrList<MPEG2frame> >::iterator it = aFrame.begin();
             it != aFrame.end(); it++)
     {
         int i = aud_map[it.key()];
         char *lang = inputFC->streams[it.key()]->language;
-        ring_init(&rx.extrbuf[i], memsize / 5);
-        ring_init(&rx.index_extrbuf[i], INDEX_BUF);
-        rx.extframe[i].set = 1;
-        rx.extframe[i].bit_rate = getCodecContext(it.key())->bit_rate;
-        rx.extframe[i].framesize = it.data().first()->pkt.size;
-        strncpy(rx.extframe[i].language, lang, 4);
         switch(GetStreamType(it.key()))
         {
             case CODEC_ID_MP2:
             case CODEC_ID_MP3:
-                rx.exttype[i] = 2;
-                rx.exttypcnt[i] = mp2_count++;
+                ring_init(&rx.extrbuf[i], memsize / 5);
+                ring_init(&rx.index_extrbuf[i], INDEX_BUF);
+                memset(&rx.extframe[i], 0, sizeof(audio_frame_t));
+                rx.extframe[i].set = 1;
+                rx.extframe[i].bit_rate = getCodecContext(it.key())->bit_rate;
+                rx.extframe[i].framesize = it.data().first()->pkt.size;
                 break;
             case CODEC_ID_AC3:
-                rx.exttype[i] = 1;
-                rx.exttypcnt[i] = ac3_count++;
+                ring_init(&rx.ac3extrbuf[i], memsize / 5);
+                ring_init(&rx.index_ac3extrbuf[i], INDEX_BUF);
+                memset(&rx.ac3frame[i], 0, sizeof(audio_frame_t));
+                rx.ac3frame[i].set = 1;
+                rx.ac3frame[i].bit_rate = getCodecContext(it.key())->bit_rate;
+                rx.ac3frame[i].framesize = it.data().first()->pkt.size;
                 break;
         }
     }
@@ -601,6 +625,7 @@
                          26999999ULL) / vFrame.first()->mpeg2_seq.frame_period;
 
     rx.ext_count = ext_count;
+    rx.ac3_count = ac3_count;
 }
 
 void MPEG2fixup::FrameInfo(MPEG2frame *f)
@@ -616,6 +641,13 @@
             msg += QString(" %2")
                    .arg(ring_free(&rx.index_extrbuf[i]) / sizeof(index_unit));
     }
+    if (ac3_count)
+    {
+        msg += " AC3:";
+        for (int i = 0; i < ac3_count; i++)
+            msg += QString(" %2")
+                   .arg(ring_free(&rx.index_ac3extrbuf[i]) / sizeof(index_unit));
+    }
     VERBOSE(MPF_RPLXQUEUE, msg);
 }
 
@@ -640,9 +672,17 @@
         iu.frame_off = f->framePos - f->pkt.data;
         iu.dts = f->pkt.dts * 300;
     }
+    else if (GetStreamType(id) == CODEC_ID_AC3)
+    {
+        //VERBOSE(MPF_IMPORTANT, QString("Ringbuffer AC3 stream: %1 aud_map: %2 size: %3 "
+        //                           ).arg(id).arg(aud_map[id]).arg(f->pkt.size));
+        rb = &rx.ac3extrbuf[aud_map[id]];
+        rbi = &rx.index_ac3extrbuf[aud_map[id]];
+        iu.framesize = f->pkt.size;
+    }
     else if (GetStreamType(id) == CODEC_ID_MP2 ||
-             GetStreamType(id) == CODEC_ID_MP3 ||
-             GetStreamType(id) == CODEC_ID_AC3)
+             GetStreamType(id) == CODEC_ID_MP3 /* ||
+             GetStreamType(id) == CODEC_ID_AC3 */)
     {
         rb = &rx.extrbuf[aud_map[id]];
         rbi = &rx.index_extrbuf[aud_map[id]];
@@ -675,6 +715,11 @@
                     ring_avail(&rx.index_extrbuf[i]) < sizeof(index_unit))
                 ok = 0;
 
+        for (i = 0; i < ac3_count; i++)
+            if (rbi != &rx.index_ac3extrbuf[i] &&
+                    ring_avail(&rx.index_ac3extrbuf[i]) < sizeof(index_unit))
+                ok = 0;
+
         if (! ok && ring_free(rb) < (unsigned int)f->pkt.size &&
                     ring_free(rbi) >= sizeof(index_unit))
         {
@@ -682,8 +727,8 @@
             unsigned int inc_size = 10*(unsigned int)f->pkt.size;
             VERBOSE(MPF_IMPORTANT, QString("Increasing ringbuffer size by %1 "
                                    "to avoid deadlock").arg(inc_size));
-            if (! ring_reinit(rb, rb->size + inc_size))
-                ok = 1;
+            //if (! ring_reinit(rb, rb->size + inc_size))
+            //    ok = 1;
         }
         if (! ok)
         {
@@ -777,7 +822,12 @@
                             "Skipping invalid audio stream: %1").arg(i));
                     break;
                 }
-                if (inputFC->streams[i]->codec->codec_id == CODEC_ID_AC3 ||
+                if (inputFC->streams[i]->codec->codec_id == CODEC_ID_AC3)
+	        {
+                    aud_map[i] = ac3_count++;
+                    aFrame[i] = Q3PtrList<MPEG2frame> ();
+		}
+		else if (/* inputFC->streams[i]->codec->codec_id == CODEC_ID_AC3 || */
                     inputFC->streams[i]->codec->codec_id == CODEC_ID_MP3 ||
                     inputFC->streams[i]->codec->codec_id == CODEC_ID_MP2)
                 {
@@ -1397,8 +1447,14 @@
                 }
                 if (delta < 0 && af->count() > 1)
                 {
-                    if (cmp2x33(af->next()->pkt.pts,
-                                vFrame.first()->pkt.pts) > 0)
+		    int aud_cmp = cmp2x33(af->next()->pkt.pts, vFrame.first()->pkt.pts);
+
+                    VERBOSE(MPF_PROCESS,
+                                QString("Looking for A packet from stream %1  delta %2 cmp2x33 %3")
+                                        .arg(it.key()).arg(delta).arg(aud_cmp));
+                    //if (cmp2x33(af->next()->pkt.pts,
+                    //            vFrame.first()->pkt.pts) > 0)
+		    if (aud_cmp > 0)
                     {
                         VERBOSE(MPF_PROCESS, QString("Found useful audio "
                                 "frame from stream %1").arg(it.key()));
@@ -1408,7 +1464,7 @@
                     else
                     {
                         VERBOSE(MPF_PROCESS,
-                                QString("Dropping A packet from stream %1")
+                                QString("2 Dropping A packet from stream %1")
                                        .arg(it.key()));
                         framePool.enqueue( af->first());
                         af->removeFirst();
@@ -1859,10 +1915,10 @@
     {
         Q3PtrList<MPEG2frame> *af = &it.data();
         deltaPTS = diff2x33(vFrame.current()->pkt.pts, af->first()->pkt.pts);
-        VERBOSE(MPF_GENERAL, QString("#%1 PTS:%2 Delta: %3ms queue: %4")
+        VERBOSE(MPF_GENERAL, QString("#%1 PTS:%2 Delta: %3ms queue: %4 initPTS: %5")
                              .arg(it.key())
                              .arg(PtsTime(af->current()->pkt.pts))
-                             .arg(1000.0*deltaPTS / 90000.0).arg(af->count()));
+                             .arg(1000.0*deltaPTS / 90000.0).arg(af->count()).arg(PtsTime(initPTS)));
 
         if (cmp2x33(af->current()->pkt.pts, initPTS) < 0)
             initPTS = af->current()->pkt.pts;
@@ -1971,9 +2027,11 @@
                 // beforehand
                 if (PTSdiscrep && ! file_end)
                 {
+                    VERBOSE(MPF_IMPORTANT, QString("Detected PTS Discrepency "));
+
                     int pos = vFrame.count();
                     int count = Lreorder.count();
-                    while (vFrame.count() - frame_pos - count < 20 && !file_end)
+                    while (vFrame.count() - frame_pos - count < 40 && !file_end)
                         if ((ret = GetFrame(&pkt)) < 0)
                             return ret;
                     if (! file_end)
@@ -1995,6 +2053,7 @@
                                            tmpPTSdiscrep, numframes, false);
                                 if (!tmpPTSdiscrep)
                                 {
+                                    VERBOSE(MPF_IMPORTANT, QString("Fixed a temporary PTS discrepency, moving on... "));
                                     //discrepancy was short-lived, continue on
                                     done = true;
                                     PTSdiscrep = 0;
@@ -2003,6 +2062,7 @@
                                 if (tmpPTSdiscrep != (int64_t)AV_NOPTS_VALUE &&
                                     tmpPTSdiscrep != PTSdiscrep)
                                     PTSdiscrep = tmpPTSdiscrep;
+                                    VERBOSE(MPF_IMPORTANT, QString("Severe PTS discrepency, deadlock imminent... "));
                             }
                             count += tmpReorder.count();
                         }
Index: main.cpp
===================================================================
--- main.cpp	(revision 18755)
+++ main.cpp	(working copy)
@@ -363,7 +363,7 @@
                 if(!strcmp(a.argv()[argpos + 1], "dvd"))
                     otype = REPLEX_DVD;
                 if(!strcmp(a.argv()[argpos + 1], "ts"))
-                    otype = REPLEX_TS_SD;
+                    otype = REPLEX_HDTV;
 
                 ++argpos;
             }
Index: mpeg2fix.h
===================================================================
--- mpeg2fix.h	(revision 18755)
+++ mpeg2fix.h	(working copy)
@@ -113,15 +113,19 @@
     int otype;
     ringbuffer vrbuf;
     ringbuffer extrbuf[N_AUDIO];
+    ringbuffer ac3extrbuf[N_AUDIO];
     ringbuffer index_vrbuf;
     ringbuffer index_extrbuf[N_AUDIO];
+    ringbuffer index_ac3extrbuf[N_AUDIO];
     int ext_count;
+    int ac3_count;
     int exttype[N_AUDIO];
     int exttypcnt[N_AUDIO];
 
     pthread_mutex_t mutex;
     pthread_cond_t cond;
     audio_frame_t extframe[N_AUDIO];
+    audio_frame_t ac3frame[N_AC3];
     sequence_t seq_head;
 
   private:
@@ -235,6 +239,7 @@
     AVFormatContext *inputFC;
     int vid_id;
     int ext_count;
+    int ac3_count;
     QMap <int, int> aud_map;
     int aud_stream_count;
     int64_t ptsIncrement;
