gst-inspect.c 45.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/* GStreamer
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
 *               2000 Wim Taymans <wtay@chello.be>
 *               2004 Thomas Vander Stichele <thomas@apestaart.org>
 *
 * gst-inspect.c: tool to inspect the GStreamer registry
 *
 * 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.
 */

24 25 26 27
#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

28
#include "tools.h"
29

30
#include <string.h>
31
#include <locale.h>
32 33
#include <glib/gprintf.h>

34
static char *_name = NULL;
35 36 37 38

static int print_element_info (GstElementFactory * factory,
    gboolean print_names);

39
static void
40 41 42 43 44
n_print (const char *format, ...)
{
  va_list args;

  if (_name)
45
    g_print ("%s", _name);
46 47

  va_start (args, format);
48
  g_vprintf (format, args);
49 50
  va_end (args);
}
51

52
static gboolean
53
print_field (GQuark field, const GValue * value, gpointer pfx)
54 55 56
{
  gchar *str = gst_value_serialize (value);

57
  n_print ("%s  %15s: %s\n", (gchar *) pfx, g_quark_to_string (field), str);
58 59 60 61
  g_free (str);
  return TRUE;
}

Christian Meyer's avatar
Christian Meyer committed
62
static void
63
print_caps (const GstCaps * caps, const gchar * pfx)
64
{
65 66 67 68 69
  guint i;

  g_return_if_fail (caps != NULL);

  if (gst_caps_is_any (caps)) {
70
    n_print ("%sANY\n", pfx);
71 72 73
    return;
  }
  if (gst_caps_is_empty (caps)) {
74
    n_print ("%sEMPTY\n", pfx);
75 76 77 78 79 80
    return;
  }

  for (i = 0; i < gst_caps_get_size (caps); i++) {
    GstStructure *structure = gst_caps_get_structure (caps, i);

81
    n_print ("%s%s\n", pfx, gst_structure_get_name (structure));
82 83
    gst_structure_foreach (structure, print_field, (gpointer) pfx);
  }
84 85
}

86
#if 0
Christian Meyer's avatar
Christian Meyer committed
87
static void
88
print_formats (const GstFormat * formats)
89 90
{
  while (formats && *formats) {
91 92 93 94
    const GstFormatDefinition *definition;

    definition = gst_format_get_details (*formats);
    if (definition)
95
      n_print ("\t\t(%d):\t%s (%s)\n", *formats,
96
          definition->nick, definition->description);
Wim Taymans's avatar
Wim Taymans committed
97
    else
98
      n_print ("\t\t(%d):\tUnknown format\n", *formats);
Wim Taymans's avatar
Wim Taymans committed
99

100 101 102
    formats++;
  }
}
103

Christian Meyer's avatar
Christian Meyer committed
104
static void
105
print_event_masks (const GstEventMask * masks)
106 107 108 109 110 111
{
  GType event_type;
  GEnumClass *klass;
  GType event_flags;
  GFlagsClass *flags_class = NULL;

112
  event_type = gst_event_type_get_type ();
113 114 115 116 117 118 119 120
  klass = (GEnumClass *) g_type_class_ref (event_type);

  while (masks && masks->type) {
    GEnumValue *value;
    gint flags = 0, index = 0;

    switch (masks->type) {
      case GST_EVENT_SEEK:
121 122 123 124
        flags = masks->flags;
        event_flags = gst_seek_type_get_type ();
        flags_class = (GFlagsClass *) g_type_class_ref (event_flags);
        break;
125
      default:
126
        break;
127
    }
Christian Meyer's avatar
Christian Meyer committed
128

129
    value = g_enum_get_value (klass, masks->type);
Wim Taymans's avatar
Wim Taymans committed
130
    g_print ("\t\t%s ", value->value_nick);
131 132 133 134 135

    while (flags) {
      GFlagsValue *value;

      if (flags & 1) {
136
        value = g_flags_get_first_value (flags_class, 1 << index);
137

138 139 140 141
        if (value)
          g_print ("| %s ", value->value_nick);
        else
          g_print ("| ? ");
142 143 144 145
      }
      flags >>= 1;
      index++;
    }
Wim Taymans's avatar
Wim Taymans committed
146
    g_print ("\n");
Christian Meyer's avatar
Christian Meyer committed
147

148 149
    masks++;
  }
150
}
151
#endif
152

