summaryrefslogtreecommitdiff
path: root/src/cam/sdl_sink.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/cam/sdl_sink.cpp')
-rw-r--r--src/cam/sdl_sink.cpp202
1 files changed, 0 insertions, 202 deletions
diff --git a/src/cam/sdl_sink.cpp b/src/cam/sdl_sink.cpp
deleted file mode 100644
index f8e3e95d..00000000
--- a/src/cam/sdl_sink.cpp
+++ /dev/null
@@ -1,202 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2022, Ideas on Board Oy
- *
- * sdl_sink.h - SDL Sink
- */
-
-#include "sdl_sink.h"
-
-#include <assert.h>
-#include <fcntl.h>
-#include <iomanip>
-#include <iostream>
-#include <signal.h>
-#include <sstream>
-#include <string.h>
-#include <unistd.h>
-
-#include <libcamera/camera.h>
-#include <libcamera/formats.h>
-
-#include "event_loop.h"
-#include "image.h"
-#ifdef HAVE_SDL_IMAGE
-#include "sdl_texture_mjpg.h"
-#endif
-#include "sdl_texture_yuyv.h"
-
-using namespace libcamera;
-
-using namespace std::chrono_literals;
-
-SDLSink::SDLSink()
- : window_(nullptr), renderer_(nullptr), rect_({}),
- init_(false)
-{
-}
-
-SDLSink::~SDLSink()
-{
- stop();
-}
-
-int SDLSink::configure(const libcamera::CameraConfiguration &config)
-{
- int ret = FrameSink::configure(config);
- if (ret < 0)
- return ret;
-
- if (config.size() > 1) {
- std::cerr
- << "SDL sink only supports one camera stream at present, streaming first camera stream"
- << std::endl;
- } else if (config.empty()) {
- std::cerr << "Require at least one camera stream to process"
- << std::endl;
- return -EINVAL;
- }
-
- const libcamera::StreamConfiguration &cfg = config.at(0);
- rect_.w = cfg.size.width;
- rect_.h = cfg.size.height;
-
- switch (cfg.pixelFormat) {
-#ifdef HAVE_SDL_IMAGE
- case libcamera::formats::MJPEG:
- texture_ = std::make_unique<SDLTextureMJPG>(rect_);
- break;
-#endif
- case libcamera::formats::YUYV:
- texture_ = std::make_unique<SDLTextureYUYV>(rect_);
- break;
- default:
- std::cerr << "Unsupported pixel format "
- << cfg.pixelFormat.toString() << std::endl;
- return -EINVAL;
- };
-
- return 0;
-}
-
-int SDLSink::start()
-{
- int ret = SDL_Init(SDL_INIT_VIDEO);
- if (ret) {
- std::cerr << "Failed to initialize SDL: " << SDL_GetError()
- << std::endl;
- return ret;
- }
-
- init_ = true;
- window_ = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED,
- SDL_WINDOWPOS_UNDEFINED, rect_.w,
- rect_.h,
- SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
- if (!window_) {
- std::cerr << "Failed to create SDL window: " << SDL_GetError()
- << std::endl;
- return -EINVAL;
- }
-
- renderer_ = SDL_CreateRenderer(window_, -1, 0);
- if (!renderer_) {
- std::cerr << "Failed to create SDL renderer: " << SDL_GetError()
- << std::endl;
- return -EINVAL;
- }
-
- /*
- * Set for scaling purposes, not critical, don't return in case of
- * error.
- */
- ret = SDL_RenderSetLogicalSize(renderer_, rect_.w, rect_.h);
- if (ret)
- std::cerr << "Failed to set SDL render logical size: "
- << SDL_GetError() << std::endl;
-
- ret = texture_->create(renderer_);
- if (ret) {
- return ret;
- }
-
- /* \todo Make the event cancellable to support stop/start cycles. */
- EventLoop::instance()->addTimerEvent(
- 10ms, std::bind(&SDLSink::processSDLEvents, this));
-
- return 0;
-}
-
-int SDLSink::stop()
-{
- texture_.reset();
-
- if (renderer_) {
- SDL_DestroyRenderer(renderer_);
- renderer_ = nullptr;
- }
-
- if (window_) {
- SDL_DestroyWindow(window_);
- window_ = nullptr;
- }
-
- if (init_) {
- SDL_Quit();
- init_ = false;
- }
-
- return FrameSink::stop();
-}
-
-void SDLSink::mapBuffer(FrameBuffer *buffer)
-{
- std::unique_ptr<Image> image =
- Image::fromFrameBuffer(buffer, Image::MapMode::ReadOnly);
- assert(image != nullptr);
-
- mappedBuffers_[buffer] = std::move(image);
-}
-
-bool SDLSink::processRequest(Request *request)
-{
- for (auto [stream, buffer] : request->buffers()) {
- renderBuffer(buffer);
- break; /* to be expanded to launch SDL window per buffer */
- }
-
- return true;
-}
-
-/*
- * Process SDL events, required for things like window resize and quit button
- */
-void SDLSink::processSDLEvents()
-{
- for (SDL_Event e; SDL_PollEvent(&e);) {
- if (e.type == SDL_QUIT) {
- /* Click close icon then quit */
- EventLoop::instance()->exit(0);
- }
- }
-}
-
-void SDLSink::renderBuffer(FrameBuffer *buffer)
-{
- Image *image = mappedBuffers_[buffer].get();
-
- /* \todo Implement support for multi-planar formats. */
- const FrameMetadata::Plane &meta = buffer->metadata().planes()[0];
-
- Span<uint8_t> data = image->data(0);
- if (meta.bytesused > data.size())
- std::cerr << "payload size " << meta.bytesused
- << " larger than plane size " << data.size()
- << std::endl;
-
- texture_->update(data);
-
- SDL_RenderClear(renderer_);
- SDL_RenderCopy(renderer_, texture_->get(), nullptr, nullptr);
- SDL_RenderPresent(renderer_);
-}