From 2e3393125fda047ee54f4d78961539ed19ed040e Mon Sep 17 00:00:00 2001 From: Nicolas Pope <nwpope@utu.fi> Date: Thu, 30 Jul 2020 20:48:59 +0300 Subject: [PATCH] Fix for encoder bitrate control --- .../codecs/include/ftl/codecs/packet.hpp | 4 ++-- components/codecs/src/nvidia_encoder.cpp | 4 ++-- .../streams/include/ftl/streams/sender.hpp | 2 +- components/streams/src/sender.cpp | 22 ++++++++++++++----- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/components/codecs/include/ftl/codecs/packet.hpp b/components/codecs/include/ftl/codecs/packet.hpp index 040f8a1da..65c07580e 100644 --- a/components/codecs/include/ftl/codecs/packet.hpp +++ b/components/codecs/include/ftl/codecs/packet.hpp @@ -37,9 +37,9 @@ struct IndexHeader { struct Packet { ftl::codecs::codec_t codec; uint8_t reserved=0; - uint8_t frame_count; // v4+ Frames included in this packet + uint8_t frame_count=1; // v4+ Frames included in this packet uint8_t bitrate=0; // v4+ For multi-bitrate encoding, 0=highest - uint8_t flags; // Codec dependent flags (eg. I-Frame or P-Frame) + uint8_t flags=0; // Codec dependent flags (eg. I-Frame or P-Frame) std::vector<uint8_t> data; MSGPACK_DEFINE(codec, reserved, frame_count, bitrate, flags, data); diff --git a/components/codecs/src/nvidia_encoder.cpp b/components/codecs/src/nvidia_encoder.cpp index 62ae6b0f1..a15d6e598 100644 --- a/components/codecs/src/nvidia_encoder.cpp +++ b/components/codecs/src/nvidia_encoder.cpp @@ -1,5 +1,5 @@ #include <ftl/codecs/nvidia_encoder.hpp> -//#include <loguru.hpp> +#include <loguru.hpp> #include <ftl/timer.hpp> #include <ftl/codecs/codecs.hpp> #include <ftl/cuda_util.hpp> @@ -211,7 +211,7 @@ bool NvidiaEncoder::_createEncoder(const cv::cuda::GpuMat &in, const ftl::codecs if (nvenc_ && (params == params_)) return true; uint64_t bitrate = calculateBitrate(in.cols*in.rows, float(pkt.bitrate)/255.0f) * pkt.frame_count; - //LOG(INFO) << "Calculated bitrate " << ((params.is_float) ? "(float)" : "(rgb)") << ": " << bitrate; + LOG(INFO) << "Calculated bitrate " << (float(bitrate) / 1024.0f / 1024.0f) << "Mbps (" << int(pkt.bitrate) << ")"; params_ = params; diff --git a/components/streams/include/ftl/streams/sender.hpp b/components/streams/include/ftl/streams/sender.hpp index 66b782b0c..2feb3bbe0 100644 --- a/components/streams/include/ftl/streams/sender.hpp +++ b/components/streams/include/ftl/streams/sender.hpp @@ -96,7 +96,7 @@ class Sender : public ftl::Configurable { void _encodeDataChannel(ftl::rgbd::FrameSet &fs, ftl::codecs::Channel c, bool reset, bool last_flush); void _encodeDataChannel(ftl::data::Frame &fs, ftl::codecs::Channel c, bool reset); - int _generateTiles(const ftl::rgbd::FrameSet &fs, int offset, ftl::codecs::Channel c, cv::cuda::Stream &stream, bool, bool); + int _generateTiles(const ftl::rgbd::FrameSet &fs, int offset, ftl::codecs::Channel c, cv::cuda::Stream &stream, bool); EncodingState &_getTile(int fsid, ftl::codecs::Channel c); cv::Rect _generateROI(const ftl::rgbd::FrameSet &fs, ftl::codecs::Channel c, int offset, bool stereo); float _selectFloatMax(ftl::codecs::Channel c); diff --git a/components/streams/src/sender.cpp b/components/streams/src/sender.cpp index ae56595b7..a7000329a 100644 --- a/components/streams/src/sender.cpp +++ b/components/streams/src/sender.cpp @@ -395,12 +395,22 @@ void Sender::setActiveEncoders(uint32_t fsid, const std::unordered_set<Channel> } void Sender::_encodeVideoChannel(ftl::data::FrameSet &fs, Channel c, bool reset, bool last_flush) { - bool lossless = value("lossless", false); - int max_bitrate = std::max(0, std::min(255, value("max_bitrate", 128))); + bool isfloat = ftl::codecs::type(c) == CV_32F; + + bool lossless = (isfloat) ? value("lossless_float", true) : value("lossless_colour", false); + int bitrate = std::max(0, std::min(255, (isfloat) ? value("bitrate_float", 200) : value("bitrate_colour", 64))); + //int min_bitrate = std::max(0, std::min(255, value("min_bitrate", 0))); // TODO: Use this - codec_t codec = static_cast<codec_t>(value("codec", static_cast<int>(codec_t::Any))); + codec_t codec = static_cast<codec_t>( + (isfloat) ? value("codec_float", static_cast<int>(codec_t::Any)) : + value("codec_colour", static_cast<int>(codec_t::Any))); + device_t device = static_cast<device_t>(value("encoder_device", static_cast<int>(device_t::Any))); + if (codec == codec_t::Any) { + codec = (lossless) ? codec_t::HEVC_LOSSLESS : codec_t::HEVC; + } + // TODO: Support high res bool is_stereo = value("stereo", false) && c == Channel::Colour && fs.firstFrame().hasChannel(Channel::Colour2); @@ -457,7 +467,7 @@ void Sender::_encodeVideoChannel(ftl::data::FrameSet &fs, Channel c, bool reset, //} } - int count = _generateTiles(fs, offset, cc, enc->stream(), lossless, is_stereo); + int count = _generateTiles(fs, offset, cc, enc->stream(), is_stereo); if (count <= 0) { LOG(ERROR) << "Could not generate tiles."; break; @@ -473,7 +483,7 @@ void Sender::_encodeVideoChannel(ftl::data::FrameSet &fs, Channel c, bool reset, ftl::codecs::Packet pkt; pkt.frame_count = count; pkt.codec = codec; - pkt.bitrate = (!lossless && ftl::codecs::isFloatChannel(cc)) ? max_bitrate : max_bitrate/2; + pkt.bitrate = bitrate; pkt.flags = 0; // In the event of partial frames, add a flag to indicate that @@ -668,7 +678,7 @@ float Sender::_selectFloatMax(Channel c) { } } -int Sender::_generateTiles(const ftl::rgbd::FrameSet &fs, int offset, Channel c, cv::cuda::Stream &stream, bool lossless, bool stereo) { +int Sender::_generateTiles(const ftl::rgbd::FrameSet &fs, int offset, Channel c, cv::cuda::Stream &stream, bool stereo) { auto &surface = _getTile(fs.id(), c); const ftl::data::Frame *cframe = nullptr; //&fs.frames[offset]; -- GitLab