]> git.webhop.me Git - bs-cst-neutrino-hd.git/commitdiff
bump version ffmpeg-5.1.2 for ARM
authorMarkham <markham001@gmx.de>
Sat, 14 Jan 2023 10:01:45 +0000 (11:01 +0100)
committerMarkham <markham001@gmx.de>
Sat, 14 Jan 2023 10:01:45 +0000 (11:01 +0100)
16 files changed:
archive-patches/ffmpeg-arm/5.1.2/0001-aac-optimize0.patch [new file with mode: 0644]
archive-patches/ffmpeg-arm/5.1.2/0002-add64_c-parentheses.patch [new file with mode: 0644]
archive-patches/ffmpeg-arm/5.1.2/0007-disable-whitelist.patch [new file with mode: 0644]
archive-patches/ffmpeg-arm/5.1.2/0008-mov-cenc-fixes.patch [new file with mode: 0644]
archive-patches/ffmpeg-arm/5.1.2/0009-ffmpeg-discont.patch [new file with mode: 0644]
archive-patches/ffmpeg-arm/5.1.2/0010-hls-replace-key-uri.patch [new file with mode: 0644]
archive-patches/ffmpeg-arm/5.1.2/0011-recheck-discard-flags.patch [new file with mode: 0644]
archive-patches/ffmpeg-arm/5.1.2/0012-rtsp.patch [new file with mode: 0644]
archive-patches/ffmpeg-arm/5.1.2/0013-increase-IO_BUFFER_SIZE-to-256k.patch [new file with mode: 0644]
archive-patches/ffmpeg-arm/5.1.2/0014-avcodec-vaapi_h264-skip-decode-if-pic-has-no-slices.patch [new file with mode: 0644]
archive-patches/ffmpeg-arm/5.1.2/0015-configure-add-extralibs-to-extralibs_xxx.patch [new file with mode: 0644]
archive-patches/ffmpeg-arm/5.1.2/ffmpeg-5.1-fix_edit_list_parsing.patch [new file with mode: 0644]
archive-patches/ffmpeg-arm/5.1.2/ffmpeg-5.1-fix_mpegts.patch [new file with mode: 0644]
archive-patches/ffmpeg-arm/5.1.2/ffmpeg-5.1-nolog.patch [new file with mode: 0644]
archive-patches/ffmpeg-arm/5.1.2/replay_dash.patch [new file with mode: 0644]
make/versions.mk

