2 * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
4 * riff-media.h: RIFF-id to/from caps routines
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.
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.
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.
27 #include "riff-media.h"
29 #include <gst/audio/multichannel.h>
33 GST_DEBUG_CATEGORY_EXTERN (riff_debug);
34 #define GST_CAT_DEFAULT riff_debug
37 * gst_riff_create_video_caps_with_data:
38 * @codec_fcc: fourCC codec for this codec.
39 * @strh: pointer to the strh stream header structure.
40 * @strf: pointer to the strf stream header structure, including any
41 * data that is within the range of strf.size, but excluding any
42 * additional data withint this chunk but outside strf.size.
43 * @strf_data: a #GstBuffer containing the additional data in the strf
44 * chunk outside reach of strf.size. Ususally a palette.
45 * @strd_data: a #GstBuffer containing the data in the strd stream header
46 * chunk. Usually codec initialization data.
47 * @codec_name: if given, will be filled with a human-readable codec name.
51 gst_riff_create_video_caps (guint32 codec_fcc,
52 gst_riff_strh * strh, gst_riff_strf_vids * strf,
53 GstBuffer * strf_data, GstBuffer * strd_data, char **codec_name)
56 GstBuffer *palette = NULL;
59 case GST_MAKE_FOURCC ('D', 'I', 'B', ' '):{
60 gint bpp = (strf && strf->bit_cnt != 0) ? strf->bit_cnt : 8;
64 caps = gst_caps_new_simple ("video/x-raw-rgb",
65 "bpp", G_TYPE_INT, 8, "depth", G_TYPE_INT, 8,
66 "endianness", G_TYPE_INT, G_BYTE_ORDER, NULL);
67 } else if (bpp == 24) {
68 caps = gst_caps_new_simple ("video/x-raw-rgb",
69 "bpp", G_TYPE_INT, 24, "depth", G_TYPE_INT, 24,
70 "endianness", G_TYPE_INT, G_BIG_ENDIAN,
71 "red_mask", G_TYPE_INT, 0xff, "green_mask", G_TYPE_INT, 0xff00,
72 "blue_mask", G_TYPE_INT, 0xff0000, NULL);
74 GST_WARNING ("Unhandled DIB RGB depth: %d", bpp);
78 caps = gst_caps_from_string ("video/x-raw-rgb, bpp = (int) { 8, 24 }, "
79 "depth = (int) { 8, 24}");
85 *codec_name = g_strdup_printf ("Palettized %d-bit RGB", bpp);
88 case GST_MAKE_FOURCC ('I', '4', '2', '0'):
89 caps = gst_caps_new_simple ("video/x-raw-yuv",
90 "format", GST_TYPE_FOURCC, codec_fcc, NULL);
92 *codec_name = g_strdup ("Uncompressed planar YUV 4:2:0");
95 case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
96 caps = gst_caps_new_simple ("video/x-raw-yuv",
97 "format", GST_TYPE_FOURCC, codec_fcc, NULL);
99 *codec_name = g_strdup ("Uncompressed packed YUV 4:2:2");
102 case GST_MAKE_FOURCC ('M', 'J', 'P', 'G'): /* YUY2 MJPEG */
103 case GST_MAKE_FOURCC ('A', 'V', 'R', 'n'):
104 case GST_MAKE_FOURCC ('I', 'J', 'P', 'G'):
105 case GST_MAKE_FOURCC ('i', 'j', 'p', 'g'):
106 case GST_MAKE_FOURCC ('J', 'P', 'G', 'L'):
107 caps = gst_caps_new_simple ("image/jpeg", NULL);
109 *codec_name = g_strdup ("Motion JPEG");
112 case GST_MAKE_FOURCC ('J', 'P', 'E', 'G'): /* generic (mostly RGB) MJPEG */
113 caps = gst_caps_new_simple ("image/jpeg", NULL);
115 *codec_name = g_strdup ("JPEG Still Image");
118 case GST_MAKE_FOURCC ('P', 'I', 'X', 'L'): /* Miro/Pinnacle fourccs */
119 case GST_MAKE_FOURCC ('V', 'I', 'X', 'L'): /* Miro/Pinnacle fourccs */
120 caps = gst_caps_new_simple ("image/jpeg", NULL);
122 *codec_name = g_strdup ("Miro/Pinnacle Motion JPEG Video");
125 case GST_MAKE_FOURCC ('S', 'P', '5', '3'):
126 case GST_MAKE_FOURCC ('S', 'P', '5', '4'):
127 case GST_MAKE_FOURCC ('S', 'P', '5', '5'):
128 case GST_MAKE_FOURCC ('S', 'P', '5', '6'):
129 case GST_MAKE_FOURCC ('S', 'P', '5', '7'):
130 case GST_MAKE_FOURCC ('S', 'P', '5', '8'):
131 caps = gst_caps_new_simple ("video/sp5x", NULL);
133 *codec_name = g_strdup ("Sp5x-like JPEG");
136 case GST_MAKE_FOURCC ('H', 'F', 'Y', 'U'):
137 caps = gst_caps_new_simple ("video/x-huffyuv", NULL);
139 gst_caps_set_simple (caps, "bpp",
140 G_TYPE_INT, (int) strf->bit_cnt, NULL);
143 *codec_name = g_strdup ("Huffman Lossless Codec");
146 case GST_MAKE_FOURCC ('M', 'P', 'E', 'G'):
147 case GST_MAKE_FOURCC ('M', 'P', 'G', 'I'):
148 case GST_MAKE_FOURCC ('m', 'p', 'g', '1'):
149 case GST_MAKE_FOURCC ('M', 'P', 'G', '1'):
150 case GST_MAKE_FOURCC ('P', 'I', 'M', '1'):
151 caps = gst_caps_new_simple ("video/mpeg",
152 "systemstream", G_TYPE_BOOLEAN, FALSE,
153 "mpegversion", G_TYPE_INT, 1, NULL);
155 *codec_name = g_strdup ("MPEG-1 video");
157 case GST_MAKE_FOURCC ('M', 'P', 'G', '2'):
158 case GST_MAKE_FOURCC ('m', 'p', 'g', '2'):
159 caps = gst_caps_new_simple ("video/mpeg",
160 "systemstream", G_TYPE_BOOLEAN, FALSE,
161 "mpegversion", G_TYPE_INT, 2, NULL);
163 *codec_name = g_strdup ("MPEG-2 video");
166 case GST_MAKE_FOURCC ('H', '2', '6', '3'):
167 case GST_MAKE_FOURCC ('h', '2', '6', '3'):
168 case GST_MAKE_FOURCC ('i', '2', '6', '3'):
169 case GST_MAKE_FOURCC ('U', '2', '6', '3'):
170 caps = gst_caps_new_simple ("video/x-h263", NULL);
172 *codec_name = g_strdup ("ITU H.26n");
175 case GST_MAKE_FOURCC ('L', '2', '6', '3'):
176 caps = gst_caps_new_simple ("video/x-h263", NULL);
178 *codec_name = g_strdup ("Lead H.263");
181 case GST_MAKE_FOURCC ('M', '2', '6', '3'):
182 case GST_MAKE_FOURCC ('m', '2', '6', '3'):
183 caps = gst_caps_new_simple ("video/x-h263", NULL);
185 *codec_name = g_strdup ("Microsoft H.263");
188 case GST_MAKE_FOURCC ('V', 'D', 'O', 'W'):
189 caps = gst_caps_new_simple ("video/x-h263", NULL);
191 *codec_name = g_strdup ("VDOLive");
194 case GST_MAKE_FOURCC ('V', 'I', 'V', 'O'):
195 caps = gst_caps_new_simple ("video/x-h263", NULL);
197 *codec_name = g_strdup ("Vivo H.263");
200 case GST_MAKE_FOURCC ('x', '2', '6', '3'):
201 caps = gst_caps_new_simple ("video/x-h263", NULL);
203 *codec_name = g_strdup ("Xirlink H.263");
206 /* apparently not standard H.263...? */
207 case GST_MAKE_FOURCC ('I', '2', '6', '3'):
208 caps = gst_caps_new_simple ("video/x-intel-h263", NULL);
210 *codec_name = g_strdup ("Intel H.263");
213 case GST_MAKE_FOURCC ('h', '2', '6', '4'):
214 caps = gst_caps_new_simple ("video/x-h264", NULL);
216 *codec_name = g_strdup ("ITU H.264");
219 case GST_MAKE_FOURCC ('V', 'S', 'S', 'H'):
220 caps = gst_caps_new_simple ("video/x-h264", NULL);
222 *codec_name = g_strdup ("VideoSoft H.264");
225 case GST_MAKE_FOURCC ('D', 'I', 'V', '3'):
226 case GST_MAKE_FOURCC ('d', 'i', 'v', '3'):
227 case GST_MAKE_FOURCC ('D', 'I', 'V', '4'):
228 case GST_MAKE_FOURCC ('d', 'i', 'v', '4'):
229 case GST_MAKE_FOURCC ('D', 'I', 'V', '5'):
230 case GST_MAKE_FOURCC ('d', 'i', 'v', '5'):
231 case GST_MAKE_FOURCC ('D', 'I', 'V', '6'):
232 case GST_MAKE_FOURCC ('d', 'i', 'v', '6'):
233 case GST_MAKE_FOURCC ('M', 'P', 'G', '3'):
234 case GST_MAKE_FOURCC ('m', 'p', 'g', '3'):
235 case GST_MAKE_FOURCC ('c', 'o', 'l', '0'):
236 case GST_MAKE_FOURCC ('C', 'O', 'L', '0'):
237 case GST_MAKE_FOURCC ('c', 'o', 'l', '1'):
238 case GST_MAKE_FOURCC ('C', 'O', 'L', '1'):
239 case GST_MAKE_FOURCC ('A', 'P', '4', '1'):
240 caps = gst_caps_new_simple ("video/x-divx",
241 "divxversion", G_TYPE_INT, 3, NULL);
243 *codec_name = g_strdup ("DivX MS-MPEG-4 Version 3");
246 case GST_MAKE_FOURCC ('d', 'i', 'v', 'x'):
247 case GST_MAKE_FOURCC ('D', 'I', 'V', 'X'):
248 caps = gst_caps_new_simple ("video/x-divx",
249 "divxversion", G_TYPE_INT, 4, NULL);
251 *codec_name = g_strdup ("DivX MPEG-4 Version 4");
254 case GST_MAKE_FOURCC ('B', 'L', 'Z', '0'):
255 caps = gst_caps_new_simple ("video/x-divx",
256 "divxversion", G_TYPE_INT, 4, NULL);
258 *codec_name = g_strdup ("Blizzard DivX");
261 case GST_MAKE_FOURCC ('D', 'X', '5', '0'):
262 caps = gst_caps_new_simple ("video/x-divx",
263 "divxversion", G_TYPE_INT, 5, NULL);
265 *codec_name = g_strdup ("DivX MPEG-4 Version 5");
268 case GST_MAKE_FOURCC ('X', 'V', 'I', 'D'):
269 case GST_MAKE_FOURCC ('x', 'v', 'i', 'd'):
270 caps = gst_caps_new_simple ("video/x-xvid", NULL);
272 *codec_name = g_strdup ("XVID MPEG-4");
275 case GST_MAKE_FOURCC ('M', 'P', 'G', '4'):
276 case GST_MAKE_FOURCC ('M', 'P', '4', 'S'):
277 caps = gst_caps_new_simple ("video/x-msmpeg",
278 "msmpegversion", G_TYPE_INT, 41, NULL);
280 *codec_name = g_strdup ("Microsoft MPEG-4 4.1");
283 case GST_MAKE_FOURCC ('m', 'p', '4', '2'):
284 case GST_MAKE_FOURCC ('M', 'P', '4', '2'):
285 caps = gst_caps_new_simple ("video/x-msmpeg",
286 "msmpegversion", G_TYPE_INT, 42, NULL);
288 *codec_name = g_strdup ("Microsoft MPEG-4 4.2");
291 case GST_MAKE_FOURCC ('m', 'p', '4', '3'):
292 case GST_MAKE_FOURCC ('M', 'P', '4', '3'):
293 caps = gst_caps_new_simple ("video/x-msmpeg",
294 "msmpegversion", G_TYPE_INT, 43, NULL);
296 *codec_name = g_strdup ("Microsoft MPEG-4 4.3");
299 case GST_MAKE_FOURCC ('M', '4', 'S', '2'):
300 caps = gst_caps_new_simple ("video/mpeg",
301 "mpegversion", G_TYPE_INT, 4, NULL);
303 *codec_name = g_strdup ("Microsoft ISO MPEG-4 1.1");
306 case GST_MAKE_FOURCC ('F', 'M', 'P', '4'):
307 case GST_MAKE_FOURCC ('U', 'M', 'P', '4'):
308 caps = gst_caps_new_simple ("video/mpeg",
309 "mpegversion", G_TYPE_INT, 4, NULL);
311 *codec_name = g_strdup ("FFmpeg MPEG-4");
314 case GST_MAKE_FOURCC ('3', 'i', 'v', 'd'):
315 case GST_MAKE_FOURCC ('3', 'I', 'V', 'D'):
317 *codec_name = g_strdup ("Microsoft MPEG-4 4.3"); /* FIXME? */
318 return gst_caps_from_string ("video/x-msmpeg, msmpegversion = (int) 43");
320 case GST_MAKE_FOURCC ('3', 'I', 'V', '1'):
321 case GST_MAKE_FOURCC ('3', 'I', 'V', '2'):
322 caps = gst_caps_new_simple ("video/x-3ivx", NULL);
324 *codec_name = g_strdup ("3ivx");
327 case GST_MAKE_FOURCC ('D', 'V', 'S', 'D'):
328 case GST_MAKE_FOURCC ('d', 'v', 's', 'd'):
329 case GST_MAKE_FOURCC ('C', 'D', 'V', 'C'):
330 caps = gst_caps_new_simple ("video/x-dv",
331 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
333 *codec_name = g_strdup ("Generic DV");
336 case GST_MAKE_FOURCC ('W', 'M', 'V', '1'):
337 caps = gst_caps_new_simple ("video/x-wmv",
338 "wmvversion", G_TYPE_INT, 1, NULL);
340 *codec_name = g_strdup ("Microsoft Windows Media 7");
343 case GST_MAKE_FOURCC ('W', 'M', 'V', '2'):
344 caps = gst_caps_new_simple ("video/x-wmv",
345 "wmvversion", G_TYPE_INT, 2, NULL);
347 *codec_name = g_strdup ("Microsoft Windows Media 8");
350 case GST_MAKE_FOURCC ('W', 'M', 'V', '3'):
351 caps = gst_caps_new_simple ("video/x-wmv",
352 "wmvversion", G_TYPE_INT, 3, NULL);
354 *codec_name = g_strdup ("Microsoft Windows Media 9");
357 case GST_MAKE_FOURCC ('c', 'v', 'i', 'd'):
358 caps = gst_caps_new_simple ("video/x-cinepak", NULL);
360 *codec_name = g_strdup ("Cinepak video");
363 case GST_MAKE_FOURCC ('M', 'S', 'V', 'C'):
364 case GST_MAKE_FOURCC ('m', 's', 'v', 'c'):
365 case GST_MAKE_FOURCC ('C', 'R', 'A', 'M'):
366 case GST_MAKE_FOURCC ('c', 'r', 'a', 'm'):
367 case GST_MAKE_FOURCC ('W', 'H', 'A', 'M'):
368 case GST_MAKE_FOURCC ('w', 'h', 'a', 'm'):
369 caps = gst_caps_new_simple ("video/x-msvideocodec",
370 "msvideoversion", G_TYPE_INT, 1, NULL);
372 *codec_name = g_strdup ("MS video v1");
377 case GST_MAKE_FOURCC ('R', 'L', 'E', ' '):
378 case GST_MAKE_FOURCC ('m', 'r', 'l', 'e'):
379 case GST_MAKE_FOURCC (0x1, 0x0, 0x0, 0x0): /* why, why, why? */
380 caps = gst_caps_new_simple ("video/x-rle",
381 "layout", G_TYPE_STRING, "microsoft", NULL);
385 gst_caps_set_simple (caps,
386 "depth", G_TYPE_INT, (gint) strf->bit_cnt, NULL);
388 gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 1, 64, NULL);
391 *codec_name = g_strdup ("Microsoft RLE");
394 case GST_MAKE_FOURCC ('X', 'x', 'a', 'n'):
395 caps = gst_caps_new_simple ("video/x-xan",
396 "wcversion", G_TYPE_INT, 4, NULL);
398 *codec_name = g_strdup ("Xan Wing Commander 4");
401 case GST_MAKE_FOURCC ('R', 'T', '2', '1'):
402 caps = gst_caps_new_simple ("video/x-indeo",
403 "indeoversion", G_TYPE_INT, 2, NULL);
405 *codec_name = g_strdup ("Intel Video 2");
408 case GST_MAKE_FOURCC ('I', 'V', '3', '1'):
409 case GST_MAKE_FOURCC ('I', 'V', '3', '2'):
410 case GST_MAKE_FOURCC ('i', 'v', '3', '1'):
411 case GST_MAKE_FOURCC ('i', 'v', '3', '2'):
412 caps = gst_caps_new_simple ("video/x-indeo",
413 "indeoversion", G_TYPE_INT, 3, NULL);
415 *codec_name = g_strdup ("Intel Video 3");
418 case GST_MAKE_FOURCC ('I', 'V', '4', '1'):
419 case GST_MAKE_FOURCC ('i', 'v', '4', '1'):
420 caps = gst_caps_new_simple ("video/x-indeo",
421 "indeoversion", G_TYPE_INT, 4, NULL);
423 *codec_name = g_strdup ("Intel Video 4");
426 case GST_MAKE_FOURCC ('I', 'V', '5', '0'):
427 caps = gst_caps_new_simple ("video/x-indeo",
428 "indeoversion", G_TYPE_INT, 5, NULL);
430 *codec_name = g_strdup ("Intel Video 5");
433 case GST_MAKE_FOURCC ('M', 'S', 'Z', 'H'):
434 caps = gst_caps_new_simple ("video/x-mszh", NULL);
436 *codec_name = g_strdup ("Lossless MSZH Video");
439 case GST_MAKE_FOURCC ('Z', 'L', 'I', 'B'):
440 caps = gst_caps_new_simple ("video/x-zlib", NULL);
442 *codec_name = g_strdup ("Lossless zlib video");
445 case GST_MAKE_FOURCC ('C', 'L', 'J', 'R'):
446 caps = gst_caps_new_simple ("video/x-cirrus-logic-accupak", NULL);
448 *codec_name = g_strdup ("Cirrus Logipak AccuPak");
451 case GST_MAKE_FOURCC ('C', 'Y', 'U', 'V'):
452 case GST_MAKE_FOURCC ('c', 'y', 'u', 'v'):
453 caps = gst_caps_new_simple ("video/x-compressed-yuv", NULL);
455 *codec_name = g_strdup ("CYUV Lossless");
458 case GST_MAKE_FOURCC ('D', 'U', 'C', 'K'):
459 caps = gst_caps_new_simple ("video/x-truemotion",
460 "trueversion", G_TYPE_INT, 1, NULL);
462 *codec_name = g_strdup ("Duck Truemotion1");
465 case GST_MAKE_FOURCC ('T', 'M', '2', '0'):
466 caps = gst_caps_new_simple ("video/x-truemotion",
467 "trueversion", G_TYPE_INT, 2, NULL);
469 *codec_name = g_strdup ("TrueMotion 2.0");
472 case GST_MAKE_FOURCC ('V', 'P', '3', '0'):
473 case GST_MAKE_FOURCC ('v', 'p', '3', '0'):
474 case GST_MAKE_FOURCC ('V', 'P', '3', '1'):
475 case GST_MAKE_FOURCC ('v', 'p', '3', '1'):
476 case GST_MAKE_FOURCC ('V', 'P', '3', ' '):
477 caps = gst_caps_new_simple ("video/x-vp3", NULL);
479 *codec_name = g_strdup ("VP3");
482 case GST_MAKE_FOURCC ('U', 'L', 'T', 'I'):
483 caps = gst_caps_new_simple ("video/x-ultimotion", NULL);
485 *codec_name = g_strdup ("IBM UltiMotion");
488 case GST_MAKE_FOURCC ('T', 'S', 'C', 'C'):
489 case GST_MAKE_FOURCC ('t', 's', 'c', 'c'):
490 caps = gst_caps_new_simple ("video/x-camtasia", NULL);
492 *codec_name = g_strdup ("TechSmith Camtasia");
495 case GST_MAKE_FOURCC ('V', 'C', 'R', '1'):
496 caps = gst_caps_new_simple ("video/x-ati-vcr",
497 "vcrversion", G_TYPE_INT, 1, NULL);
499 *codec_name = g_strdup ("ATI VCR 1");
502 case GST_MAKE_FOURCC ('V', 'C', 'R', '2'):
503 caps = gst_caps_new_simple ("video/x-ati-vcr",
504 "vcrversion", G_TYPE_INT, 2, NULL);
506 *codec_name = g_strdup ("ATI VCR 2");
509 case GST_MAKE_FOURCC ('A', 'S', 'V', '1'):
510 caps = gst_caps_new_simple ("video/x-asus",
511 "asusversion", G_TYPE_INT, 1, NULL);
513 *codec_name = g_strdup ("Asus Video 1");
516 case GST_MAKE_FOURCC ('A', 'S', 'V', '2'):
517 caps = gst_caps_new_simple ("video/x-asus",
518 "asusversion", G_TYPE_INT, 2, NULL);
520 *codec_name = g_strdup ("Asus Video 2");
523 case GST_MAKE_FOURCC ('M', 'P', 'N', 'G'):
524 case GST_MAKE_FOURCC ('m', 'p', 'n', 'g'):
525 case GST_MAKE_FOURCC ('P', 'N', 'G', ' '):
526 caps = gst_caps_new_simple ("image/png", NULL);
528 *codec_name = g_strdup ("PNG image");
531 case GST_MAKE_FOURCC ('F', 'L', 'V', '1'):
532 caps = gst_caps_new_simple ("video/x-flash-video",
533 "flvversion", G_TYPE_INT, 1, NULL);
535 *codec_name = g_strdup ("Flash Video 1");
539 GST_WARNING ("Unknown video fourcc %" GST_FOURCC_FORMAT,
540 GST_FOURCC_ARGS (codec_fcc));
545 gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION,
546 strh->rate, strh->scale, NULL);
548 gst_caps_set_simple (caps,
549 "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
553 gst_caps_set_simple (caps,
554 "width", G_TYPE_INT, strf->width,
555 "height", G_TYPE_INT, strf->height, NULL);
557 gst_caps_set_simple (caps,
558 "width", GST_TYPE_INT_RANGE, 16, 4096,
559 "height", GST_TYPE_INT_RANGE, 16, 4096, NULL);
563 if (strf_data || strd_data) {
564 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER,
565 strf_data ? strf_data : strd_data, NULL);
574 num_colors = strf->num_colors;
578 if (GST_BUFFER_SIZE (palette) >= (num_colors * 4)) {
579 /* palette is always at least 256*4 bytes */
581 gst_buffer_new_and_alloc (MAX (GST_BUFFER_SIZE (palette), 256 * 4));
582 memcpy (GST_BUFFER_DATA (copy), GST_BUFFER_DATA (palette),
583 GST_BUFFER_SIZE (palette));
585 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
587 guint32 *data = (guint32 *) GST_BUFFER_DATA (copy);
590 for (n = 0; n < num_colors; n++)
591 data[n] = GUINT32_FROM_LE (data[n]);
593 gst_caps_set_simple (caps, "palette_data", GST_TYPE_BUFFER, copy, NULL);
594 gst_buffer_unref (copy);
596 GST_WARNING ("Palette smaller than expected: broken file");
605 const guint32 ms_mask;
606 const GstAudioChannelPosition gst_pos;
607 } layout_mapping[] = {
609 0x00001, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT}, {
610 0x00002, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}, {
611 0x00004, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER}, {
612 0x00008, GST_AUDIO_CHANNEL_POSITION_LFE}, {
613 0x00010, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT}, {
614 0x00020, GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}, {
615 0x00040, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER}, {
616 0x00080, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER}, {
617 0x00100, GST_AUDIO_CHANNEL_POSITION_REAR_CENTER}, {
618 0x00200, GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT}, {
619 0x00400, GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT}, {
620 0x00800, GST_AUDIO_CHANNEL_POSITION_INVALID}, /* TOP_CENTER */
622 0x01000, GST_AUDIO_CHANNEL_POSITION_INVALID}, /* TOP_FRONT_LEFT */
624 0x02000, GST_AUDIO_CHANNEL_POSITION_INVALID}, /* TOP_FRONT_CENTER */
626 0x04000, GST_AUDIO_CHANNEL_POSITION_INVALID}, /* TOP_FRONT_RIGHT */
628 0x08000, GST_AUDIO_CHANNEL_POSITION_INVALID}, /* TOP_BACK_LEFT */
630 0x10000, GST_AUDIO_CHANNEL_POSITION_INVALID}, /* TOP_BACK_CENTER */
632 0x20000, GST_AUDIO_CHANNEL_POSITION_INVALID} /* TOP_BACK_RIGHT */
635 #define MAX_CHANNEL_POSITIONS G_N_ELEMENTS (layout_mapping)
638 gst_riff_wavext_add_channel_layout (GstCaps * caps, guint32 layout)
640 GstAudioChannelPosition pos[MAX_CHANNEL_POSITIONS];
642 gint num_channels, i, p;
644 s = gst_caps_get_structure (caps, 0);
645 if (!gst_structure_get_int (s, "channels", &num_channels))
646 g_return_val_if_reached (FALSE);
648 if (num_channels < 2 || num_channels > MAX_CHANNEL_POSITIONS) {
649 GST_DEBUG ("invalid number of channels: %d", num_channels);
654 for (i = 0; i < MAX_CHANNEL_POSITIONS; ++i) {
655 if ((layout & layout_mapping[i].ms_mask) != 0) {
656 if (p >= num_channels) {
657 GST_WARNING ("More bits set in the channel layout map than there "
658 "are channels! Broken file");
661 if (layout_mapping[i].gst_pos == GST_AUDIO_CHANNEL_POSITION_INVALID) {
662 GST_WARNING ("Unsupported channel position (mask 0x%08x) in channel "
663 "layout map - ignoring those channels", layout_mapping[i].ms_mask);
664 /* what to do? just ignore it and let downstream deal with a channel
665 * layout that has INVALID positions in it for now ... */
667 pos[p] = layout_mapping[i].gst_pos;
672 if (p != num_channels) {
673 GST_WARNING ("Only %d bits set in the channel layout map, but there are "
674 "supposed to be %d channels! Broken file", p, num_channels);
678 gst_audio_set_channel_positions (s, pos);
683 gst_riff_create_audio_caps (guint16 codec_id,
684 gst_riff_strh * strh, gst_riff_strf_auds * strf,
685 GstBuffer * strf_data, GstBuffer * strd_data, char **codec_name)
687 gboolean block_align = FALSE, rate_chan = TRUE;
688 GstCaps *caps = NULL;
689 gint rate_min = 1000, rate_max = 96000;
690 gint channels_max = 2;
693 case GST_RIFF_WAVE_FORMAT_MPEGL3: /* mp3 */
694 caps = gst_caps_new_simple ("audio/mpeg",
695 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 3, NULL);
697 *codec_name = g_strdup ("MPEG-1 layer 3");
700 case GST_RIFF_WAVE_FORMAT_MPEGL12: /* mp1 or mp2 */
701 caps = gst_caps_new_simple ("audio/mpeg",
702 "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 2, NULL);
704 *codec_name = g_strdup ("MPEG-1 layer 2");
707 case GST_RIFF_WAVE_FORMAT_PCM: /* PCM */
709 gint ba = strf->blockalign;
710 gint ch = strf->channels;
711 gint ws = strf->size;
713 caps = gst_caps_new_simple ("audio/x-raw-int", "endianness", G_TYPE_INT, G_LITTLE_ENDIAN, "channels", G_TYPE_INT, ch, /* needed for _add_layout() */
714 "width", G_TYPE_INT, (int) (ba * 8 / ch),
715 "depth", G_TYPE_INT, ws, "signed", G_TYPE_BOOLEAN, ws != 8, NULL);
717 /* Add default MS channel layout if we have more than 2 channels,
718 * but the layout isn't specified like with WAVEEXT below. Not sure
719 * if this is right, but at least it makes sound output work at all
720 * in those cases. Somebody with a a 5.1 setup should double-check
721 * with chan-id.wav */
723 guint32 channel_mask;
733 GST_WARNING ("don't know default layout for %d channels", ch);
739 GST_DEBUG ("using default channel layout for %d channels", ch);
740 if (!gst_riff_wavext_add_channel_layout (caps, channel_mask)) {
741 GST_WARNING ("failed to add channel layout");
746 /* FIXME: this is pretty useless - we need fixed caps */
747 caps = gst_caps_from_string ("audio/x-raw-int, "
748 "endianness = (int) LITTLE_ENDIAN, "
749 "signed = (boolean) { true, false }, "
750 "width = (int) { 8, 16, 24, 32 }, "
751 "depth = (int) { 8, 16, 24, 32 }");
753 if (codec_name && strf)
754 *codec_name = g_strdup_printf ("Uncompressed %d-bit PCM audio",
758 case GST_RIFF_WAVE_FORMAT_ADPCM:
759 caps = gst_caps_new_simple ("audio/x-adpcm",
760 "layout", G_TYPE_STRING, "microsoft", NULL);
762 *codec_name = g_strdup ("ADPCM audio");
766 case GST_RIFF_WAVE_FORMAT_DVI_ADPCM:
767 caps = gst_caps_new_simple ("audio/x-adpcm",
768 "layout", G_TYPE_STRING, "dvi", NULL);
770 *codec_name = g_strdup ("DVI ADPCM audio");
774 case GST_RIFF_WAVE_FORMAT_MULAW:
775 if (strf != NULL && strf->size != 8) {
776 GST_WARNING ("invalid depth (%d) of mulaw audio, overwriting.",
780 strf->blockalign = strf->av_bps * strf->channels;
782 if (strf != NULL && (strf->av_bps == 0 || strf->blockalign == 0)) {
783 GST_WARNING ("fixing av_bps (%d) and blockalign (%d) of mulaw audio",
784 strf->av_bps, strf->blockalign);
785 strf->av_bps = strf->size;
786 strf->blockalign = strf->av_bps * strf->channels;
788 caps = gst_caps_new_simple ("audio/x-mulaw", NULL);
790 *codec_name = g_strdup ("Mu-law audio");
793 case GST_RIFF_WAVE_FORMAT_ALAW:
794 if (strf != NULL && strf->size != 8) {
795 GST_WARNING ("invalid depth (%d) of alaw audio, overwriting.",
799 strf->blockalign = strf->av_bps * strf->channels;
801 if (strf != NULL && (strf->av_bps == 0 || strf->blockalign == 0)) {
802 GST_WARNING ("fixing av_bps (%d) and blockalign (%d) of alaw audio",
803 strf->av_bps, strf->blockalign);
804 strf->av_bps = strf->size;
805 strf->blockalign = strf->av_bps * strf->channels;
807 caps = gst_caps_new_simple ("audio/x-alaw", NULL);
809 *codec_name = g_strdup ("A-law audio");
812 case GST_RIFF_WAVE_FORMAT_VORBIS1: /* ogg/vorbis mode 1 */
813 case GST_RIFF_WAVE_FORMAT_VORBIS2: /* ogg/vorbis mode 2 */
814 case GST_RIFF_WAVE_FORMAT_VORBIS3: /* ogg/vorbis mode 3 */
815 case GST_RIFF_WAVE_FORMAT_VORBIS1PLUS: /* ogg/vorbis mode 1+ */
816 case GST_RIFF_WAVE_FORMAT_VORBIS2PLUS: /* ogg/vorbis mode 2+ */
817 case GST_RIFF_WAVE_FORMAT_VORBIS3PLUS: /* ogg/vorbis mode 3+ */
818 caps = gst_caps_new_simple ("audio/x-vorbis", NULL);
820 *codec_name = g_strdup ("Vorbis");
823 case GST_RIFF_WAVE_FORMAT_A52:
825 caps = gst_caps_new_simple ("audio/x-ac3", NULL);
827 *codec_name = g_strdup ("AC-3 audio");
829 case GST_RIFF_WAVE_FORMAT_WMAV1:
830 case GST_RIFF_WAVE_FORMAT_WMAV2:
831 case GST_RIFF_WAVE_FORMAT_WMAV3:
833 gint version = (codec_id - GST_RIFF_WAVE_FORMAT_WMAV1) + 1;
839 caps = gst_caps_new_simple ("audio/x-wma",
840 "wmaversion", G_TYPE_INT, version, NULL);
843 *codec_name = g_strdup_printf ("WMA Version %d", version + 6);
846 gst_caps_set_simple (caps,
847 "bitrate", G_TYPE_INT, strf->av_bps * 8,
848 "depth", G_TYPE_INT, strf->size, NULL);
850 gst_caps_set_simple (caps,
851 "bitrate", GST_TYPE_INT_RANGE, 0, G_MAXINT, NULL);
855 case GST_RIFF_WAVE_FORMAT_SONY_ATRAC3:
856 caps = gst_caps_new_simple ("audio/x-vnd.sony.atrac3", NULL);
858 *codec_name = g_strdup ("Sony ATRAC3");
861 case GST_RIFF_WAVE_FORMAT_EXTENSIBLE:{
862 guint16 valid_bits_per_sample;
863 guint32 channel_mask;
864 guint32 subformat_guid[4];
867 if (GST_BUFFER_SIZE (strf_data) != 22) {
868 GST_WARNING ("WAVE_FORMAT_EXTENSIBLE data size is %d (expected: 22)",
869 GST_BUFFER_SIZE (strf_data));
873 data = GST_BUFFER_DATA (strf_data);
874 valid_bits_per_sample = GST_READ_UINT16_LE (data);
875 channel_mask = GST_READ_UINT32_LE (data + 2);
876 subformat_guid[0] = GST_READ_UINT32_LE (data + 6);
877 subformat_guid[1] = GST_READ_UINT32_LE (data + 10);
878 subformat_guid[2] = GST_READ_UINT32_LE (data + 14);
879 subformat_guid[3] = GST_READ_UINT32_LE (data + 18);
881 GST_DEBUG ("valid bps = %u", valid_bits_per_sample);
882 GST_DEBUG ("channel mask = 0x%08x", channel_mask);
883 GST_DEBUG ("GUID = %08x-%08x-%08x-%08x", subformat_guid[0],
884 subformat_guid[1], subformat_guid[2], subformat_guid[3]);
886 if (subformat_guid[1] == 0x00100000 &&
887 subformat_guid[2] == 0xaa000080 && subformat_guid[3] == 0x719b3800) {
888 if (subformat_guid[0] == 0x00000001) {
891 gint ba = strf->blockalign;
892 gint ws = strf->size;
895 if (valid_bits_per_sample != 0)
896 depth = valid_bits_per_sample;
898 caps = gst_caps_new_simple ("audio/x-raw-int",
899 "endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
900 "channels", G_TYPE_INT, strf->channels,
901 "width", G_TYPE_INT, (int) (ba * 8 / strf->channels),
902 "depth", G_TYPE_INT, depth,
903 "rate", G_TYPE_INT, strf->rate,
904 "signed", G_TYPE_BOOLEAN, (depth > 8) ? TRUE : FALSE, NULL);
906 if (!gst_riff_wavext_add_channel_layout (caps, channel_mask)) {
907 GST_WARNING ("failed to add channel layout");
908 gst_caps_unref (caps);
914 *codec_name = g_strdup_printf ("Uncompressed %d-bit PCM audio",
918 } else if (subformat_guid[0] == 0x00000003) {
919 GST_DEBUG ("FIXME: handle IEEE float format");
923 GST_WARNING ("Unknown WAVE_FORMAT_EXTENSIBLE audio format");
930 GST_WARNING ("Unknown audio tag 0x%04x", codec_id);
936 gst_caps_set_simple (caps,
937 "rate", G_TYPE_INT, strf->rate,
938 "channels", G_TYPE_INT, strf->channels, NULL);
941 gst_caps_set_simple (caps,
942 "block_align", G_TYPE_INT, strf->blockalign, NULL);
946 gst_caps_set_simple (caps,
947 "rate", GST_TYPE_INT_RANGE, rate_min, rate_max,
948 "channels", GST_TYPE_INT_RANGE, 1, channels_max, NULL);
951 gst_caps_set_simple (caps,
952 "block_align", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
957 if (strf_data || strd_data) {
958 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER,
959 strf_data ? strf_data : strd_data, NULL);
966 gst_riff_create_iavs_caps (guint32 codec_fcc,
967 gst_riff_strh * strh, gst_riff_strf_iavs * strf,
968 GstBuffer * init_data, GstBuffer * extra_data, char **codec_name)
970 GstCaps *caps = NULL;
973 /* is this correct? */
974 case GST_MAKE_FOURCC ('D', 'V', 'S', 'D'):
975 case GST_MAKE_FOURCC ('d', 'v', 's', 'd'):
976 caps = gst_caps_new_simple ("video/x-dv",
977 "systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
979 *codec_name = g_strdup ("Generic DV");
983 GST_WARNING ("Unknown IAVS fourcc %" GST_FOURCC_FORMAT,
984 GST_FOURCC_ARGS (codec_fcc));
992 * Functions below are for template caps. All is variable.
996 gst_riff_create_video_template_caps (void)
999 GST_MAKE_FOURCC ('I', '4', '2', '0'),
1000 GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'),
1001 GST_MAKE_FOURCC ('M', 'J', 'P', 'G'),
1002 GST_MAKE_FOURCC ('D', 'V', 'S', 'D'),
1003 GST_MAKE_FOURCC ('W', 'M', 'V', '1'),
1004 GST_MAKE_FOURCC ('W', 'M', 'V', '2'),
1005 GST_MAKE_FOURCC ('W', 'M', 'V', '3'),
1006 GST_MAKE_FOURCC ('M', 'P', 'G', '4'),
1007 GST_MAKE_FOURCC ('M', 'P', '4', '2'),
1008 GST_MAKE_FOURCC ('M', 'P', '4', '3'),
1009 GST_MAKE_FOURCC ('H', 'F', 'Y', 'U'),
1010 GST_MAKE_FOURCC ('D', 'I', 'V', '3'),
1011 GST_MAKE_FOURCC ('M', 'P', 'E', 'G'),
1012 GST_MAKE_FOURCC ('H', '2', '6', '3'),
1013 GST_MAKE_FOURCC ('I', '2', '6', '3'),
1014 GST_MAKE_FOURCC ('h', '2', '6', '4'),
1015 GST_MAKE_FOURCC ('D', 'I', 'V', 'X'),
1016 GST_MAKE_FOURCC ('D', 'X', '5', '0'),
1017 GST_MAKE_FOURCC ('X', 'V', 'I', 'D'),
1018 GST_MAKE_FOURCC ('3', 'I', 'V', '1'),
1019 GST_MAKE_FOURCC ('c', 'v', 'i', 'd'),
1020 GST_MAKE_FOURCC ('m', 's', 'v', 'c'),
1021 GST_MAKE_FOURCC ('R', 'L', 'E', ' '),
1022 GST_MAKE_FOURCC ('D', 'I', 'B', ' '),
1023 GST_MAKE_FOURCC ('X', 'x', 'a', 'n'),
1024 GST_MAKE_FOURCC ('I', 'V', '3', '2'),
1025 GST_MAKE_FOURCC ('I', 'V', '5', '0'),
1026 GST_MAKE_FOURCC ('M', '4', 'S', '2'),
1027 GST_MAKE_FOURCC ('M', 'S', 'Z', 'H'),
1028 GST_MAKE_FOURCC ('Z', 'L', 'I', 'B'),
1029 GST_MAKE_FOURCC ('A', 'S', 'V', '1'),
1030 GST_MAKE_FOURCC ('A', 'S', 'V', '2'),
1031 GST_MAKE_FOURCC ('V', 'C', 'R', '1'),
1032 GST_MAKE_FOURCC ('V', 'C', 'R', '2'),
1033 GST_MAKE_FOURCC ('C', 'L', 'J', 'R'),
1034 GST_MAKE_FOURCC ('I', 'V', '4', '1'),
1035 GST_MAKE_FOURCC ('R', 'T', '2', '1'),
1036 GST_MAKE_FOURCC ('D', 'U', 'C', 'K'),
1037 GST_MAKE_FOURCC ('T', 'M', '2', '0'),
1038 GST_MAKE_FOURCC ('U', 'L', 'T', 'I'),
1039 GST_MAKE_FOURCC ('V', 'P', '3', ' '),
1040 GST_MAKE_FOURCC ('T', 'S', 'C', 'C'),
1041 GST_MAKE_FOURCC ('S', 'P', '5', '3'),
1042 GST_MAKE_FOURCC ('P', 'N', 'G', ' '),
1043 GST_MAKE_FOURCC ('C', 'Y', 'U', 'V'),
1044 GST_MAKE_FOURCC ('F', 'L', 'V', '1'),
1049 GstCaps *caps, *one;
1051 caps = gst_caps_new_empty ();
1052 for (i = 0; tags[i] != 0; i++) {
1053 one = gst_riff_create_video_caps (tags[i], NULL, NULL, NULL, NULL, NULL);
1055 gst_caps_append (caps, one);
1062 gst_riff_create_audio_template_caps (void)
1065 GST_RIFF_WAVE_FORMAT_MPEGL3,
1066 GST_RIFF_WAVE_FORMAT_MPEGL12,
1067 GST_RIFF_WAVE_FORMAT_PCM,
1068 GST_RIFF_WAVE_FORMAT_VORBIS1,
1069 GST_RIFF_WAVE_FORMAT_A52,
1070 GST_RIFF_WAVE_FORMAT_ALAW,
1071 GST_RIFF_WAVE_FORMAT_MULAW,
1072 GST_RIFF_WAVE_FORMAT_ADPCM,
1073 GST_RIFF_WAVE_FORMAT_DVI_ADPCM,
1074 GST_RIFF_WAVE_FORMAT_WMAV1,
1075 GST_RIFF_WAVE_FORMAT_WMAV2,
1076 GST_RIFF_WAVE_FORMAT_WMAV3,
1077 GST_RIFF_WAVE_FORMAT_SONY_ATRAC3,
1082 GstCaps *caps, *one;
1084 caps = gst_caps_new_empty ();
1085 for (i = 0; tags[i] != 0; i++) {
1086 one = gst_riff_create_audio_caps (tags[i], NULL, NULL, NULL, NULL, NULL);
1088 gst_caps_append (caps, one);
1095 gst_riff_create_iavs_template_caps (void)
1098 GST_MAKE_FOURCC ('D', 'V', 'S', 'D'),
1103 GstCaps *caps, *one;
1105 caps = gst_caps_new_empty ();
1106 for (i = 0; tags[i] != 0; i++) {
1107 one = gst_riff_create_iavs_caps (tags[i], NULL, NULL, NULL, NULL, NULL);
1109 gst_caps_append (caps, one);