gstmessage.c 99.4 KB
Newer Older
Wim Taymans's avatar
Wim Taymans committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/* GStreamer
 * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>
 *
 * gstmessage.c: GstMessage subsystem
 *
 * 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
Tim-Philipp Müller's avatar
Tim-Philipp Müller committed
18 19
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
Wim Taymans's avatar
Wim Taymans committed
20
 */
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
21

22 23
/**
 * SECTION:gstmessage
24
 * @title: GstMessage
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
25 26
 * @short_description: Lightweight objects to signal the application of
 *                     pipeline events
27
 * @see_also: #GstBus, #GstMiniObject, #GstElement
28
 *
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
29
 * Messages are implemented as a subclass of #GstMiniObject with a generic
30 31 32 33
 * #GstStructure as the content. This allows for writing custom messages without
 * requiring an API change while allowing a wide range of different types
 * of messages.
 *
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
34 35
 * Messages are posted by objects in the pipeline and are passed to the
 * application using the #GstBus.
36
 *
37
 * The basic use pattern of posting a message on a #GstBus is as follows:
38
 * |[<!-- language="C" -->
39 40
 *   gst_bus_post (bus, gst_message_new_eos());
 * ]|
41 42 43
 *
 * A #GstElement usually posts messages on the bus provided by the parent
 * container using gst_element_post_message().
44
 */
Wim Taymans's avatar
Wim Taymans committed
45 46 47


#include "gst_private.h"
48
#include <string.h>             /* memcpy */
49
#include "gsterror.h"
50
#include "gstenumtypes.h"
Wim Taymans's avatar
Wim Taymans committed
51 52
#include "gstinfo.h"
#include "gstmessage.h"
53
#include "gsttaglist.h"
54
#include "gstutils.h"
55
#include "gstquark.h"
56
#include "gstvalue.h"
Wim Taymans's avatar
Wim Taymans committed
57 58


59 60 61 62 63 64 65
typedef struct
{
  GstMessage message;

  GstStructure *structure;
} GstMessageImpl;

66
#define GST_MESSAGE_STRUCTURE(m)  (((GstMessageImpl *)(m))->structure)
67

68 69
typedef struct
{
70 71
  const gint type;
  const gchar *name;
72 73 74 75 76 77 78 79 80 81 82 83
  GQuark quark;
} GstMessageQuarks;

static GstMessageQuarks message_quarks[] = {
  {GST_MESSAGE_UNKNOWN, "unknown", 0},
  {GST_MESSAGE_EOS, "eos", 0},
  {GST_MESSAGE_ERROR, "error", 0},
  {GST_MESSAGE_WARNING, "warning", 0},
  {GST_MESSAGE_INFO, "info", 0},
  {GST_MESSAGE_TAG, "tag", 0},
  {GST_MESSAGE_BUFFERING, "buffering", 0},
  {GST_MESSAGE_STATE_CHANGED, "state-changed", 0},
84
  {GST_MESSAGE_STATE_DIRTY, "state-dirty", 0},
85
  {GST_MESSAGE_STEP_DONE, "step-done", 0},
Wim Taymans's avatar
Wim Taymans committed
86 87
  {GST_MESSAGE_CLOCK_PROVIDE, "clock-provide", 0},
  {GST_MESSAGE_CLOCK_LOST, "clock-lost", 0},
88 89 90 91
  {GST_MESSAGE_NEW_CLOCK, "new-clock", 0},
  {GST_MESSAGE_STRUCTURE_CHANGE, "structure-change", 0},
  {GST_MESSAGE_STREAM_STATUS, "stream-status", 0},
  {GST_MESSAGE_APPLICATION, "application", 0},
Wim Taymans's avatar
Wim Taymans committed
92
  {GST_MESSAGE_ELEMENT, "element", 0},
93 94
  {GST_MESSAGE_SEGMENT_START, "segment-start", 0},
  {GST_MESSAGE_SEGMENT_DONE, "segment-done", 0},
95
  {GST_MESSAGE_DURATION_CHANGED, "duration-changed", 0},
96
  {GST_MESSAGE_LATENCY, "latency", 0},
97 98
  {GST_MESSAGE_ASYNC_START, "async-start", 0},
  {GST_MESSAGE_ASYNC_DONE, "async-done", 0},
99
  {GST_MESSAGE_REQUEST_STATE, "request-state", 0},
100
  {GST_MESSAGE_STEP_START, "step-start", 0},
101
  {GST_MESSAGE_QOS, "qos", 0},
Wim Taymans's avatar
Wim Taymans committed
102
  {GST_MESSAGE_PROGRESS, "progress", 0},
Alexander Saprykin's avatar
Alexander Saprykin committed
103
  {GST_MESSAGE_TOC, "toc", 0},
104
  {GST_MESSAGE_RESET_TIME, "reset-time", 0},
105
  {GST_MESSAGE_STREAM_START, "stream-start", 0},
106 107
  {GST_MESSAGE_NEED_CONTEXT, "need-context", 0},
  {GST_MESSAGE_HAVE_CONTEXT, "have-context", 0},
108 109
  {GST_MESSAGE_DEVICE_ADDED, "device-added", 0},
  {GST_MESSAGE_DEVICE_REMOVED, "device-removed", 0},
110
  {GST_MESSAGE_PROPERTY_NOTIFY, "property-notify", 0},
111 112
  {GST_MESSAGE_STREAM_COLLECTION, "stream-collection", 0},
  {GST_MESSAGE_STREAMS_SELECTED, "streams-selected", 0},
113
  {GST_MESSAGE_REDIRECT, "redirect", 0},
114 115 116
  {0, NULL, 0}
};

117 118
static GQuark details_quark = 0;

119
GType _gst_message_type = 0;
120
GST_DEFINE_MINI_OBJECT_TYPE (GstMessage, gst_message);
121

122
void
123
_priv_gst_message_initialize (void)
124 125 126 127 128 129 130 131 132
{
  gint i;

  GST_CAT_INFO (GST_CAT_GST_INIT, "init messages");

  for (i = 0; message_quarks[i].name; i++) {
    message_quarks[i].quark =
        g_quark_from_static_string (message_quarks[i].name);
  }
133
  details_quark = g_quark_from_static_string ("details");
134 135

  _gst_message_type = gst_message_get_type ();
136 137
}

