From b20eb8ffb5f91788a1412928058cbc9304b8144b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20S=C3=B6derlund?= Date: Wed, 29 Apr 2020 16:59:15 +0200 Subject: qcam: Add RAW capture support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a toolbar button that captures RAW data to disk. The button is only enabled if the camera is configured to provide a raw stream to the application. Only when the capture action is triggered will a request with a raw buffer be queued to the camera. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- src/qcam/assets/feathericons/feathericons.qrc | 1 + src/qcam/main_window.cpp | 68 ++++++++++++++++++++++++++- src/qcam/main_window.h | 4 ++ 3 files changed, 72 insertions(+), 1 deletion(-) (limited to 'src/qcam') diff --git a/src/qcam/assets/feathericons/feathericons.qrc b/src/qcam/assets/feathericons/feathericons.qrc index c4eb7a0b..fc821392 100644 --- a/src/qcam/assets/feathericons/feathericons.qrc +++ b/src/qcam/assets/feathericons/feathericons.qrc @@ -1,5 +1,6 @@ +./aperture.svg ./camera-off.svg ./play-circle.svg ./save.svg diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp index 0bd9f358..8720c6c6 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -27,6 +27,8 @@ #include #include +#include "dng_writer.h" + using namespace libcamera; /** @@ -48,7 +50,8 @@ public: }; MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options) - : options_(options), cm_(cm), allocator_(nullptr), isCapturing_(false) + : saveRaw_(nullptr), options_(options), cm_(cm), allocator_(nullptr), + isCapturing_(false), captureRaw_(false) { int ret; @@ -144,6 +147,16 @@ int MainWindow::createToolbars() action->setShortcut(QKeySequence::SaveAs); connect(action, &QAction::triggered, this, &MainWindow::saveImageAs); +#ifdef HAVE_DNG + /* Save Raw action. */ + action = toolbar_->addAction(QIcon::fromTheme("camera-photo", + QIcon(":aperture.svg")), + "Save Raw"); + action->setEnabled(false); + connect(action, &QAction::triggered, this, &MainWindow::captureRaw); + saveRaw_ = action; +#endif + return 0; } @@ -369,6 +382,10 @@ int MainWindow::startCapture() adjustSize(); + /* Configure the raw capture button. */ + if (saveRaw_) + saveRaw_->setEnabled(config_->size() == 2); + /* Allocate and map buffers. */ allocator_ = new FrameBufferAllocator(camera_); for (StreamConfiguration &config : *config_) { @@ -474,6 +491,9 @@ void MainWindow::stopCapture() return; viewfinder_->stop(); + if (saveRaw_) + saveRaw_->setEnabled(false); + captureRaw_ = false; int ret = camera_->stop(); if (ret) @@ -524,6 +544,32 @@ void MainWindow::saveImageAs() writer.write(image); } +void MainWindow::captureRaw() +{ + captureRaw_ = true; +} + +void MainWindow::processRaw(FrameBuffer *buffer) +{ +#ifdef HAVE_DNG + QString defaultPath = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); + QString filename = QFileDialog::getSaveFileName(this, "Save DNG", defaultPath, + "DNG Files (*.dng)"); + + if (!filename.isEmpty()) { + const MappedBuffer &mapped = mappedBuffers_[buffer]; + DNGWriter::write(filename.toStdString().c_str(), camera_.get(), + rawStream_->configuration(), buffer, + mapped.memory); + } +#endif + + { + QMutexLocker locker(&mutex_); + freeBuffers_[rawStream_].enqueue(buffer); + } +} + /* ----------------------------------------------------------------------------- * Request Completion Handling */ @@ -566,6 +612,9 @@ void MainWindow::processCapture() /* Process buffers. */ if (buffers.count(vfStream_)) processViewfinder(buffers[vfStream_]); + + if (buffers.count(rawStream_)) + processRaw(buffers[rawStream_]); } void MainWindow::processViewfinder(FrameBuffer *buffer) @@ -598,5 +647,22 @@ void MainWindow::queueRequest(FrameBuffer *buffer) request->addBuffer(vfStream_, buffer); + if (captureRaw_) { + FrameBuffer *buffer = nullptr; + + { + QMutexLocker locker(&mutex_); + if (!freeBuffers_[rawStream_].isEmpty()) + buffer = freeBuffers_[rawStream_].dequeue(); + } + + if (buffer) { + request->addBuffer(rawStream_, buffer); + captureRaw_ = false; + } else { + qWarning() << "No free buffer available for RAW capture"; + } + } + camera_->queueRequest(request); } diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h index 4856ecc1..295ecc53 100644 --- a/src/qcam/main_window.h +++ b/src/qcam/main_window.h @@ -55,6 +55,8 @@ private Q_SLOTS: void toggleCapture(bool start); void saveImageAs(); + void captureRaw(); + void processRaw(FrameBuffer *buffer); void queueRequest(FrameBuffer *buffer); @@ -75,6 +77,7 @@ private: QToolBar *toolbar_; QAction *startStopAction_; QComboBox *cameraCombo_; + QAction *saveRaw_; ViewFinder *viewfinder_; QIcon iconPlay_; @@ -96,6 +99,7 @@ private: /* Capture state, buffers queue and statistics */ bool isCapturing_; + bool captureRaw_; Stream *vfStream_; Stream *rawStream_; std::map> freeBuffers_; -- cgit v1.2.1