diff --git a/archive-patches/ffmpeg-arm/5.1.2/0001-aac-optimize0.patch b/archive-patches/ffmpeg-arm/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-arm/5.1.2/0002-add64_c-parentheses.patch b/archive-patches/ffmpeg-arm/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-arm/5.1.2/0007-disable-whitelist.patch b/archive-patches/ffmpeg-arm/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-arm/5.1.2/0008-mov-cenc-fixes.patch b/archive-patches/ffmpeg-arm/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-arm/5.1.2/0009-ffmpeg-discont.patch b/archive-patches/ffmpeg-arm/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-arm/5.1.2/0010-hls-replace-key-uri.patch b/archive-patches/ffmpeg-arm/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-arm/5.1.2/0011-recheck-discard-flags.patch b/archive-patches/ffmpeg-arm/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-arm/5.1.2/0012-rtsp.patch b/archive-patches/ffmpeg-arm/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-arm/5.1.2/0013-increase-IO_BUFFER_SIZE-to-256k.patch b/archive-patches/ffmpeg-arm/5.1.2/0013-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-arm/5.1.2/0014-avcodec-vaapi_h264-skip-decode-if-pic-has-no-slices.patch b/archive-patches/ffmpeg-arm/5.1.2/0014-avcodec-vaapi_h264-skip-decode-if-pic-has-no-slices.patch
new file mode 100644 (file)
index 0000000..2892df9
--- /dev/null
@@ -0,0 +1,36 @@
+From 2c6b3f357331e203ad87214984661c40704aceb7 Mon Sep 17 00:00:00 2001
+From: Rainer Hochecker <fernetmenta@online.de>
+Date: Sat, 26 Jan 2019 19:48:35 +0100
+Subject: [PATCH] avcodec/vaapi_h264: skip decode if pic has no slices
+
+This fixes / workarounds https://bugs.freedesktop.org/show_bug.cgi?id=105368.
+It was hit frequently when watching h264 channels received via DVB-X.
+Corresponding kodi bug: https://github.com/xbmc/xbmc/issues/15704
+
+Downloaded from Kodi ffmpeg repo:
+https://github.com/xbmc/FFmpeg/commit/2c6b3f357331e203ad87214984661c40704aceb7
+
+Patch was sent upstream:
+http://ffmpeg.org/pipermail/ffmpeg-devel/2019-March/240863.html
+
+Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
+---
+ libavcodec/vaapi_h264.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c
+index dd2a6571604..e521a05c4ff 100644
+--- a/libavcodec/vaapi_h264.c
++++ b/libavcodec/vaapi_h264.c
+@@ -314,6 +314,11 @@ static int vaapi_h264_end_frame(AVCodecContext *avctx)
+     H264SliceContext *sl = &h->slice_ctx[0];
+     int ret;
++    if (pic->nb_slices == 0) {
++        ret = AVERROR_INVALIDDATA;
++        goto finish;
++    }
++
+     ret = ff_vaapi_decode_issue(avctx, pic);
+     if (ret < 0)
+         goto finish;
diff --git a/archive-patches/ffmpeg-arm/5.1.2/0015-configure-add-extralibs-to-extralibs_xxx.patch b/archive-patches/ffmpeg-arm/5.1.2/0015-configure-add-extralibs-to-extralibs_xxx.patch
new file mode 100644 (file)
index 0000000..0ae337a
--- /dev/null
@@ -0,0 +1,45 @@
+From 0c288853630b7b4e004774c39945d4a804afcfa8 Mon Sep 17 00:00:00 2001
+From: Fabrice Fontaine <fontaine.fabrice@gmail.com>
+Date: Fri, 6 Aug 2021 09:17:20 +0200
+Subject: [PATCH] configure: add extralibs to extralibs_xxx
+
+Add extralibs to extralibs_xxx (e.g. extralibs_avformat) to allow
+applications such as motion to retrieve ffmpeg dependencies such as
+-latomic through pkg-config
+
+Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
+[Upstream status: not upstreamable]
+---
+ configure | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/configure b/configure
+index 0bb3a7cf2b..3bda99e415 100755
+--- a/configure
++++ b/configure
+@@ -7918,14 +7918,14 @@
+ source_path=${source_path}
+ LIBPREF=${LIBPREF}
+ LIBSUF=${LIBSUF}
+-extralibs_avutil="$avutil_extralibs"
+-extralibs_avcodec="$avcodec_extralibs"
+-extralibs_avformat="$avformat_extralibs"
+-extralibs_avdevice="$avdevice_extralibs"
+-extralibs_avfilter="$avfilter_extralibs"
+-extralibs_postproc="$postproc_extralibs"
+-extralibs_swscale="$swscale_extralibs"
+-extralibs_swresample="$swresample_extralibs"
++extralibs_avutil="$avutil_extralibs $extralibs"
++extralibs_avcodec="$avcodec_extralibs $extralibs"
++extralibs_avformat="$avformat_extralibs $extralibs"
++extralibs_avdevice="$avdevice_extralibs $extralibs"
++extralibs_avfilter="$avfilter_extralibs $extralibs"
++extralibs_postproc="$postproc_extralibs $extralibs"
++extralibs_swscale="$swscale_extralibs $extralibs"
++extralibs_swresample="$swresample_extralibs $extralibs"
+ EOF
+ for lib in $LIBRARY_LIST; do
+-- 
+2.30.2
+
diff --git a/archive-patches/ffmpeg-arm/5.1.2/ffmpeg-5.1-fix_edit_list_parsing.patch b/archive-patches/ffmpeg-arm/5.1.2/ffmpeg-5.1-fix_edit_list_parsing.patch
new file mode 100644 (file)
index 0000000..2d477bd
--- /dev/null
@@ -0,0 +1,13 @@
+--- a/libavformat/mov.c
++++ b/libavformat/mov.c
+@@ -3771,8 +3771,10 @@
+             if (ctts_data_old && ctts_index_old < ctts_count_old) {
+                 curr_ctts = ctts_data_old[ctts_index_old].duration;
++/*
+                 av_log(mov->fc, AV_LOG_TRACE, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
+                        curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
++*/
+                 curr_cts += curr_ctts;
+                 ctts_sample_old++;
+                 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
diff --git a/archive-patches/ffmpeg-arm/5.1.2/ffmpeg-5.1-fix_mpegts.patch b/archive-patches/ffmpeg-arm/5.1.2/ffmpeg-5.1-fix_mpegts.patch
new file mode 100644 (file)
index 0000000..5867d57
--- /dev/null
@@ -0,0 +1,15 @@
+--- a/libavformat/mpegts.c
++++ b/libavformat/mpegts.c
+@@ -1018,10 +1018,12 @@
+     pes->buffer = NULL;
+     reset_pes_packet_state(pes);
++    /*
+     sd = av_packet_new_side_data(pkt, AV_PKT_DATA_MPEGTS_STREAM_ID, 1);
+     if (!sd)
+         return AVERROR(ENOMEM);
+     *sd = pes->stream_id;
++    */
+     return 0;
+ }
diff --git a/archive-patches/ffmpeg-arm/5.1.2/ffmpeg-5.1-nolog.patch b/archive-patches/ffmpeg-arm/5.1.2/ffmpeg-5.1-nolog.patch
new file mode 100644 (file)
index 0000000..e03e0f1
--- /dev/null
@@ -0,0 +1,24 @@
+diff --git a/libavutil/log.c b/libavutil/log.c
+index 5948e50467..528eaa728c 100644
+--- a/libavutil/log.c
++++ b/libavutil/log.c
+@@ -53,7 +53,7 @@ static AVMutex mutex = AV_MUTEX_INITIALIZER;
+ #define BACKTRACE_LOGLEVEL AV_LOG_ERROR
+ #endif
+-static int av_log_level = AV_LOG_INFO;
++static int av_log_level = AV_LOG_ERROR; // NOT WORKING for libs
+ static int flags;
+ #define NB_LEVELS 8
+@@ -406,10 +406,6 @@ static void (*av_log_callback)(void*, int, const char*, va_list) =
+ void av_log(void* avcl, int level, const char *fmt, ...)
+ {
+-    va_list vl;
+-    va_start(vl, fmt);
+-    av_vlog(avcl, level, fmt, vl);
+-    va_end(vl);
+ }
+ void av_log_once(void* avcl, int initial_level, int subsequent_level, int *state, const char *fmt, ...)
diff --git a/archive-patches/ffmpeg-arm/5.1.2/replay_dash.patch b/archive-patches/ffmpeg-arm/5.1.2/replay_dash.patch
new file mode 100644 (file)
index 0000000..3c3b4be
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/libavformat/dashdec.c
++++ b/libavformat/dashdec.c
+@@ -1401,6 +1401,8 @@ static int64_t calc_cur_seg_no(AVFormatContext *s, struct representation *pls)
+                 } else {
+                     num = pls->first_seq_no + (((c->publish_time - c->time_shift_buffer_depth + pls->fragment_duration) - c->suggested_presentation_delay) * pls->fragment_timescale) / pls->fragment_duration;
+                 }
++            } else if (c->period_start && c->availability_start_time && pls->fragment_timescale) {
++                num = pls->first_seq_no + (((get_current_time_in_sec() - (c->availability_start_time + c->period_start)) * pls->fragment_timescale) - pls->fragment_duration) / pls->fragment_duration;
+             } else {
+                 num = pls->first_seq_no + (((get_current_time_in_sec() - c->availability_start_time) - c->suggested_presentation_delay) * pls->fragment_timescale) / pls->fragment_duration;
+             }
index 4cc78d920d316404309b2617b8aba05de36bb26c..b2dbdf76a022c97c494086280a28b4d4fdc69f67 100644 (file)
@@ -74,7 +74,7 @@ FBSHOT_VER = 0.3
 
 # FFMPEG | A complete, cross-platform solution to record, convert and stream audio and video
 ifeq ($(BOXTYPE), armbox)
-FFMPEG_VER = 4.4.2
+FFMPEG_VER = 5.1.2
 else ifeq ($(BOXTYPE), coolstream)
 #FFMPEG_GIT = 2ba896f
 #FFMPEG_VER = 3.3