Initial commit.
[qtgstreamer:qtgstreamer.git] / src / qgstobject.cpp
1 /*
2     Copyright (C) 2009  George Kiagiadakis <kiagiadakis.george@gmail.com>
3
4     This library is free software; you can redistribute it and/or modify
5     it under the terms of the GNU Lesser General Public License as published
6     by the Free Software Foundation; either version 2.1 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU Lesser General Public License
15     along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17 #include "qgstobject.h"
18 #include <QtCore/QtDebug>
19 #include <gst/gstobject.h>
20
21 namespace QtGstreamer {
22
23 QGstObject::QGstObject(GstObject *gstObject, QObject *parent)
24     : QObject(parent), m_object(NULL)
25 {
26     Q_ASSERT(gstObject);
27     m_object = gstObject;
28     if ( GST_OBJECT_IS_FLOATING(m_object) ) {
29         gst_object_ref(m_object);
30         gst_object_sink(m_object);
31     } else {
32         gst_object_ref(m_object);
33     }
34 }
35
36 QGstObject::~QGstObject()
37 {
38     gst_object_unref(m_object);
39 }
40
41 static GValue *gValueFromQVariant(const QVariant & variant, GType gType)
42 {
43     GValue *v = g_slice_new0(GValue);
44     g_value_init(v, gType);
45
46     switch (gType) {
47     case G_TYPE_BOOLEAN:
48         g_value_set_boolean(v, variant.value<gboolean>());
49         break;
50     case G_TYPE_CHAR:
51         g_value_set_char(v, variant.value<char>());
52         break;
53     // skip G_TYPE_BOXED
54     case G_TYPE_DOUBLE:
55         g_value_set_double(v, variant.value<gdouble>());
56         break;
57     // skip G_TYPE_ENUM
58     // skip G_TYPE_FLAGS
59     case G_TYPE_FLOAT:
60         g_value_set_float(v, variant.value<gfloat>());
61         break;
62     // skip G_TYPE_GTYPE
63     case G_TYPE_INT:
64         g_value_set_int(v, variant.value<gint>());
65         break;
66     case G_TYPE_INT64:
67         g_value_set_int64(v, variant.value<gint64>());
68         break;
69     case G_TYPE_LONG:
70         g_value_set_long(v, variant.value<glong>());
71         break;
72     // skip G_TYPE_OBJECT
73     // skip G_TYPE_PARAM
74     // skip G_TYPE_POINTER:
75     case G_TYPE_STRING:
76         g_value_set_string(v, variant.value<QString>().toLocal8Bit().constData());
77         break;
78     case G_TYPE_UCHAR:
79         g_value_set_uchar(v, variant.value<guchar>());
80         break;
81     case G_TYPE_UINT:
82         g_value_set_uint(v, variant.value<guint>());
83         break;
84     case G_TYPE_UINT64:
85         g_value_set_uint64(v, variant.value<guint64>());
86         break;
87     case G_TYPE_ULONG:
88         g_value_set_ulong(v, variant.value<gulong>());
89         break;
90     // skip custom types
91     default:
92         g_slice_free(GValue, v);
93         return 0;
94     }
95
96     return v;
97 }
98
99 static QVariant gValueToQVariant(GValue *gvalue)
100 {
101     switch(G_VALUE_TYPE(gvalue)) {
102     case G_TYPE_BOOLEAN:
103         return QVariant::fromValue<bool>(g_value_get_boolean(gvalue));
104     case G_TYPE_CHAR:
105         return QVariant::fromValue<char>(g_value_get_char(gvalue));
106     // skip G_TYPE_BOXED
107     case G_TYPE_DOUBLE:
108         return QVariant::fromValue<double>(g_value_get_double(gvalue));
109     // skip G_TYPE_ENUM
110     // skip G_TYPE_FLAGS
111     case G_TYPE_FLOAT:
112         return QVariant::fromValue<float>(g_value_get_float(gvalue));
113     // skip G_TYPE_GTYPE
114     case G_TYPE_INT:
115         return QVariant::fromValue<int>(g_value_get_int(gvalue));
116     case G_TYPE_INT64:
117         return QVariant::fromValue<qint64>(g_value_get_int64(gvalue));
118     case G_TYPE_LONG:
119         return QVariant::fromValue<long>(g_value_get_long(gvalue));
120     // skip G_TYPE_OBJECT
121     // skip G_TYPE_PARAM
122     // skip G_TYPE_POINTER:
123     case G_TYPE_STRING:
124         return QVariant(QByteArray(g_value_get_string(gvalue)));
125     case G_TYPE_UCHAR:
126         return QVariant::fromValue<uchar>(g_value_get_uchar(gvalue));
127     case G_TYPE_UINT:
128         return QVariant::fromValue<uint>(g_value_get_uint(gvalue));
129     case G_TYPE_UINT64:
130         return QVariant::fromValue<quint64>(g_value_get_uint64(gvalue));
131     case G_TYPE_ULONG:
132         return QVariant::fromValue<unsigned long>(g_value_get_ulong(gvalue));
133     // skip custom types
134     default:
135         return QVariant();
136     }
137 }
138
139 QVariant QGstObject::property(const char *name) const
140 {
141     GParamSpec *paramSpec = g_object_class_find_property(G_OBJECT_GET_CLASS(m_object), name);
142     if ( !paramSpec ) {
143         qWarning() << "No such property:" << name;
144         return QVariant();
145     }
146     g_param_spec_ref_sink(paramSpec);
147
148     GValue *gvalue = g_slice_new0(GValue);
149     g_value_init(gvalue, G_PARAM_SPEC_VALUE_TYPE(paramSpec));
150
151     g_object_get_property(G_OBJECT(m_object), name, gvalue);
152
153     QVariant result = gValueToQVariant(gvalue);
154     if ( !result.isValid() ) {
155         qWarning() << "Could not convert GValue to QVariant"
156                     << "for the property:" << name << ", using the GType:"
157                     << G_PARAM_SPEC_VALUE_TYPE(paramSpec);
158     }
159
160     g_slice_free(GValue, gvalue);
161     g_param_spec_unref(paramSpec);
162     return result;
163 }
164
165 void QGstObject::setProperty(const char *name, const QVariant & value)
166 {
167     if ( !value.isValid() ) {
168         qWarning() << "Invalid argument";
169         return;
170     }
171
172     GParamSpec *paramSpec = g_object_class_find_property(G_OBJECT_GET_CLASS(m_object), name);
173     if ( !paramSpec ) {
174         qWarning() << "No such property:" << name;
175         return;
176     }
177     g_param_spec_ref_sink(paramSpec);
178
179     GValue *gvalue = gValueFromQVariant(value, G_PARAM_SPEC_VALUE_TYPE(paramSpec));
180     if ( !gvalue ) {
181         qWarning() << "Could not convert QVariant (" << value << ") to GValue"
182                     << "for the property:" << name << ", using the GType:"
183                     << G_PARAM_SPEC_VALUE_TYPE(paramSpec);
184         g_param_spec_unref(paramSpec);
185         return;
186     }
187
188     g_object_set_property(G_OBJECT(m_object), name, gvalue);
189     g_slice_free(GValue, gvalue);
190     g_param_spec_unref(paramSpec);
191 }
192
193 }
194
195 #include "qgstobject.moc"