Skip to content

[Core] Reference implementation for RGBtoNV12 and BGRtoNV12 operations#34437

Open
mostafafaheem wants to merge 43 commits into
openvinotoolkit:masterfrom
mostafafaheem:rgb_bgr_to_nv12_template_ref
Open

[Core] Reference implementation for RGBtoNV12 and BGRtoNV12 operations#34437
mostafafaheem wants to merge 43 commits into
openvinotoolkit:masterfrom
mostafafaheem:rgb_bgr_to_nv12_template_ref

Conversation

@mostafafaheem

@mostafafaheem mostafafaheem commented Mar 2, 2026

Copy link
Copy Markdown
Contributor

Details:

  • Added 2 new operations to template plugin, RGBtoNV12 and BGRtoNV12, supporting single and two-plane conversion to NV12 format
  • Integrated new operation into PostProcessing pipeline
  • Added tests for operation and PostProcessing

Tickets:

AI Assistance:

  • AI assistance used: yes
  • AI was used to give in-depth guidance about operation enabling flow and help validating code changes. All code was thoroughly reviewed and tested

@mostafafaheem
mostafafaheem requested review from a team as code owners March 2, 2026 14:57
@github-actions github-actions Bot added category: Core OpenVINO Core (aka ngraph) category: IE Tests OpenVINO Test: plugins and common category: TEMPLATE OpenVINO Template plugin category: CPP API OpenVINO CPP API bindings labels Mar 2, 2026
@sys-openvino-ci sys-openvino-ci added the ExternalPR External contributor label Mar 2, 2026
@mostafafaheem mostafafaheem changed the title Reference implementation for NV12toRGB and NV12toBGR operations [Core] Reference implementation for NV12toRGB and NV12toBGR operations Mar 2, 2026
@mostafafaheem mostafafaheem changed the title [Core] Reference implementation for NV12toRGB and NV12toBGR operations [Core] Reference implementation for RGBtoNV12 and BGRtoNV12 operations Mar 2, 2026
@mostafafaheem

Copy link
Copy Markdown
Contributor Author

Hello @riverlijunjie and @praasz, sorry for the large PR, I thought that splitting it into smaller PRs would not be suitable for the granularity of this task, however, once this PR is merged, I will submit another PR containing CPU plugin reference implementation, and hopefully extend the operation to the GPU plugin.

@mostafafaheem
mostafafaheem requested a review from a team as a code owner March 2, 2026 15:10
@mostafafaheem
mostafafaheem requested review from zKulesza and removed request for a team March 2, 2026 15:10
@github-actions github-actions Bot added the category: docs OpenVINO documentation label Mar 2, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds core ops and template-plugin reference support for RGB/BGR → NV12 conversion, and wires the conversion into the postprocessing pipeline (NV12 single-plane), with accompanying functional/type/visitor tests.

Changes:

  • Introduce new opset16 operations RGBtoNV12 and BGRtoNV12 (single-plane and two-plane outputs) with shape inference and reference implementation.
  • Enable evaluation/registration in the template plugin backend and add reference/functional tests.
  • Extend postprocessing convert_color() to support RGB/BGR → NV12_SINGLE_PLANE, plus new preprocess/postprocess tests.

Reviewed changes

