gstevent.c 9.47 KB
Newer Older
1 2 3 4
/* GStreamer
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
 *                    2000 Wim Taymans <wim.taymans@chello.be>
 *
5
 * gstevent.c: GstEvent subsystem
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

23
#include <string.h>             /* memcpy */
24

25 26 27
#include "gst_private.h"

#include "gstinfo.h"
28
#include "gstmemchunk.h"
29
#include "gstevent.h"
Benjamin Otte's avatar
Benjamin Otte committed
30
#include "gsttag.h"
31
#include "gstutils.h"
Benjamin Otte's avatar
Benjamin Otte committed
32

33

34 35 36 37
static void gst_event_init (GTypeInstance * instance, gpointer g_class);
static void gst_event_class_init (gpointer g_class, gpointer class_data);
static void gst_event_finalize (GstEvent * event);
static GstEvent *_gst_event_copy (GstEvent * event);
38 39 40 41

void
_gst_event_initialize (void)
{
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
  gst_event_get_type ();
}

GType
gst_event_get_type (void)
{
  static GType _gst_event_type;

  if (G_UNLIKELY (_gst_event_type == 0)) {
    static const GTypeInfo event_info = {
      sizeof (GstEventClass),
      NULL,
      NULL,
      gst_event_class_init,
      NULL,
      NULL,
      sizeof (GstEvent),
      0,
      gst_event_init,
      NULL
    };

    _gst_event_type = g_type_register_static (GST_TYPE_MINI_OBJECT,
        "GstEvent", &event_info, 0);
  }
67

68
  return _gst_event_type;
69 70
}

71 72
static void
gst_event_class_init (gpointer g_class, gpointer class_data)
Wim Taymans's avatar
Wim Taymans committed
73
{
74
  GstEventClass *event_class = GST_EVENT_CLASS (g_class);
Wim Taymans's avatar
Wim Taymans committed
75

76 77 78 79 80
  event_class->mini_object_class.copy =
      (GstMiniObjectCopyFunction) _gst_event_copy;
  event_class->mini_object_class.finalize =
      (GstMiniObjectFinalizeFunction) gst_event_finalize;
}
Wim Taymans's avatar
Wim Taymans committed
81

82 83 84 85
static void
gst_event_init (GTypeInstance * instance, gpointer g_class)
{
  GstEvent *event;
86

87
  event = GST_EVENT (instance);
Wim Taymans's avatar
Wim Taymans committed
88

89
  GST_EVENT_TIMESTAMP (event) = GST_CLOCK_TIME_NONE;
Wim Taymans's avatar
Wim Taymans committed
90 91
}

92
static void
93
gst_event_finalize (GstEvent * event)
94
{
95 96 97
  g_return_if_fail (event != NULL);
  g_return_if_fail (GST_IS_EVENT (event));

98
  GST_CAT_INFO (GST_CAT_EVENT, "freeing event %p", event);
Wim Taymans's avatar
Wim Taymans committed
99

100 101 102 103
  if (GST_EVENT_SRC (event)) {
    gst_object_unref (GST_EVENT_SRC (event));
  }
  switch (GST_EVENT_TYPE (event)) {
Benjamin Otte's avatar
Benjamin Otte committed
104
    case GST_EVENT_TAG:
105
      if (GST_IS_TAG_LIST (event->event_data.structure.structure)) {
106
        gst_tag_list_free (event->event_data.structure.structure);
107
      } else {
108 109
        g_warning ("tag event %p didn't contain a valid tag list!", event);
        GST_ERROR ("tag event %p didn't contain a valid tag list!", event);
110
      }
111
      break;
112 113
    case GST_EVENT_NAVIGATION:
      gst_structure_free (event->event_data.structure.structure);
114
      break;
115 116 117
    default:
      break;
  }
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
}


static GstEvent *
_gst_event_copy (GstEvent * event)
{
  GstEvent *copy;

  copy = gst_event_new (event->type);

  copy->timestamp = event->timestamp;
  if (event->src) {
    copy->src = gst_object_ref (event->src);
  }

  memcpy (&copy->event_data, &event->event_data, sizeof (event->event_data));

  /* FIXME copy/ref additional fields */
  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_TAG:
      copy->event_data.structure.structure =
          gst_tag_list_copy ((GstTagList *) event->event_data.structure.
          structure);
      break;
    case GST_EVENT_NAVIGATION:
      copy->event_data.structure.structure =
          gst_structure_copy (event->event_data.structure.structure);
    default:
      break;
  }

  return copy;
