update with-git-ffmpeg patches
authorGood Guy <good1.2guy@gmail.com>
Wed, 4 Dec 2019 01:48:07 +0000 (18:48 -0700)
committerGood Guy <good1.2guy@gmail.com>
Wed, 4 Dec 2019 01:48:07 +0000 (18:48 -0700)
cinelerra-5.1/ffmpeg/format/bluray
cinelerra-5.1/thirdparty/src/ffmpeg.git.patch0 [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/ffmpeg.git.patch1
cinelerra-5.1/thirdparty/src/ffmpeg.git.patch2
cinelerra-5.1/thirdparty/src/ffmpeg.git.patch3
cinelerra-5.1/thirdparty/src/ffmpeg.git.patch4 [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/ffmpeg.git.patch5 [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/ffmpeg.git.patch6 [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/ffmpeg.git.patch7
cinelerra-5.1/thirdparty/src/ffmpeg.git.patch8 [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/ffmpeg.git.patch9 [new file with mode: 0644]

index abb1589b160dabb14e054860a46c4420653f8cea..0a951fb3f574b8e62dbc2a1302769ac79d078f2a 100644 (file)
@@ -1,6 +1,5 @@
 mpegts
 mpegts_m2ts_mode=2
 mpegts
 mpegts_m2ts_mode=2
-mpegts_start_pid=1024
 mpegts_pmt_start_pid=256
 muxrate 1
 sdt_period=-1
 mpegts_pmt_start_pid=256
 muxrate 1
 sdt_period=-1
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg.git.patch0 b/cinelerra-5.1/thirdparty/src/ffmpeg.git.patch0
new file mode 100644 (file)
index 0000000..32c876e
--- /dev/null
@@ -0,0 +1,11 @@
+diff -urN a/fftools/cmdutils.c b/fftools/cmdutils.c
+--- a/fftools/cmdutils.c       2019-12-02 08:48:02.860360597 -0700
++++ b/fftools/cmdutils.c       2019-12-02 08:51:04.603975015 -0700
+@@ -1186,6 +1186,7 @@
+ void show_banner(int argc, char **argv, const OptionDef *options)
+ {
++    return;
+     int idx = locate_option(argc, argv, options, "version");
+     if (hide_banner || idx)
+         return;
index 831ea60f690cae5dcb149d9b4e02795cd36970ab..5ecef3c0604f62ea82aeaaee6402dc24d2944fe9 100644 (file)
@@ -1,6 +1,6 @@
 diff -urN a/libavformat/bluray.c b/libavformat/bluray.c
 diff -urN a/libavformat/bluray.c b/libavformat/bluray.c
---- a/libavformat/bluray.c     2018-04-13 17:34:28.000000000 -0600
-+++ b/libavformat/bluray.c     2018-04-24 11:02:19.724232178 -0600
+--- a/libavformat/bluray.c     2019-12-02 08:48:03.104361421 -0700
++++ b/libavformat/bluray.c     2019-12-02 08:51:33.187071639 -0700
 @@ -28,7 +28,7 @@
  #include "libavutil/opt.h"
  
 @@ -28,7 +28,7 @@
  #include "libavutil/opt.h"
  
index 1c1e293af6eabec3c3fbb93c388973779bd27b48..1d312469b1991d6b24373faa0d34638b743eda80 100644 (file)
@@ -1,65 +1,58 @@
 diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
 diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
-index fc0ea225c6..c702bc5f07 100644
 --- a/libavformat/mpegtsenc.c
 +++ b/libavformat/mpegtsenc.c
 --- a/libavformat/mpegtsenc.c
 +++ b/libavformat/mpegtsenc.c
-@@ -56,9 +56,8 @@ typedef struct MpegTSService {
+@@ -56,7 +56,8 @@ typedef struct MpegTSService {
      int sid;           /* service ID */
      uint8_t name[256];
      uint8_t provider_name[256];
 -    int pcr_pid;
      int sid;           /* service ID */
      uint8_t name[256];
      uint8_t provider_name[256];
 -    int pcr_pid;
--    int pcr_packet_count;
--    int pcr_packet_period;
-+    int64_t pcr, pcr_packet_timer, pcr_packet_period;
-+    int pcr_sid, pcr_pid;
++    int pcr_sid;       /* stream triggering pcr writes */
++    int pcr_pid;       /* pid of pcr stream */
      AVProgram *program;
  } MpegTSService;
  
      AVProgram *program;
  } MpegTSService;
  
-@@ -78,14 +77,12 @@ typedef struct MpegTSWrite {
-     MpegTSSection pat; /* MPEG-2 PAT table */
-     MpegTSSection sdt; /* MPEG-2 SDT table context */
-     MpegTSService **services;
--    int sdt_packet_count;
--    int sdt_packet_period;
--    int pat_packet_count;
--    int pat_packet_period;
-+    int64_t sdt_packet_timer, sdt_packet_period;
-+    int64_t pat_packet_timer, pat_packet_period;
+@@ -79,10 +80,8 @@ typedef struct MpegTSWrite {
+     int64_t sdt_period; /* SDT period in PCR time base */
+     int64_t pat_period; /* PAT/PMT period in PCR time base */
      int nb_services;
      int nb_services;
-     int onid;
-     int tsid;
+-    int onid;
+-    int tsid;
 -    int64_t first_pcr;
 -    int64_t first_pcr;
-+    int64_t pcr, first_pcr, delay;
+-    int64_t next_pcr;
++    int onid, tsid;
++    int64_t pcr, first_pcr, next_pcr, delay;
      int mux_rate; ///< set to 1 when VBR
      int pes_payload_size;
  
      int mux_rate; ///< set to 1 when VBR
      int pes_payload_size;
  
-@@ -95,12 +92,14 @@ typedef struct MpegTSWrite {
-     int service_type;
+@@ -94,8 +93,8 @@ typedef struct MpegTSWrite {
      int pmt_start_pid;
      int pmt_start_pid;
-+    int pcr_start_pid;
      int start_pid;
      int m2ts_mode;
 +    int64_t ts_offset;
  
      int start_pid;
      int m2ts_mode;
 +    int64_t ts_offset;
  
-     int reemit_pat_pmt; // backward compatibility
--    int pcr_period;
-+    double pcr_period;
+-    int pcr_period_ms;
  #define MPEGTS_FLAG_REEMIT_PAT_PMT  0x01
  #define MPEGTS_FLAG_AAC_LATM        0x02
  #define MPEGTS_FLAG_PAT_PMT_AT_FRAMES           0x04
  #define MPEGTS_FLAG_REEMIT_PAT_PMT  0x01
  #define MPEGTS_FLAG_AAC_LATM        0x02
  #define MPEGTS_FLAG_PAT_PMT_AT_FRAMES           0x04
-@@ -111,8 +110,6 @@ typedef struct MpegTSWrite {
+@@ -104,11 +103,11 @@ typedef struct MpegTSWrite {
+     int flags;
+     int copyts;
      int tables_version;
      int tables_version;
-     double pat_period;
-     double sdt_period;
+-    int64_t pat_period_us;
+-    int64_t sdt_period_us;
 -    int64_t last_pat_ts;
 -    int64_t last_pat_ts;
--    int64_t last_sdt_ts;
++    double pcr_period_ms;
++    double sdt_period_ms;
++    double pat_period_ms;
+     int64_t last_sdt_ts;
+-
++    int64_t last_pat_ts;
      int omit_video_pes_length;
  } MpegTSWrite;
      int omit_video_pes_length;
  } MpegTSWrite;
-@@ -222,10 +219,10 @@ static int mpegts_write_section1(MpegTSSection *s, int tid, int id,
+@@ -217,10 +216,10 @@ static int mpegts_write_section1(MpegTSSection *s, int tid, int id,
  #define DEFAULT_PROVIDER_NAME   "FFmpeg"
  #define DEFAULT_PROVIDER_NAME   "FFmpeg"
- #define DEFAULT_SERVICE_NAME    "Service01"
+ #define DEFAULT_SERVICE_NAME    "Service"
  
 -/* we retransmit the SI info at this rate */
 +/* we retransmit the SI info at this rate (ms) */
  
 -/* we retransmit the SI info at this rate */
 +/* we retransmit the SI info at this rate (ms) */
@@ -69,17 +62,18 @@ index fc0ea225c6..c702bc5f07 100644
 +#define PCR_RETRANS_TIME 50
  
  typedef struct MpegTSWriteStream {
 +#define PCR_RETRANS_TIME 50
  
  typedef struct MpegTSWriteStream {
-     struct MpegTSService *service;
-@@ -730,6 +727,7 @@ static MpegTSService *mpegts_add_service(AVFormatContext *s, int sid,
-     service->pmt.pid       = ts->pmt_start_pid + ts->nb_services;
-     service->sid           = sid;
-     service->pcr_pid       = 0x1fff;
-+    service->pcr_sid       = 0x1fff;
-     if (encode_str8(service->provider_name, provider_name) < 0 ||
-         encode_str8(service->name, name) < 0) {
-         av_log(s, AV_LOG_ERROR, "Too long service or provider name\n");
-@@ -744,18 +742,11 @@ fail:
-     return NULL;
+     int pid; /* stream associated pid */
+@@ -234,7 +233,7 @@ typedef struct MpegTSWriteStream {
+     int payload_flags;
+     uint8_t *payload;
+     AVFormatContext *amux;
+-
++    MpegTSService *service;
+     int64_t pcr_period; /* PCR period in PCR time base */
+     int64_t last_pcr;
+@@ -713,18 +712,11 @@ invalid:
+     return 0;
  }
  
 -static int64_t get_pcr(const MpegTSWrite *ts, AVIOContext *pb)
  }
  
 -static int64_t get_pcr(const MpegTSWrite *ts, AVIOContext *pb)
@@ -88,7 +82,7 @@ index fc0ea225c6..c702bc5f07 100644
 -           ts->first_pcr;
 -}
 -
 -           ts->first_pcr;
 -}
 -
- static void mpegts_prefix_m2ts_header(AVFormatContext *s)
+ static void write_packet(AVFormatContext *s, const uint8_t *packet)
  {
      MpegTSWrite *ts = s->priv_data;
      if (ts->m2ts_mode) {
  {
      MpegTSWrite *ts = s->priv_data;
      if (ts->m2ts_mode) {
@@ -98,15 +92,101 @@ index fc0ea225c6..c702bc5f07 100644
          tp_extra_header = AV_RB32(&tp_extra_header);
          avio_write(s->pb, (unsigned char *) &tp_extra_header,
                     sizeof(tp_extra_header));
          tp_extra_header = AV_RB32(&tp_extra_header);
          avio_write(s->pb, (unsigned char *) &tp_extra_header,
                     sizeof(tp_extra_header));
-@@ -776,6 +767,7 @@ static int mpegts_init(AVFormatContext *s)
-     MpegTSService *service;
-     AVStream *st, *pcr_st = NULL;
-     AVDictionaryEntry *title, *provider;
-+    double clk_rate;
-     int i, j;
-     const char *service_name;
-     const char *provider_name;
-@@ -784,6 +776,15 @@ static int mpegts_init(AVFormatContext *s)
+@@ -763,6 +755,7 @@ static MpegTSService *mpegts_add_service(AVFormatContext *s, int sid,
+     service->pmt.pid       = ts->pmt_start_pid + ts->nb_services;
+     service->sid           = sid;
+     service->pcr_pid       = 0x1fff;
++    service->pcr_sid       = 0x1fff;
+     if (encode_str8(service->provider_name, provider_name) < 0 ||
+         encode_str8(service->name, service_name) < 0) {
+         av_log(s, AV_LOG_ERROR, "Too long service or provider name\n");
+@@ -788,30 +781,32 @@ static void enable_pcr_generation_for_stream(AVFormatContext *s, AVStream *pcr_s
+     MpegTSWrite *ts = s->priv_data;
+     MpegTSWriteStream *ts_st = pcr_st->priv_data;
+-    if (ts->mux_rate > 1 || ts->pcr_period_ms >= 0) {
+-        int pcr_period_ms = ts->pcr_period_ms == -1 ? PCR_RETRANS_TIME : ts->pcr_period_ms;
+-        ts_st->pcr_period = av_rescale(pcr_period_ms, PCR_TIME_BASE, 1000);
+-    } else {
++    int64_t pcr_period = -1;
++    if (ts->pcr_period_ms >= 0)
++        pcr_period = av_rescale(ts->pcr_period_ms, PCR_TIME_BASE, 1000);
++    else if (ts->mux_rate == 1) {
+         /* By default, for VBR we select the highest multiple of frame duration which is less than 100 ms. */
+         int64_t frame_period = 0;
+         if (pcr_st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
+             int frame_size = av_get_audio_frame_duration2(pcr_st->codecpar, 0);
+-            if (!frame_size) {
++            if (frame_size > 0)
++               frame_period = av_rescale_rnd(frame_size, PCR_TIME_BASE, pcr_st->codecpar->sample_rate, AV_ROUND_UP);
++            else
+                av_log(s, AV_LOG_WARNING, "frame size not set\n");
+-               frame_size = 512;
+-            }
+-            frame_period = av_rescale_rnd(frame_size, PCR_TIME_BASE, pcr_st->codecpar->sample_rate, AV_ROUND_UP);
+         } else if (pcr_st->avg_frame_rate.num) {
+             frame_period = av_rescale_rnd(pcr_st->avg_frame_rate.den, PCR_TIME_BASE, pcr_st->avg_frame_rate.num, AV_ROUND_UP);
+         }
+-        if (frame_period > 0 && frame_period <= PCR_TIME_BASE / 10)
+-            ts_st->pcr_period = frame_period * (PCR_TIME_BASE / 10 / frame_period);
+-        else
+-            ts_st->pcr_period = 1;
++        if (frame_period > 0 && frame_period <= PCR_TIME_BASE / 10) {
++            int pcr_frames = (PCR_TIME_BASE / 10) / frame_period;
++            if( pcr_frames > 0 )
++                pcr_period = frame_period * pcr_frames;
++        }
+     }
+-
++    if( pcr_period < 0 ) 
++      pcr_period = av_rescale(PCR_RETRANS_TIME, PCR_TIME_BASE, 1000);
++    ts_st->pcr_period = pcr_period;
+     // output a PCR as soon as possible
+-    ts_st->last_pcr   = ts->first_pcr - ts_st->pcr_period;
++    ts_st->last_pcr   = ts->first_pcr - pcr_period;
+ }
+ static void select_pcr_streams(AVFormatContext *s)
+@@ -823,22 +818,32 @@ static void select_pcr_streams(AVFormatContext *s)
+         AVStream *pcr_st = NULL;
+         AVProgram *program = service->program;
+         int nb_streams = program ? program->nb_stream_indexes : s->nb_streams;
+-
++        /* find first video stream, or just use first stream */
+         for (int j = 0; j < nb_streams; j++) {
+             AVStream *st = s->streams[program ? program->stream_index[j] : j];
+-            if (!pcr_st ||
+-                pcr_st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
+-            {
++            if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
+                 pcr_st = st;
++                break;
+             }
+         }
+-
++        if (!pcr_st && s->nb_streams > 0)
++            pcr_st = s->streams[0];
+         if (pcr_st) {
+             MpegTSWriteStream *ts_st = pcr_st->priv_data;
+-            service->pcr_pid = ts_st->pid;
++            service->pcr_sid = ts_st->pid;  /* stream id for pcr writes */
++            service->pcr_pid = ts->m2ts_mode > 1 ? /* pcr pid */
++              0x1000 + ts->service_id : ts_st->pid;
+             enable_pcr_generation_for_stream(s, pcr_st);
+             av_log(s, AV_LOG_VERBOSE, "service %i using PCR in pid=%i, pcr_period=%"PRId64"ms\n",
+                 service->sid, service->pcr_pid, av_rescale(ts_st->pcr_period, 1000, PCR_TIME_BASE));
++            for (int j = 0; j < nb_streams; j++) {
++                AVStream *st = s->streams[program ? program->stream_index[j] : j];
++                MpegTSWriteStream *ts_st = st->priv_data;
++                ts_st->service = service;
++            }
++            if (service->pmt.pid == service->pcr_pid) {
++                av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", service->pcr_pid);
++            }
+         }
+     }
+ }
+@@ -860,6 +865,15 @@ static int mpegts_init(AVFormatContext *s)
  
      if (s->max_delay < 0) /* Not set by the caller */
          s->max_delay = 0;
  
      if (s->max_delay < 0) /* Not set by the caller */
          s->max_delay = 0;
@@ -122,167 +202,66 @@ index fc0ea225c6..c702bc5f07 100644
  
      // round up to a whole number of TS packets
      ts->pes_payload_size = (ts->pes_payload_size + 14 + 183) / 184 * 184 - 14;
  
      // round up to a whole number of TS packets
      ts->pes_payload_size = (ts->pes_payload_size + 14 + 183) / 184 * 184 - 14;
-@@ -830,6 +831,8 @@ static int mpegts_init(AVFormatContext *s)
-             service->program          = program;
-         }
-     }
-+    if (ts->m2ts_mode > 1)
-+        service->pmt.pid = 0x00ff + ts->service_id;
+@@ -920,14 +934,11 @@ static int mpegts_init(AVFormatContext *s)
  
  
-     ts->pat.pid          = PAT_PID;
-     /* Initialize at 15 so that it wraps and is equal to 0 for the
-@@ -915,10 +918,9 @@ static int mpegts_init(AVFormatContext *s)
-         ts_st->discontinuity   = ts->flags & MPEGTS_FLAG_DISCONT;
-         /* update PCR pid by using the first video stream */
-         if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
--            service->pcr_pid == 0x1fff) {
--            service->pcr_pid = ts_st->pid;
-+            service->pcr_sid == 0x1fff)
-             pcr_st           = st;
--        }
-+
-         if (st->codecpar->codec_id == AV_CODEC_ID_AAC &&
-             st->codecpar->extradata_size > 0) {
-             AVStream *ast;
-@@ -954,78 +956,47 @@ static int mpegts_init(AVFormatContext *s)
-     av_freep(&pids);
-     /* if no video stream, use the first stream as PCR */
--    if (service->pcr_pid == 0x1fff && s->nb_streams > 0) {
--        pcr_st           = s->streams[0];
--        ts_st            = pcr_st->priv_data;
--        service->pcr_pid = ts_st->pid;
--    } else
--        ts_st = pcr_st->priv_data;
--
--    if (ts->mux_rate > 1) {
--        service->pcr_packet_period = (int64_t)ts->mux_rate * ts->pcr_period /
--                                     (TS_PACKET_SIZE * 8 * 1000);
--        ts->sdt_packet_period      = (int64_t)ts->mux_rate * SDT_RETRANS_TIME /
--                                     (TS_PACKET_SIZE * 8 * 1000);
--        ts->pat_packet_period      = (int64_t)ts->mux_rate * PAT_RETRANS_TIME /
--                                     (TS_PACKET_SIZE * 8 * 1000);
--
--        if (ts->copyts < 1)
--            ts->first_pcr = av_rescale(s->max_delay, PCR_TIME_BASE, AV_TIME_BASE);
--    } else {
--        /* Arbitrary values, PAT/PMT will also be written on video key frames */
--        ts->sdt_packet_period = 200;
--        ts->pat_packet_period = 40;
--        if (pcr_st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
--            int frame_size = av_get_audio_frame_duration2(pcr_st->codecpar, 0);
--            if (!frame_size) {
--                av_log(s, AV_LOG_WARNING, "frame size not set\n");
--                service->pcr_packet_period =
--                    pcr_st->codecpar->sample_rate / (10 * 512);
--            } else {
--                service->pcr_packet_period =
--                    pcr_st->codecpar->sample_rate / (10 * frame_size);
--            }
+         /* MPEG pid values < 16 are reserved. Applications which set st->id in
+          * this range are assigned a calculated pid. */
+-        if (st->id < 16) {
+-            ts_st->pid = ts->start_pid + i;
 -        } else {
 -        } else {
--            // max delta PCR 0.1s
--            // TODO: should be avg_frame_rate
--            service->pcr_packet_period =
--                ts_st->user_tb.den / (10 * ts_st->user_tb.num);
+-            ts_st->pid = st->id;
 -        }
 -        }
--        if (!service->pcr_packet_period)
--            service->pcr_packet_period = 1;
--    }
--
--    ts->last_pat_ts = AV_NOPTS_VALUE;
--    ts->last_sdt_ts = AV_NOPTS_VALUE;
--    // The user specified a period, use only it
--    if (ts->pat_period < INT_MAX/2) {
--        ts->pat_packet_period = INT_MAX;
-+    if (!pcr_st && s->nb_streams > 0)
-+        pcr_st = s->streams[0];
-+    if (!pcr_st) {
-+        av_log(s, AV_LOG_ERROR, "no streams\n");
-+        ret = AVERROR(EINVAL);
-+        goto fail;
-     }
--    if (ts->sdt_period < INT_MAX/2) {
--        ts->sdt_packet_period = INT_MAX;
-+    ts_st  = pcr_st->priv_data;
-+    if (service->pcr_sid == 0x1fff)
-+        service->pcr_sid   = ts_st->pid;
-+    if (service->pcr_pid == 0x1fff)
-+        service->pcr_pid   = ts->m2ts_mode > 1 ?
-+            0x1000 + ts->service_id : service->pcr_sid ;
-+    if (service->pmt.pid == service->pcr_pid) {
-+        av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", service->pcr_pid);
-+        ret = AVERROR(EINVAL);
-+        goto fail;
-     }
+-        if (ts_st->pid >= 0x1FFF) {
++        ts_st->pid = ts->start_pid >= 0 ?  ts->start_pid + i :
++            st->id >= 16 ? st->id : FIRST_OTHER_PID + i;
++        if (ts_st->pid < 16 || ts_st->pid >= 0x1FFF) {
+             av_log(s, AV_LOG_ERROR,
+-                   "Invalid stream id %d, must be less than 8191\n", st->id);
++                   "Invalid stream id %d, must be in 16...8191\n", ts_st->pid);
+             ret = AVERROR(EINVAL);
+             goto fail;
+         }
+@@ -998,8 +1009,8 @@ static int mpegts_init(AVFormatContext *s)
  
  
-+    clk_rate = ts->mux_rate > 1 ? ts->mux_rate : PCR_TIME_BASE;
-+    ts->sdt_packet_period      = ts->sdt_period < 0 ? -1 : ts->sdt_period/1000 * clk_rate;
-+    ts->pat_packet_period      = ts->pat_period/1000 * clk_rate;
-+    service->pcr_packet_period = ts->pcr_period/1000 * clk_rate;
-+    if (service->pcr_packet_period < (TS_PACKET_SIZE*8*10))
-+        service->pcr_packet_period = (TS_PACKET_SIZE*8*10);
-+    av_log(s, AV_LOG_VERBOSE, "clk_rate %f: ticks/pkt %d pcr, %d sdt, %d pmt\n", clk_rate,
-+        (int)service->pcr_packet_period, (int)ts->sdt_packet_period, (int)ts->pat_packet_period);
-+
-+    if (ts->copyts < 1)
-+        ts->first_pcr = av_rescale(s->max_delay, PCR_TIME_BASE, AV_TIME_BASE);
-+
-     // output a PCR as soon as possible
--    service->pcr_packet_count = service->pcr_packet_period;
--    ts->pat_packet_count      = ts->pat_packet_period - 1;
--    ts->sdt_packet_count      = ts->sdt_packet_period - 1;
-+    ts->pcr = 0;
-+    service->pcr_packet_timer = 0;
-+    ts->pat_packet_timer      = 0;
-+    ts->sdt_packet_timer      = 0;
+     ts->last_pat_ts = AV_NOPTS_VALUE;
+     ts->last_sdt_ts = AV_NOPTS_VALUE;
+-    ts->pat_period = av_rescale(ts->pat_period_us, PCR_TIME_BASE, AV_TIME_BASE);
+-    ts->sdt_period = av_rescale(ts->sdt_period_us, PCR_TIME_BASE, AV_TIME_BASE);
++    ts->pat_period = av_rescale(ts->pat_period_ms, PCR_TIME_BASE, 1000);
++    ts->sdt_period = av_rescale(ts->sdt_period_ms, PCR_TIME_BASE, 1000);
  
      if (ts->mux_rate == 1)
          av_log(s, AV_LOG_VERBOSE, "muxrate VBR, ");
  
      if (ts->mux_rate == 1)
          av_log(s, AV_LOG_VERBOSE, "muxrate VBR, ");
-     else
-         av_log(s, AV_LOG_VERBOSE, "muxrate %d, ", ts->mux_rate);
--    av_log(s, AV_LOG_VERBOSE,
--           "pcr every %d pkts, sdt every %d, pat/pmt every %d pkts\n",
--           service->pcr_packet_period,
--           ts->sdt_packet_period, ts->pat_packet_period);
--
--    if (ts->m2ts_mode == -1) {
--        if (av_match_ext(s->url, "m2ts")) {
--            ts->m2ts_mode = 1;
--        } else {
--            ts->m2ts_mode = 0;
--        }
--    }
-     return 0;
-@@ -1040,22 +1011,12 @@ static void retransmit_si_info(AVFormatContext *s, int force_pat, int64_t dts)
+@@ -1022,20 +1033,16 @@ static void retransmit_si_info(AVFormatContext *s, int force_pat, int force_sdt,
+ {
      MpegTSWrite *ts = s->priv_data;
      int i;
      MpegTSWrite *ts = s->priv_data;
      int i;
--    if (++ts->sdt_packet_count == ts->sdt_packet_period ||
--        (dts != AV_NOPTS_VALUE && ts->last_sdt_ts == AV_NOPTS_VALUE) ||
--        (dts != AV_NOPTS_VALUE && dts - ts->last_sdt_ts >= ts->sdt_period*90000.0)
+-
+-    if ((pcr != AV_NOPTS_VALUE && ts->last_sdt_ts == AV_NOPTS_VALUE) ||
+-        (pcr != AV_NOPTS_VALUE && pcr - ts->last_sdt_ts >= ts->sdt_period) ||
+-        force_sdt
 -    ) {
 -    ) {
--        ts->sdt_packet_count = 0;
--        if (dts != AV_NOPTS_VALUE)
--            ts->last_sdt_ts = FFMAX(dts, ts->last_sdt_ts);
-+    if ( ts->sdt_packet_period >= 0 && ts->pcr >= ts->sdt_packet_timer ) {
-+        ts->sdt_packet_timer = ts->pcr + ts->sdt_packet_period;
+-        if (pcr != AV_NOPTS_VALUE)
+-            ts->last_sdt_ts = FFMAX(pcr, ts->last_sdt_ts);
++    if (force_sdt || (ts->sdt_period >= 0 && pcr != AV_NOPTS_VALUE &&
++         (ts->last_sdt_ts == AV_NOPTS_VALUE || (pcr - ts->last_sdt_ts >= ts->sdt_period)) )) {
++        if (pcr > ts->last_sdt_ts)
++            ts->last_sdt_ts = pcr;
          mpegts_write_sdt(s);
      }
          mpegts_write_sdt(s);
      }
--    if (++ts->pat_packet_count == ts->pat_packet_period ||
--        (dts != AV_NOPTS_VALUE && ts->last_pat_ts == AV_NOPTS_VALUE) ||
--        (dts != AV_NOPTS_VALUE && dts - ts->last_pat_ts >= ts->pat_period*90000.0) ||
+-    if ((pcr != AV_NOPTS_VALUE && ts->last_pat_ts == AV_NOPTS_VALUE) ||
+-        (pcr != AV_NOPTS_VALUE && pcr - ts->last_pat_ts >= ts->pat_period) ||
 -        force_pat) {
 -        force_pat) {
--        ts->pat_packet_count = 0;
--        if (dts != AV_NOPTS_VALUE)
--            ts->last_pat_ts = FFMAX(dts, ts->last_pat_ts);
-+    if (ts->pcr >= ts->pat_packet_timer || force_pat) {
-+        ts->pat_packet_timer = ts->pcr + ts->pat_packet_period;
+-        if (pcr != AV_NOPTS_VALUE)
+-            ts->last_pat_ts = FFMAX(pcr, ts->last_pat_ts);
++    if (force_pat || (ts->pat_period >= 0 && pcr != AV_NOPTS_VALUE &&
++         (ts->last_pat_ts == AV_NOPTS_VALUE || (pcr - ts->last_pat_ts >= ts->pat_period)) )) {
++        if (pcr > ts->last_pat_ts)
++            ts->last_pat_ts = pcr;
          mpegts_write_pat(s);
          for (i = 0; i < ts->nb_services; i++)
              mpegts_write_pmt(s, ts->services[i]);
          mpegts_write_pat(s);
          for (i = 0; i < ts->nb_services; i++)
              mpegts_write_pmt(s, ts->services[i]);
-@@ -1097,13 +1058,14 @@ static void mpegts_insert_pcr_only(AVFormatContext *s, AVStream *st)
+@@ -1076,13 +1083,14 @@ static void mpegts_insert_pcr_only(AVFormatContext *s, AVStream *st)
  {
      MpegTSWrite *ts = s->priv_data;
      MpegTSWriteStream *ts_st = st->priv_data;
  {
      MpegTSWrite *ts = s->priv_data;
      MpegTSWriteStream *ts_st = st->priv_data;
@@ -299,7 +278,7 @@ index fc0ea225c6..c702bc5f07 100644
      *q++ = 0x20 | ts_st->cc;   /* Adaptation only */
      /* Continuity Count field does not increment (see 13818-1 section 2.4.3.3) */
      *q++ = TS_PACKET_SIZE - 5; /* Adaptation Field Length */
      *q++ = 0x20 | ts_st->cc;   /* Adaptation only */
      /* Continuity Count field does not increment (see 13818-1 section 2.4.3.3) */
      *q++ = TS_PACKET_SIZE - 5; /* Adaptation Field Length */
-@@ -1114,7 +1076,7 @@ static void mpegts_insert_pcr_only(AVFormatContext *s, AVStream *st)
+@@ -1093,7 +1101,7 @@ static void mpegts_insert_pcr_only(AVFormatContext *s, AVStream *st)
      }
  
      /* PCR coded into 6 bytes */
      }
  
      /* PCR coded into 6 bytes */
@@ -308,91 +287,123 @@ index fc0ea225c6..c702bc5f07 100644
  
      /* stuffing bytes */
      memset(q, 0xFF, TS_PACKET_SIZE - (q - buf));
  
      /* stuffing bytes */
      memset(q, 0xFF, TS_PACKET_SIZE - (q - buf));
-@@ -1183,8 +1145,6 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
+@@ -1161,7 +1169,6 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
      uint8_t *q;
      int val, is_start, len, header_len, write_pcr, is_dvb_subtitle, is_dvb_teletext, flags;
      int afc_len, stuffing_len;
      uint8_t *q;
      int val, is_start, len, header_len, write_pcr, is_dvb_subtitle, is_dvb_teletext, flags;
      int afc_len, stuffing_len;
--    int64_t pcr = -1; /* avoid warning */
 -    int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE);
      int force_pat = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && key && !ts_st->prev_payload_key;
 -    int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE);
      int force_pat = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && key && !ts_st->prev_payload_key;
+     int force_sdt = 0;
  
  
-     av_assert0(ts_st->payload != buf || st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO);
-@@ -1194,28 +1154,33 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
+@@ -1178,67 +1185,46 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
  
      is_start = 1;
      while (payload_size > 0) {
  
      is_start = 1;
      while (payload_size > 0) {
+-        int64_t pcr = AV_NOPTS_VALUE;
+-        if (ts->mux_rate > 1)
+-            pcr = get_pcr(ts, s->pb);
+-        else if (dts != AV_NOPTS_VALUE)
+-            pcr = (dts - delay) * 300;
 +        ts->pcr = ts->first_pcr + (ts->mux_rate == 1 ?
 +            (dts == AV_NOPTS_VALUE ? 0 : (dts - ts->delay) * 300) :
 +            // add 11, pcr references the last byte of program clock reference base
 +            av_rescale(avio_tell(s->pb) + 11, 8 * PCR_TIME_BASE, ts->mux_rate));
 +        ts->pcr = ts->first_pcr + (ts->mux_rate == 1 ?
 +            (dts == AV_NOPTS_VALUE ? 0 : (dts - ts->delay) * 300) :
 +            // add 11, pcr references the last byte of program clock reference base
 +            av_rescale(avio_tell(s->pb) + 11, 8 * PCR_TIME_BASE, ts->mux_rate));
-+
-         retransmit_si_info(s, force_pat, dts);
+-        retransmit_si_info(s, force_pat, force_sdt, pcr);
++        retransmit_si_info(s, force_pat, force_sdt, ts->pcr);
          force_pat = 0;
          force_pat = 0;
+         force_sdt = 0;
  
          write_pcr = 0;
  
          write_pcr = 0;
--        if (ts_st->pid == ts_st->service->pcr_pid) {
--            if (ts->mux_rate > 1 || is_start) // VBR pcr period is based on frames
--                ts_st->service->pcr_packet_count++;
--            if (ts_st->service->pcr_packet_count >=
--                ts_st->service->pcr_packet_period) {
--                ts_st->service->pcr_packet_count = 0;
-+        if (ts_st->pid == ts_st->service->pcr_sid) {
-+            if( ts->pcr >= ts_st->service->pcr_packet_timer ) {
-+                ts_st->service->pcr_packet_timer = ts->pcr + ts_st->service->pcr_packet_period;
-                 write_pcr = 1;
-             }
-         }
--
+-        if (ts->mux_rate > 1) {
+-            /* Send PCR packets for all PCR streams if needed */
+-            pcr = get_pcr(ts, s->pb);
+-            if (pcr >= ts->next_pcr) {
+-                int64_t next_pcr = INT64_MAX;
+-                for (int i = 0; i < s->nb_streams; i++) {
+-                    /* Make the current stream the last, because for that we
+-                     * can insert the pcr into the payload later */
+-                    int st2_index = i < st->index ? i : (i + 1 == s->nb_streams ? st->index : i + 1);
+-                    AVStream *st2 = s->streams[st2_index];
+-                    MpegTSWriteStream *ts_st2 = st2->priv_data;
+-                    if (ts_st2->pcr_period) {
+-                        if (pcr - ts_st2->last_pcr >= ts_st2->pcr_period) {
+-                            ts_st2->last_pcr = FFMAX(pcr - ts_st2->pcr_period, ts_st2->last_pcr + ts_st2->pcr_period);
+-                            if (st2 != st) {
+-                                mpegts_insert_pcr_only(s, st2);
+-                                pcr = get_pcr(ts, s->pb);
+-                            } else {
+-                                write_pcr = 1;
+-                            }
+-                        }
+-                        next_pcr = FFMIN(next_pcr, ts_st2->last_pcr + ts_st2->pcr_period);
+-                    }
+-                }
+-                ts->next_pcr = next_pcr;
+-            }
+-            if (dts != AV_NOPTS_VALUE && (dts - pcr / 300) > delay) {
+-                /* pcr insert gets priority over null packet insert */
+-                if (write_pcr)
+-                    mpegts_insert_pcr_only(s, st);
+-                else
+-                    mpegts_insert_null_packet(s);
+-                /* recalculate write_pcr and possibly retransmit si_info */
+-                continue;
+-            }
+-        } else if (ts_st->pcr_period && pcr != AV_NOPTS_VALUE) {
+-            if (pcr - ts_st->last_pcr >= ts_st->pcr_period && is_start) {
+-                ts_st->last_pcr = FFMAX(pcr - ts_st->pcr_period, ts_st->last_pcr + ts_st->pcr_period);
+-                write_pcr = 1;
+-            }
++        if (ts_st->pcr_period > 0 && ts_st->pid == ts_st->service->pcr_sid &&
++            ts->pcr - ts_st->last_pcr >= ts_st->pcr_period) {
++            ts_st->last_pcr = ts->pcr;
++            write_pcr = 1;
++        }
 +        if (write_pcr && ts_st->service->pcr_sid != ts_st->service->pcr_pid) {
 +        if (write_pcr && ts_st->service->pcr_sid != ts_st->service->pcr_pid) {
-+           mpegts_insert_pcr_only(s, st);
-+           continue;
++            /* pcr is on a seperate stream */
++            mpegts_insert_pcr_only(s, st);
++            continue;
 +        }
 +        }
-         if (ts->mux_rate > 1 && dts != AV_NOPTS_VALUE &&
--            (dts - get_pcr(ts, s->pb) / 300) > delay) {
--            /* pcr insert gets priority over null packet insert */
--            if (write_pcr)
--                mpegts_insert_pcr_only(s, st);
++
++        if (ts->mux_rate > 1 && dts != AV_NOPTS_VALUE &&
 +               (dts - ts->pcr / 300) > ts->delay) {
 +               (dts - ts->pcr / 300) > ts->delay) {
-+           /* pcr insert gets priority over null packet insert */
-+           if (write_pcr)
-+               mpegts_insert_pcr_only(s, st);
-             else
--                mpegts_insert_null_packet(s);
--            /* recalculate write_pcr and possibly retransmit si_info */
-+               mpegts_insert_null_packet(s);
++            /* pcr insert gets priority over null packet insert */
++            if (write_pcr)
++                mpegts_insert_pcr_only(s, st);
++            else
++                mpegts_insert_null_packet(s);
 +            /* recalculate write_pcr and possibly retransimit si_info */
 +            /* recalculate write_pcr and possibly retransimit si_info */
-             continue;
++            continue;
          }
  
          }
  
-@@ -1225,6 +1190,10 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
+         /* prepare packet header */
+         q    = buf;
+         *q++ = 0x47;
          val  = ts_st->pid >> 8;
          val  = ts_st->pid >> 8;
+-        if (ts->m2ts_mode && st->codecpar->codec_id == AV_CODEC_ID_AC3)
+-            val |= 0x20;
          if (is_start)
              val |= 0x40;
          if (is_start)
              val |= 0x40;
-+        if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
-+          st->codecpar->codec_id == AV_CODEC_ID_AC3 &&
-+          ts->m2ts_mode > 1)
++        if (ts->m2ts_mode && st->codecpar->codec_id == AV_CODEC_ID_AC3)
 +            val |= 0x20;
          *q++      = val;
          *q++      = ts_st->pid;
          ts_st->cc = ts_st->cc + 1 & 0xf;
 +            val |= 0x20;
          *q++      = val;
          *q++      = ts_st->pid;
          ts_st->cc = ts_st->cc + 1 & 0xf;
-@@ -1236,7 +1205,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
+@@ -1250,7 +1236,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
          }
          if (key && is_start && pts != AV_NOPTS_VALUE) {
              // set Random Access for key frames
          }
          if (key && is_start && pts != AV_NOPTS_VALUE) {
              // set Random Access for key frames
--            if (ts_st->pid == ts_st->service->pcr_pid)
-+            if (ts_st->pid == ts_st->service->pcr_sid)
+-            if (ts_st->pcr_period)
++            if ( ts_st->pcr_period > 0 && ts_st->pid == ts_st->service->pcr_sid )
                  write_pcr = 1;
              set_af_flag(buf, 0x40);
              q = get_ts_payload_start(buf);
                  write_pcr = 1;
              set_af_flag(buf, 0x40);
              q = get_ts_payload_start(buf);
-@@ -1244,14 +1213,10 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
+@@ -1258,10 +1244,9 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
          if (write_pcr) {
              set_af_flag(buf, 0x10);
              q = get_ts_payload_start(buf);
 -            // add 11, pcr references the last byte of program clock reference base
          if (write_pcr) {
              set_af_flag(buf, 0x10);
              q = get_ts_payload_start(buf);
 -            // add 11, pcr references the last byte of program clock reference base
-             if (ts->mux_rate > 1)
--                pcr = get_pcr(ts, s->pb);
--            else
--                pcr = (dts - delay) * 300;
 -            if (dts != AV_NOPTS_VALUE && dts < pcr / 300)
 +            if (dts != AV_NOPTS_VALUE && dts < ts->pcr / 300)
                  av_log(s, AV_LOG_WARNING, "dts < pcr, TS is invalid\n");
 -            if (dts != AV_NOPTS_VALUE && dts < pcr / 300)
 +            if (dts != AV_NOPTS_VALUE && dts < ts->pcr / 300)
                  av_log(s, AV_LOG_WARNING, "dts < pcr, TS is invalid\n");
@@ -401,7 +412,7 @@ index fc0ea225c6..c702bc5f07 100644
              q = get_ts_payload_start(buf);
          }
          if (is_start) {
              q = get_ts_payload_start(buf);
          }
          if (is_start) {
-@@ -1352,11 +1317,13 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
+@@ -1362,11 +1347,13 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
              *q++ = flags;
              *q++ = header_len;
              if (pts != AV_NOPTS_VALUE) {
              *q++ = flags;
              *q++ = header_len;
              if (pts != AV_NOPTS_VALUE) {
@@ -417,56 +428,36 @@ index fc0ea225c6..c702bc5f07 100644
                  q += 5;
              }
              if (pes_extension && st->codecpar->codec_id == AV_CODEC_ID_DIRAC) {
                  q += 5;
              }
              if (pes_extension && st->codecpar->codec_id == AV_CODEC_ID_DIRAC) {
-@@ -1527,7 +1494,6 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
+@@ -1536,7 +1523,6 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
      uint8_t *data = NULL;
      MpegTSWrite *ts = s->priv_data;
      MpegTSWriteStream *ts_st = st->priv_data;
 -    const int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE) * 2;
      uint8_t *data = NULL;
      MpegTSWrite *ts = s->priv_data;
      MpegTSWriteStream *ts_st = st->priv_data;
 -    const int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE) * 2;
+     const int64_t max_audio_delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE) / 2;
      int64_t dts = pkt->dts, pts = pkt->pts;
      int opus_samples = 0;
      int64_t dts = pkt->dts, pts = pkt->pts;
      int opus_samples = 0;
-     int side_data_size;
-@@ -1548,16 +1514,15 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
-     }
-     if (ts->flags & MPEGTS_FLAG_REEMIT_PAT_PMT) {
--        ts->pat_packet_count = ts->pat_packet_period - 1;
--        ts->sdt_packet_count = ts->sdt_packet_period - 1;
-+        ts->pat_packet_timer = ts->sdt_packet_timer = 0;
-         ts->flags           &= ~MPEGTS_FLAG_REEMIT_PAT_PMT;
-     }
+@@ -1552,9 +1538,9 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
  
      if (ts->copyts < 1) {
          if (pts != AV_NOPTS_VALUE)
 -            pts += delay;
  
      if (ts->copyts < 1) {
          if (pts != AV_NOPTS_VALUE)
 -            pts += delay;
-+            pts += 2*ts->delay;
++            pts += ts->delay * 2;
          if (dts != AV_NOPTS_VALUE)
 -            dts += delay;
          if (dts != AV_NOPTS_VALUE)
 -            dts += delay;
-+            dts += 2*ts->delay;
++            dts += ts->delay * 2;
      }
  
      if (ts_st->first_pts_check && pts == AV_NOPTS_VALUE) {
      }
  
      if (ts_st->first_pts_check && pts == AV_NOPTS_VALUE) {
-@@ -1745,7 +1710,7 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
-             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->payload_dts == AV_NOPTS_VALUE || dts - ts_st2->payload_dts > ts->delay)) {
-                 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);
-@@ -1914,12 +1879,18 @@ static const AVOption options[] = {
-     { "mpegts_pmt_start_pid", "Set the first pid of the PMT.",
-       offsetof(MpegTSWrite, pmt_start_pid), AV_OPT_TYPE_INT,
-       { .i64 = 0x1000 }, 0x0010, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM },
-+    { "mpegts_pcr_start_pid", "Set the first pid of the PCR.",
-+      offsetof(MpegTSWrite, pcr_start_pid), AV_OPT_TYPE_INT,
-+      { .i64 = 0x1000 }, 0x0010, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM },
+@@ -1904,10 +1890,13 @@ static const AVOption options[] = {
+       { .i64 = 0x1000 }, FIRST_OTHER_PID, LAST_OTHER_PID, AV_OPT_FLAG_ENCODING_PARAM },
      { "mpegts_start_pid", "Set the first pid.",
        offsetof(MpegTSWrite, start_pid), AV_OPT_TYPE_INT,
      { "mpegts_start_pid", "Set the first pid.",
        offsetof(MpegTSWrite, start_pid), AV_OPT_TYPE_INT,
-       { .i64 = 0x0100 }, 0x0010, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM },
+-      { .i64 = 0x0100 }, FIRST_OTHER_PID, LAST_OTHER_PID, AV_OPT_FLAG_ENCODING_PARAM },
++      { .i64 = -1 }, -1, LAST_OTHER_PID, AV_OPT_FLAG_ENCODING_PARAM },
      { "mpegts_m2ts_mode", "Enable m2ts mode.",
      { "mpegts_m2ts_mode", "Enable m2ts mode.",
-       offsetof(MpegTSWrite, m2ts_mode), AV_OPT_TYPE_BOOL,
+-      offsetof(MpegTSWrite, m2ts_mode), AV_OPT_TYPE_BOOL,
 -      { .i64 = -1 }, -1, 1, AV_OPT_FLAG_ENCODING_PARAM },
 -      { .i64 = -1 }, -1, 1, AV_OPT_FLAG_ENCODING_PARAM },
++      offsetof(MpegTSWrite, m2ts_mode), AV_OPT_TYPE_INT,
 +      { .i64 = -1 }, -1, 2, AV_OPT_FLAG_ENCODING_PARAM },
 +    { "mpegts_pcr_offset", "clock offset.",
 +      offsetof(MpegTSWrite, ts_offset), AV_OPT_TYPE_BOOL,
 +      { .i64 = -1 }, -1, 2, AV_OPT_FLAG_ENCODING_PARAM },
 +    { "mpegts_pcr_offset", "clock offset.",
 +      offsetof(MpegTSWrite, ts_offset), AV_OPT_TYPE_BOOL,
@@ -474,25 +465,27 @@ index fc0ea225c6..c702bc5f07 100644
      { "muxrate", NULL,
        offsetof(MpegTSWrite, mux_rate), AV_OPT_TYPE_INT,
        { .i64 = 1 }, 0, INT_MAX, 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 },
-@@ -1957,15 +1928,15 @@ static const AVOption options[] = {
+@@ -1941,15 +1930,15 @@ static const AVOption options[] = {
      { "omit_video_pes_length", "Omit the PES packet length for video packets",
        offsetof(MpegTSWrite, omit_video_pes_length), AV_OPT_TYPE_BOOL,
        { .i64 = 1 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM },
 -    { "pcr_period", "PCR retransmission time in milliseconds",
      { "omit_video_pes_length", "Omit the PES packet length for video packets",
        offsetof(MpegTSWrite, omit_video_pes_length), AV_OPT_TYPE_BOOL,
        { .i64 = 1 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM },
 -    { "pcr_period", "PCR retransmission time in milliseconds",
--      offsetof(MpegTSWrite, pcr_period), AV_OPT_TYPE_INT,
--      { .i64 = PCR_RETRANS_TIME }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+-      offsetof(MpegTSWrite, pcr_period_ms), AV_OPT_TYPE_INT,
+-      { .i64 = -1 }, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
 -    { "pat_period", "PAT/PMT retransmission time limit in seconds",
 -    { "pat_period", "PAT/PMT retransmission time limit in seconds",
+-      offsetof(MpegTSWrite, pat_period_us), AV_OPT_TYPE_DURATION,
+-      { .i64 = PAT_RETRANS_TIME * 1000LL }, 0, INT64_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+-    { "sdt_period", "SDT retransmission time limit in seconds",
+-      offsetof(MpegTSWrite, sdt_period_us), AV_OPT_TYPE_DURATION,
+-      { .i64 = SDT_RETRANS_TIME * 1000LL }, 0, INT64_MAX, AV_OPT_FLAG_ENCODING_PARAM },
 +    { "pcr_period", "PCR retransmission time limit in msecs",
 +    { "pcr_period", "PCR retransmission time limit in msecs",
-+      offsetof(MpegTSWrite, pcr_period), AV_OPT_TYPE_DOUBLE,
-+      { .dbl = PCR_RETRANS_TIME }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
++      offsetof(MpegTSWrite, pcr_period_ms), AV_OPT_TYPE_DOUBLE,
++      { .dbl = -1 }, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
 +    { "pat_period", "PAT/PMT retransmission time limit in msecs",
 +    { "pat_period", "PAT/PMT retransmission time limit in msecs",
-       offsetof(MpegTSWrite, pat_period), AV_OPT_TYPE_DOUBLE,
--      { .dbl = INT_MAX }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
--    { "sdt_period", "SDT retransmission time limit in seconds",
++      offsetof(MpegTSWrite, pat_period_ms), AV_OPT_TYPE_DOUBLE,
 +      { .dbl = PAT_RETRANS_TIME }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
 +    { "sdt_period", "SDT retransmission time limit in msecs",
 +      { .dbl = PAT_RETRANS_TIME }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
 +    { "sdt_period", "SDT retransmission time limit in msecs",
-       offsetof(MpegTSWrite, sdt_period), AV_OPT_TYPE_DOUBLE,
--      { .dbl = INT_MAX }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
++      offsetof(MpegTSWrite, sdt_period_ms), AV_OPT_TYPE_DOUBLE,
 +      { .dbl = SDT_RETRANS_TIME }, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
      { NULL },
  };
 +      { .dbl = SDT_RETRANS_TIME }, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
      { NULL },
  };
index 34ce2a5aaf371ee21c40582ec43f3a7112cb3c96..e37f37a97849cb280addf4a60cd1ba42404e0b65 100644 (file)
@@ -1,8 +1,7 @@
-diff --git a/libavformat/avformat.h b/libavformat/avformat.h
-index 734ae54cac..26d9bbafbc 100644
---- a/libavformat/avformat.h
-+++ b/libavformat/avformat.h
-@@ -485,6 +485,9 @@ typedef struct AVProbeData {
+diff -urN a/libavformat/avformat.h b/libavformat/avformat.h
+--- a/libavformat/avformat.h   2019-12-02 08:48:03.103361418 -0700
++++ b/libavformat/avformat.h   2019-12-02 08:52:16.724218813 -0700
+@@ -485,6 +485,9 @@
                                          The user or muxer can override this through
                                          AVFormatContext.avoid_negative_ts
                                          */
                                          The user or muxer can override this through
                                          AVFormatContext.avoid_negative_ts
                                          */
@@ -12,22 +11,20 @@ index 734ae54cac..26d9bbafbc 100644
  
  #define AVFMT_SEEK_TO_PTS   0x4000000 /**< Seeking is based on PTS */
  
  
  #define AVFMT_SEEK_TO_PTS   0x4000000 /**< Seeking is based on PTS */
  
-@@ -653,8 +656,8 @@ typedef struct AVInputFormat {
+@@ -654,7 +657,8 @@
      /**
       * Can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_SHOW_IDS,
      /**
       * Can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_SHOW_IDS,
--     * AVFMT_NOTIMESTAMPS, AVFMT_GENERIC_INDEX, AVFMT_TS_DISCONT, AVFMT_NOBINSEARCH,
+      * AVFMT_NOTIMESTAMPS, AVFMT_GENERIC_INDEX, AVFMT_TS_DISCONT, AVFMT_NOBINSEARCH,
 -     * AVFMT_NOGENSEARCH, AVFMT_NO_BYTE_SEEK, AVFMT_SEEK_TO_PTS.
 +     * AVFMT_NOGENSEARCH, AVFMT_NO_BYTE_SEEK, AVFMT_SEEK_TO_PTS,
 +     * AVFMT_SEEK_NOSTREAMS
       */
      int flags;
  
 -     * AVFMT_NOGENSEARCH, AVFMT_NO_BYTE_SEEK, AVFMT_SEEK_TO_PTS.
 +     * AVFMT_NOGENSEARCH, AVFMT_NO_BYTE_SEEK, AVFMT_SEEK_TO_PTS,
 +     * AVFMT_SEEK_NOSTREAMS
       */
      int flags;
  
-diff --git a/libavformat/dv.c b/libavformat/dv.c
-index eb44e0acb6..b23759dd86 100644
---- a/libavformat/dv.c
-+++ b/libavformat/dv.c
-@@ -632,6 +632,7 @@ static int dv_probe(const AVProbeData *p)
+diff -urN a/libavformat/dv.c b/libavformat/dv.c
+--- a/libavformat/dv.c 2019-12-02 08:48:03.107361432 -0700
++++ b/libavformat/dv.c 2019-12-02 08:52:16.724218813 -0700
+@@ -642,6 +642,7 @@
  AVInputFormat ff_dv_demuxer = {
      .name           = "dv",
      .long_name      = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
  AVInputFormat ff_dv_demuxer = {
      .name           = "dv",
      .long_name      = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
@@ -35,11 +32,10 @@ index eb44e0acb6..b23759dd86 100644
      .priv_data_size = sizeof(RawDVContext),
      .read_probe     = dv_probe,
      .read_header    = dv_read_header,
      .priv_data_size = sizeof(RawDVContext),
      .read_probe     = dv_probe,
      .read_header    = dv_read_header,
-diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
-index cba2b3d1f8..8427b2c421 100644
---- a/libavformat/matroskadec.c
-+++ b/libavformat/matroskadec.c
-@@ -4059,6 +4059,7 @@ static const AVClass webm_dash_class = {
+diff -urN a/libavformat/matroskadec.c b/libavformat/matroskadec.c
+--- a/libavformat/matroskadec.c        2019-12-02 08:48:03.116361462 -0700
++++ b/libavformat/matroskadec.c        2019-12-02 08:52:16.725218816 -0700
+@@ -4224,6 +4224,7 @@
  AVInputFormat ff_matroska_demuxer = {
      .name           = "matroska,webm",
      .long_name      = NULL_IF_CONFIG_SMALL("Matroska / WebM"),
  AVInputFormat ff_matroska_demuxer = {
      .name           = "matroska,webm",
      .long_name      = NULL_IF_CONFIG_SMALL("Matroska / WebM"),
@@ -47,7 +43,7 @@ index cba2b3d1f8..8427b2c421 100644
      .extensions     = "mkv,mk3d,mka,mks",
      .priv_data_size = sizeof(MatroskaDemuxContext),
      .read_probe     = matroska_probe,
      .extensions     = "mkv,mk3d,mka,mks",
      .priv_data_size = sizeof(MatroskaDemuxContext),
      .read_probe     = matroska_probe,
-@@ -4072,6 +4073,7 @@ AVInputFormat ff_matroska_demuxer = {
+@@ -4237,6 +4238,7 @@
  AVInputFormat ff_webm_dash_manifest_demuxer = {
      .name           = "webm_dash_manifest",
      .long_name      = NULL_IF_CONFIG_SMALL("WebM DASH Manifest"),
  AVInputFormat ff_webm_dash_manifest_demuxer = {
      .name           = "webm_dash_manifest",
      .long_name      = NULL_IF_CONFIG_SMALL("WebM DASH Manifest"),
@@ -55,11 +51,10 @@ index cba2b3d1f8..8427b2c421 100644
      .priv_data_size = sizeof(MatroskaDemuxContext),
      .read_header    = webm_dash_manifest_read_header,
      .read_packet    = webm_dash_manifest_read_packet,
      .priv_data_size = sizeof(MatroskaDemuxContext),
      .read_header    = webm_dash_manifest_read_header,
      .read_packet    = webm_dash_manifest_read_packet,
-diff --git a/libavformat/utils.c b/libavformat/utils.c
-index a63d71b0f4..fe6608ade2 100644
---- a/libavformat/utils.c
-+++ b/libavformat/utils.c
-@@ -2472,6 +2472,13 @@ static int seek_frame_internal(AVFormatContext *s, int stream_index,
+diff -urN a/libavformat/utils.c b/libavformat/utils.c
+--- a/libavformat/utils.c      2019-12-02 08:48:03.138361536 -0700
++++ b/libavformat/utils.c      2019-12-02 08:52:16.726218820 -0700
+@@ -2488,6 +2488,13 @@
          return seek_frame_byte(s, stream_index, timestamp, flags);
      }
  
          return seek_frame_byte(s, stream_index, timestamp, flags);
      }
  
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg.git.patch4 b/cinelerra-5.1/thirdparty/src/ffmpeg.git.patch4
new file mode 100644 (file)
index 0000000..08bdcf2
--- /dev/null
@@ -0,0 +1,28 @@
+diff -urN a/libavfilter/af_aformat.c b/libavfilter/af_aformat.c
+--- a/libavfilter/af_aformat.c 2019-12-02 08:48:03.060361273 -0700
++++ b/libavfilter/af_aformat.c 2019-12-02 08:52:25.619248884 -0700
+@@ -109,6 +109,16 @@
+     return 0;
+ }
++#define DEL_FIELD(p,mem,fld) if( p->mem ) { av_freep(&p->mem->fld); av_freep(&p->mem); }
++
++static av_cold void uninit(AVFilterContext *ctx)
++{
++    AFormatContext *s = ctx->priv;
++    DEL_FIELD(s, formats, formats);
++    DEL_FIELD(s, sample_rates, formats);
++    DEL_FIELD(s, channel_layouts, channel_layouts);
++}
++
+ static int query_formats(AVFilterContext *ctx)
+ {
+     AFormatContext *s = ctx->priv;
+@@ -146,6 +156,7 @@
+     .name          = "aformat",
+     .description   = NULL_IF_CONFIG_SMALL("Convert the input audio to one of the specified formats."),
+     .init          = init,
++    .uninit        = uninit,
+     .query_formats = query_formats,
+     .priv_size     = sizeof(AFormatContext),
+     .priv_class    = &aformat_class,
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg.git.patch5 b/cinelerra-5.1/thirdparty/src/ffmpeg.git.patch5
new file mode 100644 (file)
index 0000000..3469f02
--- /dev/null
@@ -0,0 +1,29 @@
+diff -urN a/libavfilter/formats.c b/libavfilter/formats.c
+--- a/libavfilter/formats.c    2019-12-02 08:48:03.073361317 -0700
++++ b/libavfilter/formats.c    2019-12-02 08:52:32.155270978 -0700
+@@ -107,11 +107,13 @@
+        possibly causing a lossy conversion elsewhere in the graph.
+        To avoid that, pretend that there are no common formats to force the
+        insertion of a conversion filter. */
+-    if (type == AVMEDIA_TYPE_VIDEO)
+-        for (i = 0; i < a->nb_formats; i++)
++    if (type == AVMEDIA_TYPE_VIDEO) {
++        for (i = 0; i < a->nb_formats; i++) {
++            const AVPixFmtDescriptor *adesc = av_pix_fmt_desc_get(a->formats[i]);
++            if( !adesc ) continue;
+             for (j = 0; j < b->nb_formats; j++) {
+-                const AVPixFmtDescriptor *adesc = av_pix_fmt_desc_get(a->formats[i]);
+                 const AVPixFmtDescriptor *bdesc = av_pix_fmt_desc_get(b->formats[j]);
++                if( !bdesc ) continue;
+                 alpha2 |= adesc->flags & bdesc->flags & AV_PIX_FMT_FLAG_ALPHA;
+                 chroma2|= adesc->nb_components > 1 && bdesc->nb_components > 1;
+                 if (a->formats[i] == b->formats[j]) {
+@@ -119,6 +121,8 @@
+                     chroma1|= adesc->nb_components > 1;
+                 }
+             }
++        }
++    }
+     // If chroma or alpha can be lost through merging then do not merge
+     if (alpha2 > alpha1 || chroma2 > chroma1)
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg.git.patch6 b/cinelerra-5.1/thirdparty/src/ffmpeg.git.patch6
new file mode 100644 (file)
index 0000000..9009471
--- /dev/null
@@ -0,0 +1,11 @@
+diff -urN a/libavcodec/vdpau_mpeg12.c b/libavcodec/vdpau_mpeg12.c
+--- a/libavcodec/vdpau_mpeg12.c        2019-12-02 08:48:03.027361161 -0700
++++ b/libavcodec/vdpau_mpeg12.c        2019-12-02 08:52:38.667292990 -0700
+@@ -114,6 +114,7 @@
+     .frame_priv_data_size = sizeof(struct vdpau_picture_context),
+     .init           = vdpau_mpeg1_init,
+     .uninit         = ff_vdpau_common_uninit,
++    .frame_params   = ff_vdpau_common_frame_params,
+     .priv_data_size = sizeof(VDPAUContext),
+     .caps_internal  = HWACCEL_CAP_ASYNC_SAFE,
+ };
index df7bb461aecadf8b4159ccfa56fe76683e3e1dc5..231e05f568fdb22daef34d9e324c45c5cd23c09f 100644 (file)
@@ -1,7 +1,7 @@
 diff -urN a/libavcodec/h263dec.c b/libavcodec/h263dec.c
 diff -urN a/libavcodec/h263dec.c b/libavcodec/h263dec.c
---- a/libavcodec/h263dec.c
-+++ b/libavcodec/h263dec.c
-@@ -684,7 +684,7 @@ frame_end:
+--- a/libavcodec/h263dec.c     2019-12-02 08:48:02.926360820 -0700
++++ b/libavcodec/h263dec.c     2019-12-02 08:52:52.428339509 -0700
+@@ -684,7 +684,7 @@
      if (CONFIG_MPEG4_DECODER && avctx->codec_id == AV_CODEC_ID_MPEG4)
          ff_mpeg4_frame_end(avctx, buf, buf_size);
  
      if (CONFIG_MPEG4_DECODER && avctx->codec_id == AV_CODEC_ID_MPEG4)
          ff_mpeg4_frame_end(avctx, buf, buf_size);
  
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg.git.patch8 b/cinelerra-5.1/thirdparty/src/ffmpeg.git.patch8
new file mode 100644 (file)
index 0000000..9518ad7
--- /dev/null
@@ -0,0 +1,14 @@
+--- a/libavformat/mpegenc.c    2019-08-05 14:52:21.000000000 -0600
++++ /blibavformat/mpegenc.c    2019-11-14 14:07:57.407883232 -0700
+@@ -981,9 +981,9 @@
+         PacketDesc *pkt_desc;
+         while ((pkt_desc = stream->predecode_packet) &&
++               pkt_desc != stream->premux_packet &&
+                scr > pkt_desc->dts) { // FIXME: > vs >=
+-            if (stream->buffer_index < pkt_desc->size ||
+-                stream->predecode_packet == stream->premux_packet) {
++            if (stream->buffer_index < pkt_desc->size) {
+                 av_log(ctx, AV_LOG_ERROR,
+                        "buffer underflow st=%d bufi=%d size=%d\n",
+                        i, stream->buffer_index, pkt_desc->size);
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg.git.patch9 b/cinelerra-5.1/thirdparty/src/ffmpeg.git.patch9
new file mode 100644 (file)
index 0000000..f16968a
--- /dev/null
@@ -0,0 +1,35 @@
+--- a/libavutil/hwcontext_cuda.c       2019-12-03 10:04:24.521156775 -0700
++++ b/libavutil/hwcontext_cuda.c       2019-12-03 10:59:03.924121027 -0700
+@@ -282,9 +282,11 @@
+         CudaFunctions *cu = hwctx->internal->cuda_dl;
+         if (hwctx->internal->is_allocated && hwctx->cuda_ctx) {
++#ifdef CUDA_PRIMARY_CTX
+             if (hwctx->internal->flags & AV_CUDA_USE_PRIMARY_CONTEXT)
+                 CHECK_CU(cu->cuDevicePrimaryCtxRelease(hwctx->internal->cuda_device));
+             else
++#endif
+                 CHECK_CU(cu->cuCtxDestroy(hwctx->cuda_ctx));
+             hwctx->cuda_ctx = NULL;
+@@ -351,7 +353,7 @@
+         goto error;
+     hwctx->internal->flags = flags;
+-
++#ifdef CUDA_PRIMARY_CTX
+     if (flags & AV_CUDA_USE_PRIMARY_CONTEXT) {
+         ret = CHECK_CU(cu->cuDevicePrimaryCtxGetState(hwctx->internal->cuda_device, &dev_flags, &dev_active));
+         if (ret < 0)
+@@ -369,7 +371,10 @@
+         ret = CHECK_CU(cu->cuDevicePrimaryCtxRetain(&hwctx->cuda_ctx, hwctx->internal->cuda_device));
+         if (ret < 0)
+             goto error;
+-    } else {
++    }
++    else
++#endif
++    {
+         ret = CHECK_CU(cu->cuCtxCreate(&hwctx->cuda_ctx, desired_flags, hwctx->internal->cuda_device));
+         if (ret < 0)
+             goto error;