lcameraDev: Add session mgr lib for libcamera device binding
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
#include <boostAsioLinkageFix.h>
|
||||
|
||||
#include <lcameraDev.h>
|
||||
#include <probeRunner.h>
|
||||
#include <iostream>
|
||||
#include <spinscale/co/nonViralTaskNursery.h>
|
||||
|
||||
namespace {
|
||||
|
||||
sscl::co::NonViralNonPostingInvoker listCamerasCInd(
|
||||
std::exception_ptr& exceptionStorage,
|
||||
std::function<void()> callerLambda)
|
||||
{
|
||||
(void)exceptionStorage;
|
||||
(void)callerLambda;
|
||||
|
||||
const std::vector<lcamera_dev::LcameraDevCameraInfo> cameras =
|
||||
co_await lcameraDev_enumerateCamerasCReq();
|
||||
|
||||
std::cout << "lcameraDev: found " << cameras.size() << " camera(s)\n";
|
||||
|
||||
for (size_t i = 0; i < cameras.size(); ++i)
|
||||
{
|
||||
const lcamera_dev::LcameraDevCameraInfo& info = cameras[i];
|
||||
|
||||
std::cout << " [" << i << "] id=" << info.id;
|
||||
if (!info.model.empty()) {
|
||||
std::cout << " model=" << info.model;
|
||||
}
|
||||
if (!info.location.empty()) {
|
||||
std::cout << " location=" << info.location;
|
||||
}
|
||||
std::cout << '\n';
|
||||
}
|
||||
|
||||
co_return;
|
||||
}
|
||||
|
||||
void runListCameras(
|
||||
const std::shared_ptr<sscl::ComponentThread>& componentThread)
|
||||
{
|
||||
lcameraDev_main(componentThread);
|
||||
|
||||
sscl::co::NonViralTaskNursery nursery;
|
||||
nursery.openAdmission();
|
||||
nursery.launch(
|
||||
[](sscl::co::NonViralTaskNursery::Slot::Lease& lease)
|
||||
{
|
||||
return listCamerasCInd(
|
||||
lease.getExceptionStorage(),
|
||||
lease.getCallerLambda());
|
||||
});
|
||||
nursery.closeAdmission();
|
||||
nursery.syncAwaitAllSettlements(componentThread->getIoContext());
|
||||
|
||||
lcameraDev_exit();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
try {
|
||||
lcamera_dev_probe::runOnComponentThread(runListCameras);
|
||||
return 0;
|
||||
}
|
||||
catch (const std::exception& exc) {
|
||||
std::cerr << "lcameraDev_list_cameras: " << exc.what() << '\n';
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
#include <boostAsioLinkageFix.h>
|
||||
|
||||
#include <lcameraDev.h>
|
||||
#include <probeRunner.h>
|
||||
#include <iostream>
|
||||
#include <spinscale/co/nonViralTaskNursery.h>
|
||||
#include <string>
|
||||
|
||||
namespace {
|
||||
|
||||
sscl::co::NonViralNonPostingInvoker probeSelectorCInd(
|
||||
std::exception_ptr& exceptionStorage,
|
||||
std::function<void()> callerLambda,
|
||||
const std::string& deviceSelector)
|
||||
{
|
||||
(void)exceptionStorage;
|
||||
(void)callerLambda;
|
||||
|
||||
const lcamera_dev::LcameraDevGetOrCreateResult createResult =
|
||||
co_await lcameraDev_getOrCreateDeviceCReq(deviceSelector);
|
||||
|
||||
std::cout << "lcameraDev_probe: opened session for camera id="
|
||||
<< createResult.resolvedIdentity.id << '\n';
|
||||
|
||||
co_await lcameraDev_releaseDeviceCReq(createResult.deviceSession);
|
||||
|
||||
std::cout << "lcameraDev_probe: released session\n";
|
||||
co_return;
|
||||
}
|
||||
|
||||
void runProbe(
|
||||
const std::shared_ptr<sscl::ComponentThread>& componentThread,
|
||||
const std::string& deviceSelector)
|
||||
{
|
||||
lcameraDev_main(componentThread);
|
||||
|
||||
sscl::co::NonViralTaskNursery nursery;
|
||||
nursery.openAdmission();
|
||||
nursery.launch(
|
||||
[deviceSelector](sscl::co::NonViralTaskNursery::Slot::Lease& lease)
|
||||
{
|
||||
return probeSelectorCInd(
|
||||
lease.getExceptionStorage(),
|
||||
lease.getCallerLambda(),
|
||||
deviceSelector);
|
||||
});
|
||||
nursery.closeAdmission();
|
||||
nursery.syncAwaitAllSettlements(componentThread->getIoContext());
|
||||
|
||||
lcameraDev_exit();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
std::cerr << "Usage: lcameraDev_probe <deviceSelector>\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
try {
|
||||
const std::string deviceSelector = argv[1];
|
||||
|
||||
lcamera_dev_probe::runOnComponentThread(
|
||||
[&](const std::shared_ptr<sscl::ComponentThread>& componentThread)
|
||||
{
|
||||
runProbe(componentThread, deviceSelector);
|
||||
});
|
||||
|
||||
return 0;
|
||||
}
|
||||
catch (const std::exception& exc) {
|
||||
std::cerr << "lcameraDev_probe: " << exc.what() << '\n';
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
#include <boostAsioLinkageFix.h>
|
||||
|
||||
#include <probeRunner.h>
|
||||
#include <spinscale/component.h>
|
||||
#include <future>
|
||||
#include <iostream>
|
||||
|
||||
namespace lcamera_dev_probe {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr sscl::ThreadId PROBE_PUPPETEER_THREAD_ID = 1;
|
||||
|
||||
class DummyPuppeteerComponent
|
||||
: public sscl::pptr::PuppeteerComponent
|
||||
{
|
||||
public:
|
||||
explicit DummyPuppeteerComponent(
|
||||
const std::shared_ptr<sscl::PuppeteerThread>& componentThread)
|
||||
: sscl::pptr::PuppeteerComponent(componentThread)
|
||||
{}
|
||||
|
||||
void handleLoopExceptionHook() override
|
||||
{
|
||||
std::cerr << "lcameraDev probe: puppeteer loop exception\n";
|
||||
}
|
||||
};
|
||||
|
||||
void probePuppeteerMain(
|
||||
const sscl::PuppeteerThread::EntryFnArguments& args,
|
||||
const std::function<void(
|
||||
const std::shared_ptr<sscl::ComponentThread>&)>& work,
|
||||
std::promise<std::exception_ptr>& donePromise)
|
||||
{
|
||||
sscl::PuppeteerThread& thr = args.usableBeforeJolt;
|
||||
thr.initializeTls();
|
||||
sscl::ComponentThread::setPuppeteerThreadId(PROBE_PUPPETEER_THREAD_ID);
|
||||
|
||||
std::shared_ptr<sscl::PuppeteerThread> thrPtr =
|
||||
std::static_pointer_cast<sscl::PuppeteerThread>(thr.shared_from_this());
|
||||
sscl::ComponentThread::setPuppeteerThread(thrPtr);
|
||||
|
||||
try {
|
||||
work(thrPtr);
|
||||
donePromise.set_value(nullptr);
|
||||
}
|
||||
catch (...) {
|
||||
donePromise.set_value(std::current_exception());
|
||||
}
|
||||
|
||||
thr.getIoContext().stop();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void runOnComponentThread(
|
||||
const std::function<void(
|
||||
const std::shared_ptr<sscl::ComponentThread>&)>& work)
|
||||
{
|
||||
std::promise<std::exception_ptr> donePromise;
|
||||
std::future<std::exception_ptr> doneFuture = donePromise.get_future();
|
||||
|
||||
DummyPuppeteerComponent dummyComponent{
|
||||
std::shared_ptr<sscl::PuppeteerThread>()};
|
||||
|
||||
std::shared_ptr<sscl::PuppeteerThread> probeThread =
|
||||
std::make_shared<sscl::PuppeteerThread>(
|
||||
PROBE_PUPPETEER_THREAD_ID,
|
||||
"lcameraDev-probe",
|
||||
[&work, &donePromise](
|
||||
const sscl::PuppeteerThread::EntryFnArguments& args)
|
||||
{
|
||||
probePuppeteerMain(args, work, donePromise);
|
||||
},
|
||||
dummyComponent,
|
||||
nullptr);
|
||||
|
||||
dummyComponent.thread = probeThread;
|
||||
|
||||
probeThread->thread.join();
|
||||
|
||||
std::exception_ptr probeException = doneFuture.get();
|
||||
if (probeException) {
|
||||
std::rethrow_exception(probeException);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace lcamera_dev_probe
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef LCAMERA_DEV_PROBE_RUNNER_H
|
||||
#define LCAMERA_DEV_PROBE_RUNNER_H
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <spinscale/componentThread.h>
|
||||
|
||||
namespace lcamera_dev_probe {
|
||||
|
||||
void runOnComponentThread(
|
||||
const std::function<void(
|
||||
const std::shared_ptr<sscl::ComponentThread>&)>& work);
|
||||
|
||||
} // namespace lcamera_dev_probe
|
||||
|
||||
#endif // LCAMERA_DEV_PROBE_RUNNER_H
|
||||
Reference in New Issue
Block a user