]> git.webhop.me Git - bs-cst-neutrino-hd.git/commitdiff
bump version cst ffmepg-5.1.2
authorMarkham <markham001@gmx.de>
Sat, 7 Jan 2023 13:15:48 +0000 (14:15 +0100)
committerMarkham <markham001@gmx.de>
Sat, 7 Jan 2023 13:15:48 +0000 (14:15 +0100)
33 files changed:
archive-patches/ffmpeg-cst/5.1.2/0001-aac-optimize0.patch [new file with mode: 0644]
archive-patches/ffmpeg-cst/5.1.2/0002-add64_c-parentheses.patch [new file with mode: 0644]
archive-patches/ffmpeg-cst/5.1.2/0003-cst-add-ASF-VC1-Annex-G-and-RCV-bitstream-filters.patch [new file with mode: 0644]
archive-patches/ffmpeg-cst/5.1.2/0004-cst-allow-to-choose-rtmp-impl-at-runtime.patch [new file with mode: 0644]
archive-patches/ffmpeg-cst/5.1.2/0005-cst-fix-h264-sps-pps.patch [new file with mode: 0644]
archive-patches/ffmpeg-cst/5.1.2/0006-cst-fix-mpegts-pts.patch [new file with mode: 0644]
archive-patches/ffmpeg-cst/5.1.2/0007-disable-whitelist.patch [new file with mode: 0644]
archive-patches/ffmpeg-cst/5.1.2/0008-mov-cenc-fixes.patch [new file with mode: 0644]
archive-patches/ffmpeg-cst/5.1.2/0009-ffmpeg-discont.patch [new file with mode: 0644]
archive-patches/ffmpeg-cst/5.1.2/0010-hls-replace-key-uri.patch [new file with mode: 0644]
archive-patches/ffmpeg-cst/5.1.2/0011-recheck-discard-flags.patch [new file with mode: 0644]
archive-patches/ffmpeg-cst/5.1.2/0012-rtsp.patch [new file with mode: 0644]
archive-patches/ffmpeg-cst/5.1.2/ffmpeg-increase-IO_BUFFER_SIZE-to-256k.patch [new file with mode: 0644]
archive-patches/ffmpeg-cst/5.1.2/optional/README.txt [new file with mode: 0644]
archive-patches/ffmpeg-cst/5.1.2/optional/ffmpeg51-dash-hacks.patch [new file with mode: 0644]
archive-patches/ffmpeg-cst/5.1.2/optional/ffmpeg51-hls-changes.patch [new file with mode: 0644]
archive-patches/ffmpeg-cst/5.1/0001-aac-optimize0.patch [deleted file]
archive-patches/ffmpeg-cst/5.1/0002-add64_c-parentheses.patch [deleted file]
archive-patches/ffmpeg-cst/5.1/0003-cst-add-ASF-VC1-Annex-G-and-RCV-bitstream-filters.patch [deleted file]
archive-patches/ffmpeg-cst/5.1/0004-cst-allow-to-choose-rtmp-impl-at-runtime.patch [deleted file]
archive-patches/ffmpeg-cst/5.1/0005-cst-fix-h264-sps-pps.patch [deleted file]
archive-patches/ffmpeg-cst/5.1/0006-cst-fix-mpegts-pts.patch [deleted file]
archive-patches/ffmpeg-cst/5.1/0007-disable-whitelist.patch [deleted file]
archive-patches/ffmpeg-cst/5.1/0008-mov-cenc-fixes.patch [deleted file]
archive-patches/ffmpeg-cst/5.1/0009-ffmpeg-discont.patch [deleted file]
archive-patches/ffmpeg-cst/5.1/0010-hls-replace-key-uri.patch [deleted file]
archive-patches/ffmpeg-cst/5.1/0011-recheck-discard-flags.patch [deleted file]
archive-patches/ffmpeg-cst/5.1/0012-rtsp.patch [deleted file]
archive-patches/ffmpeg-cst/5.1/ffmpeg-increase-IO_BUFFER_SIZE-to-256k.patch [deleted file]
archive-patches/ffmpeg-cst/5.1/optional/README.txt [deleted file]
archive-patches/ffmpeg-cst/5.1/optional/ffmpeg51-dash-hacks.patch [deleted file]
archive-patches/ffmpeg-cst/5.1/optional/ffmpeg51-hls-changes.patch [deleted file]
make/versions.mk

