diff --git a/src/streams/netstream.cpp b/src/streams/netstream.cpp index 152589200ac19f26f3d2afc39b71d9883d4a0c81..a9b5c1582da753a40e485c32f47c6213e2d55696 100644 --- a/src/streams/netstream.cpp +++ b/src/streams/netstream.cpp @@ -201,7 +201,7 @@ bool Net::post(const StreamPacket &spkt, const DataPacket &pkt) { return true; } -void Net::_processPacket(ftl::net::Peer *p, int16_t ttimeoff, const StreamPacket &spkt_raw, const DataPacket &pkt) { +void Net::_processPacket(ftl::net::Peer *p, int16_t ttimeoff, const StreamPacket &spkt_raw, DataPacket &pkt) { int64_t now = time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count(); if (!active_) return; @@ -279,7 +279,7 @@ void Net::_processPacket(ftl::net::Peer *p, int16_t ttimeoff, const StreamPacket //} } -void Net::inject(const ftl::protocol::StreamPacket &spkt, const ftl::protocol::DataPacket &pkt) { +void Net::inject(const ftl::protocol::StreamPacket &spkt, ftl::protocol::DataPacket &pkt) { _processPacket(nullptr, 0, spkt, pkt); } @@ -500,7 +500,7 @@ void Net::_cleanUp() { * batches (max 255 unique frames by timestamp). Requests are in the form * of packets that match the request except the data component is empty. */ -bool Net::_processRequest(ftl::net::Peer *p, const StreamPacket *spkt, const DataPacket &pkt) { +bool Net::_processRequest(ftl::net::Peer *p, const StreamPacket *spkt, DataPacket &pkt) { bool found = false; if (spkt->streamID == 255 || spkt->frame_number == 255) { @@ -563,6 +563,10 @@ bool Net::_processRequest(ftl::net::Peer *p, const StreamPacket *spkt, const Dat } } + if (static_cast<int>(spkt->channel) < 32) { + pkt.bitrate = std::min(pkt.bitrate, bitrate_); + } + ftl::protocol::Request req; req.bitrate = pkt.bitrate; req.channel = spkt->channel; diff --git a/src/streams/netstream.hpp b/src/streams/netstream.hpp index f882cef99906091b3cd73e1b857197d72e26cbe6..baabbf1afa095ee303f0b69f6f3ac954ca50b000 100644 --- a/src/streams/netstream.hpp +++ b/src/streams/netstream.hpp @@ -82,7 +82,7 @@ class Net : public Stream { // Unit test support virtual void hasPosted(const ftl::protocol::StreamPacket &, const ftl::protocol::DataPacket &) {} - void inject(const ftl::protocol::StreamPacket &, const ftl::protocol::DataPacket &); + void inject(const ftl::protocol::StreamPacket &, ftl::protocol::DataPacket &); private: SHARED_MUTEX mutex_; @@ -100,7 +100,7 @@ class Net : public Stream { int tally_ = 0; std::array<std::atomic<int>, 32> reqtally_ = {0}; ftl::protocol::ChannelSet last_selected_; - uint8_t bitrate_ = 200; + uint8_t bitrate_ = 255; std::atomic_int64_t bytes_received_ = 0; int64_t last_completion_ = 0; int64_t time_at_last_ = 0; @@ -135,7 +135,7 @@ class Net : public Stream { FrameState *_getFrameState(FrameID id); bool _enable(FrameID id); - bool _processRequest(ftl::net::Peer *p, const ftl::protocol::StreamPacket *spkt, const ftl::protocol::DataPacket &pkt); + bool _processRequest(ftl::net::Peer *p, const ftl::protocol::StreamPacket *spkt, ftl::protocol::DataPacket &pkt); void _checkRXRate(size_t rx_size, int64_t rx_latency, int64_t ts); void _checkTXRate(size_t tx_size, int64_t tx_latency, int64_t ts); bool _sendRequest( @@ -146,7 +146,7 @@ class Net : public Stream { uint8_t bitrate, bool doreset = false); void _cleanUp(); - void _processPacket(ftl::net::Peer *p, int16_t ttimeoff, const StreamPacket &spkt_raw, const DataPacket &pkt); + void _processPacket(ftl::net::Peer *p, int16_t ttimeoff, const StreamPacket &spkt_raw, DataPacket &pkt); }; } // namespace protocol diff --git a/test/netstream_unit.cpp b/test/netstream_unit.cpp index e57f71b596cb2d0da335c469935c48ec2159c800..51d7e70bd37fea44fa7ec019fccf0ff8e5aed75b 100644 --- a/test/netstream_unit.cpp +++ b/test/netstream_unit.cpp @@ -145,6 +145,40 @@ TEST_CASE("Net stream sending requests") { REQUIRE( seenReq ); } + SECTION("adjusts request bitrate") { + auto s1 = std::make_shared<MockNetStream>("ftl://mystream", ftl::getSelf()->getUniverse(), true); + + REQUIRE( s1->begin() ); + + int bitrate = 255; + + auto h = s1->onRequest([&bitrate](const ftl::protocol::Request &req) { + bitrate = req.bitrate; + return true; + }); + + ftl::protocol::StreamPacketMSGPACK spkt; + ftl::protocol::PacketMSGPACK pkt; + spkt.streamID = 1; + spkt.frame_number = 1; + spkt.channel = Channel::kColour; + spkt.flags = ftl::protocol::kFlagRequest; + pkt.bitrate = 255; + s1->setProperty(ftl::protocol::StreamProperty::kBitrate, 100); + writeNotification(0, "ftl://mystream", std::make_tuple(0, spkt, pkt)); + p->data(); + + sleep_for(milliseconds(50)); + REQUIRE( bitrate == 100 ); + + s1->setProperty(ftl::protocol::StreamProperty::kBitrate, 200); + writeNotification(0, "ftl://mystream", std::make_tuple(0, spkt, pkt)); + p->data(); + + sleep_for(milliseconds(50)); + REQUIRE( bitrate == 200 ); + } + SECTION("responds to 255 requests") { auto s1 = std::make_shared<MockNetStream>("ftl://mystream", ftl::getSelf()->getUniverse(), true);