4 * This file is part of CameraPlus.
6 * Copyright (C) 2012-2013 Mohammed Sameer <msameer@foolab.org>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #ifndef QT_CAM_MODE_P_H
24 #define QT_CAM_MODE_P_H
29 #include "qtcamdevice_p.h"
30 #include "qtcamanalysisbin.h"
31 #include <gst/pbutils/encoding-profile.h>
32 #include <gst/pbutils/encoding-target.h>
33 #include "qtcamgstreamermessagehandler.h"
35 #ifndef GST_USE_UNSTABLE_API
36 #define GST_USE_UNSTABLE_API
37 #endif /* GST_USE_UNSTABLE_API */
38 #include <gst/interfaces/photography.h>
40 #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"
42 class QtCamDevicePrivate;
43 class PreviewImageHandler;
46 class QtCamModePrivate {
48 QtCamModePrivate(QtCamDevicePrivate *d) : id(-1), dev(d) {}
49 virtual ~QtCamModePrivate() {}
51 void init(DoneHandler *handler) {
52 doneHandler = handler;
55 int modeId(const char *mode) {
56 if (!dev->cameraBin) {
60 GParamSpec *pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(dev->cameraBin),
66 if (!G_IS_PARAM_SPEC_ENUM(pspec)) {
70 GParamSpecEnum *e = G_PARAM_SPEC_ENUM(pspec);
71 GEnumClass *klass = e->enum_class;
73 for (unsigned x = 0; x < klass->n_values; x++) {
74 if (QLatin1String(mode) == QLatin1String(klass->values[x].value_nick)) {
75 return klass->values[x].value;
82 GstEncodingProfile *loadProfile(const QString& path, const QString& name) {
86 if (!info.isAbsolute()) {
87 targetPath = QDir(DATA_DIR).absoluteFilePath(path);
90 targetPath = info.filePath();
93 GstEncodingTarget *target = gst_encoding_target_load_from_file(targetPath.toUtf8().constData(),
96 qCritical() << "Failed to load encoding target from" << path << error->message;
101 GstEncodingProfile *profile = gst_encoding_target_get_profile(target, name.toUtf8().data());
103 qCritical() << "Failed to load encoding profile from" << path;
104 gst_encoding_target_unref(target);
108 gst_encoding_target_unref(target);
113 void resetCaps(const char *property) {
114 if (!dev->cameraBin) {
118 g_object_set(dev->cameraBin, property, NULL, NULL);
122 if (!dev->cameraBin) {
128 g_object_get(dev->videoSource, "scene-mode", &val, NULL);
130 return val == GST_PHOTOGRAPHY_SCENE_MODE_NIGHT;
133 void setCaps(const char *property, const QSize& resolution, int fps) {
134 if (!dev->cameraBin) {
138 if (resolution.width() <= 0 || resolution.height() <= 0) {
145 caps = gst_caps_new_simple("video/x-raw-yuv",
146 "width", G_TYPE_INT, resolution.width(),
147 "height", G_TYPE_INT, resolution.height(),
151 caps = gst_caps_new_simple("video/x-raw-yuv",
152 "width", G_TYPE_INT, resolution.width(),
153 "height", G_TYPE_INT, resolution.height(),
155 GST_TYPE_FRACTION_RANGE, fps - 1, 1, fps + 1, 1,
161 g_object_get(dev->cameraBin, property, &old, NULL);
163 if (gst_caps_is_equal(caps, old)) {
165 gst_caps_unref(caps);
170 g_object_set(dev->cameraBin, property, caps, NULL);
177 void setPreviewSize(const QSize& size) {
178 if (!dev->cameraBin) {
182 if (size.width() <= 0 && size.height() <= 0) {
183 g_object_set(dev->cameraBin, "preview-caps", NULL, "post-previews", FALSE, NULL);
186 QString preview = QString(PREVIEW_CAPS).arg(size.width()).arg(size.height());
188 GstCaps *caps = gst_caps_from_string(preview.toLatin1());
190 g_object_set(dev->cameraBin, "preview-caps", caps, "post-previews", TRUE, NULL);
192 gst_caps_unref(caps);
196 void setFileName(const QString& file) {
200 void setTempFileName(const QString& file) {
204 void enableViewfinderFilters() {
205 if (dev->viewfinderFilters) {
206 dev->viewfinderFilters->setBlocked(false);
210 void disableViewfinderFilters() {
211 if (dev->viewfinderFilters) {
212 dev->viewfinderFilters->setBlocked(true);
218 QtCamDevicePrivate *dev;
219 PreviewImageHandler *previewImageHandler;
220 DoneHandler *doneHandler;
222 QString tempFileName;
225 class DoneHandler : public QtCamGStreamerMessageHandler {
227 DoneHandler(QtCamModePrivate *m, const char *done, QObject *parent = 0) :
228 QtCamGStreamerMessageHandler(done, parent) {
232 virtual ~DoneHandler() { }
234 virtual void handleMessage(GstMessage *message) {
235 // If we have a temp file then we rename it:
236 if (!mode->tempFileName.isEmpty() && !mode->fileName.isEmpty()) {
237 if (!QFile::rename(mode->tempFileName, mode->fileName)) {
238 qCritical() << "Failed to rename" << mode->tempFileName << "to" << mode->fileName;
243 const GstStructure *s = gst_message_get_structure(message);
244 if (gst_structure_has_field(s, "filename")) {
245 const char *str = gst_structure_get_string(s, "filename");
247 fileName = QString::fromUtf8(str);
251 if (fileName.isEmpty()) {
252 fileName = mode->fileName;
255 QMetaObject::invokeMethod(mode->q_ptr, "saved", Qt::QueuedConnection,
256 Q_ARG(QString, fileName));
259 QtCamModePrivate *mode;
262 #endif /* QT_CAM_MODE_P_H */