Add 'caps' property on Track
[platform/upstream/gstreamer.git] / ges / ges-track-object.c
1 /* GStreamer Editing Services
2  * Copyright (C) 2009 Edward Hervey <bilboed@bilboed.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
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 GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #include "ges-internal.h"
21 #include "ges-track-object.h"
22 #include "ges-timeline-object.h"
23
24 static GQuark _start_quark;
25 static GQuark _inpoint_quark;
26 static GQuark _duration_quark;
27 static GQuark _priority_quark;
28
29 #define _do_init \
30 { \
31   _start_quark = g_quark_from_static_string ("start"); \
32   _inpoint_quark = g_quark_from_static_string ("inpoint"); \
33   _duration_quark = g_quark_from_static_string ("duration"); \
34   _priority_quark = g_quark_from_static_string ("priority"); \
35 }
36
37 G_DEFINE_TYPE_WITH_CODE (GESTrackObject, ges_track_object, G_TYPE_OBJECT,
38     _do_init);
39
40 enum
41 {
42   PROP_0,
43   PROP_START,
44   PROP_INPOINT,
45   PROP_DURATION,
46   PROP_PRIORITY,
47 };
48
49 static gboolean
50 ges_track_object_create_gnl_object_func (GESTrackObject * object);
51
52 static void
53 ges_track_object_get_property (GObject * object, guint property_id,
54     GValue * value, GParamSpec * pspec)
55 {
56   GESTrackObject *tobj = GES_TRACK_OBJECT (object);
57
58   switch (property_id) {
59     case PROP_START:
60       g_value_set_uint64 (value, tobj->start);
61       break;
62     case PROP_INPOINT:
63       g_value_set_uint64 (value, tobj->inpoint);
64       break;
65     case PROP_DURATION:
66       g_value_set_uint64 (value, tobj->duration);
67       break;
68     case PROP_PRIORITY:
69       g_value_set_uint (value, tobj->priority);
70       break;
71     default:
72       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
73   }
74 }
75
76 static void
77 ges_track_object_set_property (GObject * object, guint property_id,
78     const GValue * value, GParamSpec * pspec)
79 {
80   GESTrackObject *tobj = GES_TRACK_OBJECT (object);
81
82   switch (property_id) {
83     case PROP_START:
84       ges_track_object_set_start_internal (tobj, g_value_get_uint64 (value));
85       break;
86     case PROP_INPOINT:
87       ges_track_object_set_inpoint_internal (tobj, g_value_get_uint64 (value));
88       break;
89     case PROP_DURATION:
90       ges_track_object_set_duration_internal (tobj, g_value_get_uint64 (value));
91       break;
92     case PROP_PRIORITY:
93       ges_track_object_set_priority_internal (tobj, g_value_get_uint (value));
94       break;
95     default:
96       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
97   }
98 }
99
100 static void
101 ges_track_object_dispose (GObject * object)
102 {
103   G_OBJECT_CLASS (ges_track_object_parent_class)->dispose (object);
104 }
105
106 static void
107 ges_track_object_finalize (GObject * object)
108 {
109   G_OBJECT_CLASS (ges_track_object_parent_class)->finalize (object);
110 }
111
112 static void
113 ges_track_object_class_init (GESTrackObjectClass * klass)
114 {
115   GObjectClass *object_class = G_OBJECT_CLASS (klass);
116
117   object_class->get_property = ges_track_object_get_property;
118   object_class->set_property = ges_track_object_set_property;
119   object_class->dispose = ges_track_object_dispose;
120   object_class->finalize = ges_track_object_finalize;
121
122   g_object_class_install_property (object_class, PROP_START,
123       g_param_spec_uint64 ("start", "Start",
124           "The position in the container", 0, G_MAXUINT64, 0,
125           G_PARAM_READWRITE));
126   g_object_class_install_property (object_class, PROP_INPOINT,
127       g_param_spec_uint64 ("inpoint", "In-point", "The in-point", 0,
128           G_MAXUINT64, 0, G_PARAM_READWRITE));
129   g_object_class_install_property (object_class, PROP_DURATION,
130       g_param_spec_uint64 ("duration", "Duration", "The duration to use",
131           0, G_MAXUINT64, 0, G_PARAM_READWRITE));
132   g_object_class_install_property (object_class, PROP_PRIORITY,
133       g_param_spec_uint ("priority", "Priority",
134           "The priority of the object", 0, G_MAXUINT, 0, G_PARAM_READWRITE));
135
136   klass->create_gnl_object = ges_track_object_create_gnl_object_func;
137 }
138
139 static void
140 ges_track_object_init (GESTrackObject * self)
141 {
142 }
143
144 GESTrackObject *
145 ges_track_object_new (GESTimelineObject * timelineobj, GESTrack * track)
146 {
147   GESTrackObject *obj;
148
149   obj = g_object_new (GES_TYPE_TRACK_OBJECT, NULL);
150
151   /* FIXME : THIS IS TOTALLY BOGUS ! */
152
153   /* Set the timeline object and track */
154   obj->timelineobj = timelineobj;
155   obj->track = track;
156
157
158   return obj;
159 }
160
161 gboolean
162 ges_track_object_set_start_internal (GESTrackObject * object, guint64 start)
163 {
164   g_return_val_if_fail (object->gnlobject, FALSE);
165
166   if (G_UNLIKELY (start == object->start))
167     return FALSE;
168
169   g_object_set (object->gnlobject, "start", start, NULL);
170   return TRUE;
171 };
172
173 gboolean
174 ges_track_object_set_inpoint_internal (GESTrackObject * object, guint64 inpoint)
175 {
176   guint64 dur;
177
178   g_return_val_if_fail (object->gnlobject, FALSE);
179
180   if (G_UNLIKELY (inpoint == object->inpoint))
181     return FALSE;
182
183   /* Calculate new media-start/duration/media-duration */
184   dur = object->inpoint - inpoint + object->duration;
185
186   g_object_set (object->gnlobject, "media-start", inpoint, "duration", dur,
187       "media-duration", dur, NULL);
188   return TRUE;
189 }
190
191 gboolean
192 ges_track_object_set_duration_internal (GESTrackObject * object,
193     guint64 duration)
194 {
195   g_return_val_if_fail (object->gnlobject, FALSE);
196
197   if (G_UNLIKELY (duration == object->duration))
198     return FALSE;
199
200   g_object_set (object->gnlobject, "duration", duration, "media-duration",
201       duration, NULL);
202   return TRUE;
203 }
204
205 gboolean
206 ges_track_object_set_priority_internal (GESTrackObject * object,
207     guint32 priority)
208 {
209   g_return_val_if_fail (object->gnlobject, FALSE);
210
211   if (G_UNLIKELY (priority == object->priority))
212     return FALSE;
213
214   g_object_set (object->gnlobject, "priority", priority, NULL);
215   return TRUE;
216 }
217
218 /* default 'create_gnl_object' virtual method implementation */
219 static gboolean
220 ges_track_object_create_gnl_object_func (GESTrackObject * object)
221 {
222
223   return FALSE;
224 }
225
226 static gboolean
227 ensure_gnl_object (GESTrackObject * object)
228 {
229   GESTrackObjectClass *class;
230   gboolean res;
231
232   if (object->gnlobject && object->valid)
233     return TRUE;
234
235   /* 1. Create the GnlObject */
236   GST_DEBUG ("Creating GnlObject");
237
238   class = GES_TRACK_OBJECT_GET_CLASS (object);
239
240   if (G_UNLIKELY (class->create_gnl_object == NULL)) {
241     GST_ERROR ("No 'create_gnl_object' implementation !");
242     return FALSE;
243   }
244
245   GST_DEBUG ("Calling virtual method");
246
247   /* call the create_gnl_object virtual method */
248   res = class->create_gnl_object (object);
249
250   if (G_UNLIKELY (res && (object->gnlobject == NULL))) {
251     GST_ERROR
252         ("'create_gnl_object' implementation returned TRUE but no GnlObject is available");
253     return FALSE;
254   }
255
256   /* 2. Fill in the GnlObject */
257   if (res) {
258     GST_DEBUG ("Got a valid GnlObject, now filling it in");
259
260     res =
261         ges_timeline_object_fill_track_object (object->timelineobj, object,
262         object->gnlobject);
263     if (res) {
264       /* Set some properties on the GnlObject */
265       g_object_set (object->gnlobject, "caps", object->track->caps, NULL);
266     }
267   }
268
269   object->valid = res;
270
271   GST_DEBUG ("Returning res:%d", res);
272
273   return res;
274 }
275
276 gboolean
277 ges_track_object_set_track (GESTrackObject * object, GESTrack * track)
278 {
279   GST_DEBUG ("object:%p, track:%p", object, track);
280
281   object->track = track;
282
283   if (object->track)
284     return ensure_gnl_object (object);
285
286   return TRUE;
287 }
288
289 void
290 ges_track_object_set_timeline_object (GESTrackObject * object,
291     GESTimelineObject * tlobj)
292 {
293   GST_DEBUG ("object:%p, timeline-object:%p", object, tlobj);
294
295   object->timelineobj = tlobj;
296 }