Skip to content

Commit aa9dcbf

Browse files
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
1 parent 21370a7 commit aa9dcbf

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

apps/transmitmedia.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -710,8 +710,10 @@ class ConsoleSource: public Source
710710
ConsoleSource()
711711
#ifdef _WIN32
712712
: may_block(true)
713-
#else
713+
#elif defined(FIONREAD)
714714
: may_block(fcntl(fileno(stdin), F_SETFL, fcntl(fileno(stdin), F_GETFL) | O_NONBLOCK) < 0)
715+
#else
716+
: may_block(true)
715717
#endif
716718
{
717719
#ifdef _WIN32
@@ -723,6 +725,21 @@ class ConsoleSource: public Source
723725

724726
int Read(size_t chunk, MediaPacket& pkt, ostream & ignored SRT_ATR_UNUSED = cout) override
725727
{
728+
#if defined(FIONREAD)
729+
// The trouble with O_NONBLOCK is that read() may return less than the expected data if not enough available
730+
// which then causes a full size SRT packet padded with zeros. Use FIONREAD, if possible, to make sure that
731+
// read() returns either chunk bytes or nothing at all.
732+
if (!may_block) {
733+
int br = 0;
734+
if (ioctl(GetSysSocket(), FIONREAD, &br) >= 0) {
735+
if (br < 0 || size_t(br) < chunk) {
736+
pkt.payload.clear();
737+
return 0;
738+
}
739+
}
740+
}
741+
#endif
742+
726743
if (pkt.payload.size() < chunk)
727744
pkt.payload.resize(chunk);
728745

0 commit comments

Comments
 (0)