1 | /* This file is part of the KDE project.
|
---|
2 |
|
---|
3 | Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
---|
4 |
|
---|
5 | This library is free software: you can redistribute it and/or modify
|
---|
6 | it under the terms of the GNU Lesser General Public License as published by
|
---|
7 | the Free Software Foundation, either version 2.1 or 3 of the License.
|
---|
8 |
|
---|
9 | This library 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 Lesser 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 library. If not, see <http://www.gnu.org/licenses/>.
|
---|
16 | */
|
---|
17 |
|
---|
18 | #include "effect.h"
|
---|
19 | #include "common.h"
|
---|
20 | #include "audiooutput.h"
|
---|
21 | #include "backend.h"
|
---|
22 | #include "medianode.h"
|
---|
23 | #include "effectmanager.h"
|
---|
24 | #include "gsthelper.h"
|
---|
25 |
|
---|
26 | #include <gst/gst.h>
|
---|
27 |
|
---|
28 | #ifndef QT_NO_PHONON_EFFECT
|
---|
29 | QT_BEGIN_NAMESPACE
|
---|
30 | namespace Phonon
|
---|
31 | {
|
---|
32 | namespace Gstreamer
|
---|
33 | {
|
---|
34 | Effect::Effect(Backend *backend, QObject *parent, NodeDescription description)
|
---|
35 | : QObject(parent),
|
---|
36 | MediaNode(backend, description)
|
---|
37 | , m_effectBin(0)
|
---|
38 | , m_effectElement(0)
|
---|
39 | {
|
---|
40 | }
|
---|
41 |
|
---|
42 | void Effect::init()
|
---|
43 | {
|
---|
44 | m_effectBin = createEffectBin();
|
---|
45 | if (m_effectBin) {
|
---|
46 | setupEffectParams();
|
---|
47 | gst_object_ref (GST_OBJECT (m_effectBin)); // Take ownership
|
---|
48 | gst_object_sink (GST_OBJECT (m_effectBin));
|
---|
49 | m_isValid = true;
|
---|
50 | }
|
---|
51 | }
|
---|
52 |
|
---|
53 | Effect::~Effect()
|
---|
54 | {
|
---|
55 | if (m_effectBin) {
|
---|
56 | gst_element_set_state (m_effectBin, GST_STATE_NULL);
|
---|
57 | gst_object_unref (m_effectBin);
|
---|
58 | }
|
---|
59 | }
|
---|
60 |
|
---|
61 | void Effect::setupEffectParams()
|
---|
62 | {
|
---|
63 |
|
---|
64 | Q_ASSERT(m_effectElement);
|
---|
65 |
|
---|
66 | //query and store parameters
|
---|
67 | if (m_effectElement) {
|
---|
68 | GParamSpec **property_specs;
|
---|
69 | guint propertyCount, i;
|
---|
70 | property_specs = g_object_class_list_properties(G_OBJECT_GET_CLASS (m_effectElement), &propertyCount);
|
---|
71 | for (i = 0; i < propertyCount; i++) {
|
---|
72 | GParamSpec *param = property_specs[i];
|
---|
73 | if (param->flags & G_PARAM_WRITABLE) {
|
---|
74 | QString propertyName = g_param_spec_get_name (param);
|
---|
75 |
|
---|
76 | // These properties should not be exposed to the front-end
|
---|
77 | if (propertyName == "qos" || propertyName == "name" || propertyName == "async-handling")
|
---|
78 | continue;
|
---|
79 |
|
---|
80 | switch(param->value_type) {
|
---|
81 | case G_TYPE_UINT:
|
---|
82 | m_parameterList.append(Phonon::EffectParameter(i, propertyName,
|
---|
83 | 0, //hints
|
---|
84 | G_PARAM_SPEC_UINT(param)->default_value,
|
---|
85 | G_PARAM_SPEC_UINT(param)->minimum,
|
---|
86 | G_PARAM_SPEC_UINT(param)->maximum));
|
---|
87 | break;
|
---|
88 |
|
---|
89 | case G_TYPE_STRING:
|
---|
90 | m_parameterList.append(Phonon::EffectParameter(i, propertyName,
|
---|
91 | 0, //hints
|
---|
92 | G_PARAM_SPEC_STRING(param)->default_value,
|
---|
93 | 0,
|
---|
94 | 0));
|
---|
95 | break;
|
---|
96 |
|
---|
97 | case G_TYPE_INT:
|
---|
98 | m_parameterList.append(Phonon::EffectParameter(i, propertyName,
|
---|
99 | EffectParameter::IntegerHint, //hints
|
---|
100 | QVariant(G_PARAM_SPEC_INT(param)->default_value),
|
---|
101 | QVariant(G_PARAM_SPEC_INT(param)->minimum),
|
---|
102 | QVariant(G_PARAM_SPEC_INT(param)->maximum)));
|
---|
103 | break;
|
---|
104 |
|
---|
105 | case G_TYPE_FLOAT:
|
---|
106 | m_parameterList.append(Phonon::EffectParameter(i, propertyName,
|
---|
107 | 0, //hints
|
---|
108 | QVariant((double)G_PARAM_SPEC_FLOAT(param)->default_value),
|
---|
109 | QVariant((double)G_PARAM_SPEC_FLOAT(param)->minimum),
|
---|
110 | QVariant((double)G_PARAM_SPEC_FLOAT(param)->maximum)));
|
---|
111 | break;
|
---|
112 |
|
---|
113 | case G_TYPE_DOUBLE:
|
---|
114 | m_parameterList.append(Phonon::EffectParameter(i, propertyName,
|
---|
115 | 0, //hints
|
---|
116 | QVariant(G_PARAM_SPEC_DOUBLE(param)->default_value),
|
---|
117 | QVariant(G_PARAM_SPEC_DOUBLE(param)->minimum),
|
---|
118 | QVariant(G_PARAM_SPEC_DOUBLE(param)->maximum)));
|
---|
119 | break;
|
---|
120 |
|
---|
121 | case G_TYPE_BOOLEAN:
|
---|
122 | m_parameterList.append(Phonon::EffectParameter(i, propertyName,
|
---|
123 | Phonon::EffectParameter::ToggledHint, //hints
|
---|
124 | QVariant((bool)G_PARAM_SPEC_BOOLEAN(param)->default_value),
|
---|
125 | QVariant((bool)false), QVariant((bool)true)));
|
---|
126 | break;
|
---|
127 |
|
---|
128 | default:
|
---|
129 | break;
|
---|
130 | }
|
---|
131 | }
|
---|
132 | }
|
---|
133 | }
|
---|
134 | }
|
---|
135 |
|
---|
136 | QList<Phonon::EffectParameter> Effect::parameters() const
|
---|
137 | {
|
---|
138 | return m_parameterList;
|
---|
139 | }
|
---|
140 |
|
---|
141 | QVariant Effect::parameterValue(const EffectParameter &p) const
|
---|
142 | {
|
---|
143 |
|
---|
144 | Q_ASSERT(m_effectElement);
|
---|
145 |
|
---|
146 | QVariant returnVal;
|
---|
147 | switch (p.type()) {
|
---|
148 | case QVariant::Int:
|
---|
149 | {
|
---|
150 | gint val = 0;
|
---|
151 | g_object_get(G_OBJECT(m_effectElement), qPrintable(p.name()), &val, (const char*)NULL);
|
---|
152 | returnVal = val;
|
---|
153 | }
|
---|
154 | break;
|
---|
155 |
|
---|
156 | case QVariant::Bool:
|
---|
157 | {
|
---|
158 | gboolean val = 0;
|
---|
159 | g_object_get(G_OBJECT(m_effectElement), qPrintable(p.name()), &val, (const char*)NULL);
|
---|
160 | returnVal = val;
|
---|
161 | }
|
---|
162 | break;
|
---|
163 |
|
---|
164 | case QVariant::String:
|
---|
165 | {
|
---|
166 | gchar *val = 0;
|
---|
167 | g_object_get(G_OBJECT(m_effectElement), qPrintable(p.name()), &val, (const char*)NULL);
|
---|
168 | returnVal = QString::fromUtf8(val);
|
---|
169 | g_free(val);
|
---|
170 | }
|
---|
171 | break;
|
---|
172 |
|
---|
173 | case QVariant::Double:
|
---|
174 | {
|
---|
175 | GParamSpec* spec = g_object_class_find_property(G_OBJECT_GET_CLASS(m_effectElement), p.name().toLatin1().constData());
|
---|
176 | Q_ASSERT(spec);
|
---|
177 | if (spec && spec->value_type == G_TYPE_FLOAT) {
|
---|
178 | gfloat val = 0;
|
---|
179 | g_object_get(G_OBJECT(m_effectElement), qPrintable(p.name()), &val, (const char*)NULL);
|
---|
180 | returnVal = QVariant((float)val);
|
---|
181 | } else {
|
---|
182 | gdouble val = 0;
|
---|
183 | g_object_get(G_OBJECT(m_effectElement), qPrintable(p.name()), &val, (const char*)NULL);
|
---|
184 | returnVal = QVariant((float)val);
|
---|
185 | }
|
---|
186 | }
|
---|
187 | break;
|
---|
188 |
|
---|
189 | default:
|
---|
190 | Q_ASSERT(0); //not a supported variant type
|
---|
191 | }
|
---|
192 | return returnVal;
|
---|
193 | }
|
---|
194 |
|
---|
195 |
|
---|
196 | void Effect::setParameterValue(const EffectParameter &p, const QVariant &v)
|
---|
197 | {
|
---|
198 | Q_ASSERT(m_effectElement);
|
---|
199 |
|
---|
200 | // Note that the frontend currently calls this after creation with a null-value
|
---|
201 | // for all parameters.
|
---|
202 |
|
---|
203 | if (v.isValid()) {
|
---|
204 |
|
---|
205 | switch (p.type()) {
|
---|
206 | // ### range values should really be checked by the front end, why isnt it working?
|
---|
207 | case QVariant::Int:
|
---|
208 | if (v.toInt() >= p.minimumValue().toInt() && v.toInt() <= p.maximumValue().toInt())
|
---|
209 | g_object_set(G_OBJECT(m_effectElement), qPrintable(p.name()), (gint)v.toInt(), (const char*)NULL);
|
---|
|
---|