gstpad.c 125 KB
Newer Older
1
2
3
4
/* GStreamer
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
 *                    2000 Wim Taymans <wtay@chello.be>
 *
5
 * gstpad.c: Pads for linking elements together
Erik Walthinsen's avatar
Erik Walthinsen committed
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
24
#include "gst_private.h"

25
#include "gstpad.h"
26
#include "gstmarshal.h"
27
#include "gstutils.h"
28
#include "gstelement.h"
29
#include "gstbin.h"
30
#include "gstscheduler.h"
31
#include "gstevent.h"
32
#include "gstinfo.h"
33
#include "gsterror.h"
David Schleef's avatar
David Schleef committed
34
35
#include "gstvalue.h"

36
37
GST_DEBUG_CATEGORY_STATIC (debug_dataflow);
#define DEBUG_DATA(obj,data,notice) G_STMT_START{\
38
39
40
  if (!data) { \
    GST_CAT_DEBUG_OBJECT (debug_dataflow, obj, "NULL data value"); \
  } else if (GST_IS_EVENT (data)) { \
41
42
    GST_CAT_DEBUG_OBJECT (debug_dataflow, obj, "%s event %p (type %d, refcount %d)", notice, data, \
	GST_EVENT_TYPE (data), GST_DATA_REFCOUNT_VALUE (data)); \
43
  } else { \
44
45
    GST_CAT_LOG_OBJECT (debug_dataflow, obj, "%s buffer %p (size %u, refcount %d)", notice, data, \
	GST_BUFFER_SIZE (data), GST_BUFFER_REFCOUNT_VALUE (data)); \
46
47
  } \
}G_STMT_END
48
49
#define GST_CAT_DEFAULT GST_CAT_PADS

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
struct _GstPadLink
{
  GType type;

  gboolean bla;
  gboolean srcnotify;
  gboolean sinknotify;

  GstPad *srcpad;
  GstPad *sinkpad;

  GstCaps *srccaps;
  GstCaps *sinkcaps;
  GstCaps *filtercaps;
  GstCaps *caps;

  GstPadFixateFunction app_fixate;

  gboolean engaged;
  GstData *temp_store;          /* used only when we invented a DISCONT */
};

72
73
enum
{
74
75
76
77
78
79
80
81
  TEMPL_PAD_CREATED,
  /* FILL ME */
  TEMPL_LAST_SIGNAL
};

static GstObject *padtemplate_parent_class = NULL;
static guint gst_pad_template_signals[TEMPL_LAST_SIGNAL] = { 0 };

82
GType _gst_pad_type = 0;
83

84
/***** Start with the base GstPad class *****/
85
86
87
static void gst_pad_class_init (GstPadClass * klass);
static void gst_pad_init (GstPad * pad);
static void gst_pad_dispose (GObject * object);
88

89
90
91
static void gst_pad_set_pad_template (GstPad * pad, GstPadTemplate * templ);
static GstCaps *_gst_pad_default_fixate_func (GstPad * pad,
    const GstCaps * caps);
92

93
94
static gboolean gst_pad_link_try (GstPadLink * link);
static void gst_pad_link_free (GstPadLink * link);
95

96
#ifndef GST_DISABLE_LOADSAVE
97
static xmlNodePtr gst_pad_save_thyself (GstObject * object, xmlNodePtr parent);
98
#endif
99

Wim Taymans's avatar
Wim Taymans committed
100
static GstObject *pad_parent_class = NULL;
Erik Walthinsen's avatar
Erik Walthinsen committed
101

102
GType
103
gst_pad_get_type (void)
104
105
{
  if (!_gst_pad_type) {
106
    static const GTypeInfo pad_info = {
107
108
      sizeof (GstPadClass), NULL, NULL,
      (GClassInitFunc) gst_pad_class_init, NULL, NULL,
109
      sizeof (GstPad),
110
      0,
111
      (GInstanceInitFunc) gst_pad_init, NULL
Erik Walthinsen's avatar
Erik Walthinsen committed
112
    };
113

114
    _gst_pad_type = g_type_register_static (GST_TYPE_OBJECT, "GstPad",
115
        &pad_info, 0);
116
117
118

    GST_DEBUG_CATEGORY_INIT (debug_dataflow, "GST_DATAFLOW",
        GST_DEBUG_BOLD | GST_DEBUG_FG_GREEN, "dataflow inside pads");
Erik Walthinsen's avatar
Erik Walthinsen committed
119
  }
120
  return _gst_pad_type;
Erik Walthinsen's avatar
Erik Walthinsen committed
121
122
123
}

