[libcamera-devel] Pinephone 1.2 and libcamera
Pavel Machek
pavel at ucw.cz
Mon Jun 27 09:05:36 CEST 2022
Hi!
> No longer than a few days ago Pavel sent this message
> https://lists.libcamera.org/pipermail/libcamera-devel/2022-June/031340.html
Here's my diff. In "run" file you can see notes about configurations I
tried; those should help with quick testing.
Best regards,
Pavel
diff --git a/README.rst b/README.rst
index f81d6e2e..55c8296e 100644
--- a/README.rst
+++ b/README.rst
@@ -89,6 +89,8 @@ for gstreamer: [optional]
for cam: [optional]
libevent-dev
+ ?? hey, what about sdl ??
+
for qcam: [optional]
qtbase5-dev libqt5core5a libqt5gui5 libqt5widgets5 qttools5-dev-tools libtiff-dev
@@ -101,6 +103,13 @@ for android: [optional]
for lc-compliance: [optional]
libevent-dev
+Basic testing with cam utility
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+cam utility can be used for basic testing. You may want to start with
+"build/src/cam/cam -c 1 -I --capture=10 --file=/tmp/".
+
+
Using GStreamer plugin
~~~~~~~~~~~~~~~~~~~~~~
diff --git a/run b/run
new file mode 100755
index 00000000..0810e114
--- /dev/null
+++ b/run
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+# Captures _many_ frames but does not terminate
+# LIBCAMERA_LOG_FILE=/tmp/camera.log LIBCAMERA_LOG_LEVELS=*:DEBUG build/src/cam/cam -c 1 -I --capture=50 --file=/tmp/
+
+# LIBCAMERA_LOG_FILE=/tmp/camera.log LIBCAMERA_LOG_LEVELS=*:DEBUG build/src/cam/cam -c 1 -I --capture=50 --file=/tmp/ -S
+
+#LIBCAMERA_LOG_FILE=/tmp/camera.log build/src/cam/cam -c 1 -I --capture=5000 -S
+
+#LIBCAMERA_LOG_FILE=/tmp/camera.log build/src/qcam/qcam -r gles
+
+build/src/qcam/qcam -r gles -spixelformat=SBGGR8,width=1280,height=720 -c /base/i2c-csi/rear-camera at 4c
+
+#build/src/cam/cam -c /base/i2c-csi/rear-camera at 4c -spixelformat=YUYV,width=640,height=480 --sdl -C600
diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp
index d055c16a..36909413 100644
--- a/src/libcamera/camera_sensor.cpp
+++ b/src/libcamera/camera_sensor.cpp
@@ -287,7 +287,6 @@ int CameraSensor::validateSensorDriver()
LOG(CameraSensor, Error)
<< "Mandatory V4L2 control " << utils::hex(ctrl)
<< " not available";
- err = -EINVAL;
}
}
diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
index bc0cb1a0..5f5b4205 100644
--- a/src/libcamera/pipeline/simple/simple.cpp
+++ b/src/libcamera/pipeline/simple/simple.cpp
@@ -1265,6 +1265,8 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator)
const SimplePipelineInfo *info = nullptr;
unsigned int numStreams = 1;
+ LOG(SimplePipeline, Error) << "Searching for device";
+
for (const SimplePipelineInfo &inf : supportedDevices) {
DeviceMatch dm(inf.driver);
media_ = acquireMediaDevice(enumerator, dm);
@@ -1276,7 +1278,9 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator)
if (!media_)
return false;
+ LOG(SimplePipeline, Error) << "Have device";
+
for (const auto &[name, streams] : info->converters) {
DeviceMatch converterMatch(name);
converter_ = acquireMediaDevice(enumerator, converterMatch);
@@ -1293,6 +1297,8 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator)
return false;
}
+ LOG(SimplePipeline, Error) << "Have sensors";
+
/*
* Create one camera data instance for each sensor and gather all
* entities in all pipelines.
@@ -1321,6 +1327,9 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator)
if (entities.empty())
return false;
+ LOG(SimplePipeline, Error) << "Have entities";
+
+
/*
* Insert all entities in the global entities list. Create and open
* V4L2VideoDevice and V4L2Subdevice instances for the corresponding
@@ -1361,6 +1370,9 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator)
entities_[entity] = { std::move(video), std::move(subdev), {} };
}
+ LOG(SimplePipeline, Error) << "Opened entities";
+
+
/* Initialize each pipeline and register a corresponding camera. */
bool registered = false;
diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp
index 98a3911a..fba90e20 100644
--- a/src/libcamera/v4l2_subdevice.cpp
+++ b/src/libcamera/v4l2_subdevice.cpp
@@ -465,7 +465,10 @@ int V4L2Subdevice::setFormat(unsigned int pad, V4L2SubdeviceFormat *format,
if (ret) {
LOG(V4L2, Error)
<< "Unable to set format on pad " << pad
- << ": " << strerror(-ret);
+ << ": " << strerror(-ret)
+ << " " << format->size.width << "x" << format->size.height
+ << " code " << format->mbus_code
+ << " colorspace " << subdevFmt.format.colorspace;
return ret;
}
diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp
index 430715af..354b81e4 100644
--- a/src/libcamera/v4l2_videodevice.cpp
+++ b/src/libcamera/v4l2_videodevice.cpp
@@ -1067,17 +1067,39 @@ V4L2VideoDevice::Formats V4L2VideoDevice::formats(uint32_t code)
return formats;
}
+#include <linux/media-bus-format.h>
+
std::vector<V4L2PixelFormat> V4L2VideoDevice::enumPixelformats(uint32_t code)
{
std::vector<V4L2PixelFormat> formats;
int ret;
- if (code && !caps_.hasMediaController()) {
+ if (code && !caps_.hasMediaController()
+ //&& code != ...
+ && code != 12289
+ && false
+ ) {
LOG(V4L2, Error)
- << "Media bus code filtering not supported by the device";
+ << "Media bus code filtering not supported by the device "
+ << "code " << code;
return {};
}
+ LOG(V4L2, Error)
+ << "Forcing format for pinephone";
+
+ if (code == MEDIA_BUS_FMT_SBGGR8_1X8)
+ formats.push_back(V4L2PixelFormat(V4L2_PIX_FMT_SBGGR8)); // Has problems at resolutions < 1280x720
+ if (code == MEDIA_BUS_FMT_YUYV8_2X8)
+ formats.push_back(V4L2PixelFormat(V4L2_PIX_FMT_YUYV)); // Has problems at resolutions > 1280x720
+ if (code == MEDIA_BUS_FMT_UYVY8_2X8)
+ formats.push_back(V4L2PixelFormat(V4L2_PIX_FMT_YUV420)); // Causes assertion
+ if (code == MEDIA_BUS_FMT_RGB565_2X8_LE)
+ formats.push_back(V4L2PixelFormat(V4L2_PIX_FMT_RGB565)); // no viewfinder available
+ if (code == MEDIA_BUS_FMT_JPEG_1X8)
+ formats.push_back(V4L2PixelFormat(V4L2_PIX_FMT_JPEG)); // No luck
+ return formats;
+
for (unsigned int index = 0; ; index++) {
struct v4l2_fmtdesc pixelformatEnum = {};
pixelformatEnum.index = index;
@@ -1112,6 +1134,7 @@ std::vector<SizeRange> V4L2VideoDevice::enumSizes(V4L2PixelFormat pixelFormat)
frameSize.pixel_format = pixelFormat;
ret = ioctl(VIDIOC_ENUM_FRAMESIZES, &frameSize);
+ LOG(V4L2, Error) << "Enumerating sizes" << ret;
if (ret)
break;
@@ -1153,7 +1176,18 @@ std::vector<SizeRange> V4L2VideoDevice::enumSizes(V4L2PixelFormat pixelFormat)
LOG(V4L2, Error)
<< "Unable to enumerate frame sizes: "
<< strerror(-ret);
- return {};
+
+ sizes.emplace_back(Size{ 2592, 1944 });
+ sizes.emplace_back(Size{ 1920, 1080 });
+ sizes.emplace_back(Size{ 1280, 720 });
+ sizes.emplace_back(Size{ 1024, 768 }); // Striped in third way
+ sizes.emplace_back(Size{ 720, 576 }); // Striped in another way
+ sizes.emplace_back(Size{ 640, 480 }); // not right, either.
+ sizes.emplace_back(Size{ 320, 240 }); // broken in different way.
+
+ sizes.emplace_back(Size{ 160, 120 }); // Gives striped output.
+
+ return sizes;
}
return sizes;
@@ -1662,6 +1696,17 @@ int V4L2VideoDevice::queueBuffer(FrameBuffer *buffer)
return ret;
}
+ LOG(V4L2, Debug) << "Queued buffer " << buf.index;
+ {
+ V4L2DeviceFormat format;
+ getFormat(&format);
+ LOG(V4L2, Debug) << "Format is " << format << utils::hex(format.fourcc.fourcc());
+
+ // BAD: we really want i420.
+
+ }
+
+
if (queuedBuffers_.empty()) {
fdBufferNotifier_->setEnabled(true);
if (watchdogDuration_)
diff --git a/src/qcam/main.cpp b/src/qcam/main.cpp
index d3f01a85..1884b2ed 100644
--- a/src/qcam/main.cpp
+++ b/src/qcam/main.cpp
@@ -45,8 +45,14 @@ OptionsParser::Options parseOptions(int argc, char *argv[])
"Print verbose log messages", "verbose");
OptionsParser::Options options = parser.parse(argc, argv);
- if (options.isSet(OptHelp))
+ if (options.isSet(OptHelp)) {
parser.usage();
+#ifdef HAVE_TIFF
+ qInfo() << "TIFF/DNG support available.";
+#else
+ qInfo() << "TIFF/DNG support NOT available, taking still images not possible";
+#endif
+ }
return options;
}
diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp
index dd0e51f5..355ee2b2 100644
--- a/src/qcam/main_window.cpp
+++ b/src/qcam/main_window.cpp
@@ -371,9 +371,12 @@ int MainWindow::startCapture()
StreamRoles roles = StreamKeyValueParser::roles(options_[OptStream]);
int ret;
+ qWarning() << "Have " << roles.size() << " streams.";
+
/* Verify roles are supported. */
switch (roles.size()) {
case 1:
+ qWarning() << "Have " << roles.size() << " streams. Raw capture will NOT be available.";
if (roles[0] != StreamRole::Viewfinder) {
qWarning() << "Only viewfinder supported for single stream";
return -EINVAL;
@@ -451,7 +454,8 @@ int MainWindow::startCapture()
QSize(vfConfig.size.width, vfConfig.size.height),
vfConfig.stride);
if (ret < 0) {
- qInfo() << "Failed to set viewfinder format";
+ qInfo() << "Failed to set viewfinder format, format " << vfConfig.pixelFormat
+ << ". Try running with -r gles option?";
return ret;
}
--
People of Russia, stop Putin before his war on Ukraine escalates.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 195 bytes
Desc: not available
URL: <https://lists.libcamera.org/pipermail/libcamera-devel/attachments/20220627/140e05eb/attachment.sig>
More information about the libcamera-devel
mailing list