diff --git a/components/codecs/include/ftl/codecs/bitrates.hpp b/components/codecs/include/ftl/codecs/bitrates.hpp index d34ede8adb88c647949051853dde33f81221a8d2..4502b7a3b35d00763e187c0b7a4e3e8e29e1236f 100644 --- a/components/codecs/include/ftl/codecs/bitrates.hpp +++ b/components/codecs/include/ftl/codecs/bitrates.hpp @@ -49,6 +49,8 @@ enum struct definition_t : uint8_t { Invalid }; +definition_t findClosestDefinition(int width, int height); + /** * Get width in pixels of definition. */ @@ -97,10 +99,8 @@ static const preset_t kPresetMinimum = -1; * Represents the details of each preset codec configuration. */ struct CodecPreset { - definition_t colour_res; - definition_t depth_res; - bitrate_t colour_qual; - bitrate_t depth_qual; + definition_t res; + bitrate_t qual; }; /** diff --git a/components/codecs/include/ftl/codecs/encoder.hpp b/components/codecs/include/ftl/codecs/encoder.hpp index 9c3aa8fefc64810bf7660e323b44a3c4440d5098..ed817f7b1c5a59b133c36317195a5c2da9203e56 100644 --- a/components/codecs/include/ftl/codecs/encoder.hpp +++ b/components/codecs/include/ftl/codecs/encoder.hpp @@ -46,16 +46,16 @@ void free(Encoder *&e); * convert an OpenCV Mat or GpuMat into a compressed byte array of some form. */ class Encoder { - public: - friend Encoder *allocateEncoder(ftl::codecs::definition_t, + public: + friend Encoder *allocateEncoder(ftl::codecs::definition_t, ftl::codecs::device_t, ftl::codecs::codec_t); - friend void free(Encoder *&); + friend void free(Encoder *&); - public: - Encoder(ftl::codecs::definition_t maxdef, + public: + Encoder(ftl::codecs::definition_t maxdef, ftl::codecs::definition_t mindef, ftl::codecs::device_t dev); - virtual ~Encoder(); + virtual ~Encoder(); /** * Wrapper encode to allow use of presets. @@ -76,21 +76,21 @@ class Encoder { * @param cb Callback containing compressed data * @return True if succeeded with encoding. */ - virtual bool encode( + virtual bool encode( const cv::cuda::GpuMat &in, ftl::codecs::definition_t definition, ftl::codecs::bitrate_t bitrate, const std::function<void(const ftl::codecs::Packet&)> &cb)=0; // TODO: Eventually, use GPU memory directly since some encoders can support this - //virtual bool encode(const cv::cuda::GpuMat &in, std::vector<uint8_t> &out, bitrate_t bix, bool)=0; + //virtual bool encode(const cv::cuda::GpuMat &in, std::vector<uint8_t> &out, bitrate_t bix, bool)=0; virtual void reset() {} virtual bool supports(ftl::codecs::codec_t codec)=0; - protected: - bool available; + protected: + bool available; const ftl::codecs::definition_t max_definition; const ftl::codecs::definition_t min_definition; const ftl::codecs::device_t device; diff --git a/components/codecs/include/ftl/codecs/nvpipe_encoder.hpp b/components/codecs/include/ftl/codecs/nvpipe_encoder.hpp index 5d04068c53cf3b46dee73c63cf8e2fcf674f148d..07c874d128b8915265f7f4035c2fcf294b4ea07a 100644 --- a/components/codecs/include/ftl/codecs/nvpipe_encoder.hpp +++ b/components/codecs/include/ftl/codecs/nvpipe_encoder.hpp @@ -8,20 +8,20 @@ namespace ftl { namespace codecs { class NvPipeEncoder : public ftl::codecs::Encoder { - public: - NvPipeEncoder(ftl::codecs::definition_t maxdef, + public: + NvPipeEncoder(ftl::codecs::definition_t maxdef, ftl::codecs::definition_t mindef); - ~NvPipeEncoder(); + ~NvPipeEncoder(); bool encode(const cv::cuda::GpuMat &in, ftl::codecs::preset_t preset, const std::function<void(const ftl::codecs::Packet&)> &cb) { return Encoder::encode(in, preset, cb); } - bool encode(const cv::cuda::GpuMat &in, ftl::codecs::definition_t definition, ftl::codecs::bitrate_t bitrate, + bool encode(const cv::cuda::GpuMat &in, ftl::codecs::definition_t definition, ftl::codecs::bitrate_t bitrate, const std::function<void(const ftl::codecs::Packet&)>&) override; - //bool encode(const cv::cuda::GpuMat &in, std::vector<uint8_t> &out, bitrate_t bix, bool); + //bool encode(const cv::cuda::GpuMat &in, std::vector<uint8_t> &out, bitrate_t bix, bool); void reset(); @@ -29,18 +29,18 @@ class NvPipeEncoder : public ftl::codecs::Encoder { static constexpr int kFlagRGB = 0x00000001; - private: - NvPipe *nvenc_; - definition_t current_definition_; - bool is_float_channel_; + private: + NvPipe *nvenc_; + definition_t current_definition_; + bool is_float_channel_; bool was_reset_; ftl::codecs::codec_t preference_; cv::cuda::GpuMat tmp_; cv::cuda::GpuMat tmp2_; cv::cuda::Stream stream_; - bool _encoderMatch(const cv::cuda::GpuMat &in, definition_t def); - bool _createEncoder(const cv::cuda::GpuMat &in, definition_t def, bitrate_t rate); + bool _encoderMatch(const cv::cuda::GpuMat &in, definition_t def); + bool _createEncoder(const cv::cuda::GpuMat &in, definition_t def, bitrate_t rate); ftl::codecs::definition_t _verifiedDefinition(ftl::codecs::definition_t def, const cv::cuda::GpuMat &in); }; diff --git a/components/codecs/src/bitrates.cpp b/components/codecs/src/bitrates.cpp index 45a5057687f8add5cbfdaf02718e880a3361bd40..9474054d258208a08cad65b0f7e05df834569cd4 100644 --- a/components/codecs/src/bitrates.cpp +++ b/components/codecs/src/bitrates.cpp @@ -8,21 +8,18 @@ using ftl::codecs::preset_t; using ftl::codecs::definition_t; using ftl::codecs::codec_t; + static const CodecPreset special_presets[] = { - definition_t::HTC_VIVE, definition_t::HTC_VIVE, bitrate_t::High, bitrate_t::High + definition_t::HTC_VIVE, bitrate_t::High }; static const CodecPreset presets[] = { - definition_t::HD1080, definition_t::HD1080, bitrate_t::High, bitrate_t::High, - definition_t::HD1080, definition_t::HD720, bitrate_t::Standard, bitrate_t::Standard, - definition_t::HD720, definition_t::HD720, bitrate_t::High, bitrate_t::High, - definition_t::HD720, definition_t::SD576, bitrate_t::Standard, bitrate_t::Standard, - definition_t::SD576, definition_t::SD576, bitrate_t::High, bitrate_t::High, - definition_t::SD576, definition_t::SD480, bitrate_t::Standard, bitrate_t::Standard, - definition_t::SD480, definition_t::SD480, bitrate_t::High, bitrate_t::High, - definition_t::SD480, definition_t::LD360, bitrate_t::Standard, bitrate_t::Standard, - definition_t::LD360, definition_t::LD360, bitrate_t::Standard, bitrate_t::Standard, - definition_t::LD360, definition_t::LD360, bitrate_t::Low, bitrate_t::Low + definition_t::HD1080, bitrate_t::High, + definition_t::HD720, bitrate_t::High, + definition_t::SD576, bitrate_t::High, + definition_t::SD480, bitrate_t::High, + definition_t::LD360, bitrate_t::Standard, + definition_t::LD360, bitrate_t::Low }; static const float kAspectRatio = 1.777778f; @@ -53,11 +50,25 @@ int ftl::codecs::getHeight(definition_t d) { return resolutions[static_cast<int>(d)].height; } +definition_t ftl::codecs::findClosestDefinition(int width, int height) { + int best = 0; + for(const Resolution res : resolutions) { + if ((res.width >= width) && (res.height >= height)) { + return static_cast<definition_t>(best); + } + best++; + } + + // TODO error! + return definition_t::Any; +} + +/* const CodecPreset &ftl::codecs::getPreset(preset_t p) { if (p < 0 && p >= -1) return special_presets[std::abs(p+1)]; - if (p > kPresetWorst) return presets[kPresetWorst]; - if (p < kPresetBest) return presets[kPresetBest]; - return presets[p]; + if (p > kPresetWorst) return presets[kPresetWorst]; + if (p < kPresetBest) return presets[kPresetBest]; + return presets[p]; } preset_t ftl::codecs::findPreset(size_t width, size_t height) { @@ -80,10 +91,11 @@ preset_t ftl::codecs::findPreset(size_t width, size_t height) { for (preset_t i=kPresetMinimum; i<=kPresetWorst; ++i) { const auto &preset = getPreset(i); - if ((int)preset.colour_res == best_def && (int)preset.depth_res == best_def) { + if ((int)preset.res == best_def) { return i; } } return kPresetWorst; } +*/ diff --git a/components/codecs/src/encoder.cpp b/components/codecs/src/encoder.cpp index 9a7eac72def3a20b966e4332d45d8073f57c47f6..428f2f49dd15814af3a81d95e1e79cdeb54273aa 100644 --- a/components/codecs/src/encoder.cpp +++ b/components/codecs/src/encoder.cpp @@ -36,7 +36,7 @@ static MUTEX mutex; Encoder *ftl::codecs::allocateEncoder(ftl::codecs::definition_t maxdef, ftl::codecs::device_t dev, ftl::codecs::codec_t codec) { - UNIQUE_LOCK(mutex, lk); + UNIQUE_LOCK(mutex, lk); if (!has_been_init) init_encoders(); for (auto i=encoders.begin(); i!=encoders.end(); ++i) { @@ -55,10 +55,10 @@ Encoder *ftl::codecs::allocateEncoder(ftl::codecs::definition_t maxdef, } void ftl::codecs::free(Encoder *&enc) { - UNIQUE_LOCK(mutex, lk); - enc->reset(); + UNIQUE_LOCK(mutex, lk); + enc->reset(); enc->available = true; - enc = nullptr; + enc = nullptr; } Encoder::Encoder(definition_t maxdef, definition_t mindef, device_t dev) : @@ -72,9 +72,8 @@ Encoder::~Encoder() { bool Encoder::encode(const cv::cuda::GpuMat &in, preset_t preset, const std::function<void(const ftl::codecs::Packet&)> &cb) { - const auto &settings = ftl::codecs::getPreset(preset); - const definition_t definition = (in.type() == CV_32F) ? settings.depth_res : settings.colour_res; - const bitrate_t bitrate = (in.type() == CV_32F) ? settings.depth_qual : settings.colour_qual; + const definition_t definition = ftl::codecs::findClosestDefinition(in.size().width, in.size().height); + const bitrate_t bitrate = bitrate_t::High; return encode(in, definition, bitrate, cb); } diff --git a/components/codecs/test/nvpipe_codec_unit.cpp b/components/codecs/test/nvpipe_codec_unit.cpp index 609ce56a50059978af931b718de57098201a0c1a..dc63131f7cb10435d7c73db21fffd8ff9a09af53 100644 --- a/components/codecs/test/nvpipe_codec_unit.cpp +++ b/components/codecs/test/nvpipe_codec_unit.cpp @@ -22,19 +22,18 @@ namespace ftl { } } +/* TEST_CASE( "NvPipeEncoder::encode() - A colour test image at preset 0" ) { ftl::codecs::NvPipeEncoder encoder(definition_t::HD1080, definition_t::SD480); cv::cuda::GpuMat m(cv::Size(1920,1080), CV_8UC3, cv::Scalar(0,0,0)); int block_total = 0; std::atomic<int> block_count = 0; - - const CodecPreset &preset = ftl::codecs::getPreset(ftl::codecs::kPreset0); - - bool r = encoder.encode(m, ftl::codecs::kPreset0, [&block_total, &block_count, preset, m](const ftl::codecs::Packet &pkt) { + encoder.encode() + bool r = encoder.encode(m, definition::H, [&block_total, &block_count, preset, m](const ftl::codecs::Packet &pkt) { REQUIRE( pkt.codec == codec_t::HEVC ); REQUIRE( pkt.data.size() > 0 ); - REQUIRE( pkt.definition == preset.colour_res ); + REQUIRE( pkt.definition == definition_t::HD1080 ); block_total = pkt.block_total; block_count++; @@ -51,12 +50,10 @@ TEST_CASE( "NvPipeEncoder::encode() - A depth test image at preset 0" ) { int block_total = 0; std::atomic<int> block_count = 0; - const CodecPreset &preset = ftl::codecs::getPreset(ftl::codecs::kPreset0); - bool r = encoder.encode(m, ftl::codecs::kPreset0, [&block_total, &block_count, preset](const ftl::codecs::Packet &pkt) { REQUIRE( pkt.codec == codec_t::HEVC ); REQUIRE( pkt.data.size() > 0 ); - REQUIRE( pkt.definition == preset.depth_res ); + REQUIRE( pkt.definition == definition_t::HD1080 ); block_total = pkt.block_total; block_count++; @@ -65,6 +62,7 @@ TEST_CASE( "NvPipeEncoder::encode() - A depth test image at preset 0" ) { REQUIRE( r ); REQUIRE( block_count == block_total ); } +*/ TEST_CASE( "NvPipeDecoder::decode() - A colour test image" ) { ftl::codecs::NvPipeEncoder encoder(definition_t::HD1080, definition_t::SD480); diff --git a/components/codecs/test/opencv_codec_unit.cpp b/components/codecs/test/opencv_codec_unit.cpp index 2505eeb8994e1397bc19175f7f0903bdb3000c9d..961658db5d4da887e8597dd90f093fa8e6abc5b2 100644 --- a/components/codecs/test/opencv_codec_unit.cpp +++ b/components/codecs/test/opencv_codec_unit.cpp @@ -21,15 +21,17 @@ namespace ftl { } } } - +/* TEST_CASE( "OpenCVEncoder::encode() - A colour test image at preset 0" ) { ftl::codecs::OpenCVEncoder encoder(definition_t::HD1080, definition_t::SD480); - cv::cuda::GpuMat m(cv::Size(1024,576), CV_8UC3, cv::Scalar(0,0,0)); int block_total = 0; std::atomic<int> block_count = 0; const CodecPreset &preset = ftl::codecs::getPreset(ftl::codecs::kPreset4); + cv::cuda::GpuMat m(cv::Size(ftl::codecs::getWidth(preset.res), + ftl::codecs::getHeight(preset.res)), + CV_8UC3, cv::Scalar(0,0,0)); std::mutex mtx; @@ -37,7 +39,7 @@ TEST_CASE( "OpenCVEncoder::encode() - A colour test image at preset 0" ) { std::unique_lock<std::mutex> lk(mtx); REQUIRE( pkt.codec == codec_t::JPG ); REQUIRE( pkt.data.size() > 0 ); - REQUIRE( pkt.definition == preset.colour_res ); + REQUIRE( pkt.definition == preset.res ); block_total = pkt.block_total; block_count++; @@ -66,7 +68,7 @@ TEST_CASE( "OpenCVEncoder::encode() - A depth test image at preset 0" ) { std::unique_lock<std::mutex> lk(mtx); REQUIRE( pkt.codec == codec_t::PNG ); REQUIRE( pkt.data.size() > 0 ); - REQUIRE( pkt.definition == preset.depth_res ); + REQUIRE( pkt.definition == preset.res ); block_total = pkt.block_total; block_count++; @@ -78,7 +80,7 @@ TEST_CASE( "OpenCVEncoder::encode() - A depth test image at preset 0" ) { REQUIRE( r ); REQUIRE( block_count == block_total ); } - +*/ TEST_CASE( "OpenCVDecoder::decode() - A colour test image no resolution change" ) { ftl::codecs::OpenCVEncoder encoder(definition_t::HD1080, definition_t::SD480); ftl::codecs::OpenCVDecoder decoder; diff --git a/components/rgbd-sources/src/streamer.cpp b/components/rgbd-sources/src/streamer.cpp index e05e7faf9305ac0a3ede6dade21596bfe8251db7..96626022c1e2bee1372870f2c2004a5c9af51a52 100644 --- a/components/rgbd-sources/src/streamer.cpp +++ b/components/rgbd-sources/src/streamer.cpp @@ -193,7 +193,7 @@ void Streamer::add(Source *src) { if (spkt.channel == Channel::Calibration) { // Calibration changed, so lets re-check the bitrate presets const auto ¶ms = src->parameters(); - s->hq_bitrate = ftl::codecs::findPreset(params.width, params.height); + s->hq_bitrate = ftl::codecs::kPresetBest; } //LOG(INFO) << "RAW CALLBACK";