Emit canCaptureChanged() for the active mode when we get an error
[harmattan/cameraplus] / lib / qtcamdevice_p.h
1 // -*- c++ -*-
2
3 #ifndef QT_CAM_DEVICE_P_H
4 #define QT_CAM_DEVICE_P_H
5
6 #include <QDebug>
7 #include <gst/gst.h>
8 #include "qtcamconfig.h"
9 #include "qtcamviewfinder.h"
10 #include "qtcamdevice.h"
11 #include "qtcammode.h"
12
13 class QtCamGStreamerMessageListener;
14 class QtCamMode;
15 class QtCamImageMode;
16 class QtCamVideoMode;
17
18 class QtCamDevicePrivate {
19 public:
20   QtCamDevicePrivate() :
21     cameraBin(0),
22     videoSource(0),
23     wrapperVideoSource(0),
24     image(0),
25     video(0),
26     active(0),
27     viewfinder(0),
28     conf(0),
29     error(false) {
30
31   }
32
33   GstElement *createAndAddElement(const QString& elementName, const char *prop, const char *name) {
34     GstElement *elem = gst_element_factory_make(elementName.toAscii(), name);
35     if (!elem) {
36       qWarning() << "Failed to create" << elementName;
37       return 0;
38     }
39
40     g_object_set(cameraBin, prop, elem, NULL);
41
42     return elem;
43   }
44
45   void createAndAddVideoSource() {
46     // TODO: rework this function
47     GstElement *src, *wrapper;
48     QString wrapperSrc = conf->wrapperVideoSource();
49     QString prop = conf->wrapperVideoSourceProperty();
50
51     if (!prop.isEmpty() && !wrapperSrc.isEmpty()) {
52       wrapper = gst_element_factory_make(wrapperSrc.toAscii(), "QCameraWrapperVideoSrc");
53       if (!wrapper) {
54         qCritical() << "Failed to create wrapper source" << wrapperSrc;
55         return;
56       }
57     }
58
59     src = gst_element_factory_make(conf->videoSource().toAscii(),
60                                                "QtCameraVideoSrc");
61     if (!src) {
62       qCritical() << "Failed to create video source";
63       if (wrapper) {
64         gst_object_unref(wrapper);
65       }
66       return;
67     }
68
69     if (wrapper) {
70       g_object_set(wrapper, prop.toAscii(), src, NULL);
71       g_object_set(cameraBin, "camera-source", wrapper, NULL);
72     }
73
74     videoSource = src;
75     wrapperVideoSource = wrapper;
76
77     if (!id.isValid() || id.isNull()) {
78       return;
79     }
80
81     if (conf->deviceScannerType() == SCANNER_TYPE_ENUM) {
82       int dev = id.toInt();
83       g_object_set(src, conf->deviceScannerProperty().toAscii().data(), dev, NULL);
84     }
85     else {
86       QString dev = id.toString();
87       g_object_set(src, conf->deviceScannerProperty().toAscii().data(),
88                    dev.toAscii().data(), NULL);
89     }
90   }
91
92   bool setViewfinderSink() {
93     GstElement *sink;
94     g_object_get(cameraBin, "viewfinder-sink", &sink, NULL);
95
96     if (sink) {
97       gst_object_unref(sink);
98       return true;
99     }
100
101     sink = viewfinder->sinkElement();
102     if (!sink) {
103       qCritical() << "Failed to create GStreamer sink element";
104       return false;
105     }
106
107     g_object_set(cameraBin, "viewfinder-sink", sink, NULL);
108
109     return true;
110   }
111
112   void _d_error(const QString& message, int code, const QString& debug) {
113     error = true;
114
115     QMetaObject::invokeMethod(q_ptr, "error", Q_ARG(QString, message),
116                               Q_ARG(int, code), Q_ARG(QString, debug));
117
118     if (active) {
119       QMetaObject::invokeMethod(active, "canCaptureChanged", Qt::QueuedConnection);
120     }
121   }
122
123   void _d_stopped() {
124     QMetaObject::invokeMethod(q_ptr, "stopped");
125   }
126
127   void _d_stopping() {
128     if (active) {
129       QMetaObject::invokeMethod(active, "canCaptureChanged", Qt::QueuedConnection);
130     }
131
132     QMetaObject::invokeMethod(q_ptr, "stopping", Qt::QueuedConnection);
133     QMetaObject::invokeMethod(q_ptr, "runningStateChanged", Qt::QueuedConnection,
134                               Q_ARG(bool, false));
135   }
136
137   void _d_started() {
138     if (active) {
139       QMetaObject::invokeMethod(active, "canCaptureChanged", Qt::QueuedConnection);
140     }
141
142     QMetaObject::invokeMethod(q_ptr, "started", Qt::QueuedConnection);
143     QMetaObject::invokeMethod(q_ptr, "runningStateChanged", Qt::QueuedConnection,
144                               Q_ARG(bool, true));
145   }
146
147   void setAudioCaptureCaps() {
148     QString captureCaps = conf->audioCaptureCaps();
149     if (!captureCaps.isEmpty()) {
150       GstCaps *caps = gst_caps_from_string(captureCaps.toAscii().data());
151       if (caps) {
152         g_object_set(cameraBin, "audio-capture-caps", caps, NULL);
153         gst_caps_unref(caps);
154       }
155     }
156   }
157
158   bool isWrapperReady() {
159     if (!wrapperVideoSource) {
160       return false;
161     }
162
163     gboolean ready = FALSE;
164     g_object_get(wrapperVideoSource, "ready-for-capture", &ready, NULL);
165
166     return ready == TRUE;
167   }
168
169   static void on_ready_for_capture_changed(GObject *obj, GParamSpec *pspec,
170                                            QtCamDevicePrivate *d)  {
171     Q_UNUSED(obj);
172     Q_UNUSED(pspec);
173
174     if (!d->active) {
175       return;
176     }
177
178     QMetaObject::invokeMethod(d->active, "canCaptureChanged", Qt::QueuedConnection);
179   }
180
181   static void on_idle_changed(GObject *obj, GParamSpec *pspec, QtCamDevicePrivate *d) {
182     Q_UNUSED(obj);
183     Q_UNUSED(pspec);
184
185     QMetaObject::invokeMethod(d->q_ptr, "idleStateChanged", Qt::QueuedConnection,
186                               Q_ARG(bool, d->q_ptr->isIdle()));
187   }
188
189 #if 0
190   void resetCapabilities() {
191     g_object_set(cameraBin, "zoom", 1.0, NULL);
192     g_object_set(videoSource, "flash-mode", 0, NULL);
193
194     // TODO: should scene mode be manual or automatic ?
195     g_object_set(videoSource, "scene-mode", 0, NULL);
196   }
197 #endif
198
199   QString name;
200   QVariant id;
201
202   QtCamDevice *q_ptr;
203
204   GstElement *cameraBin;
205   GstElement *videoSource;
206   GstElement *wrapperVideoSource;
207
208   QtCamImageMode *image;
209   QtCamVideoMode *video;
210   QtCamMode *active;
211
212   QtCamViewfinder *viewfinder;
213   QtCamConfig *conf;
214   QtCamGStreamerMessageListener *listener;
215   bool error;
216 };
217
218 #endif /* QT_CAM_DEVICE_P_H */