Benjamin Otte's avatar
Benjamin Otte committed
153
static const char *
154
get_rank_name (char *s, gint rank)
155
{
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
  static const int ranks[4] = {
    GST_RANK_NONE, GST_RANK_MARGINAL, GST_RANK_SECONDARY, GST_RANK_PRIMARY
  };
  static const char *rank_names[4] = { "none", "marginal", "secondary",
    "primary"
  };
  int i;
  int best_i;

  best_i = 0;
  for (i = 0; i < 4; i++) {
    if (rank == ranks[i])
      return rank_names[i];
    if (abs (rank - ranks[i]) < abs (rank - ranks[best_i])) {
      best_i = i;
    }
172
  }
173 174 175 176 177

  sprintf (s, "%s %c %d", rank_names[best_i],
      (rank - ranks[best_i] > 0) ? '+' : '-', abs (ranks[best_i] - rank));

  return s;
178 179
}

180
static gboolean
181
print_factory_details_metadata (GQuark field_id, const GValue * value,
182 183 184 185 186 187 188 189 190 191 192 193
    gpointer user_data)
{
  gchar *val = g_strdup_value_contents (value);
  gchar *key = g_strdup (g_quark_to_string (field_id));

  key[0] = g_ascii_toupper (key[0]);
  n_print ("  %s:\t\t%s\n", key, val);
  g_free (val);
  g_free (key);
  return TRUE;
}

194
static void
195 196
print_factory_details_info (GstElementFactory * factory)
{
197 198
  char s[20];

199 200
  n_print ("Factory Details:\n");
  n_print ("  Rank:\t\t%s (%d)\n",
201
      get_rank_name (s, GST_PLUGIN_FEATURE (factory)->rank),
202
      GST_PLUGIN_FEATURE (factory)->rank);
203 204
  gst_structure_foreach ((GstStructure *) factory->metadata,
      print_factory_details_metadata, NULL);
205
  n_print ("\n");
206 207 208 209
}

static void
print_hierarchy (GType type, gint level, gint * maxlevel)
210 211 212 213 214 215 216 217 218 219
{
  GType parent;
  gint i;

  parent = g_type_parent (type);

  *maxlevel = *maxlevel + 1;
  level++;

  if (parent)
220
    print_hierarchy (parent, level, maxlevel);
Christian Meyer's avatar
Christian Meyer committed
221

222
  if (_name)
223
    g_print ("%s", _name);
224

225 226 227
  for (i = 1; i < *maxlevel - level; i++)
    g_print ("      ");
  if (*maxlevel - level)
228 229 230
    g_print (" +----");

  g_print ("%s\n", g_type_name (type));
Christian Meyer's avatar
Christian Meyer committed
231

232
  if (level == 1)
233
    n_print ("\n");
234 235
}

236 237 238 239 240 241 242 243
static void
print_interfaces (GType type)
{
  guint n_ifaces;
  GType *iface, *ifaces = g_type_interfaces (type, &n_ifaces);

  if (ifaces) {
    if (n_ifaces) {
244
      if (_name)
245
        g_print ("%s", _name);
246
      g_print (_("Implemented Interfaces:\n"));
247 248
      iface = ifaces;
      while (*iface) {
249
        if (_name)
250
          g_print ("%s", _name);
251
        g_print ("  %s\n", g_type_name (*iface));
252 253
        iface++;
      }
254
      if (_name)
255
        g_print ("%s", _name);
256
      g_print ("\n");
257
    }
258
    g_free (ifaces);
259 260 261
  }
}

262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281
static gchar *
flags_to_string (GFlagsValue * vals, guint flags)
{
  GString *s = NULL;
  guint flags_left, i;

  /* first look for an exact match and count the number of values */
  for (i = 0; vals[i].value_name != NULL; ++i) {
    if (vals[i].value == flags)
      return g_strdup (vals[i].value_nick);
  }

  s = g_string_new (NULL);

  /* we assume the values are sorted from lowest to highest value */
  flags_left = flags;
  while (i > 0) {
    --i;
    if (vals[i].value != 0 && (flags_left & vals[i].value) == vals[i].value) {
      if (s->len > 0)
282
        g_string_append_c (s, '+');
283 284 285 286 287 288 289 290 291 292 293 294 295
      g_string_append (s, vals[i].value_nick);
      flags_left -= vals[i].value;
      if (flags_left == 0)
        break;
    }
  }

  if (s->len == 0)
    g_string_assign (s, "(none)");

  return g_string_free (s, FALSE);
}

