extract sdl cameras creation/deletion to service
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android-23]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android-23]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android-23]) (push) Has been cancelled
ContinuousDelivery / windows (push) Has been cancelled
ContinuousDelivery / windows-asan (push) Has been cancelled
ContinuousDelivery / dumpsyms (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
ContinuousIntegration / linux (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android-23]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android-23]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android-23]) (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled

and handle events
This commit is contained in:
Green Sky 2025-04-02 20:04:34 +02:00
parent 73d454e4eb
commit c7be863daf
No known key found for this signature in database
GPG Key ID: DBE05085D874AB4A
6 changed files with 149 additions and 60 deletions

View File

@ -137,6 +137,8 @@ target_sources(tomato PUBLIC
./frame_streams/sdl/video_push_converter.hpp
./frame_streams/sdl/sdl_video_frame_stream2.hpp
./frame_streams/sdl/sdl_video_frame_stream2.cpp
./frame_streams/sdl/sdl_video_input_service.hpp
./frame_streams/sdl/sdl_video_input_service.cpp
./stream_manager_ui.hpp
./stream_manager_ui.cpp

View File

@ -7,7 +7,7 @@
#include <atomic>
#include <thread>
// tips: you can force a SDL vido driver by setting an env:
// tips: you can force a SDL video driver by setting an env:
// SDL_CAMERA_DRIVER=v4l2
// SDL_CAMERA_DRIVER=pipewire
// etc.
@ -24,7 +24,7 @@ struct SDLVideo2InputDevice : public FrameStream2MultiSource<SDLVideoFrame> {
SDLVideo2InputDevice(const SDL_CameraID dev);
virtual ~SDLVideo2InputDevice(void);
// we hook int multi source
// we hook into multi source
std::shared_ptr<FrameStream2I<SDLVideoFrame>> subscribe(void) override;
bool unsubscribe(const std::shared_ptr<FrameStream2I<SDLVideoFrame>>& sub) override;
};

View File

@ -0,0 +1,114 @@
#include "./sdl_video_input_service.hpp"
#include <solanaceae/object_store/object_store.hpp>
#include "../stream_manager.hpp"
#include "./sdl_video_frame_stream2.hpp"
#include <iostream>
namespace Components {
struct SDLVideoDevice {
SDL_CameraID device;
};
} // Components
bool SDLVideoInputService::addDevice(SDL_CameraID device) {
const char *name = SDL_GetCameraName(device);
std::cout << " - Camera #" << device << ": " << name << "\n";
int speccount {0};
SDL_CameraSpec** specs = SDL_GetCameraSupportedFormats(device, &speccount);
if (specs == nullptr) {
std::cout << " - no supported spec\n";
return false;
} else {
for (int spec_i = 0; spec_i < speccount; spec_i++) {
std::cout << " - " << specs[spec_i]->width << "x" << specs[spec_i]->height << "@" << float(specs[spec_i]->framerate_numerator)/specs[spec_i]->framerate_denominator << "fps " << SDL_GetPixelFormatName(specs[spec_i]->format) << "\n";
}
SDL_free(specs);
// create sink for device
ObjectHandle vsrc {_os.registry(), _os.registry().create()};
try {
vsrc.emplace<Components::SDLVideoDevice>(device);
vsrc.emplace<Components::FrameStream2Source<SDLVideoFrame>>(
std::make_unique<SDLVideo2InputDevice>(device)
);
vsrc.emplace<Components::StreamSource>(Components::StreamSource::create<SDLVideoFrame>("SDL Video '" + std::string(name) + "'"));
//vsrc.emplace<Components::TagDefaultTarget>();
_os.throwEventConstruct(vsrc);
//last_src = vsrc;
} catch (...) {
std::cerr << "SDLVIS error: failed constructing video input source\n";
_os.registry().destroy(vsrc);
return false;
}
}
return true;
}
bool SDLVideoInputService::removeDevice(SDL_CameraID device) {
for (const auto&& [ov, svd] : _os.registry().view<Components::SDLVideoDevice>().each()) {
if (svd.device == device) {
_os.throwEventDestroy(ov);
_os.registry().destroy(ov);
return true;
}
}
return false; // not found ??
}
SDLVideoInputService::SDLVideoInputService(ObjectStore2& os) :
_os(os)
{
if (!SDL_InitSubSystem(SDL_INIT_CAMERA)) {
std::cerr << "SDLVIS warning: no sdl camera: " << SDL_GetError() << "\n";
return;
}
_subsystem_init = true;
std::cout << "SDLVIS: SDL Camera Driver: " << SDL_GetCurrentCameraDriver() << "\n";
// sdl throws all cameras as added events anyway
#if 0
int devcount {0};
SDL_CameraID *devices = SDL_GetCameras(&devcount);
std::cout << "SDLVIS: found cameras:\n";
if (devices != nullptr) {
ObjectHandle last_src{};
for (int i = 0; i < devcount; i++) {
addDevice(devices[i]);
}
SDL_free(devices);
} else {
std::cout << " none\n";
}
#endif
}
SDLVideoInputService::~SDLVideoInputService(void) {
if (_subsystem_init) {
SDL_QuitSubSystem(SDL_INIT_CAMERA);
}
}
bool SDLVideoInputService::handleEvent(SDL_Event& e) {
if (e.type == SDL_EVENT_CAMERA_DEVICE_ADDED) {
std::cout << "SDLVIS: camera added:\n";
return addDevice(e.cdevice.which);
} else if (e.type == SDL_EVENT_CAMERA_DEVICE_REMOVED) {
std::cout << "SDLVIS: camera removed\n";
return removeDevice(e.cdevice.which);
}
return false;
}

View File

@ -0,0 +1,22 @@
#pragma once
#include <solanaceae/object_store/fwd.hpp>
#include <SDL3/SDL.h>
// manages sdl camera sources
class SDLVideoInputService {
ObjectStore2& _os;
bool _subsystem_init{false};
bool addDevice(SDL_CameraID device);
bool removeDevice(SDL_CameraID device);
public:
SDLVideoInputService(ObjectStore2& os);
~SDLVideoInputService(void);
bool handleEvent(SDL_Event& e);
};

View File

@ -69,7 +69,8 @@ MainScreen::MainScreen(const SimpleConfigModel& conf_, SDL_Renderer* renderer_,
tdch(tpi),
tnui(tpi),
smui(os, sm),
dvt(os, sm, sdlrtu)
dvt(os, sm, sdlrtu),
sdlvis(os)
{
tel.subscribeAll();
@ -201,63 +202,6 @@ MainScreen::MainScreen(const SimpleConfigModel& conf_, SDL_Renderer* renderer_,
} else {
std::cerr << "MS warning: no sdl audio: " << SDL_GetError() << "\n";
}
if (SDL_InitSubSystem(SDL_INIT_CAMERA)) {
std::cout << "MS: SDL Camera Driver: " << SDL_GetCurrentCameraDriver() << "\n";
int devcount {0};
SDL_CameraID *devices = SDL_GetCameras(&devcount);
std::cout << "MS: found cameras:\n";
if (devices != nullptr) {
ObjectHandle last_src{};
for (int i = 0; i < devcount; i++) {
const SDL_CameraID device = devices[i];
const char *name = SDL_GetCameraName(device);
std::cout << " - Camera #" << i << ": " << name << "\n";
int speccount {0};
SDL_CameraSpec** specs = SDL_GetCameraSupportedFormats(device, &speccount);
if (specs == nullptr) {
std::cout << " - no supported spec\n";
} else {
for (int spec_i = 0; spec_i < speccount; spec_i++) {
std::cout << " - " << specs[spec_i]->width << "x" << specs[spec_i]->height << "@" << float(specs[spec_i]->framerate_numerator)/specs[spec_i]->framerate_denominator << "fps " << SDL_GetPixelFormatName(specs[spec_i]->format) << "\n";
}
SDL_free(specs);
// create sink for device
ObjectHandle vsrc {os.registry(), os.registry().create()};
try {
vsrc.emplace<Components::FrameStream2Source<SDLVideoFrame>>(
std::make_unique<SDLVideo2InputDevice>(device)
);
vsrc.emplace<Components::StreamSource>(Components::StreamSource::create<SDLVideoFrame>("SDL Video '" + std::string(name) + "'"));
//vsrc.emplace<Components::TagDefaultTarget>();
os.throwEventConstruct(vsrc);
last_src = vsrc;
} catch (...) {
std::cerr << "MS error: failed constructing video input source\n";
os.registry().destroy(vsrc);
}
}
}
//if (static_cast<bool>(last_src)) {
// last_src.emplace<Components::TagDefaultTarget>();
//}
SDL_free(devices);
} else {
std::cout << " none\n";
}
} else {
std::cerr << "MS warning: no sdl camera: " << SDL_GetError() << "\n";
}
}
MainScreen::~MainScreen(void) {
@ -361,6 +305,10 @@ bool MainScreen::handleEvent(SDL_Event& e) {
_time_since_event = 0.f;
}
if (sdlvis.handleEvent(e)) {
return true;
}
return false;
}

View File

@ -45,6 +45,8 @@
#include "./tox_av_voip_model.hpp"
#endif
#include "./frame_streams/sdl/sdl_video_input_service.hpp"
#include <string>
#include <iostream>
#include <chrono>
@ -103,6 +105,7 @@ struct MainScreen final : public Screen {
ToxNetprofUI tnui;
StreamManagerUI smui;
DebugVideoTap dvt;
SDLVideoInputService sdlvis;
PluginManager pm; // last, so it gets destroyed first