Copilot reviewed 22 out of 22 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/tests/test_utils/common_test_utils/include/common_test_utils/subgraph_builders/preprocess_builders.hpp Adds postprocess subgraph builders for RGB/BGR → NV12 single-plane.
src/plugins/template/tests/functional/subgraph_reference/preprocess.cpp Adds template-plugin reference preprocess tests for postprocess RGB/BGR → NV12.
src/plugins/template/tests/functional/op_reference/convert_color_to_nv12.cpp Adds op-reference tests for RGBtoNV12/BGRtoNV12 (single/two-plane).
src/plugins/template/backend/opset_int_tbl.hpp Registers new ops in the template plugin opset table.
src/plugins/template/backend/ops/ops_evaluates.hpp Declares template-backend evaluate specializations for the new ops.
src/plugins/template/backend/ops/convert_color_to_nv12.cpp Implements template-backend evaluation via the core reference function.
src/core/tests/visitors/op/convert_color_to_nv12.cpp Adds visitor attribute tests for both ops and plane modes.
src/core/tests/type_prop/convert_color_to_nv12_base.hpp Adds typed shape/type propagation tests for the new NV12 base op.
src/core/tests/type_prop/convert_color_to_nv12.cpp Instantiates the new type-prop test suite for both ops.
src/core/tests/preprocess.cpp Adds postprocess pipeline tests for RGB/BGR → NV12 single-plane and rejects two-plane.
src/core/src/preprocess/preprocess_steps_impl.cpp Wires postprocess convert_color() to emit RGBtoNV12/BGRtoNV12 for NV12_SINGLE_PLANE.
src/core/src/op/util/convert_color_to_nv12_base.cpp Implements validation/type inference for the NV12 base op.
src/core/src/op/rgb_to_nv12.cpp Implements RGBtoNV12 op shell + cloning.
src/core/src/op/bgr_to_nv12.cpp Implements BGRtoNV12 op shell + cloning.
src/core/shape_inference/include/rgb_bgr_to_nv12_shape_inference.hpp Adds shape inference for RGB/BGR → NV12 (single/two-plane).
src/core/reference/include/openvino/reference/convert_color_to_nv12.hpp Adds reference kernel for RGB/BGR → NV12 conversion.
src/core/include/openvino/opsets/opset16_tbl.hpp Registers new ops in core opset16 table.
src/core/include/openvino/op/util/convert_color_to_nv12_base.hpp Introduces the new base op API/attributes for RGB/BGR → NV12.
src/core/include/openvino/op/rgb_to_nv12.hpp Adds public op header for RGBtoNV12.
src/core/include/openvino/op/ops.hpp Exposes new op headers via umbrella include.
src/core/include/openvino/op/bgr_to_nv12.hpp Adds public op header for BGRtoNV12.
src/core/docs/operation_enabling_flow.md Updates documentation path for op implementation locations.

Comment thread src/core/include/openvino/op/util/convert_color_to_nv12_base.hpp Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 22 changed files in this pull request and generated 2 comments.

Comment thread src/core/src/preprocess/preprocess_steps_impl.cpp Outdated
@mostafafaheem
mostafafaheem requested review from a team as code owners March 4, 2026 21:17
@p-durandin

Copy link
Copy Markdown
Contributor

build_jenkins

Comment thread src/core/include/openvino/op/util/convert_color_to_nv12_base.hpp Outdated
Comment thread src/core/src/op/bgr_to_nv12.cpp Outdated
constructor_validate_and_infer_types();
}
ov::op::v17::BGRtoNV12::BGRtoNV12(const Output<Node>& arg, bool single_plane)
: util::ConvertColorToNV12Base(arg, util::ConvertColorToNV12Base::ColorConversion::BGR_TO_NV12, single_plane) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is concept of base class which defined source color format. It will more clean to keep this patter instead add ConvertColorToNV12Base

For class BGRtoNV12 the format can be set RGB_TO_NV12 which is wrong and should be not possible to set it as source is not RGB

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this ConvertColorToNV12Base::ColorConversion can be removed entirely, since it is not accessed anywhere in the code anymore and contains no useful information. However, this will diverge from other color conversion ops.

Is it OK to remove it? @praasz

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is no need for this enum to be set by user it should be removed from public interface.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done f563812

Comment thread src/core/src/op/util/convert_color_to_nv12_base.cpp
Comment thread src/core/shape_inference/include/rgb_bgr_to_nv12_shape_inference.hpp Outdated
Comment thread src/core/shape_inference/include/rgb_bgr_to_nv12_shape_inference.hpp Outdated
Comment thread src/plugins/template/backend/ops/convert_color_to_nv12.cpp Outdated
Comment thread src/plugins/template/backend/ops/convert_color_to_nv12.cpp Outdated
Comment thread src/plugins/template/backend/ops/convert_color_to_nv12.cpp Outdated
Comment thread src/plugins/template/backend/ops/convert_color_to_nv12.cpp Outdated
return std::make_shared<ov::Model>(results, ParameterVector{params}, "ConvertColorGraph");
}

