2 * This file is part of CameraPlus.
4 * Copyright (C) 2012-2013 Mohammed Sameer <msameer@foolab.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "qtcampropertysetter.h"
22 #include "qtcamdevice_p.h"
26 #define PROPERTIES_FILE DATA_DIR"/properties.ini"
28 class QtCamPropertySetterPrivate {
30 void binAdded(GstElement *bin) {
31 g_signal_connect(bin, "element-added",
32 G_CALLBACK(QtCamPropertySetterPrivate::element_added), this);
36 // Let's traverse its children:
37 GstIterator *iter = gst_bin_iterate_elements(GST_BIN(bin));
46 switch (gst_iterator_next(iter, (gpointer *)&elem)) {
48 if (GST_IS_BIN(elem)) {
55 gst_object_unref(elem);
58 case GST_ITERATOR_RESYNC:
59 gst_iterator_resync(iter);
62 case GST_ITERATOR_ERROR:
63 case GST_ITERATOR_DONE:
69 gst_iterator_free(iter);
72 void setProperties(GstElement *element) {
73 QLatin1String name = elementName(element);
78 QVariantMap map = properties(name);
83 QStringList keys = map.keys();
84 foreach (const QString& key, keys) {
85 QVariant value = map[key];
86 GParamSpec *pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(element),
87 key.toUtf8().constData());
89 qWarning() << "Property" << key << "not available for" << name;
93 GType type = getType(pspec->value_type);
98 setInt(element, key, value);
101 setUnsignedInt(element, key, value);
104 setString(element, key, value);
107 setBoolean(element, key, value);
110 if (type == gstFraction) {
111 setFraction(element, key, value);
115 qWarning() << "Unsupported property type"
116 << g_type_name(pspec->value_type) << "of parent" << g_type_name(type)
117 << "for" << key << "of element" << name;
123 QVariantMap properties(const QLatin1String& name) {
126 conf->beginGroup(name);
128 QStringList keys = conf->allKeys();
129 foreach (const QString& key, keys) {
130 map[key] = conf->value(key);
137 QLatin1String elementName(GstElement *elem) {
138 GstElementFactory *factory = gst_element_get_factory(elem);
140 return QLatin1String(0);
143 const char *n = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory));
145 return QLatin1String(0);
148 QLatin1String name(n);
153 void setInt(GstElement *elem, const QString& key, const QVariant& value) {
154 if (!value.canConvert(QVariant::Int)) {
155 qWarning() << "Cannot convert" << value << "to int";
159 g_object_set(elem, key.toUtf8().constData(), value.toInt(), NULL);
162 void setUnsignedInt(GstElement *elem, const QString& key, const QVariant& value) {
163 if (!value.canConvert(QVariant::UInt)) {
164 qWarning() << "Cannot convert" << value << "to unsigned int";
168 g_object_set(elem, key.toUtf8().constData(), value.toUInt(), NULL);
171 void setString(GstElement *elem, const QString& key, const QVariant& value) {
172 if (!value.canConvert(QVariant::String)) {
173 qWarning() << "Cannot convert" << value << "to string";
177 g_object_set(elem, key.toUtf8().constData(), value.toString().toUtf8().constData(), NULL);
180 void setBoolean(GstElement *elem, const QString& key, const QVariant& value) {
181 if (!value.canConvert(QVariant::Bool)) {
182 qWarning() << "Cannot convert" << value << "to bool";
186 g_object_set(elem, key.toUtf8().constData(), value.toBool() ? TRUE : FALSE, NULL);
189 void setFraction(GstElement *elem, const QString& key, const QVariant& value) {
190 if (!value.canConvert(QVariant::List)) {
191 qWarning() << "Cannot convert" << value << "to list";
195 QList<QVariant> list = value.toList();
196 if (list.size() != 2) {
197 qWarning() << "fraction list must contain 2 items";
201 if (!list[0].canConvert(QVariant::Int) || !list[1].canConvert(QVariant::Int)) {
202 qWarning() << "list items cannot be converted to int";
206 int val1 = list[0].toInt();
207 int val2 = list[1].toInt();
209 g_object_set(elem, key.toUtf8().constData(), val1, val2, NULL);
212 GType getType(GType parent) {
213 if (G_TYPE_IS_FUNDAMENTAL(parent)) {
217 return getType(g_type_parent(parent));
220 static void element_added(GstBin *bin, GstElement *child, gpointer user_data) {
223 QtCamPropertySetterPrivate *d = static_cast<QtCamPropertySetterPrivate *>(user_data);
225 if (GST_IS_BIN(child)) {
229 d->setProperties(child);
237 QtCamPropertySetter::QtCamPropertySetter(QtCamDevicePrivate *pvt) :
238 d_ptr(new QtCamPropertySetterPrivate) {
239 d_ptr->conf = new QSettings(PROPERTIES_FILE, QSettings::IniFormat);
240 d_ptr->gstFraction = GST_TYPE_FRACTION;
241 d_ptr->binAdded(pvt->cameraBin);
244 QtCamPropertySetter::~QtCamPropertySetter() {
245 delete d_ptr->conf; d_ptr->conf = 0;
246 delete d_ptr; d_ptr = 0;