diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index d4dd4ab..dc1b68f 100644
--- a/libavformat/mpegtsenc.c
+++ b/libavformat/mpegtsenc.c
@@ -87,6 +87,7 @@ typedef struct MpegTSWrite {
     int64_t next_pcr;
     int mux_rate; ///< set to 1 when VBR
     int pes_payload_size;
+    int pes_payload_max;
 
     int transport_stream_id;
     int original_network_id;
@@ -96,6 +97,7 @@ typedef struct MpegTSWrite {
     int pmt_start_pid;
     int start_pid;
     int m2ts_mode;
+    int parallel_mux;
 
     int pcr_period;
 #define MPEGTS_FLAG_REEMIT_PAT_PMT  0x01
@@ -117,6 +119,7 @@ typedef struct MpegTSWrite {
 /* a PES packet header is generated every DEFAULT_PES_HEADER_FREQ packets */
 #define DEFAULT_PES_HEADER_FREQ  16
 #define DEFAULT_PES_PAYLOAD_SIZE ((DEFAULT_PES_HEADER_FREQ - 1) * 184 + 170)
+#define MAX_PES_PAYLOAD 2 * 200 * 1024  // From mpegts.c
 
 /* The section length is 12 bits. The first 2 are set to 0, the remaining
  * 10 bits should not exceed 1021. */
@@ -229,11 +232,18 @@ typedef struct MpegTSWriteStream {
     int cc;
     int discontinuity;
     int payload_size;
+    int payload_top;
+    int stream_id;
     int first_pts_check; ///< first pts check needed
     int prev_payload_key;
     int64_t payload_pts;
     int64_t payload_dts;
     int payload_flags;
+    int pes_flags;
+#define PES_FLAG_READY      0x01
+#define PES_FLAG_START      0x02
+#define PES_FLAG_PARTIAL    0x04
+#define PES_FLAG_NEEDS_END  0x08
     uint8_t *payload;
     AVFormatContext *amux;
 
@@ -905,7 +915,8 @@ static int mpegts_init(AVFormatContext *s)
 
         avpriv_set_pts_info(st, 33, 1, 90000);
 
-        ts_st->payload = av_mallocz(ts->pes_payload_size);
+        ts->pes_payload_max = FFMAX(MAX_PES_PAYLOAD, ts->pes_payload_size);
+        ts_st->payload = av_mallocz(ts->parallel_mux ? ts->pes_payload_max : ts->pes_payload_size);
         if (!ts_st->payload) {
             ret = AVERROR(ENOMEM);
             goto fail;
@@ -940,6 +951,9 @@ static int mpegts_init(AVFormatContext *s)
         pids[i]                = ts_st->pid;
         ts_st->payload_pts     = AV_NOPTS_VALUE;
         ts_st->payload_dts     = AV_NOPTS_VALUE;
+        ts_st->payload_top     = 0;
+        ts_st->stream_id       = -1;
+        ts_st->pes_flags       = 0;
         ts_st->first_pts_check = 1;
         ts_st->cc              = 15;
         ts_st->discontinuity   = ts->flags & MPEGTS_FLAG_DISCONT;
@@ -1167,15 +1181,17 @@ static uint8_t *get_ts_payload_start(uint8_t *pkt)
 /* Add a PES header to the front of the payload, and segment into an integer
  * number of TS packets. The final TS packet is padded using an oversized
  * adaptation header to exactly fill the last TS packet.
- * NOTE: 'payload' contains a complete PES payload. */
-static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
+ * NOTE: 'payload' contains a complete PES payload, or a partial chunk when
+ *       the writing of the PES packet has already begun. */
+static int mpegts_write_pes(AVFormatContext *s, AVStream *st,
                              const uint8_t *payload, int payload_size,
-                             int64_t pts, int64_t dts, int key, int stream_id)
+                             int64_t pts, int64_t dts, int key)
 {
     MpegTSWriteStream *ts_st = st->priv_data;
     MpegTSWrite *ts = s->priv_data;
     uint8_t buf[TS_PACKET_SIZE];
     uint8_t *q;
+    int ret_size = 0;
     int val, is_start, len, header_len, write_pcr, is_dvb_subtitle, is_dvb_teletext, flags;
     int afc_len, stuffing_len;
     int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE);
@@ -1186,7 +1202,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
         force_pat = 1;
     }
 
-    is_start = 1;
+    is_start = !!(ts_st->pes_flags & PES_FLAG_START);
     while (payload_size > 0) {
         int64_t pcr = -1; /* avoid warning */
 
@@ -1297,9 +1313,9 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
                        st->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
                 *q++ = 0xbd;
             } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
-                *q++ = stream_id != -1 ? stream_id : 0xfc;
+                *q++ = ts_st->stream_id != -1 ? ts_st->stream_id : 0xfc;
 
-                if (stream_id == 0xbd) /* asynchronous KLV */
+                if (ts_st->stream_id == 0xbd) /* asynchronous KLV */
                     pts = dts = AV_NOPTS_VALUE;
             } else {
                 *q++ = 0xbd;
@@ -1400,12 +1416,15 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
                  * subtitle_stream_id: for DVB subtitle stream shall be identified by the value 0x00 */
                 *q++ = 0x20;
                 *q++ = 0x00;
+                /* It's required to add a final mark */
+                ts_st->pes_flags |= PES_FLAG_NEEDS_END;
             }
             if (is_dvb_teletext) {
                 memset(q, 0xff, pes_header_stuffing_bytes);
                 q += pes_header_stuffing_bytes;
             }
             is_start = 0;
+            ts_st->pes_flags &= ~PES_FLAG_START;
         }
         /* header size */
         header_len = q - buf;
@@ -1436,7 +1455,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
             }
         }
 