Stefan Kost's avatar
Stefan Kost committed
138 139 140 141 142 143
/**
 * gst_message_type_get_name:
 * @type: the message type
 *
 * Get a printable name for the given message type. Do not modify or free.
 *
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
144
 * Returns: a reference to the static name of the message.
Stefan Kost's avatar
Stefan Kost committed
145
 */
146 147 148 149 150 151 152 153 154 155 156 157
const gchar *
gst_message_type_get_name (GstMessageType type)
{
  gint i;

  for (i = 0; message_quarks[i].name; i++) {
    if (type == message_quarks[i].type)
      return message_quarks[i].name;
  }
  return "unknown";
}

Stefan Kost's avatar
Stefan Kost committed
158 159 160 161 162 163 164 165
/**
 * gst_message_type_to_quark:
 * @type: the message type
 *
 * Get the unique quark for the given message type.
 *
 * Returns: the quark associated with the message type
 */
166 167 168 169 170 171 172 173 174 175 176 177
GQuark
gst_message_type_to_quark (GstMessageType type)
{
  gint i;

  for (i = 0; message_quarks[i].name; i++) {
    if (type == message_quarks[i].type)
      return message_quarks[i].quark;
  }
  return 0;
}

178 179 180 181 182 183
static gboolean
_gst_message_dispose (GstMessage * message)
{
  gboolean do_free = TRUE;

  if (GST_MINI_OBJECT_FLAG_IS_SET (message, GST_MESSAGE_FLAG_ASYNC_DELIVERY)) {
184 185 186
    /* revive message, so bus can finish with it and clean it up */
    gst_message_ref (message);

187 188 189 190 191 192 193 194 195 196 197 198 199
    GST_INFO ("[msg %p] signalling async free", message);

    GST_MESSAGE_LOCK (message);
    GST_MESSAGE_SIGNAL (message);
    GST_MESSAGE_UNLOCK (message);

    /* don't free it yet, let bus finish with it first */
    do_free = FALSE;
  }

  return do_free;
}

Wim Taymans's avatar
Wim Taymans committed
200
static void
201
_gst_message_free (GstMessage * message)
Wim Taymans's avatar
Wim Taymans committed
202
{
203 204
  GstStructure *structure;

205
  g_return_if_fail (message != NULL);
Wim Taymans's avatar
Wim Taymans committed
206

207
  GST_CAT_LOG (GST_CAT_MESSAGE, "finalize message %p, %s from %s", message,
208
      GST_MESSAGE_TYPE_NAME (message), GST_MESSAGE_SRC_NAME (message));
209

210 211 212
  if (GST_MESSAGE_SRC (message)) {
    gst_object_unref (GST_MESSAGE_SRC (message));
    GST_MESSAGE_SRC (message) = NULL;
Wim Taymans's avatar
Wim Taymans committed
213 214
  }

215 216 217 218
  structure = GST_MESSAGE_STRUCTURE (message);
  if (structure) {
    gst_structure_set_parent_refcount (structure, NULL);
    gst_structure_free (structure);
219
  }
220

221
  g_slice_free1 (sizeof (GstMessageImpl), message);
Wim Taymans's avatar
Wim Taymans committed
222 223
}

Wim Taymans's avatar
Wim Taymans committed
224
static void
225
gst_message_init (GstMessageImpl * message, GstMessageType type,
Wim Taymans's avatar
Wim Taymans committed
226 227
    GstObject * src);

228 229
static GstMessage *
_gst_message_copy (GstMessage * message)
Wim Taymans's avatar
Wim Taymans committed
230
{
231 232
  GstMessageImpl *copy;
  GstStructure *structure;
233

234 235 236
  GST_CAT_LOG (GST_CAT_MESSAGE, "copy message %p, %s from %s", message,
      GST_MESSAGE_TYPE_NAME (message),
      GST_OBJECT_NAME (GST_MESSAGE_SRC (message)));
237

238
  copy = g_slice_new0 (GstMessageImpl);
239

240
  gst_message_init (copy, GST_MESSAGE_TYPE (message),
Wim Taymans's avatar
Wim Taymans committed
241
      GST_MESSAGE_SRC (message));
242

243
  GST_MESSAGE_TIMESTAMP (copy) = GST_MESSAGE_TIMESTAMP (message);
244
  GST_MESSAGE_SEQNUM (copy) = GST_MESSAGE_SEQNUM (message);
245

246 247
  structure = GST_MESSAGE_STRUCTURE (message);
  if (structure) {
Wim Taymans's avatar
Wim Taymans committed
248 249
    GST_MESSAGE_STRUCTURE (copy) = gst_structure_copy (structure);
    gst_structure_set_parent_refcount (GST_MESSAGE_STRUCTURE (copy),
250
        &copy->message.mini_object.refcount);
Wim Taymans's avatar
Wim Taymans committed
251 252
  } else {
    GST_MESSAGE_STRUCTURE (copy) = NULL;
253 254
  }

255
  return GST_MESSAGE_CAST (copy);
Wim Taymans's avatar
Wim Taymans committed
256 257
}

Wim Taymans's avatar
Wim Taymans committed
258
static void
259
gst_message_init (GstMessageImpl * message, GstMessageType type,
Wim Taymans's avatar
Wim Taymans committed
260 261
    GstObject * src)
{
262
  gst_mini_object_init (GST_MINI_OBJECT_CAST (message), 0, _gst_message_type,
263 264
      (GstMiniObjectCopyFunction) _gst_message_copy,
      (GstMiniObjectDisposeFunction) _gst_message_dispose,
265
      (GstMiniObjectFreeFunction) _gst_message_free);
Wim Taymans's avatar
Wim Taymans committed
266 267 268 269 270 271 272 273 274 275

  GST_MESSAGE_TYPE (message) = type;
  if (src)
    gst_object_ref (src);
  GST_MESSAGE_SRC (message) = src;
  GST_MESSAGE_TIMESTAMP (message) = GST_CLOCK_TIME_NONE;
  GST_MESSAGE_SEQNUM (message) = gst_util_seqnum_next ();
}


