Index: mpegenc.c
===================================================================
--- mpegenc.c	(revision 2027)
+++ mpegenc.c	(working copy)
@@ -31,27 +31,8 @@
 #undef NDEBUG
 #include <assert.h>
 
-typedef struct {
-    int packet_size; /* required packet size */
-    int packet_number;
-    int pack_header_freq;     /* frequency (in packets^-1) at which we send pack headers */
-    int system_header_freq;
-    int system_header_size;
-    int mux_rate; /* bitrate in units of 50 bytes/s */
-    /* stream info */
-    int audio_bound;
-    int video_bound;
-    int is_mpeg2;
-    int is_vcd;
-    int is_svcd;
-    int is_dvd;
-    int64_t last_scr; /* current system clock */
 
-    double vcd_padding_bitrate; //FIXME floats
-    int64_t vcd_padding_bytes_written;
 
-} MpegMuxContext;
-
 extern AVOutputFormat mpeg1vcd_muxer;
 extern AVOutputFormat mpeg2dvd_muxer;
 extern AVOutputFormat mpeg2svcd_muxer;
@@ -266,11 +247,12 @@
 static int mpeg_mux_init(AVFormatContext *ctx)
 {
     MpegMuxContext *s = ctx->priv_data;
-    int bitrate, i, mpa_id, mpv_id, mps_id, ac3_id, dts_id, lpcm_id, j;
+    int bitrate, i, j;
     AVStream *st;
     PESStream *stream;
     int audio_bitrate;
     int video_bitrate;
+    int ps_flag = 1;
 
     s->packet_number = 0;
     s->is_vcd =   (ENABLE_MPEG1VCD_MUXER  && ctx->oformat == &mpeg1vcd_muxer);
@@ -290,75 +272,10 @@
 
     s->audio_bound = 0;
     s->video_bound = 0;
-    mpa_id = AUDIO_ID;
-    ac3_id = AC3_ID;
-    dts_id = DTS_ID;
-    mpv_id = VIDEO_ID;
-    mps_id = SUB_ID;
-    lpcm_id = LPCM_ID;
-    for(i=0;i<ctx->nb_streams;i++) {
-        st = ctx->streams[i];
-        stream = av_mallocz(sizeof(PESStream));
-        if (!stream)
-            goto fail;
-        st->priv_data = stream;
+    
+    if(ff_pes_muxer_init(s,ps_flag) != 0)
+        goto fail;
 
-        av_set_pts_info(st, 64, 1, 90000);
-
-        switch(st->codec->codec_type) {
-        case CODEC_TYPE_AUDIO:
-            if (st->codec->codec_id == CODEC_ID_AC3) {
-                stream->id = ac3_id++;
-            } else if (st->codec->codec_id == CODEC_ID_DTS) {
-                stream->id = dts_id++;
-            } else if (st->codec->codec_id == CODEC_ID_PCM_S16BE) {
-                stream->id = lpcm_id++;
-                for(j = 0; j < 4; j++) {
-                    if (lpcm_freq_tab[j] == st->codec->sample_rate)
-                        break;
-                }
-                if (j == 4)
-                    goto fail;
-                if (st->codec->channels > 8)
-                    return -1;
-                stream->lpcm_header[0] = 0x0c;
-                stream->lpcm_header[1] = (st->codec->channels - 1) | (j << 4);
-                stream->lpcm_header[2] = 0x80;
-                stream->lpcm_align = st->codec->channels * 2;
-            } else {
-                stream->id = mpa_id++;
-            }
-
-            /* This value HAS to be used for VCD (see VCD standard, p. IV-7).
-               Right now it is also used for everything else.*/
-            stream->max_buffer_size = 4 * 1024;
-            s->audio_bound++;
-            break;
-        case CODEC_TYPE_VIDEO:
-            stream->id = mpv_id++;
-            if (st->codec->rc_buffer_size)
-                stream->max_buffer_size = 6*1024 + st->codec->rc_buffer_size/8;
-            else
-                stream->max_buffer_size = 230*1024; //FIXME this is probably too small as default
-#if 0
-                /* see VCD standard, p. IV-7*/
-                stream->max_buffer_size = 46 * 1024;
-            else
-                /* This value HAS to be used for SVCD (see SVCD standard, p. 26 V.2.3.2).
-                   Right now it is also used for everything else.*/
-                stream->max_buffer_size = 230 * 1024;
-#endif
-            s->video_bound++;
-            break;
-        case CODEC_TYPE_SUBTITLE:
-            stream->id = mps_id++;
-            stream->max_buffer_size = 16 * 1024;
-            break;
-        default:
-            return -1;
-        }
-        av_fifo_init(&stream->fifo, 16);
-    }
     bitrate = 0;
     audio_bitrate = 0;
     video_bitrate = 0;
@@ -712,84 +629,12 @@
     packet_size -= pad_packet_bytes + zero_trail_bytes;
 
     if (packet_size > 0) {
+        int ps_flag = 1;
+        ff_pes_cal_header(ps_flag,s,id,stream,
+          &packet_size,&header_len,&pts,&dts,
+          &payload_size,&startcode,&stuffing_size,
+          &trailer_size,&pad_packet_bytes);
 
-        /* packet header size */
-        packet_size -= 6;
-
-        /* packet header */
-        if (s->is_mpeg2) {
-            header_len = 3;
-            if (stream->packet_number==0)
-                header_len += 3; /* PES extension */
-            header_len += 1; /* obligatory stuffing byte */
-        } else {
-            header_len = 0;
-        }
-        if (pts != AV_NOPTS_VALUE) {
-            if (dts != pts)
-                header_len += 5 + 5;
-            else
-                header_len += 5;
-        } else {
-            if (!s->is_mpeg2)
-                header_len++;
-        }
-
-        payload_size = packet_size - header_len;
-        if (id < 0xc0) {
-            startcode = PRIVATE_STREAM_1;
-            payload_size -= 1;
-            if (id >= 0x40) {
-                payload_size -= 3;
-                if (id >= 0xa0)
-                    payload_size -= 3;
-            }
-        } else {
-            startcode = 0x100 + id;
-        }
-
-        stuffing_size = payload_size - av_fifo_size(&stream->fifo);
-
-        // first byte does not fit -> reset pts/dts + stuffing
-        if(payload_size <= trailer_size && pts != AV_NOPTS_VALUE){
-            int timestamp_len=0;
-            if(dts != pts)
-                timestamp_len += 5;
-            if(pts != AV_NOPTS_VALUE)
-                timestamp_len += s->is_mpeg2 ? 5 : 4;
-            pts=dts= AV_NOPTS_VALUE;
-            header_len -= timestamp_len;
-            if (s->is_dvd && stream->align_iframe) {
-                pad_packet_bytes += timestamp_len;
-                packet_size -= timestamp_len;
-            } else {
-                payload_size += timestamp_len;
-            }
-            stuffing_size += timestamp_len;
-            if(payload_size > trailer_size)
-                stuffing_size += payload_size - trailer_size;
-        }
-
-        if (pad_packet_bytes > 0 && pad_packet_bytes <= 7) { // can't use padding, so use stuffing
-            packet_size += pad_packet_bytes;
-            payload_size += pad_packet_bytes; // undo the previous adjustment
-            if (stuffing_size < 0) {
-                stuffing_size = pad_packet_bytes;
-            } else {
-                stuffing_size += pad_packet_bytes;
-            }
-            pad_packet_bytes = 0;
-        }
-
-        if (stuffing_size < 0)
-            stuffing_size = 0;
-        if (stuffing_size > 16) {    /*<=16 for MPEG-1, <=32 for MPEG-2*/
-            pad_packet_bytes += stuffing_size;
-            packet_size -= stuffing_size;
-            payload_size -= stuffing_size;
-            stuffing_size = 0;
-        }
-
         nb_frames= ff_pes_get_nb_frames(ctx, stream, payload_size - stuffing_size);
 
         put_be32(ctx->pb, startcode);
@@ -959,67 +804,9 @@
     int ignore_constraints=0;
     int64_t scr= s->last_scr;
     PacketDesc *timestamp_packet;
-    const int64_t max_delay= av_rescale(ctx->max_delay, 90000, AV_TIME_BASE);
 
-retry:
-    for(i=0; i<ctx->nb_streams; i++){
-        AVStream *st = ctx->streams[i];
-        PESStream *stream = st->priv_data;
-        const int avail_data=  av_fifo_size(&stream->fifo);
-        const int space= stream->max_buffer_size - stream->buffer_index;
-        int rel_space= 1024*space / stream->max_buffer_size;
-        PacketDesc *next_pkt= stream->premux_packet;
-
-        /* for subtitle, a single PES packet must be generated,
-           so we flush after every single subtitle packet */
-        if(s->packet_size > avail_data && !flush
-           && st->codec->codec_type != CODEC_TYPE_SUBTITLE)
-            return 0;
-        if(avail_data==0)
-            continue;
-        assert(avail_data>0);
-
-        if(space < s->packet_size && !ignore_constraints)
-            continue;
-
-        if(next_pkt && next_pkt->dts - scr > max_delay)
-            continue;
-
-        if(rel_space > best_score){
-            best_score= rel_space;
-            best_i = i;
-            avail_space= space;
-        }
-    }
-
-    if(best_i < 0){
-        int64_t best_dts= INT64_MAX;
-
-        for(i=0; i<ctx->nb_streams; i++){
-            AVStream *st = ctx->streams[i];
-            PESStream *stream = st->priv_data;
-            PacketDesc *pkt_desc= stream->predecode_packet;
-            if(pkt_desc && pkt_desc->dts < best_dts)
-                best_dts= pkt_desc->dts;
-        }
-
-#if 0
-        av_log(ctx, AV_LOG_DEBUG, "bumping scr, scr:%f, dts:%f\n",
-               scr/90000.0, best_dts/90000.0);
-#endif
-        if(best_dts == INT64_MAX)
-            return 0;
-
-        if(scr >= best_dts+1 && !ignore_constraints){
-            av_log(ctx, AV_LOG_ERROR, "packet too large, ignoring buffer limits to mux it\n");
-            ignore_constraints= 1;
-        }
-        scr= FFMAX(best_dts+1, scr);
-        if(ff_pes_remove_decoded_packets(ctx, scr) < 0)
-            return -1;
-        goto retry;
-    }
-
+    if((result = ff_pes_find_beststream(ctx, s->packet_size, flush, &scr, &best_i)) <= 0)
+        return result;
     assert(best_i >= 0);
 
     st = ctx->streams[best_i];
@@ -1074,48 +861,8 @@
 
 static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt)
 {
-    MpegMuxContext *s = ctx->priv_data;
-    int stream_index= pkt->stream_index;
-    int size= pkt->size;
-    uint8_t *buf= pkt->data;
-    AVStream *st = ctx->streams[stream_index];
-    PESStream *stream = st->priv_data;
-    int64_t pts, dts;
-    PacketDesc *pkt_desc;
-    const int preload= av_rescale(ctx->preload, 90000, AV_TIME_BASE);
-    const int is_iframe = st->codec->codec_type == CODEC_TYPE_VIDEO && (pkt->flags & PKT_FLAG_KEY);
+    ff_pes_write_packet(ctx, pkt);
 
-    pts= pkt->pts;
-    dts= pkt->dts;
-
-    if(pts != AV_NOPTS_VALUE) pts += preload;
-    if(dts != AV_NOPTS_VALUE) dts += preload;
-
-//av_log(ctx, AV_LOG_DEBUG, "dts:%f pts:%f flags:%d stream:%d nopts:%d\n", dts/90000.0, pts/90000.0, pkt->flags, pkt->stream_index, pts != AV_NOPTS_VALUE);
-    if (!stream->premux_packet)
-        stream->next_packet = &stream->premux_packet;
-    *stream->next_packet=
-    pkt_desc= av_mallocz(sizeof(PacketDesc));
-    pkt_desc->pts= pts;
-    pkt_desc->dts= dts;
-    pkt_desc->unwritten_size=
-    pkt_desc->size= size;
-    if(!stream->predecode_packet)
-        stream->predecode_packet= pkt_desc;
-    stream->next_packet= &pkt_desc->next;
-
-    av_fifo_realloc(&stream->fifo, av_fifo_size(&stream->fifo) + size + 1);
-
-    if (s->is_dvd){
-        if (is_iframe && (s->packet_number == 0 || (pts - stream->vobu_start_pts >= 36000))) { // min VOBU length 0.4 seconds (mpucoder)
-            stream->bytes_to_iframe = av_fifo_size(&stream->fifo);
-            stream->align_iframe = 1;
-            stream->vobu_start_pts = pts;
-        }
-    }
-
-    av_fifo_write(&stream->fifo, buf, size);
-
     for(;;){
         int ret= output_packet(ctx, 0);
         if(ret<=0)
@@ -1126,29 +873,7 @@
 static int mpeg_mux_end(AVFormatContext *ctx)
 {
 //    MpegMuxContext *s = ctx->priv_data;
-    PESStream *stream;
-    int i;
-
-    for(;;){
-        int ret= output_packet(ctx, 1);
-        if(ret<0)
-            return ret;
-        else if(ret==0)
-            break;
-    }
-
-    /* End header according to MPEG1 systems standard. We do not write
-       it as it is usually not needed by decoders and because it
-       complicates MPEG stream concatenation. */
-    //put_be32(ctx->pb, ISO_11172_END_CODE);
-    //put_flush_packet(ctx->pb);
-
-    for(i=0;i<ctx->nb_streams;i++) {
-        stream = ctx->streams[i]->priv_data;
-
-        assert(av_fifo_size(&stream->fifo) == 0);
-        av_fifo_free(&stream->fifo);
-    }
+    ff_pes_muxer_end(s);
     return 0;
 }
 
Index: mpegpes.h
===================================================================
--- mpegpes.h	(revision 2027)
+++ mpegpes.h	(working copy)
@@ -61,7 +61,51 @@
     int64_t vobu_start_pts;
 } PESStream;
 
+/**
+ * PS stream structure
+ */
+typedef struct {
+    int packet_size; /* required packet size */
+    int packet_number;
+    int pack_header_freq;     /* frequency (in packets^-1) at which we send pack headers */
+    int system_header_freq;
+    int system_header_size;
+    int mux_rate; /* bitrate in units of 50 bytes/s */
+    /* stream info */
+    int audio_bound;
+    int video_bound;
+    int is_mpeg2;
+    int is_vcd;
+    int is_svcd;
+    int is_dvd;
+    int64_t last_scr; /* current system clock */
 
+    double vcd_padding_bitrate; //FIXME floats
+    int64_t vcd_padding_bytes_written;
+
+} MpegMuxContext;
+
+/**
+ * TS stream structure
+ */
+typedef struct MpegTSWrite {
+    MpegTSSection pat; /* MPEG2 pat table */
+    MpegTSSection sdt; /* MPEG2 sdt table context */
+    MpegTSService **services;
+    int sdt_packet_count;
+    int sdt_packet_freq;
+    int pat_packet_count;
+    int pat_packet_freq;
+    int nb_services;
+    int onid;
+    int tsid;
+    int packet_number;
+    int64_t last_pcr; /* last programme clock reference */
+    int64_t cur_pcr; /* current programme clock reference */
+    int mux_rate;
+    int packet_size;
+} MpegTSWrite;
+
 #define AUDIO_ID 0xc0
 #define VIDEO_ID 0xe0
 #define AC3_ID   0x80
@@ -79,9 +123,10 @@
 /**
  * Initialization of PES muxer.
  * @param[in] ctx the AVFormatContext which contains streams
+ * @param[in] ps_flag the flag is true when PS , false when TS
  * @return  On error a negative value is returned, on success zero.
  */
-int ff_pes_muxer_init(AVFormatContext *ctx);
+int ff_pes_muxer_init(AVFormatContext *ctx,int ps_flag);
 
 /**
  * Finalization of PES muxer.
@@ -118,6 +163,27 @@
 int ff_pes_get_nb_frames(AVFormatContext *ctx, PESStream *stream, int len);
 
 /**
+ * Caculate the PES header to flush
+ * @param[in] ps_flag    the sign for PS, '1' is PS, '0' is TS
+ * @param[in] s   the  stream poiter to PS or TS
+ * @param[in] id    the stream id
+ * @param[in] packet_size    the packet size for PES
+ * @param[in] header_len     the PES header length
+ * @param[in] pts    the PTS
+ * @param[in] dts   the DTS
+ * @param[in] payload_size the PES palyload size 
+ * @param[in] startcode  the startcode 
+ * @param[in]stuffing_size the  PES stuff  size
+ * @param[in] trailer_size the trailer_ size
+ * @param[in] pad_packet_bytes the padding size for packet
+ * @return  NULL
+ */
+void ff_pes_cal_header(int ps_flag,void* s,int id,PESStream * stream,
+          int *packet_size,int *header_len,int64_t *pts,int64_t *dts,
+          int *payload_size,int *startcode,int *stuffing_size,
+          int *trailer_size,int *pad_packet_bytes);
+
+/**
  * Mux one stream into PES stream.
  * @param [in]      ctx            the AVFormatContext which contains streams
  * @param [in]      stream_index   the stream index to write
Index: mpegpesenc.c
===================================================================
--- mpegpesenc.c	(revision 2027)
+++ mpegpesenc.c	(working copy)
@@ -28,12 +28,20 @@
  * @param[in] ctx the AVFormatContext which contains streams
  * @return  On error a negative value is returned, on success zero.
  */
-int ff_pes_muxer_init(AVFormatContext *ctx)
+int ff_pes_muxer_init(AVFormatContext *ctx,int ps_flag)
 {
     AVStream *st;
     PESStream *stream;
-    int i;
+    int i,j,mpa_id, mpv_id, mps_id, ac3_id, dts_id, lpcm_id;
+    MpegMuxContext *s = ctx->priv_data;
 
+    mpa_id = AUDIO_ID;
+    ac3_id = AC3_ID;
+    dts_id = DTS_ID;
+    mpv_id = VIDEO_ID;
+    mps_id = SUB_ID;
+    lpcm_id = LPCM_ID;
+
     for(i=0;i<ctx->nb_streams;i++) {
         st = ctx->streams[i];
         stream = st->priv_data;
@@ -41,11 +49,36 @@
 
         switch(st->codec->codec_type) {
         case CODEC_TYPE_AUDIO:
+            if(ps_flag){
+                if (st->codec->codec_id == CODEC_ID_AC3) {
+                    stream->id = ac3_id++;
+                } else if (st->codec->codec_id == CODEC_ID_DTS) {
+                    stream->id = dts_id++;
+                } else if (st->codec->codec_id == CODEC_ID_PCM_S16BE) {
+                    stream->id = lpcm_id++;
+                    for(j = 0; j < 4; j++) {
+                        if (lpcm_freq_tab[j] == st->codec->sample_rate)
+                           break;
+                    }
+                    if (j == 4)
+                        goto fail;
+                    if (st->codec->channels > 8)
+                        return -1;
+                    stream->lpcm_header[0] = 0x0c;
+                    stream->lpcm_header[1] = (st->codec->channels - 1) | (j << 4);
+                    stream->lpcm_header[2] = 0x80;
+                    stream->lpcm_align = st->codec->channels * 2;
+                } else {
+                    stream->id = mpa_id++;
+                }
+            }
             /* This value HAS to be used for VCD (see VCD standard, p. IV-7).
                Right now it is also used for everything else.*/
             stream->max_buffer_size = 4 * 1024;
+            s->audio_bound++;
             break;
         case CODEC_TYPE_VIDEO:
+            stream->id = mpv_id++;
             if (st->codec->rc_buffer_size)
                 stream->max_buffer_size = 6*1024 + st->codec->rc_buffer_size/8;
             else
@@ -58,8 +91,10 @@
                    Right now it is also used for everything else.*/
                 stream->max_buffer_size = 230 * 1024;
 #endif
+            s->video_bound++;
             break;
         case CODEC_TYPE_SUBTITLE:
+            stream->id = mps_id++;
             stream->max_buffer_size = 16 * 1024;
             break;
         default:
@@ -100,7 +135,121 @@
 
     return nb_frames;
 }
+/**
+ * Caculate the PES header to flush
+ * @param[in] ps_flag    the sign for PS, '1' is PS, '0' is TS
+ * @param[in] s   the  stream poiter to PS or TS
+ * @param[in] id    the stream id
+  * @param[in] packet_size    the packet size for PES
+  * @param[in] header_len     the PES header length
+  * @param[in] pts    the PTS
+  * @param[in] dts   the DTS
+  * @param[in] payload_size the PES palyload size 
+  * @param[in] startcode  the startcode 
+  * @param[in]stuffing_size the  PES stuff  size
+  * @param[in] trailer_size the trailer_ size
+  * @param[in] pad_packet_bytes the padding size for packet
+ * @return  NULL
+ */
+void ff_pes_cal_header(int ps_flag,void* s,int id,PESStream * stream,
+          int *packet_size,int *header_len,int64_t *pts,int64_t *dts,
+    int *payload_size,int *startcode,int *stuffing_size,
+          int *trailer_size,int *pad_packet_bytes)
+{
+     /* packet header size */
+        *packet_size -= 6;
 
+        /* packet header */
+        if (ps_flag == 0) {
+            *header_len = 3;
+            *header_len += 1; /* obligatory stuffing byte */
+        }else if (s->is_mpeg2){
+             *header_len = 3;
+             if (stream->packet_number==0)
+                 *header_len += 3; /* PES extension */
+             *header_len += 1; /* obligatory stuffing byte */
+        } else {
+              *header_len = 0;
+        }
+
+        if (*pts != AV_NOPTS_VALUE) {
+            if (*dts != *pts)
+                *header_len += 5 + 5;
+            else
+                *header_len += 5;
+        }else if (ps_flag){
+        if(!s->is_mpeg2)
+            *header_len++;
+        }
+
+        *payload_size = *packet_size - *header_len;
+        if(ps_flag){
+            if (id < 0xc0) {
+                *startcode = PRIVATE_STREAM_1;
+                *payload_size -= 1;
+                if (id >= 0x40) {
+                    *payload_size -= 3;
+                    if (id >= 0xa0)
+                        *payload_size -= 3;
+                }
+            } else {
+                  *startcode = 0x100 + id;
+            }
+        }
+        *stuffing_size = *payload_size - av_fifo_size(&stream->fifo);
+
+        // first byte does not fit -> reset pts/dts + stuffing
+        if(*payload_size <= *trailer_size && (*pts) != AV_NOPTS_VALUE){
+            int timestamp_len=0;
+            if(*dts != *pts)
+                timestamp_len += 5;
+            if(*pts != AV_NOPTS_VALUE){
+                if(ps_flag)
+                    timestamp_len += s->is_mpeg2 ? 5 : 4;
+                else
+                    timestamp_len += 5;
+            }
+            *pts=AV_NOPTS_VALUE;
+            *dts=AV_NOPTS_VALUE;
+
+            *header_len -= timestamp_len;
+            if(ps_flag){
+                if (s->is_dvd && stream->align_iframe){
+                    *pad_packet_bytes += timestamp_len;
+                    *packet_size -= timestamp_len;
+                }
+            } else {
+                *payload_size += timestamp_len;
+
+                *stuffing_size += timestamp_len;
+                if(*payload_size > *trailer_size)
+                    *stuffing_size += *payload_size - *trailer_size;
+            }
+        }
+
+        if(ps_flag){
+            if (*pad_packet_bytes > 0 && *pad_packet_bytes <= 7) { // can't use padding, so use stuffing
+                *packet_size += *pad_packet_bytes;
+                *payload_size += *pad_packet_bytes; // undo the previous adjustment
+                if (*stuffing_size < 0) {
+                    *stuffing_size = *pad_packet_bytes;
+                } else {
+                    *stuffing_size += *pad_packet_bytes;
+                }
+                *pad_packet_bytes = 0;
+            }
+        }
+
+        if (*stuffing_size < 0)
+            *stuffing_size = 0;
+        if (*stuffing_size > 16) {    /*<=16 for MPEG-1, <=32 for MPEG-2*/
+            *pad_packet_bytes += *stuffing_size;
+            *packet_size -= *stuffing_size;
+            *payload_size -= *stuffing_size;
+            *stuffing_size = 0;
+        }
+}
+
 /**
  * Mux one stream into PES stream.
  * @param [in]      ctx            the AVFormatContext which contains streams
@@ -287,7 +436,6 @@
             return -1;
         goto retry;
     }
-    assert(avail_space >= packet_size || ignore_constraints);
     return 1;
 }
 
@@ -299,6 +447,7 @@
  */
 void ff_pes_write_packet(AVFormatContext *ctx, AVPacket *pkt)
 {
+    MpegMuxContext *s = ctx->priv_data;
     int stream_index= pkt->stream_index;
     int size= pkt->size;
     uint8_t *buf= pkt->data;
@@ -307,6 +456,7 @@
     int64_t pts, dts;
     PacketDesc *pkt_desc;
     const int preload= av_rescale(ctx->preload, 90000, AV_TIME_BASE);
+    const int is_iframe = st->codec->codec_type == CODEC_TYPE_VIDEO && (pkt->flags & PKT_FLAG_KEY);
 
     pts= pkt->pts;
     dts= pkt->dts;
@@ -328,6 +478,13 @@
     stream->next_packet= &pkt_desc->next;
 
     av_fifo_realloc(&stream->fifo, av_fifo_size(&stream->fifo) + size + 1);
+    if (s->is_dvd){
+        if (is_iframe && (s->packet_number == 0 || (pts - stream->vobu_start_pts >= 36000))) { // min VOBU length 0.4 seconds (mpucoder)
+            stream->bytes_to_iframe = av_fifo_size(&stream->fifo);
+            stream->align_iframe = 1;
+            stream->vobu_start_pts = pts;
+        }
+    }
     av_fifo_write(&stream->fifo, buf, size);
 }
 
@@ -341,6 +498,13 @@
     PESStream *stream;
     int i;
 
+     for(;;){
+        int ret= output_packet(ctx, 1);
+        if(ret<0)
+            return ret;
+        else if(ret==0)
+            break;
+    }
     for(i=0;i<ctx->nb_streams;i++) {
         stream = ctx->streams[i]->priv_data;
 
Index: mpegtsenc.c
===================================================================
--- mpegtsenc.c	(revision 2027)
+++ mpegtsenc.c	(working copy)
@@ -174,24 +174,6 @@
     int pcr_pid;
 } MpegTSService;
 
-typedef struct MpegTSWrite {
-    MpegTSSection pat; /* MPEG2 pat table */
-    MpegTSSection sdt; /* MPEG2 sdt table context */
-    MpegTSService **services;
-    int sdt_packet_count;
-    int sdt_packet_freq;
-    int pat_packet_count;
-    int pat_packet_freq;
-    int nb_services;
-    int onid;
-    int tsid;
-    int packet_number;
-    int64_t last_pcr; /* last programme clock reference */
-    int64_t cur_pcr; /* current programme clock reference */
-    int mux_rate;
-    int packet_size;
-} MpegTSWrite;
-
 static void mpegts_write_pat(AVFormatContext *s)
 {
     MpegTSWrite *ts = s->priv_data;
@@ -386,6 +368,7 @@
     AVStream *st;
     int bitrate;
     int i;
+    int ps_flag = 0;
     const char *service_name;
 
     ts->tsid = DEFAULT_TSID;
@@ -446,7 +429,7 @@
         service->pcr_pid = ts_st->pid;
     }
 
-    if(ff_pes_muxer_init(s) != 0)
+    if(ff_pes_muxer_init(s,ps_flag) != 0)
         goto fail;
 
     bitrate = 0;
@@ -635,45 +618,11 @@
     packet_size = s->packet_size;
 
     if (packet_size > 0) {
-        /* packet header size */
-        packet_size -= 6;
-
-        /* packet header */
-        header_len = 3;
-        header_len += 1; /* obligatory stuffing byte */
-        if (pts != AV_NOPTS_VALUE) {
-            if (dts != pts)
-                header_len += 5 + 5;
-            else
-                header_len += 5;
-        }
-        payload_size = packet_size - header_len;
-
-        stuffing_size = payload_size - av_fifo_size(&pes_stream->fifo);
-
-        // first byte does not fit -> reset pts/dts + stuffing
-        if(payload_size <= trailer_size && pts != AV_NOPTS_VALUE){
-            int timestamp_len=0;
-            if(dts != pts)
-                timestamp_len += 5;
-            if(pts != AV_NOPTS_VALUE)
-                timestamp_len += 5;
-            pts=dts= AV_NOPTS_VALUE;
-            header_len -= timestamp_len;
-            payload_size += timestamp_len;
-            stuffing_size += timestamp_len;
-            if(payload_size > trailer_size)
-                stuffing_size += payload_size - trailer_size;
-        }
-
-        if (stuffing_size < 0)
-            stuffing_size = 0;
-        if (stuffing_size > 16) {    /*<=16 for MPEG-1, <=32 for MPEG-2*/
-            pad_packet_bytes += stuffing_size;
-            packet_size -= stuffing_size;
-            payload_size -= stuffing_size;
-            stuffing_size = 0;
-        }
+        int ps_flag = 0;
+        ff_pes_cal_header(ps_flag,s,id,stream,
+          &packet_size,&header_len,&pts,&dts,
+          &payload_size,&startcode,&stuffing_size,
+          &trailer_size,&pad_packet_bytes);
         pes_size = ff_pes_muxer_write(ctx, stream_index, stream->payload, pts, dts, id, stream->startcode, NULL, 0,
                  header_len, packet_size, payload_size, stuffing_size);
         if(pes_size < 0)
@@ -732,6 +681,7 @@
     stream = st->priv_data;
 
     assert(av_fifo_size(&stream->fifo) > 0);
+    assert(avail_space >= s->packet_size || ignore_constraints);
 
     timestamp_packet= stream->premux_packet;
     if(timestamp_packet->unwritten_size == timestamp_packet->size){
@@ -772,14 +722,6 @@
     MpegTSService *service;
     int i;
 
-    for(;;){
-        int ret= output_packet(s, 1);
-        if(ret<0)
-            return ret;
-        else if(ret==0)
-            break;
-    }
-
     ff_pes_muxer_end(s);
     for(i = 0; i < ts->nb_services; i++) {
         service = ts->services[i];