296 297 298 299 300 301 302
#define KNOWN_PARAM_FLAGS \
  (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY | \
  G_PARAM_LAX_VALIDATION |  G_PARAM_STATIC_STRINGS | \
  G_PARAM_READABLE | G_PARAM_WRITABLE | GST_PARAM_CONTROLLABLE | \
  GST_PARAM_MUTABLE_PLAYING | GST_PARAM_MUTABLE_PAUSED | \
  GST_PARAM_MUTABLE_READY)

303
static void
304
print_element_properties_info (GstElement * element)
305 306
{
  GParamSpec **property_specs;
307
  guint num_properties, i;
Wim Taymans's avatar
Wim Taymans committed
308
  gboolean readable;
309
  gboolean first_flag;
Christian Meyer's avatar
Christian Meyer committed
310 311

  property_specs = g_object_class_list_properties
312
      (G_OBJECT_GET_CLASS (element), &num_properties);
313 314
  n_print ("\n");
  n_print ("Element Properties:\n");
315 316 317 318

  for (i = 0; i < num_properties; i++) {
    GValue value = { 0, };
    GParamSpec *param = property_specs[i];
319

Wim Taymans's avatar
Wim Taymans committed
320
    readable = FALSE;
321

Wim Taymans's avatar
Wim Taymans committed
322
    g_value_init (&value, param->value_type);
323 324 325 326 327

    n_print ("  %-20s: %s\n", g_param_spec_get_name (param),
        g_param_spec_get_blurb (param));

    first_flag = TRUE;
328
    n_print ("%-23.23s flags: ", "");
329 330
    if (param->flags & G_PARAM_READABLE) {
      g_object_get_property (G_OBJECT (element), param->name, &value);
Wim Taymans's avatar
Wim Taymans committed
331
      readable = TRUE;
332 333
      g_print ("%s%s", (first_flag) ? "" : ", ", _("readable"));
      first_flag = FALSE;
334
    }
335
    if (param->flags & G_PARAM_WRITABLE) {
336 337
      g_print ("%s%s", (first_flag) ? "" : ", ", _("writable"));
      first_flag = FALSE;
338 339
    }
    if (param->flags & GST_PARAM_CONTROLLABLE) {
340 341 342 343 344 345 346 347 348 349 350 351 352
      g_print (", %s", _("controllable"));
      first_flag = FALSE;
    }
    if (param->flags & GST_PARAM_MUTABLE_PLAYING) {
      g_print (", %s", _("changeable in NULL, READY, PAUSED or PLAYING state"));
    } else if (param->flags & GST_PARAM_MUTABLE_PAUSED) {
      g_print (", %s", _("changeable only in NULL, READY or PAUSED state"));
    } else if (param->flags & GST_PARAM_MUTABLE_READY) {
      g_print (", %s", _("changeable only in NULL or READY state"));
    }
    if (param->flags & ~KNOWN_PARAM_FLAGS) {
      g_print ("%s0x%0x", (first_flag) ? "" : ", ",
          param->flags & ~KNOWN_PARAM_FLAGS);
353 354
    }
    n_print ("\n");
355 356

    switch (G_VALUE_TYPE (&value)) {
Christian Meyer's avatar
Christian Meyer committed
357
      case G_TYPE_STRING:
358 359 360
      {
        GParamSpecString *pstring = G_PARAM_SPEC_STRING (param);

361
        n_print ("%-23.23s String. ", "");
362 363 364 365 366 367

        if (pstring->default_value == NULL)
          g_print ("Default: null ");
        else
          g_print ("Default: \"%s\" ", pstring->default_value);

368
        if (readable) {
369 370
          const char *string_val = g_value_get_string (&value);

371
          if (string_val == NULL)
372
            g_print ("Current: null");
373
          else
374
            g_print ("Current: \"%s\"", string_val);
375 376
        }
        break;
377
      }
Christian Meyer's avatar
Christian Meyer committed
378
      case G_TYPE_BOOLEAN:
379 380 381
      {
        GParamSpecBoolean *pboolean = G_PARAM_SPEC_BOOLEAN (param);

382
        n_print ("%-23.23s Boolean. ", "");
383
        g_print ("Default: %s ", (pboolean->default_value ? "true" : "false"));
384
        if (readable)
385
          g_print ("Current: %s",
386 387
              (g_value_get_boolean (&value) ? "true" : "false"));
        break;
388
      }
Christian Meyer's avatar
Christian Meyer committed
389
      case G_TYPE_ULONG:
390
      {
391
        GParamSpecULong *pulong = G_PARAM_SPEC_ULONG (param);
392

393
        n_print ("%-23.23s Unsigned Long. ", "");
394 395
        g_print ("Range: %lu - %lu Default: %lu ",
            pulong->minimum, pulong->maximum, pulong->default_value);
396
        if (readable)
397
          g_print ("Current: %lu", g_value_get_ulong (&value));
398
        break;
399
      }
Christian Meyer's avatar
Christian Meyer committed
400
      case G_TYPE_LONG:
401
      {
402
        GParamSpecLong *plong = G_PARAM_SPEC_LONG (param);
403

404
        n_print ("%-23.23s Long. ", "");
405 406
        g_print ("Range: %ld - %ld Default: %ld ",
            plong->minimum, plong->maximum, plong->default_value);
407
        if (readable)
408
          g_print ("Current: %ld", g_value_get_long (&value));
409
        break;
410
      }
Christian Meyer's avatar
Christian Meyer committed
411
      case G_TYPE_UINT:
412
      {
413
        GParamSpecUInt *puint = G_PARAM_SPEC_UINT (param);
414

415
        n_print ("%-23.23s Unsigned Integer. ", "");
416 417
        g_print ("Range: %u - %u Default: %u ",
            puint->minimum, puint->maximum, puint->default_value);
418
        if (readable)
419
          g_print ("Current: %u", g_value_get_uint (&value));
420
        break;
421
      }
Christian Meyer's avatar
Christian Meyer committed
422
      case G_TYPE_INT:
423
      {
424
        GParamSpecInt *pint = G_PARAM_SPEC_INT (param);
425

426
        n_print ("%-23.23s Integer. ", "");
427 428
        g_print ("Range: %d - %d Default: %d ",
            pint->minimum, pint->maximum, pint->default_value);
429
        if (readable)
430
          g_print ("Current: %d", g_value_get_int (&value));
431
        break;
432
      }
Christian Meyer's avatar
Christian Meyer committed
433
      case G_TYPE_UINT64:
434
      {
435 436
        GParamSpecUInt64 *puint64 = G_PARAM_SPEC_UINT64 (param);

437
        n_print ("%-23.23s Unsigned Integer64. ", "");
438 439 440
        g_print ("Range: %" G_GUINT64_FORMAT " - %" G_GUINT64_FORMAT
            " Default: %" G_GUINT64_FORMAT " ",
            puint64->minimum, puint64->maximum, puint64->default_value);
441
        if (readable)
442
          g_print ("Current: %" G_GUINT64_FORMAT, g_value_get_uint64 (&value));
443
        break;
444
      }
Christian Meyer's avatar
Christian Meyer committed
445
      case G_TYPE_INT64:
446
      {
447 448
        GParamSpecInt64 *pint64 = G_PARAM_SPEC_INT64 (param);

449
        n_print ("%-23.23s Integer64. ", "");
450 451 452
        g_print ("Range: %" G_GINT64_FORMAT " - %" G_GINT64_FORMAT
            " Default: %" G_GINT64_FORMAT " ",
            pint64->minimum, pint64->maximum, pint64->default_value);
453
        if (readable)
454
          g_print ("Current: %" G_GINT64_FORMAT, g_value_get_int64 (&value));
455
        break;
456
      }
Christian Meyer's avatar
Christian Meyer committed
457
      case G_TYPE_FLOAT:
458
      {
459
        GParamSpecFloat *pfloat = G_PARAM_SPEC_FLOAT (param);
460

461 462 463 464
        n_print ("%-23.23s Float. ", "");
        g_print ("Range: %15.7g - %15.7g Default: %15.7g ",
            pfloat->minimum, pfloat->maximum, pfloat->default_value);
        if (readable)
465
          g_print ("Current: %15.7g", g_value_get_float (&value));
466
        break;
467
      }
Christian Meyer's avatar
Christian Meyer committed
468
      case G_TYPE_DOUBLE:
469
      {
470
        GParamSpecDouble *pdouble = G_PARAM_SPEC_DOUBLE (param);
471

472 473 474 475
        n_print ("%-23.23s Double. ", "");
        g_print ("Range: %15.7g - %15.7g Default: %15.7g ",
            pdouble->minimum, pdouble->maximum, pdouble->default_value);
        if (readable)
476
          g_print ("Current: %15.7g", g_value_get_double (&value));
477
        break;
478 479
      }
      default:
480 481 482 483
        if (param->value_type == GST_TYPE_CAPS) {
          const GstCaps *caps = gst_value_get_caps (&value);

          if (!caps)
484
            n_print ("%-23.23s Caps (NULL)", "");
485 486 487 488
          else {
            print_caps (caps, "                           ");
          }
        } else if (G_IS_PARAM_SPEC_ENUM (param)) {
489
          GParamSpecEnum *penum = G_PARAM_SPEC_ENUM (param);
490 491 492
          GEnumValue *values;
          guint j = 0;
          gint enum_value;
493
          const gchar *def_val_nick = "", *cur_val_nick = "";
494 495 496 497 498 499

          values = G_ENUM_CLASS (g_type_class_ref (param->value_type))->values;
          enum_value = g_value_get_enum (&value);

          while (values[j].value_name) {
            if (values[j].value == enum_value)
500 501 502
              cur_val_nick = values[j].value_nick;
            if (values[j].value == penum->default_value)
              def_val_nick = values[j].value_nick;
503 504 505
            j++;
          }

506 507 508 509
          n_print
              ("%-23.23s Enum \"%s\" Default: %d, \"%s\" Current: %d, \"%s\"",
              "", g_type_name (G_VALUE_TYPE (&value)), penum->default_value,
              def_val_nick, enum_value, cur_val_nick);
510 511 512

          j = 0;
          while (values[j].value_name) {
513 514
            g_print ("\n");
            if (_name)
515
              g_print ("%s", _name);
516 517
            g_print ("%-23.23s    (%d): %-16s - %s", "",
                values[j].value, values[j].value_nick, values[j].value_name);
518 519 520 521
            j++;
          }
          /* g_type_class_unref (ec); */
        } else if (G_IS_PARAM_SPEC_FLAGS (param)) {
522
          GParamSpecFlags *pflags = G_PARAM_SPEC_FLAGS (param);
523 524
          GFlagsValue *vals;
          gchar *cur, *def;
525

526
          vals = pflags->flags_class->values;
527

528 529
          cur = flags_to_string (vals, g_value_get_flags (&value));
          def = flags_to_string (vals, pflags->default_value);
530

531
          n_print
532
              ("%-23.23s Flags \"%s\" Default: 0x%08x, \"%s\" Current: 0x%08x, \"%s\"",
533
              "", g_type_name (G_VALUE_TYPE (&value)), pflags->default_value,
534
              def, g_value_get_flags (&value), cur);
535

536
          while (vals[0].value_name) {
537 538
            g_print ("\n");
            if (_name)
539
              g_print ("%s", _name);
540
            g_print ("%-23.23s    (0x%08x): %-16s - %s", "",
541 542
                vals[0].value, vals[0].value_nick, vals[0].value_name);
            ++vals;
543 544
          }

545 546
          g_free (cur);
          g_free (def);
547
        } else if (G_IS_PARAM_SPEC_OBJECT (param)) {
548
          n_print ("%-23.23s Object of type \"%s\"", "",
549
              g_type_name (param->value_type));
550 551 552 553 554 555 556 557 558 559
        } else if (G_IS_PARAM_SPEC_BOXED (param)) {
          n_print ("%-23.23s Boxed pointer of type \"%s\"", "",
              g_type_name (param->value_type));
        } else if (G_IS_PARAM_SPEC_POINTER (param)) {
          if (param->value_type != G_TYPE_POINTER) {
            n_print ("%-23.23s Pointer of type \"%s\".", "",
                g_type_name (param->value_type));
          } else {
            n_print ("%-23.23s Pointer.", "");
          }
560
        } else if (param->value_type == G_TYPE_VALUE_ARRAY) {
561 562 563 564 565 566 567 568
          GParamSpecValueArray *pvarray = G_PARAM_SPEC_VALUE_ARRAY (param);

          if (pvarray->element_spec) {
            n_print ("%-23.23s Array of GValues of type \"%s\"", "",
                g_type_name (pvarray->element_spec->value_type));
          } else {
            n_print ("%-23.23s Array of GValues", "");
          }
569 570 571 572 573 574 575 576 577 578 579 580 581 582
        } else if (GST_IS_PARAM_SPEC_FRACTION (param)) {
          GstParamSpecFraction *pfraction = GST_PARAM_SPEC_FRACTION (param);

          n_print ("%-23.23s Fraction. ", "");

          g_print ("Range: %d/%d - %d/%d Default: %d/%d ",
              pfraction->min_num, pfraction->min_den,
              pfraction->max_num, pfraction->max_den,
              pfraction->def_num, pfraction->def_den);
          if (readable)
            g_print ("Current: %d/%d",
                gst_value_get_fraction_numerator (&value),
                gst_value_get_fraction_denominator (&value));

583
        } else {
584
          n_print ("%-23.23s Unknown type %ld \"%s\"", "", param->value_type,
585 586 587
              g_type_name (param->value_type));
        }
        break;
588
    }
Christian Meyer's avatar
Christian Meyer committed
589
    if (!readable)
590
      g_print (" Write only\n");
Christian Meyer's avatar
Christian Meyer committed
591
    else
Wim Taymans's avatar
Wim Taymans committed
592
      g_print ("\n");
593 594

    g_value_reset (&value);
595
  }
Christian Meyer's avatar
Christian Meyer committed
596
  if (num_properties == 0)
597
    n_print ("  none\n");
Stefan Kost's avatar
Stefan Kost committed
598 599

  g_free (property_specs);
600 601
}

