Merge pull request #21560 from dbudniko:dbudniko/gapi_media_format_gray_plus_gst_source
G-API gst source gray support
This commit is contained in:
@@ -29,6 +29,7 @@ namespace opencv_test
|
||||
struct GStreamerSourceTest : public TestWithParam<std::tuple<std::string, cv::Size, std::size_t>>
|
||||
{ };
|
||||
|
||||
|
||||
TEST_P(GStreamerSourceTest, AccuracyTest)
|
||||
{
|
||||
std::string pipeline;
|
||||
@@ -143,6 +144,16 @@ G_TYPED_KERNEL(GGstFrameCopyToNV12, <std::tuple<cv::GMat,cv::GMat>(GFrame)>,
|
||||
}
|
||||
};
|
||||
|
||||
G_TYPED_KERNEL(GGstFrameCopyToGRAY8, <cv::GMat(GFrame)>,
|
||||
"org.opencv.test.gstframe_copy_to_gray8")
|
||||
{
|
||||
static GMatDesc outMeta(GFrameDesc desc) {
|
||||
GMatDesc y{ CV_8U, 1, desc.size, false };
|
||||
return y;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
GAPI_OCV_KERNEL(GOCVGstFrameCopyToNV12, GGstFrameCopyToNV12)
|
||||
{
|
||||
static void run(const cv::MediaFrame& in, cv::Mat& y, cv::Mat& uv)
|
||||
@@ -156,21 +167,50 @@ GAPI_OCV_KERNEL(GOCVGstFrameCopyToNV12, GGstFrameCopyToNV12)
|
||||
}
|
||||
};
|
||||
|
||||
GAPI_OCV_KERNEL(GOCVGstFrameCopyToGRAY8, GGstFrameCopyToGRAY8)
|
||||
{
|
||||
static void run(const cv::MediaFrame & in, cv::Mat & y)
|
||||
{
|
||||
auto view = in.access(cv::MediaFrame::Access::R);
|
||||
cv::Mat ly(y.size(), y.type(), view.ptr[0], view.stride[0]);
|
||||
ly.copyTo(y);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
TEST_P(GStreamerSourceTest, GFrameTest)
|
||||
{
|
||||
std::string pipeline;
|
||||
cv::Size expectedFrameSize;
|
||||
std::size_t streamLength { };
|
||||
bool isNV12 = false;
|
||||
std::tie(pipeline, expectedFrameSize, streamLength) = GetParam();
|
||||
|
||||
//Check if pipline string contains NV12 sub-string
|
||||
if (pipeline.find("NV12") != std::string::npos) {
|
||||
isNV12 = true;
|
||||
}
|
||||
|
||||
// Graph declaration:
|
||||
cv::GFrame in;
|
||||
cv::GMat copiedY, copiedUV;
|
||||
std::tie(copiedY, copiedUV) = GGstFrameCopyToNV12::on(in);
|
||||
cv::GComputation c(cv::GIn(in), cv::GOut(copiedY, copiedUV));
|
||||
if (isNV12) {
|
||||
std::tie(copiedY, copiedUV) = GGstFrameCopyToNV12::on(in);
|
||||
}
|
||||
else {
|
||||
copiedY = GGstFrameCopyToGRAY8::on(in);
|
||||
}
|
||||
|
||||
cv::GComputation c(cv::GIn(in), isNV12 ? cv::GOut(copiedY, copiedUV) : cv::GOut(copiedY));
|
||||
|
||||
// Graph compilation for streaming mode:
|
||||
auto ccomp = c.compileStreaming(cv::compile_args(cv::gapi::kernels<GOCVGstFrameCopyToNV12>()));
|
||||
cv::GStreamingCompiled ccomp;
|
||||
if (isNV12) {
|
||||
ccomp = c.compileStreaming(cv::compile_args(cv::gapi::kernels<GOCVGstFrameCopyToNV12>()));
|
||||
} else {
|
||||
ccomp = c.compileStreaming(cv::compile_args(cv::gapi::kernels<GOCVGstFrameCopyToGRAY8>()));
|
||||
}
|
||||
|
||||
|
||||
EXPECT_TRUE(ccomp);
|
||||
EXPECT_FALSE(ccomp.running());
|
||||
@@ -186,29 +226,41 @@ TEST_P(GStreamerSourceTest, GFrameTest)
|
||||
// Streaming - pulling of frames until the end:
|
||||
cv::Mat y_mat, uv_mat;
|
||||
|
||||
EXPECT_TRUE(ccomp.pull(cv::gout(y_mat, uv_mat)));
|
||||
EXPECT_TRUE(isNV12 ? ccomp.pull(cv::gout(y_mat, uv_mat)) : ccomp.pull(cv::gout(y_mat)));
|
||||
EXPECT_TRUE(!y_mat.empty());
|
||||
EXPECT_TRUE(!uv_mat.empty());
|
||||
if (isNV12) {
|
||||
EXPECT_TRUE(!uv_mat.empty());
|
||||
}
|
||||
|
||||
cv::Size expectedYSize = expectedFrameSize;
|
||||
cv::Size expectedUVSize = expectedFrameSize / 2;
|
||||
|
||||
EXPECT_EQ(expectedYSize, y_mat.size());
|
||||
EXPECT_EQ(expectedUVSize, uv_mat.size());
|
||||
if (isNV12) {
|
||||
EXPECT_EQ(expectedUVSize, uv_mat.size());
|
||||
}
|
||||
|
||||
EXPECT_EQ(CV_8UC1, y_mat.type());
|
||||
EXPECT_EQ(CV_8UC2, uv_mat.type());
|
||||
if (isNV12) {
|
||||
EXPECT_EQ(CV_8UC2, uv_mat.type());
|
||||
}
|
||||
|
||||
std::size_t framesCount = 1UL;
|
||||
while (ccomp.pull(cv::gout(y_mat, uv_mat))) {
|
||||
while (isNV12 ? ccomp.pull(cv::gout(y_mat, uv_mat)) : ccomp.pull(cv::gout(y_mat))) {
|
||||
EXPECT_TRUE(!y_mat.empty());
|
||||
EXPECT_TRUE(!uv_mat.empty());
|
||||
if (isNV12) {
|
||||
EXPECT_TRUE(!uv_mat.empty());
|
||||
}
|
||||
|
||||
EXPECT_EQ(expectedYSize, y_mat.size());
|
||||
EXPECT_EQ(expectedUVSize, uv_mat.size());
|
||||
if (isNV12) {
|
||||
EXPECT_EQ(expectedUVSize, uv_mat.size());
|
||||
}
|
||||
|
||||
EXPECT_EQ(CV_8UC1, y_mat.type());
|
||||
EXPECT_EQ(CV_8UC2, uv_mat.type());
|
||||
if (isNV12) {
|
||||
EXPECT_EQ(CV_8UC2, uv_mat.type());
|
||||
}
|
||||
|
||||
framesCount++;
|
||||
}
|
||||
@@ -221,36 +273,56 @@ TEST_P(GStreamerSourceTest, GFrameTest)
|
||||
EXPECT_EQ(streamLength, framesCount);
|
||||
}
|
||||
|
||||
|
||||
// FIXME: Need to launch with sudo. May be infrastructure problems.
|
||||
// TODO: It is needed to add tests for streaming from native KMB camera: kmbcamsrc
|
||||
// GStreamer element.
|
||||
INSTANTIATE_TEST_CASE_P(CameraEmulatingPipeline, GStreamerSourceTest,
|
||||
Combine(Values("videotestsrc is-live=true pattern=colors num-buffers=10 ! "
|
||||
"videorate ! videoscale ! "
|
||||
"video/x-raw,width=1920,height=1080,framerate=3/1 ! "
|
||||
"video/x-raw,format=NV12,width=1920,height=1080,framerate=3/1 ! "
|
||||
"appsink",
|
||||
"videotestsrc is-live=true pattern=colors num-buffers=10 ! "
|
||||
"videorate ! videoscale ! "
|
||||
"video/x-raw,format=GRAY8,width=1920,height=1080,framerate=3/1 ! "
|
||||
"appsink"),
|
||||
Values(cv::Size(1920, 1080)),
|
||||
Values(10UL)));
|
||||
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(FileEmulatingPipeline, GStreamerSourceTest,
|
||||
Combine(Values("videotestsrc pattern=colors num-buffers=10 ! "
|
||||
"videorate ! videoscale ! "
|
||||
"video/x-raw,width=640,height=420,framerate=3/1 ! "
|
||||
"video/x-raw,format=NV12,width=640,height=420,framerate=3/1 ! "
|
||||
"appsink",
|
||||
"videotestsrc pattern=colors num-buffers=10 ! "
|
||||
"videorate ! videoscale ! "
|
||||
"video/x-raw,format=GRAY8,width=640,height=420,framerate=3/1 ! "
|
||||
"appsink"),
|
||||
Values(cv::Size(640, 420)),
|
||||
Values(10UL)));
|
||||
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(MultipleLiveSources, GStreamerSourceTest,
|
||||
Combine(Values("videotestsrc is-live=true pattern=colors num-buffers=10 ! "
|
||||
"videoscale ! video/x-raw,width=1280,height=720 ! appsink "
|
||||
"videoscale ! video/x-raw,format=NV12,width=1280,height=720 ! appsink "
|
||||
"videotestsrc is-live=true pattern=colors num-buffers=10 ! "
|
||||
"fakesink",
|
||||
"videotestsrc is-live=true pattern=colors num-buffers=10 ! "
|
||||
"videoscale ! video/x-raw,format=GRAY8,width=1280,height=720 ! appsink "
|
||||
"videotestsrc is-live=true pattern=colors num-buffers=10 ! "
|
||||
"fakesink"),
|
||||
Values(cv::Size(1280, 720)),
|
||||
Values(10UL)));
|
||||
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(MultipleNotLiveSources, GStreamerSourceTest,
|
||||
Combine(Values("videotestsrc pattern=colors num-buffers=10 ! "
|
||||
"videoscale ! video/x-raw,width=1280,height=720 ! appsink "
|
||||
"videoscale ! video/x-raw,format=NV12,width=1280,height=720 ! appsink "
|
||||
"videotestsrc pattern=colors num-buffers=10 ! "
|
||||
"fakesink",
|
||||
"videotestsrc pattern=colors num-buffers=10 ! "
|
||||
"videoscale ! video/x-raw,format=GRAY8,width=1280,height=720 ! appsink "
|
||||
"videotestsrc pattern=colors num-buffers=10 ! "
|
||||
"fakesink"),
|
||||
Values(cv::Size(1280, 720)),
|
||||
@@ -308,11 +380,11 @@ TEST(GStreamerMultiSourceSmokeTest, Test)
|
||||
EXPECT_FALSE(ccomp.running());
|
||||
}
|
||||
|
||||
struct GStreamerMultiSourceTest :
|
||||
struct GStreamerMultiSourceTestNV12 :
|
||||
public TestWithParam<std::tuple<cv::GComputation, cv::gapi::wip::GStreamerSource::OutputType>>
|
||||
{ };
|
||||
|
||||
TEST_P(GStreamerMultiSourceTest, ImageDataTest)
|
||||
TEST_P(GStreamerMultiSourceTestNV12, ImageDataTest)
|
||||
{
|
||||
std::string pathToLeftIm = findDataFile("cv/stereomatching/datasets/tsukuba/im6.png");
|
||||
std::string pathToRightIm = findDataFile("cv/stereomatching/datasets/tsukuba/im2.png");
|
||||
@@ -377,7 +449,7 @@ TEST_P(GStreamerMultiSourceTest, ImageDataTest)
|
||||
EXPECT_FALSE(compiled.running());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(GStreamerMultiSourceViaGMatsTest, GStreamerMultiSourceTest,
|
||||
INSTANTIATE_TEST_CASE_P(GStreamerMultiSourceViaGMatsTest, GStreamerMultiSourceTestNV12,
|
||||
Combine(Values(cv::GComputation([]()
|
||||
{
|
||||
cv::GMat in1, in2;
|
||||
@@ -387,7 +459,7 @@ INSTANTIATE_TEST_CASE_P(GStreamerMultiSourceViaGMatsTest, GStreamerMultiSourceTe
|
||||
})),
|
||||
Values(cv::gapi::wip::GStreamerSource::OutputType::MAT)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(GStreamerMultiSourceViaGFramesTest, GStreamerMultiSourceTest,
|
||||
INSTANTIATE_TEST_CASE_P(GStreamerMultiSourceViaGFramesTest, GStreamerMultiSourceTestNV12,
|
||||
Combine(Values(cv::GComputation([]()
|
||||
{
|
||||
cv::GFrame in1, in2;
|
||||
@@ -396,6 +468,96 @@ INSTANTIATE_TEST_CASE_P(GStreamerMultiSourceViaGFramesTest, GStreamerMultiSource
|
||||
cv::gapi::streaming::BGR(in2)));
|
||||
})),
|
||||
Values(cv::gapi::wip::GStreamerSource::OutputType::FRAME)));
|
||||
|
||||
struct GStreamerMultiSourceTestGRAY8 :
|
||||
public TestWithParam<std::tuple<cv::GComputation, cv::gapi::wip::GStreamerSource::OutputType>>
|
||||
{ };
|
||||
|
||||
TEST_P(GStreamerMultiSourceTestGRAY8, ImageDataTest)
|
||||
{
|
||||
std::string pathToLeftIm = findDataFile("cv/stereomatching/datasets/tsukuba/im6.png");
|
||||
std::string pathToRightIm = findDataFile("cv/stereomatching/datasets/tsukuba/im2.png");
|
||||
|
||||
std::string pipelineToReadImage("filesrc location=LOC ! pngdec ! videoconvert ! "
|
||||
"videoscale ! video/x-raw,format=GRAY8 ! appsink");
|
||||
|
||||
cv::gapi::wip::GStreamerSource leftImageProvider(
|
||||
std::regex_replace(pipelineToReadImage, std::regex("LOC"), pathToLeftIm));
|
||||
cv::gapi::wip::GStreamerSource rightImageProvider(
|
||||
std::regex_replace(pipelineToReadImage, std::regex("LOC"), pathToRightIm));
|
||||
|
||||
cv::gapi::wip::Data leftImData, rightImData;
|
||||
leftImageProvider.pull(leftImData);
|
||||
rightImageProvider.pull(rightImData);
|
||||
|
||||
cv::Mat leftRefMat = cv::util::get<cv::Mat>(leftImData);
|
||||
cv::Mat rightRefMat = cv::util::get<cv::Mat>(rightImData);
|
||||
|
||||
// Retrieve test parameters:
|
||||
std::tuple<cv::GComputation, cv::gapi::wip::GStreamerSource::OutputType> params = GetParam();
|
||||
cv::GComputation extractImage = std::move(std::get<0>(params));
|
||||
cv::gapi::wip::GStreamerSource::OutputType outputType = std::get<1>(params);
|
||||
|
||||
// Graph compilation for streaming mode:
|
||||
auto compiled =
|
||||
extractImage.compileStreaming();
|
||||
|
||||
EXPECT_TRUE(compiled);
|
||||
EXPECT_FALSE(compiled.running());
|
||||
|
||||
cv::gapi::wip::GStreamerPipeline
|
||||
pipeline(std::string("multifilesrc location=" + pathToLeftIm + " index=0 loop=true ! "
|
||||
"pngdec ! videoconvert ! videoscale ! video/x-raw,format=GRAY8 ! "
|
||||
"appsink name=sink1 ") +
|
||||
std::string("multifilesrc location=" + pathToRightIm + " index=0 loop=true ! "
|
||||
"pngdec ! videoconvert ! videoscale ! video/x-raw,format=GRAY8 ! "
|
||||
"appsink name=sink2"));
|
||||
|
||||
// GStreamer streaming sources configuration:
|
||||
auto src1 = pipeline.getStreamingSource("sink1", outputType);
|
||||
auto src2 = pipeline.getStreamingSource("sink2", outputType);
|
||||
|
||||
compiled.setSource(cv::gin(src1, src2));
|
||||
|
||||
// Start of streaming:
|
||||
compiled.start();
|
||||
EXPECT_TRUE(compiled.running());
|
||||
|
||||
// Streaming - pulling of frames:
|
||||
cv::Mat in_mat1, in_mat2;
|
||||
|
||||
std::size_t counter { }, limit { 10 };
|
||||
while(compiled.pull(cv::gout(in_mat1, in_mat2)) && (counter < limit)) {
|
||||
EXPECT_EQ(0, cv::norm(in_mat1, leftRefMat, cv::NORM_INF));
|
||||
EXPECT_EQ(0, cv::norm(in_mat2, rightRefMat, cv::NORM_INF));
|
||||
++counter;
|
||||
}
|
||||
|
||||
compiled.stop();
|
||||
|
||||
EXPECT_FALSE(compiled.running());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(GStreamerMultiSourceViaGMatsTest, GStreamerMultiSourceTestGRAY8,
|
||||
Combine(Values(cv::GComputation([]()
|
||||
{
|
||||
cv::GMat in1, in2;
|
||||
return cv::GComputation(cv::GIn(in1, in2),
|
||||
cv::GOut(cv::gapi::copy(in1),
|
||||
cv::gapi::copy(in2)));
|
||||
})),
|
||||
Values(cv::gapi::wip::GStreamerSource::OutputType::MAT)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(GStreamerMultiSourceViaGFramesTest, GStreamerMultiSourceTestGRAY8,
|
||||
Combine(Values(cv::GComputation([]()
|
||||
{
|
||||
cv::GFrame in1, in2;
|
||||
return cv::GComputation(cv::GIn(in1, in2),
|
||||
cv::GOut(cv::gapi::streaming::BGR(in1),
|
||||
cv::gapi::streaming::BGR(in2)));
|
||||
})),
|
||||
Values(cv::gapi::wip::GStreamerSource::OutputType::FRAME)));
|
||||
|
||||
} // namespace opencv_test
|
||||
|
||||
#endif // HAVE_GSTREAMER
|
||||
|
||||
Reference in New Issue
Block a user