Relicense gst-libs/ code to LGPL v2.1+.
[platform/upstream/gstreamer-vaapi.git] / gst-libs / gst / vaapi / gstvaapiobject.c
1 /*
2  *  gstvaapiobject.c - Base VA object
3  *
4  *  gstreamer-vaapi (C) 2010 Splitted-Desktop Systems
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Lesser General Public License
8  *  as published by the Free Software Foundation; either version 2.1
9  *  of the License, or (at your option) any later version.
10  *
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.
15  *
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
18  *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  *  Boston, MA 02110-1301 USA
20  */
21
22 /**
23  * SECTION:gstvaapiobject
24  * @short_description: Base VA object
25  */
26
27 #include "config.h"
28 #include "gstvaapiobject.h"
29 #include "gstvaapi_priv.h"
30 #include "gstvaapiparamspecs.h"
31 #include "gstvaapivalue.h"
32 #include "gstvaapimarshal.h"
33
34 #define DEBUG 1
35 #include "gstvaapidebug.h"
36
37 G_DEFINE_TYPE(GstVaapiObject, gst_vaapi_object, G_TYPE_OBJECT);
38
39 enum {
40     PROP_0,
41
42     PROP_DISPLAY,
43     PROP_ID
44 };
45
46 enum {
47     DESTROY,
48
49     LAST_SIGNAL
50 };
51
52 static guint object_signals[LAST_SIGNAL] = { 0, };
53
54 static void
55 gst_vaapi_object_dispose(GObject *object)
56 {
57     GstVaapiObjectPrivate * const priv = GST_VAAPI_OBJECT(object)->priv;
58
59     if (!priv->is_destroying) {
60         priv->is_destroying = TRUE;
61         g_signal_emit(object, object_signals[DESTROY], 0);
62         priv->is_destroying = FALSE;
63     }
64
65     G_OBJECT_CLASS(gst_vaapi_object_parent_class)->dispose(object);
66 }
67
68 static void
69 gst_vaapi_object_finalize(GObject *object)
70 {
71     GstVaapiObjectPrivate * const priv = GST_VAAPI_OBJECT(object)->priv;
72
73     priv->id = GST_VAAPI_ID_NONE;
74
75     if (priv->display) {
76         g_object_unref(priv->display);
77         priv->display = NULL;
78     }
79
80     G_OBJECT_CLASS(gst_vaapi_object_parent_class)->finalize(object);
81 }
82
83 static void
84 gst_vaapi_object_set_property(
85     GObject      *gobject,
86     guint         prop_id,
87     const GValue *value,
88     GParamSpec   *pspec
89 )
90 {
91     GstVaapiObject * const object = GST_VAAPI_OBJECT(gobject);
92
93     switch (prop_id) {
94     case PROP_DISPLAY:
95         object->priv->display = g_object_ref(g_value_get_object(value));
96         break;
97     case PROP_ID:
98         object->priv->id = gst_vaapi_value_get_id(value);
99         break;
100     default:
101         G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
102         break;
103     }
104 }
105
106 static void
107 gst_vaapi_object_get_property(
108     GObject    *gobject,
109     guint       prop_id,
110     GValue     *value,
111     GParamSpec *pspec
112 )
113 {
114     GstVaapiObject * const object = GST_VAAPI_OBJECT(gobject);
115
116     switch (prop_id) {
117     case PROP_DISPLAY:
118         g_value_set_object(value, gst_vaapi_object_get_display(object));
119         break;
120     case PROP_ID:
121         gst_vaapi_value_set_id(value, gst_vaapi_object_get_id(object));
122         break;
123     default:
124         G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
125         break;
126     }
127 }
128
129 static void
130 gst_vaapi_object_class_init(GstVaapiObjectClass *klass)
131 {
132     GObjectClass * const object_class = G_OBJECT_CLASS(klass);
133
134     g_type_class_add_private(klass, sizeof(GstVaapiObjectPrivate));
135
136     object_class->dispose      = gst_vaapi_object_dispose;
137     object_class->finalize     = gst_vaapi_object_finalize;
138     object_class->set_property = gst_vaapi_object_set_property;
139     object_class->get_property = gst_vaapi_object_get_property;
140
141     /**
142      * GstVaapiObject:display:
143      *
144      * The #GstVaapiDisplay this object is bound to.
145      */
146     g_object_class_install_property
147         (object_class,
148          PROP_DISPLAY,
149          g_param_spec_object("display",
150                              "Display",
151                              "The GstVaapiDisplay this object is bound to",
152                              GST_VAAPI_TYPE_DISPLAY,
153                              G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
154
155     /**
156      * GstVaapiObject:id:
157      *
158      * The #GstVaapiID contained in this object.
159      */
160     g_object_class_install_property
161         (object_class,
162          PROP_ID,
163          gst_vaapi_param_spec_id("id",
164                                  "ID",
165                                  "The GstVaapiID contained in this object",
166                                  GST_VAAPI_ID_NONE,
167                                  G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
168
169     /**
170      * GstVaapiObject::destroy:
171      * @object: the object which received the signal
172      *
173      * The ::destroy signal is emitted when an object is destroyed,
174      * when the user released the last reference to @object.
175      */
176     object_signals[DESTROY] = g_signal_new(
177         "destroy",
178         G_TYPE_FROM_CLASS(object_class),
179         G_SIGNAL_RUN_CLEANUP | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
180         G_STRUCT_OFFSET(GstVaapiObjectClass, destroy),
181         NULL, NULL,
182         gst_vaapi_marshal_VOID__VOID,
183         G_TYPE_NONE, 0
184     );
185 }
186
187 static void
188 gst_vaapi_object_init(GstVaapiObject *object)
189 {
190     GstVaapiObjectPrivate *priv = GST_VAAPI_OBJECT_GET_PRIVATE(object);
191
192     object->priv        = priv;
193     priv->display       = NULL;
194     priv->id            = GST_VAAPI_ID_NONE;
195     priv->is_destroying = FALSE;
196 }
197
198 /**
199  * gst_vaapi_object_get_display:
200  * @object: a #GstVaapiObject
201  *
202  * Returns the #GstVaapiDisplay this @object is bound to.
203  *
204  * Return value: the parent #GstVaapiDisplay object
205  */
206 GstVaapiDisplay *
207 gst_vaapi_object_get_display(GstVaapiObject *object)
208 {
209     g_return_val_if_fail(GST_VAAPI_IS_OBJECT(object), NULL);
210
211     return object->priv->display;
212 }
213
214 /**
215  * gst_vaapi_object_lock_display:
216  * @object: a #GstVaapiObject
217  *
218  * Locks @object parent display. If display is already locked by
219  * another thread, the current thread will block until display is
220  * unlocked by the other thread.
221  */
222 void
223 gst_vaapi_object_lock_display(GstVaapiObject *object)
224 {
225     g_return_if_fail(GST_VAAPI_IS_OBJECT(object));
226
227     GST_VAAPI_OBJECT_LOCK_DISPLAY(object);
228 }
229
230 /**
231  * gst_vaapi_object_unlock_display:
232  * @object: a #GstVaapiObject
233  *
234  * Unlocks @object parent display. If another thread is blocked in a
235  * gst_vaapi_object_lock_display() call, it will be woken and can lock
236  * display itself.
237  */
238 void
239 gst_vaapi_object_unlock_display(GstVaapiObject *object)
240 {
241     g_return_if_fail(GST_VAAPI_IS_OBJECT(object));
242
243     GST_VAAPI_OBJECT_UNLOCK_DISPLAY(object);
244 }
245
246 /**
247  * gst_vaapi_object_get_id:
248  * @object: a #GstVaapiObject
249  *
250  * Returns the #GstVaapiID contained in the @object.
251  *
252  * Return value: the #GstVaapiID of the @object
253  */
254 GstVaapiID
255 gst_vaapi_object_get_id(GstVaapiObject *object)
256 {
257     g_return_val_if_fail(GST_VAAPI_IS_OBJECT(object), GST_VAAPI_ID_NONE);
258
259     return object->priv->id;
260 }