5fae5429c3544e411d8c9de7e1f71b1f87906416
[platform/upstream/gst-plugins-base.git] / gst-libs / gst / riff / riff-media.c
1 /* GStreamer RIFF I/O
2  * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
3  *
4  * riff-media.h: RIFF-id to/from caps routines
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include "riff-ids.h"
27 #include "riff-media.h"
28
29 #include <gst/audio/audio.h>
30
31 #include <string.h>
32 #include <math.h>
33
34 GST_DEBUG_CATEGORY_EXTERN (riff_debug);
35 #define GST_CAT_DEFAULT riff_debug
36
37 /**
38  * gst_riff_create_video_caps:
39  * @codec_fcc: fourCC codec for this codec.
40  * @strh: pointer to the strh stream header structure.
41  * @strf: pointer to the strf stream header structure, including any
42  *        data that is within the range of strf.size, but excluding any
43  *        additional data withint this chunk but outside strf.size.
44  * @strf_data: a #GstBuffer containing the additional data in the strf
45  *             chunk outside reach of strf.size. Ususally a palette.
46  * @strd_data: a #GstBuffer containing the data in the strd stream header
47  *             chunk. Usually codec initialization data.
48  * @codec_name: if given, will be filled with a human-readable codec name.
49  */
50
51 GstCaps *
52 gst_riff_create_video_caps (guint32 codec_fcc,
53     gst_riff_strh * strh, gst_riff_strf_vids * strf,
54     GstBuffer * strf_data, GstBuffer * strd_data, char **codec_name)
55 {
56   GstCaps *caps = NULL;
57   GstBuffer *palette = NULL;
58
59   GST_DEBUG ("video fourcc %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (codec_fcc));
60
61   switch (codec_fcc) {
62     case GST_MAKE_FOURCC ('D', 'I', 'B', ' '): /* uncompressed RGB */
63     case GST_MAKE_FOURCC (0x00, 0x00, 0x00, 0x00):
64     case GST_MAKE_FOURCC ('R', 'G', 'B', ' '):
65     case GST_MAKE_FOURCC ('R', 'A', 'W', ' '):
66     {
67       gint bpp = (strf && strf->bit_cnt != 0) ? strf->bit_cnt : 8;
68
69       if (strf) {
70         if (bpp == 8) {
71           caps = gst_caps_new_simple ("video/x-raw",
72               "format", G_TYPE_STRING, "RGB8_PALETTED", NULL);
73         } else if (bpp == 24) {
74           caps = gst_caps_new_simple ("video/x-raw",
75               "format", G_TYPE_STRING, "BGR", NULL);
76         } else if (bpp == 32) {
77           caps = gst_caps_new_simple ("video/x-raw",
78               "format", G_TYPE_STRING, "BGRx", NULL);
79         } else {
80           GST_WARNING ("Unhandled DIB RGB depth: %d", bpp);
81           return NULL;
82         }
83       } else {
84         /* for template */
85         caps =
86             gst_caps_from_string ("video/x-raw, format = (string) "
87             "{ RGB8_PALETTED, BGR, BGRx }");
88       }
89
90       palette = strf_data;
91       strf_data = NULL;
92       if (codec_name) {
93         if (bpp == 8)
94           *codec_name = g_strdup_printf ("Palettized %d-bit RGB", bpp);
95         else
96           *codec_name = g_strdup_printf ("%d-bit RGB", bpp);
97       }
98       break;
99     }
100     case GST_MAKE_FOURCC ('I', '4', '2', '0'):
101       caps = gst_caps_new_simple ("video/x-raw",
102           "format", G_TYPE_STRING, "I420", NULL);
103       if (codec_name)
104         *codec_name = g_strdup ("Uncompressed planar YUV 4:2:0");
105       break;
106
107     case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
108     case GST_MAKE_FOURCC ('Y', 'U', 'N', 'V'):
109       caps = gst_caps_new_simple ("video/x-raw",
110           "format", G_TYPE_STRING, "YUY2", NULL);
111       if (codec_name)
112         *codec_name = g_strdup ("Uncompressed packed YUV 4:2:2");
113       break;
114
115     case GST_MAKE_FOURCC ('Y', 'V', 'U', '9'):
116       caps = gst_caps_new_simple ("video/x-raw",
117           "format", G_TYPE_STRING, "YVU9", NULL);
118       if (codec_name)
119         *codec_name = g_strdup ("Uncompressed packed YVU 4:1:0");
120       break;
121
122     case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
123     case GST_MAKE_FOURCC ('2', 'v', 'u', 'y'):
124       caps = gst_caps_new_simple ("video/x-raw",
125           "format", G_TYPE_STRING, "UYVY", NULL);
126       if (codec_name)
127         *codec_name = g_strdup ("Uncompressed packed YUV 4:2:2");
128       break;
129
130     case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
131       caps = gst_caps_new_simple ("video/x-raw",
132           "format", G_TYPE_STRING, "YV12", NULL);
133       if (codec_name)
134         *codec_name = g_strdup ("Uncompressed packed YVU 4:2:2");
135       break;
136
137     case GST_MAKE_FOURCC ('M', 'J', 'P', 'G'): /* YUY2 MJPEG */
138     case GST_MAKE_FOURCC ('A', 'V', 'R', 'n'):
139     case GST_MAKE_FOURCC ('I', 'J', 'P', 'G'):
140     case GST_MAKE_FOURCC ('i', 'j', 'p', 'g'):
141     case GST_MAKE_FOURCC ('d', 'm', 'b', '1'):
142     case GST_MAKE_FOURCC ('A', 'C', 'D', 'V'):
143     case GST_MAKE_FOURCC ('Q', 'I', 'V', 'G'):
144       caps = gst_caps_new_empty_simple ("image/jpeg");
145       if (codec_name)
146         *codec_name = g_strdup ("Motion JPEG");
147       break;
148
149     case GST_MAKE_FOURCC ('J', 'P', 'E', 'G'): /* generic (mostly RGB) MJPEG */
150     case GST_MAKE_FOURCC ('j', 'p', 'e', 'g'): /* generic (mostly RGB) MJPEG */
151       caps = gst_caps_new_empty_simple ("image/jpeg");
152       if (codec_name)
153         *codec_name = g_strdup ("JPEG Still Image");
154       break;
155
156     case GST_MAKE_FOURCC ('P', 'I', 'X', 'L'): /* Miro/Pinnacle fourccs */
157     case GST_MAKE_FOURCC ('V', 'I', 'X', 'L'): /* Miro/Pinnacle fourccs */
158       caps = gst_caps_new_empty_simple ("image/jpeg");
159       if (codec_name)
160         *codec_name = g_strdup ("Miro/Pinnacle Motion JPEG");
161       break;
162
163     case GST_MAKE_FOURCC ('C', 'J', 'P', 'G'):
164       caps = gst_caps_new_empty_simple ("image/jpeg");
165       if (codec_name)
166         *codec_name = g_strdup ("Creative Webcam JPEG");
167       break;
168
169     case GST_MAKE_FOURCC ('S', 'L', 'M', 'J'):
170       caps = gst_caps_new_empty_simple ("image/jpeg");
171       if (codec_name)
172         *codec_name = g_strdup ("SL Motion JPEG");
173       break;
174
175     case GST_MAKE_FOURCC ('J', 'P', 'G', 'L'):
176       caps = gst_caps_new_empty_simple ("image/jpeg");
177       if (codec_name)
178         *codec_name = g_strdup ("Pegasus Lossless JPEG");
179       break;
180
181     case GST_MAKE_FOURCC ('L', 'O', 'C', 'O'):
182       caps = gst_caps_new_empty_simple ("video/x-loco");
183       if (codec_name)
184         *codec_name = g_strdup ("LOCO Lossless");
185       break;
186
187     case GST_MAKE_FOURCC ('S', 'P', '5', '3'):
188     case GST_MAKE_FOURCC ('S', 'P', '5', '4'):
189     case GST_MAKE_FOURCC ('S', 'P', '5', '5'):
190     case GST_MAKE_FOURCC ('S', 'P', '5', '6'):
191     case GST_MAKE_FOURCC ('S', 'P', '5', '7'):
192     case GST_MAKE_FOURCC ('S', 'P', '5', '8'):
193       caps = gst_caps_new_empty_simple ("video/sp5x");
194       if (codec_name)
195         *codec_name = g_strdup ("Sp5x-like JPEG");
196       break;
197
198     case GST_MAKE_FOURCC ('Z', 'M', 'B', 'V'):
199       caps = gst_caps_new_empty_simple ("video/x-zmbv");
200       if (codec_name)
201         *codec_name = g_strdup ("Zip Motion Block video");
202       break;
203
204     case GST_MAKE_FOURCC ('H', 'F', 'Y', 'U'):
205       caps = gst_caps_new_empty_simple ("video/x-huffyuv");
206       if (strf) {
207         gst_caps_set_simple (caps, "bpp",
208             G_TYPE_INT, (int) strf->bit_cnt, NULL);
209       }
210       if (codec_name)
211         *codec_name = g_strdup ("Huffman Lossless Codec");
212       break;
213
214     case GST_MAKE_FOURCC ('M', 'P', 'E', 'G'):
215     case GST_MAKE_FOURCC ('M', 'P', 'G', 'I'):
216     case GST_MAKE_FOURCC ('m', 'p', 'g', '1'):
217     case GST_MAKE_FOURCC ('M', 'P', 'G', '1'):
218     case GST_MAKE_FOURCC ('P', 'I', 'M', '1'):
219     case GST_MAKE_FOURCC (0x01, 0x00, 0x00, 0x10):
220       caps = gst_caps_new_simple ("video/mpeg",
221           "systemstream", G_TYPE_BOOLEAN, FALSE,
222           "mpegversion", G_TYPE_INT, 1, NULL);
223       if (codec_name)
224         *codec_name = g_strdup ("MPEG-1 video");
225       break;
226
227     case GST_MAKE_FOURCC ('M', 'P', 'G', '2'):
228     case GST_MAKE_FOURCC ('m', 'p', 'g', '2'):
229     case GST_MAKE_FOURCC ('P', 'I', 'M', '2'):
230     case GST_MAKE_FOURCC ('D', 'V', 'R', ' '):
231     case GST_MAKE_FOURCC (0x02, 0x00, 0x00, 0x10):
232       caps = gst_caps_new_simple ("video/mpeg",
233           "systemstream", G_TYPE_BOOLEAN, FALSE,
234           "mpegversion", G_TYPE_INT, 2, NULL);
235       if (codec_name)
236         *codec_name = g_strdup ("MPEG-2 video");
237       break;
238
239     case GST_MAKE_FOURCC ('L', 'M', 'P', '2'):
240       caps = gst_caps_new_simple ("video/mpeg",
241           "systemstream", G_TYPE_BOOLEAN, FALSE,
242           "mpegversion", G_TYPE_INT, 2, NULL);
243       if (codec_name)
244         *codec_name = g_strdup ("Lead MPEG-2 video");
245       break;
246
247     case GST_MAKE_FOURCC ('H', '2', '6', '3'):
248     case GST_MAKE_FOURCC ('h', '2', '6', '3'):
249     case GST_MAKE_FOURCC ('i', '2', '6', '3'):
250     case GST_MAKE_FOURCC ('U', '2', '6', '3'):
251     case GST_MAKE_FOURCC ('v', 'i', 'v', '1'):
252     case GST_MAKE_FOURCC ('T', '2', '6', '3'):
253       caps = gst_caps_new_simple ("video/x-h263",
254           "variant", G_TYPE_STRING, "itu", NULL);
255       if (codec_name)
256         *codec_name = g_strdup ("ITU H.26n");
257       break;
258
259     case GST_MAKE_FOURCC ('L', '2', '6', '3'):
260       /* http://www.leadcodecs.com/Codecs/LEAD-H263.htm */
261       caps = gst_caps_new_simple ("video/x-h263",
262           "variant", G_TYPE_STRING, "lead", NULL);
263       if (codec_name)
264         *codec_name = g_strdup ("Lead H.263");
265       break;
266
267     case GST_MAKE_FOURCC ('M', '2', '6', '3'):
268     case GST_MAKE_FOURCC ('m', '2', '6', '3'):
269       caps = gst_caps_new_simple ("video/x-h263",
270           "variant", G_TYPE_STRING, "microsoft", NULL);
271       if (codec_name)
272         *codec_name = g_strdup ("Microsoft H.263");
273       break;
274
275     case GST_MAKE_FOURCC ('V', 'D', 'O', 'W'):
276       caps = gst_caps_new_simple ("video/x-h263",
277           "variant", G_TYPE_STRING, "vdolive", NULL);
278       if (codec_name)
279         *codec_name = g_strdup ("VDOLive");
280       break;
281
282     case GST_MAKE_FOURCC ('V', 'I', 'V', 'O'):
283       caps = gst_caps_new_simple ("video/x-h263",
284           "variant", G_TYPE_STRING, "vivo", NULL);
285       if (codec_name)
286         *codec_name = g_strdup ("Vivo H.263");
287       break;
288
289     case GST_MAKE_FOURCC ('x', '2', '6', '3'):
290       caps = gst_caps_new_simple ("video/x-h263",
291           "variant", G_TYPE_STRING, "xirlink", NULL);
292       if (codec_name)
293         *codec_name = g_strdup ("Xirlink H.263");
294       break;
295
296       /* apparently not standard H.263...? */
297     case GST_MAKE_FOURCC ('I', '2', '6', '3'):
298       caps = gst_caps_new_simple ("video/x-intel-h263",
299           "variant", G_TYPE_STRING, "intel", NULL);
300       if (codec_name)
301         *codec_name = g_strdup ("Intel H.263");
302       break;
303
304     case GST_MAKE_FOURCC ('V', 'X', '1', 'K'):
305       caps = gst_caps_new_simple ("video/x-h263",
306           "variant", G_TYPE_STRING, "lucent", NULL);
307       if (codec_name)
308         *codec_name = g_strdup ("Lucent VX1000S H.263");
309       break;
310
311     case GST_MAKE_FOURCC ('X', '2', '6', '4'):
312     case GST_MAKE_FOURCC ('x', '2', '6', '4'):
313     case GST_MAKE_FOURCC ('H', '2', '6', '4'):
314     case GST_MAKE_FOURCC ('h', '2', '6', '4'):
315     case GST_MAKE_FOURCC ('a', 'v', 'c', '1'):
316     case GST_MAKE_FOURCC ('A', 'V', 'C', '1'):
317       caps = gst_caps_new_simple ("video/x-h264",
318           "variant", G_TYPE_STRING, "itu", NULL);
319       if (codec_name)
320         *codec_name = g_strdup ("ITU H.264");
321       break;
322
323     case GST_MAKE_FOURCC ('V', 'S', 'S', 'H'):
324       caps = gst_caps_new_simple ("video/x-h264",
325           "variant", G_TYPE_STRING, "videosoft", NULL);
326       if (codec_name)
327         *codec_name = g_strdup ("VideoSoft H.264");
328       break;
329
330     case GST_MAKE_FOURCC ('L', '2', '6', '4'):
331       /* http://www.leadcodecs.com/Codecs/LEAD-H264.htm */
332       caps = gst_caps_new_simple ("video/x-h264",
333           "variant", G_TYPE_STRING, "lead", NULL);
334       if (codec_name)
335         *codec_name = g_strdup ("Lead H.264");
336       break;
337
338     case GST_MAKE_FOURCC ('S', 'E', 'D', 'G'):
339       caps = gst_caps_new_simple ("video/mpeg",
340           "mpegversion", G_TYPE_INT, 4, NULL);
341       if (codec_name)
342         *codec_name = g_strdup ("Samsung MPEG-4");
343       break;
344
345     case GST_MAKE_FOURCC ('M', '4', 'C', 'C'):
346       caps = gst_caps_new_simple ("video/mpeg",
347           "mpegversion", G_TYPE_INT, 4, NULL);
348       if (codec_name)
349         *codec_name = g_strdup ("Divio MPEG-4");
350       break;
351
352     case GST_MAKE_FOURCC ('D', 'I', 'V', '3'):
353     case GST_MAKE_FOURCC ('d', 'i', 'v', '3'):
354     case GST_MAKE_FOURCC ('D', 'V', 'X', '3'):
355     case GST_MAKE_FOURCC ('d', 'v', 'x', '3'):
356     case GST_MAKE_FOURCC ('D', 'I', 'V', '4'):
357     case GST_MAKE_FOURCC ('d', 'i', 'v', '4'):
358     case GST_MAKE_FOURCC ('D', 'I', 'V', '5'):
359     case GST_MAKE_FOURCC ('d', 'i', 'v', '5'):
360     case GST_MAKE_FOURCC ('D', 'I', 'V', '6'):
361     case GST_MAKE_FOURCC ('d', 'i', 'v', '6'):
362     case GST_MAKE_FOURCC ('M', 'P', 'G', '3'):
363     case GST_MAKE_FOURCC ('m', 'p', 'g', '3'):
364     case GST_MAKE_FOURCC ('c', 'o', 'l', '0'):
365     case GST_MAKE_FOURCC ('C', 'O', 'L', '0'):
366     case GST_MAKE_FOURCC ('c', 'o', 'l', '1'):
367     case GST_MAKE_FOURCC ('C', 'O', 'L', '1'):
368     case GST_MAKE_FOURCC ('A', 'P', '4', '1'):
369       caps = gst_caps_new_simple ("video/x-divx",
370           "divxversion", G_TYPE_INT, 3, NULL);
371       if (codec_name)
372         *codec_name = g_strdup ("DivX MS-MPEG-4 Version 3");
373       break;
374
375     case GST_MAKE_FOURCC ('d', 'i', 'v', 'x'):
376     case GST_MAKE_FOURCC ('D', 'I', 'V', 'X'):
377       caps = gst_caps_new_simple ("video/x-divx",
378           "divxversion", G_TYPE_INT, 4, NULL);
379       if (codec_name)
380         *codec_name = g_strdup ("DivX MPEG-4 Version 4");
381       break;
382
383     case GST_MAKE_FOURCC ('B', 'L', 'Z', '0'):
384       caps = gst_caps_new_simple ("video/x-divx",
385           "divxversion", G_TYPE_INT, 4, NULL);
386       if (codec_name)
387         *codec_name = g_strdup ("Blizzard DivX");
388       break;
389
390     case GST_MAKE_FOURCC ('D', 'X', '5', '0'):
391       caps = gst_caps_new_simple ("video/x-divx",
392           "divxversion", G_TYPE_INT, 5, NULL);
393       if (codec_name)
394         *codec_name = g_strdup ("DivX MPEG-4 Version 5");
395       break;
396
397     case GST_MAKE_FOURCC ('X', 'V', 'I', 'D'):
398     case GST_MAKE_FOURCC ('x', 'v', 'i', 'd'):
399       caps = gst_caps_new_empty_simple ("video/x-xvid");
400       if (codec_name)
401         *codec_name = g_strdup ("XVID MPEG-4");
402       break;
403
404     case GST_MAKE_FOURCC ('R', 'M', 'P', '4'):
405       caps = gst_caps_new_empty_simple ("video/x-xvid");
406       if (codec_name)
407         *codec_name = g_strdup ("Sigma-Designs MPEG-4");
408       break;
409
410     case GST_MAKE_FOURCC ('M', 'P', 'G', '4'):
411     case GST_MAKE_FOURCC ('M', 'P', '4', '1'):
412     case GST_MAKE_FOURCC ('m', 'p', '4', '1'):
413       caps = gst_caps_new_simple ("video/x-msmpeg",
414           "msmpegversion", G_TYPE_INT, 41, NULL);
415       if (codec_name)
416         *codec_name = g_strdup ("Microsoft MPEG-4 4.1");
417       break;
418
419     case GST_MAKE_FOURCC ('m', 'p', '4', '2'):
420     case GST_MAKE_FOURCC ('M', 'P', '4', '2'):
421       caps = gst_caps_new_simple ("video/x-msmpeg",
422           "msmpegversion", G_TYPE_INT, 42, NULL);
423       if (codec_name)
424         *codec_name = g_strdup ("Microsoft MPEG-4 4.2");
425       break;
426
427     case GST_MAKE_FOURCC ('m', 'p', '4', '3'):
428     case GST_MAKE_FOURCC ('M', 'P', '4', '3'):
429       caps = gst_caps_new_simple ("video/x-msmpeg",
430           "msmpegversion", G_TYPE_INT, 43, NULL);
431       if (codec_name)
432         *codec_name = g_strdup ("Microsoft MPEG-4 4.3");
433       break;
434
435     case GST_MAKE_FOURCC ('M', 'P', '4', 'S'):
436     case GST_MAKE_FOURCC ('M', '4', 'S', '2'):
437       caps = gst_caps_new_simple ("video/mpeg",
438           "mpegversion", G_TYPE_INT, 4, NULL);
439       if (codec_name)
440         *codec_name = g_strdup ("Microsoft ISO MPEG-4 1.1");
441       break;
442
443     case GST_MAKE_FOURCC ('F', 'M', 'P', '4'):
444     case GST_MAKE_FOURCC ('U', 'M', 'P', '4'):
445     case GST_MAKE_FOURCC ('F', 'F', 'D', 'S'):
446       caps = gst_caps_new_simple ("video/mpeg",
447           "mpegversion", G_TYPE_INT, 4, NULL);
448       if (codec_name)
449         *codec_name = g_strdup ("FFmpeg MPEG-4");
450       break;
451
452     case GST_MAKE_FOURCC ('E', 'M', '4', 'A'):
453     case GST_MAKE_FOURCC ('E', 'P', 'V', 'H'):
454     case GST_MAKE_FOURCC ('F', 'V', 'F', 'W'):
455     case GST_MAKE_FOURCC ('I', 'N', 'M', 'C'):
456     case GST_MAKE_FOURCC ('D', 'I', 'G', 'I'):
457     case GST_MAKE_FOURCC ('D', 'M', '2', 'K'):
458     case GST_MAKE_FOURCC ('D', 'C', 'O', 'D'):
459     case GST_MAKE_FOURCC ('M', 'V', 'X', 'M'):
460     case GST_MAKE_FOURCC ('P', 'M', '4', 'V'):
461     case GST_MAKE_FOURCC ('S', 'M', 'P', '4'):
462     case GST_MAKE_FOURCC ('D', 'X', 'G', 'M'):
463     case GST_MAKE_FOURCC ('V', 'I', 'D', 'M'):
464     case GST_MAKE_FOURCC ('M', '4', 'T', '3'):
465     case GST_MAKE_FOURCC ('G', 'E', 'O', 'X'):
466     case GST_MAKE_FOURCC ('M', 'P', '4', 'V'):
467     case GST_MAKE_FOURCC ('m', 'p', '4', 'v'):
468       caps = gst_caps_new_simple ("video/mpeg",
469           "mpegversion", G_TYPE_INT, 4, NULL);
470       if (codec_name)
471         *codec_name = g_strdup ("MPEG-4");
472       break;
473
474     case GST_MAKE_FOURCC ('3', 'i', 'v', 'd'):
475     case GST_MAKE_FOURCC ('3', 'I', 'V', 'D'):
476       caps = gst_caps_new_simple ("video/x-msmpeg",
477           "msmpegversion", G_TYPE_INT, 43, NULL);
478       if (codec_name)
479         *codec_name = g_strdup ("Microsoft MPEG-4 4.3");        /* FIXME? */
480       break;
481
482     case GST_MAKE_FOURCC ('3', 'I', 'V', '1'):
483     case GST_MAKE_FOURCC ('3', 'I', 'V', '2'):
484       caps = gst_caps_new_empty_simple ("video/x-3ivx");
485       if (codec_name)
486         *codec_name = g_strdup ("3ivx");
487       break;
488
489     case GST_MAKE_FOURCC ('D', 'V', 'S', 'D'):
490     case GST_MAKE_FOURCC ('d', 'v', 's', 'd'):
491     case GST_MAKE_FOURCC ('d', 'v', 'c', ' '):
492     case GST_MAKE_FOURCC ('d', 'v', '2', '5'):
493       caps = gst_caps_new_simple ("video/x-dv",
494           "systemstream", G_TYPE_BOOLEAN, FALSE,
495           "dvversion", G_TYPE_INT, 25, NULL);
496       if (codec_name)
497         *codec_name = g_strdup ("Generic DV");
498       break;
499
500     case GST_MAKE_FOURCC ('C', 'D', 'V', 'C'):
501     case GST_MAKE_FOURCC ('c', 'd', 'v', 'c'):
502       caps = gst_caps_new_simple ("video/x-dv",
503           "systemstream", G_TYPE_BOOLEAN, FALSE,
504           "dvversion", G_TYPE_INT, 25, NULL);
505       if (codec_name)
506         *codec_name = g_strdup ("Canopus DV");
507       break;
508
509     case GST_MAKE_FOURCC ('D', 'V', '5', '0'):
510     case GST_MAKE_FOURCC ('d', 'v', '5', '0'):
511       caps = gst_caps_new_simple ("video/x-dv",
512           "systemstream", G_TYPE_BOOLEAN, FALSE,
513           "dvversion", G_TYPE_INT, 50, NULL);
514       if (codec_name)
515         *codec_name = g_strdup ("DVCPro50 Video");
516       break;
517
518     case GST_MAKE_FOURCC ('W', 'M', 'V', '1'):
519       caps = gst_caps_new_simple ("video/x-wmv",
520           "wmvversion", G_TYPE_INT, 1, NULL);
521       if (codec_name)
522         *codec_name = g_strdup ("Microsoft Windows Media 7");
523       break;
524
525     case GST_MAKE_FOURCC ('W', 'M', 'V', '2'):
526       caps = gst_caps_new_simple ("video/x-wmv",
527           "wmvversion", G_TYPE_INT, 2, NULL);
528       if (codec_name)
529         *codec_name = g_strdup ("Microsoft Windows Media 8");
530       break;
531
532     case GST_MAKE_FOURCC ('W', 'M', 'V', '3'):
533       caps = gst_caps_new_simple ("video/x-wmv",
534           "wmvversion", G_TYPE_INT, 3, NULL);
535       if (codec_name)
536         *codec_name = g_strdup ("Microsoft Windows Media 9");
537       break;
538
539     case GST_MAKE_FOURCC ('W', 'M', 'V', 'A'):
540       caps = gst_caps_new_simple ("video/x-wmv",
541           "wmvversion", G_TYPE_INT, 3, "format", G_TYPE_STRING, "WMVA", NULL);
542       if (codec_name)
543         *codec_name = g_strdup ("Microsoft Windows Media Advanced Profile");
544       break;
545
546     case GST_MAKE_FOURCC ('W', 'V', 'C', '1'):
547       caps = gst_caps_new_simple ("video/x-wmv",
548           "wmvversion", G_TYPE_INT, 3, "format", G_TYPE_STRING, "WVC1", NULL);
549       if (codec_name)
550         *codec_name = g_strdup ("Microsoft Windows Media VC-1");
551       break;
552
553     case GST_MAKE_FOURCC ('c', 'v', 'i', 'd'):
554       caps = gst_caps_new_empty_simple ("video/x-cinepak");
555       if (codec_name)
556         *codec_name = g_strdup ("Cinepak video");
557       break;
558
559     case GST_MAKE_FOURCC ('M', 'S', 'V', 'C'):
560     case GST_MAKE_FOURCC ('m', 's', 'v', 'c'):
561     case GST_MAKE_FOURCC ('C', 'R', 'A', 'M'):
562     case GST_MAKE_FOURCC ('c', 'r', 'a', 'm'):
563     case GST_MAKE_FOURCC ('W', 'H', 'A', 'M'):
564     case GST_MAKE_FOURCC ('w', 'h', 'a', 'm'):
565       caps = gst_caps_new_simple ("video/x-msvideocodec",
566           "msvideoversion", G_TYPE_INT, 1, NULL);
567       if (codec_name)
568         *codec_name = g_strdup ("MS video v1");
569       palette = strf_data;
570       strf_data = NULL;
571       break;
572
573     case GST_MAKE_FOURCC ('R', 'L', 'E', ' '):
574     case GST_MAKE_FOURCC ('m', 'r', 'l', 'e'):
575     case GST_MAKE_FOURCC (0x1, 0x0, 0x0, 0x0): /* why, why, why? */
576     case GST_MAKE_FOURCC (0x2, 0x0, 0x0, 0x0): /* why, why, why? */
577       caps = gst_caps_new_simple ("video/x-rle",
578           "layout", G_TYPE_STRING, "microsoft", NULL);
579       palette = strf_data;
580       strf_data = NULL;
581       if (strf) {
582         gst_caps_set_simple (caps,
583             "depth", G_TYPE_INT, (gint) strf->bit_cnt, NULL);
584       } else {
585         gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 1, 64, NULL);
586       }
587       if (codec_name)
588         *codec_name = g_strdup ("Microsoft RLE");
589       break;
590
591     case GST_MAKE_FOURCC ('A', 'A', 'S', 'C'):
592       caps = gst_caps_new_empty_simple ("video/x-aasc");
593       if (codec_name)
594         *codec_name = g_strdup ("Autodesk Animator");
595       break;
596
597     case GST_MAKE_FOURCC ('X', 'x', 'a', 'n'):
598       caps = gst_caps_new_simple ("video/x-xan",
599           "wcversion", G_TYPE_INT, 4, NULL);
600       if (codec_name)
601         *codec_name = g_strdup ("Xan Wing Commander 4");
602       break;
603
604     case GST_MAKE_FOURCC ('R', 'T', '2', '1'):
605       caps = gst_caps_new_simple ("video/x-indeo",
606           "indeoversion", G_TYPE_INT, 2, NULL);
607       if (codec_name)
608         *codec_name = g_strdup ("Intel Video 2");
609       break;
610
611     case GST_MAKE_FOURCC ('I', 'V', '3', '1'):
612     case GST_MAKE_FOURCC ('I', 'V', '3', '2'):
613     case GST_MAKE_FOURCC ('i', 'v', '3', '1'):
614     case GST_MAKE_FOURCC ('i', 'v', '3', '2'):
615       caps = gst_caps_new_simple ("video/x-indeo",
616           "indeoversion", G_TYPE_INT, 3, NULL);
617       if (codec_name)
618         *codec_name = g_strdup ("Intel Video 3");
619       break;
620
621     case GST_MAKE_FOURCC ('I', 'V', '4', '1'):
622     case GST_MAKE_FOURCC ('i', 'v', '4', '1'):
623       caps = gst_caps_new_simple ("video/x-indeo",
624           "indeoversion", G_TYPE_INT, 4, NULL);
625       if (codec_name)
626         *codec_name = g_strdup ("Intel Video 4");
627       break;
628
629     case GST_MAKE_FOURCC ('I', 'V', '5', '0'):
630       caps = gst_caps_new_simple ("video/x-indeo",
631           "indeoversion", G_TYPE_INT, 5, NULL);
632       if (codec_name)
633         *codec_name = g_strdup ("Intel Video 5");
634       break;
635
636     case GST_MAKE_FOURCC ('M', 'S', 'Z', 'H'):
637       caps = gst_caps_new_empty_simple ("video/x-mszh");
638       if (codec_name)
639         *codec_name = g_strdup ("Lossless MSZH Video");
640       break;
641
642     case GST_MAKE_FOURCC ('Z', 'L', 'I', 'B'):
643       caps = gst_caps_new_empty_simple ("video/x-zlib");
644       if (codec_name)
645         *codec_name = g_strdup ("Lossless zlib video");
646       break;
647
648     case GST_MAKE_FOURCC ('C', 'L', 'J', 'R'):
649     case GST_MAKE_FOURCC ('c', 'l', 'j', 'r'):
650       caps = gst_caps_new_empty_simple ("video/x-cirrus-logic-accupak");
651       if (codec_name)
652         *codec_name = g_strdup ("Cirrus Logipak AccuPak");
653       break;
654
655     case GST_MAKE_FOURCC ('C', 'Y', 'U', 'V'):
656     case GST_MAKE_FOURCC ('c', 'y', 'u', 'v'):
657       caps = gst_caps_new_empty_simple ("video/x-compressed-yuv");
658       if (codec_name)
659         *codec_name = g_strdup ("CYUV Lossless");
660       break;
661
662     case GST_MAKE_FOURCC ('D', 'U', 'C', 'K'):
663     case GST_MAKE_FOURCC ('P', 'V', 'E', 'Z'):
664       caps = gst_caps_new_simple ("video/x-truemotion",
665           "trueversion", G_TYPE_INT, 1, NULL);
666       if (codec_name)
667         *codec_name = g_strdup ("Duck Truemotion1");
668       break;
669
670     case GST_MAKE_FOURCC ('T', 'M', '2', '0'):
671       caps = gst_caps_new_simple ("video/x-truemotion",
672           "trueversion", G_TYPE_INT, 2, NULL);
673       if (codec_name)
674         *codec_name = g_strdup ("TrueMotion 2.0");
675       break;
676
677     case GST_MAKE_FOURCC ('V', 'P', '3', '0'):
678     case GST_MAKE_FOURCC ('v', 'p', '3', '0'):
679     case GST_MAKE_FOURCC ('V', 'P', '3', '1'):
680     case GST_MAKE_FOURCC ('v', 'p', '3', '1'):
681     case GST_MAKE_FOURCC ('V', 'P', '3', ' '):
682       caps = gst_caps_new_empty_simple ("video/x-vp3");
683       if (codec_name)
684         *codec_name = g_strdup ("VP3");
685       break;
686
687     case GST_MAKE_FOURCC ('U', 'L', 'T', 'I'):
688       caps = gst_caps_new_empty_simple ("video/x-ultimotion");
689       if (codec_name)
690         *codec_name = g_strdup ("IBM UltiMotion");
691       break;
692
693     case GST_MAKE_FOURCC ('T', 'S', 'C', 'C'):
694     case GST_MAKE_FOURCC ('t', 's', 'c', 'c'):{
695       if (strf) {
696         gint depth = (strf->bit_cnt != 0) ? (gint) strf->bit_cnt : 24;
697
698         caps = gst_caps_new_simple ("video/x-camtasia", "depth", G_TYPE_INT,
699             depth, NULL);
700       } else {
701         /* template caps */
702         caps = gst_caps_new_empty_simple ("video/x-camtasia");
703       }
704       if (codec_name)
705         *codec_name = g_strdup ("TechSmith Camtasia");
706       break;
707     }
708
709     case GST_MAKE_FOURCC ('C', 'S', 'C', 'D'):
710     {
711       if (strf) {
712         gint depth = (strf->bit_cnt != 0) ? (gint) strf->bit_cnt : 24;
713
714         caps = gst_caps_new_simple ("video/x-camstudio", "depth", G_TYPE_INT,
715             depth, NULL);
716       } else {
717         /* template caps */
718         caps = gst_caps_new_empty_simple ("video/x-camstudio");
719       }
720       if (codec_name)
721         *codec_name = g_strdup ("Camstudio");
722       break;
723     }
724
725     case GST_MAKE_FOURCC ('V', 'C', 'R', '1'):
726       caps = gst_caps_new_simple ("video/x-ati-vcr",
727           "vcrversion", G_TYPE_INT, 1, NULL);
728       if (codec_name)
729         *codec_name = g_strdup ("ATI VCR 1");
730       break;
731
732     case GST_MAKE_FOURCC ('V', 'C', 'R', '2'):
733       caps = gst_caps_new_simple ("video/x-ati-vcr",
734           "vcrversion", G_TYPE_INT, 2, NULL);
735       if (codec_name)
736         *codec_name = g_strdup ("ATI VCR 2");
737       break;
738
739     case GST_MAKE_FOURCC ('A', 'S', 'V', '1'):
740       caps = gst_caps_new_simple ("video/x-asus",
741           "asusversion", G_TYPE_INT, 1, NULL);
742       if (codec_name)
743         *codec_name = g_strdup ("Asus Video 1");
744       break;
745
746     case GST_MAKE_FOURCC ('A', 'S', 'V', '2'):
747       caps = gst_caps_new_simple ("video/x-asus",
748           "asusversion", G_TYPE_INT, 2, NULL);
749       if (codec_name)
750         *codec_name = g_strdup ("Asus Video 2");
751       break;
752
753     case GST_MAKE_FOURCC ('M', 'P', 'N', 'G'):
754     case GST_MAKE_FOURCC ('m', 'p', 'n', 'g'):
755     case GST_MAKE_FOURCC ('P', 'N', 'G', ' '):
756       caps = gst_caps_new_empty_simple ("image/png");
757       if (codec_name)
758         *codec_name = g_strdup ("PNG image");
759       break;
760
761     case GST_MAKE_FOURCC ('F', 'L', 'V', '1'):
762       caps = gst_caps_new_simple ("video/x-flash-video",
763           "flvversion", G_TYPE_INT, 1, NULL);
764       if (codec_name)
765         *codec_name = g_strdup ("Flash Video 1");
766       break;
767
768     case GST_MAKE_FOURCC ('V', 'M', 'n', 'c'):
769       caps = gst_caps_new_simple ("video/x-vmnc",
770           "version", G_TYPE_INT, 1, NULL);
771       if (codec_name)
772         *codec_name = g_strdup ("VMWare NC Video");
773       break;
774
775     case GST_MAKE_FOURCC ('d', 'r', 'a', 'c'):
776       caps = gst_caps_new_empty_simple ("video/x-dirac");
777       if (codec_name)
778         *codec_name = g_strdup ("Dirac");
779       break;
780
781     case GST_RIFF_rpza:
782     case GST_RIFF_azpr:
783     case GST_MAKE_FOURCC ('R', 'P', 'Z', 'A'):
784       caps = gst_caps_new_empty_simple ("video/x-apple-video");
785       if (codec_name)
786         *codec_name = g_strdup ("Apple Video (RPZA)");
787       break;
788
789
790     case GST_MAKE_FOURCC ('F', 'F', 'V', '1'):
791       caps = gst_caps_new_simple ("video/x-ffv",
792           "ffvversion", G_TYPE_INT, 1, NULL);
793       if (codec_name)
794         *codec_name = g_strdup ("FFmpeg lossless video codec");
795       break;
796
797     case GST_MAKE_FOURCC ('K', 'M', 'V', 'C'):
798       caps = gst_caps_new_empty_simple ("video/x-kmvc");
799       if (codec_name)
800         *codec_name = g_strdup ("Karl Morton's video codec");
801       break;
802
803     case GST_MAKE_FOURCC ('v', 'p', '5', '0'):
804     case GST_MAKE_FOURCC ('V', 'P', '5', '0'):
805       caps = gst_caps_new_empty_simple ("video/x-vp5");
806       if (codec_name)
807         *codec_name = g_strdup ("On2 VP5");
808       break;
809
810     case GST_MAKE_FOURCC ('v', 'p', '6', '0'):
811     case GST_MAKE_FOURCC ('V', 'P', '6', '0'):
812     case GST_MAKE_FOURCC ('v', 'p', '6', '1'):
813     case GST_MAKE_FOURCC ('V', 'P', '6', '1'):
814     case GST_MAKE_FOURCC ('V', 'p', '6', '2'):
815     case GST_MAKE_FOURCC ('V', 'P', '6', '2'):
816       caps = gst_caps_new_empty_simple ("video/x-vp6");
817       if (codec_name)
818         *codec_name = g_strdup ("On2 VP6");
819       break;
820
821     case GST_MAKE_FOURCC ('V', 'P', '6', 'F'):
822     case GST_MAKE_FOURCC ('v', 'p', '6', 'f'):
823     case GST_MAKE_FOURCC ('F', 'L', 'V', '4'):
824       caps = gst_caps_new_empty_simple ("video/x-vp6-flash");
825       if (codec_name)
826         *codec_name = g_strdup ("On2 VP6");
827       break;
828
829     case GST_MAKE_FOURCC ('v', 'p', '7', '0'):
830     case GST_MAKE_FOURCC ('V', 'P', '7', '0'):
831       caps = gst_caps_new_empty_simple ("video/x-vp7");
832       if (codec_name)
833         *codec_name = g_strdup ("On2 VP7");
834       break;
835
836     case GST_MAKE_FOURCC ('V', 'P', '8', '0'):
837       caps = gst_caps_new_empty_simple ("video/x-vp8");
838       if (codec_name)
839         *codec_name = g_strdup ("On2 VP8");
840       break;
841
842     case GST_MAKE_FOURCC ('L', 'M', '2', '0'):
843       caps = gst_caps_new_empty_simple ("video/x-mimic");
844       if (codec_name)
845         *codec_name = g_strdup ("Mimic webcam");
846       break;
847
848     case GST_MAKE_FOURCC ('T', 'H', 'E', 'O'):
849     case GST_MAKE_FOURCC ('t', 'h', 'e', 'o'):
850       caps = gst_caps_new_empty_simple ("video/x-theora");
851       if (codec_name)
852         *codec_name = g_strdup ("Theora video codec");
853
854       break;
855
856     case GST_MAKE_FOURCC ('F', 'P', 'S', '1'):
857       caps = gst_caps_new_empty_simple ("video/x-fraps");
858       if (codec_name)
859         *codec_name = g_strdup ("Fraps video");
860
861       break;
862
863     default:
864       GST_WARNING ("Unknown video fourcc %" GST_FOURCC_FORMAT,
865           GST_FOURCC_ARGS (codec_fcc));
866       return NULL;
867   }
868
869   if (strh != NULL) {
870     gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION,
871         strh->rate, strh->scale, NULL);
872   } else {
873     gst_caps_set_simple (caps,
874         "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
875   }
876
877   if (strf != NULL) {
878     gst_caps_set_simple (caps,
879         "width", G_TYPE_INT, strf->width,
880         "height", G_TYPE_INT, strf->height, NULL);
881   } else {
882     gst_caps_set_simple (caps,
883         "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
884         "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
885   }
886
887   /* extradata */
888   if (strf_data || strd_data) {
889     GstBuffer *codec_data;
890
891     codec_data = strf_data ? strf_data : strd_data;
892
893     gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, codec_data, NULL);
894   }
895
896   /* palette */
897   if (palette) {
898     GstBuffer *copy;
899     guint num_colors;
900     gsize size;
901
902     if (strf != NULL)
903       num_colors = strf->num_colors;
904     else
905       num_colors = 256;
906
907     size = gst_buffer_get_size (palette);
908
909     if (size >= (num_colors * 4)) {
910       /* palette is always at least 256*4 bytes */
911       copy = gst_buffer_new_and_alloc (MAX (size, 256 * 4));
912       gst_buffer_copy_into (copy, palette, GST_BUFFER_COPY_MEMORY, 0, size);
913
914 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
915       {
916         guint8 *data, *p;
917         gint n;
918
919         data = p = gst_buffer_map (copy, NULL, NULL, GST_MAP_READWRITE);
920         /* own endianness */
921         for (n = 0; n < num_colors; n++) {
922           GST_WRITE_UINT32_BE (p, GST_READ_UINT32_LE (p));
923           p += sizeof (guint32);
924         }
925         gst_buffer_unmap (copy, data, -1);
926       }
927 #endif
928       gst_caps_set_simple (caps, "palette_data", GST_TYPE_BUFFER, copy, NULL);
929       gst_buffer_unref (copy);
930     } else {
931       GST_WARNING ("Palette smaller than expected: broken file");
932     }
933   }
934
935   return caps;
936 }
937
938 static const struct
939 {
940   const guint32 ms_mask;
941   const GstAudioChannelPosition gst_pos;
942 } layout_mapping[] = {
943   {
944   0x00001, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT}, {
945   0x00002, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}, {
946   0x00004, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER}, {
947   0x00008, GST_AUDIO_CHANNEL_POSITION_LFE1}, {
948   0x00010, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT}, {
949   0x00020, GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}, {
950   0x00040, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER}, {
951   0x00080, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER}, {
952   0x00100, GST_AUDIO_CHANNEL_POSITION_REAR_CENTER}, {
953   0x00200, GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT}, {
954   0x00400, GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT}, {
955   0x00800, GST_AUDIO_CHANNEL_POSITION_TOP_CENTER}, {
956   0x01000, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT}, {
957   0x02000, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER}, {
958   0x04000, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT}, {
959   0x08000, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT}, {
960   0x10000, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER}, {
961   0x20000, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT}
962 };
963
964 #define MAX_CHANNEL_POSITIONS G_N_ELEMENTS (layout_mapping)
965
966 static gboolean
967 gst_riff_wavext_add_channel_mask (GstCaps * caps, guint32 layout)
968 {
969   GstStructure *s;
970   gint num_channels, i, p;
971   guint64 channel_mask = 0;
972
973   s = gst_caps_get_structure (caps, 0);
974   if (!gst_structure_get_int (s, "channels", &num_channels))
975     g_return_val_if_reached (FALSE);
976
977   if (num_channels < 2 || num_channels > MAX_CHANNEL_POSITIONS) {
978     GST_DEBUG ("invalid number of channels: %d", num_channels);
979     return FALSE;
980   }
981
982   p = 0;
983   for (i = 0; i < MAX_CHANNEL_POSITIONS; ++i) {
984     if ((layout & layout_mapping[i].ms_mask) != 0) {
985       if (p >= num_channels) {
986         GST_WARNING ("More bits set in the channel layout map than there "
987             "are channels! Broken file");
988         return FALSE;
989       }
990       if (layout_mapping[i].gst_pos == GST_AUDIO_CHANNEL_POSITION_INVALID) {
991         GST_WARNING ("Unsupported channel position (mask 0x%08x) in channel "
992             "layout map - ignoring those channels", layout_mapping[i].ms_mask);
993         /* what to do? just ignore it and let downstream deal with a channel
994          * layout that has INVALID positions in it for now ... */
995       }
996       channel_mask |= G_GUINT64_CONSTANT (1) << layout_mapping[i].gst_pos;
997       ++p;
998     }
999   }
1000
1001   if (p != num_channels) {
1002     GST_WARNING ("Only %d bits set in the channel layout map, but there are "
1003         "supposed to be %d channels! Broken file", p, num_channels);
1004     return FALSE;
1005   }
1006
1007   gst_caps_set_simple (caps, "channel-mask", GST_TYPE_BITMASK, channel_mask,
1008       NULL);
1009
1010   return TRUE;
1011 }
1012
1013 static gboolean
1014 gst_riff_wave_add_default_channel_mask (GstCaps * caps)
1015 {
1016   GstStructure *s;
1017   gint nchannels;
1018   guint64 channel_mask = 0;
1019
1020   s = gst_caps_get_structure (caps, 0);
1021
1022   if (!gst_structure_get_int (s, "channels", &nchannels))
1023     g_return_val_if_reached (FALSE);
1024
1025   if (nchannels > 8) {
1026     GST_DEBUG ("invalid number of channels: %d", nchannels);
1027     return FALSE;
1028   }
1029
1030   /* This uses the default channel mapping from ALSA which
1031    * is used in quite a few surround test files and seems to be
1032    * the defacto standard. The channel mapping from
1033    * WAVE_FORMAT_EXTENSIBLE doesn't seem to be used in normal
1034    * wav files like chan-id.wav.
1035    * http://bugzilla.gnome.org/show_bug.cgi?id=489010
1036    */
1037   switch (nchannels) {
1038     case 1:
1039       /* Mono => nothing */
1040       return TRUE;
1041     case 8:
1042       channel_mask |=
1043           G_GUINT64_CONSTANT (1) << GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT;
1044       channel_mask |=
1045           G_GUINT64_CONSTANT (1) << GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT;
1046       /* fall through */
1047     case 6:
1048       channel_mask |= G_GUINT64_CONSTANT (1) << GST_AUDIO_CHANNEL_POSITION_LFE1;
1049       /* fall through */
1050     case 5:
1051       channel_mask |=
1052           G_GUINT64_CONSTANT (1) << GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER;
1053       /* fall through */
1054     case 4:
1055       channel_mask |=
1056           G_GUINT64_CONSTANT (1) << GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT;
1057       channel_mask |=
1058           G_GUINT64_CONSTANT (1) << GST_AUDIO_CHANNEL_POSITION_REAR_LEFT;
1059       /* fall through */
1060     case 2:
1061       channel_mask |=
1062           G_GUINT64_CONSTANT (1) << GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
1063       channel_mask |=
1064           G_GUINT64_CONSTANT (1) << GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
1065       break;
1066     default:
1067       return FALSE;
1068   }
1069
1070   gst_caps_set_simple (caps, "channel-mask", GST_TYPE_BITMASK, channel_mask,
1071       NULL);
1072
1073   return TRUE;
1074 }
1075
1076 static guint32
1077 gst_riff_wavext_get_default_channel_mask (guint nchannels)
1078 {
1079   guint32 channel_mask = 0;
1080
1081   /* Set the default channel mask for the given number of channels.
1082    * http://www.microsoft.com/whdc/device/audio/multichaud.mspx
1083    */
1084   switch (nchannels) {
1085     case 11:
1086       channel_mask |= 0x00400;
1087       channel_mask |= 0x00200;
1088     case 9:
1089       channel_mask |= 0x00100;
1090     case 8:
1091       channel_mask |= 0x00080;
1092       channel_mask |= 0x00040;
1093     case 6:
1094       channel_mask |= 0x00020;
1095       channel_mask |= 0x00010;
1096     case 4:
1097       channel_mask |= 0x00008;
1098     case 3:
1099       channel_mask |= 0x00004;
1100     case 2:
1101       channel_mask |= 0x00002;
1102       channel_mask |= 0x00001;
1103       break;
1104   }
1105
1106   return channel_mask;
1107 }
1108
1109 GstCaps *
1110 gst_riff_create_audio_caps (guint16 codec_id,
1111     gst_riff_strh * strh, gst_riff_strf_auds * strf,
1112     GstBuffer * strf_data, GstBuffer * strd_data, char **codec_name)
1113 {
1114   gboolean block_align = FALSE, rate_chan = TRUE;
1115   GstCaps *caps = NULL;
1116   gint rate_min = 1000, rate_max = 96000;
1117   gint channels_max = 2;
1118
1119   switch (codec_id) {
1120     case GST_RIFF_WAVE_FORMAT_PCM:     /* PCM */
1121       rate_max = 192000;
1122       channels_max = 8;
1123
1124       if (strf != NULL) {
1125         gint ba = strf->blockalign;
1126         gint ch = strf->channels;
1127         gint wd, ws;
1128         GstAudioFormat format;
1129
1130         /* If we have an empty blockalign, we take the width contained in 
1131          * strf->size */
1132         if (ba != 0)
1133           wd = ba * 8 / ch;
1134         else
1135           wd = strf->size;
1136
1137         if (strf->size > 32) {
1138           GST_WARNING ("invalid depth (%d) of pcm audio, overwriting.",
1139               strf->size);
1140           strf->size = 8 * ((wd + 7) / 8);
1141         }
1142
1143         /* in riff, the depth is stored in the size field but it just means that
1144          * the _least_ significant bits are cleared. We can therefore just play
1145          * the sample as if it had a depth == width */
1146         /* For reference, the actual depth is in strf->size */
1147         ws = wd;
1148
1149         format =
1150             gst_audio_format_build_integer (wd != 8, G_LITTLE_ENDIAN, wd, ws);
1151
1152         caps = gst_caps_new_simple ("audio/x-raw",
1153             "format", G_TYPE_STRING, gst_audio_format_to_string (format),
1154             "layout", G_TYPE_STRING, "interleaved",
1155             "channels", G_TYPE_INT, ch, NULL);
1156
1157         /* Add default channel layout. In theory this should be done
1158          * for 1 and 2 channels too but apparently breaks too many
1159          * things currently. Also we know no default layout for more than
1160          * 8 channels. */
1161         if (ch > 2) {
1162           if (ch > 8)
1163             GST_WARNING ("don't know default layout for %d channels", ch);
1164           else if (gst_riff_wave_add_default_channel_mask (caps))
1165             GST_DEBUG ("using default channel layout for %d channels", ch);
1166           else
1167             GST_WARNING ("failed to add channel layout");
1168         }
1169       } else {
1170         /* FIXME: this is pretty useless - we need fixed caps */
1171         caps = gst_caps_from_string ("audio/x-raw, "
1172             "format = (string) { S8, U8, S16LE, U16LE, S24LE, "
1173             "U24LE, S32LE, U32LE }, " "layout = (string) interleaved");
1174       }
1175       if (codec_name && strf)
1176         *codec_name = g_strdup_printf ("Uncompressed %d-bit PCM audio",
1177             strf->size);
1178       break;
1179
1180     case GST_RIFF_WAVE_FORMAT_ADPCM:
1181       caps = gst_caps_new_simple ("audio/x-adpcm",
1182           "layout", G_TYPE_STRING, "microsoft", NULL);
1183       if (codec_name)
1184         *codec_name = g_strdup ("ADPCM audio");
1185       block_align = TRUE;
1186       break;
1187
1188     case GST_RIFF_WAVE_FORMAT_IEEE_FLOAT:
1189       rate_max = 192000;
1190       channels_max = 8;
1191
1192       if (strf != NULL) {
1193         gint ba = strf->blockalign;
1194         gint ch = strf->channels;
1195         gint wd = ba * 8 / ch;
1196
1197         caps = gst_caps_new_simple ("audio/x-raw",
1198             "format", G_TYPE_STRING, wd == 64 ? "F64LE" : "F32LE",
1199             "layout", G_TYPE_STRING, "interleaved",
1200             "channels", G_TYPE_INT, ch, NULL);
1201
1202         /* Add default channel layout. In theory this should be done
1203          * for 1 and 2 channels too but apparently breaks too many
1204          * things currently. Also we know no default layout for more than
1205          * 8 channels. */
1206         if (ch > 2) {
1207           if (ch > 8)
1208             GST_WARNING ("don't know default layout for %d channels", ch);
1209           else if (gst_riff_wave_add_default_channel_mask (caps))
1210             GST_DEBUG ("using default channel layout for %d channels", ch);
1211           else
1212             GST_WARNING ("failed to add channel layout");
1213         }
1214       } else {
1215         /* FIXME: this is pretty useless - we need fixed caps */
1216         caps = gst_caps_from_string ("audio/x-raw, "
1217             "format = (string) { F32LE, F64LE }, "
1218             "layout = (string) interleaved");
1219       }
1220       if (codec_name && strf)
1221         *codec_name = g_strdup_printf ("Uncompressed %d-bit IEEE float audio",
1222             strf->size);
1223       break;
1224
1225     case GST_RIFF_WAVE_FORMAT_IBM_CVSD:
1226       goto unknown;
1227
1228     case GST_RIFF_WAVE_FORMAT_ALAW:
1229       if (strf != NULL) {
1230         if (strf->size != 8) {
1231           GST_WARNING ("invalid depth (%d) of alaw audio, overwriting.",
1232               strf->size);
1233           strf->size = 8;
1234           strf->blockalign = (strf->size * strf->channels) / 8;
1235           strf->av_bps = strf->blockalign * strf->rate;
1236         }
1237         if (strf->av_bps == 0 || strf->blockalign == 0) {
1238           GST_WARNING ("fixing av_bps (%d) and blockalign (%d) of alaw audio",
1239               strf->av_bps, strf->blockalign);
1240           strf->blockalign = (strf->size * strf->channels) / 8;
1241           strf->av_bps = strf->blockalign * strf->rate;
1242         }
1243       }
1244       rate_max = 48000;
1245       caps = gst_caps_new_empty_simple ("audio/x-alaw");
1246       if (codec_name)
1247         *codec_name = g_strdup ("A-law audio");
1248       break;
1249
1250     case GST_RIFF_WAVE_FORMAT_WMS:
1251       caps = gst_caps_new_empty_simple ("audio/x-wms");
1252       if (strf != NULL) {
1253         gst_caps_set_simple (caps,
1254             "bitrate", G_TYPE_INT, strf->av_bps * 8,
1255             "width", G_TYPE_INT, strf->size,
1256             "depth", G_TYPE_INT, strf->size, NULL);
1257       } else {
1258         gst_caps_set_simple (caps,
1259             "bitrate", GST_TYPE_INT_RANGE, 0, G_MAXINT, NULL);
1260       }
1261       if (codec_name)
1262         *codec_name = g_strdup ("Windows Media Audio Speech");
1263       block_align = TRUE;
1264       break;
1265
1266     case GST_RIFF_WAVE_FORMAT_MULAW:
1267       if (strf != NULL) {
1268         if (strf->size != 8) {
1269           GST_WARNING ("invalid depth (%d) of mulaw audio, overwriting.",
1270               strf->size);
1271           strf->size = 8;
1272           strf->blockalign = (strf->size * strf->channels) / 8;
1273           strf->av_bps = strf->blockalign * strf->rate;
1274         }
1275         if (strf->av_bps == 0 || strf->blockalign == 0) {
1276           GST_WARNING ("fixing av_bps (%d) and blockalign (%d) of mulaw audio",
1277               strf->av_bps, strf->blockalign);
1278           strf->blockalign = (strf->size * strf->channels) / 8;
1279           strf->av_bps = strf->blockalign * strf->rate;
1280         }
1281       }
1282       rate_max = 48000;
1283       caps = gst_caps_new_empty_simple ("audio/x-mulaw");
1284       if (codec_name)
1285         *codec_name = g_strdup ("Mu-law audio");
1286       break;
1287
1288     case GST_RIFF_WAVE_FORMAT_OKI_ADPCM:
1289       goto unknown;
1290
1291     case GST_RIFF_WAVE_FORMAT_DVI_ADPCM:
1292       rate_max = 48000;
1293       caps = gst_caps_new_simple ("audio/x-adpcm",
1294           "layout", G_TYPE_STRING, "dvi", NULL);
1295       if (codec_name)
1296         *codec_name = g_strdup ("DVI ADPCM audio");
1297       block_align = TRUE;
1298       break;
1299
1300     case GST_RIFF_WAVE_FORMAT_DSP_TRUESPEECH:
1301       rate_min = 8000;
1302       rate_max = 8000;
1303       caps = gst_caps_new_empty_simple ("audio/x-truespeech");
1304       if (codec_name)
1305         *codec_name = g_strdup ("DSP Group TrueSpeech");
1306       break;
1307
1308     case GST_RIFF_WAVE_FORMAT_GSM610:
1309     case GST_RIFF_WAVE_FORMAT_MSN:
1310       rate_min = 1;
1311       caps = gst_caps_new_empty_simple ("audio/ms-gsm");
1312       if (codec_name)
1313         *codec_name = g_strdup ("MS GSM audio");
1314       break;
1315
1316     case GST_RIFF_WAVE_FORMAT_MPEGL12: /* mp1 or mp2 */
1317       rate_min = 16000;
1318       rate_max = 48000;
1319       caps = gst_caps_new_simple ("audio/mpeg",
1320           "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 2, NULL);
1321       if (codec_name)
1322         *codec_name = g_strdup ("MPEG-1 layer 2");
1323       break;
1324
1325     case GST_RIFF_WAVE_FORMAT_MPEGL3:  /* mp3 */
1326       rate_min = 8000;
1327       rate_max = 48000;
1328       caps = gst_caps_new_simple ("audio/mpeg",
1329           "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 3, NULL);
1330       if (codec_name)
1331         *codec_name = g_strdup ("MPEG-1 layer 3");
1332       break;
1333
1334     case GST_RIFF_WAVE_FORMAT_AMR_NB:  /* amr-nb */
1335       rate_min = 8000;
1336       rate_max = 8000;
1337       channels_max = 1;
1338       caps = gst_caps_new_empty_simple ("audio/AMR");
1339       if (codec_name)
1340         *codec_name = g_strdup ("AMR Narrow Band (NB)");
1341       break;
1342
1343     case GST_RIFF_WAVE_FORMAT_AMR_WB:  /* amr-wb */
1344       rate_min = 16000;
1345       rate_max = 16000;
1346       channels_max = 1;
1347       caps = gst_caps_new_empty_simple ("audio/AMR-WB");
1348       if (codec_name)
1349         *codec_name = g_strdup ("AMR Wide Band (WB)");
1350       break;
1351
1352     case GST_RIFF_WAVE_FORMAT_VORBIS1: /* ogg/vorbis mode 1 */
1353     case GST_RIFF_WAVE_FORMAT_VORBIS2: /* ogg/vorbis mode 2 */
1354     case GST_RIFF_WAVE_FORMAT_VORBIS3: /* ogg/vorbis mode 3 */
1355     case GST_RIFF_WAVE_FORMAT_VORBIS1PLUS:     /* ogg/vorbis mode 1+ */
1356     case GST_RIFF_WAVE_FORMAT_VORBIS2PLUS:     /* ogg/vorbis mode 2+ */
1357     case GST_RIFF_WAVE_FORMAT_VORBIS3PLUS:     /* ogg/vorbis mode 3+ */
1358       rate_max = 192000;
1359       caps = gst_caps_new_empty_simple ("audio/x-vorbis");
1360       if (codec_name)
1361         *codec_name = g_strdup ("Vorbis");
1362       break;
1363
1364     case GST_RIFF_WAVE_FORMAT_A52:
1365       channels_max = 6;
1366       caps = gst_caps_new_empty_simple ("audio/x-ac3");
1367       if (codec_name)
1368         *codec_name = g_strdup ("AC-3 audio");
1369       break;
1370     case GST_RIFF_WAVE_FORMAT_DTS:
1371       channels_max = 6;
1372       caps = gst_caps_new_empty_simple ("audio/x-dts");
1373       if (codec_name)
1374         *codec_name = g_strdup ("DTS audio");
1375       /* wavparse is not always able to specify rate/channels for DTS-in-wav */
1376       rate_chan = FALSE;
1377       break;
1378     case GST_RIFF_WAVE_FORMAT_AAC:
1379     case GST_RIFF_WAVE_FORMAT_AAC_AC:
1380     case GST_RIFF_WAVE_FORMAT_AAC_pm:
1381     {
1382       channels_max = 8;
1383       caps = gst_caps_new_simple ("audio/mpeg",
1384           "mpegversion", G_TYPE_INT, 4, NULL);
1385       if (codec_name)
1386         *codec_name = g_strdup ("MPEG-4 AAC audio");
1387       break;
1388     }
1389     case GST_RIFF_WAVE_FORMAT_WMAV1:
1390     case GST_RIFF_WAVE_FORMAT_WMAV2:
1391     case GST_RIFF_WAVE_FORMAT_WMAV3:
1392     case GST_RIFF_WAVE_FORMAT_WMAV3_L:
1393     {
1394       gint version = (codec_id - GST_RIFF_WAVE_FORMAT_WMAV1) + 1;
1395
1396       channels_max = 6;
1397       block_align = TRUE;
1398
1399       caps = gst_caps_new_simple ("audio/x-wma",
1400           "wmaversion", G_TYPE_INT, version, NULL);
1401
1402       if (codec_name) {
1403         if (codec_id == GST_RIFF_WAVE_FORMAT_WMAV3_L)
1404           *codec_name = g_strdup ("WMA Lossless");
1405         else
1406           *codec_name = g_strdup_printf ("WMA Version %d", version + 6);
1407       }
1408
1409       if (strf != NULL) {
1410         gst_caps_set_simple (caps,
1411             "bitrate", G_TYPE_INT, strf->av_bps * 8,
1412             "depth", G_TYPE_INT, strf->size, NULL);
1413       } else {
1414         gst_caps_set_simple (caps,
1415             "bitrate", GST_TYPE_INT_RANGE, 0, G_MAXINT, NULL);
1416       }
1417       break;
1418     }
1419     case GST_RIFF_WAVE_FORMAT_SONY_ATRAC3:
1420       caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
1421       if (codec_name)
1422         *codec_name = g_strdup ("Sony ATRAC3");
1423       break;
1424
1425     case GST_RIFF_WAVE_FORMAT_SIREN:
1426       caps = gst_caps_new_empty_simple ("audio/x-siren");
1427       if (codec_name)
1428         *codec_name = g_strdup ("Siren7");
1429       rate_chan = FALSE;
1430       break;
1431
1432     case GST_RIFF_WAVE_FORMAT_ADPCM_IMA_DK4:
1433       rate_min = 8000;
1434       rate_max = 96000;
1435       channels_max = 2;
1436       caps =
1437           gst_caps_new_simple ("audio/x-adpcm", "layout", G_TYPE_STRING, "dk4",
1438           NULL);
1439       if (codec_name)
1440         *codec_name = g_strdup ("IMA/DK4 ADPCM");
1441       break;
1442     case GST_RIFF_WAVE_FORMAT_ADPCM_IMA_DK3:
1443       rate_min = 8000;
1444       rate_max = 96000;
1445       channels_max = 2;
1446       caps =
1447           gst_caps_new_simple ("audio/x-adpcm", "layout", G_TYPE_STRING, "dk3",
1448           NULL);
1449       if (codec_name)
1450         *codec_name = g_strdup ("IMA/DK3 ADPCM");
1451       break;
1452
1453     case GST_RIFF_WAVE_FORMAT_ADPCM_IMA_WAV:
1454       rate_min = 8000;
1455       rate_max = 96000;
1456       channels_max = 2;
1457       caps =
1458           gst_caps_new_simple ("audio/x-adpcm", "layout", G_TYPE_STRING, "dvi",
1459           NULL);
1460       if (codec_name)
1461         *codec_name = g_strdup ("IMA/WAV ADPCM");
1462       break;
1463     case GST_RIFF_WAVE_FORMAT_EXTENSIBLE:{
1464       guint16 valid_bits_per_sample;
1465       guint32 channel_mask;
1466       guint32 subformat_guid[4];
1467       guint8 *data;
1468       gsize size;
1469
1470       channels_max = 8;
1471
1472       /* should be at least 22 bytes */
1473       size = gst_buffer_get_size (strf_data);
1474
1475       if (strf_data == NULL || size < 22) {
1476         GST_WARNING ("WAVE_FORMAT_EXTENSIBLE data size is %" G_GSIZE_FORMAT
1477             " (expected: 22)", (strf_data) ? size : -1);
1478         return NULL;
1479       }
1480
1481       data = gst_buffer_map (strf_data, &size, NULL, GST_MAP_READ);
1482       valid_bits_per_sample = GST_READ_UINT16_LE (data);
1483       channel_mask = GST_READ_UINT32_LE (data + 2);
1484       subformat_guid[0] = GST_READ_UINT32_LE (data + 6);
1485       subformat_guid[1] = GST_READ_UINT32_LE (data + 10);
1486       subformat_guid[2] = GST_READ_UINT32_LE (data + 14);
1487       subformat_guid[3] = GST_READ_UINT32_LE (data + 18);
1488       gst_buffer_unmap (strf_data, data, size);
1489
1490       GST_DEBUG ("valid bps    = %u", valid_bits_per_sample);
1491       GST_DEBUG ("channel mask = 0x%08x", channel_mask);
1492       GST_DEBUG ("GUID         = %08x-%08x-%08x-%08x", subformat_guid[0],
1493           subformat_guid[1], subformat_guid[2], subformat_guid[3]);
1494
1495       if (subformat_guid[1] == 0x00100000 &&
1496           subformat_guid[2] == 0xaa000080 && subformat_guid[3] == 0x719b3800) {
1497         if (subformat_guid[0] == 0x00000001) {
1498           GST_DEBUG ("PCM");
1499           if (strf != NULL) {
1500             gint ba = strf->blockalign;
1501             gint wd = ba * 8 / strf->channels;
1502             gint ws;
1503             GstAudioFormat format;
1504
1505             /* in riff, the depth is stored in the size field but it just
1506              * means that the _least_ significant bits are cleared. We can
1507              * therefore just play the sample as if it had a depth == width */
1508             ws = wd;
1509
1510             /* For reference, use this to get the actual depth:
1511              * ws = strf->size;
1512              * if (valid_bits_per_sample != 0)
1513              *   ws = valid_bits_per_sample; */
1514
1515             format =
1516                 gst_audio_format_build_integer (wd != 8, G_LITTLE_ENDIAN, wd,
1517                 ws);
1518
1519             caps = gst_caps_new_simple ("audio/x-raw",
1520                 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
1521                 "layout", G_TYPE_STRING, "interleaved",
1522                 "channels", G_TYPE_INT, strf->channels,
1523                 "rate", G_TYPE_INT, strf->rate, NULL);
1524
1525             /* If channel_mask == 0 and channels > 2 let's
1526              * assume default layout as some wav files don't have the
1527              * channel mask set. Don't set the layout for 1 or 2
1528              * channels as it apparently breaks too many things currently. */
1529             if (channel_mask == 0 && strf->channels > 2)
1530               channel_mask =
1531                   gst_riff_wavext_get_default_channel_mask (strf->channels);
1532
1533             if ((channel_mask != 0 || strf->channels > 2) &&
1534                 !gst_riff_wavext_add_channel_mask (caps, channel_mask)) {
1535               GST_WARNING ("failed to add channel layout");
1536               gst_caps_unref (caps);
1537               caps = NULL;
1538             }
1539             rate_chan = FALSE;
1540
1541             if (codec_name) {
1542               *codec_name = g_strdup_printf ("Uncompressed %d-bit PCM audio",
1543                   strf->size);
1544             }
1545           }
1546         } else if (subformat_guid[0] == 0x00000003) {
1547           GST_DEBUG ("FLOAT");
1548           if (strf != NULL) {
1549             gint ba = strf->blockalign;
1550             gint wd = ba * 8 / strf->channels;
1551
1552             caps = gst_caps_new_simple ("audio/x-raw",
1553                 "format", G_TYPE_STRING, wd == 32 ? "F32LE" : "F64LE",
1554                 "layout", G_TYPE_STRING, "interleaved",
1555                 "channels", G_TYPE_INT, strf->channels,
1556                 "rate", G_TYPE_INT, strf->rate, NULL);
1557
1558             /* If channel_mask == 0 and channels > 2 let's
1559              * assume default layout as some wav files don't have the
1560              * channel mask set. Don't set the layout for 1 or 2
1561              * channels as it apparently breaks too many things currently. */
1562             if (channel_mask == 0 && strf->channels > 2)
1563               channel_mask =
1564                   gst_riff_wavext_get_default_channel_mask (strf->channels);
1565
1566             if ((channel_mask != 0 || strf->channels > 2) &&
1567                 !gst_riff_wavext_add_channel_mask (caps, channel_mask)) {
1568               GST_WARNING ("failed to add channel layout");
1569               gst_caps_unref (caps);
1570               caps = NULL;
1571             }
1572             rate_chan = FALSE;
1573
1574             if (codec_name) {
1575               *codec_name =
1576                   g_strdup_printf ("Uncompressed %d-bit IEEE float audio",
1577                   strf->size);
1578             }
1579           }
1580         } else if (subformat_guid[0] == 00000006) {
1581           GST_DEBUG ("ALAW");
1582           if (strf != NULL) {
1583             if (strf->size != 8) {
1584               GST_WARNING ("invalid depth (%d) of alaw audio, overwriting.",
1585                   strf->size);
1586               strf->size = 8;
1587               strf->av_bps = 8;
1588               strf->blockalign = strf->av_bps * strf->channels;
1589             }
1590             if (strf->av_bps == 0 || strf->blockalign == 0) {
1591               GST_WARNING
1592                   ("fixing av_bps (%d) and blockalign (%d) of alaw audio",
1593                   strf->av_bps, strf->blockalign);
1594               strf->av_bps = strf->size;
1595               strf->blockalign = strf->av_bps * strf->channels;
1596             }
1597           }
1598           rate_max = 48000;
1599           caps = gst_caps_new_empty_simple ("audio/x-alaw");
1600
1601           if (codec_name)
1602             *codec_name = g_strdup ("A-law audio");
1603         } else if (subformat_guid[0] == 0x00000007) {
1604           GST_DEBUG ("MULAW");
1605           if (strf != NULL) {
1606             if (strf->size != 8) {
1607               GST_WARNING ("invalid depth (%d) of mulaw audio, overwriting.",
1608                   strf->size);
1609               strf->size = 8;
1610               strf->av_bps = 8;
1611               strf->blockalign = strf->av_bps * strf->channels;
1612             }
1613             if (strf->av_bps == 0 || strf->blockalign == 0) {
1614               GST_WARNING
1615                   ("fixing av_bps (%d) and blockalign (%d) of mulaw audio",
1616                   strf->av_bps, strf->blockalign);
1617               strf->av_bps = strf->size;
1618               strf->blockalign = strf->av_bps * strf->channels;
1619             }
1620           }
1621           rate_max = 48000;
1622           caps = gst_caps_new_empty_simple ("audio/x-mulaw");
1623           if (codec_name)
1624             *codec_name = g_strdup ("Mu-law audio");
1625         } else if (subformat_guid[0] == 0x00000092) {
1626           GST_DEBUG ("FIXME: handle DOLBY AC3 SPDIF format");
1627         }
1628       } else if (subformat_guid[0] == 0x6ba47966 &&
1629           subformat_guid[1] == 0x41783f83 &&
1630           subformat_guid[2] == 0xf0006596 && subformat_guid[3] == 0xe59262bf) {
1631         caps = gst_caps_new_empty_simple ("application/x-ogg-avi");
1632         if (codec_name)
1633           *codec_name = g_strdup ("Ogg-AVI");
1634       }
1635
1636       if (caps == NULL) {
1637         GST_WARNING ("Unknown WAVE_FORMAT_EXTENSIBLE audio format");
1638         return NULL;
1639       }
1640       break;
1641     }
1642       /* can anything decode these? pitfdll? */
1643     case GST_RIFF_WAVE_FORMAT_VOXWARE_AC8:
1644     case GST_RIFF_WAVE_FORMAT_VOXWARE_AC10:
1645     case GST_RIFF_WAVE_FORMAT_VOXWARE_AC16:
1646     case GST_RIFF_WAVE_FORMAT_VOXWARE_AC20:
1647     case GST_RIFF_WAVE_FORMAT_VOXWARE_METAVOICE:
1648     case GST_RIFF_WAVE_FORMAT_VOXWARE_METASOUND:
1649     case GST_RIFF_WAVE_FORMAT_VOXWARE_RT29HW:
1650     case GST_RIFF_WAVE_FORMAT_VOXWARE_VR12:
1651     case GST_RIFF_WAVE_FORMAT_VOXWARE_VR18:
1652     case GST_RIFF_WAVE_FORMAT_VOXWARE_TQ40:
1653     case GST_RIFF_WAVE_FORMAT_VOXWARE_TQ60:{
1654       caps = gst_caps_new_simple ("audio/x-voxware",
1655           "voxwaretype", G_TYPE_INT, (gint) codec_id, NULL);
1656       if (codec_name)
1657         *codec_name = g_strdup ("Voxware");
1658       break;
1659     }
1660     default:
1661     unknown:
1662       GST_WARNING ("Unknown audio tag 0x%04x", codec_id);
1663       return NULL;
1664   }
1665
1666   if (strf != NULL) {
1667     if (rate_chan) {
1668       if (strf->channels > channels_max)
1669         goto too_many_channels;
1670       if (strf->rate < rate_min || strf->rate > rate_max)
1671         goto invalid_rate;
1672
1673       gst_caps_set_simple (caps,
1674           "rate", G_TYPE_INT, strf->rate,
1675           "channels", G_TYPE_INT, strf->channels, NULL);
1676     }
1677     if (block_align) {
1678       gst_caps_set_simple (caps,
1679           "block_align", G_TYPE_INT, strf->blockalign, NULL);
1680     }
1681   } else {
1682     if (rate_chan) {
1683       if (rate_min == rate_max)
1684         gst_caps_set_simple (caps, "rate", G_TYPE_INT, rate_min, NULL);
1685       else
1686         gst_caps_set_simple (caps,
1687             "rate", GST_TYPE_INT_RANGE, rate_min, rate_max, NULL);
1688       if (channels_max == 1)
1689         gst_caps_set_simple (caps, "channels", G_TYPE_INT, 1, NULL);
1690       else
1691         gst_caps_set_simple (caps,
1692             "channels", GST_TYPE_INT_RANGE, 1, channels_max, NULL);
1693     }
1694     if (block_align) {
1695       gst_caps_set_simple (caps,
1696           "block_align", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
1697     }
1698   }
1699
1700   /* extradata */
1701   if (strf_data || strd_data) {
1702     gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER,
1703         strf_data ? strf_data : strd_data, NULL);
1704   }
1705
1706   return caps;
1707
1708   /* ERROR */
1709 too_many_channels:
1710   GST_WARNING
1711       ("Stream claims to contain %u channels, but format only supports %d",
1712       strf->channels, channels_max);
1713   gst_caps_unref (caps);
1714   return NULL;
1715 invalid_rate:
1716   GST_WARNING
1717       ("Stream with sample_rate %u, but format only supports %d .. %d",
1718       strf->rate, rate_min, rate_max);
1719   gst_caps_unref (caps);
1720   return NULL;
1721 }
1722
1723 GstCaps *
1724 gst_riff_create_iavs_caps (guint32 codec_fcc,
1725     gst_riff_strh * strh, gst_riff_strf_iavs * strf,
1726     GstBuffer * init_data, GstBuffer * extra_data, char **codec_name)
1727 {
1728   GstCaps *caps = NULL;
1729
1730   switch (codec_fcc) {
1731       /* is this correct? */
1732     case GST_MAKE_FOURCC ('D', 'V', 'S', 'D'):
1733     case GST_MAKE_FOURCC ('d', 'v', 's', 'd'):
1734       caps = gst_caps_new_simple ("video/x-dv",
1735           "systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
1736       if (codec_name)
1737         *codec_name = g_strdup ("Generic DV");
1738       break;
1739
1740     default:
1741       GST_WARNING ("Unknown IAVS fourcc %" GST_FOURCC_FORMAT,
1742           GST_FOURCC_ARGS (codec_fcc));
1743       return NULL;
1744   }
1745
1746   return caps;
1747 }
1748
1749 /*
1750  * Functions below are for template caps. All is variable.
1751  */
1752
1753 GstCaps *
1754 gst_riff_create_video_template_caps (void)
1755 {
1756   static const guint32 tags[] = {
1757     GST_MAKE_FOURCC ('3', 'I', 'V', '1'),
1758     GST_MAKE_FOURCC ('A', 'S', 'V', '1'),
1759     GST_MAKE_FOURCC ('A', 'S', 'V', '2'),
1760     GST_MAKE_FOURCC ('C', 'L', 'J', 'R'),
1761     GST_MAKE_FOURCC ('C', 'S', 'C', 'D'),
1762     GST_MAKE_FOURCC ('C', 'Y', 'U', 'V'),
1763     GST_MAKE_FOURCC ('D', 'I', 'B', ' '),
1764     GST_MAKE_FOURCC ('D', 'I', 'V', '3'),
1765     GST_MAKE_FOURCC ('D', 'I', 'V', 'X'),
1766     GST_MAKE_FOURCC ('D', 'U', 'C', 'K'),
1767     GST_MAKE_FOURCC ('D', 'V', 'S', 'D'),
1768     GST_MAKE_FOURCC ('D', 'V', '5', '0'),
1769     GST_MAKE_FOURCC ('D', 'X', '5', '0'),
1770     GST_MAKE_FOURCC ('M', '4', 'C', 'C'),
1771     GST_MAKE_FOURCC ('F', 'L', 'V', '1'),
1772     GST_MAKE_FOURCC ('F', 'L', 'V', '4'),
1773     GST_MAKE_FOURCC ('H', '2', '6', '3'),
1774     GST_MAKE_FOURCC ('V', 'X', '1', 'K'),
1775     GST_MAKE_FOURCC ('H', '2', '6', '4'),
1776     GST_MAKE_FOURCC ('H', 'F', 'Y', 'U'),
1777     GST_MAKE_FOURCC ('I', '2', '6', '3'),
1778     GST_MAKE_FOURCC ('I', '4', '2', '0'),
1779     GST_MAKE_FOURCC ('I', 'V', '3', '2'),
1780     GST_MAKE_FOURCC ('I', 'V', '4', '1'),
1781     GST_MAKE_FOURCC ('I', 'V', '5', '0'),
1782     GST_MAKE_FOURCC ('L', '2', '6', '3'),
1783     GST_MAKE_FOURCC ('L', '2', '6', '4'),
1784     GST_MAKE_FOURCC ('M', '2', '6', '3'),
1785     GST_MAKE_FOURCC ('M', '4', 'S', '2'),
1786     GST_MAKE_FOURCC ('M', 'J', 'P', 'G'),
1787     GST_MAKE_FOURCC ('M', 'P', '4', '2'),
1788     GST_MAKE_FOURCC ('M', 'P', '4', '3'),
1789     GST_MAKE_FOURCC ('M', 'P', 'E', 'G'),
1790     GST_MAKE_FOURCC ('M', 'P', 'G', '2'),
1791     GST_MAKE_FOURCC ('M', 'P', 'G', '4'),
1792     GST_MAKE_FOURCC ('M', 'S', 'Z', 'H'),
1793     GST_MAKE_FOURCC ('P', 'N', 'G', ' '),
1794     GST_MAKE_FOURCC ('R', 'L', 'E', ' '),
1795     GST_MAKE_FOURCC ('R', 'T', '2', '1'),
1796     GST_MAKE_FOURCC ('S', 'P', '5', '3'),
1797     GST_MAKE_FOURCC ('T', 'M', '2', '0'),
1798     GST_MAKE_FOURCC ('T', 'S', 'C', 'C'),
1799     GST_MAKE_FOURCC ('U', 'L', 'T', 'I'),
1800     GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'),
1801     GST_MAKE_FOURCC ('V', 'C', 'R', '1'),
1802     GST_MAKE_FOURCC ('V', 'C', 'R', '2'),
1803     GST_MAKE_FOURCC ('V', 'D', 'O', 'W'),
1804     GST_MAKE_FOURCC ('V', 'I', 'V', 'O'),
1805     GST_MAKE_FOURCC ('V', 'M', 'n', 'c'),
1806     GST_MAKE_FOURCC ('V', 'P', '3', ' '),
1807     GST_MAKE_FOURCC ('V', 'S', 'S', 'H'),
1808     GST_MAKE_FOURCC ('W', 'M', 'V', '1'),
1809     GST_MAKE_FOURCC ('W', 'M', 'V', '2'),
1810     GST_MAKE_FOURCC ('W', 'M', 'V', '3'),
1811     GST_MAKE_FOURCC ('X', 'V', 'I', 'D'),
1812     GST_MAKE_FOURCC ('X', 'x', 'a', 'n'),
1813     GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'),
1814     GST_MAKE_FOURCC ('Y', 'V', 'U', '9'),
1815     GST_MAKE_FOURCC ('Z', 'L', 'I', 'B'),
1816     GST_MAKE_FOURCC ('c', 'v', 'i', 'd'),
1817     GST_MAKE_FOURCC ('h', '2', '6', '4'),
1818     GST_MAKE_FOURCC ('m', 's', 'v', 'c'),
1819     GST_MAKE_FOURCC ('x', '2', '6', '3'),
1820     GST_MAKE_FOURCC ('d', 'r', 'a', 'c'),
1821     GST_MAKE_FOURCC ('F', 'F', 'V', '1'),
1822     GST_MAKE_FOURCC ('K', 'M', 'V', 'C'),
1823     GST_MAKE_FOURCC ('V', 'P', '5', '0'),
1824     GST_MAKE_FOURCC ('V', 'P', '6', '0'),
1825     GST_MAKE_FOURCC ('V', 'P', '6', 'F'),
1826     GST_MAKE_FOURCC ('V', 'P', '7', '0'),
1827     GST_MAKE_FOURCC ('V', 'P', '8', '0'),
1828     GST_MAKE_FOURCC ('L', 'M', '2', '0'),
1829     GST_MAKE_FOURCC ('R', 'P', 'Z', 'A'),
1830     GST_MAKE_FOURCC ('T', 'H', 'E', 'O'),
1831     GST_MAKE_FOURCC ('F', 'P', 'S', '1'),
1832     GST_MAKE_FOURCC ('A', 'A', 'S', 'C'),
1833     GST_MAKE_FOURCC ('Y', 'V', '1', '2'),
1834     GST_MAKE_FOURCC ('L', 'O', 'C', 'O'),
1835     GST_MAKE_FOURCC ('Z', 'M', 'B', 'V'),
1836     /* FILL ME */
1837   };
1838   guint i;
1839   GstCaps *caps, *one;
1840
1841   caps = gst_caps_new_empty ();
1842   for (i = 0; i < G_N_ELEMENTS (tags); i++) {
1843     one = gst_riff_create_video_caps (tags[i], NULL, NULL, NULL, NULL, NULL);
1844     if (one)
1845       gst_caps_append (caps, one);
1846   }
1847
1848   return caps;
1849 }
1850
1851 GstCaps *
1852 gst_riff_create_audio_template_caps (void)
1853 {
1854   static const guint16 tags[] = {
1855     GST_RIFF_WAVE_FORMAT_GSM610,
1856     GST_RIFF_WAVE_FORMAT_MPEGL3,
1857     GST_RIFF_WAVE_FORMAT_MPEGL12,
1858     GST_RIFF_WAVE_FORMAT_PCM,
1859     GST_RIFF_WAVE_FORMAT_VORBIS1,
1860     GST_RIFF_WAVE_FORMAT_A52,
1861     GST_RIFF_WAVE_FORMAT_DTS,
1862     GST_RIFF_WAVE_FORMAT_AAC,
1863     GST_RIFF_WAVE_FORMAT_ALAW,
1864     GST_RIFF_WAVE_FORMAT_MULAW,
1865     GST_RIFF_WAVE_FORMAT_WMS,
1866     GST_RIFF_WAVE_FORMAT_ADPCM,
1867     GST_RIFF_WAVE_FORMAT_DVI_ADPCM,
1868     GST_RIFF_WAVE_FORMAT_DSP_TRUESPEECH,
1869     GST_RIFF_WAVE_FORMAT_WMAV1,
1870     GST_RIFF_WAVE_FORMAT_WMAV2,
1871     GST_RIFF_WAVE_FORMAT_WMAV3,
1872     GST_RIFF_WAVE_FORMAT_SONY_ATRAC3,
1873     GST_RIFF_WAVE_FORMAT_IEEE_FLOAT,
1874     GST_RIFF_WAVE_FORMAT_VOXWARE_METASOUND,
1875     GST_RIFF_WAVE_FORMAT_ADPCM_IMA_DK4,
1876     GST_RIFF_WAVE_FORMAT_ADPCM_IMA_DK3,
1877     GST_RIFF_WAVE_FORMAT_ADPCM_IMA_WAV,
1878     GST_RIFF_WAVE_FORMAT_AMR_NB,
1879     GST_RIFF_WAVE_FORMAT_AMR_WB,
1880     GST_RIFF_WAVE_FORMAT_SIREN,
1881     /* FILL ME */
1882   };
1883   guint i;
1884   GstCaps *caps, *one;
1885
1886   caps = gst_caps_new_empty ();
1887   for (i = 0; i < G_N_ELEMENTS (tags); i++) {
1888     one = gst_riff_create_audio_caps (tags[i], NULL, NULL, NULL, NULL, NULL);
1889     if (one)
1890       gst_caps_append (caps, one);
1891   }
1892   one = gst_caps_new_empty_simple ("application/x-ogg-avi");
1893   gst_caps_append (caps, one);
1894
1895   return caps;
1896 }
1897
1898 GstCaps *
1899 gst_riff_create_iavs_template_caps (void)
1900 {
1901   static const guint32 tags[] = {
1902     GST_MAKE_FOURCC ('D', 'V', 'S', 'D')
1903         /* FILL ME */
1904   };
1905   guint i;
1906   GstCaps *caps, *one;
1907
1908   caps = gst_caps_new_empty ();
1909   for (i = 0; i < G_N_ELEMENTS (tags); i++) {
1910     one = gst_riff_create_iavs_caps (tags[i], NULL, NULL, NULL, NULL, NULL);
1911     if (one)
1912       gst_caps_append (caps, one);
1913   }
1914
1915   return caps;
1916 }