-        if (is_dvb_subtitle && payload_size == len) {
+        if ((ts_st->pes_flags & PES_FLAG_NEEDS_END) && payload_size == len) {
             memcpy(buf + TS_PACKET_SIZE - len, payload, len - 1);
             buf[TS_PACKET_SIZE - 1] = 0xff; /* end_of_PES_data_field_marker: an 8-bit field with fixed contents 0xff for DVB subtitle */
         } else {
@@ -1447,8 +1466,12 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
         payload_size -= len;
         mpegts_prefix_m2ts_header(s);
         avio_write(s->pb, buf, TS_PACKET_SIZE);
+        ret_size += len;
+        if (ts_st->pes_flags & PES_FLAG_PARTIAL)
+            break;
     }
     ts_st->prev_payload_key = key;
+    return ret_size;
 }
 
 int ff_check_h264_startcode(AVFormatContext *s, const AVStream *st, const AVPacket *pkt)
@@ -1535,6 +1558,83 @@ static int opus_get_packet_samples(AVFormatContext *s, AVPacket *pkt)
     return duration;
 }
 
+static inline void mpegts_write_full_pes_stream(AVFormatContext *s, AVStream *st, const uint8_t *payload)
+{
+    MpegTSWriteStream *ts_st = st->priv_data;
+    ts_st->pes_flags |= PES_FLAG_START;
+    ts_st->pes_flags &= ~PES_FLAG_PARTIAL;
+    mpegts_write_pes(s, st, payload,
+                    ts_st->payload_size,
+                    ts_st->payload_pts, ts_st->payload_dts,
+                    ts_st->payload_flags & AV_PKT_FLAG_KEY);
+    ts_st->payload_size = 0;
+    ts_st->payload_top  = 0;
+    ts_st->pes_flags    = 0;
+}
+
+static inline void mpegts_flush_pes_stream(AVFormatContext *s, AVStream *st, const uint8_t *payload)
+{
+    MpegTSWriteStream *ts_st = st->priv_data;
+    ts_st->pes_flags &= ~PES_FLAG_PARTIAL;
+    mpegts_write_pes(s, st, payload + ts_st->payload_top,
+                    ts_st->payload_size - ts_st->payload_top,
+                    ts_st->payload_pts, ts_st->payload_dts,
+                    ts_st->payload_flags & AV_PKT_FLAG_KEY);
+    ts_st->payload_size = 0;
+    ts_st->payload_top  = 0;
+    ts_st->pes_flags    = 0;
+}
+
+static inline void mpegts_write_partial_pes_stream(AVFormatContext *s, AVStream *st, const uint8_t *payload)
+{
+    MpegTSWriteStream *ts_st = st->priv_data;
+    MpegTSWrite *ts = s->priv_data;
+    if (ts_st->payload_size > ts->pes_payload_max) {
+        av_log(s, AV_LOG_WARNING, "PES packet oversized (%d), full sequential writing required\n", ts_st->payload_size);    
+        ts_st->pes_flags &= ~PES_FLAG_PARTIAL;
+    } else
+        ts_st->pes_flags |= PES_FLAG_PARTIAL;
+    ts_st->payload_top += mpegts_write_pes(s, st, payload + ts_st->payload_top,
+                                        ts_st->payload_size - ts_st->payload_top,
+                                        ts_st->payload_pts, ts_st->payload_dts,
+                                        ts_st->payload_flags & AV_PKT_FLAG_KEY);
+    if (ts_st->payload_size && ts_st->payload_size == ts_st->payload_top) {
+        ts_st->payload_size = 0;
+        ts_st->payload_top  = 0;
+        ts_st->pes_flags    = 0;
+    }
+}
+
+static inline void mpegts_start_partial_pes_stream(AVFormatContext *s, AVStream *st, const uint8_t *payload)
+{
+    MpegTSWriteStream *ts_st = st->priv_data;
+    ts_st->payload_top = 0;
+    ts_st->pes_flags |= PES_FLAG_START | PES_FLAG_READY;
+    mpegts_write_partial_pes_stream(s, st, payload);
+}
+
+static void write_side_pes_streams(AVFormatContext *s, int64_t dts, int64_t delay, int parallel)
+{
+    int i;
+    for(i=0; i<s->nb_streams; i++) {
+        AVStream *st2 = s->streams[i];
+        MpegTSWriteStream *ts_st2 = st2->priv_data;
+        if (   ts_st2->payload_size
+            && (ts_st2->payload_dts == AV_NOPTS_VALUE
+                || dts - ts_st2->payload_dts > delay/2
+                || (ts_st2->pes_flags & PES_FLAG_READY))) {
+            if (parallel) {
+                if (!(ts_st2->pes_flags & PES_FLAG_READY))
+                    mpegts_start_partial_pes_stream(s, st2, ts_st2->payload);
+                else
+                    mpegts_write_partial_pes_stream(s, st2, ts_st2->payload);
+            } else {
+                mpegts_write_full_pes_stream(s, st2, ts_st2->payload);
+            }
+        }
+    }
+}
+
 static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
 {
     AVStream *st = s->streams[pkt->stream_index];
@@ -1548,13 +1648,12 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
     int opus_samples = 0;
     int side_data_size;
     uint8_t *side_data = NULL;
-    int stream_id = -1;
 
     side_data = av_packet_get_side_data(pkt,
                                         AV_PKT_DATA_MPEGTS_STREAM_ID,
                                         &side_data_size);
     if (side_data)
-        stream_id = side_data[0];
+        ts_st->stream_id = side_data[0];
 
     if (ts->flags & MPEGTS_FLAG_REEMIT_PAT_PMT) {
         ts->pat_packet_count = ts->pat_packet_period - 1;
@@ -1749,52 +1848,66 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
     }
 
     if (pkt->dts != AV_NOPTS_VALUE) {
-        int i;
-        for(i=0; i<s->nb_streams; i++) {
-            AVStream *st2 = s->streams[i];
-            MpegTSWriteStream *ts_st2 = st2->priv_data;
-            if (   ts_st2->payload_size
-               && (ts_st2->payload_dts == AV_NOPTS_VALUE || dts - ts_st2->payload_dts > delay/2)) {
-                mpegts_write_pes(s, st2, ts_st2->payload, ts_st2->payload_size,
-                                 ts_st2->payload_pts, ts_st2->payload_dts,
-                                 ts_st2->payload_flags & AV_PKT_FLAG_KEY, stream_id);
-                ts_st2->payload_size = 0;
-            }
-        }
+        if (!ts->parallel_mux) {
+            /* In sequential mode first flush PES packets of other streams */
+            write_side_pes_streams(s, dts, delay, ts->parallel_mux);
+        } else while (ts_st->pes_flags & PES_FLAG_READY)
+            /* In parallel mode first write one PES chunk of every pending streams */
+            write_side_pes_streams(s, dts, delay, ts->parallel_mux);
     }
 
+    /* Complete the PES packet if it's time to do it
+     * (incoming data will go into another PES packet) */
     if (ts_st->payload_size && (ts_st->payload_size + size > ts->pes_payload_size ||
         (dts != AV_NOPTS_VALUE && ts_st->payload_dts != AV_NOPTS_VALUE &&
          av_compare_ts(dts - ts_st->payload_dts, st->time_base,
                        s->max_delay, AV_TIME_BASE_Q) >= 0) ||
         ts_st->opus_queued_samples + opus_samples >= 5760 /* 120ms */)) {
-        mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_size,
-                         ts_st->payload_pts, ts_st->payload_dts,
-                         ts_st->payload_flags & AV_PKT_FLAG_KEY, stream_id);
-        ts_st->payload_size = 0;
-        ts_st->opus_queued_samples = 0;
+        if (!ts->parallel_mux || ts_st->opus_queued_samples) {
+            mpegts_write_full_pes_stream(s, st, ts_st->payload);
+            ts_st->opus_queued_samples = 0;
+        } else {
+            mpegts_start_partial_pes_stream(s, st, ts_st->payload);
+            /* and write the entire pes packet interleaved until end */
+            while (ts_st->pes_flags & PES_FLAG_READY)
+                write_side_pes_streams(s, dts, delay, ts->parallel_mux);
+        }
     }
 