Wim Taymans's avatar
Wim Taymans committed
276 277 278
/**
 * gst_message_new_custom:
 * @type: The #GstMessageType to distinguish messages
279
 * @src: (transfer none) (allow-none): The object originating the message.
280 281
 * @structure: (transfer full) (allow-none): the structure for the
 *     message. The message will take ownership of the structure.
Wim Taymans's avatar
Wim Taymans committed
282 283 284
 *
 * Create a new custom-typed message. This can be used for anything not
 * handled by other message-specific functions to pass a message to the
285
 * app. The structure field can be %NULL.
Wim Taymans's avatar
Wim Taymans committed
286
 *
287
 * Returns: (transfer full) (nullable): The new message.
Wim Taymans's avatar
Wim Taymans committed
288 289 290 291 292 293
 *
 * MT safe.
 */
GstMessage *
gst_message_new_custom (GstMessageType type, GstObject * src,
    GstStructure * structure)
Wim Taymans's avatar
Wim Taymans committed
294
{
295
  GstMessageImpl *message;
Wim Taymans's avatar
Wim Taymans committed
296

297
  message = g_slice_new0 (GstMessageImpl);
298

299 300
  GST_CAT_LOG (GST_CAT_MESSAGE, "source %s: creating new message %p %s",
      (src ? GST_OBJECT_NAME (src) : "NULL"), message,
301
      gst_message_type_get_name (type));
Wim Taymans's avatar
Wim Taymans committed
302

Wim Taymans's avatar
Wim Taymans committed
303
  if (structure) {
Wim Taymans's avatar
Wim Taymans committed
304 305 306 307
    /* structure must not have a parent */
    if (!gst_structure_set_parent_refcount (structure,
            &message->message.mini_object.refcount))
      goto had_parent;
Wim Taymans's avatar
Wim Taymans committed
308
  }
309
  gst_message_init (message, type, src);
Wim Taymans's avatar
Wim Taymans committed
310 311

  GST_MESSAGE_STRUCTURE (message) = structure;
Wim Taymans's avatar
Wim Taymans committed
312

313
  return GST_MESSAGE_CAST (message);
Wim Taymans's avatar
Wim Taymans committed
314 315 316 317

  /* ERRORS */
had_parent:
  {
318
    g_slice_free1 (sizeof (GstMessageImpl), message);
Wim Taymans's avatar
Wim Taymans committed
319 320 321
    g_warning ("structure is already owned by another object");
    return NULL;
  }
Wim Taymans's avatar
Wim Taymans committed
322 323
}

324 325 326 327 328 329 330 331 332 333 334 335 336 337
/**
 * gst_message_get_seqnum:
 * @message: A #GstMessage.
 *
 * Retrieve the sequence number of a message.
 *
 * Messages have ever-incrementing sequence numbers, which may also be set
 * explicitly via gst_message_set_seqnum(). Sequence numbers are typically used
 * to indicate that a message corresponds to some other set of messages or
 * events, for example a SEGMENT_DONE message corresponding to a SEEK event. It
 * is considered good practice to make this correspondence when possible, though
 * it is not required.
 *
 * Note that events and messages share the same sequence number incrementor;
338
 * two events or messages will never have the same sequence number unless
339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
 * that correspondence was made explicitly.
 *
 * Returns: The message's sequence number.
 *
 * MT safe.
 */
guint32
gst_message_get_seqnum (GstMessage * message)
{
  g_return_val_if_fail (GST_IS_MESSAGE (message), -1);

  return GST_MESSAGE_SEQNUM (message);
}

/**
 * gst_message_set_seqnum:
 * @message: A #GstMessage.
 * @seqnum: A sequence number.
 *
 * Set the sequence number of a message.
 *
 * This function might be called by the creator of a message to indicate that
 * the message relates to other messages or events. See gst_message_get_seqnum()
 * for more information.
 *
 * MT safe.
 */
void
gst_message_set_seqnum (GstMessage * message, guint32 seqnum)
{
  g_return_if_fail (GST_IS_MESSAGE (message));

  GST_MESSAGE_SEQNUM (message) = seqnum;
}

Wim Taymans's avatar
Wim Taymans committed
374 375
/**
 * gst_message_new_eos:
376
 * @src: (transfer none) (allow-none): The object originating the message.
Wim Taymans's avatar
Wim Taymans committed
377
 *
378 379 380
 * Create a new eos message. This message is generated and posted in
 * the sink elements of a GstBin. The bin will only forward the EOS
 * message to the application if all sinks have posted an EOS message.
Wim Taymans's avatar
Wim Taymans committed
381
 *
382
 * Returns: (transfer full): The new eos message.
Wim Taymans's avatar
Wim Taymans committed
383 384 385 386 387 388 389 390
 *
 * MT safe.
 */
GstMessage *
gst_message_new_eos (GstObject * src)
{
  GstMessage *message;

Wim Taymans's avatar
Wim Taymans committed
391
  message = gst_message_new_custom (GST_MESSAGE_EOS, src, NULL);
Wim Taymans's avatar
Wim Taymans committed
392 393 394 395 396

  return message;
}

/**
397
 * gst_message_new_error_with_details:
398
 * @src: (transfer none) (allow-none): The object originating the message.
399
 * @error: (transfer none): The GError for this message.
400
 * @debug: A debugging string.
401
 * @details: (transfer full): (allow-none): A GstStructure with details
Wim Taymans's avatar
Wim Taymans committed
402
 *
403
 * Create a new error message. The message will copy @error and
404
 * @debug. This message is posted by element when a fatal event
405
 * occurred. The pipeline will probably (partially) stop. The application
406
 * receiving this message should stop the pipeline.
Wim Taymans's avatar
Wim Taymans committed
407
 *
408
 * Returns: (transfer full) (nullable): the new error message.
Wim Taymans's avatar
Wim Taymans committed
409
 *
410
 * Since: 1.10
Wim Taymans's avatar
Wim Taymans committed
411 412
 */
GstMessage *
413 414
gst_message_new_error_with_details (GstObject * src, GError * error,
    const gchar * debug, GstStructure * details)