static void
124
gst_pad_class_init (GstPadClass * klass)
125
{
126
127
  GObjectClass *gobject_class;

128
  gobject_class = (GObjectClass *) klass;
129

130
  pad_parent_class = g_type_class_ref (GST_TYPE_OBJECT);
131
132

  gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_pad_dispose);
133
134
135
}

static void
136
gst_pad_init (GstPad * pad)
137
{
138
139
140
  /* all structs are initialized to NULL by glib */
}
static void
141
gst_pad_dispose (GObject * object)
142
143
144
145
{
  GstPad *pad = GST_PAD (object);

  gst_pad_set_pad_template (pad, NULL);
146

147
  G_OBJECT_CLASS (pad_parent_class)->dispose (object);
148
149
150
151
152
}



/***** Then do the Real Pad *****/
153
/* Pad signals and args */
154
155
enum
{
156
  REAL_LINKED,
Thomas Vander Stichele's avatar
oopsie    
Thomas Vander Stichele committed
157
  REAL_UNLINKED,
158
  REAL_FIXATE,
159
160
161
162
  /* FILL ME */
  REAL_LAST_SIGNAL
};

163
164
enum
{
165
  REAL_ARG_0,
Wim Taymans's avatar
Wim Taymans committed
166
  REAL_ARG_CAPS,
167
  REAL_ARG_ACTIVE
168
      /* FILL ME */
169
170
};

171
172
173
static void gst_real_pad_class_init (GstRealPadClass * klass);
static void gst_real_pad_init (GstRealPad * pad);
static void gst_real_pad_dispose (GObject * object);
174

175
176
177
178
179
180
static gboolean _gst_real_pad_fixate_accumulator (GSignalInvocationHint * ihint,
    GValue * return_accu, const GValue * handler_return, gpointer dummy);
static void gst_real_pad_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_real_pad_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
181

182
GType _gst_real_pad_type = 0;
183
184

static GstPad *real_pad_parent_class = NULL;
185
static guint gst_real_pad_signals[REAL_LAST_SIGNAL] = { 0 };
186

187
GType
188
189
gst_real_pad_get_type (void)
{
190
  if (!_gst_real_pad_type) {
191
    static const GTypeInfo pad_info = {
192
193
194
      sizeof (GstRealPadClass), NULL, NULL,
      (GClassInitFunc) gst_real_pad_class_init, NULL, NULL,
      sizeof (GstRealPad),
195
      0,
196
      (GInstanceInitFunc) gst_real_pad_init, NULL
197
    };
198

199
    _gst_real_pad_type = g_type_register_static (GST_TYPE_PAD, "GstRealPad",
200
        &pad_info, 0);
201
  }
202
  return _gst_real_pad_type;
203
204
205
}

static void
206
gst_real_pad_class_init (GstRealPadClass * klass)
207
{
208
  GObjectClass *gobject_class;
209
  GstObjectClass *gstobject_class;
Erik Walthinsen's avatar
Erik Walthinsen committed
210

211
212
  gobject_class = (GObjectClass *) klass;
  gstobject_class = (GstObjectClass *) klass;
Erik Walthinsen's avatar
Erik Walthinsen committed
213

214
  real_pad_parent_class = g_type_class_ref (GST_TYPE_PAD);
215

216
217
218
  gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_real_pad_dispose);
  gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_real_pad_set_property);
  gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_real_pad_get_property);
Erik Walthinsen's avatar
Erik Walthinsen committed
219

220
  gst_real_pad_signals[REAL_LINKED] =
221
222
223
      g_signal_new ("linked", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
      G_STRUCT_OFFSET (GstRealPadClass, linked), NULL, NULL,
      gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_PAD);
Thomas Vander Stichele's avatar
oopsie    
Thomas Vander Stichele committed
224
  gst_real_pad_signals[REAL_UNLINKED] =
225
226
227
      g_signal_new ("unlinked", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
      G_STRUCT_OFFSET (GstRealPadClass, unlinked), NULL, NULL,
      gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_PAD);
228
  gst_real_pad_signals[REAL_FIXATE] =
