diff --git a/src/libcamera/pipeline/virtual/frame_generator.h b/src/libcamera/pipeline/virtual/frame_generator.h
index a0658c45..acbf2cc1 100644
--- a/src/libcamera/pipeline/virtual/frame_generator.h
+++ b/src/libcamera/pipeline/virtual/frame_generator.h
@@ -7,6 +7,7 @@
 
 #pragma once
 
+#include <libcamera/color_space.h>
 #include <libcamera/framebuffer.h>
 #include <libcamera/geometry.h>
 
@@ -19,6 +20,8 @@ public:
 
 	virtual void configure(const Size &size) = 0;
 
+	virtual const ColorSpace colorspace() = 0;
+
 	virtual int generateFrame(const Size &size,
 				  const FrameBuffer *buffer) = 0;
 
diff --git a/src/libcamera/pipeline/virtual/image_frame_generator.cpp b/src/libcamera/pipeline/virtual/image_frame_generator.cpp
index d1545b5d..bab3cfdc 100644
--- a/src/libcamera/pipeline/virtual/image_frame_generator.cpp
+++ b/src/libcamera/pipeline/virtual/image_frame_generator.cpp
@@ -149,6 +149,15 @@ int ImageFrameGenerator::generateFrame(const Size &size, const FrameBuffer *buff
 	return 0;
 }
 
+const ColorSpace ImageFrameGenerator::colorspace()
+{
+	/*
+	 * libyuv ensures sYCC colorspace of frames during MJPGToNV12()
+	 * conversion.
+	 */
+	return ColorSpace::Sycc;
+}
+
 /*
  * \var ImageFrameGenerator::imageFrameDatas_
  * \brief List of pointers to the not scaled image buffers
diff --git a/src/libcamera/pipeline/virtual/image_frame_generator.h b/src/libcamera/pipeline/virtual/image_frame_generator.h
index 851ddbc0..24c362e6 100644
--- a/src/libcamera/pipeline/virtual/image_frame_generator.h
+++ b/src/libcamera/pipeline/virtual/image_frame_generator.h
@@ -13,6 +13,7 @@
 #include <sys/types.h>
 #include <vector>
 
+#include <libcamera/color_space.h>
 #include <libcamera/framebuffer.h>
 #include <libcamera/geometry.h>
 
@@ -41,6 +42,7 @@ private:
 
 	void configure(const Size &size) override;
 	int generateFrame(const Size &size, const FrameBuffer *buffer) override;
+	const ColorSpace colorspace() override;
 
 	std::vector<ImageFrameData> imageFrameDatas_;
 	std::vector<ImageFrameData> scaledFrameDatas_;
diff --git a/src/libcamera/pipeline/virtual/test_pattern_generator.cpp b/src/libcamera/pipeline/virtual/test_pattern_generator.cpp
index 745be83b..04efe6cc 100644
--- a/src/libcamera/pipeline/virtual/test_pattern_generator.cpp
+++ b/src/libcamera/pipeline/virtual/test_pattern_generator.cpp
@@ -62,6 +62,24 @@ int TestPatternGenerator::generateFrame(const Size &size,
 	return ret;
 }
 
+/*
+ * libyuv internally converts ARGB<>YUV following the BT.601 colorspace.
+ * The corresponding YCbCr encoding is ColorSpace::YcbcrEncoding::Rec601
+ * with limited range.
+ *
+ * Since the test patterns generation occurs in RGB, transfer function is set
+ * to ColorSpace::TransferFunction::Srgb. Color primaries is assumed
+ * ColorSpace::Primaries::Rec709 for the RGB test patterns.
+ */
+const ColorSpace TestPatternGenerator::colorspace()
+{
+	ColorSpace colorspace{ ColorSpace::Primaries::Rec709,
+			       ColorSpace::TransferFunction::Srgb,
+			       ColorSpace::YcbcrEncoding::Rec601,
+			       ColorSpace::Range::Limited };
+	return colorspace;
+}
+
 void ColorBarsGenerator::configure(const Size &size)
 {
 	constexpr uint8_t kColorBar[8][3] = {
diff --git a/src/libcamera/pipeline/virtual/test_pattern_generator.h b/src/libcamera/pipeline/virtual/test_pattern_generator.h
index 2a51bd31..fb2de65f 100644
--- a/src/libcamera/pipeline/virtual/test_pattern_generator.h
+++ b/src/libcamera/pipeline/virtual/test_pattern_generator.h
@@ -9,6 +9,7 @@
 
 #include <memory>
 
+#include <libcamera/color_space.h>
 #include <libcamera/framebuffer.h>
 #include <libcamera/geometry.h>
 
@@ -29,6 +30,9 @@ public:
 protected:
 	/* Buffer of test pattern template */
 	std::unique_ptr<uint8_t[]> template_;
+
+private:
+	const ColorSpace colorspace() override;
 };
 
 class ColorBarsGenerator : public TestPatternGenerator