Wim Taymans's avatar
Wim Taymans committed
415 416
{
  GstMessage *message;
417
  GstStructure *structure;
Wim Taymans's avatar
Wim Taymans committed
418

419
  if (debug && !g_utf8_validate (debug, -1, NULL)) {
420 421 422 423 424
    debug = NULL;
    g_warning ("Trying to set debug field of error message, but "
        "string is not valid UTF-8. Please file a bug.");
  }

Wim Taymans's avatar
Wim Taymans committed
425
  structure = gst_structure_new_id (GST_QUARK (MESSAGE_ERROR),
426
      GST_QUARK (GERROR), G_TYPE_ERROR, error,
427 428
      GST_QUARK (DEBUG), G_TYPE_STRING, debug, NULL);
  message = gst_message_new_custom (GST_MESSAGE_ERROR, src, structure);
429 430 431 432 433 434 435 436
  if (details) {
    GValue v = G_VALUE_INIT;

    g_value_init (&v, GST_TYPE_STRUCTURE);
    g_value_take_boxed (&v, details);
    gst_structure_id_take_value (GST_MESSAGE_STRUCTURE (message), details_quark,
        &v);
  }
Wim Taymans's avatar
Wim Taymans committed
437 438 439 440 441

  return message;
}

/**
442
 * gst_message_new_error:
443
 * @src: (transfer none) (allow-none): The object originating the message.
444
 * @error: (transfer none): The GError for this message.
445
 * @debug: A debugging string.
Wim Taymans's avatar
Wim Taymans committed
446
 *
447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463
 * Create a new error message. The message will copy @error and
 * @debug. This message is posted by element when a fatal event
 * occurred. The pipeline will probably (partially) stop. The application
 * receiving this message should stop the pipeline.
 *
 * Returns: (transfer full): the new error message.
 *
 * MT safe.
 */
GstMessage *
gst_message_new_error (GstObject * src, GError * error, const gchar * debug)
{
  return gst_message_new_error_with_details (src, error, debug, NULL);
}

/**
 * gst_message_parse_error_details:
464
 * @message: The message object
465
 * @structure: (transfer none) (out): A pointer to the returned details
466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496
 *
 * Returns the optional details structure, may be NULL if none.
 * The returned structure must not be freed.
 *
 * Since: 1.10
 */
void
gst_message_parse_error_details (GstMessage * message,
    const GstStructure ** structure)
{
  const GValue *v;

  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR);
  g_return_if_fail (structure != NULL);

  *structure = NULL;
  v = gst_structure_id_get_value (GST_MESSAGE_STRUCTURE (message),
      details_quark);
  if (v) {
    *structure = g_value_get_boxed (v);
  }
}

/**
 * gst_message_new_warning_with_details:
 * @src: (transfer none) (allow-none): The object originating the message.
 * @error: (transfer none): The GError for this message.
 * @debug: A debugging string.
 * @details: (transfer full): (allow-none): A GstStructure with details
 *
497
 * Create a new warning message. The message will make copies of @error and
Wim Taymans's avatar
Wim Taymans committed
498 499
 * @debug.
 *
500
 * Returns: (transfer full) (nullable): the new warning message.
501 502
 *
 * Since: 1.10
Wim Taymans's avatar
Wim Taymans committed
503 504
 */
GstMessage *
505 506
gst_message_new_warning_with_details (GstObject * src, GError * error,
    const gchar * debug, GstStructure * details)
Wim Taymans's avatar
Wim Taymans committed
507 508
{
  GstMessage *message;
509
  GstStructure *structure;
Wim Taymans's avatar
Wim Taymans committed
510

511
  if (debug && !g_utf8_validate (debug, -1, NULL)) {
512 513 514 515 516
    debug = NULL;
    g_warning ("Trying to set debug field of warning message, but "
        "string is not valid UTF-8. Please file a bug.");
  }

Wim Taymans's avatar
Wim Taymans committed
517
  structure = gst_structure_new_id (GST_QUARK (MESSAGE_WARNING),
518
      GST_QUARK (GERROR), G_TYPE_ERROR, error,
519 520
      GST_QUARK (DEBUG), G_TYPE_STRING, debug, NULL);
  message = gst_message_new_custom (GST_MESSAGE_WARNING, src, structure);
521 522 523 524 525 526 527 528
  if (details) {
    GValue v = G_VALUE_INIT;

    g_value_init (&v, GST_TYPE_STRUCTURE);
    g_value_take_boxed (&v, details);
    gst_structure_id_take_value (GST_MESSAGE_STRUCTURE (message), details_quark,
        &v);
  }
Wim Taymans's avatar
Wim Taymans committed
529 530 531 532

  return message;
}

533
/**
534
 * gst_message_new_warning:
535
 * @src: (transfer none) (allow-none): The object originating the message.
536
 * @error: (transfer none): The GError for this message.
537
 * @debug: A debugging string.
538
 *
539
 * Create a new warning message. The message will make copies of @error and
540 541
 * @debug.
 *
542 543
 * Returns: (transfer full): the new warning message.
 *
544
 * MT safe.
545 546 547 548 549 550 551 552 553
 */
GstMessage *
gst_message_new_warning (GstObject * src, GError * error, const gchar * debug)
{
  return gst_message_new_warning_with_details (src, error, debug, NULL);
}

/**
 * gst_message_parse_warning_details:
554
 * @message: The message object
555
 * @structure: (transfer none) (out): A pointer to the returned details structure
556
 *
557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589
 * Returns the optional details structure, may be NULL if none
 * The returned structure must not be freed.
 *
 * Since: 1.10
 */
void
gst_message_parse_warning_details (GstMessage * message,
    const GstStructure ** structure)
{
  const GValue *v;

  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_WARNING);
  g_return_if_fail (structure != NULL);

  *structure = NULL;
  v = gst_structure_id_get_value (GST_MESSAGE_STRUCTURE (message),
      details_quark);
  if (v) {
    *structure = g_value_get_boxed (v);
  }
}

