Make 5 libcamera-apps work. They are libcamera-hello, libcamera-jpeg, libcamera-still, libcamera-raw, libcamera-vid
Signed-off-by: zejian.su <zejian.su@starfivetech.com>
This commit is contained in:
@@ -0,0 +1,204 @@
|
||||
From f79f0914c3f8e740cf653da0dd14e5664760188d Mon Sep 17 00:00:00 2001
|
||||
From: "zejian.su" <zejian.su@starfivetech.com>
|
||||
Date: Thu, 12 Oct 2023 11:56:48 +0800
|
||||
Subject: [PATCH 3/4] Make libcamera-still run normally
|
||||
|
||||
---
|
||||
apps/libcamera_still.cpp | 137 +++++++++++++++++++++++++--------------
|
||||
image/dng.cpp | 1 -
|
||||
2 files changed, 88 insertions(+), 50 deletions(-)
|
||||
|
||||
diff --git a/apps/libcamera_still.cpp b/apps/libcamera_still.cpp
|
||||
index 856f1be..bd44818 100644
|
||||
--- a/apps/libcamera_still.cpp
|
||||
+++ b/apps/libcamera_still.cpp
|
||||
@@ -74,22 +74,79 @@ static void update_latest_link(std::string const &filename, StillOptions const *
|
||||
}
|
||||
}
|
||||
|
||||
+void cvtRawData(const libcamera::Span<uint8_t> &mem, std::vector<libcamera::Span<uint8_t>> &packRaw, StreamInfo &info)
|
||||
+{
|
||||
+ const uint8_t *src = (uint8_t *)mem.data();
|
||||
+ uint32_t width = info.width, height = info.height;
|
||||
+ uint32_t bufSize = (width * height) + ((width * height) >> 1);
|
||||
+ uint8_t * dstBuf = new uint8_t[bufSize];
|
||||
+ uint8_t * dst = dstBuf;
|
||||
+ uint32_t srcStride = ((width * 12 / 8 + 8 * 16 - 1) / (8 * 16)) * 128;
|
||||
+
|
||||
+ if(!dst)
|
||||
+ throw std::runtime_error("fail to apply memory");
|
||||
+
|
||||
+ for(uint32_t i = 0; i < height; i++, src += srcStride, dst += (3 * width) >> 1) {
|
||||
+ const uint8_t *srcRow = src;
|
||||
+ uint8_t * dstRow = dst;
|
||||
+ for(uint32_t j = 0; j < width; j += 2, srcRow += 3, dstRow += 3) {
|
||||
+ dstRow[0] = ((srcRow[1] & 0xf) << 4) | (srcRow[0] >> 4);
|
||||
+ dstRow[1] = srcRow[2];
|
||||
+ dstRow[2] = (srcRow[1] & 0xf0) | (srcRow[0] & 0xf);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ packRaw.push_back(libcamera::Span<uint8_t>(dstBuf, bufSize));
|
||||
+
|
||||
+ if(libcamera::formats::SRGGB12 == info.pixel_format)
|
||||
+ info.pixel_format = libcamera::formats::SRGGB12_CSI2P;
|
||||
+ else if(libcamera::formats::SGRBG12 == info.pixel_format)
|
||||
+ info.pixel_format = libcamera::formats::SGRBG12_CSI2P;
|
||||
+ else if(libcamera::formats::SBGGR12 == info.pixel_format)
|
||||
+ info.pixel_format = libcamera::formats::SBGGR12_CSI2P;
|
||||
+ else if(libcamera::formats::SGBRG12 == info.pixel_format)
|
||||
+ info.pixel_format = libcamera::formats::SGBRG12_CSI2P;
|
||||
+ else
|
||||
+ throw std::runtime_error("unsupported Bayer format");
|
||||
+ info.stride = (3 * width) >> 1;
|
||||
+}
|
||||
+
|
||||
+void NV12ToYUV420(const libcamera::Span<uint8_t> &mem, std::vector<libcamera::Span<uint8_t>> &yuv420, StreamInfo &info);
|
||||
+void NV12ToRGB888(const libcamera::Span<uint8_t> &mem, std::vector<libcamera::Span<uint8_t>> &rgb888, StreamInfo &info);
|
||||
+void NV12ToBGR888(const libcamera::Span<uint8_t> &mem, std::vector<libcamera::Span<uint8_t>> &rgb888, StreamInfo &info);
|
||||
+
|
||||
static void save_image(LibcameraStillApp &app, CompletedRequestPtr &payload, Stream *stream,
|
||||
std::string const &filename)
|
||||
{
|
||||
StillOptions const *options = app.GetOptions();
|
||||
StreamInfo info = app.GetStreamInfo(stream);
|
||||
const std::vector<libcamera::Span<uint8_t>> mem = app.Mmap(payload->buffers[stream]);
|
||||
- if (stream == app.RawStream())
|
||||
- dng_save(mem, info, payload->metadata, filename, app.CameraModel(), options);
|
||||
- else if (options->encoding == "jpg")
|
||||
- jpeg_save(mem, info, payload->metadata, filename, app.CameraModel(), options);
|
||||
- else if (options->encoding == "png")
|
||||
- png_save(mem, info, filename, options);
|
||||
- else if (options->encoding == "bmp")
|
||||
- bmp_save(mem, info, filename, options);
|
||||
- else
|
||||
- yuv_save(mem, info, filename, options);
|
||||
+ if (stream == app.RawStream()) {
|
||||
+ std::vector<libcamera::Span<uint8_t>> packRaw;
|
||||
+ cvtRawData(mem[0], packRaw, info);
|
||||
+ dng_save(packRaw, info, payload->metadata, filename, app.CameraModel(), options);
|
||||
+ delete[] packRaw[0].data();
|
||||
+ } else if (options->encoding == "jpg") {
|
||||
+ std::vector<libcamera::Span<uint8_t>> yuv420;
|
||||
+ NV12ToYUV420(mem[0], yuv420, info);
|
||||
+ jpeg_save(yuv420, info, payload->metadata, filename, app.CameraModel(), options);
|
||||
+ delete[] yuv420[0].data();
|
||||
+ } else if (options->encoding == "png") {
|
||||
+ std::vector<libcamera::Span<uint8_t>> rgb888;
|
||||
+ NV12ToBGR888(mem[0], rgb888, info);
|
||||
+ png_save(rgb888, info, filename, options);
|
||||
+ delete[] rgb888[0].data();
|
||||
+ } else if (options->encoding == "bmp") {
|
||||
+ std::vector<libcamera::Span<uint8_t>> rgb888;
|
||||
+ NV12ToRGB888(mem[0], rgb888, info);
|
||||
+ bmp_save(rgb888, info, filename, options);
|
||||
+ delete[] rgb888[0].data();
|
||||
+ } else {
|
||||
+ std::vector<libcamera::Span<uint8_t>> yuv420;
|
||||
+ NV12ToYUV420(mem[0], yuv420, info);
|
||||
+ yuv_save(yuv420, info, filename, options);
|
||||
+ delete[] yuv420[0].data();
|
||||
+ }
|
||||
LOG(2, "Saved image " << info.width << " x " << info.height << " to file " << filename);
|
||||
}
|
||||
|
||||
@@ -193,7 +250,7 @@ static void event_loop(LibcameraStillApp &app)
|
||||
}
|
||||
}
|
||||
else
|
||||
- app.ConfigureViewfinder();
|
||||
+ app.ConfigureStill();
|
||||
app.StartCamera();
|
||||
auto start_time = std::chrono::high_resolution_clock::now();
|
||||
auto timelapse_time = start_time;
|
||||
@@ -234,7 +291,7 @@ static void event_loop(LibcameraStillApp &app)
|
||||
// In viewfinder mode, run until the timeout or keypress. When that happens,
|
||||
// if the "--autofocus-on-capture" option was set, trigger an AF scan and wait
|
||||
// for it to complete. Then switch to capture mode if an output was requested.
|
||||
- if (app.ViewfinderStream())
|
||||
+ if (app.StillStream())
|
||||
{
|
||||
LOG(2, "Viewfinder frame " << count);
|
||||
timelapse_frames++;
|
||||
@@ -280,47 +337,29 @@ static void event_loop(LibcameraStillApp &app)
|
||||
keypressed = false;
|
||||
af_wait_state = AF_WAIT_NONE;
|
||||
timelapse_time = std::chrono::high_resolution_clock::now();
|
||||
+
|
||||
+ save_images(app, completed_request);
|
||||
+ if (!options->metadata.empty())
|
||||
+ save_metadata(options, completed_request->metadata);
|
||||
+
|
||||
app.StopCamera();
|
||||
app.Teardown();
|
||||
- app.ConfigureStill(still_flags);
|
||||
- if (options->af_on_capture)
|
||||
- {
|
||||
- libcamera::ControlList cl;
|
||||
- cl.set(libcamera::controls::AfMode, libcamera::controls::AfModeAuto);
|
||||
- cl.set(libcamera::controls::AfTrigger, libcamera::controls::AfTriggerCancel);
|
||||
- app.SetControls(cl);
|
||||
- }
|
||||
- app.StartCamera();
|
||||
- }
|
||||
- else
|
||||
- app.ShowPreview(completed_request, app.ViewfinderStream());
|
||||
- }
|
||||
- // In still capture mode, save a jpeg. Go back to viewfinder if in timelapse mode,
|
||||
- // otherwise quit.
|
||||
- else if (app.StillStream())
|
||||
- {
|
||||
- app.StopCamera();
|
||||
- LOG(1, "Still capture image received");
|
||||
- save_images(app, completed_request);
|
||||
- if (!options->metadata.empty())
|
||||
- save_metadata(options, completed_request->metadata);
|
||||
- timelapse_frames = 0;
|
||||
- if (!options->immediate && (options->timelapse || options->signal || options->keypress))
|
||||
- {
|
||||
- app.Teardown();
|
||||
- app.ConfigureViewfinder();
|
||||
- if (options->af_on_capture && options->afMode_index == -1)
|
||||
- {
|
||||
- libcamera::ControlList cl;
|
||||
- cl.set(libcamera::controls::AfMode, libcamera::controls::AfModeAuto);
|
||||
- cl.set(libcamera::controls::AfTrigger, libcamera::controls::AfTriggerCancel);
|
||||
- app.SetControls(cl);
|
||||
- }
|
||||
- app.StartCamera();
|
||||
- af_wait_state = AF_WAIT_NONE;
|
||||
+ if (!options->immediate && (options->timelapse || options->signal || options->keypress)){
|
||||
+ app.ConfigureStill(still_flags);
|
||||
+ if (options->af_on_capture)
|
||||
+ {
|
||||
+ libcamera::ControlList cl;
|
||||
+ cl.set(libcamera::controls::AfMode, libcamera::controls::AfModeAuto);
|
||||
+ cl.set(libcamera::controls::AfTrigger, libcamera::controls::AfTriggerCancel);
|
||||
+ app.SetControls(cl);
|
||||
+ }
|
||||
+ app.StartCamera();
|
||||
+ }
|
||||
+ else
|
||||
+ return;
|
||||
}
|
||||
else
|
||||
- return;
|
||||
+ app.ShowPreview(completed_request, app.StillStream());
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/image/dng.cpp b/image/dng.cpp
|
||||
index fbc02bb..98cb5e7 100644
|
||||
--- a/image/dng.cpp
|
||||
+++ b/image/dng.cpp
|
||||
@@ -151,7 +151,6 @@ void dng_save(std::vector<libcamera::Span<uint8_t>> const &mem, StreamInfo const
|
||||
std::string const &filename, std::string const &cam_model, StillOptions const *options)
|
||||
{
|
||||
// Check the Bayer format and unpack it to u16.
|
||||
-
|
||||
auto it = bayer_formats.find(info.pixel_format);
|
||||
if (it == bayer_formats.end())
|
||||
throw std::runtime_error("unsupported Bayer format");
|
||||
--
|
||||
2.34.1
|
||||
|
||||
Reference in New Issue
Block a user