mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-22 08:05:06 +03:00
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>
This commit is contained in:
parent
db7235b714
commit
b20eb8ffb5
3 changed files with 72 additions and 1 deletions
|
@ -1,5 +1,6 @@
|
||||||
<!DOCTYPE RCC><RCC version="1.0">
|
<!DOCTYPE RCC><RCC version="1.0">
|
||||||
<qresource>
|
<qresource>
|
||||||
|
<file>./aperture.svg</file>
|
||||||
<file>./camera-off.svg</file>
|
<file>./camera-off.svg</file>
|
||||||
<file>./play-circle.svg</file>
|
<file>./play-circle.svg</file>
|
||||||
<file>./save.svg</file>
|
<file>./save.svg</file>
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#include <libcamera/camera_manager.h>
|
#include <libcamera/camera_manager.h>
|
||||||
#include <libcamera/version.h>
|
#include <libcamera/version.h>
|
||||||
|
|
||||||
|
#include "dng_writer.h"
|
||||||
|
|
||||||
using namespace libcamera;
|
using namespace libcamera;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,7 +50,8 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options)
|
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;
|
int ret;
|
||||||
|
|
||||||
|
@ -144,6 +147,16 @@ int MainWindow::createToolbars()
|
||||||
action->setShortcut(QKeySequence::SaveAs);
|
action->setShortcut(QKeySequence::SaveAs);
|
||||||
connect(action, &QAction::triggered, this, &MainWindow::saveImageAs);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,6 +382,10 @@ int MainWindow::startCapture()
|
||||||
|
|
||||||
adjustSize();
|
adjustSize();
|
||||||
|
|
||||||
|
/* Configure the raw capture button. */
|
||||||
|
if (saveRaw_)
|
||||||
|
saveRaw_->setEnabled(config_->size() == 2);
|
||||||
|
|
||||||
/* Allocate and map buffers. */
|
/* Allocate and map buffers. */
|
||||||
allocator_ = new FrameBufferAllocator(camera_);
|
allocator_ = new FrameBufferAllocator(camera_);
|
||||||
for (StreamConfiguration &config : *config_) {
|
for (StreamConfiguration &config : *config_) {
|
||||||
|
@ -474,6 +491,9 @@ void MainWindow::stopCapture()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
viewfinder_->stop();
|
viewfinder_->stop();
|
||||||
|
if (saveRaw_)
|
||||||
|
saveRaw_->setEnabled(false);
|
||||||
|
captureRaw_ = false;
|
||||||
|
|
||||||
int ret = camera_->stop();
|
int ret = camera_->stop();
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -524,6 +544,32 @@ void MainWindow::saveImageAs()
|
||||||
writer.write(image);
|
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
|
* Request Completion Handling
|
||||||
*/
|
*/
|
||||||
|
@ -566,6 +612,9 @@ void MainWindow::processCapture()
|
||||||
/* Process buffers. */
|
/* Process buffers. */
|
||||||
if (buffers.count(vfStream_))
|
if (buffers.count(vfStream_))
|
||||||
processViewfinder(buffers[vfStream_]);
|
processViewfinder(buffers[vfStream_]);
|
||||||
|
|
||||||
|
if (buffers.count(rawStream_))
|
||||||
|
processRaw(buffers[rawStream_]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::processViewfinder(FrameBuffer *buffer)
|
void MainWindow::processViewfinder(FrameBuffer *buffer)
|
||||||
|
@ -598,5 +647,22 @@ void MainWindow::queueRequest(FrameBuffer *buffer)
|
||||||
|
|
||||||
request->addBuffer(vfStream_, 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);
|
camera_->queueRequest(request);
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,8 @@ private Q_SLOTS:
|
||||||
void toggleCapture(bool start);
|
void toggleCapture(bool start);
|
||||||
|
|
||||||
void saveImageAs();
|
void saveImageAs();
|
||||||
|
void captureRaw();
|
||||||
|
void processRaw(FrameBuffer *buffer);
|
||||||
|
|
||||||
void queueRequest(FrameBuffer *buffer);
|
void queueRequest(FrameBuffer *buffer);
|
||||||
|
|
||||||
|
@ -75,6 +77,7 @@ private:
|
||||||
QToolBar *toolbar_;
|
QToolBar *toolbar_;
|
||||||
QAction *startStopAction_;
|
QAction *startStopAction_;
|
||||||
QComboBox *cameraCombo_;
|
QComboBox *cameraCombo_;
|
||||||
|
QAction *saveRaw_;
|
||||||
ViewFinder *viewfinder_;
|
ViewFinder *viewfinder_;
|
||||||
|
|
||||||
QIcon iconPlay_;
|
QIcon iconPlay_;
|
||||||
|
@ -96,6 +99,7 @@ private:
|
||||||
|
|
||||||
/* Capture state, buffers queue and statistics */
|
/* Capture state, buffers queue and statistics */
|
||||||
bool isCapturing_;
|
bool isCapturing_;
|
||||||
|
bool captureRaw_;
|
||||||
Stream *vfStream_;
|
Stream *vfStream_;
|
||||||
Stream *rawStream_;
|
Stream *rawStream_;
|
||||||
std::map<Stream *, QQueue<FrameBuffer *>> freeBuffers_;
|
std::map<Stream *, QQueue<FrameBuffer *>> freeBuffers_;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue