source: trunk/third/gstreamer/gst/gstevent.c @ 21448

Revision 21448, 10.7 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r21447, which included commits to RCS files with non-trunk default branches.
Line 
1/* GStreamer
2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 *                    2000 Wim Taymans <wim.taymans@chello.be>
4 *
5 * gstevent.c: GstEvent subsystem
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 */
22
23#include <string.h>             /* memcpy */
24
25#include "gst_private.h"
26#include "gstdata_private.h"
27
28#include "gstclock.h"
29#include "gstinfo.h"
30#include "gstmemchunk.h"
31#include "gstevent.h"
32#include "gsttag.h"
33
34#ifndef GST_DISABLE_TRACE
35/* #define GST_WITH_ALLOC_TRACE */
36#include "gsttrace.h"
37static GstAllocTrace *_event_trace;
38#endif
39
40static GstMemChunk *chunk;
41
42/* #define MEMPROF */
43
44GType _gst_event_type;
45
46void
47_gst_event_initialize (void)
48{
49  /* register the type */
50  _gst_event_type = g_boxed_type_register_static ("GstEvent",
51      (GBoxedCopyFunc) gst_data_copy, (GBoxedFreeFunc) gst_data_unref);
52
53#ifndef GST_DISABLE_TRACE
54  _event_trace = gst_alloc_trace_register (GST_EVENT_TRACE_NAME);
55#endif
56
57  chunk = gst_mem_chunk_new ("GstEventChunk", sizeof (GstEvent),
58      sizeof (GstEvent) * 50, 0);
59}
60
61static GstEvent *
62_gst_event_copy (GstEvent * event)
63{
64  GstEvent *copy;
65
66  copy = gst_mem_chunk_alloc (chunk);
67#ifndef GST_DISABLE_TRACE
68  gst_alloc_trace_new (_event_trace, copy);
69#endif
70
71  memcpy (copy, event, sizeof (GstEvent));
72  if (GST_EVENT_SRC (copy)) {
73    gst_object_ref (GST_EVENT_SRC (copy));
74  }
75
76  /* FIXME copy/ref additional fields */
77  switch (GST_EVENT_TYPE (event)) {
78    case GST_EVENT_TAG:
79      copy->event_data.structure.structure =
80          gst_tag_list_copy ((GstTagList *) event->event_data.structure.
81          structure);
82      break;
83    case GST_EVENT_NAVIGATION:
84      copy->event_data.structure.structure =
85          gst_structure_copy (event->event_data.structure.structure);
86    default:
87      break;
88  }
89
90  return copy;
91}
92
93static void
94_gst_event_free (GstEvent * event)
95{
96  GST_CAT_INFO (GST_CAT_EVENT, "freeing event %p", event);
97
98  if (GST_EVENT_SRC (event)) {
99    gst_object_unref (GST_EVENT_SRC (event));
100  }
101  switch (GST_EVENT_TYPE (event)) {
102    case GST_EVENT_TAG:
103      if (GST_IS_TAG_LIST (event->event_data.structure.structure)) {
104        gst_tag_list_free (event->event_data.structure.structure);
105      } else {
106        g_warning ("tag event %p didn't contain a valid tag list!", event);
107        GST_ERROR ("tag event %p didn't contain a valid tag list!", event);
108      }
109      break;
110    case GST_EVENT_NAVIGATION:
111      gst_structure_free (event->event_data.structure.structure);
112      break;
113    default:
114      break;
115  }
116  _GST_DATA_DISPOSE (GST_DATA (event));
117#ifndef GST_DISABLE_TRACE
118  gst_alloc_trace_free (_event_trace, event);
119#endif
120  gst_mem_chunk_free (chunk, event);
121}
122
123/**
124 * gst_event_masks_contains:
125 * @masks: The eventmask array to search
126 * @mask: the event mask to find
127 *
128 * See if the given eventmask is inside the eventmask array.
129 *
130 * Returns: TRUE if the eventmask is found inside the array
131 */
132gboolean
133gst_event_masks_contains (const GstEventMask * masks, GstEventMask * mask)
134{
135  g_return_val_if_fail (mask != NULL, FALSE);
136
137  if (!masks)
138    return FALSE;
139
140  while (masks->type) {
141    if (masks->type == mask->type &&
142        (masks->flags & mask->flags) == mask->flags)
143      return TRUE;
144
145    masks++;
146  }
147
148  return FALSE;
149}
150
151GType
152gst_event_get_type (void)
153{
154  return _gst_event_type;
155}
156
157/**
158 * gst_event_new:
159 * @type: The type of the new event
160 *
161 * Allocate a new event of the given type.
162 *
163 * Returns: A new event.
164 */
165GstEvent *
166gst_event_new (GstEventType type)
167{
168  GstEvent *event;
169
170  event = gst_mem_chunk_alloc0 (chunk);
171#ifndef GST_DISABLE_TRACE
172  gst_alloc_trace_new (_event_trace, event);
173#endif
174
175  GST_CAT_INFO (GST_CAT_EVENT, "creating new event type %d: %p", type, event);
176
177  _GST_DATA_INIT (GST_DATA (event),
178      _gst_event_type,
179      0,
180      (GstDataFreeFunction) _gst_event_free,
181      (GstDataCopyFunction) _gst_event_copy);
182
183  GST_EVENT_TYPE (event) = type;
184  GST_EVENT_TIMESTAMP (event) = G_GINT64_CONSTANT (0);
185  GST_EVENT_SRC (event) = NULL;
186
187  return event;
188}
189
190/**
191 * gst_event_new_seek:
192 * @type: The type of the seek event
193 * @offset: The offset of the seek
194 *
195 * Allocate a new seek event with the given parameters.
196 *
197 * Returns: A new seek event.
198 */
199GstEvent *
200gst_event_new_seek (GstSeekType type, gint64 offset)
201{
202  GstEvent *event;
203
204  event = gst_event_new (GST_EVENT_SEEK);
205
206  GST_EVENT_SEEK_TYPE (event) = type;
207  GST_EVENT_SEEK_OFFSET (event) = offset;
208  GST_EVENT_SEEK_ENDOFFSET (event) = -1;
209
210  return event;
211}
212
213/**
214 * gst_event_new_discontinuous_valist:
215 * @new_media: A flag indicating a new media type starts
216 * @format1: The format of the discont value
217 * @var_args: more discont values and formats
218 *
219 * Allocate a new discontinuous event with the given format/value pairs. Note
220 * that the values are of type gint64 - you may not use simple integers such
221 * as "0" when calling this function, always cast them like "(gint64) 0".
222 * Terminate the list with #GST_FORMAT_UNDEFINED.
223 *
224 * Returns: A new discontinuous event.
225 */
226GstEvent *
227gst_event_new_discontinuous_valist (gboolean new_media, GstFormat format1,
228    va_list var_args)
229{
230  GstEvent *event;
231  gint count = 0;
232
233  event = gst_event_new (GST_EVENT_DISCONTINUOUS);
234  GST_EVENT_DISCONT_NEW_MEDIA (event) = new_media;
235
236  while (format1 != GST_FORMAT_UNDEFINED && count < 8) {
237
238    GST_EVENT_DISCONT_OFFSET (event, count).format =
239        format1 & GST_SEEK_FORMAT_MASK;
240    GST_EVENT_DISCONT_OFFSET (event, count).value = va_arg (var_args, gint64);
241
242    format1 = va_arg (var_args, GstFormat);
243
244    count++;
245  }
246
247  GST_EVENT_DISCONT_OFFSET_LEN (event) = count;
248
249  return event;
250}
251
252/**
253 * gst_event_new_discontinuous:
254 * @new_media: A flag indicating a new media type starts
255 * @format1: The format of the discont value
256 * @...: more discont values and formats
257 *
258 * Allocate a new discontinuous event with the given format/value pairs. Note
259 * that the values are of type gint64 - you may not use simple integers such
260 * as "0" when calling this function, always cast them like "(gint64) 0".
261 * Terminate the list with #GST_FORMAT_UNDEFINED.
262 *
263 * Returns: A new discontinuous event.
264 */
265GstEvent *
266gst_event_new_discontinuous (gboolean new_media, GstFormat format1, ...)
267{
268  va_list var_args;
269  GstEvent *event;
270
271  va_start (var_args, format1);
272
273  event = gst_event_new_discontinuous_valist (new_media, format1, var_args);
274
275  va_end (var_args);
276
277  return event;
278}
279
280/**
281 * gst_event_discont_get_value:
282 * @event: The event to query
283 * @format: The format of the discontinuous value
284 * @value: A pointer to the value
285 *
286 * Get the value for the given format in the discontinous event.
287 *
288 * Returns: TRUE if the discontinuous event carries the specified
289 * format/value pair.
290 */
291gboolean
292gst_event_discont_get_value (GstEvent * event, GstFormat format, gint64 * value)
293{
294  gint i, n;
295
296  g_return_val_if_fail (event != NULL, FALSE);
297  g_return_val_if_fail (value != NULL, FALSE);
298
299  n = GST_EVENT_DISCONT_OFFSET_LEN (event);
300
301  for (i = 0; i < n; i++) {
302    if (GST_EVENT_DISCONT_OFFSET (event, i).format == format) {
303      *value = GST_EVENT_DISCONT_OFFSET (event, i).value;
304      return TRUE;
305    }
306  }
307
308  return FALSE;
309}
310
311
312/**
313 * gst_event_new_size:
314 * @format: The format of the size value
315 * @value: The value of the size event
316 *
317 * Create a new size event with the given values.
318 *
319 * Returns: The new size event.
320 */
321GstEvent *
322gst_event_new_size (GstFormat format, gint64 value)
323{
324  GstEvent *event;
325
326  event = gst_event_new (GST_EVENT_SIZE);
327
328  GST_EVENT_SIZE_FORMAT (event) = format;
329  GST_EVENT_SIZE_VALUE (event) = value;
330
331  return event;
332}
333
334
335/**
336 * gst_event_new_segment_seek:
337 * @type: The type of the seek event
338 * @start: The start offset of the seek
339 * @stop: The stop offset of the seek
340 *
341 * Allocate a new segment seek event with the given parameters.
342 *
343 * Returns: A new segment seek event.
344 */
345GstEvent *
346gst_event_new_segment_seek (GstSeekType type, gint64 start, gint64 stop)
347{
348  GstEvent *event;
349
350  g_return_val_if_fail (start < stop, NULL);
351
352  event = gst_event_new (GST_EVENT_SEEK_SEGMENT);
353
354  GST_EVENT_SEEK_TYPE (event) = type;
355  GST_EVENT_SEEK_OFFSET (event) = start;
356  GST_EVENT_SEEK_ENDOFFSET (event) = stop;
357
358  return event;
359}
360
361/**
362 * gst_event_new_filler_stamped:
363 * @time: timestamp of the filler, in nanoseconds.
364 * @duration: duration of the filler, in nanoseconds.
365 *
366 * Creates "filler" data, which is basically empty data that is used to
367 * synchronize streams if one stream has no data for a while. This is
368 * used to prevent deadlocks.
369 *
370 * Returns: the newly created event.
371 */
372
373GstEvent *
374gst_event_new_filler_stamped (guint64 time, guint64 duration)
375{
376  GstEvent *event = gst_event_new_filler ();
377
378  GST_EVENT_TIMESTAMP (event) = time;
379  if (GST_CLOCK_TIME_IS_VALID (duration)) {
380    GValue value = { 0 };
381
382    event->event_data.structure.structure =
383        gst_structure_new ("application/x-gst-filler", NULL);
384    g_value_init (&value, G_TYPE_UINT64);
385    g_value_set_uint64 (&value, duration);
386    gst_structure_set_value (event->event_data.structure.structure,
387        "duration", &value);
388    g_value_unset (&value);
389  }
390
391  return event;
392}
393
394/**
395 * gst_event_filler_get_duration:
396 * @event: the event to get the duration from.
397 *
398 * Filler events are used to synchronize streams (and thereby prevent
399 * application deadlocks) if one stream receives no data for a while.
400 * This function gets the duration of a filler event, which is the
401 * amount of time from the start of this event (see GST_EVENT_TIMESTAMP())
402 * that no data is available.
403 *
404 * Returns: duration of the lack of data, or GST_CLOCK_TIME_NONE.
405 */
406
407guint64
408gst_event_filler_get_duration (GstEvent * event)
409{
410  const GValue *value;
411
412  g_return_val_if_fail (event != NULL, GST_CLOCK_TIME_NONE);
413  g_return_val_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_FILLER,
414      GST_CLOCK_TIME_NONE);
415
416  /* check the event */
417  if (!event->event_data.structure.structure)
418    return GST_CLOCK_TIME_NONE;
419  value = gst_structure_get_value (event->event_data.structure.structure,
420      "duration");
421  if (!value)
422    return GST_CLOCK_TIME_NONE;
423  g_return_val_if_fail (G_VALUE_TYPE (value) == G_TYPE_UINT64,
424      GST_CLOCK_TIME_NONE);
425
426  /* return */
427  return g_value_get_uint64 (value);
428}
Note: See TracBrowser for help on using the repository browser.