602
static void
603
print_pad_templates_info (GstElement * element, GstElementFactory * factory)
Wim Taymans's avatar
Wim Taymans committed
604
{
605
  GstElementClass *gstelement_class;
606
  const GList *pads;
607
  GstStaticPadTemplate *padtemplate;
608

609
  n_print ("Pad Templates:\n");
610
  if (!factory->numpadtemplates) {
611
    n_print ("  none\n");
612
    return;
613
  }
614

615
  gstelement_class = GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS (element));
616

617
  pads = factory->staticpadtemplates;
618
  while (pads) {
619
    padtemplate = (GstStaticPadTemplate *) (pads->data);
620
    pads = g_list_next (pads);
621

622
    if (padtemplate->direction == GST_PAD_SRC)
623
      n_print ("  SRC template: '%s'\n", padtemplate->name_template);
624
    else if (padtemplate->direction == GST_PAD_SINK)
625
      n_print ("  SINK template: '%s'\n", padtemplate->name_template);
626
    else
627
      n_print ("  UNKNOWN!!! template: '%s'\n", padtemplate->name_template);
628 629

    if (padtemplate->presence == GST_PAD_ALWAYS)
630
      n_print ("    Availability: Always\n");
631
    else if (padtemplate->presence == GST_PAD_SOMETIMES)
632
      n_print ("    Availability: Sometimes\n");
633
    else if (padtemplate->presence == GST_PAD_REQUEST) {
634 635
      n_print ("    Availability: On request\n");
      n_print ("      Has request_new_pad() function: %s\n",
636 637
          GST_DEBUG_FUNCPTR_NAME (gstelement_class->request_new_pad));
    } else
638
      n_print ("    Availability: UNKNOWN!!!\n");
639

640
    if (padtemplate->static_caps.string) {
641
      n_print ("    Capabilities:\n");
642
      print_caps (gst_static_caps_get (&padtemplate->static_caps), "      ");
643 644
    }

645
    n_print ("\n");
646 647 648 649 650 651 652
  }
}

