123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- 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
|