Update patches

This commit is contained in:
Ingo Oppermann
2025-12-19 11:59:06 +02:00
parent a580cb21c7
commit 4223ffe411
3 changed files with 459 additions and 38 deletions

View File

@@ -16,7 +16,7 @@ jobs:
os: ubuntu
os_version: "24.04"
platforms: linux/amd64
cuda_version: "12.8.0"
cuda_version: "12.8.1"
ffnvcodec_version: "12.2.72.0"
ffmpeg_version: "7.1.1"
steps:

View File

@@ -1,12 +1,12 @@
From 763304129a1fb2e347c870b1250b90a696ee4317 Mon Sep 17 00:00:00 2001
From 014b594a77161a7b4ffb5d63846547bb176fe6ba Mon Sep 17 00:00:00 2001
From: Ingo Oppermann <ingo@datarhei.com>
Date: Mon, 20 Jan 2025 17:32:20 +0100
Subject: [PATCH v3] hls (7.1.0)
Date: Wed, 22 Oct 2025 17:28:57 +0200
Subject: [PATCH v2] hls (7.1.1)
---
README.HLS.md | 48 +++++++++++++++++++++++++++
libavformat/hlsenc.c | 79 ++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 125 insertions(+), 2 deletions(-)
README.HLS.md | 48 ++++++++++++++++++++
libavformat/hlsenc.c | 104 +++++++++++++++++++++++++++++++++++++++++--
2 files changed, 149 insertions(+), 3 deletions(-)
create mode 100644 README.HLS.md
diff --git a/README.HLS.md b/README.HLS.md
@@ -64,10 +64,18 @@ index 00000000..5462338b
+
+In the command, the `-var_stream_map` option had the value `v:0,a:0 v:1,a:1`.
diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 1e932b7b..11a3f0dd 100644
index 081d91f7..14fa5480 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -125,6 +125,7 @@ typedef struct VariantStream {
@@ -109,6 +109,7 @@ typedef enum HLSFlags {
HLS_PERIODIC_REKEY = (1 << 12),
HLS_INDEPENDENT_SEGMENTS = (1 << 13),
HLS_I_FRAMES_ONLY = (1 << 14),
+ HLS_ADJUST_SEQUENCE = (1 << 15),
} HLSFlags;
typedef enum {
@@ -125,6 +126,7 @@ typedef struct VariantStream {
AVIOContext *out;
AVIOContext *out_single_file;
int packets_written;
@@ -75,7 +83,7 @@ index 1e932b7b..11a3f0dd 100644
int init_range_length;
uint8_t *temp_buffer;
uint8_t *init_buffer;
@@ -139,6 +140,8 @@ typedef struct VariantStream {
@@ -139,6 +141,8 @@ typedef struct VariantStream {
double dpp; // duration per packet
int64_t start_pts;
int64_t end_pts;
@@ -84,7 +92,16 @@ index 1e932b7b..11a3f0dd 100644
int64_t video_lastpos;
int64_t video_keyframe_pos;
int64_t video_keyframe_size;
@@ -1507,6 +1510,16 @@ static int create_master_playlist(AVFormatContext *s,
@@ -1503,12 +1507,28 @@ static int create_master_playlist(AVFormatContext *s,
if (final) {
bandwidth = vs->max_bitrate;
avg_bandwidth = vs->avg_bitrate;
+ if (avg_bandwidth < 0) {
+ avg_bandwidth = 0;
+ }
} else {
bandwidth = 0;
if (vid_st)
bandwidth += get_stream_bit_rate(vid_st);
if (aud_st)
bandwidth += get_stream_bit_rate(aud_st);
@@ -92,6 +109,9 @@ index 1e932b7b..11a3f0dd 100644
+ if (bandwidth == 0) {
+ // Estimate bandwidth
+ bandwidth = (int)round((double)vs->bytes_written / (av_q2d(AV_TIME_BASE_Q) * (vs->scaled_cur_pts - vs->scaled_start_pts)) * 8);
+ if (bandwidth < 0) {
+ bandwidth = 0;
+ }
+
+ // Reset counters
+ vs->bytes_written = 0;
@@ -101,7 +121,33 @@ index 1e932b7b..11a3f0dd 100644
bandwidth += bandwidth / 10;
}
@@ -2475,6 +2488,19 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
@@ -2439,7 +2459,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
HLSContext *hls = s->priv_data;
AVFormatContext *oc = NULL;
AVStream *st = s->streams[pkt->stream_index];
- int64_t end_pts = 0;
+ int64_t end_pts = 0, max_sequence = 0;
int is_ref_pkt = 1;
int ret = 0, can_split = 1, i, j;
int stream_index = 0;
@@ -2449,6 +2469,16 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
VariantStream *vs = NULL;
char *old_filename = NULL;
+ if (hls->flags & HLS_ADJUST_SEQUENCE) {
+ for (i = 0; i < hls->nb_varstreams; i++) {
+ vs = &hls->var_streams[i];
+
+ if (vs->sequence > max_sequence) {
+ max_sequence = vs->sequence;
+ }
+ }
+ }
+
for (i = 0; i < hls->nb_varstreams; i++) {
int subtitle_streams = 0;
vs = &hls->var_streams[i];
@@ -2477,6 +2507,19 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
return AVERROR(ENOMEM);
}
@@ -121,7 +167,7 @@ index 1e932b7b..11a3f0dd 100644
end_pts = hls->recording_time * vs->number;
if (vs->sequence - vs->nb_entries > hls->start_sequence && hls->init_time > 0) {
@@ -2523,8 +2549,8 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
@@ -2525,8 +2568,8 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
}
can_split = can_split && (pkt->pts - vs->end_pts > 0);
@@ -132,7 +178,19 @@ index 1e932b7b..11a3f0dd 100644
int64_t new_start_pos;
int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
double cur_duration;
@@ -2700,6 +2726,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
@@ -2643,6 +2686,11 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
cur_duration = (double)(pkt->pts - vs->end_pts) * st->time_base.num / st->time_base.den;
ret = hls_append_segment(s, hls, vs, cur_duration, vs->start_pos, vs->size);
+ if ((hls->flags & HLS_ADJUST_SEQUENCE) && vs->sequence < max_sequence) {
+ av_log(s, AV_LOG_WARNING, "fixing sequence number of variant %s.\n", vs->m3u8_name);
+ vs->sequence = max_sequence + 1;
+ vs->discontinuity = 1;
+ }
vs->end_pts = pkt->pts;
vs->duration = 0;
if (ret < 0) {
@@ -2702,6 +2750,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
}
vs->packets_written++;
@@ -140,7 +198,7 @@ index 1e932b7b..11a3f0dd 100644
if (oc->pb) {
ret = ff_write_chained(oc, stream_index, pkt, s, 0);
vs->video_keyframe_size += pkt->size;
@@ -2888,6 +2915,49 @@ failed:
@@ -2890,6 +2939,49 @@ failed:
return 0;
}
@@ -190,7 +248,7 @@ index 1e932b7b..11a3f0dd 100644
static int hls_init(AVFormatContext *s)
{
@@ -2995,6 +3065,8 @@ static int hls_init(AVFormatContext *s)
@@ -2997,6 +3089,8 @@ static int hls_init(AVFormatContext *s)
vs->sequence = hls->start_sequence;
vs->start_pts = AV_NOPTS_VALUE;
vs->end_pts = AV_NOPTS_VALUE;
@@ -199,7 +257,7 @@ index 1e932b7b..11a3f0dd 100644
vs->current_segment_final_filename_fmt[0] = '\0';
vs->initial_prog_date_time = initial_program_date_time;
@@ -3137,6 +3209,9 @@ static int hls_init(AVFormatContext *s)
@@ -3139,6 +3233,9 @@ static int hls_init(AVFormatContext *s)
vs->number++;
}
@@ -209,8 +267,16 @@ index 1e932b7b..11a3f0dd 100644
return ret;
}
@@ -3183,6 +3280,7 @@ static const AVOption options[] = {
{"periodic_rekey", "reload keyinfo file periodically for re-keying", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_PERIODIC_REKEY }, 0, UINT_MAX, E, .unit = "flags"},
{"independent_segments", "add EXT-X-INDEPENDENT-SEGMENTS, whenever applicable", 0, AV_OPT_TYPE_CONST, { .i64 = HLS_INDEPENDENT_SEGMENTS }, 0, UINT_MAX, E, .unit = "flags"},
{"iframes_only", "add EXT-X-I-FRAMES-ONLY, whenever applicable", 0, AV_OPT_TYPE_CONST, { .i64 = HLS_I_FRAMES_ONLY }, 0, UINT_MAX, E, .unit = "flags"},
+ {"adjust_sequence", "adjust sequence numbers of variants if they diverge", 0, AV_OPT_TYPE_CONST, { .i64 = HLS_ADJUST_SEQUENCE }, 0, UINT_MAX, E, .unit = "flags"},
{"strftime", "set filename expansion with strftime at segment creation", OFFSET(use_localtime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
{"strftime_mkdir", "create last directory component in strftime-generated filename", OFFSET(use_localtime_mkdir), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
{"hls_playlist_type", "set the HLS playlist type", OFFSET(pl_type), AV_OPT_TYPE_INT, {.i64 = PLAYLIST_TYPE_NONE }, 0, PLAYLIST_TYPE_NB-1, E, .unit = "pl_type" },
base-commit: e1601d14100f6c7d088eba676d9555118ca94931
base-commit: c526666f8869a5fffb04fbfeb862cde13338b001
--
2.39.5 (Apple Git-154)
2.50.1 (Apple Git-155)

View File

@@ -1,22 +1,25 @@
From 70ca589dd67895bb87b403d97f899d08f9999b08 Mon Sep 17 00:00:00 2001
From 399e6b27c4b308352554d3ef84329c854330fe83 Mon Sep 17 00:00:00 2001
From: Ingo Oppermann <ingo@datarhei.com>
Date: Wed, 8 Jan 2025 13:29:22 +0100
Subject: [PATCH v2] progress (7.1.0)
Date: Thu, 21 Aug 2025 11:42:34 +0200
Subject: [PATCH v1] progress (7.1.1)
---
README.PROGRESS.md | 759 ++++++++++++++++++++++++++++++++++++++++
README.PROGRESS.md | 759 ++++++++++++++++++++++++++++++++++
fftools/Makefile | 1 +
fftools/ffmpeg.c | 35 +-
fftools/ffmpeg.h | 1 +
fftools/ffmpeg_demux.c | 149 +++-----
fftools/ffmpeg_demux.h | 163 +++++++++
fftools/ffmpeg_demux.c | 149 ++-----
fftools/ffmpeg_demux.h | 163 ++++++++
fftools/ffmpeg_filter.c | 10 +-
fftools/ffmpeg_json.c | 668 +++++++++++++++++++++++++++++++++++
fftools/ffmpeg_json.c | 888 ++++++++++++++++++++++++++++++++++++++++
fftools/ffmpeg_json.h | 16 +
fftools/ffmpeg_mux.c | 50 ++-
fftools/ffmpeg_mux.h | 19 +-
fftools/ffmpeg_opt.c | 6 +
12 files changed, 1763 insertions(+), 114 deletions(-)
fftools/ffmpeg_sched.c | 6 +-
libavformat/fifo.c | 7 +
libavformat/tee.c | 15 +-
15 files changed, 2006 insertions(+), 119 deletions(-)
create mode 100644 README.PROGRESS.md
create mode 100644 fftools/ffmpeg_demux.h
create mode 100644 fftools/ffmpeg_json.c
@@ -1246,7 +1249,7 @@ index 00000000..709aba7a
+#endif /* FFTOOLS_FFMPEG_DEMUX_H */
\ No newline at end of file
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 7ec328e0..814b5761 100644
index 38c7676a..b2e68bd1 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -21,6 +21,7 @@
@@ -1274,7 +1277,7 @@ index 7ec328e0..814b5761 100644
av_freep(&fgp->nb_threads);
av_frame_free(&fgp->frame);
@@ -2019,6 +2023,10 @@ static int configure_filtergraph(FilterGraph *fg, FilterGraphThread *fgt)
@@ -2024,6 +2028,10 @@ static int configure_filtergraph(FilterGraph *fg, FilterGraphThread *fgt)
goto fail;
}
@@ -1285,7 +1288,7 @@ index 7ec328e0..814b5761 100644
return 0;
fail:
cleanup_filtergraph(fg, fgt);
@@ -2917,7 +2925,7 @@ static void fg_thread_uninit(FilterGraphThread *fgt)
@@ -2922,7 +2930,7 @@ static void fg_thread_uninit(FilterGraphThread *fgt)
av_freep(&fgt->eof_in);
av_freep(&fgt->eof_out);
@@ -1296,10 +1299,10 @@ index 7ec328e0..814b5761 100644
}
diff --git a/fftools/ffmpeg_json.c b/fftools/ffmpeg_json.c
new file mode 100644
index 00000000..b63110e1
index 00000000..381e2566
--- /dev/null
+++ b/fftools/ffmpeg_json.c
@@ -0,0 +1,668 @@
@@ -0,0 +1,888 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
@@ -1322,6 +1325,56 @@ index 00000000..b63110e1
+#include "libavformat/internal.h"
+#include "libavcodec/avcodec.h"
+
+static void append_disposition(AVBPrint *buf, int disposition)
+{
+ av_bprintf(buf, "\"disposition\":[");
+
+ if (disposition & AV_DISPOSITION_DEFAULT)
+ av_bprintf(buf, "\"default\",");
+ if (disposition & AV_DISPOSITION_DUB)
+ av_bprintf(buf, "\"dub\",");
+ if (disposition & AV_DISPOSITION_ORIGINAL)
+ av_bprintf(buf, "\"original\",");
+ if (disposition & AV_DISPOSITION_COMMENT)
+ av_bprintf(buf, "\"comment\",");
+ if (disposition & AV_DISPOSITION_LYRICS)
+ av_bprintf(buf, "\"lyrics\",");
+ if (disposition & AV_DISPOSITION_KARAOKE)
+ av_bprintf(buf, "\"karaoke\",");
+ if (disposition & AV_DISPOSITION_FORCED)
+ av_bprintf(buf, "\"forced\",");
+ if (disposition & AV_DISPOSITION_HEARING_IMPAIRED)
+ av_bprintf(buf, "\"hearing impaired\",");
+ if (disposition & AV_DISPOSITION_VISUAL_IMPAIRED)
+ av_bprintf(buf, "\"visual impaired\",");
+ if (disposition & AV_DISPOSITION_CLEAN_EFFECTS)
+ av_bprintf(buf, "\"clean effects\",");
+ if (disposition & AV_DISPOSITION_ATTACHED_PIC)
+ av_bprintf(buf, "\"attached pic\",");
+ if (disposition & AV_DISPOSITION_TIMED_THUMBNAILS)
+ av_bprintf(buf, "\"timed thumbnails\",");
+ if (disposition & AV_DISPOSITION_CAPTIONS)
+ av_bprintf(buf, "\"captions\",");
+ if (disposition & AV_DISPOSITION_DESCRIPTIONS)
+ av_bprintf(buf, "\"descriptions\",");
+ if (disposition & AV_DISPOSITION_METADATA)
+ av_bprintf(buf, "\"metadata\",");
+ if (disposition & AV_DISPOSITION_DEPENDENT)
+ av_bprintf(buf, "\"dependent\",");
+ if (disposition & AV_DISPOSITION_STILL_IMAGE)
+ av_bprintf(buf, "\"still image\",");
+ if (disposition & AV_DISPOSITION_NON_DIEGETIC)
+ av_bprintf(buf, "\"non-diegetic\",");
+ if (disposition & AV_DISPOSITION_MULTILAYER)
+ av_bprintf(buf, "\"multilayer\",");
+
+ if(buf->str[buf->len-1] == ',') {
+ buf->len--;
+ }
+
+ av_bprintf(buf, "]");
+}
+
+/**
+ * Print all inputs in JSON format
+ */
@@ -1371,10 +1424,11 @@ index 00000000..b63110e1
+ avcodec_get_name(st->codecpar->codec_id),
+ st->codecpar->bit_rate / 1000);
+ av_bprintf(&buf,
+ "\"duration_sec\":%f,\"language\":\"%s\",\"profile\":%d,\"level\":%d",
+ "\"duration_sec\":%f,\"language\":\"%s\",\"profile\":%d,\"level\":%d,",
+ duration,
+ lang != NULL ? lang->value : "und",
+ st->codecpar->profile, st->codecpar->level);
+ append_disposition(&buf, st->disposition);
+
+ av_free(url);
+
@@ -1423,6 +1477,99 @@ index 00000000..b63110e1
+ av_bprint_finalize(&buf, NULL);
+}
+
+typedef enum SlaveFailurePolicy {
+ ON_SLAVE_FAILURE_ABORT = 1,
+ ON_SLAVE_FAILURE_IGNORE = 2
+} SlaveFailurePolicy;
+
+typedef struct TeeSlave {
+ AVFormatContext *avf;
+ AVBSFContext **bsfs;
+ SlaveFailurePolicy on_fail;
+ int use_fifo;
+ AVDictionary *fifo_options;
+ int *stream_map;
+ int header_written;
+ char *id;
+ char *filename;
+} TeeSlave;
+
+typedef struct TeeContext {
+ const AVClass *class;
+ unsigned nb_slaves;
+ unsigned nb_alive;
+ TeeSlave *slaves;
+} TeeContext;
+
+/**
+ * Append all tee outputs for a context in JSON format
+ *
+ * @param buf The AVBPrint buffer to which the JSON output will be appended.
+ * @param ofctx The AVFormatContext for the output, which contains the TeeContext.
+ */
+static void append_outputs_tee(AVBPrint *buf, AVFormatContext *ofctx)
+{
+ TeeContext *tc;
+ const char *format_name, *base_format;
+ char *address;
+
+ tc = (TeeContext *)ofctx->priv_data;
+ if (!tc || tc->nb_slaves == 0 || !tc->slaves) {
+ return;
+ }
+
+ av_bprintf(buf, ",\"tee\":[");
+
+ for (unsigned int i = 0; i < tc->nb_slaves; i++) {
+ uint8_t *fifo_fmt_opt = NULL;
+ TeeSlave *slave = &tc->slaves[i];
+ AVFormatContext *slave_ctx = slave->avf;
+
+ format_name = "";
+
+ if (slave_ctx && slave_ctx->oformat) {
+ base_format = slave_ctx->oformat->name ? slave_ctx->oformat->name : "";
+ format_name = base_format;
+
+ fifo_fmt_opt = NULL;
+ if (strcmp(base_format, "fifo") == 0) {
+ uint8_t *fifo_fmt_opt = NULL;
+
+ if (av_opt_get(slave_ctx->priv_data, "fifo_format", AV_OPT_SEARCH_CHILDREN | AV_OPT_ALLOW_NULL, &fifo_fmt_opt) >= 0) {
+ if(fifo_fmt_opt && fifo_fmt_opt[0] != '\0') {
+ format_name = (const char *)fifo_fmt_opt;
+ }
+ }
+ }
+ }
+
+ address = NULL;
+ if (av_escape(&address,
+ slave->filename ? slave->filename : "",
+ "\\\"",
+ AV_ESCAPE_MODE_BACKSLASH,
+ AV_UTF8_FLAG_ACCEPT_ALL) < 0) {
+ address = av_strdup("-");
+ }
+
+ av_bprintf(buf, "{\"id\":\"%s\",\"address\":\"%s\",\"format\":\"%s\",\"fifo_enabled\":%s}",
+ slave->id ? slave->id : "", address, format_name, slave->use_fifo == 1 ? "true" : "false");
+
+ av_free(address);
+ if (fifo_fmt_opt) {
+ av_free(fifo_fmt_opt);
+ }
+
+ if (i < tc->nb_slaves - 1) {
+ av_bprintf(buf, ",");
+ }
+ }
+
+ av_bprintf(buf, "]");
+
+ return;
+}
+
+/**
+ * Print all outputs in JSON format
+ */
@@ -1465,13 +1612,14 @@ index 00000000..b63110e1
+ ",",
+ av_get_media_type_string(st->codecpar->codec_type),
+ avcodec_get_name(st->codecpar->codec_id),
+ !ost->enc ? "copy" : "unknown",
+ ost->enc_ctx ? (ost->enc_ctx->codec ? ost->enc_ctx->codec->name : "unknown") : "copy",
+ st->codecpar->bit_rate / 1000);
+ av_bprintf(&buf,
+ "\"duration_sec\":%f,\"language\":\"%s\",\"profile\":%d,\"level\":%d",
+ "\"duration_sec\":%f,\"language\":\"%s\",\"profile\":%d,\"level\":%d,",
+ 0.0,
+ lang != NULL ? lang->value : "und",
+ st->codecpar->profile, st->codecpar->level);
+ append_disposition(&buf, st->disposition);
+
+ av_free(url);
+
@@ -1499,6 +1647,10 @@ index 00000000..b63110e1
+ st->codecpar->ch_layout.nb_channels);
+ }
+
+ if (!strcmp(ctx->oformat->name, "tee")) {
+ append_outputs_tee(&buf, ctx);
+ }
+
+ if(ost_iter(ost) == NULL) {
+ av_bprintf(&buf, "}");
+ } else {
@@ -1521,6 +1673,70 @@ index 00000000..b63110e1
+ return;
+}
+
+typedef struct FifoContext {
+ const AVClass *class;
+ AVFormatContext *avf;
+
+ uint64_t total_recovery_attempts;
+ int status; // 0 = alive, 1 = restarting, 2 = failed
+} FifoContext;
+
+/**
+ * Append all tee outputs to output in JSON format
+ *
+ * @param buf The AVBPrint buffer to which the JSON output will be appended.
+ * @param ofc The AVFormatContext for the output, which contains the TeeContext.
+ */
+static void append_progress_tee(AVBPrint *buf, AVFormatContext *ofctx)
+{
+ TeeContext *tc;
+
+ tc = (TeeContext *)ofctx->priv_data;
+ if (!tc || tc->nb_slaves == 0 || !tc->slaves) {
+ return;
+ }
+
+ av_bprintf(buf, ",\"tee\":[");
+
+ for (unsigned int i = 0; i < tc->nb_slaves; i++) {
+ const char *tee_state = "failed", *fifo_state = "";
+ uint64_t total_recovery_attempts = 0;
+ TeeSlave *slave = &tc->slaves[i];
+ AVFormatContext *slave_ctx = slave->avf;
+
+ if(slave_ctx && slave_ctx->oformat) {
+ tee_state = (slave_ctx->pb && slave_ctx->pb->error < 0) ? "failed" : "running";
+
+ if (!strcmp(slave_ctx->oformat->name, "fifo")) {
+ FifoContext *fifo_ctx = (FifoContext *)slave_ctx->priv_data;
+
+ switch(fifo_ctx->status) {
+ case 0: fifo_state = "running"; break;
+ case 1: fifo_state = "restarting"; break;
+ case 2: fifo_state = "failed"; break;
+ default: fifo_state = "";
+ }
+
+ total_recovery_attempts = fifo_ctx->total_recovery_attempts;
+ }
+ }
+
+ av_bprintf(buf,
+ "{\"state\":\"%s\",\"fifo_recovery_attempts_total\":%"PRIu64",\"fifo_state\":\"%s\"}",
+ tee_state,
+ total_recovery_attempts,
+ fifo_state);
+
+ if (i < tc->nb_slaves - 1) {
+ av_bprintf(buf, ",");
+ }
+ }
+
+ av_bprintf(buf, "]");
+
+ return;
+}
+
+/**
+ * Print progress report in JSON format
+ *
@@ -1593,7 +1809,10 @@ index 00000000..b63110e1
+
+ av_bprintf(&buf, "\"outputs\":[");
+ for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
+ MuxStream *ms = ms_from_ost(ost);
+ MuxStream *ms = ms_from_ost(ost);
+ OutputFile *of = output_files[ost->file->index];
+ Muxer *mux = mux_from_of(of);
+ AVFormatContext *ctx = mux ? mux->fc : NULL;
+
+ q = -1;
+ if(ost->enc) {
@@ -1639,6 +1858,10 @@ index 00000000..b63110e1
+ av_bprintf(&buf, "\"size_kb\":%.0f,\"size_bytes\":%" PRIu64 ",", stream_size / 1024.0, stream_size);
+ av_bprintf(&buf, "\"extradata_size_bytes\":%d", 0);
+
+ if (ctx && ctx->oformat && !strcmp(ctx->oformat->name, "tee")) {
+ append_progress_tee(&buf, ctx);
+ }
+
+ if(ost_iter(ost) == NULL) {
+ av_bprintf(&buf, "}");
+ } else {
@@ -1733,7 +1956,7 @@ index 00000000..b63110e1
+ avfilter_pad_get_name(link->srcpad, 0),
+ avfilter_pad_get_name(link->dstpad, 0));
+ av_bprintf(buf,
+ "\"timebase\": \"%d/%d\",",
+ "\"timebase\":\"%d/%d\",",
+ link->time_base.num,
+ link->time_base.den);
+
@@ -2128,8 +2351,140 @@ index f639a1cf..cb893874 100644
{ "stats_period", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_EXPERT,
{ .func_arg = opt_stats_period },
"set the period at which ffmpeg updates stats and -progress output", "time" },
diff --git a/fftools/ffmpeg_sched.c b/fftools/ffmpeg_sched.c
index ef0b6e28..6dc61923 100644
--- a/fftools/ffmpeg_sched.c
+++ b/fftools/ffmpeg_sched.c
@@ -444,7 +444,7 @@ static void task_init(Scheduler *sch, SchTask *task, enum SchedulerNodeType type
static int64_t trailing_dts(const Scheduler *sch, int count_finished)
{
- int64_t min_dts = INT64_MAX;
+ int64_t max_dts = INT64_MIN;
for (unsigned i = 0; i < sch->nb_mux; i++) {
const SchMux *mux = &sch->mux[i];
@@ -457,11 +457,11 @@ static int64_t trailing_dts(const Scheduler *sch, int count_finished)
if (ms->last_dts == AV_NOPTS_VALUE)
return AV_NOPTS_VALUE;
- min_dts = FFMIN(min_dts, ms->last_dts);
+ max_dts = FFMAX(max_dts, ms->last_dts);
}
}
- return min_dts == INT64_MAX ? AV_NOPTS_VALUE : min_dts;
+ return max_dts == INT64_MIN ? AV_NOPTS_VALUE : max_dts;
}
void sch_free(Scheduler **psch)
diff --git a/libavformat/fifo.c b/libavformat/fifo.c
index 23e4149a..259f9fe6 100644
--- a/libavformat/fifo.c
+++ b/libavformat/fifo.c
@@ -38,6 +38,9 @@ typedef struct FifoContext {
const AVClass *class;
AVFormatContext *avf;
+ uint64_t total_recovery_attempts;
+ int status; // 0 = running, 1 = restarting, 2 = failed
+
char *format;
AVDictionary *format_options;
@@ -362,6 +365,8 @@ static int fifo_thread_attempt_recovery(FifoThreadContext *ctx, FifoMessage *msg
}
ctx->recovery_nr++;
+ fifo->total_recovery_attempts++;
+ fifo->status = 1;
if (fifo->max_recovery_attempts) {
av_log(avf, AV_LOG_VERBOSE, "Recovery attempt #%d/%d\n",
@@ -379,11 +384,13 @@ static int fifo_thread_attempt_recovery(FifoThreadContext *ctx, FifoMessage *msg
if (is_recoverable(fifo, ret)) {
return fifo_thread_process_recovery_failure(ctx, pkt, ret);
} else {
+ fifo->status = 2; // failed
goto fail;
}
} else {
av_log(avf, AV_LOG_INFO, "Recovery successful\n");
ctx->recovery_nr = 0;
+ fifo->status = 0; // running
}
return 0;
diff --git a/libavformat/tee.c b/libavformat/tee.c
index 1a2a8ead..6fb753f0 100644
--- a/libavformat/tee.c
+++ b/libavformat/tee.c
@@ -49,6 +49,9 @@ typedef struct {
* disabled output streams are set to -1 */
int *stream_map;
int header_written;
+
+ char *id;
+ char *filename;
} TeeSlave;
typedef struct TeeContext {
@@ -135,6 +138,8 @@ static int close_slave(TeeSlave *tee_slave)
}
av_freep(&tee_slave->stream_map);
av_freep(&tee_slave->bsfs);
+ av_freep(&tee_slave->id);
+ av_freep(&tee_slave->filename);
ff_format_io_close(avf, &avf->pb);
avformat_free_context(avf);
@@ -157,8 +162,8 @@ static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave)
int ret;
AVDictionary *options = NULL, *bsf_options = NULL;
const AVDictionaryEntry *entry;
- char *filename;
- char *format = NULL, *select = NULL;
+ char *filename = NULL;
+ char *format = NULL, *select = NULL, *id = NULL;
AVFormatContext *avf2 = NULL;
int stream_count;
int fullret;
@@ -185,6 +190,7 @@ static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave)
} while (0)
STEAL_OPTION("f", format);
+ STEAL_OPTION("id", id);
STEAL_OPTION("select", select);
PROCESS_OPTION("onfail",
parse_slave_failure_policy_option(value, tee_slave),
@@ -203,6 +209,9 @@ static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave)
av_dict_set(&options, entry->key, NULL, 0);
}
+ tee_slave->filename = av_strdup(filename);
+ tee_slave->id = av_strdup(id);
+
if (tee_slave->use_fifo) {
if (options) {
@@ -233,6 +242,7 @@ static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave)
tee_slave->use_fifo ? "fifo" :format, filename);
if (ret < 0)
goto end;
+
tee_slave->avf = avf2;
av_dict_copy(&avf2->metadata, avf->metadata, 0);
avf2->opaque = avf->opaque;
@@ -398,6 +408,7 @@ static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave)
end:
av_free(format);
+ av_free(id);
av_free(select);
av_dict_free(&options);
av_dict_free(&bsf_options);
base-commit: e1601d14100f6c7d088eba676d9555118ca94931
base-commit: c526666f8869a5fffb04fbfeb862cde13338b001
--
2.39.5 (Apple Git-154)