150 151
}

152 153 154 155 156 157 158 159 160 161
/**
 * gst_event_masks_contains:
 * @masks: The eventmask array to search
 * @mask: the event mask to find
 *
 * See if the given eventmask is inside the eventmask array.
 *
 * Returns: TRUE if the eventmask is found inside the array
 */
gboolean
162
gst_event_masks_contains (const GstEventMask * masks, GstEventMask * mask)
163 164 165 166 167
{
  g_return_val_if_fail (mask != NULL, FALSE);

  if (!masks)
    return FALSE;
168

169 170
  while (masks->type) {
    if (masks->type == mask->type &&
171
        (masks->flags & mask->flags) == mask->flags)
172 173 174 175 176 177 178 179
      return TRUE;

    masks++;
  }

  return FALSE;
}

180 181 182 183 184 185 186 187
/**
 * gst_event_new:
 * @type: The type of the new event
 *
 * Allocate a new event of the given type.
 *
 * Returns: A new event.
 */
188
GstEvent *
189 190 191 192
gst_event_new (GstEventType type)
{
  GstEvent *event;

193
  event = (GstEvent *) gst_mini_object_new (GST_TYPE_EVENT);
194

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
195
  GST_CAT_INFO (GST_CAT_EVENT, "creating new event type %d: %p", type, event);
196 197 198 199

  GST_EVENT_TYPE (event) = type;

  return event;
200 201
}

202 203 204 205 206 207 208 209 210
/**
 * gst_event_new_seek:
 * @type: The type of the seek event
 * @offset: The offset of the seek
 *
 * Allocate a new seek event with the given parameters.
 *
 * Returns: A new seek event.
 */
211
GstEvent *
212
gst_event_new_seek (GstSeekType type, gint64 offset)
213 214 215 216
{
  GstEvent *event;

  event = gst_event_new (GST_EVENT_SEEK);
217

218 219
  GST_EVENT_SEEK_TYPE (event) = type;
  GST_EVENT_SEEK_OFFSET (event) = offset;
220
  GST_EVENT_SEEK_ENDOFFSET (event) = -1;
221 222 223

  return event;
}
224

Wim Taymans's avatar
Wim Taymans committed
225
/**
226
 * gst_event_new_discontinuous_valist:
Wim Taymans's avatar
Wim Taymans committed
227 228
 * @new_media: A flag indicating a new media type starts
 * @format1: The format of the discont value
229
 * @var_args: more discont values and formats
Wim Taymans's avatar
Wim Taymans committed
230
 *
231 232 233 234
 * Allocate a new discontinuous event with the given format/value pairs. Note
 * that the values are of type gint64 - you may not use simple integers such
 * as "0" when calling this function, always cast them like "(gint64) 0".
 * Terminate the list with #GST_FORMAT_UNDEFINED.
Wim Taymans's avatar
Wim Taymans committed
235 236 237
 *
 * Returns: A new discontinuous event.
 */
238
GstEvent *
239
gst_event_new_discontinuous_valist (gdouble rate, GstFormat format1,
240
    va_list var_args)
241 242 243 244 245
{
  GstEvent *event;
  gint count = 0;

  event = gst_event_new (GST_EVENT_DISCONTINUOUS);
246
  GST_EVENT_DISCONT_RATE (event) = rate;
247

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
248
  while (format1 != GST_FORMAT_UNDEFINED && count < 8) {
249

250
    GST_EVENT_DISCONT_OFFSET (event, count).format =
251
        format1 & GST_SEEK_FORMAT_MASK;
252 253 254 255
    GST_EVENT_DISCONT_OFFSET (event, count).start_value =
        va_arg (var_args, gint64);
    GST_EVENT_DISCONT_OFFSET (event, count).end_value =
        va_arg (var_args, gint64);
256

257
    format1 = va_arg (var_args, GstFormat);
258 259 260 261 262

    count++;
  }

  GST_EVENT_DISCONT_OFFSET_LEN (event) = count;
263

264 265 266
  return event;
}

267 268 269 270 271 272 273 274 275 276 277 278 279
/**
 * gst_event_new_discontinuous:
 * @new_media: A flag indicating a new media type starts
 * @format1: The format of the discont value
 * @...: more discont values and formats
 *
 * Allocate a new discontinuous event with the given format/value pairs. Note
 * that the values are of type gint64 - you may not use simple integers such
 * as "0" when calling this function, always cast them like "(gint64) 0".
 * Terminate the list with #GST_FORMAT_UNDEFINED.
 *
 * Returns: A new discontinuous event.
 */
