Files
fml13v01-buildroot/package/starfive/libcamera-apps/0003-Make-libcamera-still-run-normally.patch
T

205 lines
7.7 KiB
Diff

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