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:
70 void setProperties(GstElement *element) {
71 QLatin1String name = elementName(element);
76 QVariantMap map = properties(name);
81 QStringList keys = map.keys();
82 foreach (const QString& key, keys) {
83 QVariant value = map[key];
84 GParamSpec *pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(element),
85 key.toUtf8().constData());
87 qWarning() << "Property" << key << "not available for" << name;
91 GType type = getType(pspec->value_type);
96 setInt(element, key, value);
99 setUnsignedInt(element, key, value);
102 setString(element, key, value);
105 setBoolean(element, key, value);
108 if (type == gstFraction) {
109 setFraction(element, key, value);
113 qWarning() << "Unsupported property type"
114 << g_type_name(pspec->value_type) << "of parent" << g_type_name(type)
115 << "for" << key << "of element" << name;
121 QVariantMap properties(const QLatin1String& name) {
124 conf->beginGroup(name);
126 QStringList keys = conf->allKeys();
127 foreach (const QString& key, keys) {
128 map[key] = conf->value(key);
135 QLatin1String elementName(GstElement *elem) {
136 GstElementFactory *factory = gst_element_get_factory(elem);
138 return QLatin1String(0);
141 const char *n = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory));
143 return QLatin1String(0);
146 QLatin1String name(n);
151 void setInt(GstElement *elem, const QString& key, const QVariant& value) {
152 if (!value.canConvert(QVariant::Int)) {
153 qWarning() << "Cannot convert" << value << "to int";
157 g_object_set(elem, key.toUtf8().constData(), value.toInt(), NULL);
160 void setUnsignedInt(GstElement *elem, const QString& key, const QVariant& value) {
161 if (!value.canConvert(QVariant::UInt)) {
162 qWarning() << "Cannot convert" << value << "to unsigned int";
166 g_object_set(elem, key.toUtf8().constData(), value.toUInt(), NULL);
169 void setString(GstElement *elem, const QString& key, const QVariant& value) {
170 if (!value.canConvert(QVariant::String)) {
171 qWarning() << "Cannot convert" << value << "to string";
175 g_object_set(elem, key.toUtf8().constData(), value.toString().toUtf8().constData(), NULL);
178 void setBoolean(GstElement *elem, const QString& key, const QVariant& value) {
179 if (!value.canConvert(QVariant::Bool)) {
180 qWarning() << "Cannot convert" << value << "to bool";
184 g_object_set(elem, key.toUtf8().constData(), value.toBool() ? TRUE : FALSE, NULL);
187 void setFraction(GstElement *elem, const QString& key, const QVariant& value) {
188 if (!value.canConvert(QVariant::List)) {
189 qWarning() << "Cannot convert" << value << "to list";
193 QList<QVariant> list = value.toList();
194 if (list.size() != 2) {
195 qWarning() << "fraction list must contain 2 items";
199 if (!list[0].canConvert(QVariant::Int) || !list[1].canConvert(QVariant::Int)) {
200 qWarning() << "list items cannot be converted to int";
204 int val1 = list[0].toInt();
205 int val2 = list[1].toInt();
207 g_object_set(elem, key.toUtf8().constData(), val1, val2, NULL);
210 GType getType(GType parent) {
211 if (G_TYPE_IS_FUNDAMENTAL(parent)) {
215 return getType(g_type_parent(parent));
218 static void element_added(GstBin *bin, GstElement *child, gpointer user_data) {
221 QtCamPropertySetterPrivate *d = static_cast<QtCamPropertySetterPrivate *>(user_data);
223 if (GST_IS_BIN(child)) {
227 d->setProperties(child);
235 QtCamPropertySetter::QtCamPropertySetter(QtCamDevicePrivate *pvt) :
236 d_ptr(new QtCamPropertySetterPrivate) {
237 d_ptr->conf = new QSettings(PROPERTIES_FILE, QSettings::IniFormat);
238 d_ptr->gstFraction = GST_TYPE_FRACTION;
239 d_ptr->binAdded(pvt->cameraBin);
242 QtCamPropertySetter::~QtCamPropertySetter() {
243 delete d_ptr->conf; d_ptr->conf = 0;
244 delete d_ptr; d_ptr = 0;