229
230
231
232
233
      g_signal_new ("fixate", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
      G_STRUCT_OFFSET (GstRealPadClass, appfixatefunc),
      _gst_real_pad_fixate_accumulator, NULL,
      gst_marshal_BOXED__BOXED, GST_TYPE_CAPS, 1,
      GST_TYPE_CAPS | G_SIGNAL_TYPE_STATIC_SCOPE);
234

235
  g_object_class_install_property (G_OBJECT_CLASS (klass), REAL_ARG_ACTIVE,
236
      g_param_spec_boolean ("active", "Active", "Whether the pad is active.",
237
          TRUE, G_PARAM_READWRITE));
Wim Taymans's avatar
Wim Taymans committed
238
  g_object_class_install_property (G_OBJECT_CLASS (klass), REAL_ARG_CAPS,
239
      g_param_spec_boxed ("caps", "Caps", "The capabilities of the pad",
240
          GST_TYPE_CAPS, G_PARAM_READABLE));
241

242
#ifndef GST_DISABLE_LOADSAVE
243
  gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_pad_save_thyself);
244
#endif
245
  gstobject_class->path_string_separator = ".";
Erik Walthinsen's avatar
Erik Walthinsen committed
246
247
}

248
static gboolean
249
250
_gst_real_pad_fixate_accumulator (GSignalInvocationHint * ihint,
    GValue * return_accu, const GValue * handler_return, gpointer dummy)
251
{
252
  if (gst_value_get_caps (handler_return)) {
253
    g_value_copy (handler_return, return_accu);
254
255
256
257
258
259
    /* stop emission if something was returned */
    return FALSE;
  }
  return TRUE;
}

Wim Taymans's avatar
Wim Taymans committed
260
static void
261
gst_real_pad_init (GstRealPad * pad)
262
{
Erik Walthinsen's avatar
Erik Walthinsen committed
263
264
  pad->direction = GST_PAD_UNKNOWN;
  pad->peer = NULL;
265

266
  pad->chainfunc = NULL;
267
268
  pad->getfunc = NULL;

Wim Taymans's avatar
Wim Taymans committed
269
  pad->chainhandler = NULL;
270
  pad->gethandler = NULL;
271

272
  pad->ghostpads = NULL;
273
  pad->caps = NULL;
274

275
  pad->linkfunc = NULL;
276
  pad->getcapsfunc = NULL;
277

278
279
280
281
  pad->eventfunc = gst_pad_event_default;
  pad->convertfunc = gst_pad_convert_default;
  pad->queryfunc = gst_pad_query_default;
  pad->intlinkfunc = gst_pad_get_internal_links_default;
282

283
284
285
  pad->eventmaskfunc = gst_pad_get_event_masks_default;
  pad->formatsfunc = gst_pad_get_formats_default;
  pad->querytypefunc = gst_pad_get_query_types_default;
Wim Taymans's avatar
Wim Taymans committed
286

287
  GST_FLAG_SET (pad, GST_PAD_DISABLED);
288
  GST_FLAG_UNSET (pad, GST_PAD_NEGOTIATING);
289

Wim Taymans's avatar
Wim Taymans committed
290
  gst_probe_dispatcher_init (&pad->probedisp);
Erik Walthinsen's avatar
Erik Walthinsen committed
291
292
}

293
static void
294
295
gst_real_pad_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
296
{
297
  g_return_if_fail (GST_IS_PAD (object));
298

299
  switch (prop_id) {
300
    case REAL_ARG_ACTIVE:
301
      gst_pad_set_active (GST_PAD (object), g_value_get_boolean (value));
302
303
      break;
    default:
304
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
305
306
307
308
309
      break;
  }
}

static void
310
311
gst_real_pad_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
312
313
314
{
  g_return_if_fail (GST_IS_PAD (object));

315
  switch (prop_id) {
316
    case REAL_ARG_ACTIVE:
317
      g_value_set_boolean (value, !GST_FLAG_IS_SET (object, GST_PAD_DISABLED));
318
      break;
Wim Taymans's avatar
Wim Taymans committed
319
320
321
    case REAL_ARG_CAPS:
      g_value_set_boxed (value, GST_PAD_CAPS (GST_REAL_PAD (object)));
      break;
322
    default:
323
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
324
325
326
327
      break;
  }
}

328
329
/* FIXME-0.9: Replace these custom functions with proper inheritance via _init
   functions and object properties */
