Set media.name to '*'.
[harmattan/cameraplus] / lib / qtcammode_p.h
1 // -*- c++ -*-
2
3 /*!
4  * This file is part of CameraPlus.
5  *
6  * Copyright (C) 2012-2013 Mohammed Sameer <msameer@foolab.org>
7  *
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.
12  *
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.
17  *
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
21  */
22
23 #ifndef QT_CAM_MODE_P_H
24 #define QT_CAM_MODE_P_H
25
26 #include <QSize>
27 #include <QFileInfo>
28 #include <QDir>
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"
34
35 #ifndef GST_USE_UNSTABLE_API
36 #define GST_USE_UNSTABLE_API
37 #endif /* GST_USE_UNSTABLE_API */
38 #include <gst/interfaces/photography.h>
39
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"
41
42 class QtCamDevicePrivate;
43 class PreviewImageHandler;
44 class DoneHandler;
45
46 class QtCamModePrivate {
47 public:
48   QtCamModePrivate(QtCamDevicePrivate *d) : id(-1), dev(d) {}
49   virtual ~QtCamModePrivate() {}
50
51   void init(DoneHandler *handler) {
52     doneHandler = handler;
53   }
54
55   int modeId(const char *mode) {
56     if (!dev->cameraBin) {
57       return -1;
58     }
59
60     GParamSpec *pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(dev->cameraBin),
61                                                      "mode");
62     if (!pspec) {
63       return -1;
64     }
65
66     if (!G_IS_PARAM_SPEC_ENUM(pspec)) {
67       return -1;
68     }
69
70     GParamSpecEnum *e = G_PARAM_SPEC_ENUM(pspec);
71     GEnumClass *klass = e->enum_class;
72
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;
76       }
77     }
78
79     return -1;
80   }
81
82   GstEncodingProfile *loadProfile(const QString& path, const QString& name) {
83     GError *error = NULL;
84     QString targetPath;
85     QFileInfo info(path);
86     if (!info.isAbsolute()) {
87       targetPath = QDir(DATA_DIR).absoluteFilePath(path);
88     }
89     else {
90       targetPath = info.filePath();
91     }
92
93     GstEncodingTarget *target = gst_encoding_target_load_from_file(targetPath.toUtf8().constData(),
94                                                                    &error);
95     if (!target) {
96       qCritical() << "Failed to load encoding target from" << path << error->message;
97       g_error_free(error);
98       return 0;
99     }
100
101     GstEncodingProfile *profile = gst_encoding_target_get_profile(target, name.toUtf8().data());
102     if (!profile) {
103       qCritical() << "Failed to load encoding profile from" << path;
104       gst_encoding_target_unref(target);
105       return 0;
106     }
107
108     gst_encoding_target_unref(target);
109
110     return profile;
111   }
112
113   void resetCaps(const char *property) {
114     if (!dev->cameraBin) {
115       return;
116     }
117
118     g_object_set(dev->cameraBin, property, NULL, NULL);
119   }
120
121   bool inNightMode() {
122     if (!dev->cameraBin) {
123       return false;
124     }
125
126     int val = 0;
127
128     g_object_get(dev->videoSource, "scene-mode", &val, NULL);
129
130     return val == GST_PHOTOGRAPHY_SCENE_MODE_NIGHT;
131   }
132
133   void setCaps(const char *property, const QSize& resolution, int fps) {
134     if (!dev->cameraBin) {
135       return;
136     }
137
138     if (resolution.width() <= 0 || resolution.height() <= 0) {
139       return;
140     }
141
142     GstCaps *caps = 0;
143
144     if (fps <= 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(),
148                                  NULL);
149     }
150     else {
151       caps = gst_caps_new_simple("video/x-raw-yuv",
152                                  "width", G_TYPE_INT, resolution.width(),
153                                  "height", G_TYPE_INT, resolution.height(),
154                                  "framerate",
155                                  GST_TYPE_FRACTION_RANGE, fps - 1, 1, fps + 1, 1,
156                                  NULL);
157     }
158
159     GstCaps *old = 0;
160
161     g_object_get(dev->cameraBin, property, &old, NULL);
162
163     if (gst_caps_is_equal(caps, old)) {
164       gst_caps_unref(old);
165       gst_caps_unref(caps);
166
167       return;
168     }
169
170     g_object_set(dev->cameraBin, property, caps, NULL);
171
172     if (old) {
173       gst_caps_unref(old);
174     }
175   }
176
177   void setPreviewSize(const QSize& size) {
178     if (!dev->cameraBin) {
179       return;
180     }
181
182     if (size.width() <= 0 && size.height() <= 0) {
183       g_object_set(dev->cameraBin, "preview-caps", NULL, "post-previews", FALSE, NULL);
184     }
185     else {
186       QString preview = QString(PREVIEW_CAPS).arg(size.width()).arg(size.height());
187
188       GstCaps *caps = gst_caps_from_string(preview.toLatin1());
189
190       if (!dev->conf->isPreviewSupported()) {
191         qWarning() << "Cannot set preview caps. Preview not supported";
192         gst_caps_unref(caps);
193         return;
194       }
195
196       g_object_set(dev->cameraBin, "preview-caps", caps, "post-previews", TRUE, NULL);
197
198       gst_caps_unref(caps);
199     }
200   }
201
202   void setFileName(const QString& file) {
203     fileName = file;
204   }
205
206   void setTempFileName(const QString& file) {
207     tempFileName = file;
208   }
209
210   void enableViewfinderFilters() {
211     if (dev->viewfinderFilters) {
212       dev->viewfinderFilters->setBlocked(false);
213     }
214   }
215
216   void disableViewfinderFilters() {
217     if (dev->viewfinderFilters) {
218       dev->viewfinderFilters->setBlocked(true);
219     }
220   }
221
222   int id;
223   QtCamMode *q_ptr;
224   QtCamDevicePrivate *dev;
225   PreviewImageHandler *previewImageHandler;
226   DoneHandler *doneHandler;
227   QString fileName;
228   QString tempFileName;
229 };
230
231 class DoneHandler : public QtCamGStreamerMessageHandler {
232 public:
233   DoneHandler(QtCamModePrivate *m, const char *done, QObject *parent = 0) :
234     QtCamGStreamerMessageHandler(done, parent) {
235     mode = m;
236   }
237
238   virtual ~DoneHandler() { }
239
240   virtual void handleMessage(GstMessage *message) {
241     // If we have a temp file then we rename it:
242     if (!mode->tempFileName.isEmpty() && !mode->fileName.isEmpty()) {
243       if (!QFile::rename(mode->tempFileName, mode->fileName)) {
244         qCritical() << "Failed to rename" << mode->tempFileName << "to" << mode->fileName;
245       }
246     }
247
248     QString fileName;
249     const GstStructure *s = gst_message_get_structure(message);
250     if (gst_structure_has_field(s, "filename")) {
251       const char *str = gst_structure_get_string(s, "filename");
252       if (str) {
253         fileName = QString::fromUtf8(str);
254       }
255     }
256
257     if (fileName.isEmpty()) {
258       fileName = mode->fileName;
259     }
260
261     QMetaObject::invokeMethod(mode->q_ptr, "saved", Qt::QueuedConnection,
262                               Q_ARG(QString, fileName));
263   }
264
265   QtCamModePrivate *mode;
266 };
267
268 #endif /* QT_CAM_MODE_P_H */