/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Copyright (C) 2019, Google Inc. * * libcamera V4L2 API tests */ #include #include #include "libcamera/internal/device_enumerator.h" #include "libcamera/internal/media_device.h" #include "v4l2_videodevice_test.h" using namespace std; using namespace libcamera; int V4L2VideoDeviceTest::init() { enumerator_ = DeviceEnumerator::create(); if (!enumerator_) { cerr << "Failed to create device enumerator" << endl; return TestFail; } if (enumerator_->enumerate()) { cerr << "Failed to enumerate media devices" << endl; return TestFail; } DeviceMatch dm(driver_); dm.add(entity_); media_ = enumerator_->search(dm); if (!media_) return TestSkip; MediaEntity *entity = media_->getEntityByName(entity_); if (!entity) return TestSkip; capture_ = new V4L2VideoDevice(entity); if (!capture_) return TestFail; if (!media_->acquire()) return TestFail; int ret = media_->disableLinks(); media_->release(); if (ret) return TestFail; if (capture_->open()) return TestFail; V4L2DeviceFormat format = {}; if (capture_->getFormat(&format)) return TestFail; if (driver_ == "vimc") { sensor_ = new CameraSensor(media_->getEntityByName("Sensor A")); if (sensor_->init()) return TestFail; debayer_ = new V4L2Subdevice(media_->getEntityByName("Debayer A")); if (debayer_->open()) return TestFail; format.fourcc = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR8); V4L2SubdeviceFormat subformat = {}; subformat.mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8; subformat.size = format.size; if (sensor_->setFormat(&subformat)) return TestFail; if (debayer_->setFormat(0, &subformat)) return TestFail; } format.size.width = 640; format.size.height = 480; if (capture_->setFormat(&format)) return TestFail; return TestPass; } void V4L2VideoDeviceTest::cleanup() { capture_->streamOff(); capture_->releaseBuffers(); capture_->close(); delete debayer_; delete sensor_; delete capture_; } diactl -l "\"$sensor\":0 -> \"$ipu3_csi2\":0[1]" $mediactl -l "\"$ipu3_csi2\":1 -> \"$ipu3_capture\":0[1]" $mediactl -V "\"$sensor\":0 [$format]" $mediactl -V "\"$ipu3_csi2\":1 [$format]" } # Capture frames capture_frames() { local file_op local frame_count=$1 local ipu3_format=IPU3_${bus_format/_1X10/} local save_file=$2 if [[ $save_file -eq 1 ]]; then file_op="--file=/tmp/frame-#.bin" fi yavta -c$frame_count -n5 -I -f $ipu3_format -s $sensor_size $file_op \ $($mediactl -e "$ipu3_capture") } # Convert captured files to ppm convert_files() { local frame_count=$1 local format=${bus_format/_1X10/} local padded_width=$(expr \( $sensor_width + 49 \) / 50 \* 50) echo "Converting ${sensor_width}x${sensor_height} (${padded_width}x${sensor_height})" for i in `seq -f '%06.0f' 0 $(($frame_count - 1))`; do ipu3-unpack /tmp/frame-$i.bin /tmp/frame-$i.raw raw2pnm -x$padded_width -y$sensor_height -f$format /tmp/frame-$i.raw /tmp/frame-$i.ppm done } # Print usage message usage() { echo "Usage: $1 [options] sensor-name" echo "Supported options:" echo "-c,--count n Number of frame to capture" echo "--no-save Do not save captured frames to disk" } # Parse command line arguments frame_count=10 save_file=1 while (( "$#" )) ; do case $1 in -c|--count) frame_count=$2 shift 2 ;; --no-save) save_file=0 shift ;; -*) echo "Unsupported option $1" >&2 usage $0 exit 1 ;; *) break ;; esac done if [[ $# -ne 1 ]] ; then usage $0 exit 1 fi sensor_name=$1 sensor=$(find_sensor $sensor_name) || exit mdev=$(find_media_device) || exit mediactl="media-ctl -d $mdev" parse_pipeline $sensor configure_pipeline capture_frames $frame_count $save_file [[ $save_file -eq 1 ]] && convert_files $frame_count