diff options
author | Paul Elder <paul.elder@ideasonboard.com> | 2022-10-17 20:33:23 +0900 |
---|---|---|
committer | Paul Elder <paul.elder@ideasonboard.com> | 2022-10-19 21:05:49 +0900 |
commit | 6404b163bcbb021508b0b09c36c12b516dcb9a36 (patch) | |
tree | 3cba44ffb2fb937b514f0423373bb2366d17fd61 /src | |
parent | bb394442abf0f1bcb70fa6a48e3949da79703a71 (diff) |
cam: file_sink: Add support for DNG output
Add support for outputting buffers in DNG format. It reuses the DNG
writer that we had previously in qcam.
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/cam/camera_session.cpp | 4 | ||||
-rw-r--r-- | src/cam/file_sink.cpp | 32 | ||||
-rw-r--r-- | src/cam/file_sink.h | 7 | ||||
-rw-r--r-- | src/cam/main.cpp | 2 | ||||
-rw-r--r-- | src/cam/meson.build | 8 |
5 files changed, 43 insertions, 10 deletions
diff --git a/src/cam/camera_session.cpp b/src/cam/camera_session.cpp index 238186a3..6b409c98 100644 --- a/src/cam/camera_session.cpp +++ b/src/cam/camera_session.cpp @@ -207,10 +207,10 @@ int CameraSession::start() if (options_.isSet(OptFile)) { if (!options_[OptFile].toString().empty()) - sink_ = std::make_unique<FileSink>(streamNames_, + sink_ = std::make_unique<FileSink>(camera_.get(), streamNames_, options_[OptFile]); else - sink_ = std::make_unique<FileSink>(streamNames_); + sink_ = std::make_unique<FileSink>(camera_.get(), streamNames_); } if (sink_) { diff --git a/src/cam/file_sink.cpp b/src/cam/file_sink.cpp index 45213d4a..9d60c04e 100644 --- a/src/cam/file_sink.cpp +++ b/src/cam/file_sink.cpp @@ -15,14 +15,16 @@ #include <libcamera/camera.h> +#include "dng_writer.h" #include "file_sink.h" #include "image.h" using namespace libcamera; -FileSink::FileSink(const std::map<const libcamera::Stream *, std::string> &streamNames, +FileSink::FileSink(const libcamera::Camera *camera, + const std::map<const libcamera::Stream *, std::string> &streamNames, const std::string &pattern) - : streamNames_(streamNames), pattern_(pattern) + : camera_(camera), streamNames_(streamNames), pattern_(pattern) { } @@ -51,12 +53,13 @@ void FileSink::mapBuffer(FrameBuffer *buffer) bool FileSink::processRequest(Request *request) { for (auto [stream, buffer] : request->buffers()) - writeBuffer(stream, buffer); + writeBuffer(stream, buffer, request->metadata()); return true; } -void FileSink::writeBuffer(const Stream *stream, FrameBuffer *buffer) +void FileSink::writeBuffer(const Stream *stream, FrameBuffer *buffer, + [[maybe_unused]] const ControlList &metadata) { std::string filename; size_t pos; @@ -65,6 +68,10 @@ void FileSink::writeBuffer(const Stream *stream, FrameBuffer *buffer) if (!pattern_.empty()) filename = pattern_; +#ifdef HAVE_TIFF + bool dng = filename.find(".dng", filename.size() - 4) != std::string::npos; +#endif /* HAVE_TIFF */ + if (filename.empty() || filename.back() == '/') filename += "frame-#.bin"; @@ -76,6 +83,21 @@ void FileSink::writeBuffer(const Stream *stream, FrameBuffer *buffer) filename.replace(pos, 1, ss.str()); } + Image *image = mappedBuffers_[buffer].get(); + +#ifdef HAVE_TIFF + if (dng) { + ret = DNGWriter::write(filename.c_str(), camera_, + stream->configuration(), metadata, + buffer, image->data(0).data()); + if (ret < 0) + std::cerr << "failed to write DNG file `" << filename + << "'" << std::endl; + + return; + } +#endif /* HAVE_TIFF */ + fd = open(filename.c_str(), O_CREAT | O_WRONLY | (pos == std::string::npos ? O_APPEND : O_TRUNC), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); @@ -86,8 +108,6 @@ void FileSink::writeBuffer(const Stream *stream, FrameBuffer *buffer) return; } - Image *image = mappedBuffers_[buffer].get(); - for (unsigned int i = 0; i < buffer->planes().size(); ++i) { const FrameMetadata::Plane &meta = buffer->metadata().planes()[i]; diff --git a/src/cam/file_sink.h b/src/cam/file_sink.h index 067736f5..9ce8b619 100644 --- a/src/cam/file_sink.h +++ b/src/cam/file_sink.h @@ -20,7 +20,8 @@ class Image; class FileSink : public FrameSink { public: - FileSink(const std::map<const libcamera::Stream *, std::string> &streamNames, + FileSink(const libcamera::Camera *camera, + const std::map<const libcamera::Stream *, std::string> &streamNames, const std::string &pattern = ""); ~FileSink(); @@ -32,8 +33,10 @@ public: private: void writeBuffer(const libcamera::Stream *stream, - libcamera::FrameBuffer *buffer); + libcamera::FrameBuffer *buffer, + const libcamera::ControlList &metadata); + const libcamera::Camera *camera_; std::map<const libcamera::Stream *, std::string> streamNames_; std::string pattern_; std::map<libcamera::FrameBuffer *, std::unique_ptr<Image>> mappedBuffers_; diff --git a/src/cam/main.cpp b/src/cam/main.cpp index 53c2ffde..c4e18a13 100644 --- a/src/cam/main.cpp +++ b/src/cam/main.cpp @@ -144,6 +144,8 @@ int CamApp::parseOptions(int argc, char *argv[]) "to write files, using the default file name. Otherwise it sets the\n" "full file path and name. The first '#' character in the file name\n" "is expanded to the camera index, stream name and frame sequence number.\n" + "If the file name ends with '.dng', then the frame will be written to\n" + "the output file(s) in DNG format.\n" "The default file name is 'frame-#.bin'.", "file", ArgumentOptional, "filename", false, OptCamera); diff --git a/src/cam/meson.build b/src/cam/meson.build index 9c766221..06dbea06 100644 --- a/src/cam/meson.build +++ b/src/cam/meson.build @@ -52,6 +52,13 @@ if libsdl2.found() endif endif +if libtiff.found() + cam_cpp_args += ['-DHAVE_TIFF'] + cam_sources += files([ + 'dng_writer.cpp', + ]) +endif + cam = executable('cam', cam_sources, dependencies : [ libatomic, @@ -60,6 +67,7 @@ cam = executable('cam', cam_sources, libevent, libjpeg, libsdl2, + libtiff, libyaml, ], cpp_args : cam_cpp_args, |