+    /* Complete the PES packet too with the incoming data when necessary */
     if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO || size > ts->pes_payload_size) {
         av_assert0(!ts_st->payload_size);
-        // for video and subtitle, write a single pes packet
-        mpegts_write_pes(s, st, buf, size, pts, dts,
-                         pkt->flags & AV_PKT_FLAG_KEY, stream_id);
-        ts_st->opus_queued_samples = 0;
-        av_free(data);
-        return 0;
+        /* for video and subtitle, a single pes packet is required */
+        ts_st->payload_size  = size;
+        ts_st->payload_pts   = pts;
+        ts_st->payload_dts   = dts;
+        ts_st->payload_flags = pkt->flags;
+        if (!ts->parallel_mux || ts_st->opus_queued_samples) {
+            mpegts_write_full_pes_stream(s, st, buf);
+            ts_st->opus_queued_samples = 0;
+            goto free;
+        } else {
+            /* start writing the first part of this pes packet */
+            mpegts_start_partial_pes_stream(s, st, buf);
+            if (ts_st->payload_size == 0)
+                goto free;
+            ts_st->payload_size = 0;  // note: this value will be set later
+        }
     }
 
+    /* Start a new PES packet */
     if (!ts_st->payload_size) {
         ts_st->payload_pts   = pts;
         ts_st->payload_dts   = dts;
         ts_st->payload_flags = pkt->flags;
     }
 