Erik Walthinsen's avatar
Erik Walthinsen committed
330
/**
331
 * gst_pad_custom_new:
332
333
334
 * @type: the #Gtype of the pad.
 * @name: the name of the new pad.
 * @direction: the #GstPadDirection of the pad.
Erik Walthinsen's avatar
Erik Walthinsen committed
335
 *
336
337
338
 * Creates a new pad with the given name and type in the given direction.
 * If name is NULL, a guaranteed unique name (across all pads) 
 * will be assigned.
Erik Walthinsen's avatar
Erik Walthinsen committed
339
 *
340
 * Returns: a new #GstPad, or NULL in case of an error.
Erik Walthinsen's avatar
Erik Walthinsen committed
341
 */
342
343
GstPad *
gst_pad_custom_new (GType type, const gchar * name, GstPadDirection direction)
344
{
345
  GstRealPad *pad;
Erik Walthinsen's avatar
Erik Walthinsen committed
346

347
  g_return_val_if_fail (direction != GST_PAD_UNKNOWN, NULL);
Erik Walthinsen's avatar
Erik Walthinsen committed
348

349
  pad = g_object_new (type, NULL);
350
  gst_object_set_name (GST_OBJECT (pad), name);
351
  GST_RPAD_DIRECTION (pad) = direction;
352

353
  return GST_PAD (pad);
354
355
356
}

/**
357
 * gst_pad_new:
358
359
 * @name: the name of the new pad.
 * @direction: the #GstPadDirection of the pad.
360
 *
361
362
363
 * Creates a new real pad with the given name in the given direction.
 * If name is NULL, a guaranteed unique name (across all pads) 
 * will be assigned.
364
 *
365
 * Returns: a new #GstPad, or NULL in case of an error.
366
 */
367
368
GstPad *
gst_pad_new (const gchar * name, GstPadDirection direction)
369
370
371
{
  return gst_pad_custom_new (gst_real_pad_get_type (), name, direction);
}
372

373
374
/**
 * gst_pad_custom_new_from_template:
375
376
377
 * @type: the custom #GType of the pad.
 * @templ: the #GstPadTemplate to instantiate from.
 * @name: the name of the new pad.
378
 *
379
380
381
 * Creates a new custom pad with the given name from the given template.
 * If name is NULL, a guaranteed unique name (across all pads) 
 * will be assigned.
382
 *
383
 * Returns: a new #GstPad, or NULL in case of an error.
384
 */
385
386
387
GstPad *
gst_pad_custom_new_from_template (GType type, GstPadTemplate * templ,
    const gchar * name)
388
389
390
{
  GstPad *pad;

391
  g_return_val_if_fail (GST_IS_PAD_TEMPLATE (templ), NULL);
392

393
  pad = gst_pad_custom_new (type, name, templ->direction);
394
  gst_pad_set_pad_template (pad, templ);
395

Erik Walthinsen's avatar
Erik Walthinsen committed
396
397
398
  return pad;
}

399
400
401
402
403
/**
 * gst_pad_new_from_template:
 * @templ: the pad template to use
 * @name: the name of the element
 *
404
405
406
 * Creates a new real pad with the given name from the given template.
 * If name is NULL, a guaranteed unique name (across all pads) 
 * will be assigned.
407
 *
408
 * Returns: a new #GstPad, or NULL in case of an error.
409
 */
410
411
GstPad *
gst_pad_new_from_template (GstPadTemplate * templ, const gchar * name)
412
{
413
414
  return gst_pad_custom_new_from_template (gst_real_pad_get_type (),
      templ, name);
415
416
}

417
/* FIXME 0.9: GST_PAD_UNKNOWN needs to die! */
418
419
/**
 * gst_pad_get_direction:
420
 * @pad: a #GstPad to get the direction of.
421
 *
422
 * Gets the direction of the pad.
423
 *
424
 * Returns: the #GstPadDirection of the pad.
425
 */
Wim Taymans's avatar
Wim Taymans committed
426
GstPadDirection
427
gst_pad_get_direction (GstPad * pad)
428
{
429
  g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_UNKNOWN);
Erik Walthinsen's avatar
Erik Walthinsen committed
430

431
432
433
434
  if (GST_IS_REAL_PAD (pad))
    return GST_PAD_DIRECTION (pad);
  else
    return GST_PAD_UNKNOWN;
