From b5426a867969adf0ef5a050d6dc90b738e578015 Mon Sep 17 00:00:00 2001 From: Anton Potapov Date: Wed, 13 Nov 2019 15:05:56 +0300 Subject: [PATCH] G-API (Fluid) core support for I420 - Extended NV12 support in Fluid Core engine to cover I420 --- .../opencv2/gapi/fluid/gfluidkernel.hpp | 2 +- .../gapi/src/backends/fluid/gfluidbackend.cpp | 33 ++++++++++--------- modules/gapi/test/gapi_fluid_test_kernels.cpp | 2 +- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/modules/gapi/include/opencv2/gapi/fluid/gfluidkernel.hpp b/modules/gapi/include/opencv2/gapi/fluid/gfluidkernel.hpp index a0e6894e7b..443b40599c 100644 --- a/modules/gapi/include/opencv2/gapi/fluid/gfluidkernel.hpp +++ b/modules/gapi/include/opencv2/gapi/fluid/gfluidkernel.hpp @@ -50,7 +50,7 @@ public: { Filter, Resize, - NV12toRGB + YUV420toRGB //Color conversion of 4:2:0 chroma sub-sampling formats (NV12, I420 ..etc) to RGB }; // This function is a generic "doWork" callback diff --git a/modules/gapi/src/backends/fluid/gfluidbackend.cpp b/modules/gapi/src/backends/fluid/gfluidbackend.cpp index 6f45b3dd00..5e3d68319e 100644 --- a/modules/gapi/src/backends/fluid/gfluidbackend.cpp +++ b/modules/gapi/src/backends/fluid/gfluidbackend.cpp @@ -198,7 +198,7 @@ public: using FluidAgent::FluidAgent; }; -struct FluidNV12toRGBAgent : public FluidAgent +struct Fluid420toRGBAgent : public FluidAgent { private: virtual int firstWindow(std::size_t inPort) const override; @@ -313,7 +313,7 @@ static int maxLineConsumption(const cv::GFluidKernel::Kind kind, int window, int return (inH == 1) ? 1 : 2 + lpi - 1; } } break; - case cv::GFluidKernel::Kind::NV12toRGB: return inPort == 0 ? 2 : 1; break; + case cv::GFluidKernel::Kind::YUV420toRGB: return inPort == 0 ? 2 : 1; break; default: GAPI_Assert(false); return 0; } } @@ -325,7 +325,7 @@ static int borderSize(const cv::GFluidKernel::Kind kind, int window) case cv::GFluidKernel::Kind::Filter: return (window - 1) / 2; break; // Resize never reads from border pixels case cv::GFluidKernel::Kind::Resize: return 0; break; - case cv::GFluidKernel::Kind::NV12toRGB: return 0; break; + case cv::GFluidKernel::Kind::YUV420toRGB: return 0; break; default: GAPI_Assert(false); return 0; } } @@ -435,13 +435,13 @@ std::pair cv::gimpl::FluidResizeAgent::linesReadAndnextWindow(std::size return m_mapper->linesReadAndNextWindow(outIdx, lpi); } -int cv::gimpl::FluidNV12toRGBAgent::firstWindow(std::size_t inPort) const +int cv::gimpl::Fluid420toRGBAgent::firstWindow(std::size_t inPort) const { // 2 lines for Y, 1 for UV return inPort == 0 ? 2 : 1; } -std::pair cv::gimpl::FluidNV12toRGBAgent::linesReadAndnextWindow(std::size_t inPort) const +std::pair cv::gimpl::Fluid420toRGBAgent::linesReadAndnextWindow(std::size_t inPort) const { // 2 lines for Y, 1 for UV return inPort == 0 ? std::make_pair(2, 2) : std::make_pair(1, 1); @@ -675,7 +675,7 @@ void cv::gimpl::GFluidExecutable::initBufferRois(std::vector& readStarts, return roi; }; - auto adjNV12Roi = [&](cv::gapi::own::Rect produced, std::size_t port) { + auto adj420Roi = [&](cv::gapi::own::Rect produced, std::size_t port) { GAPI_Assert(produced.x % 2 == 0); GAPI_Assert(produced.y % 2 == 0); GAPI_Assert(produced.width % 2 == 0); @@ -684,7 +684,8 @@ void cv::gimpl::GFluidExecutable::initBufferRois(std::vector& readStarts, cv::gapi::own::Rect roi; switch (port) { case 0: roi = produced; break; - case 1: roi = cv::gapi::own::Rect{ produced.x/2, produced.y/2, produced.width/2, produced.height/2 }; break; + case 1: + case 2: roi = cv::gapi::own::Rect{ produced.x/2, produced.y/2, produced.width/2, produced.height/2 }; break; default: GAPI_Assert(false); } return roi; @@ -696,19 +697,19 @@ void cv::gimpl::GFluidExecutable::initBufferRois(std::vector& readStarts, cv::gapi::own::Rect resized; switch (fg.metadata(oh).get().k.m_kind) { - case GFluidKernel::Kind::Filter: resized = produced; break; - case GFluidKernel::Kind::Resize: resized = adjResizeRoi(produced, in_meta.size, meta.size); break; - case GFluidKernel::Kind::NV12toRGB: resized = adjNV12Roi(produced, m_gm.metadata(in_edge).get().port); break; + case GFluidKernel::Kind::Filter: resized = produced; break; + case GFluidKernel::Kind::Resize: resized = adjResizeRoi(produced, in_meta.size, meta.size); break; + case GFluidKernel::Kind::YUV420toRGB: resized = adj420Roi(produced, m_gm.metadata(in_edge).get().port); break; default: GAPI_Assert(false); } // All below transformations affect roi of the writer, preserve read start position here int readStart = resized.y; - // Extend required input roi (both y and height) to be even if it's produced by NV12toRGB + // Extend required input roi (both y and height) to be even if it's produced by CS420toRGB if (!in_node->inNodes().empty()) { auto in_data_producer = in_node->inNodes().front(); - if (fg.metadata(in_data_producer).get().k.m_kind == GFluidKernel::Kind::NV12toRGB) { + if (fg.metadata(in_data_producer).get().k.m_kind == GFluidKernel::Kind::YUV420toRGB) { if (resized.y % 2 != 0) { resized.y--; resized.height++; @@ -840,9 +841,9 @@ cv::gimpl::GFluidExecutable::GFluidExecutable(const ade::Graph std::unique_ptr agent_ptr; switch (agent_data.kind) { - case GFluidKernel::Kind::Filter: agent_ptr.reset(new FluidFilterAgent(g, agent_data.nh)); break; - case GFluidKernel::Kind::Resize: agent_ptr.reset(new FluidResizeAgent(g, agent_data.nh)); break; - case GFluidKernel::Kind::NV12toRGB: agent_ptr.reset(new FluidNV12toRGBAgent(g, agent_data.nh)); break; + case GFluidKernel::Kind::Filter: agent_ptr.reset(new FluidFilterAgent(g, agent_data.nh)); break; + case GFluidKernel::Kind::Resize: agent_ptr.reset(new FluidResizeAgent(g, agent_data.nh)); break; + case GFluidKernel::Kind::YUV420toRGB: agent_ptr.reset(new Fluid420toRGBAgent(g, agent_data.nh)); break; default: GAPI_Assert(false); } std::tie(agent_ptr->in_buffer_ids, agent_ptr->out_buffer_ids) = std::tie(agent_data.in_buffer_ids, agent_data.out_buffer_ids); @@ -1005,7 +1006,7 @@ namespace GAPI_Assert((out_ws.size() == 1 && out_hs.size() == 1) && ((in_hs.size() == 1) || - ((in_hs.size() == 2) && fu.k.m_kind == cv::GFluidKernel::Kind::NV12toRGB))); + ((in_hs.size() == 2) && fu.k.m_kind == cv::GFluidKernel::Kind::YUV420toRGB))); const auto &op = g.metadata(node).get(); fu.line_consumption.resize(op.args.size(), 0); diff --git a/modules/gapi/test/gapi_fluid_test_kernels.cpp b/modules/gapi/test/gapi_fluid_test_kernels.cpp index 83813842eb..fb643649da 100644 --- a/modules/gapi/test/gapi_fluid_test_kernels.cpp +++ b/modules/gapi/test/gapi_fluid_test_kernels.cpp @@ -530,7 +530,7 @@ GAPI_FLUID_KERNEL(FNV12toRGB, cv::gapi::imgproc::GNV12toRGB, false) { static const int Window = 1; static const int LPI = 2; - static const auto Kind = GFluidKernel::Kind::NV12toRGB; + static const auto Kind = GFluidKernel::Kind::YUV420toRGB; static void run(const cv::gapi::fluid::View &in1, const cv::gapi::fluid::View &in2,