summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libcamera/pipeline/raspberrypi/raspberrypi.cpp18
1 files changed, 15 insertions, 3 deletions
diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
index 996743cf..44760093 100644
--- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
+++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
@@ -995,7 +995,6 @@ bool PipelineHandlerRPi::match(DeviceEnumerator *enumerator)
DeviceMatch unicam("unicam");
DeviceMatch isp("bcm2835-isp");
- unicam.add("unicam-embedded");
unicam.add("unicam-image");
isp.add("bcm2835-isp0-output0"); /* Input */
@@ -1016,9 +1015,16 @@ bool PipelineHandlerRPi::match(DeviceEnumerator *enumerator)
return false;
/* Locate and open the unicam video streams. */
- data->unicam_[Unicam::Embedded] = RPi::Stream("Unicam Embedded", unicam_->getEntityByName("unicam-embedded"));
data->unicam_[Unicam::Image] = RPi::Stream("Unicam Image", unicam_->getEntityByName("unicam-image"));
+ /* An embedded data node will not be present if the sensor does not support it. */
+ MediaEntity *embeddedEntity = unicam_->getEntityByName("unicam-embedded");
+ if (embeddedEntity) {
+ data->unicam_[Unicam::Embedded] = RPi::Stream("Unicam Embedded", embeddedEntity);
+ data->unicam_[Unicam::Embedded].dev()->bufferReady.connect(data.get(),
+ &RPiCameraData::unicamBufferDequeue);
+ }
+
/* Tag the ISP input stream as an import stream. */
data->isp_[Isp::Input] = RPi::Stream("ISP Input", isp_->getEntityByName("bcm2835-isp0-output0"), true);
data->isp_[Isp::Output0] = RPi::Stream("ISP Output0", isp_->getEntityByName("bcm2835-isp0-capture1"));
@@ -1028,7 +1034,6 @@ bool PipelineHandlerRPi::match(DeviceEnumerator *enumerator)
/* Wire up all the buffer connections. */
data->unicam_[Unicam::Image].dev()->frameStart.connect(data.get(), &RPiCameraData::frameStarted);
data->unicam_[Unicam::Image].dev()->bufferReady.connect(data.get(), &RPiCameraData::unicamBufferDequeue);
- data->unicam_[Unicam::Embedded].dev()->bufferReady.connect(data.get(), &RPiCameraData::unicamBufferDequeue);
data->isp_[Isp::Input].dev()->bufferReady.connect(data.get(), &RPiCameraData::ispInputDequeue);
data->isp_[Isp::Output0].dev()->bufferReady.connect(data.get(), &RPiCameraData::ispOutputDequeue);
data->isp_[Isp::Output1].dev()->bufferReady.connect(data.get(), &RPiCameraData::ispOutputDequeue);
@@ -1056,6 +1061,13 @@ bool PipelineHandlerRPi::match(DeviceEnumerator *enumerator)
return false;
}
+ if (sensorConfig.sensorMetadata ^ !!embeddedEntity) {
+ LOG(RPI, Warning) << "Mismatch between Unicam and CamHelper for embedded data usage!";
+ sensorConfig.sensorMetadata = false;
+ if (embeddedEntity)
+ data->unicam_[Unicam::Embedded].dev()->bufferReady.disconnect();
+ }
+
/*
* Open all Unicam and ISP streams. The exception is the embedded data
* stream, which only gets opened below if the IPA reports that the sensor
href='#n164'>164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * Copyright (C) 2020, Google Inc.
 *
 * Test generated serializer
 */

#include <algorithm>
#include <tuple>
#include <vector>

#include "test.h"

#include "test_ipa_interface.h"
#include "test_ipa_serializer.h"

using namespace std;
using namespace libcamera;

class IPAGeneratedSerializerTest : public Test
{
protected:
	int init() override
	{
		return TestPass;
	}

