1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 /* SPDX-License-Identifier: LGPL-2.1-or-later */ /* * Copyright (C) 2018, Google Inc. * * camera_manager.h - Camera management */ #ifndef __LIBCAMERA_CAMERA_MANAGER_H__ #define __LIBCAMERA_CAMERA_MANAGER_H__ #include <memory> #include <string> #include <sys/types.h> #include <vector> #include <libcamera/extensible.h> #include <libcamera/object.h> #include <libcamera/signal.h> namespace libcamera { class Camera; class CameraManager : public Object, public Extensible { LIBCAMERA_DECLARE_PRIVATE(CameraManager) public: CameraManager(); CameraManager(const CameraManager &) = delete; CameraManager &operator=(const CameraManager &) = delete; ~CameraManager(); int start(); void stop(); std::vector<std::shared_ptr<Camera>> cameras() const; std::shared_ptr<Camera> get(const std::string &name); std::shared_ptr<Camera> get(dev_t devnum); void addCamera(std::shared_ptr<Camera> camera, const std::vector<dev_t> &devnums); void removeCamera(std::shared_ptr<Camera> camera); static const std::string &version() { return version_; } Signal<std::/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Copyright (C) 2019, Google Inc. * * libcamera V4L2 API tests * * Validate the function of exporting buffers from a V4L2Device and * the ability to import them to another V4L2Device instance. * Ensure that the Buffers can successfully be queued and dequeued * between both devices. */ #include <iostream> #include <libcamera/buffer.h> #include <libcamera/camera_manager.h> #include <libcamera/event_dispatcher.h> #include <libcamera/timer.h> #include "v4l2_device_test.h" class BufferSharingTest : public V4L2DeviceTest { public: BufferSharingTest() : output_(nullptr), framesCaptured_(0), framesOutput_(0) { } private: const unsigned int bufferCount = 4; V4L2Device *output_; unsigned int framesCaptured_; unsigned int framesOutput_; protected: int init() { int ret = V4L2DeviceTest::init(); if (ret) return ret; /* media_ already represents VIVID */ MediaEntity *entity = media_->getEntityByName("vivid-000-vid-out"); if (!entity) return TestSkip; output_ = new V4L2Device(entity); if (!output_) { std::cout << "Failed to create output device" << std::endl; return TestFail; } ret = output_->open(); if (ret) { std::cout << "Failed to open output device" << std::endl; return TestFail; } V4L2DeviceFormat format = {}; ret = capture_->getFormat(&format); if (ret) { std::cout << "Failed to get capture format" << std::endl; return TestFail; } ret = output_->setFormat(&format); if (ret) { std::cout << "Failed to set output format" << std::endl; return TestFail; } pool_.createBuffers(bufferCount); ret = capture_->exportBuffers(&pool_); if (ret) { std::cout << "Failed to export buffers" << std::endl; return TestFail; } ret = output_->importBuffers(&pool_); if (ret) { std::cout << "Failed to import buffers" << std::endl; return TestFail; } return 0; } void captureBufferReady(Buffer *buffer) { std::cout << "Received capture buffer: " << buffer->index() << " sequence " << buffer->sequence() << std::endl; output_->queueBuffer(buffer); framesCaptured_++; } void outputBufferReady(Buffer *buffer) { std::cout << "Received output buffer: " << buffer->index() << " sequence " << buffer->sequence() << std::endl; capture_->queueBuffer(buffer); framesOutput_++; } int run() { EventDispatcher *dispatcher = CameraManager::instance()->eventDispatcher(); Timer timeout; int ret; capture_->bufferReady.connect(this, &BufferSharingTest::captureBufferReady); output_->bufferReady.connect(this, &BufferSharingTest::outputBufferReady); /* Queue all the buffers to the capture device. */ for (Buffer &buffer : pool_.buffers()) { if (capture_->queueBuffer(&buffer)) return TestFail; } ret = capture_->streamOn(); if (ret) { std::cout << "Failed to start streaming on the capture device" << std::endl; return TestFail; } ret = output_->streamOn(); if (ret) { std::cout << "Failed to start streaming on the output device" << std::endl; return TestFail; } timeout.start(10000); while (timeout.isRunning()) { dispatcher->processEvents(); if (framesCaptured_ > 30 && framesOutput_ > 30) break; } if ((framesCaptured_ < 1) || (framesOutput_ < 1)) { std::cout << "Failed to process any frames within timeout." << std::endl; return TestFail; } if ((framesCaptured_ < 30) || (framesOutput_ < 30)) { std::cout << "Failed to process 30 frames within timeout." << std::endl; return TestFail; } ret = capture_->streamOff(); if (ret) { std::cout << "Failed to stop streaming on the capture device" << std::endl; return TestFail; } ret = output_->streamOff(); if (ret) { std::cout << "Failed to stop streaming on the output device" << std::endl; return TestFail; } return TestPass; } void cleanup() { std::cout << "Captured " << framesCaptured_ << " frames and " << "output " << framesOutput_ << " frames" << std::endl; output_->streamOff(); output_->releaseBuffers(); output_->close(); delete output_; V4L2DeviceTest::cleanup(); } }; TEST_REGISTER(BufferSharingTest);