Erik Walthinsen's avatar
Erik Walthinsen committed
435
436
}

437
438
/**
 * gst_pad_set_active:
439
 * @pad: the #GstPad to activate or deactivate.
Wim Taymans's avatar
Wim Taymans committed
440
 * @active: TRUE to activate the pad.
441
 *
442
 * Activates or deactivates the given pad.
443
444
 */
void
445
gst_pad_set_active (GstPad * pad, gboolean active)
446
447
{
  GstRealPad *realpad;
Wim Taymans's avatar
Wim Taymans committed
448
  gboolean old;
449
  GstPadLink *link;
450
451
452

  g_return_if_fail (GST_IS_PAD (pad));

453
454
455
  old = GST_PAD_IS_ACTIVE (pad);

  if (old == active)
456
457
458
459
460
    return;

  realpad = GST_PAD_REALIZE (pad);

  if (active) {
461
    GST_CAT_DEBUG (GST_CAT_PADS, "activating pad %s:%s",
462
        GST_DEBUG_PAD_NAME (realpad));
463
464
    GST_FLAG_UNSET (realpad, GST_PAD_DISABLED);
  } else {
465
    GST_CAT_DEBUG (GST_CAT_PADS, "de-activating pad %s:%s",
466
        GST_DEBUG_PAD_NAME (realpad));
467
468
    GST_FLAG_SET (realpad, GST_PAD_DISABLED);
  }
469
470
471
472
  link = GST_RPAD_LINK (realpad);
  if (link) {
    if (link->temp_store) {
      GST_CAT_INFO (GST_CAT_PADS,
473
          "deleting cached data %p from bufpen of pad %s:%s", link->temp_store,
474
475
476
477
478
          GST_DEBUG_PAD_NAME (realpad));
      gst_data_unref (link->temp_store);
      link->temp_store = NULL;
    }
  }
479

David Schleef's avatar
David Schleef committed
480
  g_object_notify (G_OBJECT (realpad), "active");
481
482
}

483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
/**
 * gst_pad_set_active_recursive:
 * @pad: the #GstPad to activate or deactivate.
 * @active: TRUE to activate the pad.
 *
 * Activates or deactivates the given pad and all internally linked
 * pads upstream until it finds an element with multiple source pads.
 */
void
gst_pad_set_active_recursive (GstPad * pad, gboolean active)
{
  GstElement *parent;
  const GList *int_links;

  g_return_if_fail (GST_IS_PAD (pad));
  g_return_if_fail (GST_PAD_IS_SRC (pad));

  GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
      "Recursively %s pad %s:%s", active ? "activating" : "deactivating",
      GST_DEBUG_PAD_NAME (pad));

  gst_pad_set_active (pad, active);

  /* If we have more than one sourcepad, then the other pads should
   * possibly be kept active. FIXME: maybe we should recurse
   * activation if any one pad is active and recurse deactivation
   * if no single pad is active? */
  parent = gst_pad_get_parent (pad);
  if (!parent || parent->numsrcpads > 1)
    return;

  for (int_links = gst_pad_get_internal_links (pad);
      int_links; int_links = g_list_next (int_links)) {
    GstPad *sinkpad = GST_PAD (int_links->data);
    GstPad *peer = GST_PAD_PEER (sinkpad);

    GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, sinkpad,
        "Recursing %s on pad %s:%s",
        active ? "activation" : "deactivation", GST_DEBUG_PAD_NAME (sinkpad));

    gst_pad_set_active (sinkpad, active);
    if (peer)
      gst_pad_set_active_recursive (peer, active);
  }
}

Wim Taymans's avatar
Wim Taymans committed
529
530
531
532
533
534
535
536
537
/**
 * gst_pad_is_active:
 * @pad: the #GstPad to query
 *
 * Query if a pad is active
 *
 * Returns: TRUE if the pad is active.
 */
gboolean
538
gst_pad_is_active (GstPad * pad)
Wim Taymans's avatar
Wim Taymans committed
539
540
541
542
543
544
{
  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);

  return !GST_FLAG_IS_SET (pad, GST_PAD_DISABLED);
}

545
546
/**
 * gst_pad_set_name:
547
548
 * @pad: a #GstPad to set the name of.
 * @name: the name of the pad.
549
 *
550
551
 * Sets the name of a pad.  If name is NULL, then a guaranteed unique
 * name will be assigned.
552
 */
