Skip to content

Commit

Permalink
Fix libcamera crash due to not parsing options
Browse files Browse the repository at this point in the history
  • Loading branch information
knro committed Feb 29, 2024
1 parent ffd2d56 commit d833c43
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 32 deletions.
19 changes: 19 additions & 0 deletions indi-libcamera/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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*")
Expand Down
57 changes: 37 additions & 20 deletions indi-libcamera/indi_libcamera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,14 +200,6 @@ void INDILibCamera::outputReady(void *mem, size_t size, int64_t timestamp_us, bo
Streamer->newFrame(static_cast<uint8_t*>(mem), size);
}

/////////////////////////////////////////////////////////////////////////////
///
/////////////////////////////////////////////////////////////////////////////
void INDILibCamera::shutdownExposure()
{
PrimaryCCD.setExposureFailed();
}

/////////////////////////////////////////////////////////////////////////////
///
/////////////////////////////////////////////////////////////////////////////
Expand All @@ -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();
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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();
}

/*
Expand Down Expand Up @@ -591,6 +604,10 @@ void INDILibCamera::configureStillOptions(StillOptions *options, double duration
TimeVal<std::chrono::microseconds> 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;
Expand Down
23 changes: 11 additions & 12 deletions indi-libcamera/indi_libcamera.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,17 @@
#include <indiccd.h>
#include <inditimer.h>

class RPiCamINDIApp : public RPiCamApp
{
public:
RPiCamINDIApp() : RPiCamApp(std::make_unique<StillOptions>()) {}

StillOptions *GetOptions() const
{
return static_cast<StillOptions *>(options_.get());
}
};

class SingleWorker;
class INDILibCamera : public INDI::CCD
{
Expand Down Expand Up @@ -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:

Expand All @@ -128,14 +138,3 @@ class INDILibCamera : public INDI::CCD
libcamera::ControlList m_ControlList;

};

class RPiCamINDIApp : public RPiCamApp
{
public:
RPiCamINDIApp() : RPiCamApp(std::make_unique<StillOptions>()) {}

StillOptions *GetOptions() const
{
return static_cast<StillOptions *>(options_.get());
}
};
56 changes: 56 additions & 0 deletions indi-libcamera/rpicam_test.cpp
Original file line number Diff line number Diff line change
@@ -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 <chrono>

#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>()) {}

StillOptions *GetOptions() const
{
return static_cast<StillOptions *>(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();
}

0 comments on commit d833c43

Please sign in to comment.