summaryrefslogtreecommitdiff
path: root/src/qcam
diff options
context:
space:
mode:
authorNiklas Söderlund <niklas.soderlund@ragnatech.se>2020-04-29 16:59:15 +0200
committerNiklas Söderlund <niklas.soderlund@ragnatech.se>2020-05-02 14:46:20 +0200
commitb20eb8ffb5f91788a1412928058cbc9304b8144b (patch)
tree6e351a0ed5835773425ec3e9e5f20448feeab4b6 /src/qcam
parentdb7235b7141aa4e2922827b4678e25da4faa8c5d (diff)
qcam: Add RAW capture support
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 <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'src/qcam')
-rw-r--r--src/qcam/assets/feathericons/feathericons.qrc1
-rw-r--r--src/qcam/main_window.cpp68
-rw-r--r--src/qcam/main_window.h4
3 files changed, 72 insertions, 1 deletions
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 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
+<file>./aperture.svg</file>
<file>./camera-off.svg</file>
<file>./play-circle.svg</file>
<file>./save.svg</file>
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 <libcamera/camera_manager.h>
#include <libcamera/version.h>
+#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<Stream *, QQueue<FrameBuffer *>> freeBuffers_;