/**
 * gst_message_new_info_with_details:
 * @src: (transfer none) (allow-none): The object originating the message.
 * @error: (transfer none): The GError for this message.
 * @debug: A debugging string.
 * @details: (transfer full): (allow-none): A GstStructure with details
 *
 * Create a new info message. The message will make copies of @error and
 * @debug.
 *
590
 * Returns: (transfer full) (nullable): the new warning message.
591 592
 *
 * Since: 1.10
593 594
 */
GstMessage *
595 596
gst_message_new_info_with_details (GstObject * src, GError * error,
    const gchar * debug, GstStructure * details)
597 598
{
  GstMessage *message;
599
  GstStructure *structure;
600

601
  if (debug && !g_utf8_validate (debug, -1, NULL)) {
602 603 604 605 606
    debug = NULL;
    g_warning ("Trying to set debug field of info message, but "
        "string is not valid UTF-8. Please file a bug.");
  }

Wim Taymans's avatar
Wim Taymans committed
607
  structure = gst_structure_new_id (GST_QUARK (MESSAGE_INFO),
608
      GST_QUARK (GERROR), G_TYPE_ERROR, error,
609
      GST_QUARK (DEBUG), G_TYPE_STRING, debug, NULL);
610
  message = gst_message_new_custom (GST_MESSAGE_INFO, src, structure);
611 612 613 614 615 616 617 618
  if (details) {
    GValue v = G_VALUE_INIT;

    g_value_init (&v, GST_TYPE_STRUCTURE);
    g_value_take_boxed (&v, details);
    gst_structure_id_take_value (GST_MESSAGE_STRUCTURE (message), details_quark,
        &v);
  }
619 620 621 622

  return message;
}

623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643
/**
 * gst_message_new_info:
 * @src: (transfer none) (allow-none): The object originating the message.
 * @error: (transfer none): The GError for this message.
 * @debug: A debugging string.
 *
 * Create a new info message. The message will make copies of @error and
 * @debug.
 *
 * Returns: (transfer full): the new info message.
 *
 * MT safe.
 */
GstMessage *
gst_message_new_info (GstObject * src, GError * error, const gchar * debug)
{
  return gst_message_new_info_with_details (src, error, debug, NULL);
}

/**
 * gst_message_parse_info_details:
644
 * @message: The message object
645
 * @structure: (transfer none) (out): A pointer to the returned details structure
646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669
 *
 * Returns the optional details structure, may be NULL if none
 * The returned structure must not be freed.
 *
 * Since: 1.10
 */
void
gst_message_parse_info_details (GstMessage * message,
    const GstStructure ** structure)
{
  const GValue *v;

  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_INFO);
  g_return_if_fail (structure != NULL);

  *structure = NULL;
  v = gst_structure_id_get_value (GST_MESSAGE_STRUCTURE (message),
      details_quark);
  if (v) {
    *structure = g_value_get_boxed (v);
  }
}

Wim Taymans's avatar
Wim Taymans committed
670 671
/**
 * gst_message_new_tag:
672
 * @src: (transfer none) (allow-none): The object originating the message.
673
 * @tag_list: (transfer full): the tag list for the message.
Wim Taymans's avatar
Wim Taymans committed
674 675
 *
 * Create a new tag message. The message will take ownership of the tag list.
676
 * The message is posted by elements that discovered a new taglist.
Wim Taymans's avatar
Wim Taymans committed
677
 *
678
 * Returns: (transfer full): the new tag message.
Wim Taymans's avatar
Wim Taymans committed
679 680 681 682 683 684
 *
 * MT safe.
 */
GstMessage *
gst_message_new_tag (GstObject * src, GstTagList * tag_list)
{
685
  GstStructure *s;
Wim Taymans's avatar
Wim Taymans committed
686
  GstMessage *message;
687
  GValue val = G_VALUE_INIT;
Wim Taymans's avatar
Wim Taymans committed
688

689
  g_return_val_if_fail (GST_IS_TAG_LIST (tag_list), NULL);
Wim Taymans's avatar
Wim Taymans committed
690

691 692 693 694 695
  s = gst_structure_new_id_empty (GST_QUARK (MESSAGE_TAG));
  g_value_init (&val, GST_TYPE_TAG_LIST);
  g_value_take_boxed (&val, tag_list);
  gst_structure_id_take_value (s, GST_QUARK (TAGLIST), &val);
  message = gst_message_new_custom (GST_MESSAGE_TAG, src, s);
Wim Taymans's avatar
Wim Taymans committed
696 697 698
  return message;
}

699 700
/**
 * gst_message_new_buffering:
701
 * @src: (transfer none) (allow-none): The object originating the message.
702 703 704 705 706 707
 * @percent: The buffering percent
 *
 * Create a new buffering message. This message can be posted by an element that
 * needs to buffer data before it can continue processing. @percent should be a
 * value between 0 and 100. A value of 100 means that the buffering completed.
 *
Wim Taymans's avatar
Wim Taymans committed
708 709 710 711 712
 * When @percent is < 100 the application should PAUSE a PLAYING pipeline. When
 * @percent is 100, the application can set the pipeline (back) to PLAYING.
 * The application must be prepared to receive BUFFERING messages in the
 * PREROLLING state and may only set the pipeline to PLAYING after receiving a
 * message with @percent set to 100, which can happen after the pipeline
713
 * completed prerolling.
Wim Taymans's avatar
Wim Taymans committed
714
 *
715
 * MT safe.
716
 *
717
 * Returns: (transfer full) (nullable): The new buffering message.
718 719 720 721 722
 */
GstMessage *
gst_message_new_buffering (GstObject * src, gint percent)
{
  GstMessage *message;
723
  GstStructure *structure;
724
  gint64 buffering_left;
725 726 727

  g_return_val_if_fail (percent >= 0 && percent <= 100, NULL);

728 729
  buffering_left = (percent == 100 ? 0 : -1);

Wim Taymans's avatar
Wim Taymans committed
730
  structure = gst_structure_new_id (GST_QUARK (MESSAGE_BUFFERING),
731 732 733 734
      GST_QUARK (BUFFER_PERCENT), G_TYPE_INT, percent,
      GST_QUARK (BUFFERING_MODE), GST_TYPE_BUFFERING_MODE, GST_BUFFERING_STREAM,
      GST_QUARK (AVG_IN_RATE), G_TYPE_INT, -1,
      GST_QUARK (AVG_OUT_RATE), G_TYPE_INT, -1,
735
      GST_QUARK (BUFFERING_LEFT), G_TYPE_INT64, buffering_left, NULL);
736
  message = gst_message_new_custom (GST_MESSAGE_BUFFERING, src, structure);
737 738 739 740

  return message;
}