280
GstEvent *
281
gst_event_new_discontinuous (gdouble rate, GstFormat format1, ...)
282 283 284 285 286 287
{
  va_list var_args;
  GstEvent *event;

  va_start (var_args, format1);

288
  event = gst_event_new_discontinuous_valist (rate, format1, var_args);
289 290 291 292 293 294

  va_end (var_args);

  return event;
}

Wim Taymans's avatar
Wim Taymans committed
295 296 297
/**
 * gst_event_discont_get_value:
 * @event: The event to query
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
298
 * @format: The format of the discontinuous value
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
299 300
 * @start_value: A pointer to store the end value in
 * @end_value: A pointer to store the end value in
Wim Taymans's avatar
Wim Taymans committed
301
 *
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
302
 * Get the start and end value for the given format in the discontinous event.
Wim Taymans's avatar
Wim Taymans committed
303
 *
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
304 305
 * Returns: TRUE if the discontinuous event carries the specified
 * format/value pair.
Wim Taymans's avatar
Wim Taymans committed
306
 */
307
gboolean
308 309
gst_event_discont_get_value (GstEvent * event, GstFormat format,
    gint64 * start_value, gint64 * end_value)
310 311 312
{
  gint i, n;

Wim Taymans's avatar
Wim Taymans committed
313
  g_return_val_if_fail (event != NULL, FALSE);
314 315 316 317

  n = GST_EVENT_DISCONT_OFFSET_LEN (event);

  for (i = 0; i < n; i++) {
318
    if (GST_EVENT_DISCONT_OFFSET (event, i).format == format) {
319 320 321 322
      if (start_value)
        *start_value = GST_EVENT_DISCONT_OFFSET (event, i).start_value;
      if (end_value)
        *end_value = GST_EVENT_DISCONT_OFFSET (event, i).end_value;
323 324 325
      return TRUE;
    }
  }
326

327 328 329 330
  return FALSE;
}


331 332 333 334 335 336 337 338 339
/**
 * gst_event_new_size:
 * @format: The format of the size value
 * @value: The value of the size event
 *
 * Create a new size event with the given values.
 *
 * Returns: The new size event.
 */
340
GstEvent *
341 342 343 344 345
gst_event_new_size (GstFormat format, gint64 value)
{
  GstEvent *event;

  event = gst_event_new (GST_EVENT_SIZE);
346

347 348
  GST_EVENT_SIZE_FORMAT (event) = format;
  GST_EVENT_SIZE_VALUE (event) = value;
349

350 351 352
  return event;
}

353

354 355 356 357 358 359 360 361 362 363
/**
 * gst_event_new_segment_seek:
 * @type: The type of the seek event
 * @start: The start offset of the seek
 * @stop: The stop offset of the seek
 *
 * Allocate a new segment seek event with the given parameters. 
 *
 * Returns: A new segment seek event.
 */
364
GstEvent *
365 366 367 368
gst_event_new_segment_seek (GstSeekType type, gint64 start, gint64 stop)
{
  GstEvent *event;

Wim Taymans's avatar
Wim Taymans committed
369
  g_return_val_if_fail (start < stop || stop == -1, NULL);
370

Wim Taymans's avatar
Wim Taymans committed
371
  event = gst_event_new (GST_EVENT_SEEK);
372 373 374 375 376 377 378

  GST_EVENT_SEEK_TYPE (event) = type;
  GST_EVENT_SEEK_OFFSET (event) = start;
  GST_EVENT_SEEK_ENDOFFSET (event) = stop;

  return event;
}
379 380

/**
Wim Taymans's avatar
Wim Taymans committed
381 382
 * gst_event_new_flush:
 * @done: Indicates the end of the flush
383
 *
Wim Taymans's avatar
Wim Taymans committed
384
 * Allocate a new flush event.
385
 *
Wim Taymans's avatar
Wim Taymans committed
386
 * Returns: A new flush event.
387 388
 */
GstEvent *
Wim Taymans's avatar
Wim Taymans committed
389
gst_event_new_flush (gboolean done)
390
{
Wim Taymans's avatar
Wim Taymans committed
391
  GstEvent *event;
392

Wim Taymans's avatar
Wim Taymans committed
393 394
  event = gst_event_new (GST_EVENT_FLUSH);
  GST_EVENT_FLUSH_DONE (event) = done;
395

Wim Taymans's avatar
Wim Taymans committed
396
  return event;
397
}