summaryrefslogtreecommitdiff
path: root/test/serialization/control_serialization.cpp
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2022-10-09 07:34:09 +0300
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2022-10-10 17:04:29 +0300
commite0e54965df015b954d75ebe945221372f2dffb80 (patch)
treeb5849d8a9a7116a2461c3641fedfe7cfbcf0f8da /test/serialization/control_serialization.cpp
parent603a4d60f6ac4dbc2474700943dd1a0066ee1f23 (diff)
libcamera: base: utils: Drop defopt
utils::defopt causes compilation issues on gcc 8.0.0 to gcc 8.3.0, likely due to bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86521 that was fixed in gcc 8.4.0. gcc 8.3.0 may be considered old (libcamera requires gcc-8 or newer), but it is shipped by Debian 10 that has LTS support until mid-2024. As no workaround has been found to fix compilation on gcc 8.3.0 while still retaining the functionality of utils::defopt, remove it from the libcamera base library. This change could be reverted once support for gcc-8 will be dropped. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Diffstat (limited to 'test/serialization/control_serialization.cpp')
0 files changed, 0 insertions, 0 deletions
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
 * Copyright (C) 2020, Google Inc.
 *
 * camera_stream.cpp - Camera HAL stream
 */

#include "camera_stream.h"

#include <sys/mman.h>

#include "camera_buffer.h"
#include "camera_device.h"
#include "camera_metadata.h"
#include "jpeg/post_processor_jpeg.h"

#include <libcamera/formats.h>

using namespace libcamera;

LOG_DECLARE_CATEGORY(HAL)

/*
 * \class CameraStream
 * \brief Map a camera3_stream_t to a StreamConfiguration
 *
 * The CameraStream class maps a camera3_stream_t provided by Android
 * camera framework to a libcamera::StreamConfiguration.
 *
 * The StreamConfiguration is represented by its index as recorded in the
 * CameraConfiguration and not by pointer as StreamConfiguration is subject to
 * relocation.
 *
 * A single StreamConfiguration may be used to deliver one or more streams to
 * the Android framework. The mapping type between a camera3 stream to a
 * StreamConfiguration is described by the CameraStream::Type.
 *
 * CameraStream handles all the aspects of producing a stream with the size
 * and format requested by the camera3 stream from the data produced by
 * the associated libcamera::Stream, including the creation of the encoder
 * and buffer allocation.
 */

CameraStream::CameraStream(CameraDevice *const cameraDevice,
			   CameraConfiguration *config, Type type,
			   camera3_stream_t *camera3Stream, unsigned int index)
	: cameraDevice_(cameraDevice), config_(config), type_(type),
	  camera3Stream_(camera3Stream), index_(index)
{
	if (type_ == Type::Internal || type_ == Type::Mapped) {
		/*
		 * \todo There might be multiple post-processors. The logic
		 * which should be instantiated here, is deferred for the
		 * future. For now, we only have PostProcessorJpeg and that
		 * is what we instantiate here.
		 */
		postProcessor_ = std::make_unique<PostProcessorJpeg>(cameraDevice_);
	}

	if (type == Type::Internal) {
		allocator_ = std::make_unique<FrameBufferAllocator>(cameraDevice_->camera());
		mutex_ = std::make_unique<std::mutex>();
	}
}

const StreamConfiguration &CameraStream::configuration() const
{
	return config_->at(index_);
}

Stream *CameraStream::stream() const
{
	return configuration().stream();
}

int CameraStream::configure()
{
	if (postProcessor_) {
		StreamConfiguration output = configuration();
		output.pixelFormat = formats::MJPEG;
		int ret = postProcessor_->configure(configuration(), output);
		if (ret)
			return ret;
	}

	if (allocator_) {
		int ret = allocator_->allocate(stream());
		if (ret < 0)
			return ret;

		/* Save a pointer to the reserved frame buffers */
		for (const auto &frameBuffer : allocator_->buffers(stream()))
			buffers_.push_back(frameBuffer.get());
	}

	camera3Stream_->max_buffers = configuration().bufferCount;

	return 0;
}

int CameraStream::process(const libcamera::FrameBuffer &source,
			  buffer_handle_t camera3Dest,
			  const CameraMetadata &requestMetadata,
			  CameraMetadata *resultMetadata)
{
	if (!postProcessor_)
		return 0;

	/*
	 * \todo Buffer mapping and processing should be moved to a
	 * separate thread.
	 */
	const StreamConfiguration &output = configuration();
	CameraBuffer dest(camera3Dest, formats::MJPEG, output.size,
			  PROT_READ | PROT_WRITE);
	if (!dest.isValid()) {
		LOG(HAL, Error) << "Failed to map android blob buffer";
		return -EINVAL;
	}

	return postProcessor_->process(source, &dest, requestMetadata, resultMetadata);
}

FrameBuffer *CameraStream::getBuffer()
{
	if (!allocator_)
		return nullptr;

	std::lock_guard<std::mutex> locker(*mutex_);

	if (buffers_.empty()) {
		LOG(HAL, Error) << "Buffer underrun";
		return nullptr;
	}

	FrameBuffer *buffer = buffers_.back();
	buffers_.pop_back();

	return buffer;
}