Wim Taymans's avatar
Wim Taymans committed
741
/**
Stefan Kost's avatar
Stefan Kost committed
742
 * gst_message_new_state_changed:
743
 * @src: (transfer none) (allow-none): The object originating the message.
744 745 746
 * @oldstate: the previous state
 * @newstate: the new (current) state
 * @pending: the pending (target) state
Wim Taymans's avatar
Wim Taymans committed
747
 *
748 749
 * Create a state change message. This message is posted whenever an element
 * changed its state.
Wim Taymans's avatar
Wim Taymans committed
750
 *
751
 * Returns: (transfer full): the new state change message.
Wim Taymans's avatar
Wim Taymans committed
752 753 754 755
 *
 * MT safe.
 */
GstMessage *
756
gst_message_new_state_changed (GstObject * src,
757
    GstState oldstate, GstState newstate, GstState pending)
Wim Taymans's avatar
Wim Taymans committed
758 759
{
  GstMessage *message;
760
  GstStructure *structure;
Wim Taymans's avatar
Wim Taymans committed
761

762
  structure = gst_structure_new_id (GST_QUARK (MESSAGE_STATE_CHANGED),
763 764 765 766
      GST_QUARK (OLD_STATE), GST_TYPE_STATE, (gint) oldstate,
      GST_QUARK (NEW_STATE), GST_TYPE_STATE, (gint) newstate,
      GST_QUARK (PENDING_STATE), GST_TYPE_STATE, (gint) pending, NULL);
  message = gst_message_new_custom (GST_MESSAGE_STATE_CHANGED, src, structure);
Wim Taymans's avatar
Wim Taymans committed
767 768 769 770

  return message;
}

771 772
/**
 * gst_message_new_state_dirty:
773
 * @src: (transfer none) (allow-none): The object originating the message
774 775 776 777 778
 *
 * Create a state dirty message. This message is posted whenever an element
 * changed its state asynchronously and is used internally to update the
 * states of container objects.
 *
779
 * Returns: (transfer full): the new state dirty message.
780 781 782 783 784 785 786 787 788 789 790 791 792
 *
 * MT safe.
 */
GstMessage *
gst_message_new_state_dirty (GstObject * src)
{
  GstMessage *message;

  message = gst_message_new_custom (GST_MESSAGE_STATE_DIRTY, src, NULL);

  return message;
}

Wim Taymans's avatar
Wim Taymans committed
793 794
/**
 * gst_message_new_clock_provide:
795
 * @src: (transfer none) (allow-none): The object originating the message.
796
 * @clock: (transfer none): the clock it provides
797
 * @ready: %TRUE if the sender can provide a clock
Wim Taymans's avatar
Wim Taymans committed
798
 *
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
799
 * Create a clock provide message. This message is posted whenever an
Wim Taymans's avatar
Wim Taymans committed
800 801 802
 * element is ready to provide a clock or lost its ability to provide
 * a clock (maybe because it paused or became EOS).
 *
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
803
 * This message is mainly used internally to manage the clock
Wim Taymans's avatar
Wim Taymans committed
804 805
 * selection.
 *
806
 * Returns: (transfer full): the new provide clock message.
Wim Taymans's avatar
Wim Taymans committed
807 808 809 810
 *
 * MT safe.
 */
GstMessage *
811 812
gst_message_new_clock_provide (GstObject * src, GstClock * clock,
    gboolean ready)
Wim Taymans's avatar
Wim Taymans committed
813 814
{
  GstMessage *message;
815
  GstStructure *structure;
Wim Taymans's avatar
Wim Taymans committed
816

Wim Taymans's avatar
Wim Taymans committed
817
  structure = gst_structure_new_id (GST_QUARK (MESSAGE_CLOCK_PROVIDE),
818 819 820
      GST_QUARK (CLOCK), GST_TYPE_CLOCK, clock,
      GST_QUARK (READY), G_TYPE_BOOLEAN, ready, NULL);
  message = gst_message_new_custom (GST_MESSAGE_CLOCK_PROVIDE, src, structure);
821

Wim Taymans's avatar
Wim Taymans committed
822 823 824
  return message;
}

825 826
/**
 * gst_message_new_clock_lost:
827
 * @src: (transfer none) (allow-none): The object originating the message.
828
 * @clock: (transfer none): the clock that was lost
829 830 831 832 833 834 835 836
 *
 * Create a clock lost message. This message is posted whenever the
 * clock is not valid anymore.
 *
 * If this message is posted by the pipeline, the pipeline will
 * select a new clock again when it goes to PLAYING. It might therefore
 * be needed to set the pipeline to PAUSED and PLAYING again.
 *
837
 * Returns: (transfer full): The new clock lost message.
838 839 840 841 842 843 844
 *
 * MT safe.
 */
GstMessage *
gst_message_new_clock_lost (GstObject * src, GstClock * clock)
{
  GstMessage *message;
845
  GstStructure *structure;
846

Wim Taymans's avatar
Wim Taymans committed
847
  structure = gst_structure_new_id (GST_QUARK (MESSAGE_CLOCK_LOST),
848 849
      GST_QUARK (CLOCK), GST_TYPE_CLOCK, clock, NULL);
  message = gst_message_new_custom (GST_MESSAGE_CLOCK_LOST, src, structure);
850 851 852 853

  return message;
}

Wim Taymans's avatar
Wim Taymans committed
854 855
/**
 * gst_message_new_new_clock:
856
 * @src: (transfer none) (allow-none): The object originating the message.
857
 * @clock: (transfer none): the new selected clock
Wim Taymans's avatar
Wim Taymans committed
858 859
 *
 * Create a new clock message. This message is posted whenever the
860
 * pipeline selects a new clock for the pipeline.
Wim Taymans's avatar
Wim Taymans committed
861
 *
862
 * Returns: (transfer full): The new new clock message.
Wim Taymans's avatar
Wim Taymans committed
863 864 865 866 867 868 869
 *
 * MT safe.
 */
