diff --git a/src/frame_streams/sdl/sdl_video_frame_stream2.cpp b/src/frame_streams/sdl/sdl_video_frame_stream2.cpp index 37d10f5c..c18473c1 100644 --- a/src/frame_streams/sdl/sdl_video_frame_stream2.cpp +++ b/src/frame_streams/sdl/sdl_video_frame_stream2.cpp @@ -7,34 +7,21 @@ SDLVideo2InputDevice::SDLVideo2InputDevice(void) { int devcount {0}; SDL_CameraID *devices = SDL_GetCameras(&devcount); - std::cout << "SDLVID: SDL Camera Driver: " << SDL_GetCurrentCameraDriver() << "\n"; if (devices == nullptr || devcount < 1) { throw int(2); // TODO: proper error code } - std::cout << "SDLVID: found cameras:\n"; - for (int i = 0; i < devcount; i++) { - const SDL_CameraID device = devices[i]; + // pick the last (usually the newest device) + _dev = devices[devcount-1]; - 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); - } - } SDL_free(devices); } +SDLVideo2InputDevice::SDLVideo2InputDevice(const SDL_CameraID dev) : _dev(dev) { + // nothing else? +} + SDLVideo2InputDevice::~SDLVideo2InputDevice(void) { } @@ -44,19 +31,6 @@ std::shared_ptr> SDLVideo2InputDevice::subscribe(vo // there was previously no stream, we assume no thread // open device here? or on the thread? - int devcount {0}; - SDL_CameraID *devices = SDL_GetCameras(&devcount); - - if (devices == nullptr || devcount < 1) { - _ref--; - // error/no devices, should we do this in the constructor? - SDL_free(devices); - return nullptr; - } - - //auto device = devices[0]; - auto device = devices[devcount-1]; - SDL_CameraSpec spec { // FORCE a different pixel format SDL_PIXELFORMAT_UNKNOWN, @@ -71,7 +45,7 @@ std::shared_ptr> SDLVideo2InputDevice::subscribe(vo // choose a good spec, large res but <= 1080p int speccount {0}; - SDL_CameraSpec** specs = SDL_GetCameraSupportedFormats(device, &speccount); + SDL_CameraSpec** specs = SDL_GetCameraSupportedFormats(_dev, &speccount); if (specs != nullptr) { spec = *specs[0]; for (int spec_i = 1; spec_i < speccount; spec_i++) { @@ -104,10 +78,9 @@ std::shared_ptr> SDLVideo2InputDevice::subscribe(vo camera = { //SDL_OpenCamera(device, nullptr), - SDL_OpenCamera(device, &spec), + SDL_OpenCamera(_dev, &spec), &SDL_CloseCamera }; - SDL_free(devices); if (!camera) { std::cerr << "SDLVID error: failed opening camera device\n"; diff --git a/src/frame_streams/sdl/sdl_video_frame_stream2.hpp b/src/frame_streams/sdl/sdl_video_frame_stream2.hpp index b94c7c6e..3e427529 100644 --- a/src/frame_streams/sdl/sdl_video_frame_stream2.hpp +++ b/src/frame_streams/sdl/sdl_video_frame_stream2.hpp @@ -15,11 +15,13 @@ // while a stream is subscribed, have the camera device open // and aquire and push frames from a thread struct SDLVideo2InputDevice : public FrameStream2MultiSource { + SDL_CameraID _dev {0}; + std::atomic_uint _ref {0}; std::thread _thread; - // TODO: device id SDLVideo2InputDevice(void); + SDLVideo2InputDevice(const SDL_CameraID dev); virtual ~SDLVideo2InputDevice(void); // we hook int multi source diff --git a/src/main_screen.cpp b/src/main_screen.cpp index 2fac7c7a..82c465f7 100644 --- a/src/main_screen.cpp +++ b/src/main_screen.cpp @@ -181,21 +181,57 @@ MainScreen::MainScreen(SimpleConfigModel&& conf_, SDL_Renderer* renderer_, Theme } if (SDL_InitSubSystem(SDL_INIT_CAMERA)) { - { // video in - ObjectHandle vsrc {os.registry(), os.registry().create()}; - try { - vsrc.emplace>( - std::make_unique() - ); + std::cout << "MS: SDL Camera Driver: " << SDL_GetCurrentCameraDriver() << "\n"; - vsrc.emplace(Components::StreamSource::create("SDL Video Default Recording Device")); - vsrc.emplace(); + int devcount {0}; + SDL_CameraID *devices = SDL_GetCameras(&devcount); - os.throwEventConstruct(vsrc); - } catch (...) { - std::cerr << "MS error: failed constructing default video input source\n"; - os.registry().destroy(vsrc); + 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>( + std::make_unique(device) + ); + + vsrc.emplace(Components::StreamSource::create("SDL Video '" + std::string(name) + "'")); + //vsrc.emplace(); + + os.throwEventConstruct(vsrc); + last_src = vsrc; + } catch (...) { + std::cerr << "MS error: failed constructing video input source\n"; + os.registry().destroy(vsrc); + } + } } + + //if (static_cast(last_src)) { + // last_src.emplace(); + //} + + SDL_free(devices); + } else { + std::cout << " none\n"; } } else { std::cerr << "MS warning: no sdl camera: " << SDL_GetError() << "\n";