cam: file_sink: Use Image class to access pixel data

Replace the manual implementation of frame buffer mapping with the Image
class to improve code sharing.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
Laurent Pinchart 2021-09-06 00:41:54 +03:00
parent 8926fe6d74
commit f8f6bc657d
2 changed files with 17 additions and 31 deletions

View file

@ -5,17 +5,18 @@
* file_sink.cpp - File Sink * file_sink.cpp - File Sink
*/ */
#include <assert.h>
#include <fcntl.h> #include <fcntl.h>
#include <iomanip> #include <iomanip>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <string.h> #include <string.h>
#include <sys/mman.h>
#include <unistd.h> #include <unistd.h>
#include <libcamera/camera.h> #include <libcamera/camera.h>
#include "file_sink.h" #include "file_sink.h"
#include "image.h"
using namespace libcamera; using namespace libcamera;
@ -26,12 +27,6 @@ FileSink::FileSink(const std::string &pattern)
FileSink::~FileSink() FileSink::~FileSink()
{ {
for (auto &iter : mappedBuffers_) {
void *memory = iter.second.first;
unsigned int length = iter.second.second;
munmap(memory, length);
}
mappedBuffers_.clear();
} }
int FileSink::configure(const libcamera::CameraConfiguration &config) int FileSink::configure(const libcamera::CameraConfiguration &config)
@ -51,23 +46,11 @@ int FileSink::configure(const libcamera::CameraConfiguration &config)
void FileSink::mapBuffer(FrameBuffer *buffer) void FileSink::mapBuffer(FrameBuffer *buffer)
{ {
/* \todo use MappedFrameBuffer. */ std::unique_ptr<Image> image =
for (const FrameBuffer::Plane &plane : buffer->planes()) { Image::fromFrameBuffer(buffer, Image::MapMode::ReadOnly);
const int fd = plane.fd.fd(); assert(image != nullptr);
if (mappedBuffers_.find(fd) == mappedBuffers_.end()) {
/**
* \todo Should we try to only map the portions of the
* dmabuf that are used by planes ?
*/
size_t length = lseek(fd, 0, SEEK_END);
void *memory = mmap(NULL, plane.length, PROT_READ,
MAP_SHARED, fd, 0);
mappedBuffers_[fd] = std::make_pair(memory, length);
}
void *memory = mappedBuffers_[fd].first; mappedBuffers_[buffer] = std::move(image);
planeData_[&plane] = static_cast<uint8_t *>(memory) + plane.offset;
}
} }
bool FileSink::processRequest(Request *request) bool FileSink::processRequest(Request *request)
@ -108,19 +91,20 @@ void FileSink::writeBuffer(const Stream *stream, FrameBuffer *buffer)
return; return;
} }
Image *image = mappedBuffers_[buffer].get();
for (unsigned int i = 0; i < buffer->planes().size(); ++i) { for (unsigned int i = 0; i < buffer->planes().size(); ++i) {
const FrameBuffer::Plane &plane = buffer->planes()[i];
const FrameMetadata::Plane &meta = buffer->metadata().planes()[i]; const FrameMetadata::Plane &meta = buffer->metadata().planes()[i];
uint8_t *data = planeData_[&plane]; Span<uint8_t> data = image->data(i);
unsigned int length = std::min(meta.bytesused, plane.length); unsigned int length = std::min<unsigned int>(meta.bytesused, data.size());
if (meta.bytesused > plane.length) if (meta.bytesused > data.size())
std::cerr << "payload size " << meta.bytesused std::cerr << "payload size " << meta.bytesused
<< " larger than plane size " << plane.length << " larger than plane size " << data.size()
<< std::endl; << std::endl;
ret = ::write(fd, data, length); ret = ::write(fd, data.data(), length);
if (ret < 0) { if (ret < 0) {
ret = -errno; ret = -errno;
std::cerr << "write error: " << strerror(-ret) std::cerr << "write error: " << strerror(-ret)

View file

@ -8,12 +8,15 @@
#define __CAM_FILE_SINK_H__ #define __CAM_FILE_SINK_H__
#include <map> #include <map>
#include <memory>
#include <string> #include <string>
#include <libcamera/stream.h> #include <libcamera/stream.h>
#include "frame_sink.h" #include "frame_sink.h"
class Image;
class FileSink : public FrameSink class FileSink : public FrameSink
{ {
public: public:
@ -32,8 +35,7 @@ private:
std::map<const libcamera::Stream *, std::string> streamNames_; std::map<const libcamera::Stream *, std::string> streamNames_;
std::string pattern_; std::string pattern_;
std::map<int, std::pair<void *, unsigned int>> mappedBuffers_; std::map<libcamera::FrameBuffer *, std::unique_ptr<Image>> mappedBuffers_;
std::map<const libcamera::FrameBuffer::Plane *, uint8_t *> planeData_;
}; };
#endif /* __CAM_FILE_SINK_H__ */ #endif /* __CAM_FILE_SINK_H__ */