GstMessage *
gst_message_new_new_clock (GstObject * src, GstClock * clock)
{
  GstMessage *message;
870
  GstStructure *structure;
Wim Taymans's avatar
Wim Taymans committed
871

Wim Taymans's avatar
Wim Taymans committed
872
  structure = gst_structure_new_id (GST_QUARK (MESSAGE_NEW_CLOCK),
873 874
      GST_QUARK (CLOCK), GST_TYPE_CLOCK, clock, NULL);
  message = gst_message_new_custom (GST_MESSAGE_NEW_CLOCK, src, structure);
Wim Taymans's avatar
Wim Taymans committed
875 876 877 878

  return message;
}

879 880
/**
 * gst_message_new_structure_change:
881
 * @src: (transfer none) (allow-none): The object originating the message.
882
 * @type: The change type.
883
 * @owner: (transfer none): The owner element of @src.
884 885 886 887 888 889
 * @busy: Whether the structure change is busy.
 *
 * Create a new structure change message. This message is posted when the
 * structure of a pipeline is in the process of being changed, for example
 * when pads are linked or unlinked.
 *
890
 * @src should be the sinkpad that unlinked or linked.
891
 *
892
 * Returns: (transfer full): the new structure change message.
893 894 895 896 897 898 899 900 901 902 903
 *
 * MT safe.
 */
GstMessage *
gst_message_new_structure_change (GstObject * src, GstStructureChangeType type,
    GstElement * owner, gboolean busy)
{
  GstMessage *message;
  GstStructure *structure;

  g_return_val_if_fail (GST_IS_PAD (src), NULL);
Jan Schmidt's avatar
Jan Schmidt committed
904
  /* g_return_val_if_fail (GST_PAD_DIRECTION (src) == GST_PAD_SINK, NULL); */
905 906
  g_return_val_if_fail (GST_IS_ELEMENT (owner), NULL);

Wim Taymans's avatar
Wim Taymans committed
907
  structure = gst_structure_new_id (GST_QUARK (MESSAGE_STRUCTURE_CHANGE),
908 909 910 911 912 913 914 915 916 917
      GST_QUARK (TYPE), GST_TYPE_STRUCTURE_CHANGE_TYPE, type,
      GST_QUARK (OWNER), GST_TYPE_ELEMENT, owner,
      GST_QUARK (BUSY), G_TYPE_BOOLEAN, busy, NULL);

  message = gst_message_new_custom (GST_MESSAGE_STRUCTURE_CHANGE, src,
      structure);

  return message;
}

Wim Taymans's avatar
Wim Taymans committed
918
/**
919
 * gst_message_new_segment_start:
920
 * @src: (transfer none) (allow-none): The object originating the message.
921 922
 * @format: The format of the position being played
 * @position: The position of the segment being played
923 924 925 926 927 928
 *
 * Create a new segment message. This message is posted by elements that
 * start playback of a segment as a result of a segment seek. This message
 * is not received by the application but is used for maintenance reasons in
 * container elements.
 *
929
 * Returns: (transfer full): the new segment start message.
930 931 932 933
 *
 * MT safe.
 */
GstMessage *
934 935
gst_message_new_segment_start (GstObject * src, GstFormat format,
    gint64 position)
936 937
{
  GstMessage *message;
938
  GstStructure *structure;
939

Wim Taymans's avatar
Wim Taymans committed
940
  structure = gst_structure_new_id (GST_QUARK (MESSAGE_SEGMENT_START),
941 942 943
      GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
      GST_QUARK (POSITION), G_TYPE_INT64, position, NULL);
  message = gst_message_new_custom (GST_MESSAGE_SEGMENT_START, src, structure);
944 945 946 947 948 949

  return message;
}

/**
 * gst_message_new_segment_done:
950
 * @src: (transfer none) (allow-none): The object originating the message.
951 952
 * @format: The format of the position being done
 * @position: The position of the segment being done
953 954 955 956 957 958
 *
 * Create a new segment done message. This message is posted by elements that
 * finish playback of a segment as a result of a segment seek. This message
 * is received by the application after all elements that posted a segment_start
 * have posted the segment_done.
 *
959
 * Returns: (transfer full): the new segment done message.
960 961 962 963
 *
 * MT safe.
 */
GstMessage *
964 965
gst_message_new_segment_done (GstObject * src, GstFormat format,
    gint64 position)
966 967
{
  GstMessage *message;
968
  GstStructure *structure;
969

Wim Taymans's avatar
Wim Taymans committed
970
  structure = gst_structure_new_id (GST_QUARK (MESSAGE_SEGMENT_DONE),
971 972 973
      GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
      GST_QUARK (POSITION), G_TYPE_INT64, position, NULL);
  message = gst_message_new_custom (GST_MESSAGE_SEGMENT_DONE, src, structure);
974 975 976 977

  return message;
}

978 979
/**
 * gst_message_new_application:
980
 * @src: (transfer none) (allow-none): The object originating the message.
981 982
 * @structure: (transfer full): the structure for the message. The message
 *     will take ownership of the structure.
983 984 985 986
 *
 * Create a new application-typed message. GStreamer will never create these
 * messages; they are a gift from us to you. Enjoy.
 *
987
 * Returns: (transfer full) (nullable): The new application message.
Stefan Kost's avatar
Stefan Kost committed
988
 *
989 990 991 992 993
 * MT safe.
 */
GstMessage *
gst_message_new_application (GstObject * src, GstStructure * structure)
{
994 995
  g_return_val_if_fail (structure != NULL, NULL);

996 997 998 999 1000
  return gst_message_new_custom (GST_MESSAGE_APPLICATION, src, structure);
}

/**
 * gst_message_new_element:
1001
 * @src: (transfer none) (allow-none): The object originating the message.
1002 1003
 * @structure: (transfer full): The structure for the
 *     message. The message will take ownership of the structure.
1004 1005 1006 1007
 *
 * Create a new element-specific message. This is meant as a generic way of
 * allowing one-way communication from an element to an application, for example
 * "the firewire cable was unplugged". The format of the message should be
1008
 * documented in the element's documentation. The structure field can be %NULL.
1009
 *
1010
 * Returns: (transfer full) (nullable): The new element message.
Stefan Kost's avatar
Stefan Kost committed
1011
 *
1012 1013 1014 1015 1016
 * MT safe.
 */
