From 5ff5942258015d0c690c58cd5ed4b32b45e3a856 Mon Sep 17 00:00:00 2001 From: loki Date: Sun, 11 Jul 2021 16:18:49 +0200 Subject: [PATCH] Fix video packet corruption after error correction --- sunshine/stream.cpp | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/sunshine/stream.cpp b/sunshine/stream.cpp index a1916969..da431689 100644 --- a/sunshine/stream.cpp +++ b/sunshine/stream.cpp @@ -912,11 +912,10 @@ void videoBroadcastThread(udp::socket &sock) { auto blockIndex = 0; std::for_each(fec_blocks_begin, fec_blocks_end, [&](std::string_view ¤t_payload) { - auto shards = fec::encode(current_payload, blocksize, fecPercentage, session->config.minRequiredFecPackets); + auto packets = (current_payload.size() + (blocksize - 1)) / blocksize; - // set FEC info now that we know for sure what our percentage will be for this frame - for(auto x = 0; x < shards.size(); ++x) { - auto *inspect = (video_packet_raw_t *)shards.data(x); + for(int x = 0; x < packets; ++x) { + auto *inspect = (video_packet_raw_t *)¤t_payload[x * blocksize]; inspect->packet.frameIndex = packet->pts; inspect->packet.streamPacketIndex = ((uint32_t)lowseq + x) << 8; @@ -925,21 +924,31 @@ void videoBroadcastThread(udp::socket &sock) { inspect->packet.multiFecFlags = 0x10; inspect->packet.multiFecBlocks = (blockIndex << 4) | lastBlockIndex; - inspect->packet.fecInfo = - (x << 12 | - shards.data_shards << 22 | - shards.percentage << 4); - if(x == 0) { inspect->packet.flags |= FLAG_SOF; } - if(x == shards.data_shards - 1) { + if(x == packets - 1) { inspect->packet.flags |= FLAG_EOF; } + } + + auto shards = fec::encode(current_payload, blocksize, fecPercentage, session->config.minRequiredFecPackets); + + // set FEC info now that we know for sure what our percentage will be for this frame + for(auto x = 0; x < shards.size(); ++x) { + auto *inspect = (video_packet_raw_t *)shards.data(x); + + inspect->packet.fecInfo = + (x << 12 | + shards.data_shards << 22 | + shards.percentage << 4); inspect->rtp.header = 0x80 | FLAG_EXTENSION; inspect->rtp.sequenceNumber = util::endian::big(lowseq + x); + + inspect->packet.multiFecBlocks = (blockIndex << 4) | lastBlockIndex; + inspect->packet.frameIndex = packet->pts; } for(auto x = 0; x < shards.size(); ++x) {