// -*- c++ -*-
+/*!
+ * This file is part of CameraPlus.
+ *
+ * Copyright (C) 2012-2013 Mohammed Sameer <msameer@foolab.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
#ifndef QT_CAM_MODE_P_H
#define QT_CAM_MODE_P_H
#include <QSize>
+#include <QFileInfo>
+#include <QDir>
#include "qtcamdevice_p.h"
+#include "qtcamanalysisbin.h"
#include <gst/pbutils/encoding-profile.h>
#include <gst/pbutils/encoding-target.h>
+#include "qtcamgstreamermessagehandler.h"
+
+#ifndef GST_USE_UNSTABLE_API
+#define GST_USE_UNSTABLE_API
+#endif /* GST_USE_UNSTABLE_API */
+#include <gst/interfaces/photography.h>
+
+#define PREVIEW_CAPS "video/x-raw-rgb, width = (int) %1, height = (int) %2, bpp = (int) 32, depth = (int) 24, red_mask = (int) 65280, green_mask = (int) 16711680, blue_mask = (int) -16777216"
class QtCamDevicePrivate;
class PreviewImageHandler;
class DoneHandler;
-#define CAPS "video/x-raw-yuv, width = (int) %1, height = (int) %2, framerate = (fraction) %3/%4"
-
class QtCamModePrivate {
public:
- QtCamModePrivate(QtCamDevicePrivate *d) : id(-1), dev(d), night(false) {}
+ QtCamModePrivate(QtCamDevicePrivate *d) : id(-1), dev(d) {}
virtual ~QtCamModePrivate() {}
+ void init(DoneHandler *handler) {
+ doneHandler = handler;
+ }
+
int modeId(const char *mode) {
if (!dev->cameraBin) {
return -1;
return -1;
}
- GParamSpecEnum *e = (GParamSpecEnum *)pspec;
+ GParamSpecEnum *e = G_PARAM_SPEC_ENUM(pspec);
GEnumClass *klass = e->enum_class;
for (unsigned x = 0; x < klass->n_values; x++) {
GstEncodingProfile *loadProfile(const QString& path, const QString& name) {
GError *error = NULL;
+ QString targetPath;
+ QFileInfo info(path);
+ if (!info.isAbsolute()) {
+ targetPath = QDir(DATA_DIR).absoluteFilePath(path);
+ }
+ else {
+ targetPath = info.filePath();
+ }
- GstEncodingTarget *target = gst_encoding_target_load_from_file(path.toUtf8().data(), &error);
+ GstEncodingTarget *target = gst_encoding_target_load_from_file(targetPath.toUtf8().constData(),
+ &error);
if (!target) {
qCritical() << "Failed to load encoding target from" << path << error->message;
g_error_free(error);
return profile;
}
- void setCaps(const char *property, const QSize& resolution, const QPair<int, int> frameRate) {
+ void resetCaps(const char *property) {
if (!dev->cameraBin) {
return;
}
- // TODO: allow proceeding without specifying a frame rate (maybe we can calculate it ?)
- if (frameRate.first <= 0 || frameRate.second <= 0) {
+ g_object_set(dev->cameraBin, property, NULL, NULL);
+ }
+
+ bool inNightMode() {
+ if (!dev->cameraBin) {
+ return false;
+ }
+
+ int val = 0;
+
+ g_object_get(dev->videoSource, "scene-mode", &val, NULL);
+
+ return val == GST_PHOTOGRAPHY_SCENE_MODE_NIGHT;
+ }
+
+ void setCaps(const char *property, const QSize& resolution, int fps) {
+ if (!dev->cameraBin) {
return;
}
return;
}
- QString capsString = QString(CAPS)
- .arg(resolution.width()).arg(resolution.height())
- .arg(frameRate.first).arg(frameRate.second);
+ GstCaps *caps = 0;
+
+ if (fps <= 0) {
+ caps = gst_caps_new_simple("video/x-raw-yuv",
+ "width", G_TYPE_INT, resolution.width(),
+ "height", G_TYPE_INT, resolution.height(),
+ NULL);
+ }
+ else {
+ caps = gst_caps_new_simple("video/x-raw-yuv",
+ "width", G_TYPE_INT, resolution.width(),
+ "height", G_TYPE_INT, resolution.height(),
+ "framerate",
+ GST_TYPE_FRACTION_RANGE, fps - 1, 1, fps + 1, 1,
+ NULL);
+ }
+
+ GstCaps *old = 0;
+
+ g_object_get(dev->cameraBin, property, &old, NULL);
- GstCaps *caps = gst_caps_from_string(capsString.toAscii());
+ if (gst_caps_is_equal(caps, old)) {
+ gst_caps_unref(old);
+ gst_caps_unref(caps);
+
+ return;
+ }
g_object_set(dev->cameraBin, property, caps, NULL);
- gst_caps_unref(caps);
+ if (old) {
+ gst_caps_unref(old);
+ }
+ }
+
+ void setPreviewSize(const QSize& size) {
+ if (!dev->cameraBin) {
+ return;
+ }
+
+ if (size.width() <= 0 && size.height() <= 0) {
+ g_object_set(dev->cameraBin, "preview-caps", NULL, "post-previews", FALSE, NULL);
+ }
+ else {
+ QString preview = QString(PREVIEW_CAPS).arg(size.width()).arg(size.height());
+
+ GstCaps *caps = gst_caps_from_string(preview.toLatin1());
+
+ if (!dev->conf->isPreviewSupported()) {
+ qWarning() << "Cannot set preview caps. Preview not supported";
+ gst_caps_unref(caps);
+ return;
+ }
+
+ g_object_set(dev->cameraBin, "preview-caps", caps, "post-previews", TRUE, NULL);
+
+ gst_caps_unref(caps);
+ }
+ }
+
+ void setFileName(const QString& file) {
+ fileName = file;
+ }
+
+ void setTempFileName(const QString& file) {
+ tempFileName = file;
+ }
+
+ void enableViewfinderFilters() {
+ if (dev->viewfinderFilters) {
+ dev->viewfinderFilters->setBlocked(false);
+ }
+ }
+
+ void disableViewfinderFilters() {
+ if (dev->viewfinderFilters) {
+ dev->viewfinderFilters->setBlocked(true);
+ }
}
int id;
+ QtCamMode *q_ptr;
QtCamDevicePrivate *dev;
PreviewImageHandler *previewImageHandler;
DoneHandler *doneHandler;
- bool night;
+ QString fileName;
+ QString tempFileName;
+};
+
+class DoneHandler : public QtCamGStreamerMessageHandler {
+public:
+ DoneHandler(QtCamModePrivate *m, const char *done, QObject *parent = 0) :
+ QtCamGStreamerMessageHandler(done, parent) {
+ mode = m;
+ }
+
+ virtual ~DoneHandler() { }
+
+ virtual void handleMessage(GstMessage *message) {
+ // If we have a temp file then we rename it:
+ if (!mode->tempFileName.isEmpty() && !mode->fileName.isEmpty()) {
+ if (!QFile::rename(mode->tempFileName, mode->fileName)) {
+ qCritical() << "Failed to rename" << mode->tempFileName << "to" << mode->fileName;
+ }
+ }
+
+ QString fileName;
+ const GstStructure *s = gst_message_get_structure(message);
+ if (gst_structure_has_field(s, "filename")) {
+ const char *str = gst_structure_get_string(s, "filename");
+ if (str) {
+ fileName = QString::fromUtf8(str);
+ }
+ }
+
+ if (fileName.isEmpty()) {
+ fileName = mode->fileName;
+ }
+
+ QMetaObject::invokeMethod(mode->q_ptr, "saved", Qt::QueuedConnection,
+ Q_ARG(QString, fileName));
+ }
+
+ QtCamModePrivate *mode;
};
#endif /* QT_CAM_MODE_P_H */