static void
print_element_flag_info (GstElement * element)
{
  gboolean have_flags = FALSE;
Wim Taymans's avatar
Wim Taymans committed
653

654 655
  n_print ("\n");
  n_print ("Element Flags:\n");
656

Wim Taymans's avatar
Wim Taymans committed
657
  if (!have_flags)
658
    n_print ("  no flags set\n");
659

Wim Taymans's avatar
Wim Taymans committed
660
  if (GST_IS_BIN (element)) {
661 662
    n_print ("\n");
    n_print ("Bin Flags:\n");
Wim Taymans's avatar
Wim Taymans committed
663
    if (!have_flags)
664
      n_print ("  no flags set\n");
Wim Taymans's avatar
Wim Taymans committed
665
  }
666
}
Wim Taymans's avatar
Wim Taymans committed
667

668 669 670 671
static void
print_implementation_info (GstElement * element)
{
  GstElementClass *gstelement_class;
672

673
  gstelement_class = GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS (element));
674

675 676
  n_print ("\n");
  n_print ("Element Implementation:\n");
677

678
  n_print ("  Has change_state() function: %s\n",
679
      GST_DEBUG_FUNCPTR_NAME (gstelement_class->change_state));
680
}
681

682 683 684 685 686 687
static void
print_clocking_info (GstElement * element)
{
  if (!gst_element_requires_clock (element) &&
      !(gst_element_provides_clock (element) &&
          gst_element_get_clock (element))) {
688 689
    n_print ("\n");
    n_print ("Element has no clocking capabilities.");
690 691
    return;
  }
Wim Taymans's avatar
Wim Taymans committed
692

693 694
  n_print ("\n");
  n_print ("Clocking Interaction:\n");
695
  if (gst_element_requires_clock (element)) {
696
    n_print ("  element requires a clock\n");
Wim Taymans's avatar
Wim Taymans committed
697
  }
698

699
  if (gst_element_provides_clock (element)) {
Wim Taymans's avatar
Wim Taymans committed
700 701 702
    GstClock *clock;

    clock = gst_element_get_clock (element);
Andy Wingo Wingo's avatar
Andy Wingo Wingo committed
703
    if (clock)
704
      n_print ("  element provides a clock: %s\n", GST_OBJECT_NAME (clock));
705
    else
706
      n_print ("  element is supposed to provide a clock but returned NULL\n");
Wim Taymans's avatar
Wim Taymans committed
707
  }
708 709 710 711 712
}

