X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=nageru%2Fvideo_encoder.cpp;h=b68086c946c58723084250f262d06440eb3d107e;hb=HEAD;hp=338428ba16e703235002b00ad28d49dfc3a61dcf;hpb=87624ed9172349ee174637618a51f959de92b2e8;p=nageru diff --git a/nageru/video_encoder.cpp b/nageru/video_encoder.cpp index 338428b..b68086c 100644 --- a/nageru/video_encoder.cpp +++ b/nageru/video_encoder.cpp @@ -1,17 +1,27 @@ -#include "video_encoder.h" - +#include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include +#include +#include +#include #include +#include #include +#include +#include +#include extern "C" { #include +#include +#include +#include +#include } #include "audio_encoder.h" @@ -26,10 +36,15 @@ extern "C" { #include "quicksync_encoder.h" #include "shared/timebase.h" #include "x264_encoder.h" +#include "video_encoder.h" +#include "shared/metrics.h" +#include "shared/ref_counted_gl_sync.h" +#include "shared/shared_defs.h" class RefCountedFrame; using namespace std; +using namespace std::chrono; using namespace movit; namespace { @@ -335,7 +350,7 @@ int VideoEncoder::open_srt_socket() return -1; } - if (srt_setsockopt(sock, 0, SRTO_LATENCY, &global_flags.srt_output_latency, sizeof(global_flags.srt_output_latency)) < 0) { + if (srt_setsockopt(sock, 0, SRTO_LATENCY, &global_flags.srt_output_latency_ms, sizeof(global_flags.srt_output_latency_ms)) < 0) { fprintf(stderr, "srt_setsockopt(SRTO_LATENCY): %s\n", srt_getlasterror_str()); srt_close(sock); return -1; @@ -463,21 +478,52 @@ int VideoEncoder::write_srt_packet(uint8_t *buf, int buf_size) if (want_srt_metric_update.exchange(false) && srt_sock != -1) { srt_metrics.update_srt_stats(srt_sock); } + + bool has_drained = false; + bool trying_reconnect = false; + steady_clock::time_point first_connect_start; + while (buf_size > 0 && !should_quit.load()) { if (srt_sock == -1) { + if (!trying_reconnect) { + first_connect_start = steady_clock::now(); + trying_reconnect = true; + } srt_sock = connect_to_srt(); if (srt_sock == -1) { usleep(100000); + if (!has_drained && duration(steady_clock::now() - first_connect_start).count() >= global_flags.srt_output_latency_ms * 1e-3) { + // The entire concept for SRT is to have fixed, low latency. + // If we've been out for more than a latency period, we shouldn't + // try to send the entire backlog. (But we should be tolerant + // of a quick disconnect and reconnect.) Maybe it would be better + // to have a sliding window of how much we remove, but it quickly + // starts getting esoteric, so juts drop it all. + fprintf(stderr, "WARNING: No SRT connection for more than %d ms, dropping data.\n", + global_flags.srt_output_latency_ms); + srt_mux->drain(); + has_drained = true; + } continue; } srt_metrics.update_srt_stats(srt_sock); } + if (has_drained) { + // Now that we're reconnected, we can start accepting data again, + // but discard the rest of this write (it is very old by now). + srt_mux->undrain(); + break; + } int to_send = min(buf_size, SRT_LIVE_DEF_PLSIZE); int ret = srt_send(srt_sock, (char *)buf, to_send); if (ret < 0) { fprintf(stderr, "srt_send(): %s\n", srt_getlasterror_str()); srt_close(srt_sock); srt_metrics.metric_srt_uptime_seconds = 0.0 / 0.0; + if (!trying_reconnect) { + first_connect_start = steady_clock::now(); + trying_reconnect = true; + } srt_sock = connect_to_srt(); continue; }