GstMessage *
gst_message_new_element (GstObject * src, GstStructure * structure)
{
1017 1018
  g_return_val_if_fail (structure != NULL, NULL);

1019 1020 1021
  return gst_message_new_custom (GST_MESSAGE_ELEMENT, src, structure);
}

1022
/**
1023
 * gst_message_new_duration_changed:
1024
 * @src: (transfer none) (allow-none): The object originating the message.
1025
 *
1026 1027
 * Create a new duration changed message. This message is posted by elements
 * that know the duration of a stream when the duration changes. This message
1028
 * is received by bins and is used to calculate the total duration of a
1029
 * pipeline.
1030
 *
1031
 * Returns: (transfer full): The new duration-changed message.
1032 1033 1034 1035
 *
 * MT safe.
 */
GstMessage *
1036
gst_message_new_duration_changed (GstObject * src)
1037 1038 1039
{
  GstMessage *message;

1040 1041
  message = gst_message_new_custom (GST_MESSAGE_DURATION_CHANGED, src,
      gst_structure_new_id_empty (GST_QUARK (MESSAGE_DURATION_CHANGED)));
1042 1043 1044 1045

  return message;
}

1046 1047
/**
 * gst_message_new_async_start:
1048
 * @src: (transfer none) (allow-none): The object originating the message.
1049
 *
1050
 * This message is posted by elements when they start an ASYNC state change.
1051
 *
1052
 * Returns: (transfer full): The new async_start message.
1053 1054 1055 1056
 *
 * MT safe.
 */
GstMessage *
1057
gst_message_new_async_start (GstObject * src)
1058 1059 1060
{
  GstMessage *message;

1061
  message = gst_message_new_custom (GST_MESSAGE_ASYNC_START, src, NULL);
1062 1063 1064 1065 1066 1067

  return message;
}

/**
 * gst_message_new_async_done:
1068
 * @src: (transfer none) (allow-none): The object originating the message.
1069
 * @running_time: the desired running_time
1070
 *
Stefan Kost's avatar
Stefan Kost committed
1071
 * The message is posted when elements completed an ASYNC state change.
1072 1073 1074 1075
 * @running_time contains the time of the desired running_time when this
 * elements goes to PLAYING. A value of #GST_CLOCK_TIME_NONE for @running_time
 * means that the element has no clock interaction and thus doesn't care about
 * the running_time of the pipeline.
Stefan Kost's avatar
Stefan Kost committed
1076
 *
1077
 * Returns: (transfer full): The new async_done message.
1078 1079 1080 1081
 *
 * MT safe.
 */
GstMessage *
1082
gst_message_new_async_done (GstObject * src, GstClockTime running_time)
1083 1084
{
  GstMessage *message;
1085
  GstStructure *structure;
1086

Wim Taymans's avatar
Wim Taymans committed
1087
  structure = gst_structure_new_id (GST_QUARK (MESSAGE_ASYNC_DONE),
1088
      GST_QUARK (RUNNING_TIME), G_TYPE_UINT64, running_time, NULL);
1089
  message = gst_message_new_custom (GST_MESSAGE_ASYNC_DONE, src, structure);
1090 1091 1092 1093

  return message;
}

1094 1095
/**
 * gst_message_new_latency:
1096
 * @src: (transfer none) (allow-none): The object originating the message.
1097 1098 1099 1100
 *
 * This message can be posted by elements when their latency requirements have
 * changed.
 *
1101
 * Returns: (transfer full): The new latency message.
1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114
 *
 * MT safe.
 */
GstMessage *
gst_message_new_latency (GstObject * src)
{
  GstMessage *message;

  message = gst_message_new_custom (GST_MESSAGE_LATENCY, src, NULL);

  return message;
}

1115 1116
/**
 * gst_message_new_request_state:
1117
 * @src: (transfer none) (allow-none): The object originating the message.
1118 1119 1120 1121 1122 1123
 * @state: The new requested state
 *
 * This message can be posted by elements when they want to have their state
 * changed. A typical use case would be an audio server that wants to pause the
 * pipeline because a higher priority stream is being played.
 *
1124
 * Returns: (transfer full): the new request state message.
1125 1126 1127 1128 1129 1130 1131 1132 1133
 *
 * MT safe.
 */
GstMessage *
gst_message_new_request_state (GstObject * src, GstState state)
{
  GstMessage *message;
  GstStructure *structure;

Wim Taymans's avatar
Wim Taymans committed
1134
  structure = gst_structure_new_id (GST_QUARK (MESSAGE_REQUEST_STATE),
1135 1136 1137 1138 1139 1140
      GST_QUARK (NEW_STATE), GST_TYPE_STATE, (gint) state, NULL);
  message = gst_message_new_custom (GST_MESSAGE_REQUEST_STATE, src, structure);

  return message;
}

Wim Taymans's avatar
Wim Taymans committed
1141 1142 1143 1144 1145 1146
/**
 * gst_message_get_structure:
 * @message: The #GstMessage.
 *
 * Access the structure of the message.
 *
1147 1148 1149
 * Returns: (transfer none) (nullable): The structure of the message. The
 * structure is still owned by the message, which means that you should not
 * free it and that the pointer becomes invalid when you free the message.
Wim Taymans's avatar
Wim Taymans committed
1150 1151 1152 1153 1154 1155 1156
 *
 * MT safe.
 */
const GstStructure *
gst_message_get_structure (GstMessage * message)
{
  g_return_val_if_fail (GST_IS_MESSAGE (message), NULL);
1157

1158 1159 1160
  return GST_MESSAGE_STRUCTURE (message);
}

1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197
/**
 * gst_message_writable_structure:
 * @message: The #GstMessage.
 *
 * Get a writable version of the structure.
 *
 * Returns: (transfer none): The structure of the message. The structure
 * is still owned by the message, which means that you should not free
 * it and that the pointer becomes invalid when you free the message.