Wim Taymans's avatar
Wim Taymans committed
553
void
554
gst_pad_set_name (GstPad * pad, const gchar * name)
555
556
{
  g_return_if_fail (GST_IS_PAD (pad));
Erik Walthinsen's avatar
Erik Walthinsen committed
557

558
  gst_object_set_name (GST_OBJECT (pad), name);
Erik Walthinsen's avatar
Erik Walthinsen committed
559
560
}

561
/* FIXME 0.9: This function must die */
562
563
/**
 * gst_pad_get_name:
564
 * @pad: a #GstPad to get the name of.
565
 *
566
 * Gets the name of a pad.
567
 *
568
569
 * Returns: the name of the pad.  This is not a newly allocated pointer
 * so you must not free it.
570
 */
571
572
const gchar *
gst_pad_get_name (GstPad * pad)
573
574
{
  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
Erik Walthinsen's avatar
Erik Walthinsen committed
575

576
  return GST_OBJECT_NAME (pad);
Erik Walthinsen's avatar
Erik Walthinsen committed
577
578
}

Wim Taymans's avatar
Wim Taymans committed
579
/**
580
 * gst_pad_set_chain_function:
581
 * @pad: a real sink #GstPad.
582
 * @chain: the #GstPadChainFunction to set.
Wim Taymans's avatar
Wim Taymans committed
583
 *
584
585
 * Sets the given chain function for the pad. The chain function is called to
 * process a #GstData input buffer.
Wim Taymans's avatar
Wim Taymans committed
586
 */
587
588
void
gst_pad_set_chain_function (GstPad * pad, GstPadChainFunction chain)
589
{
590
  g_return_if_fail (GST_IS_REAL_PAD (pad));
591
  g_return_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SINK);
592

593
  GST_RPAD_CHAINFUNC (pad) = chain;
594
  GST_CAT_DEBUG (GST_CAT_PADS, "chainfunc for %s:%s set to %s",
595
      GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (chain));
596
597
}

Wim Taymans's avatar
Wim Taymans committed
598
/**
Wim Taymans's avatar
Wim Taymans committed
599
 * gst_pad_set_get_function:
600
 * @pad: a real source #GstPad.
601
 * @get: the #GstPadGetFunction to set.
Wim Taymans's avatar
Wim Taymans committed
602
 *
603
604
605
 * Sets the given get function for the pad. The get function is called to
 * produce a new #GstData to start the processing pipeline. Get functions cannot
 * return %NULL.
Wim Taymans's avatar
Wim Taymans committed
606
 */
Wim Taymans's avatar
Wim Taymans committed
607
void
608
gst_pad_set_get_function (GstPad * pad, GstPadGetFunction get)
Wim Taymans's avatar
Wim Taymans committed
609
{
610
  g_return_if_fail (GST_IS_REAL_PAD (pad));
611
  g_return_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SRC);
Wim Taymans's avatar
Wim Taymans committed
612

613
  GST_RPAD_GETFUNC (pad) = get;
614

615
  GST_CAT_DEBUG (GST_CAT_PADS, "getfunc for %s:%s  set to %s",
616
      GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (get));
Wim Taymans's avatar
Wim Taymans committed
617
618
}

619
620
/**
 * gst_pad_set_event_function:
621
 * @pad: a real source #GstPad.
622
 * @event: the #GstPadEventFunction to set.
623
 *
624
 * Sets the given event handler for the pad.
625
626
 */
void
627
gst_pad_set_event_function (GstPad * pad, GstPadEventFunction event)
628
629
{
  g_return_if_fail (GST_IS_REAL_PAD (pad));
630
  g_return_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SRC);
631

632
633
  GST_RPAD_EVENTFUNC (pad) = event;

634
  GST_CAT_DEBUG (GST_CAT_PADS, "eventfunc for %s:%s  set to %s",
635
      GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (event));
636
637
}

Wim Taymans's avatar
Wim Taymans committed
638
639
/**
 * gst_pad_set_event_mask_function:
640
 * @pad: a real #GstPad of either direction.
Wim Taymans's avatar
Wim Taymans committed
641
642
643
644
 * @mask_func: the #GstPadEventMaskFunction to set.
 *
 * Sets the given event mask function for the pad.
 */
