Emit canCaptureChanged on the active mode when ready-for-capture changes
[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     GstElement *src, *wrapper;
47     QString wrapperSrc = conf->wrapperVideoSource();
48     QString prop = conf->wrapperVideoSourceProperty();
49
50     if (!prop.isEmpty() && !wrapperSrc.isEmpty()) {
51       wrapper = gst_element_factory_make(wrapperSrc.toAscii(), "QCameraWrapperVideoSrc");
52       if (!wrapper) {
53         qCritical() << "Failed to create wrapper source" << wrapperSrc;
54         return;
55       }
56     }
57
58     src = gst_element_factory_make(conf->videoSource().toAscii(),
59                                                "QtCameraVideoSrc");
60     if (!src) {
61       qCritical() << "Failed to create video source";
62       if (wrapper) {
63         gst_object_unref(wrapper);
64       }
65       return;
66     }
67
68     if (wrapper) {
69       g_object_set(wrapper, prop.toAscii(), src, NULL);
70       g_object_set(cameraBin, "camera-source", wrapper, NULL);
71     }
72
73     videoSource = src;
74     wrapperVideoSource = wrapper;
75
76     if (conf->deviceScannerType() == SCANNER_TYPE_ENUM) {
77       int dev = id.toInt();
78       g_object_set(src, conf->deviceScannerProperty().toAscii().data(), dev, NULL);
79     }
80     else {
81       QString dev = id.toString();
82       g_object_set(src, conf->deviceScannerProperty().toAscii().data(),
83                    dev.toAscii().data(), NULL);
84     }
85   }
86
87   bool setViewfinderSink() {
88     GstElement *sink;
89     g_object_get(cameraBin, "viewfinder-sink", &sink, NULL);
90
91     if (sink) {
92       gst_object_unref(sink);
93       return true;
94     }
95
96     sink = viewfinder->sinkElement();
97     if (!sink) {
98       qCritical() << "Failed to create GStreamer sink element";
99       return false;
100     }
101
102     g_object_set(cameraBin, "viewfinder-sink", sink, NULL);
103
104     return true;
105   }
106
107   void _d_error(const QString& message, int code, const QString& debug) {
108     error = true;
109
110     QMetaObject::invokeMethod(q_ptr, "error", Q_ARG(QString, message),
111                               Q_ARG(int, code), Q_ARG(QString, debug));
112   }
113
114   void _d_stopped() {
115     QMetaObject::invokeMethod(q_ptr, "stopped");
116   }
117
118   void _d_stopping() {
119     if (active) {
120       QMetaObject::invokeMethod(active, "canCaptureChanged", Qt::QueuedConnection);
121     }
122
123     QMetaObject::invokeMethod(q_ptr, "stopping", Qt::QueuedConnection);
124     QMetaObject::invokeMethod(q_ptr, "runningStateChanged", Qt::QueuedConnection,
125                               Q_ARG(bool, false));
126   }
127
128   void _d_started() {
129     if (active) {
130       QMetaObject::invokeMethod(active, "canCaptureChanged", Qt::QueuedConnection);
131     }
132
133     QMetaObject::invokeMethod(q_ptr, "started", Qt::QueuedConnection);
134     QMetaObject::invokeMethod(q_ptr, "runningStateChanged", Qt::QueuedConnection,
135                               Q_ARG(bool, true));
136   }
137
138   void setAudioCaptureCaps() {
139     QString captureCaps = conf->audioCaptureCaps();
140     if (!captureCaps.isEmpty()) {
141       GstCaps *caps = gst_caps_from_string(captureCaps.toAscii().data());
142       if (caps) {
143         g_object_set(cameraBin, "audio-capture-caps", caps, NULL);
144         gst_caps_unref(caps);
145       }
146     }
147   }
148
149   bool isWrapperReady() {
150     if (!wrapperVideoSource) {
151       return false;
152     }
153
154     gboolean ready = FALSE;
155     g_object_get(wrapperVideoSource, "ready-for-capture", &ready, NULL);
156
157     return ready == TRUE;
158   }
159
160   static void on_ready_for_capture_changed(GObject *obj, GParamSpec *pspec,
161                                            QtCamDevicePrivate *d)  {
162     Q_UNUSED(obj);
163     Q_UNUSED(pspec);
164
165     if (!d->active) {
166       return;
167     }
168
169     QMetaObject::invokeMethod(d->active, "canCaptureChanged", Qt::QueuedConnection);
170   }
171
172   static void on_idle_changed(GObject *obj, GParamSpec *pspec, QtCamDevicePrivate *d) {
173     Q_UNUSED(obj);
174     Q_UNUSED(pspec);
175
176     QMetaObject::invokeMethod(d->q_ptr, "idleStateChanged", Qt::QueuedConnection,
177                               Q_ARG(bool, d->q_ptr->isIdle()));
178   }
179
180   QString name;
181   QVariant id;
182
183   QtCamDevice *q_ptr;
184
185   GstElement *cameraBin;
186   GstElement *videoSource;
187   GstElement *wrapperVideoSource;
188
189   QtCamImageMode *image;
190   QtCamVideoMode *video;
191   QtCamMode *active;
192
193   QtCamViewfinder *viewfinder;
194   QtCamConfig *conf;
195   QtCamGStreamerMessageListener *listener;
196   bool error;
197 };
198
199 #endif /* QT_CAM_DEVICE_P_H */