diff --git a/components/codecs/src/nvidia_encoder.cpp b/components/codecs/src/nvidia_encoder.cpp index 188e36682b2efe62c006e1ff7371eb66dd44b434..1df49b0e15170b2dfc823e009bc4fa3ef8efebeb 100644 --- a/components/codecs/src/nvidia_encoder.cpp +++ b/components/codecs/src/nvidia_encoder.cpp @@ -20,6 +20,8 @@ using ftl::codecs::definition_t; using ftl::codecs::format_t; using ftl::codecs::Packet; using ftl::codecs::kFlagFloat; +using ftl::codecs::kFlagFlipRGB; +using ftl::codecs::kFlagMappedDepth; static inline std::string EncErrorCodeToString(NVENCSTATUS code) { @@ -125,7 +127,12 @@ static uint64_t calculateBitrate(definition_t def, float ratescale) { */ static bool validate(const cv::cuda::GpuMat &in, ftl::codecs::Packet &pkt) { if (in.type() == CV_32F) pkt.flags |= kFlagFloat; - else pkt.flags |= ftl::codecs::kFlagFlipRGB; + else pkt.flags |= kFlagFlipRGB; + + // Remove unwanted flags + if (in.type() == CV_32F && (pkt.flags & kFlagFlipRGB)) pkt.flags &= ~kFlagFlipRGB; + if (in.type() == CV_8UC4 && (pkt.flags & kFlagFloat)) pkt.flags &= ~kFlagFloat; + if (pkt.codec == codec_t::HEVC_LOSSLESS && (pkt.flags & kFlagMappedDepth)) pkt.flags &= ~kFlagMappedDepth; if (pkt.codec == codec_t::Any) pkt.codec = codec_t::HEVC; diff --git a/components/codecs/test/nvidia_codec_unit.cpp b/components/codecs/test/nvidia_codec_unit.cpp index ea92fa4b16eb29e08a9e6c21a84ba03a2a395916..9c46b0ee5c73906b7eb9dc81a35645cc699c7b6d 100644 --- a/components/codecs/test/nvidia_codec_unit.cpp +++ b/components/codecs/test/nvidia_codec_unit.cpp @@ -42,7 +42,7 @@ TEST_CASE( "NvidiaEncoder::encode() - A valid colour image" ) { REQUIRE( r ); REQUIRE( pkt.codec == codec_t::HEVC ); REQUIRE( pkt.definition == definition_t::HD1080 ); - REQUIRE( pkt.flags == 0 ); + REQUIRE( pkt.flags == ftl::codecs::kFlagFlipRGB ); REQUIRE( pkt.data.size() > 0 ); REQUIRE( ftl::codecs::hevc::validNAL(pkt.data.data(), pkt.data.size()) ); } @@ -83,9 +83,9 @@ TEST_CASE( "NvidiaEncoder::encode() - A valid colour image" ) { bool r = encoder.encode(m, pkt); - REQUIRE( !r ); - REQUIRE( pkt.flags == 0 ); - REQUIRE( pkt.data.size() == 0 ); + REQUIRE( r ); + REQUIRE( pkt.flags == ftl::codecs::kFlagFlipRGB ); + REQUIRE( pkt.data.size() != 0 ); } SECTION("invalid codec") { @@ -126,7 +126,7 @@ TEST_CASE( "NvidiaEncoder::encode() - A tiled colour image" ) { REQUIRE( r ); REQUIRE( pkt.codec == codec_t::HEVC ); REQUIRE( pkt.definition == definition_t::HD720 ); - REQUIRE( pkt.flags == 0 ); + REQUIRE( pkt.flags == ftl::codecs::kFlagFlipRGB ); REQUIRE( pkt.data.size() > 0 ); REQUIRE( ftl::codecs::hevc::validNAL(pkt.data.data(), pkt.data.size()) ); } @@ -134,14 +134,14 @@ TEST_CASE( "NvidiaEncoder::encode() - A tiled colour image" ) { TEST_CASE( "NvidiaEncoder::encode() - A valid lossless float image" ) { ftl::codecs::NvidiaEncoder encoder(definition_t::HD1080, definition_t::SD480); - cv::cuda::GpuMat m(cv::Size(1280,720), CV_16U, cv::Scalar(0)); + cv::cuda::GpuMat m(cv::Size(1280,720), CV_32F, cv::Scalar(0.0f)); SECTION("auto codec and definition, single frame") { ftl::codecs::Packet pkt; - pkt.codec = codec_t::Any; + pkt.codec = codec_t::HEVC_LOSSLESS; pkt.bitrate = 255; pkt.definition = definition_t::Any; - pkt.flags = ftl::codecs::kFlagFloat; + pkt.flags = 0; pkt.frame_count = 1; bool r = encoder.encode(m, pkt); @@ -154,63 +154,32 @@ TEST_CASE( "NvidiaEncoder::encode() - A valid lossless float image" ) { REQUIRE( ftl::codecs::hevc::validNAL(pkt.data.data(), pkt.data.size()) ); } - SECTION("missing float flag") { - ftl::codecs::Packet pkt; - pkt.codec = codec_t::Any; - pkt.bitrate = 255; - pkt.definition = definition_t::Any; - pkt.flags = 0; - pkt.frame_count = 1; - - bool r = encoder.encode(m, pkt); - - REQUIRE( !r ); - REQUIRE( pkt.data.size() == 0 ); - } - SECTION("invalid lossy flag") { ftl::codecs::Packet pkt; - pkt.codec = codec_t::Any; + pkt.codec = codec_t::HEVC_LOSSLESS; pkt.bitrate = 255; pkt.definition = definition_t::Any; - pkt.flags = ftl::codecs::kFlagFloat & ftl::codecs::kFlagMappedDepth; + pkt.flags = ftl::codecs::kFlagMappedDepth; pkt.frame_count = 1; bool r = encoder.encode(m, pkt); - REQUIRE( !r ); - REQUIRE( pkt.data.size() == 0 ); + REQUIRE( r ); + REQUIRE( pkt.flags == ftl::codecs::kFlagFloat ); + REQUIRE( pkt.data.size() != 0 ); } } TEST_CASE( "NvidiaEncoder::encode() - A valid lossy float image" ) { ftl::codecs::NvidiaEncoder encoder(definition_t::HD1080, definition_t::SD480); - cv::cuda::GpuMat m(cv::Size(1280,720), CV_8UC4, cv::Scalar(0)); + cv::cuda::GpuMat m(cv::Size(1280,720), CV_32F, cv::Scalar(0.0f)); SECTION("auto codec and definition, single frame") { ftl::codecs::Packet pkt; pkt.codec = codec_t::Any; pkt.bitrate = 255; pkt.definition = definition_t::Any; - pkt.flags = ftl::codecs::kFlagFloat | ftl::codecs::kFlagMappedDepth; - pkt.frame_count = 1; - - bool r = encoder.encode(m, pkt); - - REQUIRE( r ); - REQUIRE( pkt.codec == codec_t::HEVC ); - REQUIRE( pkt.definition == definition_t::HD720 ); - REQUIRE( pkt.flags == (ftl::codecs::kFlagFloat | ftl::codecs::kFlagMappedDepth) ); - REQUIRE( pkt.data.size() > 0 ); - REQUIRE( ftl::codecs::hevc::validNAL(pkt.data.data(), pkt.data.size()) ); - } - - SECTION("correct codec, missing flag") { - ftl::codecs::Packet pkt; - pkt.codec = codec_t::HEVC; - pkt.bitrate = 255; - pkt.definition = definition_t::Any; - pkt.flags = ftl::codecs::kFlagFloat; + pkt.flags = 0; pkt.frame_count = 1; bool r = encoder.encode(m, pkt); @@ -226,7 +195,7 @@ TEST_CASE( "NvidiaEncoder::encode() - A valid lossy float image" ) { TEST_CASE( "NvidiaEncoder::encode() - A tiled lossy float image" ) { ftl::codecs::NvidiaEncoder encoder(definition_t::HD1080, definition_t::SD480); - cv::cuda::GpuMat m(cv::Size(2560,720), CV_8UC4, cv::Scalar(0)); + cv::cuda::GpuMat m(cv::Size(2560,720), CV_32F, cv::Scalar(0)); SECTION("auto codec and definition, 2x1 frame") { ftl::codecs::Packet pkt; @@ -241,7 +210,7 @@ TEST_CASE( "NvidiaEncoder::encode() - A tiled lossy float image" ) { REQUIRE( r ); REQUIRE( pkt.codec == codec_t::HEVC ); REQUIRE( pkt.definition == definition_t::HD720 ); - REQUIRE( pkt.flags == (ftl::codecs::kFlagFloat & ftl::codecs::kFlagMappedDepth) ); + REQUIRE( pkt.flags == (ftl::codecs::kFlagFloat | ftl::codecs::kFlagMappedDepth) ); REQUIRE( pkt.data.size() > 0 ); REQUIRE( ftl::codecs::hevc::validNAL(pkt.data.data(), pkt.data.size()) ); } @@ -249,14 +218,14 @@ TEST_CASE( "NvidiaEncoder::encode() - A tiled lossy float image" ) { TEST_CASE( "NvidiaEncoder::encode() - A large tiled lossy float image" ) { ftl::codecs::NvidiaEncoder encoder(definition_t::HD1080, definition_t::SD480); - cv::cuda::GpuMat m(cv::Size(5120,1440), CV_8UC4, cv::Scalar(0)); + cv::cuda::GpuMat m(cv::Size(5120,1440), CV_32F, cv::Scalar(0)); SECTION("auto codec and definition, 4x2 frame") { ftl::codecs::Packet pkt; pkt.codec = codec_t::Any; pkt.bitrate = 255; pkt.definition = definition_t::Any; - pkt.flags = ftl::codecs::kFlagFloat & ftl::codecs::kFlagMappedDepth; + pkt.flags = 0; pkt.frame_count = 7; bool r = encoder.encode(m, pkt); @@ -264,7 +233,7 @@ TEST_CASE( "NvidiaEncoder::encode() - A large tiled lossy float image" ) { REQUIRE( r ); REQUIRE( pkt.codec == codec_t::HEVC ); REQUIRE( pkt.definition == definition_t::HD720 ); - REQUIRE( pkt.flags == (ftl::codecs::kFlagFloat & ftl::codecs::kFlagMappedDepth) ); + REQUIRE( pkt.flags == (ftl::codecs::kFlagFloat | ftl::codecs::kFlagMappedDepth) ); REQUIRE( pkt.data.size() > 0 ); REQUIRE( ftl::codecs::hevc::validNAL(pkt.data.data(), pkt.data.size()) ); } @@ -335,15 +304,15 @@ TEST_CASE( "NvidiaDecoder::decode() - A lossless depth image" ) { cv::cuda::GpuMat out; //SECTION("FHD in and out, FHD encoding") { - in = cv::cuda::GpuMat(cv::Size(1280,720), CV_16U, cv::Scalar(255)); - out = cv::cuda::GpuMat(cv::Size(1280,720), CV_32F, cv::Scalar(0)); + in = cv::cuda::GpuMat(cv::Size(1280,720), CV_32F, cv::Scalar(10.0f)); + out = cv::cuda::GpuMat(cv::Size(1280,720), CV_32F, cv::Scalar(0.0f)); ftl::codecs::Packet pkt; - pkt.codec = codec_t::Any; + pkt.codec = codec_t::HEVC_LOSSLESS; pkt.bitrate = 255; pkt.definition = definition_t::Any; pkt.frame_count = 1; - pkt.flags = ftl::codecs::kFlagFloat; + pkt.flags = 0; bool r = encoder.encode(in, pkt); REQUIRE( r ); @@ -362,7 +331,7 @@ TEST_CASE( "NvidiaDecoder::decode() - A lossy depth image" ) { cv::cuda::GpuMat out; //SECTION("FHD in and out, FHD encoding") { - in = cv::cuda::GpuMat(cv::Size(1280,720), CV_8UC4, cv::Scalar(255)); + in = cv::cuda::GpuMat(cv::Size(1280,720), CV_32F, cv::Scalar(10.0f)); out = cv::cuda::GpuMat(cv::Size(1280,720), CV_32F, cv::Scalar(0)); ftl::codecs::Packet pkt; @@ -370,7 +339,7 @@ TEST_CASE( "NvidiaDecoder::decode() - A lossy depth image" ) { pkt.bitrate = 255; pkt.definition = definition_t::Any; pkt.frame_count = 1; - pkt.flags = ftl::codecs::kFlagFloat | ftl::codecs::kFlagMappedDepth; + pkt.flags = 0; bool r = encoder.encode(in, pkt); REQUIRE( r ); @@ -461,30 +430,30 @@ TEST_CASE( "NvidiaDecoder::decode() - corrupted packet" ) { } SECTION("Corrupted float mapped flags") { - in = cv::cuda::GpuMat(cv::Size(1280,720), CV_16U, cv::Scalar(255)); - out = cv::cuda::GpuMat(cv::Size(1280,720), CV_16U, cv::Scalar(0)); + in = cv::cuda::GpuMat(cv::Size(1280,720), CV_32F, cv::Scalar(10.0f)); + out = cv::cuda::GpuMat(cv::Size(1280,720), CV_32F, cv::Scalar(0)); ftl::codecs::Packet pkt; - pkt.codec = codec_t::Any; + pkt.codec = codec_t::HEVC_LOSSLESS; pkt.bitrate = 255; pkt.definition = definition_t::Any; pkt.frame_count = 1; pkt.flags = ftl::codecs::kFlagFloat; bool r = encoder.encode(in, pkt); - pkt.codec = codec_t::HEVC; + //pkt.codec = codec_t::HEVC; pkt.flags = ftl::codecs::kFlagFloat | ftl::codecs::kFlagMappedDepth; REQUIRE( r ); - REQUIRE( !decoder.decode(pkt, out) ); + REQUIRE( decoder.decode(pkt, out) ); } SECTION("Missing float flag - lossless") { - in = cv::cuda::GpuMat(cv::Size(1280,720), CV_16U, cv::Scalar(255)); - out = cv::cuda::GpuMat(cv::Size(1280,720), CV_16U, cv::Scalar(0)); + in = cv::cuda::GpuMat(cv::Size(1280,720), CV_32F, cv::Scalar(255)); + out = cv::cuda::GpuMat(cv::Size(1280,720), CV_32F, cv::Scalar(0)); ftl::codecs::Packet pkt; - pkt.codec = codec_t::Any; + pkt.codec = codec_t::HEVC_LOSSLESS; pkt.bitrate = 255; pkt.definition = definition_t::Any; pkt.frame_count = 1; @@ -498,15 +467,15 @@ TEST_CASE( "NvidiaDecoder::decode() - corrupted packet" ) { } SECTION("Missing data") { - in = cv::cuda::GpuMat(cv::Size(1280,720), CV_16U, cv::Scalar(255)); - out = cv::cuda::GpuMat(cv::Size(1280,720), CV_16U, cv::Scalar(0)); + in = cv::cuda::GpuMat(cv::Size(1280,720), CV_32F, cv::Scalar(255)); + out = cv::cuda::GpuMat(cv::Size(1280,720), CV_32F, cv::Scalar(0)); ftl::codecs::Packet pkt; pkt.codec = codec_t::Any; pkt.bitrate = 255; pkt.definition = definition_t::Any; pkt.frame_count = 1; - pkt.flags = ftl::codecs::kFlagFloat; + pkt.flags = 0; bool r = encoder.encode(in, pkt); pkt.data.resize(0);