645
void
646
647
gst_pad_set_event_mask_function (GstPad * pad,
    GstPadEventMaskFunction mask_func)
648
649
650
{
  g_return_if_fail (GST_IS_REAL_PAD (pad));

Wim Taymans's avatar
Wim Taymans committed
651
  GST_RPAD_EVENTMASKFUNC (pad) = mask_func;
652

653
  GST_CAT_DEBUG (GST_CAT_PADS, "eventmaskfunc for %s:%s  set to %s",
654
      GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (mask_func));
655
656
}

Wim Taymans's avatar
Wim Taymans committed
657
658
/**
 * gst_pad_get_event_masks:
659
 * @pad: a #GstPad.
Wim Taymans's avatar
Wim Taymans committed
660
661
662
 *
 * Gets the array of eventmasks from the given pad.
 *
663
664
 * Returns: a zero-terminated array of #GstEventMask, or NULL if the pad does
 * not have an event mask function.
Wim Taymans's avatar
Wim Taymans committed
665
 */
666
667
const GstEventMask *
gst_pad_get_event_masks (GstPad * pad)
668
669
{
  GstRealPad *rpad;
670

671
  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
672
673
674

  rpad = GST_PAD_REALIZE (pad);

675
  g_return_val_if_fail (rpad, NULL);
676
677

  if (GST_RPAD_EVENTMASKFUNC (rpad))
678
    return GST_RPAD_EVENTMASKFUNC (rpad) (GST_PAD (pad));
679
680
681
682
683

  return NULL;
}

static gboolean
684
gst_pad_get_event_masks_dispatcher (GstPad * pad, const GstEventMask ** data)
685
{
Wim Taymans's avatar
Wim Taymans committed
686
  *data = gst_pad_get_event_masks (pad);
687
688
689
690

  return TRUE;
}

Wim Taymans's avatar
Wim Taymans committed
691
692
/**
 * gst_pad_get_event_masks_default:
693
 * @pad: a #GstPad.
Wim Taymans's avatar
Wim Taymans committed
694
695
696
 *
 * Invokes the default event masks dispatcher on the pad.
 *
697
698
 * Returns: a zero-terminated array of #GstEventMask, or NULL if none of the
 * internally-linked pads have an event mask function.
Wim Taymans's avatar
Wim Taymans committed
699
 */
700
701
const GstEventMask *
gst_pad_get_event_masks_default (GstPad * pad)
702
703
704
{
  GstEventMask *result = NULL;

705
706
  g_return_val_if_fail (GST_IS_PAD (pad), NULL);

707
708
  gst_pad_dispatcher (pad, (GstPadDispatcherFunction)
      gst_pad_get_event_masks_dispatcher, &result);
709
710
711
712

  return result;
}

Wim Taymans's avatar
Wim Taymans committed
713
/**
714
 * gst_pad_set_convert_function:
715
 * @pad: a real #GstPad of either direction.
716
 * @convert: the #GstPadConvertFunction to set.
717
 *
718
 * Sets the given convert function for the pad.
719
720
 */
void
721
gst_pad_set_convert_function (GstPad * pad, GstPadConvertFunction convert)
722
723
724
{
  g_return_if_fail (GST_IS_REAL_PAD (pad));

725
726
  GST_RPAD_CONVERTFUNC (pad) = convert;

727
  GST_CAT_DEBUG (GST_CAT_PADS, "convertfunc for %s:%s  set to %s",
728
      GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (convert));
729
730
731
732
}

/**
 * gst_pad_set_query_function:
733
 * @pad: a real #GstPad of either direction.
734
 * @query: the #GstPadQueryFunction to set.
Wim Taymans's avatar
Wim Taymans committed
735
 *
736
 * Set the given query function for the pad.
Wim Taymans's avatar
Wim Taymans committed
737
 */
Wim Taymans's avatar
Wim Taymans committed
738
void
739
gst_pad_set_query_function (GstPad * pad, GstPadQueryFunction query)
740
{
741
  g_return_if_fail (GST_IS_REAL_PAD (pad));
742

743
  GST_RPAD_QUERYFUNC (pad) = query;
744

745
  GST_CAT_DEBUG (GST_CAT_PADS, "queryfunc for %s:%s  set to %s",
746
      GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (query));
Erik Walthinsen's avatar
Erik Walthinsen committed
747
748
}

