From 4ab8caadb41ac42482f8c7a43725054067674fe3 Mon Sep 17 00:00:00 2001 From: Sylvain BERTRAND Date: Tue, 30 Aug 2022 17:17:21 +0000 Subject: [PATCH] npv: my iap hls peering with twitch.tv is accute trash --- npv/TODO | 1 + npv/config.h | 6 ++++++ npv/fmt/local/code.frag.c | 12 ++++++++++++ npv/fmt/namespace/main.c | 2 ++ npv/fmt/public/code.frag.c | 31 +++++++++++++++++++++---------- npv/pipeline/public/code.frag.c | 5 +++-- 6 files changed, 45 insertions(+), 12 deletions(-) diff --git a/npv/TODO b/npv/TODO index 90608f3..0158304 100644 --- a/npv/TODO +++ b/npv/TODO @@ -1,4 +1,5 @@ not ordered: +- move to a shared audio/video prefill - try to workaround as much as possible the nasty live streams out there. - "buffering" indicator (no)? subtitles (mmmmh...)? - use vulkan shaders (no glsl or hlsl), compute or not, in order to perform diff --git a/npv/config.h b/npv/config.h index 1fe6dee..706648e 100644 --- a/npv/config.h +++ b/npv/config.h @@ -95,4 +95,10 @@ struct npv_x11_bind_t npv_x11_binds[] = { * or 60 fps */ #define RESYNC_RATE_LIMITER_MS 16 +/* + * our iap hls peering with twitch.tv is accute trash, ffmpeg allows us to + * flush and retry. Let's do that in the pipeline read thread, may need a timer + * to avoid hammering the peering links though. + */ +#define FMT_RETRIES_N 100 #endif diff --git a/npv/fmt/local/code.frag.c b/npv/fmt/local/code.frag.c index 477055e..27a391b 100644 --- a/npv/fmt/local/code.frag.c +++ b/npv/fmt/local/code.frag.c @@ -7,6 +7,15 @@ STATIC void fatal(u8 *fmt, ...) npv_vfatal(fmt, ap); va_end(ap); /* unreachable */ } +STATIC void warning(u8 *fmt, ...) +{ + va_list ap; + + npv_perr("format:WARNING:"); + va_start(ap, fmt); + npv_vperr(fmt, ap); + va_end(ap); +} STATIC void pout(u8 *fmt, ...) { va_list ap; @@ -36,7 +45,10 @@ STATIC void init_once_public(u8 *url) int r; AVDictionary *options = 0; + av_dict_set(&options, "reconnect", "1", 0); + /* av_dict_set(&options, "reconnect_at_eof", "1", 0); breaks youtube live */ av_dict_set(&options, "reconnect_on_network_error", "1", 0); + av_dict_set(&options, "reconnect_streamed", "1", 0); ctx_p = 0; r = avformat_open_input(&ctx_p, url, NULL, &options); diff --git a/npv/fmt/namespace/main.c b/npv/fmt/namespace/main.c index d245a54..05a993a 100644 --- a/npv/fmt/namespace/main.c +++ b/npv/fmt/namespace/main.c @@ -15,6 +15,7 @@ #define pkt_l npv_fmt_pkt_l #define pout npv_fmt_pout #define video npv_fmt_break_on_video +#define warning npv_fmt_warning /*============================================================================*/ #else /*----------------------------------------------------------------------------*/ @@ -32,4 +33,5 @@ #undef pout #undef pkt_l #undef video +#undef warning #endif diff --git a/npv/fmt/public/code.frag.c b/npv/fmt/public/code.frag.c index f5c1a38..874b4e9 100644 --- a/npv/fmt/public/code.frag.c +++ b/npv/fmt/public/code.frag.c @@ -38,19 +38,30 @@ STATIC u8 *duration_estimate_to_str(enum avformat_duration_estimation_method_t STATIC u8 pkts_read_and_q(void) { loop { int r; + u8 retries_n; if (did_reached_limits()) return LIMITS_REACHED; - /* XXX: there, new streams can appear (could some disappear?) */ - ctx_lock(); - r = avformat_read_pkt(ctx_p, pkt_l); - ctx_unlock(); - if (r == AVERROR(EAGAIN)) - return AGAIN; - else if (r == AVERROR_EOF) - return EOF_FMT; - else if (r != 0) - fatal("ffmpeg:error while reading coded/compressed data into packets\n"); + retries_n = 0; + loop { + /* XXX: there, new streams can appear (could some disappear?) */ + ctx_lock(); + r = avformat_read_pkt(ctx_p, pkt_l); + ctx_unlock(); + if (r == AVERROR(EAGAIN)) + return AGAIN; + else if (r == AVERROR_EOF) + return EOF_FMT; + else if (r != 0) { + if (retries_n == FMT_RETRIES_N) + fatal("ffmpeg:error while reading coded/compressed data into packets\n"); + warning("ffmpeg:error while reading coded/compressed data into packets, flushing, retries = %u(%u)\n", retries_n, FMT_RETRIES_N); + flush(); + ++retries_n; + continue; + } + break; + } /* r == 0 */ if (pkt_l->st_idx == npv_audio_st_p.idx) { npv_pipeline_limits_lock(); diff --git a/npv/pipeline/public/code.frag.c b/npv/pipeline/public/code.frag.c index bc341e7..e922715 100644 --- a/npv/pipeline/public/code.frag.c +++ b/npv/pipeline/public/code.frag.c @@ -2,9 +2,10 @@ STATIC void limits_reset(void) { limits_p.pkts.audio_bytes_n = 0; limits_p.pkts.video_bytes_n = 0; + /* TODO: nah, move to a shared audio/video quantities */ /* hardcoded for now: arbitrary rough estimates */ - /* ~8s of 400kb audio */ - limits_p.pkts.limit.audio_bytes_n = 400000 / 8 * 8; + /* ~8s of 200kb audio */ + limits_p.pkts.limit.audio_bytes_n = 200000 / 8 * 8; /* ~8s of 10Mb video */ limits_p.pkts.limit.video_bytes_n = 10000000 / 8 * 8; } -- 2.11.4.GIT