diff --git a/archive-patches/ffmpeg-cst/5.1.2/0001-aac-optimize0.patch b/archive-patches/ffmpeg-cst/5.1.2/0001-aac-optimize0.patch
new file mode 100644 (file)
index 0000000..ff81c27
--- /dev/null
@@ -0,0 +1,48 @@
+diff --git a/libavcodec/aacps.c b/libavcodec/aacps.c
+index 655e8fe5b4..45190d678d 100644
+--- a/libavcodec/aacps.c
++++ b/libavcodec/aacps.c
+@@ -397,7 +397,7 @@ static void map_val_20_to_34(INTFLOAT par[PS_MAX_NR_IIDICC])
+     par[ 1] = AAC_HALF_SUM(par[ 0], par[ 1]);
+ }
+-static void decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const INTFLOAT (*s)[32][2], int is34)
++static void __attribute__((optimize(0))) decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const INTFLOAT (*s)[32][2], int is34)
+ {
+     LOCAL_ALIGNED_16(INTFLOAT, power, [34], [PS_QMF_TIME_SLOTS]);
+     LOCAL_ALIGNED_16(INTFLOAT, transient_gain, [34], [PS_QMF_TIME_SLOTS]);
+diff --git a/libavcodec/fft_template.c b/libavcodec/fft_template.c
+index f2742a3ae8..59b4085eba 100644
+--- a/libavcodec/fft_template.c
++++ b/libavcodec/fft_template.c
+@@ -551,7 +551,7 @@ static void fft##n(FFTComplex *z)\
+     pass(z,FFT_NAME(ff_cos_##n),n4/2);\
+ }
+-static void fft4(FFTComplex *z)
++static void __attribute__((optimize(0))) fft4(FFTComplex *z)
+ {
+     FFTDouble t1, t2, t3, t4, t5, t6, t7, t8;
+@@ -565,7 +565,7 @@ static void fft4(FFTComplex *z)
+     BF(z[2].im, z[0].im, t2, t5);
+ }
+-static void fft8(FFTComplex *z)
++static void __attribute__((optimize(0))) fft8(FFTComplex *z)
+ {
+     FFTDouble t1, t2, t3, t4, t5, t6;
+diff --git a/libavcodec/mdct_template.c b/libavcodec/mdct_template.c
+index a854ad2700..6119be0d1a 100644
+--- a/libavcodec/mdct_template.c
++++ b/libavcodec/mdct_template.c
+@@ -98,7 +98,7 @@ av_cold int ff_mdct_init(FFTContext *s, int nbits, int inverse, double scale)
+  * @param output N/2 samples
+  * @param input N/2 samples
+  */
+-void ff_imdct_half_c(FFTContext *s, FFTSample *output, const FFTSample *input)
++void __attribute__((optimize(0))) ff_imdct_half_c(FFTContext *s, FFTSample *output, const FFTSample *input)
+ {
+     int k, n8, n4, n2, n, j;
+     const uint16_t *revtab = s->revtab;
diff --git a/archive-patches/ffmpeg-cst/5.1.2/0002-add64_c-parentheses.patch b/archive-patches/ffmpeg-cst/5.1.2/0002-add64_c-parentheses.patch
new file mode 100644 (file)
index 0000000..38b74bf
--- /dev/null
@@ -0,0 +1,14 @@
+diff --git a/libavutil/common.h b/libavutil/common.h
+index fd1404be6c..0bb8650e83 100644
+--- a/libavutil/common.h
++++ b/libavutil/common.h
+@@ -350,7 +350,8 @@ static av_always_inline int64_t av_sat_add64_c(int64_t a, int64_t b) {
+     return !__builtin_add_overflow(a, b, &tmp) ? tmp : (tmp < 0 ? INT64_MAX : INT64_MIN);
+ #else
+     int64_t s = a+(uint64_t)b;
+-    if ((int64_t)(a^b | ~s^b) >= 0)
++    // PATCH: GCC 4.9.4 complains about missing parentheses when combining bitwise operations.
++    if ((int64_t)((a^b) | (~s^b)) >= 0)
+         return INT64_MAX ^ (b >> 63);
+     return s;
+ #endif
diff --git a/archive-patches/ffmpeg-cst/5.1.2/0003-cst-add-ASF-VC1-Annex-G-and-RCV-bitstream-filters.patch b/archive-patches/ffmpeg-cst/5.1.2/0003-cst-add-ASF-VC1-Annex-G-and-RCV-bitstream-filters.patch
new file mode 100644 (file)
index 0000000..86bdb91
--- /dev/null
@@ -0,0 +1,333 @@
+diff --git a/libavcodec/Makefile b/libavcodec/Makefile
+index 457ec58377..49bf260764 100644
+--- a/libavcodec/Makefile
++++ b/libavcodec/Makefile
+@@ -1209,6 +1209,8 @@ OBJS-$(CONFIG_SETTS_BSF)                  += setts_bsf.o
+ OBJS-$(CONFIG_TEXT2MOVSUB_BSF)            += movsub_bsf.o
+ OBJS-$(CONFIG_TRACE_HEADERS_BSF)          += trace_headers_bsf.o
+ OBJS-$(CONFIG_TRUEHD_CORE_BSF)            += truehd_core_bsf.o mlp_parse.o mlp.o
++OBJS-$(CONFIG_VC1_ASFTORCV_BSF)           += vc1_asftorcv_bsf.o
++OBJS-$(CONFIG_VC1_ASFTOANNEXG_BSF)        += vc1_asftoannexg_bsf.o vc1.o
+ OBJS-$(CONFIG_VP9_METADATA_BSF)           += vp9_metadata_bsf.o
+ OBJS-$(CONFIG_VP9_RAW_REORDER_BSF)        += vp9_raw_reorder_bsf.o
+ OBJS-$(CONFIG_VP9_SUPERFRAME_BSF)         += vp9_superframe_bsf.o
+diff --git a/libavcodec/bitstream_filters.c b/libavcodec/bitstream_filters.c
+index 444423ae93..482d3473b2 100644
+--- a/libavcodec/bitstream_filters.c
++++ b/libavcodec/bitstream_filters.c
+@@ -59,6 +59,8 @@ extern const FFBitStreamFilter ff_setts_bsf;
+ extern const FFBitStreamFilter ff_text2movsub_bsf;
+ extern const FFBitStreamFilter ff_trace_headers_bsf;
+ extern const FFBitStreamFilter ff_truehd_core_bsf;
++extern const FFBitStreamFilter ff_vc1_asftoannexg_bsf;
++extern const FFBitStreamFilter ff_vc1_asftorcv_bsf;
+ extern const FFBitStreamFilter ff_vp9_metadata_bsf;
+ extern const FFBitStreamFilter ff_vp9_raw_reorder_bsf;
+ extern const FFBitStreamFilter ff_vp9_superframe_bsf;
+diff --git a/libavcodec/vc1_asftoannexg_bsf.c b/libavcodec/vc1_asftoannexg_bsf.c
+new file mode 100644
+index 0000000000..2901f84d9c
+--- /dev/null
++++ b/libavcodec/vc1_asftoannexg_bsf.c
+@@ -0,0 +1,190 @@
++/*
++ * copyright (c) 2010 Google Inc.
++ * copyright (c) 2013 CoolStream International Ltd.
++ * copyright (c) 2017 Jacek Jendrzej port to 3.x
++ * This file is part of FFmpeg.
++ *
++ * FFmpeg is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * FFmpeg is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include "avcodec.h"
++#include "bytestream.h"
++#include "vc1.h"
++#include "bsf.h"
++#include "bsf_internal.h"
++
++// An arbitrary limit in bytes greater than the current bytes used.
++#define MAX_SEQ_HEADER_SIZE 50
++
++typedef struct ASFTOANNEXGBSFContext {
++    int frames;
++    uint8_t *seq_header;
++    int seq_header_size;
++    uint8_t *ep_header;
++    int ep_header_size;
++} ASFTOANNEXGBSFContext;
++
++static int find_codec_data(ASFTOANNEXGBSFContext *ctx, uint8_t *data, int data_size, int keyframe) {
++    const uint8_t *start = data;
++    const uint8_t *end = data + data_size;
++    const uint8_t *next;
++    int size;
++    int has_seq_header = 0;
++    int has_ep_header = 0;
++    int has_frame_header = 0;
++
++    start = find_next_marker(start, end);
++    next = start;
++    for(; next < end; start = next){
++        next = find_next_marker(start + 4, end);
++        size = next - start;
++        if(size <= 0) continue;
++        switch(AV_RB32(start)){
++        case VC1_CODE_SEQHDR:
++            has_seq_header = 1;
++            break;
++        case VC1_CODE_ENTRYPOINT:
++            has_ep_header = 1;
++            break;
++        case VC1_CODE_FRAME:
++            has_frame_header = 1;
++            break;
++        default:
++            break;
++        }
++    }
++
++    if((has_seq_header && has_ep_header && has_frame_header && keyframe) ||
++       (!has_seq_header && !has_ep_header && has_frame_header) ) return 0;
++
++    return -1;
++}
++
++static int parse_extradata(ASFTOANNEXGBSFContext *ctx, uint8_t *extradata, int extradata_size) {
++    const uint8_t *start = extradata;
++    const uint8_t *end = extradata + extradata_size;
++    const uint8_t *next;
++    int size;
++
++    start = find_next_marker(start, end);
++    next = start;
++    for(; next < end; start = next){
++        next = find_next_marker(start + 4, end);
++        size = next - start;
++        if(size <= 0) continue;
++        switch(AV_RB32(start)){
++        case VC1_CODE_SEQHDR:
++            ctx->seq_header = av_mallocz(size);
++            ctx->seq_header_size = size;
++            memcpy(ctx->seq_header, start, size);
++            break;
++        case VC1_CODE_ENTRYPOINT:
++            ctx->ep_header = av_malloc(size);
++            ctx->ep_header_size = size;
++            memcpy(ctx->ep_header, start, size);
++            break;
++        default:
++            break;
++        }
++    }
++
++    if(!ctx->seq_header || !ctx->ep_header) {
++        av_log(NULL, AV_LOG_ERROR, "Incomplete extradata\n");
++        return -1;
++    }
++    return 0;
++}
++
++static int asftoannexg_filter(AVBSFContext *ctx, AVPacket *out)
++{
++    ASFTOANNEXGBSFContext* bsfctx = ctx->priv_data;
++    AVPacket *in;
++    int keyframe;
++    int ret;
++    uint8_t* bs = NULL;
++
++    ret = ff_bsf_get_packet(ctx, &in);
++    if (ret < 0)
++        return ret;
++
++    keyframe = in->flags & AV_PKT_FLAG_KEY;
++    if(in->size >= 1 && !find_codec_data(bsfctx, in->data, in->size, keyframe)) {
++//         av_log(NULL, AV_LOG_INFO, "Nothing to do: %i\n",in->size);
++        av_packet_move_ref(out, in);
++        av_packet_free(&in);
++        return 0;
++    }
++
++    if(!ctx->par_in->extradata || ctx->par_in->extradata_size < 16) {
++        av_log(NULL, AV_LOG_INFO, "Extradata size too small: %i\n", ctx->par_in->extradata_size);
++        av_packet_move_ref(out, in);
++        av_packet_free(&in);
++        return 0;
++    }
++
++    if (!bsfctx->frames && parse_extradata(bsfctx, ctx->par_in->extradata , ctx->par_in->extradata_size) < 0) {
++        av_packet_free(&in);
++        av_log(NULL, AV_LOG_ERROR, "Cannot parse extra data!\n");
++        return -1;
++    }
++
++    if (keyframe) {
++        // If this is the keyframe, need to put sequence header and entry point header.
++        ret = av_new_packet(out, bsfctx->seq_header_size + bsfctx->ep_header_size + 4 + in->size);
++        if (ret < 0)
++            goto exit;
++        bs = out->data;
++
++        memcpy(bs, bsfctx->seq_header, bsfctx->seq_header_size);
++        bs += bsfctx->seq_header_size;
++        memcpy(bs, bsfctx->ep_header, bsfctx->ep_header_size);
++        bs += bsfctx->ep_header_size;
++    } else {
++        ret = av_new_packet(out, 4 + in->size);
++        if (ret < 0)
++            goto exit;
++        bs = out->data;
++    }
++
++    // Put the frame start code and frame data.
++    bytestream_put_be32(&bs, VC1_CODE_FRAME);
++    memcpy(bs, in->data, in->size);
++    ++bsfctx->frames;
++
++    ret = av_packet_copy_props(out, in);
++
++exit:
++    av_packet_free(&in);
++
++    return ret;
++}
++
++static void asftoannexg_close(AVBSFContext *bsfc) {
++    ASFTOANNEXGBSFContext *bsfctx = bsfc->priv_data;
++    av_freep(&bsfctx->seq_header);
++    av_freep(&bsfctx->ep_header);
++}
++
++static const enum AVCodecID codec_ids[] = {
++    AV_CODEC_ID_VC1, AV_CODEC_ID_NONE,
++};
++
++FFBitStreamFilter ff_vc1_asftoannexg_bsf = {
++    .p.name         = "vc1_asftoannexg",
++    .priv_data_size = sizeof(ASFTOANNEXGBSFContext),
++    .filter         = asftoannexg_filter,
++    .close          = asftoannexg_close,
++    .p.codec_ids    = codec_ids,
++};
+diff --git a/libavcodec/vc1_asftorcv_bsf.c b/libavcodec/vc1_asftorcv_bsf.c
+new file mode 100644
+index 0000000000..02e510b4b6
+--- /dev/null
++++ b/libavcodec/vc1_asftorcv_bsf.c
+@@ -0,0 +1,105 @@
++/*
++ * copyright (c) 2010 Google Inc.
++ * copyright (c) 2017 Jacek Jendrzej port to 3.x
++ * This file is part of FFmpeg.
++ *
++ * FFmpeg is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * FFmpeg is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include "avcodec.h"
++#include "bytestream.h"
++#include "bsf.h"
++#include "bsf_internal.h"
++
++#define RCV_STREAM_HEADER_SIZE 36
++#define RCV_PICTURE_HEADER_SIZE 8
++
++typedef struct ASFTORCVBSFContext {
++    int frames;
++} ASFTORCVBSFContext;
++
++static int asftorcv_filter(AVBSFContext *ctx, AVPacket *out){
++    ASFTORCVBSFContext* bsfctx = ctx->priv_data;
++    AVPacket *in;
++    int keyframe;
++    int ret;
++    uint8_t* bs = NULL;
++
++    ret = ff_bsf_get_packet(ctx, &in);
++    if (ret < 0)
++        return ret;
++
++    keyframe = in->flags & AV_PKT_FLAG_KEY;
++
++    if (!bsfctx->frames) {
++        // Write the header if this is the first frame.
++        ret = av_new_packet(out, RCV_STREAM_HEADER_SIZE + RCV_PICTURE_HEADER_SIZE + in->size);
++        if (ret < 0)
++            goto exit;
++        bs = out->data;
++
++        // The following structure of stream header comes from libavformat/vc1testenc.c.
++        bytestream_put_le24(&bs, 0);  // Frame count. 0 for streaming.
++        bytestream_put_byte(&bs, 0xC5);
++        bytestream_put_le32(&bs, 4);  // 4 bytes of extra data.
++        bytestream_put_byte(&bs, ctx->par_in->extradata[0]);
++        bytestream_put_byte(&bs, ctx->par_in->extradata[1]);
++        bytestream_put_byte(&bs, ctx->par_in->extradata[2]);
++        bytestream_put_byte(&bs, ctx->par_in->extradata[3]);
++        bytestream_put_le32(&bs, ctx->par_in->height);
++        bytestream_put_le32(&bs, ctx->par_in->width);
++        bytestream_put_le32(&bs, 0xC);
++        bytestream_put_le24(&bs, 0);  // hrd_buffer
++        bytestream_put_byte(&bs, 0x80);  // level|cbr|res1
++        bytestream_put_le32(&bs, 0);  // hrd_rate
++
++        // The following LE32 describes the frame rate. Since we don't care so fill
++        // it with 0xFFFFFFFF which means variable framerate.
++        // See: libavformat/vc1testenc.c
++        bytestream_put_le32(&bs, 0xFFFFFFFF);
++    } else {
++        ret = av_new_packet(out, RCV_PICTURE_HEADER_SIZE + in->size);
++        if (ret < 0)
++            goto exit;
++        bs = out->data;
++    }
++
++    // Write the picture header.
++    bytestream_put_le32(&bs, in->size | (keyframe ? 0x80000000 : 0));
++
++    //  The following LE32 describes the pts. Since we don't care so fill it with 0.
++    bytestream_put_le32(&bs, 0);
++    memcpy(bs, in->data, in->size);
++
++    ++bsfctx->frames;
++
++    ret = av_packet_copy_props(out, in);
++
++exit:
++    av_packet_free(&in);
++
++    return ret;
++}
++
++static const enum AVCodecID codec_ids[] = {
++    AV_CODEC_ID_WMV3, AV_CODEC_ID_NONE,
++};
++
++FFBitStreamFilter ff_vc1_asftorcv_bsf = {
++    .p.name       = "vc1_asftorcv",
++    .priv_data_size = sizeof(ASFTORCVBSFContext),
++    .filter         = asftorcv_filter,
++    .p.codec_ids    = codec_ids,
++};
diff --git a/archive-patches/ffmpeg-cst/5.1.2/0004-cst-allow-to-choose-rtmp-impl-at-runtime.patch b/archive-patches/ffmpeg-cst/5.1.2/0004-cst-allow-to-choose-rtmp-impl-at-runtime.patch
new file mode 100644 (file)
index 0000000..9360812
--- /dev/null
@@ -0,0 +1,132 @@
+diff --git a/configure b/configure
+index ba5793b2ff..b199365427 100755
+--- a/configure
++++ b/configure
+@@ -3549,10 +3549,8 @@ xv_outdev_deps="xlib_xv xlib_x11 xlib_xext"
+ # protocols
+ async_protocol_deps="threads"
+ bluray_protocol_deps="libbluray"
+-ffrtmpcrypt_protocol_conflict="librtmp_protocol"
+ ffrtmpcrypt_protocol_deps_any="gcrypt gmp openssl mbedtls"
+ ffrtmpcrypt_protocol_select="tcp_protocol"
+-ffrtmphttp_protocol_conflict="librtmp_protocol"
+ ffrtmphttp_protocol_select="http_protocol"
+ ftp_protocol_select="tcp_protocol"
+ gopher_protocol_select="tcp_protocol"
+@@ -3566,20 +3564,18 @@ https_protocol_suggest="zlib"
+ icecast_protocol_select="http_protocol"
+ mmsh_protocol_select="http_protocol"
+ mmst_protocol_select="network"
+-rtmp_protocol_conflict="librtmp_protocol"
+-rtmp_protocol_select="tcp_protocol"
+-rtmp_protocol_suggest="zlib"
+-rtmpe_protocol_select="ffrtmpcrypt_protocol"
+-rtmpe_protocol_suggest="zlib"
+-rtmps_protocol_conflict="librtmp_protocol"
+-rtmps_protocol_select="tls_protocol"
+-rtmps_protocol_suggest="zlib"
+-rtmpt_protocol_select="ffrtmphttp_protocol"
+-rtmpt_protocol_suggest="zlib"
+-rtmpte_protocol_select="ffrtmpcrypt_protocol ffrtmphttp_protocol"
+-rtmpte_protocol_suggest="zlib"
+-rtmpts_protocol_select="ffrtmphttp_protocol https_protocol"
+-rtmpts_protocol_suggest="zlib"
++ffrtmp_protocol_select="tcp_protocol"
++ffrtmp_protocol_suggest="zlib"
++ffrtmpe_protocol_select="ffrtmpcrypt_protocol"
++ffrtmpe_protocol_suggest="zlib"
++ffrtmps_protocol_select="tls_protocol"
++ffrtmps_protocol_suggest="zlib"
++ffrtmpt_protocol_select="ffrtmphttp_protocol"
++ffrtmpt_protocol_suggest="zlib"
++ffrtmpte_protocol_select="ffrtmpcrypt_protocol ffrtmphttp_protocol"
++ffrtmpte_protocol_suggest="zlib"
++ffrtmpts_protocol_select="ffrtmphttp_protocol https_protocol"
++ffrtmpts_protocol_suggest="zlib"
+ rtp_protocol_select="udp_protocol"
+ schannel_conflict="openssl gnutls libtls mbedtls"
+ sctp_protocol_deps="struct_sctp_event_subscribe struct_msghdr_msg_flags"
+diff --git a/libavformat/Makefile b/libavformat/Makefile
+index 6c6b779080..f641b43de6 100644
+--- a/libavformat/Makefile
++++ b/libavformat/Makefile
+@@ -656,12 +656,12 @@ OBJS-$(CONFIG_MMSH_PROTOCOL)             += mmsh.o mms.o asf_tags.o
+ OBJS-$(CONFIG_MMST_PROTOCOL)             += mmst.o mms.o asf_tags.o
+ OBJS-$(CONFIG_PIPE_PROTOCOL)             += file.o
+ OBJS-$(CONFIG_PROMPEG_PROTOCOL)          += prompeg.o
+-OBJS-$(CONFIG_RTMP_PROTOCOL)             += rtmpproto.o rtmpdigest.o rtmppkt.o
+-OBJS-$(CONFIG_RTMPE_PROTOCOL)            += rtmpproto.o rtmpdigest.o rtmppkt.o
+-OBJS-$(CONFIG_RTMPS_PROTOCOL)            += rtmpproto.o rtmpdigest.o rtmppkt.o
+-OBJS-$(CONFIG_RTMPT_PROTOCOL)            += rtmpproto.o rtmpdigest.o rtmppkt.o
+-OBJS-$(CONFIG_RTMPTE_PROTOCOL)           += rtmpproto.o rtmpdigest.o rtmppkt.o
+-OBJS-$(CONFIG_RTMPTS_PROTOCOL)           += rtmpproto.o rtmpdigest.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMP_PROTOCOL)           += rtmpproto.o rtmpdigest.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMPE_PROTOCOL)          += rtmpproto.o rtmpdigest.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMPS_PROTOCOL)          += rtmpproto.o rtmpdigest.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMPT_PROTOCOL)          += rtmpproto.o rtmpdigest.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMPTE_PROTOCOL)         += rtmpproto.o rtmpdigest.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMPTS_PROTOCOL)         += rtmpproto.o rtmpdigest.o rtmppkt.o
+ OBJS-$(CONFIG_RTP_PROTOCOL)              += rtpproto.o ip.o
+ OBJS-$(CONFIG_SCTP_PROTOCOL)             += sctp.o
+ OBJS-$(CONFIG_SRTP_PROTOCOL)             += srtpproto.o srtp.o
+diff --git a/libavformat/protocols.c b/libavformat/protocols.c
+index 6ee62a598a..3480a2b521 100644
+--- a/libavformat/protocols.c
++++ b/libavformat/protocols.c
+@@ -44,12 +44,12 @@ extern const URLProtocol ff_mmst_protocol;
+ extern const URLProtocol ff_md5_protocol;
+ extern const URLProtocol ff_pipe_protocol;
+ extern const URLProtocol ff_prompeg_protocol;
+-extern const URLProtocol ff_rtmp_protocol;
+-extern const URLProtocol ff_rtmpe_protocol;
+-extern const URLProtocol ff_rtmps_protocol;
+-extern const URLProtocol ff_rtmpt_protocol;
+-extern const URLProtocol ff_rtmpte_protocol;
+-extern const URLProtocol ff_rtmpts_protocol;
++extern const URLProtocol ff_ffrtmp_protocol;
++extern const URLProtocol ff_ffrtmpe_protocol;
++extern const URLProtocol ff_ffrtmps_protocol;
++extern const URLProtocol ff_ffrtmpt_protocol;
++extern const URLProtocol ff_ffrtmpte_protocol;
++extern const URLProtocol ff_ffrtmpts_protocol;
+ extern const URLProtocol ff_rtp_protocol;
+ extern const URLProtocol ff_sctp_protocol;
+ extern const URLProtocol ff_srtp_protocol;
+diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
+index f0ef223f05..53a078b426 100644
+--- a/libavformat/rtmpproto.c
++++ b/libavformat/rtmpproto.c
+@@ -2594,7 +2594,7 @@ static int inject_fake_duration_metadata(RTMPContext *rt)
+ static int rtmp_open(URLContext *s, const char *uri, int flags, AVDictionary **opts)
+ {
+     RTMPContext *rt = s->priv_data;
+-    char proto[8], hostname[256], path[1024], auth[100], *fname;
++    char *proto, tmpProto[10], hostname[256], path[1024], auth[100], *fname;
+     char *old_app, *qmark, *n, fname_buffer[1024];
+     uint8_t buf[2048];
+     int port;
+@@ -2605,7 +2605,7 @@ static int rtmp_open(URLContext *s, const char *uri, int flags, AVDictionary **o
+     rt->is_input = !(flags & AVIO_FLAG_WRITE);
+-    av_url_split(proto, sizeof(proto), auth, sizeof(auth),
++    memset(tmpProto, 0, sizeof(tmpProto)); proto = &tmpProto[2]; av_url_split(tmpProto, sizeof(tmpProto), auth, sizeof(auth),
+                  hostname, sizeof(hostname), &port,
+                  path, sizeof(path), s->filename);
+@@ -3151,9 +3151,9 @@ const URLProtocol ff_##flavor##_protocol = {     \
+ #define RTMP_PROTOCOL(flavor, uppercase)         \
+     RTMP_PROTOCOL_3(flavor, CONFIG_ ## uppercase ## _PROTOCOL)
+-RTMP_PROTOCOL(rtmp,   RTMP)
+-RTMP_PROTOCOL(rtmpe,  RTMPE)
+-RTMP_PROTOCOL(rtmps,  RTMPS)
+-RTMP_PROTOCOL(rtmpt,  RTMPT)
+-RTMP_PROTOCOL(rtmpte, RTMPTE)
+-RTMP_PROTOCOL(rtmpts, RTMPTS)
++RTMP_PROTOCOL(ffrtmp,   FFRTMP)
++RTMP_PROTOCOL(ffrtmpe,  FFRTMPE)
++RTMP_PROTOCOL(ffrtmps,  FFRTMPS)
++RTMP_PROTOCOL(ffrtmpt,  FFRTMPT)
++RTMP_PROTOCOL(ffrtmpte, FFRTMPTE)
++RTMP_PROTOCOL(ffrtmpts, FFRTMPTS)
diff --git a/archive-patches/ffmpeg-cst/5.1.2/0005-cst-fix-h264-sps-pps.patch b/archive-patches/ffmpeg-cst/5.1.2/0005-cst-fix-h264-sps-pps.patch
new file mode 100644 (file)
index 0000000..338ff1b
--- /dev/null
@@ -0,0 +1,27 @@
+# Test case: The.Purge.2013.1080p.BluRay.x264.YIFY.mp4
+From 1c7b83f945e710a17a41ad9feb7dc929f26f2b0e Mon Sep 17 00:00:00 2001
+From: Jacek Jendrzej <satbaby@kawaii.com>
+Date: Wed, 28 Jun 2017 11:38:20 +0200
+Subject: [PATCH] fix sps/pps for cooli;This is commit that breaks seek in some
+ mkv.break with commit 6d2219e9f950b96279fd8464cc11c4d02518b629
+
+---
+ libavcodec/h264_mp4toannexb_bsf.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/libavcodec/h264_mp4toannexb_bsf.c b/libavcodec/h264_mp4toannexb_bsf.c
+index 2822644b10..d57647d25c 100644
+--- a/libavcodec/h264_mp4toannexb_bsf.c
++++ b/libavcodec/h264_mp4toannexb_bsf.c
+@@ -242,6 +242,11 @@ static int h264_mp4toannexb_filter(AVBSFContext *ctx, AVPacket *opkt)
+             if (!new_idr && unit_type == H264_NAL_IDR_SLICE && (buf[1] & 0x80))
+                 new_idr = 1;
+
++            if (s->new_idr && unit_type == H264_NAL_SEI && s->idr_sps_seen && s->idr_pps_seen) {
++                s->idr_sps_seen = 0;
++                s->idr_pps_seen = 0;
++            }
++
+             /* prepend only to the first type 5 NAL unit of an IDR picture, if no sps/pps are already present */
+             if (new_idr && unit_type == H264_NAL_IDR_SLICE && !sps_seen && !pps_seen) {
+                 if (ctx->par_out->extradata)
diff --git a/archive-patches/ffmpeg-cst/5.1.2/0006-cst-fix-mpegts-pts.patch b/archive-patches/ffmpeg-cst/5.1.2/0006-cst-fix-mpegts-pts.patch
new file mode 100644 (file)
index 0000000..534e404
--- /dev/null
@@ -0,0 +1,17 @@
+diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
+index 8a3436f2be..abdfe41d85 100644
+--- a/libavformat/mpegts.c
++++ b/libavformat/mpegts.c
+@@ -1037,10 +1037,10 @@ static int new_pes_packet(PESContext *pes, AVPacket *pkt)
+     pes->buffer = NULL;
+     reset_pes_packet_state(pes);
+-    sd = av_packet_new_side_data(pkt, AV_PKT_DATA_MPEGTS_STREAM_ID, 1);
++    /*sd = av_packet_new_side_data(pkt, AV_PKT_DATA_MPEGTS_STREAM_ID, 1);
+     if (!sd)
+         return AVERROR(ENOMEM);
+-    *sd = pes->stream_id;
++    *sd = pes->stream_id;*/
+     return 0;
+ }
diff --git a/archive-patches/ffmpeg-cst/5.1.2/0007-disable-whitelist.patch b/archive-patches/ffmpeg-cst/5.1.2/0007-disable-whitelist.patch
new file mode 100644 (file)
index 0000000..343b124
--- /dev/null
@@ -0,0 +1,19 @@
+diff --git a/libavformat/avio.c b/libavformat/avio.c\r
+index 4846bbd8c6..978bf72994 100644\r
+--- a/libavformat/avio.c\r
++++ b/libavformat/avio.c\r
+@@ -177,12 +177,12 @@ int ffurl_connect(URLContext *uc, AVDictionary **options)\r
+                (uc->protocol_whitelist && !strcmp(uc->protocol_whitelist, e->value)));\r
+     av_assert0(!(e=av_dict_get(*options, "protocol_blacklist", NULL, 0)) ||\r
+                (uc->protocol_blacklist && !strcmp(uc->protocol_blacklist, e->value)));\r
+-\r
++/*\r
+     if (uc->protocol_whitelist && av_match_list(uc->prot->name, uc->protocol_whitelist, ',') <= 0) {\r
+         av_log(uc, AV_LOG_ERROR, "Protocol '%s' not on whitelist '%s'!\n", uc->prot->name, uc->protocol_whitelist);\r
+         return AVERROR(EINVAL);\r
+     }\r
+-\r
++*/\r
+     if (uc->protocol_blacklist && av_match_list(uc->prot->name, uc->protocol_blacklist, ',') > 0) {\r
+         av_log(uc, AV_LOG_ERROR, "Protocol '%s' on blacklist '%s'!\n", uc->prot->name, uc->protocol_blacklist);\r
+         return AVERROR(EINVAL);\r
diff --git a/archive-patches/ffmpeg-cst/5.1.2/0008-mov-cenc-fixes.patch b/archive-patches/ffmpeg-cst/5.1.2/0008-mov-cenc-fixes.patch
new file mode 100644 (file)
index 0000000..42c9e57
--- /dev/null
@@ -0,0 +1,210 @@
+diff --git a/libavformat/mov.c b/libavformat/mov.c
+index 2b1131b911..bf56b41eb3 100644
+--- a/libavformat/mov.c
++++ b/libavformat/mov.c
+@@ -1237,6 +1237,36 @@ static MOVFragmentStreamInfo * get_current_frag_stream_info(
+     return NULL;
+ }
++static MOVFragmentStreamInfo * get_frag_stream_by_sample_index(
++    MOVFragmentIndex *frag_index,
++    int sample_index,
++    int stream_id,
++    int *found_index)
++{
++    int i, j;
++    MOVFragmentIndexItem * item;
++
++    for (i = 0; i < frag_index->nb_items; i++) {
++        item = &frag_index->item[i];
++        for (j = 0; j < item->nb_stream_info; j++) {
++            if (item->stream_info[j].id == stream_id &&
++                item->stream_info[j].index_entry >= sample_index &&
++                (i == frag_index->nb_items - 1 ||
++                 (frag_index->item[i+1].nb_stream_info > j &&
++                  (frag_index->item[i+1].stream_info[j].index_entry == -1 ||
++                   sample_index < frag_index->item[i+1].stream_info[j].index_entry)))) {
++                if (found_index) {
++                    *found_index = i;
++                }
++                return &item->stream_info[j];
++            }
++        }
++    }
++
++    // This shouldn't happen
++    return NULL;
++}
++
+ static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
+ {
+     int a, b, m;
+@@ -5118,7 +5148,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+     sc->ctts_count = sti->nb_index_entries;
+     // Record the index_entry position in frag_index of this fragment
+-    if (frag_stream_info)
++    if (frag_stream_info && frag_stream_info->index_entry == -1)  // BUGFIX: In case of multiple trun, this must remain at the first value
+         frag_stream_info->index_entry = index_entry_pos;
+     if (index_entry_pos > 0)
+@@ -5986,6 +6016,8 @@ out:
+     return ret;
+ }
++static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom);
++
+ static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+ {
+     AVStream *st;
+@@ -6004,6 +6036,10 @@ static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+         0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
+         0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
+     };
++    static const AVUUID uuid_piff_senc = {
++        0xA2, 0x39, 0x4F, 0x52, 0x5A, 0x9B, 0x4f, 0x14,
++        0xA2, 0x44, 0x6C, 0x42, 0x7C, 0x64, 0x8D, 0xF4
++    };
+     if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
+         return AVERROR_INVALIDDATA;
+@@ -6086,6 +6122,9 @@ static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+             return ret;
+         if (!sc->spherical)
+             av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
++    } else if (av_uuid_equal(uuid, uuid_piff_senc)) {
++        // PATCH: Netflix's stream packager outputs PIFF, which uses an uuid atom for senc boxes.
++        mov_read_senc(c, pb, atom);
+     }
+     return 0;
+@@ -6407,7 +6446,12 @@ static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
+         offset += to_read;
+     }
+-    *data = buffer;
++    // PATCH: The original code leads to huge amounts of memory being hogged during playback (especially CENC streams).
++    *data = av_realloc(buffer, size);
++    if (!*data) {
++        av_free(buffer);
++        return AVERROR(ENOMEM);
++    }
+     return 0;
+ }
+@@ -7026,15 +7070,16 @@ static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryption
+     }
+     /* whole-block full sample encryption */
+-    if (!sample->subsample_count) {
++    // PATCH: Fix for Apple TV+, they have subsamples but don't use pattern encryption.
++    if (!sample->subsample_count || (!sample->crypt_byte_block && !sample->skip_byte_block)) {
+         /* decrypt the whole packet */
+         memcpy(iv, sample->iv, 16);
+         av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
+         return 0;
+-    } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
++    }/* else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
+         av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
+         return AVERROR_INVALIDDATA;
+-    }
++    }*/
+     for (i = 0; i < sample->subsample_count; i++) {
+         if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
+@@ -7102,10 +7147,20 @@ static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPa
+         // Note this only supports encryption info in the first sample descriptor.
+         if (mov->fragment.stsd_id == 1) {
+             if (frag_stream_info->encryption_index) {
+-                if (!current_index && frag_stream_info->index_entry)
++                // PATCH: Fix seeking backwards in encrypted streams.
++                //av_log(mov->fc, AV_LOG_INFO, "Frag Id: %d Index: %d (frag entry: %d)\n", frag_stream_info->id, current_index, frag_stream_info->index_entry);
++                encrypted_index = current_index - frag_stream_info->index_entry;
++                encryption_index = frag_stream_info->encryption_index;
++                if (encrypted_index < 0 || encrypted_index >= encryption_index->nb_encrypted_samples) {
++                    frag_stream_info = get_frag_stream_by_sample_index(&mov->frag_index, current_index, st->id,
++                                                                        &mov->frag_index.current);
++                    encrypted_index = current_index - frag_stream_info->index_entry;
++                    encryption_index = frag_stream_info->encryption_index;
++                }
++                /*if (!current_index && frag_stream_info->index_entry)
+                     sc->cenc.frag_index_entry_base = frag_stream_info->index_entry;
+                 encrypted_index = current_index - (frag_stream_info->index_entry - sc->cenc.frag_index_entry_base);
+-                encryption_index = frag_stream_info->encryption_index;
++                encryption_index = frag_stream_info->encryption_index;*/
+             } else {
+                 encryption_index = sc->cenc.encryption_index;
+             }
+@@ -7133,8 +7188,9 @@ static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPa
+             // Per-sample setting override.
+             encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
+         } else {
+-            av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
+-            return AVERROR_INVALIDDATA;
++            av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info (index %d, nb %d)\n", encrypted_index, encryption_index->nb_encrypted_samples);
++            return 0; // CST hack - this can sometimes happen while seeking/switching audio streams, it's a non-fatal error.
++            //return AVERROR_INVALIDDATA;
+         }
+         if (mov->decryption_key) {
+@@ -8572,15 +8628,16 @@ static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
+     if (index >= 0 && index < mov->frag_index.nb_items)
+         target = mov->frag_index.item[index].moof_offset;
+-    if (avio_seek(s->pb, target, SEEK_SET) != target) {
++    // https://ffmpeg.org/pipermail/ffmpeg-devel/2020-April/261343.html
++    if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
+         av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
+         return AVERROR_INVALIDDATA;
+     }
+     mov->next_root_atom = 0;
+-    if (index < 0 || index >= mov->frag_index.nb_items)
++    if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
+         index = search_frag_moof_offset(&mov->frag_index, target);
+-    if (index < mov->frag_index.nb_items &&
++    if (index >= 0 && index < mov->frag_index.nb_items &&
+         mov->frag_index.item[index].moof_offset == target) {
+         if (index + 1 < mov->frag_index.nb_items)
+             mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
+@@ -8653,8 +8710,40 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
+     AVStream *st = NULL;
+     int64_t current_index;
+     int ret;
++    int i;
+     mov->fc = s;
+  retry:
++    // https://ffmpeg.org/pipermail/ffmpeg-devel/2020-April/261343.html
++    if (s->pb->pos == 0) {
++
++        // Discard current fragment index
++        if (mov->frag_index.allocated_size > 0) {
++            av_freep(&mov->frag_index.item);
++            mov->frag_index.nb_items = 0;
++            mov->frag_index.allocated_size = 0;
++            mov->frag_index.current = -1;
++            mov->frag_index.complete = 0;
++        }
++
++        for (i = 0; i < s->nb_streams; i++) {
++            AVStream *avst = s->streams[i];
++            FFStream *const avsti = ffstream(avst);
++            MOVStreamContext *msc = avst->priv_data;
++
++            // Clear current sample
++            mov_current_sample_set(msc, 0);
++
++            // Discard current index entries
++            if (avsti->index_entries_allocated_size > 0) {
++                av_freep(&avsti->index_entries);
++                avsti->index_entries_allocated_size = 0;
++                avsti->nb_index_entries = 0;
++            }
++        }
++
++        if ((ret = mov_switch_root(s, -1, -1)) < 0)
++            return ret;
++    }
+     sample = mov_find_next_sample(s, &st);
+     if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
+         if (!mov->next_root_atom)
diff --git a/archive-patches/ffmpeg-cst/5.1.2/0009-ffmpeg-discont.patch b/archive-patches/ffmpeg-cst/5.1.2/0009-ffmpeg-discont.patch
new file mode 100644 (file)
index 0000000..71f3bb4
--- /dev/null
@@ -0,0 +1,124 @@
+diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
+index e7384f052a..bc75fe3df6 100644
+--- a/fftools/ffmpeg.c
++++ b/fftools/ffmpeg.c
+@@ -4080,7 +4080,7 @@ static int process_input(int file_index)
+     if ((ist->dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO ||
+          ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) &&
+         pkt_dts != AV_NOPTS_VALUE && ist->next_dts == AV_NOPTS_VALUE && !copy_ts
+-        && (is->iformat->flags & AVFMT_TS_DISCONT) && ifile->last_ts != AV_NOPTS_VALUE) {
++        && (is->iformat->flags & AVFMT_TS_DISCONT) && ifile->last_ts != AV_NOPTS_VALUE && !force_dts_monotonicity) {
+         int64_t delta   = pkt_dts - ifile->last_ts;
+         if (delta < -1LL*dts_delta_threshold*AV_TIME_BASE ||
+             delta >  1LL*dts_delta_threshold*AV_TIME_BASE){
+@@ -4118,7 +4118,7 @@ static int process_input(int file_index)
+     if ((ist->dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO ||
+          ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) &&
+          pkt_dts != AV_NOPTS_VALUE && ist->next_dts != AV_NOPTS_VALUE &&
+-        !disable_discontinuity_correction) {
++        !disable_discontinuity_correction && !force_dts_monotonicity) {
+         int64_t delta   = pkt_dts - ist->next_dts;
+         if (is->iformat->flags & AVFMT_TS_DISCONT) {
+             if (delta < -1LL*dts_delta_threshold*AV_TIME_BASE ||
+@@ -4156,6 +4156,43 @@ static int process_input(int file_index)
+     if (pkt->dts != AV_NOPTS_VALUE)
+         ifile->last_ts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q);
++    if ((ist->dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO ||
++         ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) &&
++        (pkt->pts != AV_NOPTS_VALUE || pkt->dts != AV_NOPTS_VALUE) &&
++        force_dts_monotonicity) {
++        int64_t ff_pts_error = 0;
++        int64_t ff_dts_error = 0;
++        int64_t ff_dts_threshold = av_rescale_q(dts_monotonicity_threshold, AV_TIME_BASE_Q, ist->st->time_base);
++
++        // adjust the incoming packet by the accumulated monotonicity error
++        if (pkt->pts != AV_NOPTS_VALUE) {
++            pkt->pts += ifile->ff_timestamp_monotonicity_offset;
++            if (ist->next_pts != AV_NOPTS_VALUE) {
++                ff_pts_error = av_rescale_q(ist->next_pts, AV_TIME_BASE_Q, ist->st->time_base) - pkt->pts;
++            }
++        }
++        if (pkt->dts != AV_NOPTS_VALUE) {
++            pkt->dts += ifile->ff_timestamp_monotonicity_offset;
++            if (ist->next_dts != AV_NOPTS_VALUE) {
++                ff_dts_error = av_rescale_q(ist->next_dts, AV_TIME_BASE_Q, ist->st->time_base) - pkt->dts;
++            }
++        }
++
++        if (ff_dts_error > 0 || ff_dts_error < (-ff_dts_threshold) || ff_pts_error < (-ff_dts_threshold)) {
++            if (pkt->dts == AV_NOPTS_VALUE /*|| ist->next_dts != AV_NOPTS_VALUE*/) {
++                pkt->pts += ff_pts_error;
++                ifile->ff_timestamp_monotonicity_offset += ff_pts_error;
++                av_log(is, AV_LOG_INFO, "Incoming PTS error %"PRId64", offsetting subsequent timestamps by %"PRId64" to correct\n", ff_pts_error, ifile->ff_timestamp_monotonicity_offset);
++            }
++            else {
++                pkt->pts += ff_dts_error;
++                pkt->dts += ff_dts_error;
++                ifile->ff_timestamp_monotonicity_offset += ff_dts_error;
++                av_log(is, AV_LOG_INFO, "Incoming DTS error %"PRId64", offsetting subsequent timestamps by %"PRId64" to correct\n", ff_dts_error, ifile->ff_timestamp_monotonicity_offset);
++            }
++        }
++    }
++
+     if (debug_ts) {
+         av_log(NULL, AV_LOG_INFO, "demuxer+ffmpeg -> ist_index:%d type:%s pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s duration:%s duration_time:%s off:%s off_time:%s\n",
+                ifile->ist_index + pkt->stream_index, av_get_media_type_string(ist->dec_ctx->codec_type),
+diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
+index 391a35cf50..3ca42c8f0c 100644
+--- a/fftools/ffmpeg.h
++++ b/fftools/ffmpeg.h
+@@ -433,6 +433,10 @@ typedef struct InputFile {
+     int joined;                 /* the thread has been joined */
+     int thread_queue_size;      /* maximum number of queued packets */
+ #endif
++
++    // A value added to inbound timestamps to prevent them from going "backward" in cases such as HLS discontinuities
++    int64_t ff_timestamp_monotonicity_offset;
++
+ } InputFile;
+ enum forced_keyframes_const {
+@@ -620,6 +624,9 @@ extern float audio_drift_threshold;
+ extern float dts_delta_threshold;
+ extern float dts_error_threshold;
++extern int dts_monotonicity_threshold;
++extern int force_dts_monotonicity;
++
+ extern int audio_volume;
+ extern int audio_sync_method;
+ extern enum VideoSyncMethod video_sync_method;
+diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
+index 6e18a4a23e..f2c2313219 100644
+--- a/fftools/ffmpeg_opt.c
++++ b/fftools/ffmpeg_opt.c
+@@ -156,6 +156,9 @@ float audio_drift_threshold = 0.1;
+ float dts_delta_threshold   = 10;
+ float dts_error_threshold   = 3600*30;
++int dts_monotonicity_threshold = AV_TIME_BASE;
++int force_dts_monotonicity = 0;
++
+ int audio_volume      = 256;
+ int audio_sync_method = 0;
+ enum VideoSyncMethod video_sync_method = VSYNC_AUTO;
+@@ -1361,6 +1364,7 @@ static int open_input_file(OptionsContext *o, const char *filename)
+     f->input_sync_ref = o->input_sync_ref;
+     f->input_ts_offset = o->input_ts_offset;
+     f->ts_offset  = o->input_ts_offset - (copy_ts ? (start_at_zero && ic->start_time != AV_NOPTS_VALUE ? ic->start_time : 0) : timestamp);
++    f->ff_timestamp_monotonicity_offset = 0;
+     f->nb_streams = ic->nb_streams;
+     f->rate_emu   = o->rate_emu;
+     f->accurate_seek = o->accurate_seek;
+@@ -3760,6 +3764,10 @@ const OptionDef options[] = {
+     { "apad",           OPT_STRING | HAS_ARG | OPT_SPEC |
+                         OPT_OUTPUT,                                  { .off = OFFSET(apad) },
+         "audio pad", "" },
++    { "force_dts_monotonicity", OPT_BOOL | OPT_EXPERT,               { &force_dts_monotonicity },
++        "correct dts monotonicity errors" },
++    { "dts_monotonicity_threshold", HAS_ARG | OPT_INT | OPT_EXPERT,  { &dts_monotonicity_threshold },
++        "dts correction threshold for forward jumps", "microseconds" },
+     { "dts_delta_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT,       { &dts_delta_threshold },
+         "timestamp discontinuity delta threshold", "threshold" },
+     { "dts_error_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT,       { &dts_error_threshold },
diff --git a/archive-patches/ffmpeg-cst/5.1.2/0010-hls-replace-key-uri.patch b/archive-patches/ffmpeg-cst/5.1.2/0010-hls-replace-key-uri.patch
new file mode 100644 (file)
index 0000000..113cd28
--- /dev/null
@@ -0,0 +1,49 @@
+diff --git a/libavformat/hls.c b/libavformat/hls.c
+index faf92804a2..bbc8388c94 100644
+--- a/libavformat/hls.c
++++ b/libavformat/hls.c
+@@ -225,6 +225,8 @@ typedef struct HLSContext {
+     int http_persistent;
+     int http_multiple;
+     int http_seekable;
++    char *key_uri_replace_old;
++    char *key_uri_replace_new;
+     AVIOContext *playlist_pb;
+     HLSCryptoContext  crypto_ctx;
+ } HLSContext;
+@@ -1293,8 +1295,16 @@ static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg,
+     if (seg->key_type == KEY_AES_128 || seg->key_type == KEY_SAMPLE_AES) {
+         if (strcmp(seg->key, pls->key_url)) {
++            char *key_url = NULL;
+             AVIOContext *pb = NULL;
+-            if (open_url(pls->parent, &pb, seg->key, &c->avio_opts, opts, NULL) == 0) {
++            if (NULL != c->key_uri_replace_old && \
++                NULL != c-> key_uri_replace_new && \
++                '\0' != c->key_uri_replace_old[0]) {
++                key_url = av_strireplace(seg->key, c->key_uri_replace_old, c->key_uri_replace_new);
++            } else {
++                key_url = seg->key;
++            }
++            if (open_url(pls->parent, &pb, key_url, &c->avio_opts, opts, NULL) == 0) {
+                 ret = avio_read(pb, pls->key, sizeof(pls->key));
+                 if (ret != sizeof(pls->key)) {
+                     av_log(pls->parent, AV_LOG_ERROR, "Unable to read key file %s\n",
+@@ -1306,6 +1316,8 @@ static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg,
+                        seg->key);
+             }
+             av_strlcpy(pls->key_url, seg->key, sizeof(pls->key_url));
++            if (key_url != seg->key)
++                av_free(key_url);
+         }
+     }
+@@ -2530,6 +2542,8 @@ static int hls_probe(const AVProbeData *p)
+ #define OFFSET(x) offsetof(HLSContext, x)
+ #define FLAGS AV_OPT_FLAG_DECODING_PARAM
+ static const AVOption hls_options[] = {
++    { "key_uri_old", "allow to replace part of AES key uri - old", OFFSET(key_uri_replace_old), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, FLAGS },
++    { "key_uri_new", "allow to replace part of AES key uri - new", OFFSET(key_uri_replace_new), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, FLAGS },
+     {"live_start_index", "segment index to start live streams at (negative values are from the end)",
+         OFFSET(live_start_index), AV_OPT_TYPE_INT, {.i64 = -3}, INT_MIN, INT_MAX, FLAGS},
+     {"prefer_x_start", "prefer to use #EXT-X-START if it's in playlist instead of live_start_index",
diff --git a/archive-patches/ffmpeg-cst/5.1.2/0011-recheck-discard-flags.patch b/archive-patches/ffmpeg-cst/5.1.2/0011-recheck-discard-flags.patch
new file mode 100644 (file)
index 0000000..afddf42
--- /dev/null
@@ -0,0 +1,15 @@
+--- a/libavformat/hls.c
++++ b/libavformat/hls.c
+@@ -2171,8 +2171,10 @@
+     HLSContext *c = s->priv_data;
+     int ret, i, minplaylist = -1;
+-    recheck_discard_flags(s, c->first_packet);
+-    c->first_packet = 0;
++    if (c->first_packet) {
++        recheck_discard_flags(s, 1);
++        c->first_packet = 0;
++    }
+     for (i = 0; i < c->n_playlists; i++) {
+         struct playlist *pls = c->playlists[i];
diff --git a/archive-patches/ffmpeg-cst/5.1.2/0012-rtsp.patch b/archive-patches/ffmpeg-cst/5.1.2/0012-rtsp.patch
new file mode 100644 (file)
index 0000000..08930f4
--- /dev/null
@@ -0,0 +1,55 @@
+diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
+index f948f1d395..69507ec866 100644
+--- a/libavformat/rtsp.c
++++ b/libavformat/rtsp.c
+@@ -2391,6 +2391,8 @@ static int sdp_read_header(AVFormatContext *s)
+     int i, err;
+     char url[MAX_URL_SIZE];
+     AVBPrint bp;
++    const char *p, *sp="", *sources="", *sp2, *sources2;
++    char sources_buf[1024];
+     if (!ff_network_init())
+         return AVERROR(EIO);
+@@ -2412,6 +2414,16 @@ static int sdp_read_header(AVFormatContext *s)
+     av_bprint_finalize(&bp, NULL);
+     if (err) goto fail;
++    /* Search for sources= tag in original URL for rtp protocol only */
++    if (strncmp(s->url, "rtp://", 6) == 0) {
++        p = strchr(s->url, '?');
++        if (p && av_find_info_tag(sources_buf, sizeof(sources_buf), "sources", p)) {
++            /* av_log(s, AV_LOG_VERBOSE, "sdp_read_header found sources %s\n", sources_buf);  */
++            sp = sources_buf;
++            sources = "&sources=";
++        }
++    }
++
+     /* open each RTP stream */
+     for (i = 0; i < rt->nb_rtsp_streams; i++) {
+         char namebuf[50];
+@@ -2431,12 +2443,22 @@ static int sdp_read_header(AVFormatContext *s)
+                 av_dict_free(&opts);
+                 goto fail;
+             }
++
++            /* Prepare to add sources to the url to be opened.
++               Otherwise the join to the source specific muliticast will be missing */
++            sources2 = sources;
++            sp2 = sp;
++            /* ignore sources from original URL, when sources are already set in rtsp_st */
++            if (rtsp_st->nb_include_source_addrs > 0)
++                sources2 = sp2 = "";
++
+             ff_url_join(url, sizeof(url), "rtp", NULL,
+                         namebuf, rtsp_st->sdp_port,
+-                        "?localport=%d&ttl=%d&connect=%d&write_to_source=%d",
++                        "?localport=%d&ttl=%d&connect=%d&write_to_source=%d%s%s",
+                         rtsp_st->sdp_port, rtsp_st->sdp_ttl,
+                         rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0,
+-                        rt->rtsp_flags & RTSP_FLAG_RTCP_TO_SOURCE ? 1 : 0);
++                        rt->rtsp_flags & RTSP_FLAG_RTCP_TO_SOURCE ? 1 : 0,
++                        sources2, sp2);
+             p = strchr(s->url, '?');
+             if (p && av_find_info_tag(buf, sizeof(buf), "localaddr", p))
diff --git a/archive-patches/ffmpeg-cst/5.1.2/ffmpeg-increase-IO_BUFFER_SIZE-to-256k.patch b/archive-patches/ffmpeg-cst/5.1.2/ffmpeg-increase-IO_BUFFER_SIZE-to-256k.patch
new file mode 100644 (file)
index 0000000..1c96a07
--- /dev/null
@@ -0,0 +1,26 @@
+From f193409d354a41d8afaf1b75ca34dc1839a60b69 Mon Sep 17 00:00:00 2001
+From: gandharva <gandharva@gmx.de>
+Date: Wed, 14 Jun 2017 19:51:24 +0200
+Subject: [PATCH 8/8] - increase IO_BUFFER_SIZE to 128k
+
+performance improvement when using SMB/CIFS
+---
+ libavformat/aviobuf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
+index c2681ed..711fff8 100644
+--- a/libavformat/aviobuf.c
++++ b/libavformat/aviobuf.c
+@@ -33,7 +33,7 @@
+ #include "url.h"
+ #include <stdarg.h>
+-#define IO_BUFFER_SIZE 32768
++#define IO_BUFFER_SIZE 262144
+ /**
+  * Do seeks within this distance ahead of the current buffer by skipping
+-- 
+2.1.4
+
diff --git a/archive-patches/ffmpeg-cst/5.1.2/optional/README.txt b/archive-patches/ffmpeg-cst/5.1.2/optional/README.txt
new file mode 100644 (file)
index 0000000..5a14c71
--- /dev/null
@@ -0,0 +1,5 @@
+These patches mostly fix processing DRM DASH/HLS streams.\r
+\r
+hls-changes sets a rather high buffer size (tuned towards 1080p VOD content), which may be undesirable for live streams or SD VOD content.\r
+\r
+dash-hacks contains some fixes that may help with DASH streams that contain subtitles and multiple audio streams (esp. switching between streams on CST).
\ No newline at end of file
diff --git a/archive-patches/ffmpeg-cst/5.1.2/optional/ffmpeg51-dash-hacks.patch b/archive-patches/ffmpeg-cst/5.1.2/optional/ffmpeg51-dash-hacks.patch
new file mode 100644 (file)
index 0000000..5668bbd
--- /dev/null
@@ -0,0 +1,142 @@
+diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c
+index 2ca91bea8b..ecaf50047d 100644
+--- a/libavformat/dashdec.c
++++ b/libavformat/dashdec.c
+@@ -441,8 +441,12 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url,
+         return AVERROR_INVALIDDATA;
+     av_freep(pb);
++
+     av_dict_copy(&tmp, *opts, 0);
+     av_dict_copy(&tmp, opts2, 0);
++    av_dict_set_int(&tmp, "reconnect", 1, 0);
++    av_dict_set_int(&tmp, "icy", 0, 0);
++
+     ret = avio_open2(pb, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp);
+     if (ret >= 0) {
+         // update cookies on http response with setcookies.
+@@ -768,7 +772,8 @@ static int resolve_content_path(AVFormatContext *s, const char *url, int *max_ur
+     baseurl = xmlNodeGetContent(node);
+     root_url = (av_strcasecmp(baseurl, "")) ? baseurl : path;
+     if (node) {
+-        xmlNodeSetContent(node, root_url);
++        // HACK: SetContent fails if the URL happens to include '&', which isn't that uncommon...
++        //xmlNodeSetContent(node, root_url);
+         updated = 1;
+     }
+@@ -802,7 +807,7 @@ static int resolve_content_path(AVFormatContext *s, const char *url, int *max_ur
+                 memset(p + 1, 0, strlen(p));
+             }
+             av_strlcat(tmp_str, text + start, tmp_max_url_size);
+-            xmlNodeSetContent(baseurl_nodes[i], tmp_str);
++            //xmlNodeSetContent(baseurl_nodes[i], tmp_str);
+             updated = 1;
+             xmlFree(text);
+         }
+@@ -1217,6 +1222,7 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in)
+     char *val  = NULL;
+     uint32_t period_duration_sec = 0;
+     uint32_t period_start_sec = 0;
++    char *nfcs_key = NULL;
+     if (!in) {
+         close_in = 1;
+@@ -1335,6 +1341,12 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in)
+             } else if (!av_strcasecmp(node->name, "ProgramInformation")) {
+                 parse_programinformation(s, node);
+             }
++            // HACK: libvodstream stores decrypted keys in a custom tag.
++            if (!av_strcasecmp(node->name, (const char*)"nfcskey")) {
++                nfcs_key = xmlNodeGetContent(node->children);
++                c->cenc_decryption_key = av_strdup(nfcs_key);
++                xmlFree(nfcs_key);
++            }
+             node = xmlNextElementSibling(node);
+         }
+         if (!period_node) {
+@@ -1879,7 +1891,8 @@ static int reopen_demux_for_component(AVFormatContext *s, struct representation
+     }
+     ffio_init_context(&pls->pb, avio_ctx_buffer, INITIAL_BUFFER_SIZE, 0,
+                       pls, read_data, NULL, c->is_live ? NULL : seek_data);
+-    pls->pb.pub.seekable = 0;
++    // PATCH: If this is 0, seeking in VOD streams downloads the entire content between origin and target.
++    pls->pb.pub.seekable = 1;
+     if ((ret = ff_copy_whiteblacklists(pls->ctx, s)) < 0)
+         goto fail;
+@@ -2167,6 +2180,7 @@ static int dash_read_packet(AVFormatContext *s, AVPacket *pkt)
+     int ret = 0, i;
+     int64_t mints = 0;
+     struct representation *cur = NULL;
++    struct representation *curHack = NULL;
+     struct representation *rep = NULL;
+     recheck_discard_flags(s, c->videos, c->n_videos);
+@@ -2188,6 +2202,7 @@ static int dash_read_packet(AVFormatContext *s, AVPacket *pkt)
+             continue;
+         if (!cur || rep->cur_timestamp < mints) {
+             cur = rep;
++            curHack = rep;
+             mints = rep->cur_timestamp;
+         }
+     }
+@@ -2203,6 +2218,7 @@ static int dash_read_packet(AVFormatContext *s, AVPacket *pkt)
+     }
+     if (!cur) {
++        av_log(s, AV_LOG_WARNING, "INVALIDDATA\n");
+         return AVERROR_INVALIDDATA;
+     }
+     while (!ff_check_interrupt(c->interrupt_callback) && !ret) {
+@@ -2221,6 +2237,26 @@ static int dash_read_packet(AVFormatContext *s, AVPacket *pkt)
+             cur->is_restart_needed = 0;
+         }
+     }
++    if (curHack && curHack != cur) {
++        cur = curHack;
++        ret = 0;
++        while (!ff_check_interrupt(c->interrupt_callback) && !ret) {
++            ret = av_read_frame(cur->ctx, pkt);
++            if (ret >= 0) {
++                /* If we got a packet, return it */
++                cur->cur_timestamp = av_rescale(pkt->pts, (int64_t)cur->ctx->streams[0]->time_base.num * 90000, cur->ctx->streams[0]->time_base.den);
++                pkt->stream_index = cur->stream_index;
++                return 0;
++            }
++            if (cur->is_restart_needed) {
++                cur->cur_seg_offset = 0;
++                cur->init_sec_buf_read_offset = 0;
++                ff_format_io_close(cur->parent, &cur->input);
++                ret = reopen_demux_for_component(s, cur);
++                cur->is_restart_needed = 0;
++            }
++        }
++    }
+     return AVERROR_EOF;
+ }
+@@ -2232,6 +2268,7 @@ static int dash_close(AVFormatContext *s)
+     free_subtitle_list(c);
+     av_dict_free(&c->avio_opts);
+     av_freep(&c->base_url);
++    av_freep(&c->cenc_decryption_key);
+     return 0;
+ }
+@@ -2319,10 +2356,11 @@ static int dash_read_seek(AVFormatContext *s, int stream_index, int64_t timestam
+         if (!ret)
+             ret = dash_seek(s, c->audios[i], seek_pos_msec, flags, !c->audios[i]->ctx);
+     }
+-    for (i = 0; i < c->n_subtitles; i++) {
+-        if (!ret)
+-            ret = dash_seek(s, c->subtitles[i], seek_pos_msec, flags, !c->subtitles[i]->ctx);
+-    }
++    // PATCH: Seeking in subtitle streams breaks things, and it doesn't seem necessary.
++    //for (i = 0; i < c->n_subtitles; i++) {
++    //    if (!ret)
++    //        ret = dash_seek(s, c->subtitles[i], seek_pos_msec, flags, !c->subtitles[i]->ctx);
++    //}
+     return ret;
+ }
diff --git a/archive-patches/ffmpeg-cst/5.1.2/optional/ffmpeg51-hls-changes.patch b/archive-patches/ffmpeg-cst/5.1.2/optional/ffmpeg51-hls-changes.patch
new file mode 100644 (file)
index 0000000..ea96739
--- /dev/null
@@ -0,0 +1,57 @@
+diff --git a/libavformat/hls.c b/libavformat/hls.c
+index e622425e80..faf92804a2 100644
+--- a/libavformat/hls.c
++++ b/libavformat/hls.c
+@@ -46,7 +46,7 @@
+ #include "hls_sample_encryption.h"
+-#define INITIAL_BUFFER_SIZE 32768
++#define INITIAL_BUFFER_SIZE 1048576
+ #define MAX_FIELD_LEN 64
+ #define MAX_CHARACTERISTICS_LEN 512
+@@ -1580,7 +1580,7 @@ reload:
+     seg = next_segment(v);
+     if (c->http_multiple == 1 && !v->input_next_requested &&
+-        seg && seg->key_type == KEY_NONE && av_strstart(seg->url, "http", NULL)) {
++        seg && seg->key_type != KEY_AES_128 && av_strstart(seg->url, "http", NULL)) {
+         ret = open_input(c, v, seg, &v->input_next);
+         if (ret < 0) {
+             if (ff_check_interrupt(c->interrupt_callback))
+@@ -1613,7 +1613,7 @@ reload:
+         return ret;
+     }
+     if (c->http_persistent &&
+-        seg->key_type == KEY_NONE && av_strstart(seg->url, "http", NULL)) {
++        seg->key_type != KEY_AES_128 && av_strstart(seg->url, "http", NULL)) {
+         v->input_read_done = 1;
+     } else {
+         ff_format_io_close(v->parent, &v->input);
+@@ -2475,6 +2475,7 @@ static int hls_read_seek(AVFormatContext *s, int stream_index,
+     /* set segment now so we do not need to search again below */
+     seek_pls->cur_seq_no = seq_no;
+     seek_pls->seek_stream_index = stream_subdemuxer_index;
++    //av_log(s, AV_LOG_INFO, "Seek to %d in %d\n", seq_no, stream_subdemuxer_index);
+     for (i = 0; i < c->n_playlists; i++) {
+         /* Reset reading */
+@@ -2535,7 +2536,7 @@ static const AVOption hls_options[] = {
+         OFFSET(prefer_x_start), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS},
+     {"allowed_extensions", "List of file extensions that hls is allowed to access",
+         OFFSET(allowed_extensions), AV_OPT_TYPE_STRING,
+-        {.str = "3gp,aac,avi,ac3,eac3,flac,mkv,m3u8,m4a,m4s,m4v,mpg,mov,mp2,mp3,mp4,mpeg,mpegts,ogg,ogv,oga,ts,vob,wav"},
++        {.str = "3gp,aac,avi,ac3,eac3,flac,key,mkv,m3u8,m4a,m4s,m4v,mpg,mov,mp2,mp3,mp4,mpeg,mpegts,ogg,ogv,oga,ts,vob,wav"},
+         INT_MIN, INT_MAX, FLAGS},
+     {"max_reload", "Maximum number of times a insufficient list is attempted to be reloaded",
+         OFFSET(max_reload), AV_OPT_TYPE_INT, {.i64 = 1000}, 0, INT_MAX, FLAGS},
+@@ -2544,7 +2545,7 @@ static const AVOption hls_options[] = {
+     {"http_persistent", "Use persistent HTTP connections",
+         OFFSET(http_persistent), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, FLAGS },
+     {"http_multiple", "Use multiple HTTP connections for fetching segments",
+-        OFFSET(http_multiple), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, FLAGS},
++        OFFSET(http_multiple), AV_OPT_TYPE_BOOL, {.i64 = 0}, -1, 1, FLAGS},
+     {"http_seekable", "Use HTTP partial requests, 0 = disable, 1 = enable, -1 = auto",
+         OFFSET(http_seekable), AV_OPT_TYPE_BOOL, { .i64 = -1}, -1, 1, FLAGS},
+     {"seg_format_options", "Set options for segment demuxer",
diff --git a/archive-patches/ffmpeg-cst/5.1/0001-aac-optimize0.patch b/archive-patches/ffmpeg-cst/5.1/0001-aac-optimize0.patch
deleted file mode 100644 (file)
index ff81c27..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-diff --git a/libavcodec/aacps.c b/libavcodec/aacps.c
-index 655e8fe5b4..45190d678d 100644
---- a/libavcodec/aacps.c
-+++ b/libavcodec/aacps.c
-@@ -397,7 +397,7 @@ static void map_val_20_to_34(INTFLOAT par[PS_MAX_NR_IIDICC])
-     par[ 1] = AAC_HALF_SUM(par[ 0], par[ 1]);
- }
--static void decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const INTFLOAT (*s)[32][2], int is34)
-+static void __attribute__((optimize(0))) decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const INTFLOAT (*s)[32][2], int is34)
- {
-     LOCAL_ALIGNED_16(INTFLOAT, power, [34], [PS_QMF_TIME_SLOTS]);
-     LOCAL_ALIGNED_16(INTFLOAT, transient_gain, [34], [PS_QMF_TIME_SLOTS]);
-diff --git a/libavcodec/fft_template.c b/libavcodec/fft_template.c
-index f2742a3ae8..59b4085eba 100644
---- a/libavcodec/fft_template.c
-+++ b/libavcodec/fft_template.c
-@@ -551,7 +551,7 @@ static void fft##n(FFTComplex *z)\
-     pass(z,FFT_NAME(ff_cos_##n),n4/2);\
- }
--static void fft4(FFTComplex *z)
-+static void __attribute__((optimize(0))) fft4(FFTComplex *z)
- {
-     FFTDouble t1, t2, t3, t4, t5, t6, t7, t8;
-@@ -565,7 +565,7 @@ static void fft4(FFTComplex *z)
-     BF(z[2].im, z[0].im, t2, t5);
- }
--static void fft8(FFTComplex *z)
-+static void __attribute__((optimize(0))) fft8(FFTComplex *z)
- {
-     FFTDouble t1, t2, t3, t4, t5, t6;
-diff --git a/libavcodec/mdct_template.c b/libavcodec/mdct_template.c
-index a854ad2700..6119be0d1a 100644
---- a/libavcodec/mdct_template.c
-+++ b/libavcodec/mdct_template.c
-@@ -98,7 +98,7 @@ av_cold int ff_mdct_init(FFTContext *s, int nbits, int inverse, double scale)
-  * @param output N/2 samples
-  * @param input N/2 samples
-  */
--void ff_imdct_half_c(FFTContext *s, FFTSample *output, const FFTSample *input)
-+void __attribute__((optimize(0))) ff_imdct_half_c(FFTContext *s, FFTSample *output, const FFTSample *input)
- {
-     int k, n8, n4, n2, n, j;
-     const uint16_t *revtab = s->revtab;
diff --git a/archive-patches/ffmpeg-cst/5.1/0002-add64_c-parentheses.patch b/archive-patches/ffmpeg-cst/5.1/0002-add64_c-parentheses.patch
deleted file mode 100644 (file)
index 38b74bf..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-diff --git a/libavutil/common.h b/libavutil/common.h
-index fd1404be6c..0bb8650e83 100644
---- a/libavutil/common.h
-+++ b/libavutil/common.h
-@@ -350,7 +350,8 @@ static av_always_inline int64_t av_sat_add64_c(int64_t a, int64_t b) {
-     return !__builtin_add_overflow(a, b, &tmp) ? tmp : (tmp < 0 ? INT64_MAX : INT64_MIN);
- #else
-     int64_t s = a+(uint64_t)b;
--    if ((int64_t)(a^b | ~s^b) >= 0)
-+    // PATCH: GCC 4.9.4 complains about missing parentheses when combining bitwise operations.
-+    if ((int64_t)((a^b) | (~s^b)) >= 0)
-         return INT64_MAX ^ (b >> 63);
-     return s;
- #endif
diff --git a/archive-patches/ffmpeg-cst/5.1/0003-cst-add-ASF-VC1-Annex-G-and-RCV-bitstream-filters.patch b/archive-patches/ffmpeg-cst/5.1/0003-cst-add-ASF-VC1-Annex-G-and-RCV-bitstream-filters.patch
deleted file mode 100644 (file)
index 86bdb91..0000000
+++ /dev/null
@@ -1,333 +0,0 @@
-diff --git a/libavcodec/Makefile b/libavcodec/Makefile
-index 457ec58377..49bf260764 100644
---- a/libavcodec/Makefile
-+++ b/libavcodec/Makefile
-@@ -1209,6 +1209,8 @@ OBJS-$(CONFIG_SETTS_BSF)                  += setts_bsf.o
- OBJS-$(CONFIG_TEXT2MOVSUB_BSF)            += movsub_bsf.o
- OBJS-$(CONFIG_TRACE_HEADERS_BSF)          += trace_headers_bsf.o
- OBJS-$(CONFIG_TRUEHD_CORE_BSF)            += truehd_core_bsf.o mlp_parse.o mlp.o
-+OBJS-$(CONFIG_VC1_ASFTORCV_BSF)           += vc1_asftorcv_bsf.o
-+OBJS-$(CONFIG_VC1_ASFTOANNEXG_BSF)        += vc1_asftoannexg_bsf.o vc1.o
- OBJS-$(CONFIG_VP9_METADATA_BSF)           += vp9_metadata_bsf.o
- OBJS-$(CONFIG_VP9_RAW_REORDER_BSF)        += vp9_raw_reorder_bsf.o
- OBJS-$(CONFIG_VP9_SUPERFRAME_BSF)         += vp9_superframe_bsf.o
-diff --git a/libavcodec/bitstream_filters.c b/libavcodec/bitstream_filters.c
-index 444423ae93..482d3473b2 100644
---- a/libavcodec/bitstream_filters.c
-+++ b/libavcodec/bitstream_filters.c
-@@ -59,6 +59,8 @@ extern const FFBitStreamFilter ff_setts_bsf;
- extern const FFBitStreamFilter ff_text2movsub_bsf;
- extern const FFBitStreamFilter ff_trace_headers_bsf;
- extern const FFBitStreamFilter ff_truehd_core_bsf;
-+extern const FFBitStreamFilter ff_vc1_asftoannexg_bsf;
-+extern const FFBitStreamFilter ff_vc1_asftorcv_bsf;
- extern const FFBitStreamFilter ff_vp9_metadata_bsf;
- extern const FFBitStreamFilter ff_vp9_raw_reorder_bsf;
- extern const FFBitStreamFilter ff_vp9_superframe_bsf;
-diff --git a/libavcodec/vc1_asftoannexg_bsf.c b/libavcodec/vc1_asftoannexg_bsf.c
-new file mode 100644
-index 0000000000..2901f84d9c
---- /dev/null
-+++ b/libavcodec/vc1_asftoannexg_bsf.c
-@@ -0,0 +1,190 @@
-+/*
-+ * copyright (c) 2010 Google Inc.
-+ * copyright (c) 2013 CoolStream International Ltd.
-+ * copyright (c) 2017 Jacek Jendrzej port to 3.x
-+ * This file is part of FFmpeg.
-+ *
-+ * FFmpeg is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Lesser General Public
-+ * License as published by the Free Software Foundation; either
-+ * version 2.1 of the License, or (at your option) any later version.
-+ *
-+ * FFmpeg is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public
-+ * License along with FFmpeg; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-+ */
-+
-+#include "avcodec.h"
-+#include "bytestream.h"
-+#include "vc1.h"
-+#include "bsf.h"
-+#include "bsf_internal.h"
-+
-+// An arbitrary limit in bytes greater than the current bytes used.
-+#define MAX_SEQ_HEADER_SIZE 50
-+
-+typedef struct ASFTOANNEXGBSFContext {
-+    int frames;
-+    uint8_t *seq_header;
-+    int seq_header_size;
-+    uint8_t *ep_header;
-+    int ep_header_size;
-+} ASFTOANNEXGBSFContext;
-+
-+static int find_codec_data(ASFTOANNEXGBSFContext *ctx, uint8_t *data, int data_size, int keyframe) {
-+    const uint8_t *start = data;
-+    const uint8_t *end = data + data_size;
-+    const uint8_t *next;
-+    int size;
-+    int has_seq_header = 0;
-+    int has_ep_header = 0;
-+    int has_frame_header = 0;
-+
-+    start = find_next_marker(start, end);
-+    next = start;
-+    for(; next < end; start = next){
-+        next = find_next_marker(start + 4, end);
-+        size = next - start;
-+        if(size <= 0) continue;
-+        switch(AV_RB32(start)){
-+        case VC1_CODE_SEQHDR:
-+            has_seq_header = 1;
-+            break;
-+        case VC1_CODE_ENTRYPOINT:
-+            has_ep_header = 1;
-+            break;
-+        case VC1_CODE_FRAME:
-+            has_frame_header = 1;
-+            break;
-+        default:
-+            break;
-+        }
-+    }
-+
-+    if((has_seq_header && has_ep_header && has_frame_header && keyframe) ||
-+       (!has_seq_header && !has_ep_header && has_frame_header) ) return 0;
-+
-+    return -1;
-+}
-+
-+static int parse_extradata(ASFTOANNEXGBSFContext *ctx, uint8_t *extradata, int extradata_size) {
-+    const uint8_t *start = extradata;
-+    const uint8_t *end = extradata + extradata_size;
-+    const uint8_t *next;
-+    int size;
-+
-+    start = find_next_marker(start, end);
-+    next = start;
-+    for(; next < end; start = next){
-+        next = find_next_marker(start + 4, end);
-+        size = next - start;
-+        if(size <= 0) continue;
-+        switch(AV_RB32(start)){
-+        case VC1_CODE_SEQHDR:
-+            ctx->seq_header = av_mallocz(size);
-+            ctx->seq_header_size = size;
-+            memcpy(ctx->seq_header, start, size);
-+            break;
-+        case VC1_CODE_ENTRYPOINT:
-+            ctx->ep_header = av_malloc(size);
-+            ctx->ep_header_size = size;
-+            memcpy(ctx->ep_header, start, size);
-+            break;
-+        default:
-+            break;
-+        }
-+    }
-+
-+    if(!ctx->seq_header || !ctx->ep_header) {
-+        av_log(NULL, AV_LOG_ERROR, "Incomplete extradata\n");
-+        return -1;
-+    }
-+    return 0;
-+}
-+
-+static int asftoannexg_filter(AVBSFContext *ctx, AVPacket *out)
-+{
-+    ASFTOANNEXGBSFContext* bsfctx = ctx->priv_data;
-+    AVPacket *in;
-+    int keyframe;
-+    int ret;
-+    uint8_t* bs = NULL;
-+
-+    ret = ff_bsf_get_packet(ctx, &in);
-+    if (ret < 0)
-+        return ret;
-+
-+    keyframe = in->flags & AV_PKT_FLAG_KEY;
-+    if(in->size >= 1 && !find_codec_data(bsfctx, in->data, in->size, keyframe)) {
-+//         av_log(NULL, AV_LOG_INFO, "Nothing to do: %i\n",in->size);
-+        av_packet_move_ref(out, in);
-+        av_packet_free(&in);
-+        return 0;
-+    }
-+
-+    if(!ctx->par_in->extradata || ctx->par_in->extradata_size < 16) {
-+        av_log(NULL, AV_LOG_INFO, "Extradata size too small: %i\n", ctx->par_in->extradata_size);
-+        av_packet_move_ref(out, in);
-+        av_packet_free(&in);
-+        return 0;
-+    }
-+
-+    if (!bsfctx->frames && parse_extradata(bsfctx, ctx->par_in->extradata , ctx->par_in->extradata_size) < 0) {
-+        av_packet_free(&in);
-+        av_log(NULL, AV_LOG_ERROR, "Cannot parse extra data!\n");
-+        return -1;
-+    }
-+
-+    if (keyframe) {
-+        // If this is the keyframe, need to put sequence header and entry point header.
-+        ret = av_new_packet(out, bsfctx->seq_header_size + bsfctx->ep_header_size + 4 + in->size);
-+        if (ret < 0)
-+            goto exit;
-+        bs = out->data;
-+
-+        memcpy(bs, bsfctx->seq_header, bsfctx->seq_header_size);
-+        bs += bsfctx->seq_header_size;
-+        memcpy(bs, bsfctx->ep_header, bsfctx->ep_header_size);
-+        bs += bsfctx->ep_header_size;
-+    } else {
-+        ret = av_new_packet(out, 4 + in->size);
-+        if (ret < 0)
-+            goto exit;
-+        bs = out->data;
-+    }
-+
-+    // Put the frame start code and frame data.
-+    bytestream_put_be32(&bs, VC1_CODE_FRAME);
-+    memcpy(bs, in->data, in->size);
-+    ++bsfctx->frames;
-+
-+    ret = av_packet_copy_props(out, in);
-+
-+exit:
-+    av_packet_free(&in);
-+
-+    return ret;
-+}
-+
-+static void asftoannexg_close(AVBSFContext *bsfc) {
-+    ASFTOANNEXGBSFContext *bsfctx = bsfc->priv_data;
-+    av_freep(&bsfctx->seq_header);
-+    av_freep(&bsfctx->ep_header);
-+}
-+
-+static const enum AVCodecID codec_ids[] = {
-+    AV_CODEC_ID_VC1, AV_CODEC_ID_NONE,
-+};
-+
-+FFBitStreamFilter ff_vc1_asftoannexg_bsf = {
-+    .p.name         = "vc1_asftoannexg",
-+    .priv_data_size = sizeof(ASFTOANNEXGBSFContext),
-+    .filter         = asftoannexg_filter,
-+    .close          = asftoannexg_close,
-+    .p.codec_ids    = codec_ids,
-+};
-diff --git a/libavcodec/vc1_asftorcv_bsf.c b/libavcodec/vc1_asftorcv_bsf.c
-new file mode 100644
-index 0000000000..02e510b4b6
---- /dev/null
-+++ b/libavcodec/vc1_asftorcv_bsf.c
-@@ -0,0 +1,105 @@
-+/*
-+ * copyright (c) 2010 Google Inc.
-+ * copyright (c) 2017 Jacek Jendrzej port to 3.x
-+ * This file is part of FFmpeg.
-+ *
-+ * FFmpeg is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Lesser General Public
-+ * License as published by the Free Software Foundation; either
-+ * version 2.1 of the License, or (at your option) any later version.
-+ *
-+ * FFmpeg is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public
-+ * License along with FFmpeg; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-+ */
-+
-+#include "avcodec.h"
-+#include "bytestream.h"
-+#include "bsf.h"
-+#include "bsf_internal.h"
-+
-+#define RCV_STREAM_HEADER_SIZE 36
-+#define RCV_PICTURE_HEADER_SIZE 8
-+
-+typedef struct ASFTORCVBSFContext {
-+    int frames;
-+} ASFTORCVBSFContext;
-+
-+static int asftorcv_filter(AVBSFContext *ctx, AVPacket *out){
-+    ASFTORCVBSFContext* bsfctx = ctx->priv_data;
-+    AVPacket *in;
-+    int keyframe;
-+    int ret;
-+    uint8_t* bs = NULL;
-+
-+    ret = ff_bsf_get_packet(ctx, &in);
-+    if (ret < 0)
-+        return ret;
-+
-+    keyframe = in->flags & AV_PKT_FLAG_KEY;
-+
-+    if (!bsfctx->frames) {
-+        // Write the header if this is the first frame.
-+        ret = av_new_packet(out, RCV_STREAM_HEADER_SIZE + RCV_PICTURE_HEADER_SIZE + in->size);
-+        if (ret < 0)
-+            goto exit;
-+        bs = out->data;
-+
-+        // The following structure of stream header comes from libavformat/vc1testenc.c.
-+        bytestream_put_le24(&bs, 0);  // Frame count. 0 for streaming.
-+        bytestream_put_byte(&bs, 0xC5);
-+        bytestream_put_le32(&bs, 4);  // 4 bytes of extra data.
-+        bytestream_put_byte(&bs, ctx->par_in->extradata[0]);
-+        bytestream_put_byte(&bs, ctx->par_in->extradata[1]);
-+        bytestream_put_byte(&bs, ctx->par_in->extradata[2]);
-+        bytestream_put_byte(&bs, ctx->par_in->extradata[3]);
-+        bytestream_put_le32(&bs, ctx->par_in->height);
-+        bytestream_put_le32(&bs, ctx->par_in->width);
-+        bytestream_put_le32(&bs, 0xC);
-+        bytestream_put_le24(&bs, 0);  // hrd_buffer
-+        bytestream_put_byte(&bs, 0x80);  // level|cbr|res1
-+        bytestream_put_le32(&bs, 0);  // hrd_rate
-+
-+        // The following LE32 describes the frame rate. Since we don't care so fill
-+        // it with 0xFFFFFFFF which means variable framerate.
-+        // See: libavformat/vc1testenc.c
-+        bytestream_put_le32(&bs, 0xFFFFFFFF);
-+    } else {
-+        ret = av_new_packet(out, RCV_PICTURE_HEADER_SIZE + in->size);
-+        if (ret < 0)
-+            goto exit;
-+        bs = out->data;
-+    }
-+
-+    // Write the picture header.
-+    bytestream_put_le32(&bs, in->size | (keyframe ? 0x80000000 : 0));
-+
-+    //  The following LE32 describes the pts. Since we don't care so fill it with 0.
-+    bytestream_put_le32(&bs, 0);
-+    memcpy(bs, in->data, in->size);
-+
-+    ++bsfctx->frames;
-+
-+    ret = av_packet_copy_props(out, in);
-+
-+exit:
-+    av_packet_free(&in);
-+
-+    return ret;
-+}
-+
-+static const enum AVCodecID codec_ids[] = {
-+    AV_CODEC_ID_WMV3, AV_CODEC_ID_NONE,
-+};
-+
-+FFBitStreamFilter ff_vc1_asftorcv_bsf = {
-+    .p.name       = "vc1_asftorcv",
-+    .priv_data_size = sizeof(ASFTORCVBSFContext),
-+    .filter         = asftorcv_filter,
-+    .p.codec_ids    = codec_ids,
-+};
diff --git a/archive-patches/ffmpeg-cst/5.1/0004-cst-allow-to-choose-rtmp-impl-at-runtime.patch b/archive-patches/ffmpeg-cst/5.1/0004-cst-allow-to-choose-rtmp-impl-at-runtime.patch
deleted file mode 100644 (file)
index 9360812..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-diff --git a/configure b/configure
-index ba5793b2ff..b199365427 100755
---- a/configure
-+++ b/configure
-@@ -3549,10 +3549,8 @@ xv_outdev_deps="xlib_xv xlib_x11 xlib_xext"
- # protocols
- async_protocol_deps="threads"
- bluray_protocol_deps="libbluray"
--ffrtmpcrypt_protocol_conflict="librtmp_protocol"
- ffrtmpcrypt_protocol_deps_any="gcrypt gmp openssl mbedtls"
- ffrtmpcrypt_protocol_select="tcp_protocol"
--ffrtmphttp_protocol_conflict="librtmp_protocol"
- ffrtmphttp_protocol_select="http_protocol"
- ftp_protocol_select="tcp_protocol"
- gopher_protocol_select="tcp_protocol"
-@@ -3566,20 +3564,18 @@ https_protocol_suggest="zlib"
- icecast_protocol_select="http_protocol"
- mmsh_protocol_select="http_protocol"
- mmst_protocol_select="network"
--rtmp_protocol_conflict="librtmp_protocol"
--rtmp_protocol_select="tcp_protocol"
--rtmp_protocol_suggest="zlib"
--rtmpe_protocol_select="ffrtmpcrypt_protocol"
--rtmpe_protocol_suggest="zlib"
--rtmps_protocol_conflict="librtmp_protocol"
--rtmps_protocol_select="tls_protocol"
--rtmps_protocol_suggest="zlib"
--rtmpt_protocol_select="ffrtmphttp_protocol"
--rtmpt_protocol_suggest="zlib"
--rtmpte_protocol_select="ffrtmpcrypt_protocol ffrtmphttp_protocol"
--rtmpte_protocol_suggest="zlib"
--rtmpts_protocol_select="ffrtmphttp_protocol https_protocol"
--rtmpts_protocol_suggest="zlib"
-+ffrtmp_protocol_select="tcp_protocol"
-+ffrtmp_protocol_suggest="zlib"
-+ffrtmpe_protocol_select="ffrtmpcrypt_protocol"
-+ffrtmpe_protocol_suggest="zlib"
-+ffrtmps_protocol_select="tls_protocol"
-+ffrtmps_protocol_suggest="zlib"
-+ffrtmpt_protocol_select="ffrtmphttp_protocol"
-+ffrtmpt_protocol_suggest="zlib"
-+ffrtmpte_protocol_select="ffrtmpcrypt_protocol ffrtmphttp_protocol"
-+ffrtmpte_protocol_suggest="zlib"
-+ffrtmpts_protocol_select="ffrtmphttp_protocol https_protocol"
-+ffrtmpts_protocol_suggest="zlib"
- rtp_protocol_select="udp_protocol"
- schannel_conflict="openssl gnutls libtls mbedtls"
- sctp_protocol_deps="struct_sctp_event_subscribe struct_msghdr_msg_flags"
-diff --git a/libavformat/Makefile b/libavformat/Makefile
-index 6c6b779080..f641b43de6 100644
---- a/libavformat/Makefile
-+++ b/libavformat/Makefile
-@@ -656,12 +656,12 @@ OBJS-$(CONFIG_MMSH_PROTOCOL)             += mmsh.o mms.o asf_tags.o
- OBJS-$(CONFIG_MMST_PROTOCOL)             += mmst.o mms.o asf_tags.o
- OBJS-$(CONFIG_PIPE_PROTOCOL)             += file.o
- OBJS-$(CONFIG_PROMPEG_PROTOCOL)          += prompeg.o
--OBJS-$(CONFIG_RTMP_PROTOCOL)             += rtmpproto.o rtmpdigest.o rtmppkt.o
--OBJS-$(CONFIG_RTMPE_PROTOCOL)            += rtmpproto.o rtmpdigest.o rtmppkt.o
--OBJS-$(CONFIG_RTMPS_PROTOCOL)            += rtmpproto.o rtmpdigest.o rtmppkt.o
--OBJS-$(CONFIG_RTMPT_PROTOCOL)            += rtmpproto.o rtmpdigest.o rtmppkt.o
--OBJS-$(CONFIG_RTMPTE_PROTOCOL)           += rtmpproto.o rtmpdigest.o rtmppkt.o
--OBJS-$(CONFIG_RTMPTS_PROTOCOL)           += rtmpproto.o rtmpdigest.o rtmppkt.o
-+OBJS-$(CONFIG_FFRTMP_PROTOCOL)           += rtmpproto.o rtmpdigest.o rtmppkt.o
-+OBJS-$(CONFIG_FFRTMPE_PROTOCOL)          += rtmpproto.o rtmpdigest.o rtmppkt.o
-+OBJS-$(CONFIG_FFRTMPS_PROTOCOL)          += rtmpproto.o rtmpdigest.o rtmppkt.o
-+OBJS-$(CONFIG_FFRTMPT_PROTOCOL)          += rtmpproto.o rtmpdigest.o rtmppkt.o
-+OBJS-$(CONFIG_FFRTMPTE_PROTOCOL)         += rtmpproto.o rtmpdigest.o rtmppkt.o
-+OBJS-$(CONFIG_FFRTMPTS_PROTOCOL)         += rtmpproto.o rtmpdigest.o rtmppkt.o
- OBJS-$(CONFIG_RTP_PROTOCOL)              += rtpproto.o ip.o
- OBJS-$(CONFIG_SCTP_PROTOCOL)             += sctp.o
- OBJS-$(CONFIG_SRTP_PROTOCOL)             += srtpproto.o srtp.o
-diff --git a/libavformat/protocols.c b/libavformat/protocols.c
-index 6ee62a598a..3480a2b521 100644
---- a/libavformat/protocols.c
-+++ b/libavformat/protocols.c
-@@ -44,12 +44,12 @@ extern const URLProtocol ff_mmst_protocol;
- extern const URLProtocol ff_md5_protocol;
- extern const URLProtocol ff_pipe_protocol;
- extern const URLProtocol ff_prompeg_protocol;
--extern const URLProtocol ff_rtmp_protocol;
--extern const URLProtocol ff_rtmpe_protocol;
--extern const URLProtocol ff_rtmps_protocol;
--extern const URLProtocol ff_rtmpt_protocol;
--extern const URLProtocol ff_rtmpte_protocol;
--extern const URLProtocol ff_rtmpts_protocol;
-+extern const URLProtocol ff_ffrtmp_protocol;
-+extern const URLProtocol ff_ffrtmpe_protocol;
-+extern const URLProtocol ff_ffrtmps_protocol;
-+extern const URLProtocol ff_ffrtmpt_protocol;
-+extern const URLProtocol ff_ffrtmpte_protocol;
-+extern const URLProtocol ff_ffrtmpts_protocol;
- extern const URLProtocol ff_rtp_protocol;
- extern const URLProtocol ff_sctp_protocol;
- extern const URLProtocol ff_srtp_protocol;
-diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
-index f0ef223f05..53a078b426 100644
---- a/libavformat/rtmpproto.c
-+++ b/libavformat/rtmpproto.c
-@@ -2594,7 +2594,7 @@ static int inject_fake_duration_metadata(RTMPContext *rt)
- static int rtmp_open(URLContext *s, const char *uri, int flags, AVDictionary **opts)
- {
-     RTMPContext *rt = s->priv_data;
--    char proto[8], hostname[256], path[1024], auth[100], *fname;
-+    char *proto, tmpProto[10], hostname[256], path[1024], auth[100], *fname;
-     char *old_app, *qmark, *n, fname_buffer[1024];
-     uint8_t buf[2048];
-     int port;
-@@ -2605,7 +2605,7 @@ static int rtmp_open(URLContext *s, const char *uri, int flags, AVDictionary **o
-     rt->is_input = !(flags & AVIO_FLAG_WRITE);
--    av_url_split(proto, sizeof(proto), auth, sizeof(auth),
-+    memset(tmpProto, 0, sizeof(tmpProto)); proto = &tmpProto[2]; av_url_split(tmpProto, sizeof(tmpProto), auth, sizeof(auth),
-                  hostname, sizeof(hostname), &port,
-                  path, sizeof(path), s->filename);
-@@ -3151,9 +3151,9 @@ const URLProtocol ff_##flavor##_protocol = {     \
- #define RTMP_PROTOCOL(flavor, uppercase)         \
-     RTMP_PROTOCOL_3(flavor, CONFIG_ ## uppercase ## _PROTOCOL)
--RTMP_PROTOCOL(rtmp,   RTMP)
--RTMP_PROTOCOL(rtmpe,  RTMPE)
--RTMP_PROTOCOL(rtmps,  RTMPS)
--RTMP_PROTOCOL(rtmpt,  RTMPT)
--RTMP_PROTOCOL(rtmpte, RTMPTE)
--RTMP_PROTOCOL(rtmpts, RTMPTS)
-+RTMP_PROTOCOL(ffrtmp,   FFRTMP)
-+RTMP_PROTOCOL(ffrtmpe,  FFRTMPE)
-+RTMP_PROTOCOL(ffrtmps,  FFRTMPS)
-+RTMP_PROTOCOL(ffrtmpt,  FFRTMPT)
-+RTMP_PROTOCOL(ffrtmpte, FFRTMPTE)
-+RTMP_PROTOCOL(ffrtmpts, FFRTMPTS)
diff --git a/archive-patches/ffmpeg-cst/5.1/0005-cst-fix-h264-sps-pps.patch b/archive-patches/ffmpeg-cst/5.1/0005-cst-fix-h264-sps-pps.patch
deleted file mode 100644 (file)
index 338ff1b..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-# Test case: The.Purge.2013.1080p.BluRay.x264.YIFY.mp4
-From 1c7b83f945e710a17a41ad9feb7dc929f26f2b0e Mon Sep 17 00:00:00 2001
-From: Jacek Jendrzej <satbaby@kawaii.com>
-Date: Wed, 28 Jun 2017 11:38:20 +0200
-Subject: [PATCH] fix sps/pps for cooli;This is commit that breaks seek in some
- mkv.break with commit 6d2219e9f950b96279fd8464cc11c4d02518b629
-
----
- libavcodec/h264_mp4toannexb_bsf.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/libavcodec/h264_mp4toannexb_bsf.c b/libavcodec/h264_mp4toannexb_bsf.c
-index 2822644b10..d57647d25c 100644
---- a/libavcodec/h264_mp4toannexb_bsf.c
-+++ b/libavcodec/h264_mp4toannexb_bsf.c
-@@ -242,6 +242,11 @@ static int h264_mp4toannexb_filter(AVBSFContext *ctx, AVPacket *opkt)
-             if (!new_idr && unit_type == H264_NAL_IDR_SLICE && (buf[1] & 0x80))
-                 new_idr = 1;
-
-+            if (s->new_idr && unit_type == H264_NAL_SEI && s->idr_sps_seen && s->idr_pps_seen) {
-+                s->idr_sps_seen = 0;
-+                s->idr_pps_seen = 0;
-+            }
-+
-             /* prepend only to the first type 5 NAL unit of an IDR picture, if no sps/pps are already present */
-             if (new_idr && unit_type == H264_NAL_IDR_SLICE && !sps_seen && !pps_seen) {
-                 if (ctx->par_out->extradata)
diff --git a/archive-patches/ffmpeg-cst/5.1/0006-cst-fix-mpegts-pts.patch b/archive-patches/ffmpeg-cst/5.1/0006-cst-fix-mpegts-pts.patch
deleted file mode 100644 (file)
index 534e404..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
-index 8a3436f2be..abdfe41d85 100644
---- a/libavformat/mpegts.c
-+++ b/libavformat/mpegts.c
-@@ -1037,10 +1037,10 @@ static int new_pes_packet(PESContext *pes, AVPacket *pkt)
-     pes->buffer = NULL;
-     reset_pes_packet_state(pes);
--    sd = av_packet_new_side_data(pkt, AV_PKT_DATA_MPEGTS_STREAM_ID, 1);
-+    /*sd = av_packet_new_side_data(pkt, AV_PKT_DATA_MPEGTS_STREAM_ID, 1);
-     if (!sd)
-         return AVERROR(ENOMEM);
--    *sd = pes->stream_id;
-+    *sd = pes->stream_id;*/
-     return 0;
- }
diff --git a/archive-patches/ffmpeg-cst/5.1/0007-disable-whitelist.patch b/archive-patches/ffmpeg-cst/5.1/0007-disable-whitelist.patch
deleted file mode 100644 (file)
index 343b124..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-diff --git a/libavformat/avio.c b/libavformat/avio.c\r
-index 4846bbd8c6..978bf72994 100644\r
---- a/libavformat/avio.c\r
-+++ b/libavformat/avio.c\r
-@@ -177,12 +177,12 @@ int ffurl_connect(URLContext *uc, AVDictionary **options)\r
-                (uc->protocol_whitelist && !strcmp(uc->protocol_whitelist, e->value)));\r
-     av_assert0(!(e=av_dict_get(*options, "protocol_blacklist", NULL, 0)) ||\r
-                (uc->protocol_blacklist && !strcmp(uc->protocol_blacklist, e->value)));\r
--\r
-+/*\r
-     if (uc->protocol_whitelist && av_match_list(uc->prot->name, uc->protocol_whitelist, ',') <= 0) {\r
-         av_log(uc, AV_LOG_ERROR, "Protocol '%s' not on whitelist '%s'!\n", uc->prot->name, uc->protocol_whitelist);\r
-         return AVERROR(EINVAL);\r
-     }\r
--\r
-+*/\r
-     if (uc->protocol_blacklist && av_match_list(uc->prot->name, uc->protocol_blacklist, ',') > 0) {\r
-         av_log(uc, AV_LOG_ERROR, "Protocol '%s' on blacklist '%s'!\n", uc->prot->name, uc->protocol_blacklist);\r
-         return AVERROR(EINVAL);\r
diff --git a/archive-patches/ffmpeg-cst/5.1/0008-mov-cenc-fixes.patch b/archive-patches/ffmpeg-cst/5.1/0008-mov-cenc-fixes.patch
deleted file mode 100644 (file)
index 42c9e57..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-diff --git a/libavformat/mov.c b/libavformat/mov.c
-index 2b1131b911..bf56b41eb3 100644
---- a/libavformat/mov.c
-+++ b/libavformat/mov.c
-@@ -1237,6 +1237,36 @@ static MOVFragmentStreamInfo * get_current_frag_stream_info(
-     return NULL;
- }
-+static MOVFragmentStreamInfo * get_frag_stream_by_sample_index(
-+    MOVFragmentIndex *frag_index,
-+    int sample_index,
-+    int stream_id,
-+    int *found_index)
-+{
-+    int i, j;
-+    MOVFragmentIndexItem * item;
-+
-+    for (i = 0; i < frag_index->nb_items; i++) {
-+        item = &frag_index->item[i];
-+        for (j = 0; j < item->nb_stream_info; j++) {
-+            if (item->stream_info[j].id == stream_id &&
-+                item->stream_info[j].index_entry >= sample_index &&
-+                (i == frag_index->nb_items - 1 ||
-+                 (frag_index->item[i+1].nb_stream_info > j &&
-+                  (frag_index->item[i+1].stream_info[j].index_entry == -1 ||
-+                   sample_index < frag_index->item[i+1].stream_info[j].index_entry)))) {
-+                if (found_index) {
-+                    *found_index = i;
-+                }
-+                return &item->stream_info[j];
-+            }
-+        }
-+    }
-+
-+    // This shouldn't happen
-+    return NULL;
-+}
-+
- static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
- {
-     int a, b, m;
-@@ -5118,7 +5148,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
-     sc->ctts_count = sti->nb_index_entries;
-     // Record the index_entry position in frag_index of this fragment
--    if (frag_stream_info)
-+    if (frag_stream_info && frag_stream_info->index_entry == -1)  // BUGFIX: In case of multiple trun, this must remain at the first value
-         frag_stream_info->index_entry = index_entry_pos;
-     if (index_entry_pos > 0)
-@@ -5986,6 +6016,8 @@ out:
-     return ret;
- }
-+static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom);
-+
- static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
- {
-     AVStream *st;
-@@ -6004,6 +6036,10 @@ static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
-         0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
-         0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
-     };
-+    static const AVUUID uuid_piff_senc = {
-+        0xA2, 0x39, 0x4F, 0x52, 0x5A, 0x9B, 0x4f, 0x14,
-+        0xA2, 0x44, 0x6C, 0x42, 0x7C, 0x64, 0x8D, 0xF4
-+    };
-     if (atom.size < AV_UUID_LEN || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
-         return AVERROR_INVALIDDATA;
-@@ -6086,6 +6122,9 @@ static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
-             return ret;
-         if (!sc->spherical)
-             av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
-+    } else if (av_uuid_equal(uuid, uuid_piff_senc)) {
-+        // PATCH: Netflix's stream packager outputs PIFF, which uses an uuid atom for senc boxes.
-+        mov_read_senc(c, pb, atom);
-     }
-     return 0;
-@@ -6407,7 +6446,12 @@ static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
-         offset += to_read;
-     }
--    *data = buffer;
-+    // PATCH: The original code leads to huge amounts of memory being hogged during playback (especially CENC streams).
-+    *data = av_realloc(buffer, size);
-+    if (!*data) {
-+        av_free(buffer);
-+        return AVERROR(ENOMEM);
-+    }
-     return 0;
- }
-@@ -7026,15 +7070,16 @@ static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryption
-     }
-     /* whole-block full sample encryption */
--    if (!sample->subsample_count) {
-+    // PATCH: Fix for Apple TV+, they have subsamples but don't use pattern encryption.
-+    if (!sample->subsample_count || (!sample->crypt_byte_block && !sample->skip_byte_block)) {
-         /* decrypt the whole packet */
-         memcpy(iv, sample->iv, 16);
-         av_aes_crypt(sc->cenc.aes_ctx, input, input, size/16, iv, 1);
-         return 0;
--    } else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
-+    }/* else if (!sample->crypt_byte_block && !sample->skip_byte_block) {
-         av_log(c->fc, AV_LOG_ERROR, "pattern encryption is not present in 'cbcs' scheme\n");
-         return AVERROR_INVALIDDATA;
--    }
-+    }*/
-     for (i = 0; i < sample->subsample_count; i++) {
-         if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
-@@ -7102,10 +7147,20 @@ static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPa
-         // Note this only supports encryption info in the first sample descriptor.
-         if (mov->fragment.stsd_id == 1) {
-             if (frag_stream_info->encryption_index) {
--                if (!current_index && frag_stream_info->index_entry)
-+                // PATCH: Fix seeking backwards in encrypted streams.
-+                //av_log(mov->fc, AV_LOG_INFO, "Frag Id: %d Index: %d (frag entry: %d)\n", frag_stream_info->id, current_index, frag_stream_info->index_entry);
-+                encrypted_index = current_index - frag_stream_info->index_entry;
-+                encryption_index = frag_stream_info->encryption_index;
-+                if (encrypted_index < 0 || encrypted_index >= encryption_index->nb_encrypted_samples) {
-+                    frag_stream_info = get_frag_stream_by_sample_index(&mov->frag_index, current_index, st->id,
-+                                                                        &mov->frag_index.current);
-+                    encrypted_index = current_index - frag_stream_info->index_entry;
-+                    encryption_index = frag_stream_info->encryption_index;
-+                }
-+                /*if (!current_index && frag_stream_info->index_entry)
-                     sc->cenc.frag_index_entry_base = frag_stream_info->index_entry;
-                 encrypted_index = current_index - (frag_stream_info->index_entry - sc->cenc.frag_index_entry_base);
--                encryption_index = frag_stream_info->encryption_index;
-+                encryption_index = frag_stream_info->encryption_index;*/
-             } else {
-                 encryption_index = sc->cenc.encryption_index;
-             }
-@@ -7133,8 +7188,9 @@ static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPa
-             // Per-sample setting override.
-             encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
-         } else {
--            av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
--            return AVERROR_INVALIDDATA;
-+            av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info (index %d, nb %d)\n", encrypted_index, encryption_index->nb_encrypted_samples);
-+            return 0; // CST hack - this can sometimes happen while seeking/switching audio streams, it's a non-fatal error.
-+            //return AVERROR_INVALIDDATA;
-         }
-         if (mov->decryption_key) {
-@@ -8572,15 +8628,16 @@ static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
-     if (index >= 0 && index < mov->frag_index.nb_items)
-         target = mov->frag_index.item[index].moof_offset;
--    if (avio_seek(s->pb, target, SEEK_SET) != target) {
-+    // https://ffmpeg.org/pipermail/ffmpeg-devel/2020-April/261343.html
-+    if (target >= 0 && avio_seek(s->pb, target, SEEK_SET) != target) {
-         av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
-         return AVERROR_INVALIDDATA;
-     }
-     mov->next_root_atom = 0;
--    if (index < 0 || index >= mov->frag_index.nb_items)
-+    if ((index < 0 && target >= 0) || index >= mov->frag_index.nb_items)
-         index = search_frag_moof_offset(&mov->frag_index, target);
--    if (index < mov->frag_index.nb_items &&
-+    if (index >= 0 && index < mov->frag_index.nb_items &&
-         mov->frag_index.item[index].moof_offset == target) {
-         if (index + 1 < mov->frag_index.nb_items)
-             mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
-@@ -8653,8 +8710,40 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
-     AVStream *st = NULL;
-     int64_t current_index;
-     int ret;
-+    int i;
-     mov->fc = s;
-  retry:
-+    // https://ffmpeg.org/pipermail/ffmpeg-devel/2020-April/261343.html
-+    if (s->pb->pos == 0) {
-+
-+        // Discard current fragment index
-+        if (mov->frag_index.allocated_size > 0) {
-+            av_freep(&mov->frag_index.item);
-+            mov->frag_index.nb_items = 0;
-+            mov->frag_index.allocated_size = 0;
-+            mov->frag_index.current = -1;
-+            mov->frag_index.complete = 0;
-+        }
-+
-+        for (i = 0; i < s->nb_streams; i++) {
-+            AVStream *avst = s->streams[i];
-+            FFStream *const avsti = ffstream(avst);
-+            MOVStreamContext *msc = avst->priv_data;
-+
-+            // Clear current sample
-+            mov_current_sample_set(msc, 0);
-+
-+            // Discard current index entries
-+            if (avsti->index_entries_allocated_size > 0) {
-+                av_freep(&avsti->index_entries);
-+                avsti->index_entries_allocated_size = 0;
-+                avsti->nb_index_entries = 0;
-+            }
-+        }
-+
-+        if ((ret = mov_switch_root(s, -1, -1)) < 0)
-+            return ret;
-+    }
-     sample = mov_find_next_sample(s, &st);
-     if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
-         if (!mov->next_root_atom)
diff --git a/archive-patches/ffmpeg-cst/5.1/0009-ffmpeg-discont.patch b/archive-patches/ffmpeg-cst/5.1/0009-ffmpeg-discont.patch
deleted file mode 100644 (file)
index 71f3bb4..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
-index e7384f052a..bc75fe3df6 100644
---- a/fftools/ffmpeg.c
-+++ b/fftools/ffmpeg.c
-@@ -4080,7 +4080,7 @@ static int process_input(int file_index)
-     if ((ist->dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO ||
-          ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) &&
-         pkt_dts != AV_NOPTS_VALUE && ist->next_dts == AV_NOPTS_VALUE && !copy_ts
--        && (is->iformat->flags & AVFMT_TS_DISCONT) && ifile->last_ts != AV_NOPTS_VALUE) {
-+        && (is->iformat->flags & AVFMT_TS_DISCONT) && ifile->last_ts != AV_NOPTS_VALUE && !force_dts_monotonicity) {
-         int64_t delta   = pkt_dts - ifile->last_ts;
-         if (delta < -1LL*dts_delta_threshold*AV_TIME_BASE ||
-             delta >  1LL*dts_delta_threshold*AV_TIME_BASE){
-@@ -4118,7 +4118,7 @@ static int process_input(int file_index)
-     if ((ist->dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO ||
-          ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) &&
-          pkt_dts != AV_NOPTS_VALUE && ist->next_dts != AV_NOPTS_VALUE &&
--        !disable_discontinuity_correction) {
-+        !disable_discontinuity_correction && !force_dts_monotonicity) {
-         int64_t delta   = pkt_dts - ist->next_dts;
-         if (is->iformat->flags & AVFMT_TS_DISCONT) {
-             if (delta < -1LL*dts_delta_threshold*AV_TIME_BASE ||
-@@ -4156,6 +4156,43 @@ static int process_input(int file_index)
-     if (pkt->dts != AV_NOPTS_VALUE)
-         ifile->last_ts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q);
-+    if ((ist->dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO ||
-+         ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) &&
-+        (pkt->pts != AV_NOPTS_VALUE || pkt->dts != AV_NOPTS_VALUE) &&
-+        force_dts_monotonicity) {
-+        int64_t ff_pts_error = 0;
-+        int64_t ff_dts_error = 0;
-+        int64_t ff_dts_threshold = av_rescale_q(dts_monotonicity_threshold, AV_TIME_BASE_Q, ist->st->time_base);
-+
-+        // adjust the incoming packet by the accumulated monotonicity error
-+        if (pkt->pts != AV_NOPTS_VALUE) {
-+            pkt->pts += ifile->ff_timestamp_monotonicity_offset;
-+            if (ist->next_pts != AV_NOPTS_VALUE) {
-+                ff_pts_error = av_rescale_q(ist->next_pts, AV_TIME_BASE_Q, ist->st->time_base) - pkt->pts;
-+            }
-+        }
-+        if (pkt->dts != AV_NOPTS_VALUE) {
-+            pkt->dts += ifile->ff_timestamp_monotonicity_offset;
-+            if (ist->next_dts != AV_NOPTS_VALUE) {
-+                ff_dts_error = av_rescale_q(ist->next_dts, AV_TIME_BASE_Q, ist->st->time_base) - pkt->dts;
-+            }
-+        }
-+
-+        if (ff_dts_error > 0 || ff_dts_error < (-ff_dts_threshold) || ff_pts_error < (-ff_dts_threshold)) {
-+            if (pkt->dts == AV_NOPTS_VALUE /*|| ist->next_dts != AV_NOPTS_VALUE*/) {
-+                pkt->pts += ff_pts_error;
-+                ifile->ff_timestamp_monotonicity_offset += ff_pts_error;
-+                av_log(is, AV_LOG_INFO, "Incoming PTS error %"PRId64", offsetting subsequent timestamps by %"PRId64" to correct\n", ff_pts_error, ifile->ff_timestamp_monotonicity_offset);
-+            }
-+            else {
-+                pkt->pts += ff_dts_error;
-+                pkt->dts += ff_dts_error;
-+                ifile->ff_timestamp_monotonicity_offset += ff_dts_error;
-+                av_log(is, AV_LOG_INFO, "Incoming DTS error %"PRId64", offsetting subsequent timestamps by %"PRId64" to correct\n", ff_dts_error, ifile->ff_timestamp_monotonicity_offset);
-+            }
-+        }
-+    }
-+
-     if (debug_ts) {
-         av_log(NULL, AV_LOG_INFO, "demuxer+ffmpeg -> ist_index:%d type:%s pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s duration:%s duration_time:%s off:%s off_time:%s\n",
-                ifile->ist_index + pkt->stream_index, av_get_media_type_string(ist->dec_ctx->codec_type),
-diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
-index 391a35cf50..3ca42c8f0c 100644
---- a/fftools/ffmpeg.h
-+++ b/fftools/ffmpeg.h
-@@ -433,6 +433,10 @@ typedef struct InputFile {
-     int joined;                 /* the thread has been joined */
-     int thread_queue_size;      /* maximum number of queued packets */
- #endif
-+
-+    // A value added to inbound timestamps to prevent them from going "backward" in cases such as HLS discontinuities
-+    int64_t ff_timestamp_monotonicity_offset;
-+
- } InputFile;
- enum forced_keyframes_const {
-@@ -620,6 +624,9 @@ extern float audio_drift_threshold;
- extern float dts_delta_threshold;
- extern float dts_error_threshold;
-+extern int dts_monotonicity_threshold;
-+extern int force_dts_monotonicity;
-+
- extern int audio_volume;
- extern int audio_sync_method;
- extern enum VideoSyncMethod video_sync_method;
-diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
-index 6e18a4a23e..f2c2313219 100644
---- a/fftools/ffmpeg_opt.c
-+++ b/fftools/ffmpeg_opt.c
-@@ -156,6 +156,9 @@ float audio_drift_threshold = 0.1;
- float dts_delta_threshold   = 10;
- float dts_error_threshold   = 3600*30;
-+int dts_monotonicity_threshold = AV_TIME_BASE;
-+int force_dts_monotonicity = 0;
-+
- int audio_volume      = 256;
- int audio_sync_method = 0;
- enum VideoSyncMethod video_sync_method = VSYNC_AUTO;
-@@ -1361,6 +1364,7 @@ static int open_input_file(OptionsContext *o, const char *filename)
-     f->input_sync_ref = o->input_sync_ref;
-     f->input_ts_offset = o->input_ts_offset;
-     f->ts_offset  = o->input_ts_offset - (copy_ts ? (start_at_zero && ic->start_time != AV_NOPTS_VALUE ? ic->start_time : 0) : timestamp);
-+    f->ff_timestamp_monotonicity_offset = 0;
-     f->nb_streams = ic->nb_streams;
-     f->rate_emu   = o->rate_emu;
-     f->accurate_seek = o->accurate_seek;
-@@ -3760,6 +3764,10 @@ const OptionDef options[] = {
-     { "apad",           OPT_STRING | HAS_ARG | OPT_SPEC |
-                         OPT_OUTPUT,                                  { .off = OFFSET(apad) },
-         "audio pad", "" },
-+    { "force_dts_monotonicity", OPT_BOOL | OPT_EXPERT,               { &force_dts_monotonicity },
-+        "correct dts monotonicity errors" },
-+    { "dts_monotonicity_threshold", HAS_ARG | OPT_INT | OPT_EXPERT,  { &dts_monotonicity_threshold },
-+        "dts correction threshold for forward jumps", "microseconds" },
-     { "dts_delta_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT,       { &dts_delta_threshold },
-         "timestamp discontinuity delta threshold", "threshold" },
-     { "dts_error_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT,       { &dts_error_threshold },
diff --git a/archive-patches/ffmpeg-cst/5.1/0010-hls-replace-key-uri.patch b/archive-patches/ffmpeg-cst/5.1/0010-hls-replace-key-uri.patch
deleted file mode 100644 (file)
index 113cd28..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-diff --git a/libavformat/hls.c b/libavformat/hls.c
-index faf92804a2..bbc8388c94 100644
---- a/libavformat/hls.c
-+++ b/libavformat/hls.c
-@@ -225,6 +225,8 @@ typedef struct HLSContext {
-     int http_persistent;
-     int http_multiple;
-     int http_seekable;
-+    char *key_uri_replace_old;
-+    char *key_uri_replace_new;
-     AVIOContext *playlist_pb;
-     HLSCryptoContext  crypto_ctx;
- } HLSContext;
-@@ -1293,8 +1295,16 @@ static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg,
-     if (seg->key_type == KEY_AES_128 || seg->key_type == KEY_SAMPLE_AES) {
-         if (strcmp(seg->key, pls->key_url)) {
-+            char *key_url = NULL;
-             AVIOContext *pb = NULL;
--            if (open_url(pls->parent, &pb, seg->key, &c->avio_opts, opts, NULL) == 0) {
-+            if (NULL != c->key_uri_replace_old && \
-+                NULL != c-> key_uri_replace_new && \
-+                '\0' != c->key_uri_replace_old[0]) {
-+                key_url = av_strireplace(seg->key, c->key_uri_replace_old, c->key_uri_replace_new);
-+            } else {
-+                key_url = seg->key;
-+            }
-+            if (open_url(pls->parent, &pb, key_url, &c->avio_opts, opts, NULL) == 0) {
-                 ret = avio_read(pb, pls->key, sizeof(pls->key));
-                 if (ret != sizeof(pls->key)) {
-                     av_log(pls->parent, AV_LOG_ERROR, "Unable to read key file %s\n",
-@@ -1306,6 +1316,8 @@ static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg,
-                        seg->key);
-             }
-             av_strlcpy(pls->key_url, seg->key, sizeof(pls->key_url));
-+            if (key_url != seg->key)
-+                av_free(key_url);
-         }
-     }
-@@ -2530,6 +2542,8 @@ static int hls_probe(const AVProbeData *p)
- #define OFFSET(x) offsetof(HLSContext, x)
- #define FLAGS AV_OPT_FLAG_DECODING_PARAM
- static const AVOption hls_options[] = {
-+    { "key_uri_old", "allow to replace part of AES key uri - old", OFFSET(key_uri_replace_old), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, FLAGS },
-+    { "key_uri_new", "allow to replace part of AES key uri - new", OFFSET(key_uri_replace_new), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, FLAGS },
-     {"live_start_index", "segment index to start live streams at (negative values are from the end)",
-         OFFSET(live_start_index), AV_OPT_TYPE_INT, {.i64 = -3}, INT_MIN, INT_MAX, FLAGS},
-     {"prefer_x_start", "prefer to use #EXT-X-START if it's in playlist instead of live_start_index",
diff --git a/archive-patches/ffmpeg-cst/5.1/0011-recheck-discard-flags.patch b/archive-patches/ffmpeg-cst/5.1/0011-recheck-discard-flags.patch
deleted file mode 100644 (file)
index afddf42..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
---- a/libavformat/hls.c
-+++ b/libavformat/hls.c
-@@ -2171,8 +2171,10 @@
-     HLSContext *c = s->priv_data;
-     int ret, i, minplaylist = -1;
--    recheck_discard_flags(s, c->first_packet);
--    c->first_packet = 0;
-+    if (c->first_packet) {
-+        recheck_discard_flags(s, 1);
-+        c->first_packet = 0;
-+    }
-     for (i = 0; i < c->n_playlists; i++) {
-         struct playlist *pls = c->playlists[i];
diff --git a/archive-patches/ffmpeg-cst/5.1/0012-rtsp.patch b/archive-patches/ffmpeg-cst/5.1/0012-rtsp.patch
deleted file mode 100644 (file)
index 08930f4..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
-index f948f1d395..69507ec866 100644
---- a/libavformat/rtsp.c
-+++ b/libavformat/rtsp.c
-@@ -2391,6 +2391,8 @@ static int sdp_read_header(AVFormatContext *s)
-     int i, err;
-     char url[MAX_URL_SIZE];
-     AVBPrint bp;
-+    const char *p, *sp="", *sources="", *sp2, *sources2;
-+    char sources_buf[1024];
-     if (!ff_network_init())
-         return AVERROR(EIO);
-@@ -2412,6 +2414,16 @@ static int sdp_read_header(AVFormatContext *s)
-     av_bprint_finalize(&bp, NULL);
-     if (err) goto fail;
-+    /* Search for sources= tag in original URL for rtp protocol only */
-+    if (strncmp(s->url, "rtp://", 6) == 0) {
-+        p = strchr(s->url, '?');
-+        if (p && av_find_info_tag(sources_buf, sizeof(sources_buf), "sources", p)) {
-+            /* av_log(s, AV_LOG_VERBOSE, "sdp_read_header found sources %s\n", sources_buf);  */
-+            sp = sources_buf;
-+            sources = "&sources=";
-+        }
-+    }
-+
-     /* open each RTP stream */
-     for (i = 0; i < rt->nb_rtsp_streams; i++) {
-         char namebuf[50];
-@@ -2431,12 +2443,22 @@ static int sdp_read_header(AVFormatContext *s)
-                 av_dict_free(&opts);
-                 goto fail;
-             }
-+
-+            /* Prepare to add sources to the url to be opened.
-+               Otherwise the join to the source specific muliticast will be missing */
-+            sources2 = sources;
-+            sp2 = sp;
-+            /* ignore sources from original URL, when sources are already set in rtsp_st */
-+            if (rtsp_st->nb_include_source_addrs > 0)
-+                sources2 = sp2 = "";
-+
-             ff_url_join(url, sizeof(url), "rtp", NULL,
-                         namebuf, rtsp_st->sdp_port,
--                        "?localport=%d&ttl=%d&connect=%d&write_to_source=%d",
-+                        "?localport=%d&ttl=%d&connect=%d&write_to_source=%d%s%s",
-                         rtsp_st->sdp_port, rtsp_st->sdp_ttl,
-                         rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0,
--                        rt->rtsp_flags & RTSP_FLAG_RTCP_TO_SOURCE ? 1 : 0);
-+                        rt->rtsp_flags & RTSP_FLAG_RTCP_TO_SOURCE ? 1 : 0,
-+                        sources2, sp2);
-             p = strchr(s->url, '?');
-             if (p && av_find_info_tag(buf, sizeof(buf), "localaddr", p))
diff --git a/archive-patches/ffmpeg-cst/5.1/ffmpeg-increase-IO_BUFFER_SIZE-to-256k.patch b/archive-patches/ffmpeg-cst/5.1/ffmpeg-increase-IO_BUFFER_SIZE-to-256k.patch
deleted file mode 100644 (file)
index 1c96a07..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-From f193409d354a41d8afaf1b75ca34dc1839a60b69 Mon Sep 17 00:00:00 2001
-From: gandharva <gandharva@gmx.de>
-Date: Wed, 14 Jun 2017 19:51:24 +0200
-Subject: [PATCH 8/8] - increase IO_BUFFER_SIZE to 128k
-
-performance improvement when using SMB/CIFS
----
- libavformat/aviobuf.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
-index c2681ed..711fff8 100644
---- a/libavformat/aviobuf.c
-+++ b/libavformat/aviobuf.c
-@@ -33,7 +33,7 @@
- #include "url.h"
- #include <stdarg.h>
--#define IO_BUFFER_SIZE 32768
-+#define IO_BUFFER_SIZE 262144
- /**
-  * Do seeks within this distance ahead of the current buffer by skipping
--- 
-2.1.4
-
diff --git a/archive-patches/ffmpeg-cst/5.1/optional/README.txt b/archive-patches/ffmpeg-cst/5.1/optional/README.txt
deleted file mode 100644 (file)
index 5a14c71..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-These patches mostly fix processing DRM DASH/HLS streams.\r
-\r
-hls-changes sets a rather high buffer size (tuned towards 1080p VOD content), which may be undesirable for live streams or SD VOD content.\r
-\r
-dash-hacks contains some fixes that may help with DASH streams that contain subtitles and multiple audio streams (esp. switching between streams on CST).
\ No newline at end of file
diff --git a/archive-patches/ffmpeg-cst/5.1/optional/ffmpeg51-dash-hacks.patch b/archive-patches/ffmpeg-cst/5.1/optional/ffmpeg51-dash-hacks.patch
deleted file mode 100644 (file)
index 5668bbd..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c
-index 2ca91bea8b..ecaf50047d 100644
---- a/libavformat/dashdec.c
-+++ b/libavformat/dashdec.c
-@@ -441,8 +441,12 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url,
-         return AVERROR_INVALIDDATA;
-     av_freep(pb);
-+
-     av_dict_copy(&tmp, *opts, 0);
-     av_dict_copy(&tmp, opts2, 0);
-+    av_dict_set_int(&tmp, "reconnect", 1, 0);
-+    av_dict_set_int(&tmp, "icy", 0, 0);
-+
-     ret = avio_open2(pb, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp);
-     if (ret >= 0) {
-         // update cookies on http response with setcookies.
-@@ -768,7 +772,8 @@ static int resolve_content_path(AVFormatContext *s, const char *url, int *max_ur
-     baseurl = xmlNodeGetContent(node);
-     root_url = (av_strcasecmp(baseurl, "")) ? baseurl : path;
-     if (node) {
--        xmlNodeSetContent(node, root_url);
-+        // HACK: SetContent fails if the URL happens to include '&', which isn't that uncommon...
-+        //xmlNodeSetContent(node, root_url);
-         updated = 1;
-     }
-@@ -802,7 +807,7 @@ static int resolve_content_path(AVFormatContext *s, const char *url, int *max_ur
-                 memset(p + 1, 0, strlen(p));
-             }
-             av_strlcat(tmp_str, text + start, tmp_max_url_size);
--            xmlNodeSetContent(baseurl_nodes[i], tmp_str);
-+            //xmlNodeSetContent(baseurl_nodes[i], tmp_str);
-             updated = 1;
-             xmlFree(text);
-         }
-@@ -1217,6 +1222,7 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in)
-     char *val  = NULL;
-     uint32_t period_duration_sec = 0;
-     uint32_t period_start_sec = 0;
-+    char *nfcs_key = NULL;
-     if (!in) {
-         close_in = 1;
-@@ -1335,6 +1341,12 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in)
-             } else if (!av_strcasecmp(node->name, "ProgramInformation")) {
-                 parse_programinformation(s, node);
-             }
-+            // HACK: libvodstream stores decrypted keys in a custom tag.
-+            if (!av_strcasecmp(node->name, (const char*)"nfcskey")) {
-+                nfcs_key = xmlNodeGetContent(node->children);
-+                c->cenc_decryption_key = av_strdup(nfcs_key);
-+                xmlFree(nfcs_key);
-+            }
-             node = xmlNextElementSibling(node);
-         }
-         if (!period_node) {
-@@ -1879,7 +1891,8 @@ static int reopen_demux_for_component(AVFormatContext *s, struct representation
-     }
-     ffio_init_context(&pls->pb, avio_ctx_buffer, INITIAL_BUFFER_SIZE, 0,
-                       pls, read_data, NULL, c->is_live ? NULL : seek_data);
--    pls->pb.pub.seekable = 0;
-+    // PATCH: If this is 0, seeking in VOD streams downloads the entire content between origin and target.
-+    pls->pb.pub.seekable = 1;
-     if ((ret = ff_copy_whiteblacklists(pls->ctx, s)) < 0)
-         goto fail;
-@@ -2167,6 +2180,7 @@ static int dash_read_packet(AVFormatContext *s, AVPacket *pkt)
-     int ret = 0, i;
-     int64_t mints = 0;
-     struct representation *cur = NULL;
-+    struct representation *curHack = NULL;
-     struct representation *rep = NULL;
-     recheck_discard_flags(s, c->videos, c->n_videos);
-@@ -2188,6 +2202,7 @@ static int dash_read_packet(AVFormatContext *s, AVPacket *pkt)
-             continue;
-         if (!cur || rep->cur_timestamp < mints) {
-             cur = rep;
-+            curHack = rep;
-             mints = rep->cur_timestamp;
-         }
-     }
-@@ -2203,6 +2218,7 @@ static int dash_read_packet(AVFormatContext *s, AVPacket *pkt)
-     }
-     if (!cur) {
-+        av_log(s, AV_LOG_WARNING, "INVALIDDATA\n");
-         return AVERROR_INVALIDDATA;
-     }
-     while (!ff_check_interrupt(c->interrupt_callback) && !ret) {
-@@ -2221,6 +2237,26 @@ static int dash_read_packet(AVFormatContext *s, AVPacket *pkt)
-             cur->is_restart_needed = 0;
-         }
-     }
-+    if (curHack && curHack != cur) {
-+        cur = curHack;
-+        ret = 0;
-+        while (!ff_check_interrupt(c->interrupt_callback) && !ret) {
-+            ret = av_read_frame(cur->ctx, pkt);
-+            if (ret >= 0) {
-+                /* If we got a packet, return it */
-+                cur->cur_timestamp = av_rescale(pkt->pts, (int64_t)cur->ctx->streams[0]->time_base.num * 90000, cur->ctx->streams[0]->time_base.den);
-+                pkt->stream_index = cur->stream_index;
-+                return 0;
-+            }
-+            if (cur->is_restart_needed) {
-+                cur->cur_seg_offset = 0;
-+                cur->init_sec_buf_read_offset = 0;
-+                ff_format_io_close(cur->parent, &cur->input);
-+                ret = reopen_demux_for_component(s, cur);
-+                cur->is_restart_needed = 0;
-+            }
-+        }
-+    }
-     return AVERROR_EOF;
- }
-@@ -2232,6 +2268,7 @@ static int dash_close(AVFormatContext *s)
-     free_subtitle_list(c);
-     av_dict_free(&c->avio_opts);
-     av_freep(&c->base_url);
-+    av_freep(&c->cenc_decryption_key);
-     return 0;
- }
-@@ -2319,10 +2356,11 @@ static int dash_read_seek(AVFormatContext *s, int stream_index, int64_t timestam
-         if (!ret)
-             ret = dash_seek(s, c->audios[i], seek_pos_msec, flags, !c->audios[i]->ctx);
-     }
--    for (i = 0; i < c->n_subtitles; i++) {
--        if (!ret)
--            ret = dash_seek(s, c->subtitles[i], seek_pos_msec, flags, !c->subtitles[i]->ctx);
--    }
-+    // PATCH: Seeking in subtitle streams breaks things, and it doesn't seem necessary.
-+    //for (i = 0; i < c->n_subtitles; i++) {
-+    //    if (!ret)
-+    //        ret = dash_seek(s, c->subtitles[i], seek_pos_msec, flags, !c->subtitles[i]->ctx);
-+    //}
-     return ret;
- }
diff --git a/archive-patches/ffmpeg-cst/5.1/optional/ffmpeg51-hls-changes.patch b/archive-patches/ffmpeg-cst/5.1/optional/ffmpeg51-hls-changes.patch
deleted file mode 100644 (file)
index ea96739..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-diff --git a/libavformat/hls.c b/libavformat/hls.c
-index e622425e80..faf92804a2 100644
---- a/libavformat/hls.c
-+++ b/libavformat/hls.c
-@@ -46,7 +46,7 @@
- #include "hls_sample_encryption.h"
--#define INITIAL_BUFFER_SIZE 32768
-+#define INITIAL_BUFFER_SIZE 1048576
- #define MAX_FIELD_LEN 64
- #define MAX_CHARACTERISTICS_LEN 512
-@@ -1580,7 +1580,7 @@ reload:
-     seg = next_segment(v);
-     if (c->http_multiple == 1 && !v->input_next_requested &&
--        seg && seg->key_type == KEY_NONE && av_strstart(seg->url, "http", NULL)) {
-+        seg && seg->key_type != KEY_AES_128 && av_strstart(seg->url, "http", NULL)) {
-         ret = open_input(c, v, seg, &v->input_next);
-         if (ret < 0) {
-             if (ff_check_interrupt(c->interrupt_callback))
-@@ -1613,7 +1613,7 @@ reload:
-         return ret;
-     }
-     if (c->http_persistent &&
--        seg->key_type == KEY_NONE && av_strstart(seg->url, "http", NULL)) {
-+        seg->key_type != KEY_AES_128 && av_strstart(seg->url, "http", NULL)) {
-         v->input_read_done = 1;
-     } else {
-         ff_format_io_close(v->parent, &v->input);
-@@ -2475,6 +2475,7 @@ static int hls_read_seek(AVFormatContext *s, int stream_index,
-     /* set segment now so we do not need to search again below */
-     seek_pls->cur_seq_no = seq_no;
-     seek_pls->seek_stream_index = stream_subdemuxer_index;
-+    //av_log(s, AV_LOG_INFO, "Seek to %d in %d\n", seq_no, stream_subdemuxer_index);
-     for (i = 0; i < c->n_playlists; i++) {
-         /* Reset reading */
-@@ -2535,7 +2536,7 @@ static const AVOption hls_options[] = {
-         OFFSET(prefer_x_start), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS},
-     {"allowed_extensions", "List of file extensions that hls is allowed to access",
-         OFFSET(allowed_extensions), AV_OPT_TYPE_STRING,
--        {.str = "3gp,aac,avi,ac3,eac3,flac,mkv,m3u8,m4a,m4s,m4v,mpg,mov,mp2,mp3,mp4,mpeg,mpegts,ogg,ogv,oga,ts,vob,wav"},
-+        {.str = "3gp,aac,avi,ac3,eac3,flac,key,mkv,m3u8,m4a,m4s,m4v,mpg,mov,mp2,mp3,mp4,mpeg,mpegts,ogg,ogv,oga,ts,vob,wav"},
-         INT_MIN, INT_MAX, FLAGS},
-     {"max_reload", "Maximum number of times a insufficient list is attempted to be reloaded",
-         OFFSET(max_reload), AV_OPT_TYPE_INT, {.i64 = 1000}, 0, INT_MAX, FLAGS},
-@@ -2544,7 +2545,7 @@ static const AVOption hls_options[] = {
-     {"http_persistent", "Use persistent HTTP connections",
-         OFFSET(http_persistent), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, FLAGS },
-     {"http_multiple", "Use multiple HTTP connections for fetching segments",
--        OFFSET(http_multiple), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, FLAGS},
-+        OFFSET(http_multiple), AV_OPT_TYPE_BOOL, {.i64 = 0}, -1, 1, FLAGS},
-     {"http_seekable", "Use HTTP partial requests, 0 = disable, 1 = enable, -1 = auto",
-         OFFSET(http_seekable), AV_OPT_TYPE_BOOL, { .i64 = -1}, -1, 1, FLAGS},
-     {"seg_format_options", "Set options for segment demuxer",
index 2782ea9d825f3dfe28117b66af487bddf2e7cd92..aa53e26b0b7a893147bcd22fbd603053acf21552 100644 (file)
@@ -78,7 +78,7 @@ FFMPEG_VER = 4.4.2
 else ifeq ($(BOXTYPE), coolstream)
 #FFMPEG_GIT = 2ba896f
 #FFMPEG_VER = 3.3
-FFMPEG_VER = 5.1
+FFMPEG_VER = 5.1.2
 endif
 
 # FLAC stands for Free Lossless Audio Codec, an audio format similar to MP3, but lossless, meaning that audio is compressed in FLAC without any loss in quality