std::shared_ptr<ov::Model> generateConvertColorToNV12(const std::shared_ptr<ov::op::Op> &node) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why generateConvertColor cannot be expanded?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because RGB input has a channel dim, unlike I420 and NV12, so params in generateConvertColor wouldn't work with RGBtoNV12 and BGRtoNV12.

@mostafafaheem

Copy link
Copy Markdown
Contributor Author

@praasz Thanks for the diligent review. All comments were addressed. I provided commit links under each comment for easier review (except namespace related changes, they are in 320f11d) and asked clarifying questions if needed. Please have a look whenever you have the time :)

cc @mitruska

@p-durandin

Copy link
Copy Markdown
Contributor

build_jenkins

@p-wysocki p-wysocki left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your PR, it's very well done. I only had minor comments, mostly about tests. For other reviewers, the scope of my changes was shape infer, spec, type prop tests, reference tests, reference implementation.

Comment thread src/core/reference/include/openvino/reference/convert_color_to_nv12.hpp Outdated
@@ -0,0 +1,129 @@
// Copyright (C) 2018-2026 Intel Corporation

@p-wysocki p-wysocki Jul 15, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[random spot]

  • Can we get a multibatch test? There's some logic in reference implementation which is not tested when N=1
  • The inputs are monochrome, can we switch at least one of the tests to have different colors in the 2x2 pixel blocks? While we're at it, also all tests assume 2x2 blocks, can we test bigger ones as well?
  • Since we already have NV12toRGB and NV12toBGR operators, can we get a round-trip tests, such as NV12 -> RGB -> NV12? It would explicitly assert that the operation is correct.

@mostafafaheem mostafafaheem Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for these suggestions, 0ba5bfa added the following:

  • Multi-batch RGB to single-plane NV12
  • Multi-batch BGR to two-plane NV12
  • Mixed primary colors RGB to single-plane NV12
  • Mixed primary colors BGR to two-plane NV12
  • Mixed RGB values to single-plane NV12
  • Mixed RGB values to two-plane NV12
  • 4x4 RGB to single-plane NV12
  • 4x4 BGR to two-plane NV12
  • Round-trip NV12 to RGB to NV12
  • Round-trip NV12 to BGR to NV12

All pass locally. I used a python script to calculate the expected outputs for each using the RGB -> YUV formula, I can share if you want.

mostafafaheem and others added 4 commits July 15, 2026 13:46
Co-authored-by: Przemyslaw Wysocki <przemyslaw.wysocki@intel.com>
@mostafafaheem

Copy link
Copy Markdown
Contributor Author

@p-wysocki I really appreciate it, and thanks for the review😄 Always glad to be contributing

@p-wysocki

Copy link
Copy Markdown
Contributor

Some builds are failing due to

/__w/openvino/openvino/openvino/src/core/reference/include/openvino/reference/convert_color_to_nv12.hpp:18:36: error: no member named 'min' in namespace 'std'; did you mean 'fmin'?
   18 |         return static_cast<T>(std::min(std::max(std::round(a), 0.0), 255.0));

Overall LGTM, thank you for your PR. Let's wait for more reviews, since this PR is quite big, I'm only covering a part of it. My approve is for the scope of shape infer, spec, type prop tests, reference tests and reference implementation.

@riverlijunjie do you know if there's a model we can use to test the changes?

@p-wysocki

Copy link
Copy Markdown
Contributor

build_jenkins

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

category: Core OpenVINO Core (aka ngraph) category: CPP API OpenVINO CPP API bindings category: CPU OpenVINO CPU plugin category: docs OpenVINO documentation category: GPU OpenVINO GPU plugin category: IE Tests OpenVINO Test: plugins and common category: TEMPLATE OpenVINO Template plugin ExternalPR External contributor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Good First Issue] PostProcess supports RGB->NV12 color convert function

7 participants