	int run() override
	{

#define TEST_FIELD_EQUALITY(struct1, struct2, field)		\
if (struct1.field != struct2.field) {				\
	cerr << #field << " field incorrect: expected \""	\
	     << t.field << "\", got \"" << u.field << "\"" << endl;\
	return TestFail;					\
}

#define TEST_SCOPED_ENUM_EQUALITY(struct1, struct2, field)	\
if (struct1.field != struct2.field) {				\
	cerr << #field << " field incorrect" << endl;		\
	return TestFail;					\
}


		ipa::test::TestStruct t, u;

		t.m = {
			{ "a", "z" },
			{ "b", "z" },
			{ "c", "z" },
			{ "d", "z" },
			{ "e", "z" },
		};

		t.a = { "a", "b", "c", "d", "e" };

		t.s1 = "hello world";
		t.s2 = "goodbye";
		t.s3 = "lorem ipsum";
		t.i  = 58527;
		t.c = ipa::test::IPAOperationInit;
		t.e = ipa::test::ErrorFlags::Error1;

		Flags<ipa::test::ErrorFlags> flags;
		flags |= ipa::test::ErrorFlags::Error1;
		flags |= ipa::test::ErrorFlags::Error2;
		t.f = flags;

		std::vector<uint8_t> serialized;

		std::tie(serialized, ignore) =
			IPADataSerializer<ipa::test::TestStruct>::serialize(t);

		u = IPADataSerializer<ipa::test::TestStruct>::deserialize(serialized);

		if (!equals(t.m, u.m))
			return TestFail;

		if (!equals(t.a, u.a))
			return TestFail;

		TEST_FIELD_EQUALITY(t, u, s1);
		TEST_FIELD_EQUALITY(t, u, s2);
		TEST_FIELD_EQUALITY(t, u, s3);
		TEST_FIELD_EQUALITY(t, u, i);
		TEST_FIELD_EQUALITY(t, u, c);

		TEST_SCOPED_ENUM_EQUALITY(t, u, e);
		TEST_SCOPED_ENUM_EQUALITY(t, u, f);

		/* Test vector of generated structs */
		std::vector<ipa::test::TestStruct> v = { t, u };
		std::vector<ipa::test::TestStruct> w;

		std::tie(serialized, ignore) =
			IPADataSerializer<vector<ipa::test::TestStruct>>::serialize(v);

		w = IPADataSerializer<vector<ipa::test::TestStruct>>::deserialize(serialized);

		if (!equals(v[0].m, w[0].m) ||
		    !equals(v[1].m, w[1].m))
			return TestFail;

		if (!equals(v[0].a, w[0].a) ||
		    !equals(v[1].a, w[1].a))
			return TestFail;

		TEST_FIELD_EQUALITY(v[0], w[0], s1);
		TEST_FIELD_EQUALITY(v[0], w[0], s2);
		TEST_FIELD_EQUALITY(v[0], w[0], s3);
		TEST_FIELD_EQUALITY(v[0], w[0], i);
		TEST_FIELD_EQUALITY(v[0], w[0], c);

		TEST_SCOPED_ENUM_EQUALITY(v[0], w[0], e);
		TEST_SCOPED_ENUM_EQUALITY(v[0], w[0], f);

		TEST_FIELD_EQUALITY(v[1], w[1], s1);
		TEST_FIELD_EQUALITY(v[1], w[1], s2);
		TEST_FIELD_EQUALITY(v[1], w[1], s3);
		TEST_FIELD_EQUALITY(v[1], w[1], i);
		TEST_FIELD_EQUALITY(v[1], w[1], c);

		TEST_SCOPED_ENUM_EQUALITY(v[1], w[1], e);
		TEST_SCOPED_ENUM_EQUALITY(v[1], w[1], f);

		return TestPass;
	}

private:
	bool equals(const map<string, string> &lhs, const map<string, string> &rhs)
	{
		bool eq = lhs.size() == rhs.size() &&
			  equal(lhs.begin(), lhs.end(), rhs.begin(),
				[](auto &a, auto &b) { return a.first == b.first &&
							      a.second == b.second; });

		if (eq)
			return true;

		cerr << "lhs:" << endl;
		for (const auto &pair : lhs)
			cerr << "- " << pair.first << ": "
			     << pair.second << endl;

		cerr << "rhs:" << endl;
		for (const auto &pair : rhs)
			cerr << "- " << pair.first << ": "
			     << pair.second << endl;

		return false;
	}

	bool equals(const vector<string> &lhs, const vector<string> &rhs)
	{
		bool eq = lhs.size() == rhs.size();

		if (!eq) {
			cerr << "sizes not equal" << endl;
			return false;
		}

		for (unsigned int i = 0; i < lhs.size(); i++)
			if (lhs[i] != rhs[i])
				eq = false;

		if (eq)
			return true;

		cerr << "lhs:" << endl;
		for (const auto &str : lhs)
			cerr << "- " << str << endl;

		cerr << "rhs:" << endl;
		for (const auto &str : rhs)
			cerr << "- " << str << endl;

		return false;
	}
};

TEST_REGISTER(IPAGeneratedSerializerTest)