From d833c43269ba2e9b53cb7bda26a065edf02894b6 Mon Sep 17 00:00:00 2001 From: Jasem Mutlaq Date: Thu, 29 Feb 2024 14:37:19 +0300 Subject: [PATCH] Fix libcamera crash due to not parsing options --- indi-libcamera/CMakeLists.txt | 19 +++++++++++ indi-libcamera/indi_libcamera.cpp | 57 ++++++++++++++++++++----------- indi-libcamera/indi_libcamera.h | 23 ++++++------- indi-libcamera/rpicam_test.cpp | 56 ++++++++++++++++++++++++++++++ 4 files changed, 123 insertions(+), 32 deletions(-) create mode 100644 indi-libcamera/rpicam_test.cpp diff --git a/indi-libcamera/CMakeLists.txt b/indi-libcamera/CMakeLists.txt index b2ecc2865..ea194ea05 100644 --- a/indi-libcamera/CMakeLists.txt +++ b/indi-libcamera/CMakeLists.txt @@ -58,6 +58,25 @@ target_link_libraries(indi_libcamera_ccd ##################################### +########### rpicam_test ########### +set(rpicam_test_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/rpicam_test.cpp +) + +add_executable(rpicam_test ${rpicam_test_SRCS}) + +target_link_libraries(rpicam_test + ${LibCameraApps_LIBRARY} + ${LibCamera_LIBRARY} + ${Boost_LIBRARIES} + ${USB1_LIBRARIES} + ${LibRaw_LIBRARIES} + ${JPEG_LIBRARIES} + ${ZLIB_LIBRARY} + ${CMAKE_THREAD_LIBS_INIT}) + +##################################### + if (CMAKE_SYSTEM_PROCESSOR MATCHES "arm*") target_link_libraries(indi_libcamera_ccd rt) endif (CMAKE_SYSTEM_PROCESSOR MATCHES "arm*") diff --git a/indi-libcamera/indi_libcamera.cpp b/indi-libcamera/indi_libcamera.cpp index e973a51e4..01c61c6f8 100644 --- a/indi-libcamera/indi_libcamera.cpp +++ b/indi-libcamera/indi_libcamera.cpp @@ -200,14 +200,6 @@ void INDILibCamera::outputReady(void *mem, size_t size, int64_t timestamp_us, bo Streamer->newFrame(static_cast(mem), size); } -///////////////////////////////////////////////////////////////////////////// -/// -///////////////////////////////////////////////////////////////////////////// -void INDILibCamera::shutdownExposure() -{ - PrimaryCCD.setExposureFailed(); -} - ///////////////////////////////////////////////////////////////////////////// /// ///////////////////////////////////////////////////////////////////////////// @@ -227,20 +219,29 @@ void INDILibCamera::workerExposure(const std::atomic_bool &isAboutToQuit, float catch (std::exception &e) { LOGF_ERROR("Error opening camera: %s", e.what()); - shutdownExposure(); - return; + PrimaryCCD.setExposureFailed(); + app.StopCamera(); + app.Teardown(); + app.CloseCamera(); } RPiCamApp::Msg msg = app.Wait(); if (msg.type != RPiCamApp::MsgType::RequestComplete) { PrimaryCCD.setExposureFailed(); - shutdownExposure(); + app.StopCamera(); + app.Teardown(); + app.CloseCamera(); LOGF_ERROR("Exposure failed: %d", msg.type); return; } else if (isAboutToQuit) + { + app.StopCamera(); + app.Teardown(); + app.CloseCamera(); return; + } bool raw = CaptureFormatSP.findOnSwitchIndex() == CAPTURE_DNG; auto stream = raw ? app.RawStream() : app.StillStream(); @@ -276,7 +277,10 @@ void INDILibCamera::workerExposure(const std::atomic_bool &isAboutToQuit, float if (!processRAW(filename, &memptr, &memsize, &naxis, &w, &h, &bpp, bayer_pattern)) { LOG_ERROR("Exposure failed to parse raw image."); - shutdownExposure(); + PrimaryCCD.setExposureFailed(); + app.StopCamera(); + app.Teardown(); + app.CloseCamera(); unlink(filename); return; } @@ -290,7 +294,10 @@ void INDILibCamera::workerExposure(const std::atomic_bool &isAboutToQuit, float if (!processJPEG(filename, &memptr, &memsize, &naxis, &w, &h)) { LOG_ERROR("Exposure failed to parse jpeg."); - shutdownExposure(); + PrimaryCCD.setExposureFailed(); + app.StopCamera(); + app.Teardown(); + app.CloseCamera(); unlink(filename); return; } @@ -386,7 +393,10 @@ void INDILibCamera::workerExposure(const std::atomic_bool &isAboutToQuit, float if (fstat(fd, &sb) == -1) { LOGF_ERROR("Error opening file %s: %s", filename, strerror(errno)); - shutdownExposure(); + PrimaryCCD.setExposureFailed(); + app.StopCamera(); + app.Teardown(); + app.CloseCamera(); close(fd); return; } @@ -409,7 +419,10 @@ void INDILibCamera::workerExposure(const std::atomic_bool &isAboutToQuit, float if (mmap_mem == nullptr) { LOGF_ERROR("Error reading file %s: %s", filename, strerror(errno)); - shutdownExposure(); + PrimaryCCD.setExposureFailed(); + app.StopCamera(); + app.Teardown(); + app.CloseCamera(); close(fd); return; } @@ -433,16 +446,16 @@ void INDILibCamera::workerExposure(const std::atomic_bool &isAboutToQuit, float } ExposureComplete(&PrimaryCCD); - - app.StopCamera(); - app.Teardown(); - app.CloseCamera(); } catch (std::exception &e) { LOGF_ERROR("Error saving image: %s", e.what()); - shutdownExposure(); + PrimaryCCD.setExposureFailed(); } + + app.StopCamera(); + app.Teardown(); + app.CloseCamera(); } /* @@ -591,6 +604,10 @@ void INDILibCamera::configureStillOptions(StillOptions *options, double duration TimeVal tv; tv.set(std::to_string(duration) + "s"); + int argc = 0; + char *argv[] = {}; + options->Parse(argc, argv); + options->camera = m_CameraIndex; options->nopreview = true; options->immediate = true; diff --git a/indi-libcamera/indi_libcamera.h b/indi-libcamera/indi_libcamera.h index 9ff0a7b61..897d92cc5 100644 --- a/indi-libcamera/indi_libcamera.h +++ b/indi-libcamera/indi_libcamera.h @@ -32,6 +32,17 @@ #include #include +class RPiCamINDIApp : public RPiCamApp +{ +public: + RPiCamINDIApp() : RPiCamApp(std::make_unique()) {} + + StillOptions *GetOptions() const + { + return static_cast(options_.get()); + } +}; + class SingleWorker; class INDILibCamera : public INDI::CCD { @@ -105,7 +116,6 @@ class INDILibCamera : public INDI::CCD int processJPEGMemory(unsigned char *inBuffer, unsigned long inSize, uint8_t **memptr, size_t *memsize, int *naxis, int *w, int *h); void shutdownVideo(); - void shutdownExposure(); private: @@ -128,14 +138,3 @@ class INDILibCamera : public INDI::CCD libcamera::ControlList m_ControlList; }; - -class RPiCamINDIApp : public RPiCamApp -{ -public: - RPiCamINDIApp() : RPiCamApp(std::make_unique()) {} - - StillOptions *GetOptions() const - { - return static_cast(options_.get()); - } -}; diff --git a/indi-libcamera/rpicam_test.cpp b/indi-libcamera/rpicam_test.cpp new file mode 100644 index 000000000..a6abbacda --- /dev/null +++ b/indi-libcamera/rpicam_test.cpp @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (C) 2020, Raspberry Pi (Trading) Ltd. + * + * rpicam_hello.cpp - libcamera "hello world" app. + */ + +#include + +#include "core/rpicam_app.hpp" +#include "core/still_options.hpp" + +using namespace std::placeholders; + +// The main event loop for the application. + +class RPiCamTestApp : public RPiCamApp +{ +public: + RPiCamTestApp() : RPiCamApp(std::make_unique()) {} + + StillOptions *GetOptions() const + { + return static_cast(options_.get()); + } +}; + +static void event_loop() +{ + RPiCamTestApp app; + auto options = app.GetOptions(); + + options->camera = 0; + options->nopreview = true; + options->immediate = false; + options->quality = 100; + options->restart = false; + options->thumb_quality = 0; + options->denoise = "cdn_off"; + + app.OpenCamera(); + app.ConfigureStill(RPiCamApp::FLAG_STILL_RAW); + app.StartCamera(); + + std::this_thread::sleep_for(1s); + + app.StopCamera(); + app.Teardown(); + app.CloseCamera(); +} + +int main(int argc, char *argv[]) +{ + for (int i=0; i < 3; i++) + event_loop(); +}