textbox cursor fix, h265 param files, bluray updates, new-proj theme fixes
[goodguy/history.git] / cinelerra-5.1 / thirdparty / src / ffmpeg.patch4
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg.patch4 b/cinelerra-5.1/thirdparty/src/ffmpeg.patch4
new file mode 100644 (file)
index 0000000..cd7c425
--- /dev/null
@@ -0,0 +1,261 @@
+--- a/libavformat/mpegtsenc.c  2016-09-30 19:12:42.000000000 -0600
++++ b/libavformat/mpegtsenc.c  2017-01-25 17:25:58.720017593 -0700
+@@ -55,7 +55,7 @@
+     int sid;           /* service ID */
+     char *name;
+     char *provider_name;
+-    int pcr_pid;
++    int pcr_sid, pcr_pid;
+     int pcr_packet_count;
+     int pcr_packet_period;
+     AVProgram *program;
+@@ -94,8 +94,10 @@
+     int service_type;
+     int pmt_start_pid;
++    int pcr_start_pid;
+     int start_pid;
+     int m2ts_mode;
++    int64_t pcr_offset;
+     int reemit_pat_pmt; // backward compatibility
+@@ -704,6 +706,7 @@
+     service->pmt.pid       = ts->pmt_start_pid + ts->nb_services;
+     service->sid           = sid;
+     service->pcr_pid       = 0x1fff;
++    service->pcr_sid       = 0x1fff;
+     service->provider_name = av_strdup(provider_name);
+     service->name          = av_strdup(name);
+     if (!service->provider_name || !service->name)
+@@ -722,7 +725,7 @@
+ static int64_t get_pcr(const MpegTSWrite *ts, AVIOContext *pb)
+ {
+     return av_rescale(avio_tell(pb) + 11, 8 * PCR_TIME_BASE, ts->mux_rate) +
+-           ts->first_pcr;
++           ts->first_pcr + ts->pcr_offset;
+ }
+ static void mpegts_prefix_m2ts_header(AVFormatContext *s)
+@@ -760,6 +763,14 @@
+     if (s->max_delay < 0) /* Not set by the caller */
+         s->max_delay = 0;
++    if (ts->m2ts_mode == -1) {
++        if (av_match_ext(s->filename, "m2ts")) {
++            ts->m2ts_mode = 1;
++        } else {
++            ts->m2ts_mode = 0;
++        }
++    }
++
+     // round up to a whole number of TS packets
+     ts->pes_payload_size = (ts->pes_payload_size + 14 + 183) / 184 * 184 - 14;
+@@ -803,6 +814,8 @@
+             service->program          = program;
+         }
+     }
++    if (ts->m2ts_mode > 1)
++        service->pmt.pid = 0x00ff + ts->service_id;
+     ts->pat.pid          = PAT_PID;
+     /* Initialize at 15 so that it wraps and is equal to 0 for the
+@@ -885,10 +898,9 @@
+         ts_st->cc              = 15;
+         /* 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;
+@@ -924,12 +936,24 @@
+     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 (!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;
++    }
++    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->mux_rate > 1) {
+         service->pcr_packet_period = (int64_t)ts->mux_rate * ts->pcr_period /
+@@ -989,14 +1013,6 @@
+            service->pcr_packet_period,
+            ts->sdt_packet_period, ts->pat_packet_period);
+-    if (ts->m2ts_mode == -1) {
+-        if (av_match_ext(s->filename, "m2ts")) {
+-            ts->m2ts_mode = 1;
+-        } else {
+-            ts->m2ts_mode = 0;
+-        }
+-    }
+-
+     return 0;
+ fail:
+@@ -1010,9 +1026,9 @@
+     MpegTSWrite *ts = s->priv_data;
+     int i;
+-    if (++ts->sdt_packet_count == ts->sdt_packet_period ||
++    if ( ts->sdt_period >= 0 && (++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)
++        (dts != AV_NOPTS_VALUE && dts - ts->last_sdt_ts >= ts->sdt_period*90000.0))
+     ) {
+         ts->sdt_packet_count = 0;
+         if (dts != AV_NOPTS_VALUE)
+@@ -1067,13 +1083,14 @@
+ {
+     MpegTSWrite *ts = s->priv_data;
+     MpegTSWriteStream *ts_st = st->priv_data;
++    uint32_t pcr_pid = ts_st->service->pcr_pid;
+     uint8_t *q;
+     uint8_t buf[TS_PACKET_SIZE];
+     q    = buf;
+     *q++ = 0x47;
+-    *q++ = ts_st->pid >> 8;
+-    *q++ = ts_st->pid;
++    *q++ = pcr_pid >> 8;
++    *q++ = pcr_pid;
+     *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 */
+@@ -1148,7 +1165,7 @@
+     uint8_t buf[TS_PACKET_SIZE];
+     uint8_t *q;
+     int val, is_start, len, header_len, write_pcr, is_dvb_subtitle, is_dvb_teletext, flags;
+-    int afc_len, stuffing_len;
++    int afc_len, stuffing_len, write_null;
+     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;
+@@ -1163,8 +1180,8 @@
+         retransmit_si_info(s, force_pat, dts);
+         force_pat = 0;
+-        write_pcr = 0;
+-        if (ts_st->pid == ts_st->service->pcr_pid) {
++        write_pcr = write_null = 0;
++        if (ts_st->pid == ts_st->service->pcr_sid) {
+             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 >=
+@@ -1173,15 +1190,17 @@
+                 write_pcr = 1;
+             }
+         }
+-
+         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);
+-            else
+-                mpegts_insert_null_packet(s);
+-            /* recalculate write_pcr and possibly retransmit si_info */
++               (dts - get_pcr(ts, s->pb) / 300) > delay) {
++            write_null = 1;
++        }
++        /* pcr insert gets priority over null packet insert */
++        if (write_pcr && ts_st->service->pcr_sid != ts_st->service->pcr_pid) {
++            mpegts_insert_pcr_only(s, st);
++            continue;
++        }
++        if (write_null) {
++            mpegts_insert_null_packet(s);
+             continue;
+         }
+@@ -1191,13 +1210,17 @@
+         val  = ts_st->pid >> 8;
+         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)
++            val |= 0x20;
+         *q++      = val;
+         *q++      = ts_st->pid;
+         ts_st->cc = ts_st->cc + 1 & 0xf;
+         *q++      = 0x10 | ts_st->cc; // payload indicator + CC
+         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)
+                 write_pcr = 1;
+             set_af_flag(buf, 0x40);
+             q = get_ts_payload_start(buf);
+@@ -1310,11 +1333,13 @@
+             *q++ = flags;
+             *q++ = header_len;
+             if (pts != AV_NOPTS_VALUE) {
+-                write_pts(q, flags >> 6, pts);
++                int64_t ts_pts = pts + ts->pcr_offset;
++                write_pts(q, flags >> 6, ts_pts);
+                 q += 5;
+             }
+             if (dts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE && dts != pts) {
+-                write_pts(q, 1, dts);
++                int64_t ts_dts = dts + ts->pcr_offset;
++                write_pts(q, 1, ts_dts);
+                 q += 5;
+             }
+             if (pes_extension && st->codecpar->codec_id == AV_CODEC_ID_DIRAC) {
+@@ -1838,12 +1863,18 @@
+     { "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 },
+     { "mpegts_start_pid", "Set the first pid.",
+       offsetof(MpegTSWrite, start_pid), AV_OPT_TYPE_INT,
+       { .i64 = 0x0100 }, 0x0020, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM },
+     { "mpegts_m2ts_mode", "Enable m2ts mode.",
+       offsetof(MpegTSWrite, m2ts_mode), AV_OPT_TYPE_BOOL,
+-      { .i64 = -1 }, -1, 1, AV_OPT_FLAG_ENCODING_PARAM },
++      { .i64 = -1 }, -1, 2, AV_OPT_FLAG_ENCODING_PARAM },
++    { "mpegts_pcr_offset", "clock offset.",
++      offsetof(MpegTSWrite, pcr_offset), AV_OPT_TYPE_BOOL,
++      { .i64 = 0 }, INT_MIN, 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 },
+@@ -1886,7 +1917,7 @@
+       { .dbl = INT_MAX }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+     { "sdt_period", "SDT retransmission time limit in seconds",
+       offsetof(MpegTSWrite, sdt_period), AV_OPT_TYPE_DOUBLE,
+-      { .dbl = INT_MAX }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
++      { .dbl = INT_MAX }, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+     { NULL },
+ };