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,222 @@
|
||||
From d02d3b3a6c0abdfd8a89ee92447df7d8d48639d5 Mon Sep 17 00:00:00 2001
|
||||
From: "zejian.su" <zejian.su@starfivetech.com>
|
||||
Date: Thu, 12 Oct 2023 11:55:47 +0800
|
||||
Subject: [PATCH 2/4] Make libcamera-jpeg run normally
|
||||
|
||||
---
|
||||
apps/libcamera_jpeg.cpp | 28 +++++----
|
||||
core/CMakeLists.txt | 2 +-
|
||||
core/cvt_color_format.cpp | 119 ++++++++++++++++++++++++++++++++++++++
|
||||
image/jpeg.cpp | 1 +
|
||||
4 files changed, 134 insertions(+), 16 deletions(-)
|
||||
create mode 100755 core/cvt_color_format.cpp
|
||||
|
||||
diff --git a/apps/libcamera_jpeg.cpp b/apps/libcamera_jpeg.cpp
|
||||
index 05a632b..b791960 100644
|
||||
--- a/apps/libcamera_jpeg.cpp
|
||||
+++ b/apps/libcamera_jpeg.cpp
|
||||
@@ -15,6 +15,8 @@
|
||||
using namespace std::placeholders;
|
||||
using libcamera::Stream;
|
||||
|
||||
+void NV12ToYUV420(const libcamera::Span<uint8_t> &mem, std::vector<libcamera::Span<uint8_t>> &yuv420, StreamInfo &info);
|
||||
+
|
||||
class LibcameraJpegApp : public LibcameraApp
|
||||
{
|
||||
public:
|
||||
@@ -61,10 +63,19 @@ static void event_loop(LibcameraJpegApp &app)
|
||||
auto now = std::chrono::high_resolution_clock::now();
|
||||
if (options->timeout && now - start_time > std::chrono::milliseconds(options->timeout))
|
||||
{
|
||||
+ Stream *stream = app.ViewfinderStream();
|
||||
+ StreamInfo info = app.GetStreamInfo(stream);
|
||||
+ CompletedRequestPtr &payload = std::get<CompletedRequestPtr>(msg.payload);
|
||||
+ const std::vector<libcamera::Span<uint8_t>> mem = app.Mmap(payload->buffers[stream]);
|
||||
+ std::vector<libcamera::Span<uint8_t>> yuv420;
|
||||
+
|
||||
+ NV12ToYUV420(mem[0], yuv420, info);
|
||||
app.StopCamera();
|
||||
app.Teardown();
|
||||
- app.ConfigureStill();
|
||||
- app.StartCamera();
|
||||
+
|
||||
+ jpeg_save(yuv420, info, payload->metadata, options->output, app.CameraModel(), options);
|
||||
+ delete[] yuv420[0].data();
|
||||
+ return;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -72,19 +83,6 @@ static void event_loop(LibcameraJpegApp &app)
|
||||
app.ShowPreview(completed_request, app.ViewfinderStream());
|
||||
}
|
||||
}
|
||||
- // In still capture mode, save a jpeg and quit.
|
||||
- else if (app.StillStream())
|
||||
- {
|
||||
- app.StopCamera();
|
||||
- LOG(1, "Still capture image received");
|
||||
-
|
||||
- Stream *stream = app.StillStream();
|
||||
- StreamInfo info = app.GetStreamInfo(stream);
|
||||
- CompletedRequestPtr &payload = std::get<CompletedRequestPtr>(msg.payload);
|
||||
- const std::vector<libcamera::Span<uint8_t>> mem = app.Mmap(payload->buffers[stream]);
|
||||
- jpeg_save(mem, info, payload->metadata, options->output, app.CameraModel(), options);
|
||||
- return;
|
||||
- }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt
|
||||
index b601538..5d9ee30 100644
|
||||
--- a/core/CMakeLists.txt
|
||||
+++ b/core/CMakeLists.txt
|
||||
@@ -7,7 +7,7 @@ find_package(Boost REQUIRED COMPONENTS program_options)
|
||||
add_custom_target(VersionCpp ${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_SOURCE_DIR} -P ${CMAKE_CURRENT_LIST_DIR}/version.cmake)
|
||||
set_source_files_properties(version.cpp PROPERTIES GENERATED 1)
|
||||
|
||||
-add_library(libcamera_app libcamera_app.cpp post_processor.cpp version.cpp options.cpp)
|
||||
+add_library(libcamera_app libcamera_app.cpp post_processor.cpp version.cpp options.cpp cvt_color_format.cpp)
|
||||
add_dependencies(libcamera_app VersionCpp)
|
||||
|
||||
set_target_properties(libcamera_app PROPERTIES PREFIX "" IMPORT_PREFIX "" VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR})
|
||||
diff --git a/core/cvt_color_format.cpp b/core/cvt_color_format.cpp
|
||||
new file mode 100755
|
||||
index 0000000..9ff2b6b
|
||||
--- /dev/null
|
||||
+++ b/core/cvt_color_format.cpp
|
||||
@@ -0,0 +1,119 @@
|
||||
+/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
+/*
|
||||
+ * Copyright (C) 2023, Starfive Technology Co., Ltd.
|
||||
+ *
|
||||
+ * cvt_color_format.cpp - convert other format to yuv420.
|
||||
+ */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <unistd.h>
|
||||
+#include <sys/types.h>
|
||||
+#include "core/still_options.hpp"
|
||||
+
|
||||
+void NV12ToYUV420(const uint8_t *mem, uint8_t *dst, const StreamInfo &info)
|
||||
+{
|
||||
+ const uint8_t *src = mem;
|
||||
+ uint32_t width = info.width, height = info.height, stride = info.stride;
|
||||
+ uint8_t *u = dst + height * stride;
|
||||
+ uint8_t *v = u + ((height * width) >> 2);
|
||||
+ uint32_t i;
|
||||
+
|
||||
+ memcpy(dst, src, height * stride);
|
||||
+
|
||||
+ src += height * stride;
|
||||
+ for(i = 0; i < (height * width) >> 2; i++, src += 2)
|
||||
+ u[i] = src[0], v[i] = src[1];
|
||||
+}
|
||||
+
|
||||
+void NV12ToYUV420(const libcamera::Span<uint8_t> &mem, uint8_t *dst, const StreamInfo &info)
|
||||
+{
|
||||
+ NV12ToYUV420((const uint8_t *)(mem.data()), dst, info);
|
||||
+/*
|
||||
+ const uint8_t *src = mem.data();
|
||||
+ uint32_t width = info.width, height = info.height, stride = info.stride;
|
||||
+ uint8_t *u = dst + height * stride;
|
||||
+ uint8_t *v = u + ((height * width) >> 2);
|
||||
+ uint32_t i;
|
||||
+
|
||||
+ memcpy(dst, src, height * stride);
|
||||
+
|
||||
+ src += height * stride;
|
||||
+ for(i = 0; i < (height * width) >> 2; i++, src += 2)
|
||||
+ u[i] = src[0], v[i] = src[1];
|
||||
+*/
|
||||
+}
|
||||
+
|
||||
+void NV12ToYUV420(const libcamera::Span<uint8_t> &mem, std::vector<libcamera::Span<uint8_t>> &yuv420, StreamInfo &info)
|
||||
+{
|
||||
+ uint32_t imgBufSize = info.height * info.stride + ((info.height * info.width) >> 1);
|
||||
+ uint8_t * yuv420Buf = new uint8_t[imgBufSize];
|
||||
+
|
||||
+ if(!yuv420Buf)
|
||||
+ throw std::runtime_error("fail to apply memory");
|
||||
+
|
||||
+ yuv420.push_back(libcamera::Span<uint8_t>(yuv420Buf, imgBufSize));
|
||||
+
|
||||
+ NV12ToYUV420(mem, yuv420Buf, info);
|
||||
+ info.pixel_format = libcamera::formats::YUV420;
|
||||
+}
|
||||
+
|
||||
+template<int R>
|
||||
+void NV12ToRGB888(const libcamera::Span<uint8_t> &mem, uint8_t *dst, const StreamInfo &info)
|
||||
+{
|
||||
+ uint32_t width = info.width, height = info.height, stride = info.stride;
|
||||
+ const uint8_t *yRow = mem.data();
|
||||
+ const uint8_t *uv = yRow + height * stride;
|
||||
+ int ri = R ? 2 : 0;
|
||||
+
|
||||
+ for(uint32_t i = 0; i < height; i++, yRow += stride, dst += 3 * width)
|
||||
+ {
|
||||
+ const uint8_t * curUV = uv;
|
||||
+ uint8_t * curDst = dst;
|
||||
+ for(uint32_t j = 0; j < width; j++, curDst += 3)
|
||||
+ {
|
||||
+ int32_t y = (int32_t)yRow[j] - 16;
|
||||
+ int32_t u = (int32_t)curUV[0] - 128;
|
||||
+ int32_t v = (int32_t)curUV[1] - 128;
|
||||
+ int32_t val;
|
||||
+
|
||||
+ val = (1192 * y + 2066 * u - v) >> 10;
|
||||
+ curDst[ri] = val < 0 ? 0 : (val > 255 ? 255 : (uint8_t)val);
|
||||
+ val = (1192 * y - 401 * u - 833 * v) >> 10;
|
||||
+ curDst[1] = val < 0 ? 0 : (val > 255 ? 255 : (uint8_t)val);
|
||||
+ val = (1192 * y - 2 * u + 1634 * v) >> 10;
|
||||
+ curDst[2 - ri] = val < 0 ? 0 : (val > 255 ? 255 : (uint8_t)val);
|
||||
+
|
||||
+ if(j & 1)
|
||||
+ curUV += 2;
|
||||
+ }
|
||||
+ if(i & 1)
|
||||
+ uv += width;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+template<int R>
|
||||
+void RGB888FromNV12(const libcamera::Span<uint8_t> &mem, std::vector<libcamera::Span<uint8_t>> &rgb888, StreamInfo &info)
|
||||
+{
|
||||
+ uint32_t imgBufSize = info.height * info.width * 3;
|
||||
+ uint8_t * rgb888Buf = new uint8_t[imgBufSize];
|
||||
+
|
||||
+ if(!rgb888Buf)
|
||||
+ throw std::runtime_error("fail to apply memory");
|
||||
+
|
||||
+ rgb888.push_back(libcamera::Span<uint8_t>(rgb888Buf, imgBufSize));
|
||||
+
|
||||
+ NV12ToRGB888<R>(mem, rgb888Buf, info);
|
||||
+ info.stride = 3 * info.width;
|
||||
+}
|
||||
+
|
||||
+void NV12ToRGB888(const libcamera::Span<uint8_t> &mem, std::vector<libcamera::Span<uint8_t>> &rgb888, StreamInfo &info)
|
||||
+{
|
||||
+ RGB888FromNV12<0>(mem, rgb888, info);
|
||||
+ info.pixel_format = libcamera::formats::RGB888;
|
||||
+}
|
||||
+
|
||||
+void NV12ToBGR888(const libcamera::Span<uint8_t> &mem, std::vector<libcamera::Span<uint8_t>> &rgb888, StreamInfo &info)
|
||||
+{
|
||||
+ RGB888FromNV12<2>(mem, rgb888, info);
|
||||
+ info.pixel_format = libcamera::formats::BGR888;
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/image/jpeg.cpp b/image/jpeg.cpp
|
||||
index e3516ef..872f5c6 100644
|
||||
--- a/image/jpeg.cpp
|
||||
+++ b/image/jpeg.cpp
|
||||
@@ -447,6 +447,7 @@ static void create_exif_data(std::vector<libcamera::Span<uint8_t>> const &mem, S
|
||||
exif = exif_data_new();
|
||||
if (!exif)
|
||||
throw std::runtime_error("failed to allocate EXIF data");
|
||||
+
|
||||
exif_data_set_byte_order(exif, exif_byte_order);
|
||||
|
||||
// First add some fixed EXIF tags.
|
||||
--
|
||||
2.34.1
|
||||
|
||||
Reference in New Issue
Block a user