summaryrefslogtreecommitdiff
path: root/utils/ipu3
AgeCommit message (Collapse)Author
2018-12-11utils: ipu3: process: Configure formats on ImgU subdev padsLaurent Pinchart
Set format and selection rectangles on the ImgU subdev as required by the driver. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2018-12-11utils: ipu3: process: Fix typo in output files pathLaurent Pinchart
A typo in the output files path causes the script to attempt to write all captured frames to /. Fix it. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2018-12-11utils: ipu3: Abort when sensor or media device isn't foundLaurent Pinchart
Calling exit from a function only exits from the function, it doesn't abort the whole script. Propagate the errors to stop operation when the sensor or media device can't be found. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2018-12-02utils: ipu3: Add test process scriptLaurent Pinchart
The script processes raw frames through the Intel IPU3 IMGU. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2018-11-29utils: ipu3: Add test capture scriptLaurent Pinchart
The script captures raw frames from cameras based on the Intel IPU3. It takes the sensor name as an argument and isn't meant to depend on a particular platform. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2018-11-20utils: ipu3: Add IPU3 raw capture unpack utilityLaurent Pinchart
The IPU3 captures Bayer data in a 25-pixels-in-32-bytes packed format, which no standard tool can process. Add a quick implementation of data unpacking to turn raw binary files into 16 bits per pixel unpacked Bayer data. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
n117' href='#n117'>117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * Copyright (C) 2018-2019, Google Inc.
 *
 * media_device_print_test.cpp - Print out media devices
 */

#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#include "media_device.h"

#include "test.h"

using namespace libcamera;
using namespace std;

/*
 * MediaDevicePrintTest takes all media devices found in the system and print
 * them out to verify correctness.
 *
 * If no accessible media device is found, the test is skipped.
 */
class MediaDevicePrintTest : public Test
{
public:
	MediaDevicePrintTest() {}
	~MediaDevicePrintTest() {}

protected:
	int init() { return 0; }
	int run();
	void cleanup() {}

private:
	int testMediaDevice(string deviceNode);

	void printMediaGraph(const MediaDevice &media, ostream &os);
	void printLinkFlags(const MediaLink *link, ostream &os);
	void printNode(const MediaPad *pad, ostream &os);
};

void MediaDevicePrintTest::printNode(const MediaPad *pad, ostream &os)
{
	const MediaEntity *entity = pad->entity();

	os << "\"" << entity->name() << "\"["
	   << pad->index() << "]";
}

void MediaDevicePrintTest::printLinkFlags(const MediaLink *link, ostream &os)
{
	unsigned int flags = link->flags();

	os << " [";
	if (flags) {
		os << (flags & MEDIA_LNK_FL_ENABLED ? "ENABLED," : "")
		   << (flags & MEDIA_LNK_FL_IMMUTABLE ? "IMMUTABLE" : "");
	}
	os  << "]\n";
}

/*
 * For each entity in the media graph, printout links directed to its sinks
 * and source pads.
 */
void MediaDevicePrintTest::printMediaGraph(const MediaDevice &media, ostream &os)
{
	os << "\n" << media.driver() << " - " << media.deviceNode() << "\n\n";

	for (auto const &entity : media.entities()) {
		os << "\"" << entity->name() << "\"\n";

		for (auto const &sink : entity->pads()) {
			if (!(sink->flags() & MEDIA_PAD_FL_SINK))
				continue;

			os << "  [" << sink->index() << "]" << ": Sink\n";
			for (auto const &link : sink->links()) {
				os << "\t";
				printNode(sink, os);
				os << " <- ";
				printNode(link->source(), os);
				printLinkFlags(link, os);
			}
			os << "\n";
		}

		for (auto const &source : entity->pads()) {
			if (!(source->flags() & MEDIA_PAD_FL_SOURCE))
				continue;

			os << "  [" << source->index() << "]" << ": Source\n";
			for (auto const &link : source->links()) {
				os << "\t";
				printNode(source, os);
				os << " -> ";
				printNode(link->sink(), os);
				printLinkFlags(link, os);
			}
			os << "\n";
		}
	}

	os.flush();
}

/* Test a single media device. */
int MediaDevicePrintTest::testMediaDevice(const string deviceNode)
{
	MediaDevice dev(deviceNode);
	int ret;

	ret = dev.populate();
	if (ret)
		return ret;

	/* Print out the media graph. */
	printMediaGraph(dev, cerr);

	return 0;
}

/* Run tests on all media devices. */
#define MAX_MEDIA_DEV 256
int MediaDevicePrintTest::run()
{
	const string deviceNode("/dev/media");
	unsigned int i;
	int ret = 77; /* skip test exit code */

	/*
	 * Run the test sequence on all media device found in the
	 * system, if any.
	 */
	for (i = 0; i < MAX_MEDIA_DEV; i++) {
		string mediadev = deviceNode + to_string(i);
		struct stat pstat = {};

		if (stat(mediadev.c_str(), &pstat))
			continue;

		ret = testMediaDevice(mediadev);
		if (ret)
			return ret;

	}

	return ret;
}

TEST_REGISTER(MediaDevicePrintTest);