static void
print_index_info (GstElement * element)
{
Wim Taymans's avatar
Wim Taymans committed
713
  if (gst_element_is_indexable (element)) {
714 715 716
    n_print ("\n");
    n_print ("Indexing capabilities:\n");
    n_print ("  element can do indexing\n");
717
  } else {
718 719
    n_print ("\n");
    n_print ("Element has no indexing capabilities.\n");
720
  }
721
}
722

723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755
static void
print_uri_handler_info (GstElement * element)
{
  if (GST_IS_URI_HANDLER (element)) {
    const gchar *uri_type;
    gchar **uri_protocols;

    if (gst_uri_handler_get_uri_type (GST_URI_HANDLER (element)) == GST_URI_SRC)
      uri_type = "source";
    else if (gst_uri_handler_get_uri_type (GST_URI_HANDLER (element)) ==
        GST_URI_SINK)
      uri_type = "sink";
    else
      uri_type = "unknown";

    uri_protocols = gst_uri_handler_get_protocols (GST_URI_HANDLER (element));

    n_print ("\n");
    n_print ("URI handling capabilities:\n");
    n_print ("  Element can act as %s.\n", uri_type);

    if (uri_protocols && *uri_protocols) {
      n_print ("  Supported URI protocols:\n");
      for (; *uri_protocols != NULL; uri_protocols++)
        n_print ("    %s\n", *uri_protocols);
    } else {
      n_print ("  No supported URI protocols\n");
    }
  } else {
    n_print ("Element has no URI handling capabilities.\n");
  }
}

756 757 758 759 760 761
static void
print_pad_info (GstElement * element)
{
  const GList *pads;
  GstPad *pad;

762 763
  n_print ("\n");
  n_print ("Pads:\n");
764

765
  if (!element->numpads) {
766
    n_print ("  none\n");
767 768
    return;
  }
769

770
  pads = element->pads;
771
  while (pads) {
772
    gchar *name;
Wim Taymans's avatar
Wim Taymans committed
773
    GstCaps *caps;
774

775 776
    pad = GST_PAD (pads->data);
    pads = g_list_next (pads);
777

778 779
    n_print ("");

780
    name = gst_pad_get_name (pad);
781
    if (gst_pad_get_direction (pad) == GST_PAD_SRC)
782
      g_print ("  SRC: '%s'", name);
783
    else if (gst_pad_get_direction (pad) == GST_PAD_SINK)
784
      g_print ("  SINK: '%s'", name);
785
    else
786 787 788
      g_print ("  UNKNOWN!!!: '%s'", name);

    g_free (name);
789

790
    g_print ("\n");
791

792
    n_print ("    Implementation:\n");