gst_plugins_base/gst-libs/gst/pbutils/descriptions.c
changeset 0 0e761a78d257
child 7 567bb019e3e3
equal deleted inserted replaced
-1:000000000000 0:0e761a78d257
       
     1 /* GStreamer Plugins Base utils library source/sink/codec description support
       
     2  * Copyright (C) 2006 Tim-Philipp Müller <tim centricular net>
       
     3  *
       
     4  * This library is free software; you can redistribute it and/or
       
     5  * modify it under the terms of the GNU Library General Public
       
     6  * License as published by the Free Software Foundation; either
       
     7  * version 2 of the License, or (at your option) any later version.
       
     8  *
       
     9  * This library is distributed in the hope that it will be useful,
       
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    12  * Library General Public License for more details.
       
    13  *
       
    14  * You should have received a copy of the GNU Library General Public
       
    15  * License along with this library; if not, write to the
       
    16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
       
    17  * Boston, MA 02111-1307, USA.
       
    18  */
       
    19 
       
    20 /**
       
    21  * SECTION:gstpbutilsdescriptions
       
    22  * @short_description: Provides human-readable descriptions for caps/codecs
       
    23  * and encoder, decoder, URI source and URI sink elements
       
    24  *
       
    25  * <refsect2>
       
    26  * <para>
       
    27  * The above functions provide human-readable strings for media formats
       
    28  * and decoder/demuxer/depayloader/encoder/muxer/payloader elements for use
       
    29  * in error dialogs or other messages shown to users.
       
    30  * </para>
       
    31  * <para>
       
    32  * gst_pb_utils_add_codec_description_to_tag_list() is a utility function
       
    33  * for demuxer and decoder elements to add audio/
       
    34 #ifdef __SYMBIAN32__
       
    35 EXPORT_C
       
    36 #endif
       
    37 video codec tags from a
       
    38  * given (fixed) #GstCaps.
       
    39  * </para>
       
    40  * </refsect2>
       
    41  */
       
    42 
       
    43 #ifdef HAVE_CONFIG_H
       
    44 # include "config.h"
       
    45 #endif
       
    46 
       
    47 #ifdef __SYMBIAN32__
       
    48 #include <gst_global.h>
       
    49 #endif
       
    50 
       
    51 #include "gst/gst-i18n-plugin.h"
       
    52 
       
    53 #include "pbutils.h"
       
    54 
       
    55 #include <string.h>
       
    56 
       
    57 typedef enum
       
    58 {
       
    59   FLAG_CONTAINER = (1 << 0),    /* format is a container format (muxed)             */
       
    60   FLAG_SYSTEMSTREAM = (1 << 1)  /* match record only if caps have systemstream=true */
       
    61 } FormatFlags;
       
    62 
       
    63 typedef struct
       
    64 {
       
    65   const gchar *type;
       
    66   const gchar *desc;
       
    67   FormatFlags flags;
       
    68 } FormatInfo;
       
    69 
       
    70 static const FormatInfo formats[] = {
       
    71   /* container/tag formats with static descriptions */
       
    72   {"application/ogg", "Ogg", FLAG_CONTAINER},
       
    73   {"application/vnd.rn-realmedia", "Realmedia", FLAG_CONTAINER},
       
    74   {"application/x-id3", N_("ID3 tag"), FLAG_CONTAINER},
       
    75   {"application/x-ape", N_("APE tag"), FLAG_CONTAINER},
       
    76   {"application/x-icy", N_("ICY internet radio"), FLAG_CONTAINER},
       
    77   {"video/x-fli", "FLI/FLC/FLX Animation", FLAG_CONTAINER},
       
    78   {"video/x-flv", "Flash", FLAG_CONTAINER},
       
    79   {"video/x-matroska", "Matroska", FLAG_CONTAINER},
       
    80   {"video/x-ms-asf", "Advanced Streaming Format (ASF)", FLAG_CONTAINER},
       
    81   {"video/x-msvideo", "AVI", FLAG_CONTAINER},
       
    82   {"video/x-quicktime", "Quicktime", FLAG_CONTAINER},
       
    83   {"video/quicktime", "Quicktime", FLAG_CONTAINER},
       
    84 
       
    85   /* audio formats with static descriptions */
       
    86   {"audio/x-ac3", "AC-3 (ATSC A/52)", 0},
       
    87   {"audio/ac3", "AC-3 (ATSC A/52)", 0},
       
    88   {"audio/x-private-ac3", "DVD AC-3 (ATSC A/52)", 0},
       
    89   {"audio/x-private1-ac3", "DVD AC-3 (ATSC A/52)", 0},
       
    90   {"audio/x-alaw", "A-Law", 0},
       
    91   {"audio/amr", "Adaptive Multi Rate (AMR)", 0},
       
    92   {"audio/AMR", "Adaptive Multi Rate (AMR)", 0},
       
    93   {"audio/AMR-WB", "Adaptive Multi Rate WideBand (AMR-WB)", 0},
       
    94   {"audio/iLBC-sh", "Internet Low Bitrate Codec (iLBC)", 0},
       
    95   {"audio/ms-gsm", "MS GSM", 0},
       
    96   {"audio/qcelp", "QCELP", 0},
       
    97   {"audio/aiff", "Audio Interchange File Format (AIFF)", 0},
       
    98   {"audio/x-aiff", "Audio Interchange File Format (AIFF)", 0},
       
    99   {"audio/x-alac", N_("Apple Lossless Audio (ALAC)"), 0},
       
   100   {"audio/x-amr-nb-sh", "Adaptive Multi Rate NarrowBand (AMR-NB)", 0},
       
   101   {"audio/x-amr-wb-sh", "Adaptive Multi Rate WideBand (AMR-WB)", 0},
       
   102   {"audio/x-au", "Sun .au", 0},
       
   103   {"audio/x-cinepak", "Cinepak Audio", 0},
       
   104   {"audio/x-dpcm", "DPCM", 0},
       
   105   {"audio/x-dts", "DTS", 0},
       
   106   {"audio/x-private1-dts", "DTS", 0},
       
   107   {"audio/x-dv", "DV Audio", 0},
       
   108   {"audio/x-flac", N_("Free Lossless Audio Codec (FLAC)"), 0},
       
   109   {"audio/x-gsm", "GSM", 0},
       
   110   {"audio/x-iec958", "S/PDIF IEC958", 0},       /* TODO: check description */
       
   111   {"audio/x-iLBC", "Internet Low Bitrate Codec (iLBC)", 0},
       
   112   {"audio/x-ircam", "Berkeley/IRCAM/CARL", 0},
       
   113   {"audio/x-lpcm", "LPCM", 0},
       
   114   {"audio/x-private1-lpcm", "DVD LPCM", 0},
       
   115   {"audio/x-m4a", "MPEG-4 AAC", FLAG_CONTAINER},
       
   116   {"audio/x-mod", "Module Music Format (MOD)", 0},
       
   117   {"audio/x-mulaw", "Mu-Law", 0},
       
   118   {"audio/x-musepack", "Musepack (MPC)", 0},
       
   119   {"audio/x-nellymoser", "Nellymoser Asao", 0},
       
   120   {"audio/x-nist", "Sphere NIST", 0},
       
   121   {"audio/x-nsf", "Nintendo NSF", 0},
       
   122   {"audio/x-paris", "Ensoniq PARIS", 0},
       
   123   {"audio/x-qdm2", "QDesign Music (QDM) 2", 0},
       
   124   {"audio/x-ralf-mpeg4-generic", "Real Audio Lossless (RALF)", 0},
       
   125   {"audio/x-sds", "SDS", 0},
       
   126   {"audio/x-shorten", "Shorten Lossless", 0},
       
   127   {"audio/x-sid", "Sid", 0},
       
   128   {"audio/x-sipro", "Sipro/ACELP.NET Voice", 0},
       
   129   {"audio/x-spc", "SNES-SPC700 Sound File Data", 0},
       
   130   {"audio/x-speex", "Speex", 0},
       
   131   {"audio/x-svx", "Amiga IFF / SVX8 / SV16", 0},
       
   132   {"audio/x-tta", N_("Lossless True Audio (TTA)"), 0},
       
   133   {"audio/x-ttafile", N_("Lossless True Audio (TTA)"), 0},
       
   134   {"audio/x-vnd.sony.atrac3", "Sony ATRAC3", 0},
       
   135   {"audio/x-vorbis", "Vorbis", 0},
       
   136   {"audio/x-voc", "SoundBlaster VOC", 0},
       
   137   {"audio/x-w64", "Sonic Foundry Wave64", 0},
       
   138   {"audio/x-wav", "WAV", 0},
       
   139   {"audio/x-wavpack", "Wavpack", 0},
       
   140   {"audio/x-wavpack-correction", "Wavpack", 0},
       
   141   {"audio/x-wms", N_("Windows Media Speech"), 0},
       
   142   {"audio/x-voxware", "Voxware", 0},
       
   143 
       
   144 
       
   145   /* video formats with static descriptions */
       
   146   {"video/sp5x", "Sunplus JPEG 5.x", 0},
       
   147   {"video/vivo", "Vivo", 0},
       
   148   {"video/x-3ivx", "3ivx", 0},
       
   149   {"video/x-4xm", "4X Techologies Video", 0},
       
   150   {"video/x-apple-video", "Apple video", 0},
       
   151   {"video/x-camtasia", "TechSmith Camtasia", 0},
       
   152   {"video/x-cdxa", "RIFF/CDXA (VCD)", 0},
       
   153   {"video/x-cinepak", "Cinepak Video", 0},
       
   154   {"video/x-cirrus-logic-accupak", "Cirrus Logipak AccuPak", 0},
       
   155   {"video/x-compressed-yuv", N_("CYUV Lossless"), 0},
       
   156   {"video/x-dirac", "Dirac", 0},
       
   157   {"video/x-dvd-subpicture", "DVD subpicture", 0},
       
   158   {"video/x-ffv", N_("FFMpeg v1"), 0},
       
   159   {"video/x-flash-screen", "Flash Screen Video", 0},
       
   160   {"video/x-flash-video", "Flash Video", 0},
       
   161   {"video/x-h261", "H.261", 0},
       
   162   {"video/x-huffyuv", "Huffyuv", 0},
       
   163   {"video/x-intel-h263", "Intel H.263", 0},
       
   164   {"video/x-jpeg", "Motion JPEG", 0},
       
   165   /* { "video/x-jpeg-b", "", 0 }, does this actually exist? */
       
   166   {"video/x-mjpeg", "Motion-JPEG", 0},
       
   167   {"video/x-mjpeg-b", "Motion-JPEG format B", 0},
       
   168   {"video/mpegts", "MPEG-2 Transport Stream", FLAG_CONTAINER},
       
   169   {"video/x-mng", "Multiple Image Network Graphics (MNG)", 0},
       
   170   {"video/x-mszh", N_("Lossless MSZH"), 0},
       
   171   {"video/x-msvideocodec", "Microsoft Video 1", 0},
       
   172   {"video/x-mve", "Interplay MVE", FLAG_CONTAINER},
       
   173   {"video/x-nut", "NUT", FLAG_CONTAINER},
       
   174   {"video/x-nuv", "MythTV NuppelVideo (NUV)", FLAG_CONTAINER},
       
   175   {"video/x-qdrw", "Apple QuickDraw", 0},
       
   176   {"video/x-raw-gray", N_("Uncompressed Gray Image"), 0},
       
   177   {"video/x-smc", "Apple SMC", 0},
       
   178   {"video/x-smoke", "Smoke", 0},
       
   179   {"video/x-tarkin", "Tarkin", 0},
       
   180   {"video/x-theora", "Theora", 0},
       
   181   {"video/x-rle", N_("Run-length encoding"), 0},
       
   182   {"video/x-ultimotion", "IBM UltiMotion", 0},
       
   183   {"video/x-vcd", "VideoCD (VCD)", 0},
       
   184   {"video/x-vmnc", "VMWare NC", 0},
       
   185   {"video/x-vp3", "On2 VP3", 0},
       
   186   {"video/x-vp5", "On2 VP5", 0},
       
   187   {"video/x-vp6", "On2 VP6", 0},
       
   188   {"video/x-vp6-flash", "On2 VP6/Flash", 0},
       
   189   {"video/x-vp7", "On2 VP7", 0},
       
   190   {"video/x-xvid", "XVID MPEG-4", 0},
       
   191   {"video/x-zlib", "Lossless zlib video", 0},
       
   192 
       
   193   /* image formats with static descriptions */
       
   194   {"image/bmp", "BMP", 0},
       
   195   {"image/x-bmp", "BMP", 0},
       
   196   {"image/x-MS-bmp", "BMP", 0},
       
   197   {"image/gif", "GIF", 0},
       
   198   {"image/jpeg", "JPEG", 0},
       
   199   {"image/jng", "JPEG Network Graphics (JNG)", 0},
       
   200   {"image/png", "PNG", 0},
       
   201   {"image/pbm", "PBM", 0},
       
   202   {"image/ppm", "PPM", 0},
       
   203   {"image/svg+xml", "Scalable Vector Graphics (SVG)", 0},
       
   204   {"image/tiff", "TIFF", 0},
       
   205   {"image/x-cmu-raster", "CMU Raster Format", 0},
       
   206   {"image/x-icon", "ICO", 0},
       
   207   {"image/x-xcf", "XFC", 0},
       
   208   {"image/x-pixmap", "XPM", 0},
       
   209   {"image/x-xpixmap", "XPM", 0},
       
   210   {"image/x-quicktime", "QuickTime Image Format (QTIF)", 0},
       
   211   {"image/x-sun-raster", "Sun Raster Format (RAS)", 0},
       
   212   {"image/x-tga", "TGA", 0},
       
   213 
       
   214   /* subtitle formats with static descriptions */
       
   215   {"application/x-subtitle-sami", N_("Sami subtitle format"), 0},
       
   216   {"application/x-subtitle-tmplayer", N_("TMPlayer subtitle format"), 0},
       
   217   /* add variant field to typefinder? { "application/x-subtitle", N_("subtitle"), 0}, */
       
   218 
       
   219   /* formats with dynamic descriptions */
       
   220   {"audio/mpeg", NULL, 0},
       
   221   {"audio/x-adpcm", NULL, 0},
       
   222   {"audio/x-mace", NULL, 0},
       
   223   {"audio/x-pn-realaudio", NULL, 0},
       
   224   {"audio/x-raw-int", NULL, 0},
       
   225   {"audio/x-raw-float", NULL, 0},
       
   226   {"audio/x-wma", NULL, 0},
       
   227   {"video/mpeg", NULL, FLAG_CONTAINER | FLAG_SYSTEMSTREAM},
       
   228   {"video/mpeg", NULL, 0},
       
   229   {"video/x-asus", NULL, 0},
       
   230   {"video/x-ati-vcr", NULL, 0},
       
   231   {"video/x-divx", NULL, 0},
       
   232   {"video/x-dv", "Digital Video (DV) System Stream",
       
   233       FLAG_CONTAINER | FLAG_SYSTEMSTREAM},
       
   234   {"video/x-dv", "Digital Video (DV)", 0},
       
   235   {"video/x-h263", NULL, 0},
       
   236   {"video/x-h264", NULL, 0},
       
   237   {"video/x-indeo", NULL, 0},
       
   238   {"video/x-msmpeg", NULL, 0},
       
   239   {"video/x-pn-realvideo", NULL, 0},
       
   240 #if 0
       
   241   /* do these exist? are they used anywhere? */
       
   242   {"video/x-pn-multirate-realvideo", NULL, 0},
       
   243   {"audio/x-pn-multirate-realaudio", NULL, 0},
       
   244   {"audio/x-pn-multirate-realaudio-live", NULL, 0},
       
   245 #endif
       
   246   {"video/x-truemotion", NULL, 0},
       
   247   {"video/x-raw-rgb", NULL, 0},
       
   248   {"video/x-raw-yuv", NULL, 0},
       
   249   {"video/x-svq", NULL, 0},
       
   250   {"video/x-wmv", NULL, 0},
       
   251   {"video/x-xan", NULL, 0}
       
   252 };
       
   253 
       
   254 /* returns static descriptions and dynamic ones (such as video/x-raw-yuv),
       
   255  * or NULL if caps aren't known at all */
       
   256 static gchar *
       
   257 format_info_get_desc (const FormatInfo * info, const GstCaps * caps)
       
   258 {
       
   259   const GstStructure *s;
       
   260 
       
   261   g_assert (info != NULL);
       
   262 
       
   263   if (info->desc != NULL)
       
   264     return g_strdup (_(info->desc));
       
   265 
       
   266   s = gst_caps_get_structure (caps, 0);
       
   267 
       
   268   if (strcmp (info->type, "video/x-raw-yuv") == 0) {
       
   269     const gchar *ret = NULL;
       
   270     guint32 fourcc = 0;
       
   271 
       
   272     gst_structure_get_fourcc (s, "format", &fourcc);
       
   273     switch (fourcc) {
       
   274       case GST_MAKE_FOURCC ('I', '4', '2', '0'):
       
   275         ret = _("Uncompressed planar YUV 4:2:0");
       
   276         break;
       
   277       case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
       
   278         ret = _("Uncompressed planar YVU 4:2:0");
       
   279         break;
       
   280       case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
       
   281         ret = _("Uncompressed packed YUV 4:2:2");
       
   282         break;
       
   283       case GST_MAKE_FOURCC ('Y', 'U', 'V', '9'):
       
   284         ret = _("Uncompressed packed YUV 4:1:0");
       
   285         break;
       
   286       case GST_MAKE_FOURCC ('Y', 'V', 'U', '9'):
       
   287         ret = _("Uncompressed packed YVU 4:1:0");
       
   288         break;
       
   289       case GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'):
       
   290       case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
       
   291         ret = _("Uncompressed packed YUV 4:2:2");
       
   292         break;
       
   293       case GST_MAKE_FOURCC ('Y', '4', '1', 'P'):
       
   294         ret = _("Uncompressed packed YUV 4:1:1");
       
   295         break;
       
   296       case GST_MAKE_FOURCC ('I', 'Y', 'U', '2'):
       
   297         ret = _("Uncompressed packed YUV 4:4:4");
       
   298         break;
       
   299       case GST_MAKE_FOURCC ('Y', '4', '2', 'B'):
       
   300         ret = _("Uncompressed planar YUV 4:2:2");
       
   301         break;
       
   302       case GST_MAKE_FOURCC ('Y', '4', '1', 'B'):
       
   303         ret = _("Uncompressed planar YUV 4:1:1");
       
   304         break;
       
   305       case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
       
   306         ret = _("Uncompressed black and white Y-plane");
       
   307         break;
       
   308       default:
       
   309         ret = _("Uncompressed YUV");
       
   310         break;
       
   311     }
       
   312     return g_strdup (ret);
       
   313   } else if (strcmp (info->type, "video/x-raw-rgb") == 0) {
       
   314     const gchar *rgb_str;
       
   315     gint depth = 0;
       
   316 
       
   317     gst_structure_get_int (s, "depth", &depth);
       
   318     rgb_str = gst_structure_has_field (s, "alpha_mask") ? "RGBA" : "RGB";
       
   319     if (gst_structure_has_field (s, "paletted_data")) {
       
   320       return g_strdup_printf (_("Uncompressed palettized %d-bit %s"), depth,
       
   321           rgb_str);
       
   322     } else {
       
   323       return g_strdup_printf ("Uncompressed %d-bit %s", depth, rgb_str);
       
   324     }
       
   325   } else if (strcmp (info->type, "video/x-h263") == 0) {
       
   326     const gchar *variant, *ret;
       
   327 
       
   328     variant = gst_structure_get_string (s, "variant");
       
   329     if (variant == NULL)
       
   330       ret = "H.263";
       
   331     else if (strcmp (variant, "itu") == 0)
       
   332       ret = "ITU H.26n";        /* why not ITU H.263? (tpm) */
       
   333     else if (strcmp (variant, "lead") == 0)
       
   334       ret = "Lead H.263";
       
   335     else if (strcmp (variant, "microsoft") == 0)
       
   336       ret = "Microsoft H.263";
       
   337     else if (strcmp (variant, "vdolive") == 0)
       
   338       ret = "VDOLive";
       
   339     else if (strcmp (variant, "vivo") == 0)
       
   340       ret = "Vivo H.263";
       
   341     else if (strcmp (variant, "xirlink") == 0)
       
   342       ret = "Xirlink H.263";
       
   343     else {
       
   344       GST_WARNING ("Unknown H263 variant '%s'", variant);
       
   345       ret = "H.263";
       
   346     }
       
   347     return g_strdup (ret);
       
   348   } else if (strcmp (info->type, "video/x-h264") == 0) {
       
   349     const gchar *variant, *ret;
       
   350 
       
   351     variant = gst_structure_get_string (s, "variant");
       
   352     if (variant == NULL)
       
   353       ret = "H.264";
       
   354     else if (strcmp (variant, "itu") == 0)
       
   355       ret = "ITU H.264";
       
   356     else if (strcmp (variant, "videosoft") == 0)
       
   357       ret = "Videosoft H.264";
       
   358     else {
       
   359       GST_WARNING ("Unknown H264 variant '%s'", variant);
       
   360       ret = "H.264";
       
   361     }
       
   362     return g_strdup (ret);
       
   363   } else if (strcmp (info->type, "video/x-divx") == 0) {
       
   364     gint ver = 0;
       
   365 
       
   366     if (!gst_structure_get_int (s, "divxversion", &ver) || ver <= 2) {
       
   367       GST_WARNING ("Unexpected DivX version in %" GST_PTR_FORMAT, caps);
       
   368       return g_strdup ("DivX MPEG-4");
       
   369     }
       
   370     return g_strdup_printf (_("DivX MPEG-4 Version %d"), ver);
       
   371   } else if (strcmp (info->type, "video/x-msmpeg") == 0) {
       
   372     gint ver = 0;
       
   373 
       
   374     if (!gst_structure_get_int (s, "msmpegversion", &ver) ||
       
   375         ver < 40 || ver > 49) {
       
   376       GST_WARNING ("Unexpected msmpegversion in %" GST_PTR_FORMAT, caps);
       
   377       return g_strdup ("Microsoft MPEG-4 4.x");
       
   378     }
       
   379     return g_strdup_printf ("Microsoft MPEG-4 4.%d", ver % 10);
       
   380   } else if (strcmp (info->type, "video/x-truemotion") == 0) {
       
   381     gint ver = 0;
       
   382 
       
   383     gst_structure_get_int (s, "trueversion", &ver);
       
   384     switch (ver) {
       
   385       case 1:
       
   386         return g_strdup_printf ("Duck TrueMotion 1");
       
   387       case 2:
       
   388         return g_strdup_printf ("TrueMotion 2.0");
       
   389       default:
       
   390         GST_WARNING ("Unexpected trueversion in %" GST_PTR_FORMAT, caps);
       
   391         break;
       
   392     }
       
   393     return g_strdup_printf ("TrueMotion");
       
   394   } else if (strcmp (info->type, "video/x-xan") == 0) {
       
   395     gint ver = 0;
       
   396 
       
   397     if (!gst_structure_get_int (s, "wcversion", &ver) || ver < 1) {
       
   398       GST_WARNING ("Unexpected wcversion in %" GST_PTR_FORMAT, caps);
       
   399       return g_strdup ("Xan Wing Commander");
       
   400     }
       
   401     return g_strdup_printf ("Xan Wing Commander %u", ver);
       
   402   } else if (strcmp (info->type, "video/x-indeo") == 0) {
       
   403     gint ver = 0;
       
   404 
       
   405     if (!gst_structure_get_int (s, "indeoversion", &ver) || ver < 2) {
       
   406       GST_WARNING ("Unexpected indeoversion in %" GST_PTR_FORMAT, caps);
       
   407       return g_strdup ("Intel Indeo");
       
   408     }
       
   409     return g_strdup_printf ("Intel Indeo %u", ver);
       
   410   } else if (strcmp (info->type, "audio/x-wma") == 0) {
       
   411     gint ver = 0;
       
   412 
       
   413     gst_structure_get_int (s, "wmaversion", &ver);
       
   414     switch (ver) {
       
   415       case 1:
       
   416       case 2:
       
   417       case 3:
       
   418         return g_strdup_printf ("Windows Media Audio %d", ver + 6);
       
   419       default:
       
   420         break;
       
   421     }
       
   422     GST_WARNING ("Unexpected wmaversion in %" GST_PTR_FORMAT, caps);
       
   423     return g_strdup ("Windows Media Audio");
       
   424   } else if (strcmp (info->type, "video/x-wmv") == 0) {
       
   425     gint ver = 0;
       
   426 
       
   427     gst_structure_get_int (s, "wmvversion", &ver);
       
   428     switch (ver) {
       
   429       case 1:
       
   430       case 2:
       
   431       case 3:
       
   432         return g_strdup_printf ("Windows Media Video %d", ver + 6);
       
   433       default:
       
   434         break;
       
   435     }
       
   436     GST_WARNING ("Unexpected wmvversion in %" GST_PTR_FORMAT, caps);
       
   437     return g_strdup ("Windows Media Video");
       
   438   } else if (strcmp (info->type, "audio/x-mace") == 0) {
       
   439     gint ver = 0;
       
   440 
       
   441     gst_structure_get_int (s, "maceversion", &ver);
       
   442     if (ver == 3 || ver == 6) {
       
   443       return g_strdup_printf ("MACE-%d", ver);
       
   444     } else {
       
   445       GST_WARNING ("Unexpected maceversion in %" GST_PTR_FORMAT, caps);
       
   446       return g_strdup ("MACE");
       
   447     }
       
   448   } else if (strcmp (info->type, "video/x-svq") == 0) {
       
   449     gint ver = 0;
       
   450 
       
   451     gst_structure_get_int (s, "svqversion", &ver);
       
   452     if (ver == 1 || ver == 3) {
       
   453       return g_strdup_printf ("Sorensen Video %d", ver);
       
   454     } else {
       
   455       GST_WARNING ("Unexpected svqversion in %" GST_PTR_FORMAT, caps);
       
   456       return g_strdup ("Sorensen Video");
       
   457     }
       
   458   } else if (strcmp (info->type, "video/x-asus") == 0) {
       
   459     gint ver = 0;
       
   460 
       
   461     gst_structure_get_int (s, "asusversion", &ver);
       
   462     if (ver == 1 || ver == 2) {
       
   463       return g_strdup_printf ("Asus Video %d", ver);
       
   464     } else {
       
   465       GST_WARNING ("Unexpected asusversion in %" GST_PTR_FORMAT, caps);
       
   466       return g_strdup ("Asus Video");
       
   467     }
       
   468   } else if (strcmp (info->type, "video/x-ati-vcr") == 0) {
       
   469     gint ver = 0;
       
   470 
       
   471     gst_structure_get_int (s, "vcrversion", &ver);
       
   472     if (ver == 1 || ver == 2) {
       
   473       return g_strdup_printf ("ATI VCR %d", ver);
       
   474     } else {
       
   475       GST_WARNING ("Unexpected acrversion in %" GST_PTR_FORMAT, caps);
       
   476       return g_strdup ("ATI VCR");
       
   477     }
       
   478   } else if (strcmp (info->type, "audio/x-adpcm") == 0) {
       
   479     const GValue *layout_val;
       
   480 
       
   481     layout_val = gst_structure_get_value (s, "layout");
       
   482     if (layout_val != NULL && G_VALUE_HOLDS_STRING (layout_val)) {
       
   483       const gchar *layout;
       
   484 
       
   485       if ((layout = g_value_get_string (layout_val))) {
       
   486         gchar *layout_upper, *ret;
       
   487 
       
   488         if (strcmp (layout, "swf") == 0)
       
   489           return g_strdup ("Shockwave ADPCM");
       
   490         if (strcmp (layout, "microsoft") == 0)
       
   491           return g_strdup ("Microsoft ADPCM");
       
   492         if (strcmp (layout, "quicktime") == 0)
       
   493           return g_strdup ("Quicktime ADPCM");
       
   494         if (strcmp (layout, "westwood") == 0)
       
   495           return g_strdup ("Westwood ADPCM");
       
   496         if (strcmp (layout, "yamaha") == 0)
       
   497           return g_strdup ("Yamaha ADPCM");
       
   498         /* FIXME: other layouts: sbpro2, sbpro3, sbpro4, ct, g726, ea,
       
   499          * adx, xa, 4xm, smjpeg, dk4, dk3, dvi */
       
   500         layout_upper = g_ascii_strup (layout, -1);
       
   501         ret = g_strdup_printf ("%s ADPCM", layout_upper);
       
   502         g_free (layout_upper);
       
   503         return ret;
       
   504       }
       
   505     }
       
   506     return g_strdup ("ADPCM");
       
   507   } else if (strcmp (info->type, "audio/mpeg") == 0) {
       
   508     gint ver = 0, layer = 0;
       
   509 
       
   510     gst_structure_get_int (s, "mpegversion", &ver);
       
   511 
       
   512     switch (ver) {
       
   513       case 1:
       
   514         gst_structure_get_int (s, "layer", &layer);
       
   515         switch (layer) {
       
   516           case 1:
       
   517           case 2:
       
   518           case 3:
       
   519             return g_strdup_printf ("MPEG-1 Layer %d (MP%d)", layer, layer);
       
   520           default:
       
   521             break;
       
   522         }
       
   523         GST_WARNING ("Unexpected MPEG-1 layer in %" GST_PTR_FORMAT, caps);
       
   524         return g_strdup ("MPEG-1 Audio");
       
   525       case 4:
       
   526         return g_strdup ("MPEG-4 AAC");
       
   527       default:
       
   528         break;
       
   529     }
       
   530     GST_WARNING ("Unexpected audio mpegversion in %" GST_PTR_FORMAT, caps);
       
   531     return g_strdup ("MPEG Audio");
       
   532   } else if (strcmp (info->type, "audio/x-pn-realaudio") == 0) {
       
   533     gint ver = 0;
       
   534 
       
   535     gst_structure_get_int (s, "raversion", &ver);
       
   536     switch (ver) {
       
   537       case 1:
       
   538         return g_strdup ("RealAudio 14k4bps");
       
   539       case 2:
       
   540         return g_strdup ("RealAudio 28k8bps");
       
   541       case 8:
       
   542         return g_strdup ("RealAudio G2 (Cook)");
       
   543       default:
       
   544         break;
       
   545     }
       
   546     GST_WARNING ("Unexpected raversion in %" GST_PTR_FORMAT, caps);
       
   547     return g_strdup ("RealAudio");
       
   548   } else if (strcmp (info->type, "video/x-pn-realvideo") == 0) {
       
   549     gint ver = 0;
       
   550 
       
   551     gst_structure_get_int (s, "rmversion", &ver);
       
   552     switch (ver) {
       
   553       case 1:
       
   554         return g_strdup ("RealVideo 1.0");
       
   555       case 2:
       
   556         return g_strdup ("RealVideo 2.0");
       
   557       case 3:
       
   558         return g_strdup ("RealVideo 3.0");
       
   559       case 4:
       
   560         return g_strdup ("RealVideo 4.0");
       
   561       default:
       
   562         break;
       
   563     }
       
   564     GST_WARNING ("Unexpected rmversion in %" GST_PTR_FORMAT, caps);
       
   565     return g_strdup ("RealVideo");
       
   566   } else if (strcmp (info->type, "video/mpeg") == 0) {
       
   567     gboolean sysstream;
       
   568     gint ver = 0;
       
   569 
       
   570     if (!gst_structure_get_boolean (s, "systemstream", &sysstream) ||
       
   571         !gst_structure_get_int (s, "mpegversion", &ver) || ver < 1 || ver > 4) {
       
   572       GST_WARNING ("Missing fields in mpeg video caps %" GST_PTR_FORMAT, caps);
       
   573     } else {
       
   574       if (sysstream) {
       
   575         return g_strdup_printf ("MPEG-%d System Stream", ver);
       
   576       } else {
       
   577         return g_strdup_printf ("MPEG-%d Video", ver);
       
   578       }
       
   579     }
       
   580     return g_strdup ("MPEG Video");
       
   581   } else if (strcmp (info->type, "audio/x-raw-int") == 0) {
       
   582     gint bitdepth = 0;
       
   583 
       
   584     /* 8-bit pcm might not have depth field (?) */
       
   585     if (!gst_structure_get_int (s, "depth", &bitdepth))
       
   586       gst_structure_get_int (s, "width", &bitdepth);
       
   587     if (bitdepth != 0)
       
   588       return g_strdup_printf (_("Raw %d-bit PCM audio"), bitdepth);
       
   589     else
       
   590       return g_strdup (_("Raw PCM audio"));
       
   591   } else if (strcmp (info->type, "audio/x-raw-float") == 0) {
       
   592     gint bitdepth = 0;
       
   593 
       
   594     gst_structure_get_int (s, "width", &bitdepth);
       
   595     if (bitdepth != 0)
       
   596       return g_strdup_printf (_("Raw %d-bit floating-point audio"), bitdepth);
       
   597     else
       
   598       return g_strdup (_("Raw floating-point audio"));
       
   599   }
       
   600 
       
   601   return NULL;
       
   602 }
       
   603 
       
   604 /* returns format info structure, will return NULL for dynamic media types! */
       
   605 static const FormatInfo *
       
   606 find_format_info (const GstCaps * caps)
       
   607 {
       
   608   const GstStructure *s;
       
   609   const gchar *media_type;
       
   610   guint i;
       
   611 
       
   612   s = gst_caps_get_structure (caps, 0);
       
   613   media_type = gst_structure_get_name (s);
       
   614 
       
   615   for (i = 0; i < G_N_ELEMENTS (formats); ++i) {
       
   616     if (strcmp (media_type, formats[i].type) == 0) {
       
   617       gboolean is_sys = FALSE;
       
   618 
       
   619       if ((formats[i].flags & FLAG_SYSTEMSTREAM) == 0)
       
   620         return &formats[i];
       
   621 
       
   622       /* this record should only be matched if the systemstream field is set */
       
   623       if (gst_structure_get_boolean (s, "systemstream", &is_sys) && is_sys)
       
   624         return &formats[i];
       
   625     }
       
   626   }
       
   627 
       
   628   return NULL;
       
   629 }
       
   630 
       
   631 static gboolean
       
   632 caps_are_rtp_caps (const GstCaps * caps, const gchar * media, gchar ** format)
       
   633 {
       
   634   const GstStructure *s;
       
   635   const gchar *str;
       
   636 
       
   637   g_assert (media != NULL && format != NULL);
       
   638 
       
   639   s = gst_caps_get_structure (caps, 0);
       
   640   if (!gst_structure_has_name (s, "application/x-rtp"))
       
   641     return FALSE;
       
   642   if (!gst_structure_has_field_typed (s, "media", G_TYPE_STRING))
       
   643     return FALSE;
       
   644   str = gst_structure_get_string (s, "media");
       
   645   if (str == NULL || !g_str_equal (str, media))
       
   646     return FALSE;
       
   647   str = gst_structure_get_string (s, "encoding-name");
       
   648   if (str == NULL || *str == '\0')
       
   649     return FALSE;
       
   650 
       
   651   if (strcmp (str, "X-ASF-PF") == 0) {
       
   652     *format = g_strdup ("Windows Media");
       
   653   } else if (g_str_has_prefix (str, "X-")) {
       
   654     *format = g_strdup (str + 2);
       
   655   } else {
       
   656     *format = g_strdup (str);
       
   657   }
       
   658 
       
   659   return TRUE;
       
   660 }
       
   661 
       
   662 /**
       
   663  * gst_pb_utils_get_source_description:
       
   664  * @protocol: the protocol the source element needs to handle, e.g. "http"
       
   665  *
       
   666  * Returns a localised string describing a source element handling the protocol
       
   667  * specified in @protocol, for use in error dialogs or other messages to be
       
   668  * seen by the user. Should never return NULL unless @protocol is invalid.
       
   669  *
       
   670  * This function is mainly for internal use, applications would typically
       
   671  * use gst_missing_plugin_message_get_description() to get a description of
       
   672  * a missing feature from a missing-plugin message.
       
   673  *
       
   674  * Returns: a newly-allocated description string, or NULL on error. Free
       
   675  *          string with g_free() when not needed any longer.
       
   676  */
       
   677 #ifdef __SYMBIAN32__
       
   678 EXPORT_C
       
   679 #endif
       
   680 
       
   681 gchar *
       
   682 gst_pb_utils_get_source_description (const gchar * protocol)
       
   683 {
       
   684   gchar *proto_uc, *ret;
       
   685 
       
   686   g_return_val_if_fail (protocol != NULL, NULL);
       
   687 
       
   688   if (strcmp (protocol, "cdda") == 0)
       
   689     return g_strdup (_("Audio CD source"));
       
   690 
       
   691   if (strcmp (protocol, "dvd") == 0)
       
   692     return g_strdup (_("DVD source"));
       
   693 
       
   694   if (strcmp (protocol, "rtsp") == 0)
       
   695     return g_strdup (_("Real Time Streaming Protocol (RTSP) source"));
       
   696 
       
   697   /* TODO: what about mmst, mmsu, mmsh? */
       
   698   if (strcmp (protocol, "mms") == 0)
       
   699     return g_strdup (_("Microsoft Media Server (MMS) protocol source"));
       
   700 
       
   701   /* make protocol uppercase */
       
   702   proto_uc = g_ascii_strup (protocol, -1);
       
   703 
       
   704   /* TODO: find out how to add a comment for translators to the source code
       
   705    * (and tell them to make the first letter uppercase below if they move
       
   706    * the protocol to the middle or end of the string) */
       
   707   ret = g_strdup_printf (_("%s protocol source"), proto_uc);
       
   708 
       
   709   g_free (proto_uc);
       
   710 
       
   711   return ret;
       
   712 }
       
   713 
       
   714 /**
       
   715  * gst_pb_utils_get_sink_description:
       
   716  * @protocol: the protocol the sink element needs to handle, e.g. "http"
       
   717  *
       
   718  * Returns a localised string describing a sink element handling the protocol
       
   719  * specified in @protocol, for use in error dialogs or other messages to be
       
   720  * seen by the user. Should never return NULL unless @protocol is invalid.
       
   721  *
       
   722  * This function is mainly for internal use, applications would typically
       
   723  * use gst_missing_plugin_message_get_description() to get a description of
       
   724  * a missing feature from a missing-plugin message.
       
   725  *
       
   726  * Returns: a newly-allocated description string, or NULL on error. Free
       
   727  *          string with g_free() when not needed any longer.
       
   728  */
       
   729 #ifdef __SYMBIAN32__
       
   730 EXPORT_C
       
   731 #endif
       
   732 
       
   733 gchar *
       
   734 gst_pb_utils_get_sink_description (const gchar * protocol)
       
   735 {
       
   736   gchar *proto_uc, *ret;
       
   737 
       
   738   g_return_val_if_fail (protocol != NULL, NULL);
       
   739 
       
   740   /* make protocol uppercase */
       
   741   proto_uc = g_ascii_strup (protocol, -1);
       
   742 
       
   743   /* TODO: find out how to add a comment for translators to the source code
       
   744    * (and tell them to make the first letter uppercase below if they move
       
   745    * the protocol to the middle or end of the string) */
       
   746   ret = g_strdup_printf ("%s protocol sink", proto_uc);
       
   747 
       
   748   g_free (proto_uc);
       
   749 
       
   750   return ret;
       
   751 }
       
   752 
       
   753 /**
       
   754  * gst_pb_utils_get_decoder_description:
       
   755  * @caps: the (fixed) #GstCaps for which an decoder description is needed
       
   756  *
       
   757  * Returns a localised string describing an decoder for the format specified
       
   758  * in @caps, for use in error dialogs or other messages to be seen by the user.
       
   759  * Should never return NULL unless @factory_name or @caps are invalid.
       
   760  *
       
   761  * This function is mainly for internal use, applications would typically
       
   762  * use gst_missing_plugin_message_get_description() to get a description of
       
   763  * a missing feature from a missing-plugin message.
       
   764  *
       
   765  * Returns: a newly-allocated description string, or NULL on error. Free
       
   766  *          string with g_free() when not needed any longer.
       
   767  */
       
   768 #ifdef __SYMBIAN32__
       
   769 EXPORT_C
       
   770 #endif
       
   771 
       
   772 gchar *
       
   773 gst_pb_utils_get_decoder_description (const GstCaps * caps)
       
   774 {
       
   775   gchar *str, *ret;
       
   776 
       
   777   g_return_val_if_fail (caps != NULL, NULL);
       
   778   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
       
   779   g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
       
   780 
       
   781   /* special-case RTP caps */
       
   782   if (caps_are_rtp_caps (caps, "video", &str)) {
       
   783     ret = g_strdup_printf (_("%s video RTP depayloader"), str);
       
   784   } else if (caps_are_rtp_caps (caps, "audio", &str)) {
       
   785     ret = g_strdup_printf (_("%s audio RTP depayloader"), str);
       
   786   } else if (caps_are_rtp_caps (caps, "application", &str)) {
       
   787     ret = g_strdup_printf (_("%s RTP depayloader"), str);
       
   788   } else {
       
   789     const FormatInfo *info;
       
   790 
       
   791     str = gst_pb_utils_get_codec_description (caps);
       
   792     info = find_format_info (caps);
       
   793     if (info != NULL && (info->flags & FLAG_CONTAINER) != 0) {
       
   794       ret = g_strdup_printf (_("%s demuxer"), str);
       
   795     } else {
       
   796       ret = g_strdup_printf (_("%s decoder"), str);
       
   797     }
       
   798   }
       
   799 
       
   800   g_free (str);
       
   801 
       
   802   return ret;
       
   803 }
       
   804 
       
   805 /**
       
   806  * gst_pb_utils_get_encoder_description:
       
   807  * @caps: the (fixed) #GstCaps for which an encoder description is needed
       
   808  *
       
   809  * Returns a localised string describing an encoder for the format specified
       
   810  * in @caps, for use in error dialogs or other messages to be seen by the user.
       
   811  * Should never return NULL unless @factory_name or @caps are invalid.
       
   812  *
       
   813  * This function is mainly for internal use, applications would typically
       
   814  * use gst_missing_plugin_message_get_description() to get a description of
       
   815  * a missing feature from a missing-plugin message.
       
   816  *
       
   817  * Returns: a newly-allocated description string, or NULL on error. Free
       
   818  *          string with g_free() when not needed any longer.
       
   819  */
       
   820 #ifdef __SYMBIAN32__
       
   821 EXPORT_C
       
   822 #endif
       
   823 
       
   824 gchar *
       
   825 gst_pb_utils_get_encoder_description (const GstCaps * caps)
       
   826 {
       
   827   gchar *str, *ret;
       
   828 
       
   829   g_return_val_if_fail (caps != NULL, NULL);
       
   830   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
       
   831   g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
       
   832 
       
   833   /* special-case RTP caps */
       
   834   if (caps_are_rtp_caps (caps, "video", &str)) {
       
   835     ret = g_strdup_printf (_("%s video RTP payloader"), str);
       
   836   } else if (caps_are_rtp_caps (caps, "audio", &str)) {
       
   837     ret = g_strdup_printf (_("%s audio RTP payloader"), str);
       
   838   } else if (caps_are_rtp_caps (caps, "application", &str)) {
       
   839     ret = g_strdup_printf (_("%s RTP payloader"), str);
       
   840   } else {
       
   841     const FormatInfo *info;
       
   842 
       
   843     str = gst_pb_utils_get_codec_description (caps);
       
   844     info = find_format_info (caps);
       
   845     if (info != NULL && (info->flags & FLAG_CONTAINER) != 0) {
       
   846       ret = g_strdup_printf (_("%s muxer"), str);
       
   847     } else {
       
   848       ret = g_strdup_printf (_("%s encoder"), str);
       
   849     }
       
   850   }
       
   851 
       
   852   g_free (str);
       
   853 
       
   854   return ret;
       
   855 }
       
   856 
       
   857 /**
       
   858  * gst_pb_utils_get_element_description:
       
   859  * @factory_name: the name of the element, e.g. "gnomevfssrc"
       
   860  *
       
   861  * Returns a localised string describing the given element, for use in
       
   862  * error dialogs or other messages to be seen by the user. Should never
       
   863  * return NULL unless @factory_name is invalid.
       
   864  *
       
   865  * This function is mainly for internal use, applications would typically
       
   866  * use gst_missing_plugin_message_get_description() to get a description of
       
   867  * a missing feature from a missing-plugin message.
       
   868  *
       
   869  * Returns: a newly-allocated description string, or NULL on error. Free
       
   870  *          string with g_free() when not needed any longer.
       
   871  */
       
   872 #ifdef __SYMBIAN32__
       
   873 EXPORT_C
       
   874 #endif
       
   875 
       
   876 gchar *
       
   877 gst_pb_utils_get_element_description (const gchar * factory_name)
       
   878 {
       
   879   gchar *ret;
       
   880 
       
   881   g_return_val_if_fail (factory_name != NULL, NULL);
       
   882 
       
   883   ret = g_strdup_printf (_("GStreamer element %s"), factory_name);
       
   884   if (ret && g_str_has_prefix (ret, factory_name))
       
   885     *ret = g_ascii_toupper (*ret);
       
   886 
       
   887   return ret;
       
   888 }
       
   889 
       
   890 /**
       
   891  * gst_pb_utils_add_codec_description_to_tag_list:
       
   892  * @taglist: a #GstTagList
       
   893  * @codec_tag: a GStreamer codec tag such as #GST_TAG_AUDIO_CODEC,
       
   894  *             #GST_TAG_VIDEO_CODEC or #GST_TAG_CODEC
       
   895  * @caps: the (fixed) #GstCaps for which a codec tag should be added.
       
   896  *
       
   897  * Adds a codec tag describing the format specified by @caps to @taglist.
       
   898  *
       
   899  * Returns: TRUE if a codec tag was added, FALSE otherwise.
       
   900  */
       
   901 #ifdef __SYMBIAN32__
       
   902 EXPORT_C
       
   903 #endif
       
   904 
       
   905 gboolean
       
   906 gst_pb_utils_add_codec_description_to_tag_list (GstTagList * taglist,
       
   907     const gchar * codec_tag, const GstCaps * caps)
       
   908 {
       
   909   const FormatInfo *info;
       
   910   gchar *desc;
       
   911 
       
   912   g_return_val_if_fail (taglist != NULL, FALSE);
       
   913   g_return_val_if_fail (GST_IS_TAG_LIST (taglist), FALSE);
       
   914   g_return_val_if_fail (codec_tag != NULL, FALSE);
       
   915   g_return_val_if_fail (gst_tag_exists (codec_tag), FALSE);
       
   916   g_return_val_if_fail (gst_tag_get_type (codec_tag) == G_TYPE_STRING, FALSE);
       
   917   g_return_val_if_fail (caps != NULL, FALSE);
       
   918   g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
       
   919 
       
   920   info = find_format_info (caps);
       
   921   if (info == NULL)
       
   922     return FALSE;
       
   923 
       
   924   desc = format_info_get_desc (info, caps);
       
   925   gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE, codec_tag, desc, NULL);
       
   926   g_free (desc);
       
   927 
       
   928   return TRUE;
       
   929 }
       
   930 
       
   931 /**
       
   932  * gst_pb_utils_get_codec_description:
       
   933  * @caps: the (fixed) #GstCaps for which an format description is needed
       
   934  *
       
   935  * Returns a localised (as far as this is possible) string describing the
       
   936  * media format specified in @caps, for use in error dialogs or other messages
       
   937  * to be seen by the user. Should never return NULL unless @caps is invalid.
       
   938  *
       
   939  * Also see the convenience function
       
   940  * gst_pb_utils_add_codec_description_to_tag_list().
       
   941  *
       
   942  * Returns: a newly-allocated description string, or NULL on error. Free
       
   943  *          string with g_free() when not needed any longer.
       
   944  */
       
   945 #ifdef __SYMBIAN32__
       
   946 EXPORT_C
       
   947 #endif
       
   948 
       
   949 gchar *
       
   950 gst_pb_utils_get_codec_description (const GstCaps * caps)
       
   951 {
       
   952   const FormatInfo *info;
       
   953   gchar *str, *comma;
       
   954 
       
   955   g_return_val_if_fail (caps != NULL, NULL);
       
   956   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
       
   957   g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
       
   958 
       
   959   info = find_format_info (caps);
       
   960 
       
   961   if (info) {
       
   962     str = format_info_get_desc (info, caps);
       
   963   } else {
       
   964     str = gst_caps_to_string (caps);
       
   965 
       
   966     /* cut off everything after the media type, if there is anything */
       
   967     if ((comma = strchr (str, ','))) {
       
   968       *comma = '\0';
       
   969       g_strchomp (str);
       
   970       /* we could do something more elaborate here, like taking into account
       
   971        * audio/, video/, image/ and application/ prefixes etc. */
       
   972     }
       
   973 
       
   974     GST_WARNING ("No description available for media type: %s", str);
       
   975   }
       
   976 
       
   977   return str;
       
   978 }
       
   979 
       
   980 #if 0
       
   981 void
       
   982 gst_pb_utils_list_all (void)
       
   983 {
       
   984   gint i;
       
   985 
       
   986   g_print ("static const gchar *caps_strings[] = { ");
       
   987 
       
   988   for (i = 0; i < G_N_ELEMENTS (formats); ++i) {
       
   989     if (formats[i].desc != NULL)
       
   990       g_print ("  \"%s\", ", formats[i].type);
       
   991   }
       
   992   g_print ("\n#if 0\n");
       
   993   for (i = 0; i < G_N_ELEMENTS (formats); ++i) {
       
   994     if (formats[i].desc == NULL)
       
   995       g_print ("  \"%s\", \n", formats[i].type);
       
   996   }
       
   997   g_print ("\n#endif\n");
       
   998 }
       
   999 #endif