Add support for minimum required FEC packets attribute
This commit is contained in:
+21
-10
@@ -309,15 +309,23 @@ struct fec_t {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static fec_t encode(const std::string_view &payload, size_t blocksize, size_t fecpercentage) {
|
static fec_t encode(const std::string_view &payload, size_t blocksize, size_t fecpercentage, size_t minparityshards) {
|
||||||
auto payload_size = payload.size();
|
auto payload_size = payload.size();
|
||||||
|
|
||||||
auto pad = payload_size % blocksize != 0;
|
auto pad = payload_size % blocksize != 0;
|
||||||
|
|
||||||
auto data_shards = payload_size / blocksize + (pad ? 1 : 0);
|
auto data_shards = payload_size / blocksize + (pad ? 1 : 0);
|
||||||
auto parity_shards = (data_shards * fecpercentage + 99) / 100;
|
auto parity_shards = (data_shards * fecpercentage + 99) / 100;
|
||||||
auto nr_shards = data_shards + parity_shards;
|
|
||||||
|
|
||||||
|
// increase the FEC percentage for this frame if the parity shard minimum is not met
|
||||||
|
if(parity_shards < minparityshards) {
|
||||||
|
parity_shards = minparityshards;
|
||||||
|
fecpercentage = (100 * parity_shards) / data_shards;
|
||||||
|
|
||||||
|
BOOST_LOG(verbose) << "Increasing FEC percentage to "sv << fecpercentage << " to meet parity shard minimum"sv << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto nr_shards = data_shards + parity_shards;
|
||||||
if(nr_shards > DATA_SHARDS_MAX) {
|
if(nr_shards > DATA_SHARDS_MAX) {
|
||||||
BOOST_LOG(warning)
|
BOOST_LOG(warning)
|
||||||
<< "Number of fragments for reed solomon exceeds DATA_SHARDS_MAX"sv << std::endl
|
<< "Number of fragments for reed solomon exceeds DATA_SHARDS_MAX"sv << std::endl
|
||||||
@@ -641,9 +649,6 @@ void videoBroadcastThread(udp::socket &sock) {
|
|||||||
video_packet->packet.flags = FLAG_CONTAINS_PIC_DATA;
|
video_packet->packet.flags = FLAG_CONTAINS_PIC_DATA;
|
||||||
video_packet->packet.frameIndex = packet->pts;
|
video_packet->packet.frameIndex = packet->pts;
|
||||||
video_packet->packet.streamPacketIndex = ((uint32_t)lowseq + fecIndex) << 8;
|
video_packet->packet.streamPacketIndex = ((uint32_t)lowseq + fecIndex) << 8;
|
||||||
video_packet->packet.fecInfo = (fecIndex << 12 |
|
|
||||||
end << 22 |
|
|
||||||
fecPercentage << 4);
|
|
||||||
|
|
||||||
if(fecIndex == 0) {
|
if(fecIndex == 0) {
|
||||||
video_packet->packet.flags |= FLAG_SOF;
|
video_packet->packet.flags |= FLAG_SOF;
|
||||||
@@ -659,7 +664,7 @@ void videoBroadcastThread(udp::socket &sock) {
|
|||||||
|
|
||||||
payload = { (char *)payload_new.data(), payload_new.size() };
|
payload = { (char *)payload_new.data(), payload_new.size() };
|
||||||
|
|
||||||
auto shards = fec::encode(payload, blocksize, fecPercentage);
|
auto shards = fec::encode(payload, blocksize, fecPercentage, session->config.minRequiredFecPackets);
|
||||||
if(shards.data_shards == 0) {
|
if(shards.data_shards == 0) {
|
||||||
BOOST_LOG(info) << "skipping frame..."sv << std::endl;
|
BOOST_LOG(info) << "skipping frame..."sv << std::endl;
|
||||||
continue;
|
continue;
|
||||||
@@ -668,15 +673,21 @@ void videoBroadcastThread(udp::socket &sock) {
|
|||||||
for(auto x = shards.data_shards; x < shards.size(); ++x) {
|
for(auto x = shards.data_shards; x < shards.size(); ++x) {
|
||||||
auto *inspect = (video_packet_raw_t *)shards.data(x);
|
auto *inspect = (video_packet_raw_t *)shards.data(x);
|
||||||
|
|
||||||
inspect->packet.frameIndex = packet->pts;
|
inspect->packet.frameIndex = packet->pts;
|
||||||
inspect->packet.fecInfo = (x << 12 |
|
|
||||||
shards.data_shards << 22 |
|
|
||||||
shards.percentage << 4);
|
|
||||||
|
|
||||||
inspect->rtp.header = FLAG_EXTENSION;
|
inspect->rtp.header = FLAG_EXTENSION;
|
||||||
inspect->rtp.sequenceNumber = util::endian::big<uint16_t>(lowseq + x);
|
inspect->rtp.sequenceNumber = util::endian::big<uint16_t>(lowseq + x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
for(auto x = 0; x < shards.size(); ++x) {
|
for(auto x = 0; x < shards.size(); ++x) {
|
||||||
sock.send_to(asio::buffer(shards[x]), session->video.peer);
|
sock.send_to(asio::buffer(shards[x]), session->video.peer);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user