From aa9dcbffe848d618366827d444a4d725ebf34d4a Mon Sep 17 00:00:00 2001 From: Jonathan Campbell Date: Wed, 21 May 2025 15:41:42 -0700 Subject: [PATCH] If file://con input is using O_NONBLOCK, that is fine, but use FIONREAD to make sure all the data requested is there to read first to prevent short reads that cause zero padding in the SRT stream --- apps/transmitmedia.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/apps/transmitmedia.cpp b/apps/transmitmedia.cpp index 862875fa2..5a20d9b7f 100644 --- a/apps/transmitmedia.cpp +++ b/apps/transmitmedia.cpp @@ -710,8 +710,10 @@ class ConsoleSource: public Source ConsoleSource() #ifdef _WIN32 : may_block(true) -#else +#elif defined(FIONREAD) : may_block(fcntl(fileno(stdin), F_SETFL, fcntl(fileno(stdin), F_GETFL) | O_NONBLOCK) < 0) +#else + : may_block(true) #endif { #ifdef _WIN32 @@ -723,6 +725,21 @@ class ConsoleSource: public Source int Read(size_t chunk, MediaPacket& pkt, ostream & ignored SRT_ATR_UNUSED = cout) override { +#if defined(FIONREAD) + // The trouble with O_NONBLOCK is that read() may return less than the expected data if not enough available + // which then causes a full size SRT packet padded with zeros. Use FIONREAD, if possible, to make sure that + // read() returns either chunk bytes or nothing at all. + if (!may_block) { + int br = 0; + if (ioctl(GetSysSocket(), FIONREAD, &br) >= 0) { + if (br < 0 || size_t(br) < chunk) { + pkt.payload.clear(); + return 0; + } + } + } +#endif + if (pkt.payload.size() < chunk) pkt.payload.resize(chunk);