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>
This commit is contained in:
parent
bb394442ab
commit
6404b163bc
5 changed files with 43 additions and 10 deletions
|
@ -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_) {
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue