From patchwork Fri May 1 15:27:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 3654 Return-Path: Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3D8ED603F3 for ; Fri, 1 May 2020 17:28:07 +0200 (CEST) X-Halon-ID: 5a83473f-8bc0-11ea-aeed-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p4fca2392.dip0.t-ipconnect.de [79.202.35.146]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id 5a83473f-8bc0-11ea-aeed-005056917f90; Fri, 01 May 2020 17:28:05 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Fri, 1 May 2020 17:27:45 +0200 Message-Id: <20200501152745.437777-4-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200501152745.437777-1-niklas.soderlund@ragnatech.se> References: <20200501152745.437777-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 3/3] qcam: Add RAW capture support X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 01 May 2020 15:28:07 -0000 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 --- src/qcam/assets/feathericons/feathericons.qrc | 1 + src/qcam/main_window.cpp | 40 ++++++++++++++++++- src/qcam/main_window.h | 6 +++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/qcam/assets/feathericons/feathericons.qrc b/src/qcam/assets/feathericons/feathericons.qrc index c4eb7a0be6884373..fc8213928ece70ea 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 dc8824dae4669a7e..1c9948b98a231e05 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -48,7 +48,8 @@ public: }; MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options) - : options_(options), cm_(cm), allocator_(nullptr), isCapturing_(false) + : options_(options), cm_(cm), allocator_(nullptr), isCapturing_(false), + captureRaw_(false) { int ret; @@ -144,6 +145,14 @@ int MainWindow::createToolbars() action->setShortcut(QKeySequence::SaveAs); connect(action, &QAction::triggered, this, &MainWindow::saveImageAs); + /* Save Raw action. */ + action = toolbar_->addAction(QIcon::fromTheme("camera-photo", + QIcon(":aperture.svg")), + "Save Raw"); + action->setEnabled(false); + connect(action, &QAction::triggered, this, &MainWindow::saveRaw); + saveRaw_ = action; + return 0; } @@ -369,6 +378,9 @@ int MainWindow::startCapture() adjustSize(); + /* Configure the raw capture button. */ + saveRaw_->setEnabled(config_->size() == 2); + /* Allocate and map buffers. */ allocator_ = new FrameBufferAllocator(camera_); for (StreamConfiguration &config : *config_) { @@ -474,6 +486,7 @@ void MainWindow::stopCapture() return; viewfinder_->stop(); + saveRaw_->setEnabled(false); int ret = camera_->stop(); if (ret) @@ -524,6 +537,11 @@ void MainWindow::saveImageAs() writer.write(image); } +void MainWindow::saveRaw() +{ + captureRaw_ = true; +} + /* ----------------------------------------------------------------------------- * Request Completion Handling */ @@ -567,6 +585,9 @@ void MainWindow::processCapture() if (buffers.count(vfStream_)) processViewfinder(buffers[vfStream_]); + if (buffers.count(rawStream_)) + processRaw(buffers[rawStream_]); + /* * Return buffers so they can be reused. No processing involving * a buffer can happen after they are returned to the free list. @@ -603,6 +624,13 @@ void MainWindow::processViewfinder(FrameBuffer *buffer) viewfinder_->render(buffer, &mappedBuffers_[buffer]); } +void MainWindow::processRaw(FrameBuffer *buffer) +{ + const MappedBuffer &mapped = mappedBuffers_[buffer]; + + dngWriter_.write(camera_.get(), rawStream_, buffer, mapped.memory); +} + void MainWindow::queueRequest(FrameBuffer *buffer) { Request *request = camera_->createRequest(); @@ -613,5 +641,15 @@ void MainWindow::queueRequest(FrameBuffer *buffer) request->addBuffer(vfStream_, buffer); + if (captureRaw_) { + QMutexLocker locker(&mutex_); + + if (!freeBuffers_[rawStream_].isEmpty()) { + request->addBuffer(rawStream_, + freeBuffers_[rawStream_].dequeue()); + captureRaw_ = false; + } + } + camera_->queueRequest(request); } diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h index 4856ecc10729159c..068eb2e38277768e 100644 --- a/src/qcam/main_window.h +++ b/src/qcam/main_window.h @@ -24,6 +24,7 @@ #include #include "../cam/stream_options.h" +#include "dng_writer.h" #include "viewfinder.h" using namespace libcamera; @@ -55,6 +56,7 @@ private Q_SLOTS: void toggleCapture(bool start); void saveImageAs(); + void saveRaw(); void queueRequest(FrameBuffer *buffer); @@ -70,11 +72,13 @@ private: void requestComplete(Request *request); void processCapture(); void processViewfinder(FrameBuffer *buffer); + void processRaw(FrameBuffer *buffer); /* UI elements */ QToolBar *toolbar_; QAction *startStopAction_; QComboBox *cameraCombo_; + QAction *saveRaw_; ViewFinder *viewfinder_; QIcon iconPlay_; @@ -96,11 +100,13 @@ private: /* Capture state, buffers queue and statistics */ bool isCapturing_; + bool captureRaw_; Stream *vfStream_; Stream *rawStream_; std::map> freeBuffers_; QQueue> doneQueue_; QMutex mutex_; /* Protects freeBuffers_ and doneQueue_ */ + DNGWriter dngWriter_; uint64_t lastBufferTime_; QElapsedTimer frameRateInterval_;