Wim Taymans's avatar
Wim Taymans committed
749
750
/**
 * gst_pad_set_query_type_function:
751
 * @pad: a real #GstPad of either direction.
Wim Taymans's avatar
Wim Taymans committed
752
753
754
755
 * @type_func: the #GstPadQueryTypeFunction to set.
 *
 * Set the given query type function for the pad.
 */
756
void
757
758
gst_pad_set_query_type_function (GstPad * pad,
    GstPadQueryTypeFunction type_func)
759
760
761
762
763
{
  g_return_if_fail (GST_IS_REAL_PAD (pad));

  GST_RPAD_QUERYTYPEFUNC (pad) = type_func;

764
  GST_CAT_DEBUG (GST_CAT_PADS, "querytypefunc for %s:%s  set to %s",
765
      GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (type_func));
766
767
}

Wim Taymans's avatar
Wim Taymans committed
768
769
/**
 * gst_pad_get_query_types:
770
 * @pad: a #GstPad.
Wim Taymans's avatar
Wim Taymans committed
771
772
773
774
 *
 * Get an array of supported queries that can be performed
 * on this pad.
 *
775
 * Returns: a zero-terminated array of #GstQueryType.
Wim Taymans's avatar
Wim Taymans committed
776
 */
777
778
const GstQueryType *
gst_pad_get_query_types (GstPad * pad)
779
780
{
  GstRealPad *rpad;
781

782
  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
783
784
785

  rpad = GST_PAD_REALIZE (pad);

786
  g_return_val_if_fail (rpad, NULL);
787
788

  if (GST_RPAD_QUERYTYPEFUNC (rpad))
789
    return GST_RPAD_QUERYTYPEFUNC (rpad) (GST_PAD (pad));
790
791
792
793
794

  return NULL;
}

static gboolean
795
gst_pad_get_query_types_dispatcher (GstPad * pad, const GstQueryType ** data)
796
797
798
799
800
801
{
  *data = gst_pad_get_query_types (pad);

  return TRUE;
}

Wim Taymans's avatar
Wim Taymans committed
802
803
/**
 * gst_pad_get_query_types_default:
804
 * @pad: a #GstPad.
Wim Taymans's avatar
Wim Taymans committed
805
806
807
808
 *
 * Invoke the default dispatcher for the query types on
 * the pad.
 *
809
810
 * Returns: an zero-terminated array of #GstQueryType, or NULL if none of the
 * internally-linked pads has a query types function.
Wim Taymans's avatar
Wim Taymans committed
811
 */
812
813
const GstQueryType *
gst_pad_get_query_types_default (GstPad * pad)
814
{
815
  GstQueryType *result = NULL;
816

817
818
  g_return_val_if_fail (GST_IS_PAD (pad), NULL);

819
820
  gst_pad_dispatcher (pad, (GstPadDispatcherFunction)
      gst_pad_get_query_types_dispatcher, &result);
821
822
823
824

  return result;
}

Wim Taymans's avatar
Wim Taymans committed
825
/**
826
 * gst_pad_set_internal_link_function:
827
 * @pad: a real #GstPad of either direction.
David I. Lehn's avatar
David I. Lehn committed
828
 * @intlink: the #GstPadIntLinkFunction to set.
Wim Taymans's avatar
Wim Taymans committed
829
 *
830
 * Sets the given internal link function for the pad.
Wim Taymans's avatar
Wim Taymans committed
831
832
 */
void
833
gst_pad_set_internal_link_function (GstPad * pad, GstPadIntLinkFunction intlink)
Wim Taymans's avatar
Wim Taymans committed
834
835
836
{
  g_return_if_fail (GST_IS_REAL_PAD (pad));

David I. Lehn's avatar
David I. Lehn committed
837
  GST_RPAD_INTLINKFUNC (pad) = intlink;
838
  GST_CAT_DEBUG (GST_CAT_PADS, "internal link for %s:%s  set to %s",
839
      GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (intlink));
Wim Taymans's avatar
Wim Taymans committed
840
}
841

842
843
/**
 * gst_pad_set_formats_function:
844
 * @pad: a real #GstPad of either direction.
845
 * @formats: the #GstPadFormatsFunction to set.
846
 *
847
 * Sets the given formats function for the pad.
848
849
 */
void
850
gst_pad_set_formats_function (GstPad * pad, GstPadFormatsFunction formats)