android: post_processor: Use CameraBuffer API

Use the newly introduced CameraBuffer class as the type for the
destination buffer in the PostProcessor class hierarchy in place of the
libcamera::MappedFrameBuffer one and use its API to retrieve the length
and the location of the CameraBuffer plane allocated for JPEG
post-processing.

Remove all the assumption on the underlying memory storage and only go
through the CameraBuffer API when dealing with memory buffers. To do so
rework the Encoder interface to use a raw pointer and an explicit size
to remove access to the Span<uint8_t> maps that serve as memory storage
for the current implementation but might not be ideal for other memory
backend.

Now that the whole PostProcessor hierarchy has been converted to use
the CameraBuffer API remove libcamera::MappedBuffer as base class
of the CameraBuffer interface and only reply on its interface.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
This commit is contained in:
Jacopo Mondi 2021-02-24 13:22:27 +01:00
parent 63383dec43
commit eba862b0e3
7 changed files with 26 additions and 34 deletions

View file

@ -10,11 +10,9 @@
#include <hardware/camera3.h> #include <hardware/camera3.h>
#include <libcamera/class.h> #include <libcamera/class.h>
#include <libcamera/internal/buffer.h>
#include <libcamera/span.h> #include <libcamera/span.h>
class CameraBuffer final : public libcamera::Extensible, class CameraBuffer final : public libcamera::Extensible
public libcamera::MappedBuffer
{ {
LIBCAMERA_DECLARE_PRIVATE(CameraBuffer) LIBCAMERA_DECLARE_PRIVATE(CameraBuffer)

View file

@ -83,13 +83,15 @@ void PostProcessorJpeg::generateThumbnail(const FrameBuffer &source,
} }
int PostProcessorJpeg::process(const FrameBuffer &source, int PostProcessorJpeg::process(const FrameBuffer &source,
libcamera::MappedBuffer *destination, CameraBuffer *destination,
const CameraMetadata &requestMetadata, const CameraMetadata &requestMetadata,
CameraMetadata *resultMetadata) CameraMetadata *resultMetadata)
{ {
if (!encoder_) if (!encoder_)
return 0; return 0;
ASSERT(destination->numPlanes() == 1);
camera_metadata_ro_entry_t entry; camera_metadata_ro_entry_t entry;
int ret; int ret;
@ -172,28 +174,17 @@ int PostProcessorJpeg::process(const FrameBuffer &source,
const uint8_t quality = ret ? *entry.data.u8 : 95; const uint8_t quality = ret ? *entry.data.u8 : 95;
resultMetadata->addEntry(ANDROID_JPEG_QUALITY, &quality, 1); resultMetadata->addEntry(ANDROID_JPEG_QUALITY, &quality, 1);
int jpeg_size = encoder_->encode(source, destination->maps()[0], int jpeg_size = encoder_->encode(source, destination->plane(0),
exif.data(), quality); exif.data(), quality);
if (jpeg_size < 0) { if (jpeg_size < 0) {
LOG(JPEG, Error) << "Failed to encode stream image"; LOG(JPEG, Error) << "Failed to encode stream image";
return jpeg_size; return jpeg_size;
} }
/* /* Fill in the JPEG blob header. */
* Fill in the JPEG blob header. uint8_t *resultPtr = destination->plane(0).data()
* + destination->plane(0).size()
* The mapped size of the buffer is being returned as - sizeof(struct camera3_jpeg_blob);
* substantially larger than the requested JPEG_MAX_SIZE
* (which is referenced from maxJpegBufferSize_). Utilise
* this static size to ensure the correct offset of the blob is
* determined.
*
* \todo Investigate if the buffer size mismatch is an issue or
* expected behaviour.
*/
uint8_t *resultPtr = destination->maps()[0].data() +
cameraDevice_->maxJpegBufferSize() -
sizeof(struct camera3_jpeg_blob);
auto *blob = reinterpret_cast<struct camera3_jpeg_blob *>(resultPtr); auto *blob = reinterpret_cast<struct camera3_jpeg_blob *>(resultPtr);
blob->jpeg_blob_id = CAMERA3_JPEG_BLOB_ID; blob->jpeg_blob_id = CAMERA3_JPEG_BLOB_ID;
blob->jpeg_size = jpeg_size; blob->jpeg_size = jpeg_size;

View file

@ -25,7 +25,7 @@ public:
int configure(const libcamera::StreamConfiguration &incfg, int configure(const libcamera::StreamConfiguration &incfg,
const libcamera::StreamConfiguration &outcfg) override; const libcamera::StreamConfiguration &outcfg) override;
int process(const libcamera::FrameBuffer &source, int process(const libcamera::FrameBuffer &source,
libcamera::MappedBuffer *destination, CameraBuffer *destination,
const CameraMetadata &requestMetadata, const CameraMetadata &requestMetadata,
CameraMetadata *resultMetadata) override; CameraMetadata *resultMetadata) override;

View file

@ -7,6 +7,7 @@
#include "../camera_buffer.h" #include "../camera_buffer.h"
#include <libcamera/internal/buffer.h>
#include "libcamera/internal/log.h" #include "libcamera/internal/log.h"
using namespace libcamera; using namespace libcamera;

View file

@ -12,6 +12,8 @@
#include <libcamera/internal/buffer.h> #include <libcamera/internal/buffer.h>
#include "camera_buffer.h"
class CameraMetadata; class CameraMetadata;
class PostProcessor class PostProcessor
@ -22,7 +24,7 @@ public:
virtual int configure(const libcamera::StreamConfiguration &inCfg, virtual int configure(const libcamera::StreamConfiguration &inCfg,
const libcamera::StreamConfiguration &outCfg) = 0; const libcamera::StreamConfiguration &outCfg) = 0;
virtual int process(const libcamera::FrameBuffer &source, virtual int process(const libcamera::FrameBuffer &source,
libcamera::MappedBuffer *destination, CameraBuffer *destination,
const CameraMetadata &requestMetadata, const CameraMetadata &requestMetadata,
CameraMetadata *resultMetadata) = 0; CameraMetadata *resultMetadata) = 0;
}; };

View file

@ -48,7 +48,7 @@ int PostProcessorYuv::configure(const StreamConfiguration &inCfg,
} }
int PostProcessorYuv::process(const FrameBuffer &source, int PostProcessorYuv::process(const FrameBuffer &source,
libcamera::MappedBuffer *destination, CameraBuffer *destination,
[[maybe_unused]] const CameraMetadata &requestMetadata, [[maybe_unused]] const CameraMetadata &requestMetadata,
[[maybe_unused]] CameraMetadata *metadata) [[maybe_unused]] CameraMetadata *metadata)
{ {
@ -66,9 +66,9 @@ int PostProcessorYuv::process(const FrameBuffer &source,
sourceMapped.maps()[1].data(), sourceMapped.maps()[1].data(),
sourceStride_[1], sourceStride_[1],
sourceSize_.width, sourceSize_.height, sourceSize_.width, sourceSize_.height,
destination->maps()[0].data(), destination->plane(0).data(),
destinationStride_[0], destinationStride_[0],
destination->maps()[1].data(), destination->plane(1).data(),
destinationStride_[1], destinationStride_[1],
destinationSize_.width, destinationSize_.width,
destinationSize_.height, destinationSize_.height,
@ -82,16 +82,16 @@ int PostProcessorYuv::process(const FrameBuffer &source,
} }
bool PostProcessorYuv::isValidBuffers(const FrameBuffer &source, bool PostProcessorYuv::isValidBuffers(const FrameBuffer &source,
const libcamera::MappedBuffer &destination) const const CameraBuffer &destination) const
{ {
if (source.planes().size() != 2) { if (source.planes().size() != 2) {
LOG(YUV, Error) << "Invalid number of source planes: " LOG(YUV, Error) << "Invalid number of source planes: "
<< source.planes().size(); << source.planes().size();
return false; return false;
} }
if (destination.maps().size() != 2) { if (destination.numPlanes() != 2) {
LOG(YUV, Error) << "Invalid number of destination planes: " LOG(YUV, Error) << "Invalid number of destination planes: "
<< destination.maps().size(); << destination.numPlanes();
return false; return false;
} }
@ -106,12 +106,12 @@ bool PostProcessorYuv::isValidBuffers(const FrameBuffer &source,
<< sourceLength_[1] << "}"; << sourceLength_[1] << "}";
return false; return false;
} }
if (destination.maps()[0].size() < destinationLength_[0] || if (destination.plane(0).size() < destinationLength_[0] ||
destination.maps()[1].size() < destinationLength_[1]) { destination.plane(1).size() < destinationLength_[1]) {
LOG(YUV, Error) LOG(YUV, Error)
<< "The destination planes lengths are too small, actual size: {" << "The destination planes lengths are too small, actual size: {"
<< destination.maps()[0].size() << ", " << destination.plane(0).size() << ", "
<< destination.maps()[1].size() << destination.plane(1).size()
<< "}, expected size: {" << "}, expected size: {"
<< sourceLength_[0] << ", " << sourceLength_[0] << ", "
<< sourceLength_[1] << "}"; << sourceLength_[1] << "}";

View file

@ -21,13 +21,13 @@ public:
int configure(const libcamera::StreamConfiguration &incfg, int configure(const libcamera::StreamConfiguration &incfg,
const libcamera::StreamConfiguration &outcfg) override; const libcamera::StreamConfiguration &outcfg) override;
int process(const libcamera::FrameBuffer &source, int process(const libcamera::FrameBuffer &source,
libcamera::MappedBuffer *destination, CameraBuffer *destination,
const CameraMetadata &requestMetadata, const CameraMetadata &requestMetadata,
CameraMetadata *metadata) override; CameraMetadata *metadata) override;
private: private:
bool isValidBuffers(const libcamera::FrameBuffer &source, bool isValidBuffers(const libcamera::FrameBuffer &source,
const libcamera::MappedBuffer &destination) const; const CameraBuffer &destination) const;
void calculateLengths(const libcamera::StreamConfiguration &inCfg, void calculateLengths(const libcamera::StreamConfiguration &inCfg,
const libcamera::StreamConfiguration &outCfg); const libcamera::StreamConfiguration &outCfg);