|
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 |