+    /* Enqueue new data in the current PES packet */
     memcpy(ts_st->payload + ts_st->payload_size, buf, size);
     ts_st->payload_size += size;
     ts_st->opus_queued_samples += opus_samples;
 
+free:
     av_free(data);
 
     return 0;
@@ -1809,9 +1922,9 @@ static void mpegts_write_flush(AVFormatContext *s)
         AVStream *st = s->streams[i];
         MpegTSWriteStream *ts_st = st->priv_data;
         if (ts_st->payload_size > 0) {
-            mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_size,
-                             ts_st->payload_pts, ts_st->payload_dts,
-                             ts_st->payload_flags & AV_PKT_FLAG_KEY, -1);
+            if (!ts_st->pes_flags)
+                ts_st->pes_flags |= PES_FLAG_START;
+            mpegts_flush_pes_stream(s, st, ts_st->payload);
             ts_st->payload_size = 0;
             ts_st->opus_queued_samples = 0;
         }
@@ -1929,6 +2042,9 @@ static const AVOption options[] = {
     { "mpegts_m2ts_mode", "Enable m2ts mode.",
       offsetof(MpegTSWrite, m2ts_mode), AV_OPT_TYPE_BOOL,
       { .i64 = -1 }, -1, 1, AV_OPT_FLAG_ENCODING_PARAM },
+    { "mpegts_interleave_mux", "Enable interleaved (non-sequential) muxing mode.",
+      offsetof(MpegTSWrite, parallel_mux), AV_OPT_TYPE_BOOL,
+      { .i64 = 0 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM },
     { "muxrate", NULL,
       offsetof(MpegTSWrite, mux_rate), AV_OPT_TYPE_INT,
       { .i64 = 1 }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
