riff-media.c 61.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
/* GStreamer RIFF I/O
 * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
 *
 * riff-media.h: RIFF-id to/from caps routines
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "riff-ids.h"
#include "riff-media.h"

29 30 31
#include <gst/audio/multichannel.h>

#include <string.h>
32
#include <math.h>
33 34 35 36

GST_DEBUG_CATEGORY_EXTERN (riff_debug);
#define GST_CAT_DEFAULT riff_debug

37
/**
38
 * gst_riff_create_video_caps:
39 40 41 42 43 44 45 46 47 48 49 50
 * @codec_fcc: fourCC codec for this codec.
 * @strh: pointer to the strh stream header structure.
 * @strf: pointer to the strf stream header structure, including any
 *        data that is within the range of strf.size, but excluding any
 *        additional data withint this chunk but outside strf.size.
 * @strf_data: a #GstBuffer containing the additional data in the strf
 *             chunk outside reach of strf.size. Ususally a palette.
 * @strd_data: a #GstBuffer containing the data in the strd stream header
 *             chunk. Usually codec initialization data.
 * @codec_name: if given, will be filled with a human-readable codec name.
 */

51
GstCaps *
52
gst_riff_create_video_caps (guint32 codec_fcc,
53 54
    gst_riff_strh * strh, gst_riff_strf_vids * strf,
    GstBuffer * strf_data, GstBuffer * strd_data, char **codec_name)
55 56
{
  GstCaps *caps = NULL;
57
  GstBuffer *palette = NULL;
58

59 60
  GST_DEBUG ("video fourcc %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (codec_fcc));

61
  switch (codec_fcc) {
62 63 64 65 66
    case GST_MAKE_FOURCC ('D', 'I', 'B', ' '): /* uncompressed RGB */
    case GST_MAKE_FOURCC (0x00, 0x00, 0x00, 0x00):
    case GST_MAKE_FOURCC ('R', 'G', 'B', ' '):
    case GST_MAKE_FOURCC ('R', 'A', 'W', ' '):
    {
67 68 69 70 71 72 73 74 75 76 77 78 79
      gint bpp = (strf && strf->bit_cnt != 0) ? strf->bit_cnt : 8;

      if (strf) {
        if (bpp == 8) {
          caps = gst_caps_new_simple ("video/x-raw-rgb",
              "bpp", G_TYPE_INT, 8, "depth", G_TYPE_INT, 8,
              "endianness", G_TYPE_INT, G_BYTE_ORDER, NULL);
        } else if (bpp == 24) {
          caps = gst_caps_new_simple ("video/x-raw-rgb",
              "bpp", G_TYPE_INT, 24, "depth", G_TYPE_INT, 24,
              "endianness", G_TYPE_INT, G_BIG_ENDIAN,
              "red_mask", G_TYPE_INT, 0xff, "green_mask", G_TYPE_INT, 0xff00,
              "blue_mask", G_TYPE_INT, 0xff0000, NULL);
80 81 82 83 84 85
        } else if (bpp == 32) {
          caps = gst_caps_new_simple ("video/x-raw-rgb",
              "bpp", G_TYPE_INT, 32, "depth", G_TYPE_INT, 24,
              "endianness", G_TYPE_INT, G_BIG_ENDIAN,
              "red_mask", G_TYPE_INT, 0xff00, "green_mask", G_TYPE_INT,
              0xff0000, "blue_mask", G_TYPE_INT, 0xff000000, NULL);
86 87
        } else {
          GST_WARNING ("Unhandled DIB RGB depth: %d", bpp);
88
          return NULL;
89 90 91
        }
      } else {
        /* for template */
92 93
        caps =
            gst_caps_from_string ("video/x-raw-rgb, bpp = (int) { 8, 24, 32 }, "
94 95 96
            "depth = (int) { 8, 24}");
      }

97 98
      palette = strf_data;
      strf_data = NULL;
99 100 101 102 103 104
      if (codec_name) {
        if (bpp == 8)
          *codec_name = g_strdup_printf ("Palettized %d-bit RGB", bpp);
        else
          *codec_name = g_strdup_printf ("%d-bit RGB", bpp);
      }
105
      break;
106
    }
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
107
    case GST_MAKE_FOURCC ('I', '4', '2', '0'):
108
      caps = gst_caps_new_simple ("video/x-raw-yuv",
109
          "format", GST_TYPE_FOURCC, codec_fcc, NULL);
110
      if (codec_name)
111
        *codec_name = g_strdup ("Uncompressed planar YUV 4:2:0");
112
      break;
113

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
114
    case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
David Schleef's avatar
David Schleef committed
115
      caps = gst_caps_new_simple ("video/x-raw-yuv",
116
          "format", GST_TYPE_FOURCC, codec_fcc, NULL);
117
      if (codec_name)
118
        *codec_name = g_strdup ("Uncompressed packed YUV 4:2:2");
119 120
      break;

121 122 123 124 125 126 127
    case GST_MAKE_FOURCC ('Y', 'V', 'U', '9'):
      caps = gst_caps_new_simple ("video/x-raw-yuv",
          "format", GST_TYPE_FOURCC, codec_fcc, NULL);
      if (codec_name)
        *codec_name = g_strdup ("Uncompressed packed YVU 4:1:0");
      break;

128 129 130 131 132 133 134
    case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
      caps = gst_caps_new_simple ("video/x-raw-yuv",
          "format", GST_TYPE_FOURCC, codec_fcc, NULL);
      if (codec_name)
        *codec_name = g_strdup ("Uncompressed packed YUV 4:2:2");
      break;

135 136 137 138 139 140 141
    case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
      caps = gst_caps_new_simple ("video/x-raw-yuv",
          "format", GST_TYPE_FOURCC, codec_fcc, NULL);
      if (codec_name)
        *codec_name = g_strdup ("Uncompressed packed YVU 4:2:2");
      break;

142
    case GST_MAKE_FOURCC ('M', 'J', 'P', 'G'): /* YUY2 MJPEG */
143 144 145
    case GST_MAKE_FOURCC ('A', 'V', 'R', 'n'):
    case GST_MAKE_FOURCC ('I', 'J', 'P', 'G'):
    case GST_MAKE_FOURCC ('i', 'j', 'p', 'g'):
Edward Hervey's avatar
Edward Hervey committed
146 147 148
    case GST_MAKE_FOURCC ('d', 'm', 'b', '1'):
    case GST_MAKE_FOURCC ('A', 'C', 'D', 'V'):
    case GST_MAKE_FOURCC ('Q', 'I', 'V', 'G'):
149
      caps = gst_caps_new_simple ("image/jpeg", NULL);
150
      if (codec_name)
151
        *codec_name = g_strdup ("Motion JPEG");
152
      break;
153

154
    case GST_MAKE_FOURCC ('J', 'P', 'E', 'G'): /* generic (mostly RGB) MJPEG */
155
    case GST_MAKE_FOURCC ('j', 'p', 'e', 'g'): /* generic (mostly RGB) MJPEG */
156
      caps = gst_caps_new_simple ("image/jpeg", NULL);
157
      if (codec_name)
158
        *codec_name = g_strdup ("JPEG Still Image");
159
      break;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
160

161 162
    case GST_MAKE_FOURCC ('P', 'I', 'X', 'L'): /* Miro/Pinnacle fourccs */
    case GST_MAKE_FOURCC ('V', 'I', 'X', 'L'): /* Miro/Pinnacle fourccs */
163
      caps = gst_caps_new_simple ("image/jpeg", NULL);
164
      if (codec_name)
Edward Hervey's avatar
Edward Hervey committed
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
        *codec_name = g_strdup ("Miro/Pinnacle Motion JPEG");
      break;

    case GST_MAKE_FOURCC ('C', 'J', 'P', 'G'):
      caps = gst_caps_new_simple ("image/jpeg", NULL);
      if (codec_name)
        *codec_name = g_strdup ("Creative Webcam JPEG");
      break;

    case GST_MAKE_FOURCC ('S', 'L', 'M', 'J'):
      caps = gst_caps_new_simple ("image/jpeg", NULL);
      if (codec_name)
        *codec_name = g_strdup ("SL Motion JPEG");
      break;

    case GST_MAKE_FOURCC ('J', 'P', 'G', 'L'):
      caps = gst_caps_new_simple ("image/jpeg", NULL);
      if (codec_name)
        *codec_name = g_strdup ("Pegasus Lossless JPEG");
184
      break;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
185

186 187 188 189 190 191
    case GST_MAKE_FOURCC ('L', 'O', 'C', 'O'):
      caps = gst_caps_new_simple ("video/x-loco", NULL);
      if (codec_name)
        *codec_name = g_strdup ("LOCO Lossless");
      break;

192 193 194 195 196 197 198 199 200 201 202
    case GST_MAKE_FOURCC ('S', 'P', '5', '3'):
    case GST_MAKE_FOURCC ('S', 'P', '5', '4'):
    case GST_MAKE_FOURCC ('S', 'P', '5', '5'):
    case GST_MAKE_FOURCC ('S', 'P', '5', '6'):
    case GST_MAKE_FOURCC ('S', 'P', '5', '7'):
    case GST_MAKE_FOURCC ('S', 'P', '5', '8'):
      caps = gst_caps_new_simple ("video/sp5x", NULL);
      if (codec_name)
        *codec_name = g_strdup ("Sp5x-like JPEG");
      break;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
203 204
    case GST_MAKE_FOURCC ('H', 'F', 'Y', 'U'):
      caps = gst_caps_new_simple ("video/x-huffyuv", NULL);
205 206 207 208
      if (strf) {
        gst_caps_set_simple (caps, "bpp",
            G_TYPE_INT, (int) strf->bit_cnt, NULL);
      }
209
      if (codec_name)
210
        *codec_name = g_strdup ("Huffman Lossless Codec");
211
      break;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
212 213 214

    case GST_MAKE_FOURCC ('M', 'P', 'E', 'G'):
    case GST_MAKE_FOURCC ('M', 'P', 'G', 'I'):
215 216
    case GST_MAKE_FOURCC ('m', 'p', 'g', '1'):
    case GST_MAKE_FOURCC ('M', 'P', 'G', '1'):
217
    case GST_MAKE_FOURCC ('P', 'I', 'M', '1'):
218
    case GST_MAKE_FOURCC (0x01, 0x00, 0x00, 0x10):
David Schleef's avatar
David Schleef committed
219
      caps = gst_caps_new_simple ("video/mpeg",
220
          "systemstream", G_TYPE_BOOLEAN, FALSE,
221
          "mpegversion", G_TYPE_INT, 1, NULL);
222
      if (codec_name)
223
        *codec_name = g_strdup ("MPEG-1 video");
224
      break;
Edward Hervey's avatar
Edward Hervey committed
225

226 227
    case GST_MAKE_FOURCC ('M', 'P', 'G', '2'):
    case GST_MAKE_FOURCC ('m', 'p', 'g', '2'):
Edward Hervey's avatar
Edward Hervey committed
228
    case GST_MAKE_FOURCC ('P', 'I', 'M', '2'):
229
    case GST_MAKE_FOURCC ('D', 'V', 'R', ' '):
230
    case GST_MAKE_FOURCC (0x02, 0x00, 0x00, 0x10):
231 232 233 234
      caps = gst_caps_new_simple ("video/mpeg",
          "systemstream", G_TYPE_BOOLEAN, FALSE,
          "mpegversion", G_TYPE_INT, 2, NULL);
      if (codec_name)
235
        *codec_name = g_strdup ("MPEG-2 video");
236
      break;
237

Edward Hervey's avatar
Edward Hervey committed
238 239 240 241 242 243 244 245
    case GST_MAKE_FOURCC ('L', 'M', 'P', '2'):
      caps = gst_caps_new_simple ("video/mpeg",
          "systemstream", G_TYPE_BOOLEAN, FALSE,
          "mpegversion", G_TYPE_INT, 2, NULL);
      if (codec_name)
        *codec_name = g_strdup ("Lead MPEG-2 video");
      break;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
246
    case GST_MAKE_FOURCC ('H', '2', '6', '3'):
247
    case GST_MAKE_FOURCC ('h', '2', '6', '3'):
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
248
    case GST_MAKE_FOURCC ('i', '2', '6', '3'):
249
    case GST_MAKE_FOURCC ('U', '2', '6', '3'):
Edward Hervey's avatar
Edward Hervey committed
250 251
    case GST_MAKE_FOURCC ('v', 'i', 'v', '1'):
    case GST_MAKE_FOURCC ('T', '2', '6', '3'):
252 253
      caps = gst_caps_new_simple ("video/x-h263",
          "variant", G_TYPE_STRING, "itu", NULL);
254
      if (codec_name)
255
        *codec_name = g_strdup ("ITU H.26n");
256
      break;
257

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
258
    case GST_MAKE_FOURCC ('L', '2', '6', '3'):
259 260 261
      /* http://www.leadcodecs.com/Codecs/LEAD-H263.htm */
      caps = gst_caps_new_simple ("video/x-h263",
          "variant", G_TYPE_STRING, "lead", NULL);
262
      if (codec_name)
263
        *codec_name = g_strdup ("Lead H.263");
264
      break;
265

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
266
    case GST_MAKE_FOURCC ('M', '2', '6', '3'):
267
    case GST_MAKE_FOURCC ('m', '2', '6', '3'):
268 269
      caps = gst_caps_new_simple ("video/x-h263",
          "variant", G_TYPE_STRING, "microsoft", NULL);
270
      if (codec_name)
271
        *codec_name = g_strdup ("Microsoft H.263");
272
      break;
273

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
274
    case GST_MAKE_FOURCC ('V', 'D', 'O', 'W'):
275 276
      caps = gst_caps_new_simple ("video/x-h263",
          "variant", G_TYPE_STRING, "vdolive", NULL);
277
      if (codec_name)
278
        *codec_name = g_strdup ("VDOLive");
279
      break;
280

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
281
    case GST_MAKE_FOURCC ('V', 'I', 'V', 'O'):
282 283
      caps = gst_caps_new_simple ("video/x-h263",
          "variant", G_TYPE_STRING, "vivo", NULL);
284
      if (codec_name)
285
        *codec_name = g_strdup ("Vivo H.263");
286
      break;
287

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
288
    case GST_MAKE_FOURCC ('x', '2', '6', '3'):
289 290
      caps = gst_caps_new_simple ("video/x-h263",
          "variant", G_TYPE_STRING, "xirlink", NULL);
291
      if (codec_name)
292
        *codec_name = g_strdup ("Xirlink H.263");
293 294
      break;

295 296
      /* apparently not standard H.263...? */
    case GST_MAKE_FOURCC ('I', '2', '6', '3'):
297 298
      caps = gst_caps_new_simple ("video/x-intel-h263",
          "variant", G_TYPE_STRING, "intel", NULL);
299 300 301 302
      if (codec_name)
        *codec_name = g_strdup ("Intel H.263");
      break;

Edward Hervey's avatar
Edward Hervey committed
303 304 305 306 307 308 309
    case GST_MAKE_FOURCC ('V', 'X', '1', 'K'):
      caps = gst_caps_new_simple ("video/x-h263",
          "variant", G_TYPE_STRING, "lucent", NULL);
      if (codec_name)
        *codec_name = g_strdup ("Lucent VX1000S H.263");
      break;

310 311
    case GST_MAKE_FOURCC ('X', '2', '6', '4'):
    case GST_MAKE_FOURCC ('x', '2', '6', '4'):
312
    case GST_MAKE_FOURCC ('H', '2', '6', '4'):
313
    case GST_MAKE_FOURCC ('h', '2', '6', '4'):
314 315
    case GST_MAKE_FOURCC ('a', 'v', 'c', '1'):
    case GST_MAKE_FOURCC ('A', 'V', 'C', '1'):
316 317
      caps = gst_caps_new_simple ("video/x-h264",
          "variant", G_TYPE_STRING, "itu", NULL);
318 319 320 321 322
      if (codec_name)
        *codec_name = g_strdup ("ITU H.264");
      break;

    case GST_MAKE_FOURCC ('V', 'S', 'S', 'H'):
323 324
      caps = gst_caps_new_simple ("video/x-h264",
          "variant", G_TYPE_STRING, "videosoft", NULL);
325 326 327 328
      if (codec_name)
        *codec_name = g_strdup ("VideoSoft H.264");
      break;

329 330 331 332 333 334 335 336
    case GST_MAKE_FOURCC ('L', '2', '6', '4'):
      /* http://www.leadcodecs.com/Codecs/LEAD-H264.htm */
      caps = gst_caps_new_simple ("video/x-h264",
          "variant", G_TYPE_STRING, "lead", NULL);
      if (codec_name)
        *codec_name = g_strdup ("Lead H.264");
      break;

337 338 339 340 341 342 343
    case GST_MAKE_FOURCC ('S', 'E', 'D', 'G'):
      caps = gst_caps_new_simple ("video/mpeg",
          "mpegversion", G_TYPE_INT, 4, NULL);
      if (codec_name)
        *codec_name = g_strdup ("Samsung MPEG-4");
      break;

Edward Hervey's avatar
Edward Hervey committed
344 345 346 347 348 349 350
    case GST_MAKE_FOURCC ('M', '4', 'C', 'C'):
      caps = gst_caps_new_simple ("video/mpeg",
          "mpegversion", G_TYPE_INT, 4, NULL);
      if (codec_name)
        *codec_name = g_strdup ("Divio MPEG-4");
      break;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
351
    case GST_MAKE_FOURCC ('D', 'I', 'V', '3'):
352
    case GST_MAKE_FOURCC ('d', 'i', 'v', '3'):
Edward Hervey's avatar
Edward Hervey committed
353 354
    case GST_MAKE_FOURCC ('D', 'V', 'X', '3'):
    case GST_MAKE_FOURCC ('d', 'v', 'x', '3'):
355
    case GST_MAKE_FOURCC ('D', 'I', 'V', '4'):
356
    case GST_MAKE_FOURCC ('d', 'i', 'v', '4'):
357
    case GST_MAKE_FOURCC ('D', 'I', 'V', '5'):
358
    case GST_MAKE_FOURCC ('d', 'i', 'v', '5'):
359
    case GST_MAKE_FOURCC ('D', 'I', 'V', '6'):
360
    case GST_MAKE_FOURCC ('d', 'i', 'v', '6'):
361 362 363 364 365 366 367
    case GST_MAKE_FOURCC ('M', 'P', 'G', '3'):
    case GST_MAKE_FOURCC ('m', 'p', 'g', '3'):
    case GST_MAKE_FOURCC ('c', 'o', 'l', '0'):
    case GST_MAKE_FOURCC ('C', 'O', 'L', '0'):
    case GST_MAKE_FOURCC ('c', 'o', 'l', '1'):
    case GST_MAKE_FOURCC ('C', 'O', 'L', '1'):
    case GST_MAKE_FOURCC ('A', 'P', '4', '1'):
David Schleef's avatar
David Schleef committed
368
      caps = gst_caps_new_simple ("video/x-divx",
369
          "divxversion", G_TYPE_INT, 3, NULL);
370
      if (codec_name)
371
        *codec_name = g_strdup ("DivX MS-MPEG-4 Version 3");
372
      break;
373

374 375
    case GST_MAKE_FOURCC ('d', 'i', 'v', 'x'):
    case GST_MAKE_FOURCC ('D', 'I', 'V', 'X'):
376
      caps = gst_caps_new_simple ("video/x-divx",
377
          "divxversion", G_TYPE_INT, 4, NULL);
378
      if (codec_name)
379
        *codec_name = g_strdup ("DivX MPEG-4 Version 4");
380
      break;
381

382 383 384 385 386 387 388
    case GST_MAKE_FOURCC ('B', 'L', 'Z', '0'):
      caps = gst_caps_new_simple ("video/x-divx",
          "divxversion", G_TYPE_INT, 4, NULL);
      if (codec_name)
        *codec_name = g_strdup ("Blizzard DivX");
      break;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
389
    case GST_MAKE_FOURCC ('D', 'X', '5', '0'):
David Schleef's avatar
David Schleef committed
390
      caps = gst_caps_new_simple ("video/x-divx",
391
          "divxversion", G_TYPE_INT, 5, NULL);
392
      if (codec_name)
393
        *codec_name = g_strdup ("DivX MPEG-4 Version 5");
394 395
      break;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
396 397
    case GST_MAKE_FOURCC ('X', 'V', 'I', 'D'):
    case GST_MAKE_FOURCC ('x', 'v', 'i', 'd'):
David Schleef's avatar
David Schleef committed
398
      caps = gst_caps_new_simple ("video/x-xvid", NULL);
399
      if (codec_name)
400
        *codec_name = g_strdup ("XVID MPEG-4");
401 402
      break;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
403
    case GST_MAKE_FOURCC ('M', 'P', 'G', '4'):
Edward Hervey's avatar
Edward Hervey committed
404 405
    case GST_MAKE_FOURCC ('M', 'P', '4', '1'):
    case GST_MAKE_FOURCC ('m', 'p', '4', '1'):
David Schleef's avatar
David Schleef committed
406
      caps = gst_caps_new_simple ("video/x-msmpeg",
407
          "msmpegversion", G_TYPE_INT, 41, NULL);
408
      if (codec_name)
409
        *codec_name = g_strdup ("Microsoft MPEG-4 4.1");
410 411
      break;

412
    case GST_MAKE_FOURCC ('m', 'p', '4', '2'):
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
413
    case GST_MAKE_FOURCC ('M', 'P', '4', '2'):
David Schleef's avatar
David Schleef committed
414
      caps = gst_caps_new_simple ("video/x-msmpeg",
415
          "msmpegversion", G_TYPE_INT, 42, NULL);
416
      if (codec_name)
417
        *codec_name = g_strdup ("Microsoft MPEG-4 4.2");
418 419
      break;

420
    case GST_MAKE_FOURCC ('m', 'p', '4', '3'):
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
421
    case GST_MAKE_FOURCC ('M', 'P', '4', '3'):
David Schleef's avatar
David Schleef committed
422
      caps = gst_caps_new_simple ("video/x-msmpeg",
423
          "msmpegversion", G_TYPE_INT, 43, NULL);
424
      if (codec_name)
425
        *codec_name = g_strdup ("Microsoft MPEG-4 4.3");
426 427
      break;

428
    case GST_MAKE_FOURCC ('M', 'P', '4', 'S'):
429 430 431 432 433 434 435 436
    case GST_MAKE_FOURCC ('M', '4', 'S', '2'):
      caps = gst_caps_new_simple ("video/mpeg",
          "mpegversion", G_TYPE_INT, 4, NULL);
      if (codec_name)
        *codec_name = g_strdup ("Microsoft ISO MPEG-4 1.1");
      break;

    case GST_MAKE_FOURCC ('F', 'M', 'P', '4'):
437
    case GST_MAKE_FOURCC ('U', 'M', 'P', '4'):
Edward Hervey's avatar
Edward Hervey committed
438
    case GST_MAKE_FOURCC ('F', 'F', 'D', 'S'):
439 440 441 442 443 444
      caps = gst_caps_new_simple ("video/mpeg",
          "mpegversion", G_TYPE_INT, 4, NULL);
      if (codec_name)
        *codec_name = g_strdup ("FFmpeg MPEG-4");
      break;

Edward Hervey's avatar
Edward Hervey committed
445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464
    case GST_MAKE_FOURCC ('E', 'M', '4', 'A'):
    case GST_MAKE_FOURCC ('E', 'P', 'V', 'H'):
    case GST_MAKE_FOURCC ('F', 'V', 'F', 'W'):
    case GST_MAKE_FOURCC ('I', 'N', 'M', 'C'):
    case GST_MAKE_FOURCC ('D', 'I', 'G', 'I'):
    case GST_MAKE_FOURCC ('D', 'M', '2', 'K'):
    case GST_MAKE_FOURCC ('D', 'C', 'O', 'D'):
    case GST_MAKE_FOURCC ('M', 'V', 'X', 'M'):
    case GST_MAKE_FOURCC ('P', 'M', '4', 'V'):
    case GST_MAKE_FOURCC ('S', 'M', 'P', '4'):
    case GST_MAKE_FOURCC ('D', 'X', 'G', 'M'):
    case GST_MAKE_FOURCC ('V', 'I', 'D', 'M'):
    case GST_MAKE_FOURCC ('M', '4', 'T', '3'):
    case GST_MAKE_FOURCC ('G', 'E', 'O', 'X'):
      caps = gst_caps_new_simple ("video/mpeg",
          "mpegversion", G_TYPE_INT, 4, NULL);
      if (codec_name)
        *codec_name = g_strdup ("MPEG-4");
      break;

465 466
    case GST_MAKE_FOURCC ('3', 'i', 'v', 'd'):
    case GST_MAKE_FOURCC ('3', 'I', 'V', 'D'):
467 468
      caps = gst_caps_new_simple ("video/x-msmpeg",
          "msmpegversion", G_TYPE_INT, 43, NULL);
469 470
      if (codec_name)
        *codec_name = g_strdup ("Microsoft MPEG-4 4.3");        /* FIXME? */
471
      break;
472

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
473 474 475
    case GST_MAKE_FOURCC ('3', 'I', 'V', '1'):
    case GST_MAKE_FOURCC ('3', 'I', 'V', '2'):
      caps = gst_caps_new_simple ("video/x-3ivx", NULL);
476
      if (codec_name)
477
        *codec_name = g_strdup ("3ivx");
478 479
      break;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
480 481
    case GST_MAKE_FOURCC ('D', 'V', 'S', 'D'):
    case GST_MAKE_FOURCC ('d', 'v', 's', 'd'):
Edward Hervey's avatar
Edward Hervey committed
482 483
    case GST_MAKE_FOURCC ('d', 'v', 'c', ' '):
    case GST_MAKE_FOURCC ('d', 'v', '2', '5'):
David Schleef's avatar
David Schleef committed
484
      caps = gst_caps_new_simple ("video/x-dv",
485 486
          "systemstream", G_TYPE_BOOLEAN, FALSE,
          "dvversion", G_TYPE_INT, 25, NULL);
487
      if (codec_name)
488
        *codec_name = g_strdup ("Generic DV");
489 490
      break;

Edward Hervey's avatar
Edward Hervey committed
491 492 493 494 495 496 497 498 499
    case GST_MAKE_FOURCC ('C', 'D', 'V', 'C'):
    case GST_MAKE_FOURCC ('c', 'd', 'v', 'c'):
      caps = gst_caps_new_simple ("video/x-dv",
          "systemstream", G_TYPE_BOOLEAN, FALSE,
          "dvversion", G_TYPE_INT, 25, NULL);
      if (codec_name)
        *codec_name = g_strdup ("Canopus DV");
      break;

500 501 502 503 504 505 506 507 508
    case GST_MAKE_FOURCC ('D', 'V', '5', '0'):
    case GST_MAKE_FOURCC ('d', 'v', '5', '0'):
      caps = gst_caps_new_simple ("video/x-dv",
          "systemstream", G_TYPE_BOOLEAN, FALSE,
          "dvversion", G_TYPE_INT, 50, NULL);
      if (codec_name)
        *codec_name = g_strdup ("DVCPro50 Video");
      break;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
509
    case GST_MAKE_FOURCC ('W', 'M', 'V', '1'):
David Schleef's avatar
David Schleef committed
510
      caps = gst_caps_new_simple ("video/x-wmv",
511
          "wmvversion", G_TYPE_INT, 1, NULL);
512
      if (codec_name)
513
        *codec_name = g_strdup ("Microsoft Windows Media 7");
514 515
      break;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
516
    case GST_MAKE_FOURCC ('W', 'M', 'V', '2'):
David Schleef's avatar
David Schleef committed
517
      caps = gst_caps_new_simple ("video/x-wmv",
518
          "wmvversion", G_TYPE_INT, 2, NULL);
519
      if (codec_name)
520
        *codec_name = g_strdup ("Microsoft Windows Media 8");
521
      break;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
522 523

    case GST_MAKE_FOURCC ('W', 'M', 'V', '3'):
524
      caps = gst_caps_new_simple ("video/x-wmv",
525
          "wmvversion", G_TYPE_INT, 3, NULL);
526
      if (codec_name)
527
        *codec_name = g_strdup ("Microsoft Windows Media 9");
528 529
      break;

530 531
    case GST_MAKE_FOURCC ('W', 'M', 'V', 'A'):
      caps = gst_caps_new_simple ("video/x-wmv",
532
          "wmvversion", G_TYPE_INT, 3, "format", GST_TYPE_FOURCC,
533 534 535 536 537
          codec_fcc, NULL);
      if (codec_name)
        *codec_name = g_strdup ("Microsoft Windows Media Advanced Profile");
      break;

538 539
    case GST_MAKE_FOURCC ('W', 'V', 'C', '1'):
      caps = gst_caps_new_simple ("video/x-wmv",
540
          "wmvversion", G_TYPE_INT, 3, "format", GST_TYPE_FOURCC,
541 542 543 544 545
          codec_fcc, NULL);
      if (codec_name)
        *codec_name = g_strdup ("Microsoft Windows Media VC-1");
      break;

546 547 548 549 550 551
    case GST_MAKE_FOURCC ('c', 'v', 'i', 'd'):
      caps = gst_caps_new_simple ("video/x-cinepak", NULL);
      if (codec_name)
        *codec_name = g_strdup ("Cinepak video");
      break;

552 553 554 555 556 557 558 559 560 561
    case GST_MAKE_FOURCC ('M', 'S', 'V', 'C'):
    case GST_MAKE_FOURCC ('m', 's', 'v', 'c'):
    case GST_MAKE_FOURCC ('C', 'R', 'A', 'M'):
    case GST_MAKE_FOURCC ('c', 'r', 'a', 'm'):
    case GST_MAKE_FOURCC ('W', 'H', 'A', 'M'):
    case GST_MAKE_FOURCC ('w', 'h', 'a', 'm'):
      caps = gst_caps_new_simple ("video/x-msvideocodec",
          "msvideoversion", G_TYPE_INT, 1, NULL);
      if (codec_name)
        *codec_name = g_strdup ("MS video v1");
562 563
      palette = strf_data;
      strf_data = NULL;
564 565
      break;

566 567 568
    case GST_MAKE_FOURCC ('R', 'L', 'E', ' '):
    case GST_MAKE_FOURCC ('m', 'r', 'l', 'e'):
    case GST_MAKE_FOURCC (0x1, 0x0, 0x0, 0x0): /* why, why, why? */
Edward Hervey's avatar
Edward Hervey committed
569
    case GST_MAKE_FOURCC (0x2, 0x0, 0x0, 0x0): /* why, why, why? */
570 571
      caps = gst_caps_new_simple ("video/x-rle",
          "layout", G_TYPE_STRING, "microsoft", NULL);
572 573
      palette = strf_data;
      strf_data = NULL;
574 575 576 577 578 579 580
      if (strf) {
        gst_caps_set_simple (caps,
            "depth", G_TYPE_INT, (gint) strf->bit_cnt, NULL);
      } else {
        gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 1, 64, NULL);
      }
      if (codec_name)
581 582 583
        *codec_name = g_strdup ("Microsoft RLE");
      break;

584 585 586 587 588 589
    case GST_MAKE_FOURCC ('A', 'A', 'S', 'C'):
      caps = gst_caps_new_simple ("video/x-aasc", NULL);
      if (codec_name)
        *codec_name = g_strdup ("Autodesk Animator");
      break;

590 591 592 593 594
    case GST_MAKE_FOURCC ('X', 'x', 'a', 'n'):
      caps = gst_caps_new_simple ("video/x-xan",
          "wcversion", G_TYPE_INT, 4, NULL);
      if (codec_name)
        *codec_name = g_strdup ("Xan Wing Commander 4");
595 596
      break;

597 598 599 600 601 602 603 604
    case GST_MAKE_FOURCC ('R', 'T', '2', '1'):
      caps = gst_caps_new_simple ("video/x-indeo",
          "indeoversion", G_TYPE_INT, 2, NULL);
      if (codec_name)
        *codec_name = g_strdup ("Intel Video 2");
      break;

    case GST_MAKE_FOURCC ('I', 'V', '3', '1'):
605
    case GST_MAKE_FOURCC ('I', 'V', '3', '2'):
606 607
    case GST_MAKE_FOURCC ('i', 'v', '3', '1'):
    case GST_MAKE_FOURCC ('i', 'v', '3', '2'):
608 609 610 611 612 613
      caps = gst_caps_new_simple ("video/x-indeo",
          "indeoversion", G_TYPE_INT, 3, NULL);
      if (codec_name)
        *codec_name = g_strdup ("Intel Video 3");
      break;

614 615 616 617 618 619 620 621
    case GST_MAKE_FOURCC ('I', 'V', '4', '1'):
    case GST_MAKE_FOURCC ('i', 'v', '4', '1'):
      caps = gst_caps_new_simple ("video/x-indeo",
          "indeoversion", G_TYPE_INT, 4, NULL);
      if (codec_name)
        *codec_name = g_strdup ("Intel Video 4");
      break;

622
    case GST_MAKE_FOURCC ('I', 'V', '5', '0'):
623 624
      caps = gst_caps_new_simple ("video/x-indeo",
          "indeoversion", G_TYPE_INT, 5, NULL);
625 626 627 628
      if (codec_name)
        *codec_name = g_strdup ("Intel Video 5");
      break;

629 630 631 632 633 634 635 636 637 638 639 640 641
    case GST_MAKE_FOURCC ('M', 'S', 'Z', 'H'):
      caps = gst_caps_new_simple ("video/x-mszh", NULL);
      if (codec_name)
        *codec_name = g_strdup ("Lossless MSZH Video");
      break;

    case GST_MAKE_FOURCC ('Z', 'L', 'I', 'B'):
      caps = gst_caps_new_simple ("video/x-zlib", NULL);
      if (codec_name)
        *codec_name = g_strdup ("Lossless zlib video");
      break;

    case GST_MAKE_FOURCC ('C', 'L', 'J', 'R'):
Edward Hervey's avatar
Edward Hervey committed
642
    case GST_MAKE_FOURCC ('c', 'l', 'j', 'r'):
643 644 645 646 647 648 649 650 651 652 653 654 655
      caps = gst_caps_new_simple ("video/x-cirrus-logic-accupak", NULL);
      if (codec_name)
        *codec_name = g_strdup ("Cirrus Logipak AccuPak");
      break;

    case GST_MAKE_FOURCC ('C', 'Y', 'U', 'V'):
    case GST_MAKE_FOURCC ('c', 'y', 'u', 'v'):
      caps = gst_caps_new_simple ("video/x-compressed-yuv", NULL);
      if (codec_name)
        *codec_name = g_strdup ("CYUV Lossless");
      break;

    case GST_MAKE_FOURCC ('D', 'U', 'C', 'K'):
Edward Hervey's avatar
Edward Hervey committed
656
    case GST_MAKE_FOURCC ('P', 'V', 'E', 'Z'):
657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686
      caps = gst_caps_new_simple ("video/x-truemotion",
          "trueversion", G_TYPE_INT, 1, NULL);
      if (codec_name)
        *codec_name = g_strdup ("Duck Truemotion1");
      break;

    case GST_MAKE_FOURCC ('T', 'M', '2', '0'):
      caps = gst_caps_new_simple ("video/x-truemotion",
          "trueversion", G_TYPE_INT, 2, NULL);
      if (codec_name)
        *codec_name = g_strdup ("TrueMotion 2.0");
      break;

    case GST_MAKE_FOURCC ('V', 'P', '3', '0'):
    case GST_MAKE_FOURCC ('v', 'p', '3', '0'):
    case GST_MAKE_FOURCC ('V', 'P', '3', '1'):
    case GST_MAKE_FOURCC ('v', 'p', '3', '1'):
    case GST_MAKE_FOURCC ('V', 'P', '3', ' '):
      caps = gst_caps_new_simple ("video/x-vp3", NULL);
      if (codec_name)
        *codec_name = g_strdup ("VP3");
      break;

    case GST_MAKE_FOURCC ('U', 'L', 'T', 'I'):
      caps = gst_caps_new_simple ("video/x-ultimotion", NULL);
      if (codec_name)
        *codec_name = g_strdup ("IBM UltiMotion");
      break;

    case GST_MAKE_FOURCC ('T', 'S', 'C', 'C'):
687 688
    case GST_MAKE_FOURCC ('t', 's', 'c', 'c'):{
      if (strf) {
689
        gint depth = (strf->bit_cnt != 0) ? (gint) strf->bit_cnt : 24;
690

691 692
        caps = gst_caps_new_simple ("video/x-camtasia", "depth", G_TYPE_INT,
            depth, NULL);
693 694 695 696
      } else {
        /* template caps */
        caps = gst_caps_new_simple ("video/x-camtasia", NULL);
      }
697 698 699
      if (codec_name)
        *codec_name = g_strdup ("TechSmith Camtasia");
      break;
700
    }
701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737

    case GST_MAKE_FOURCC ('V', 'C', 'R', '1'):
      caps = gst_caps_new_simple ("video/x-ati-vcr",
          "vcrversion", G_TYPE_INT, 1, NULL);
      if (codec_name)
        *codec_name = g_strdup ("ATI VCR 1");
      break;

    case GST_MAKE_FOURCC ('V', 'C', 'R', '2'):
      caps = gst_caps_new_simple ("video/x-ati-vcr",
          "vcrversion", G_TYPE_INT, 2, NULL);
      if (codec_name)
        *codec_name = g_strdup ("ATI VCR 2");
      break;

    case GST_MAKE_FOURCC ('A', 'S', 'V', '1'):
      caps = gst_caps_new_simple ("video/x-asus",
          "asusversion", G_TYPE_INT, 1, NULL);
      if (codec_name)
        *codec_name = g_strdup ("Asus Video 1");
      break;

    case GST_MAKE_FOURCC ('A', 'S', 'V', '2'):
      caps = gst_caps_new_simple ("video/x-asus",
          "asusversion", G_TYPE_INT, 2, NULL);
      if (codec_name)
        *codec_name = g_strdup ("Asus Video 2");
      break;

    case GST_MAKE_FOURCC ('M', 'P', 'N', 'G'):
    case GST_MAKE_FOURCC ('m', 'p', 'n', 'g'):
    case GST_MAKE_FOURCC ('P', 'N', 'G', ' '):
      caps = gst_caps_new_simple ("image/png", NULL);
      if (codec_name)
        *codec_name = g_strdup ("PNG image");
      break;

738 739 740 741 742 743 744
    case GST_MAKE_FOURCC ('F', 'L', 'V', '1'):
      caps = gst_caps_new_simple ("video/x-flash-video",
          "flvversion", G_TYPE_INT, 1, NULL);
      if (codec_name)
        *codec_name = g_strdup ("Flash Video 1");
      break;

745 746 747 748 749 750 751
    case GST_MAKE_FOURCC ('V', 'M', 'n', 'c'):
      caps = gst_caps_new_simple ("video/x-vmnc",
          "version", G_TYPE_INT, 1, NULL);
      if (codec_name)
        *codec_name = g_strdup ("VMWare NC Video");
      break;

752 753 754 755 756 757
    case GST_MAKE_FOURCC ('d', 'r', 'a', 'c'):
      caps = gst_caps_new_simple ("video/x-dirac", NULL);
      if (codec_name)
        *codec_name = g_strdup ("Dirac");
      break;

Edward Hervey's avatar
Edward Hervey committed
758 759 760 761 762 763 764 765 766
    case GST_RIFF_rpza:
    case GST_RIFF_azpr:
    case GST_MAKE_FOURCC ('R', 'P', 'Z', 'A'):
      caps = gst_caps_new_simple ("video/x-apple-video", NULL);
      if (codec_name)
        *codec_name = g_strdup ("Apple Video (RPZA)");
      break;


767 768 769 770 771 772 773
    case GST_MAKE_FOURCC ('F', 'F', 'V', '1'):
      caps = gst_caps_new_simple ("video/x-ffv",
          "ffvversion", G_TYPE_INT, 1, NULL);
      if (codec_name)
        *codec_name = g_strdup ("FFmpeg lossless video codec");
      break;

774 775 776 777 778 779
    case GST_MAKE_FOURCC ('K', 'M', 'V', 'C'):
      caps = gst_caps_new_simple ("video/x-kmvc", NULL);
      if (codec_name)
        *codec_name = g_strdup ("Karl Morton's video codec");
      break;

780 781 782 783 784 785 786
    case GST_MAKE_FOURCC ('v', 'p', '6', '0'):
    case GST_MAKE_FOURCC ('V', 'P', '6', '0'):
      caps = gst_caps_new_simple ("video/x-vp6", NULL);
      if (codec_name)
        *codec_name = g_strdup ("On2 VP6");
      break;

Edward Hervey's avatar
Edward Hervey committed
787 788 789 790 791 792
    case GST_MAKE_FOURCC ('L', 'M', '2', '0'):
      caps = gst_caps_new_simple ("video/x-mimic", NULL);
      if (codec_name)
        *codec_name = g_strdup ("Mimic webcam");
      break;

Wim Taymans's avatar
Wim Taymans committed
793 794 795 796 797 798 799
    case GST_MAKE_FOURCC ('T', 'H', 'E', 'O'):
    case GST_MAKE_FOURCC ('t', 'h', 'e', 'o'):
      caps = gst_caps_new_simple ("video/x-theora", NULL);
      if (codec_name)
        *codec_name = g_strdup ("Theora video codec");

      break;
Edward Hervey's avatar
Edward Hervey committed
800

801 802 803 804 805 806 807
    case GST_MAKE_FOURCC ('F', 'P', 'S', '1'):
      caps = gst_caps_new_simple ("video/x-fraps", NULL);
      if (codec_name)
        *codec_name = g_strdup ("Fraps video");

      break;

808
    default:
809
      GST_WARNING ("Unknown video fourcc %" GST_FOURCC_FORMAT,
810
          GST_FOURCC_ARGS (codec_fcc));
David Schleef's avatar
David Schleef committed
811
      return NULL;
812 813
  }

David Schleef's avatar
David Schleef committed
814
  if (strh != NULL) {
815 816
    gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION,
        strh->rate, strh->scale, NULL);
David Schleef's avatar
David Schleef committed
817 818
  } else {
    gst_caps_set_simple (caps,
819
        "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
David Schleef's avatar
David Schleef committed
820 821 822 823
  }

  if (strf != NULL) {
    gst_caps_set_simple (caps,
824 825
        "width", G_TYPE_INT, strf->width,
        "height", G_TYPE_INT, strf->height, NULL);
David Schleef's avatar
David Schleef committed
826 827
  } else {
    gst_caps_set_simple (caps,
828 829
        "width", GST_TYPE_INT_RANGE, 16, 4096,
        "height", GST_TYPE_INT_RANGE, 16, 4096, NULL);
830 831
  }

832 833
  /* extradata */
  if (strf_data || strd_data) {
Wim Taymans's avatar
Wim Taymans committed
834 835 836 837 838
    GstBuffer *codec_data;

    codec_data = strf_data ? strf_data : strd_data;

    gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, codec_data, NULL);
839 840
  }

841
  /* palette */
842 843 844 845 846 847 848 849 850
  if (palette) {
    GstBuffer *copy;
    guint num_colors;

    if (strf != NULL)
      num_colors = strf->num_colors;
    else
      num_colors = 256;

851 852
    if (GST_BUFFER_SIZE (palette) >= (num_colors * 4)) {
      /* palette is always at least 256*4 bytes */
853 854
      copy =
          gst_buffer_new_and_alloc (MAX (GST_BUFFER_SIZE (palette), 256 * 4));
855 856
      memcpy (GST_BUFFER_DATA (copy), GST_BUFFER_DATA (palette),
          GST_BUFFER_SIZE (palette));
857 858

#if (G_BYTE_ORDER == G_BIG_ENDIAN)
859 860 861 862 863 864 865 866 867 868
      {
        guint8 *data = GST_BUFFER_DATA (copy);
        gint n;

        /* own endianness */
        for (n = 0; n < num_colors; n++) {
          GST_WRITE_UINT32_BE (data, GST_READ_UINT32_LE (data));
          data += sizeof (guint32);
        }
      }
869
#endif
870 871 872 873 874
      gst_caps_set_simple (caps, "palette_data", GST_TYPE_BUFFER, copy, NULL);
      gst_buffer_unref (copy);
    } else {
      GST_WARNING ("Palette smaller than expected: broken file");
    }
875 876
  }

877 878 879
  return caps;
}

880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924
static const struct
{
  const guint32 ms_mask;
  const GstAudioChannelPosition gst_pos;
} layout_mapping[] = {
  {
  0x00001, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT}, {
  0x00002, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}, {
  0x00004, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER}, {
  0x00008, GST_AUDIO_CHANNEL_POSITION_LFE}, {
  0x00010, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT}, {
  0x00020, GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}, {
  0x00040, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER}, {
  0x00080, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER}, {
  0x00100, GST_AUDIO_CHANNEL_POSITION_REAR_CENTER}, {
  0x00200, GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT}, {
  0x00400, GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT}, {
  0x00800, GST_AUDIO_CHANNEL_POSITION_INVALID}, /* TOP_CENTER       */
  {
  0x01000, GST_AUDIO_CHANNEL_POSITION_INVALID}, /* TOP_FRONT_LEFT   */
  {
  0x02000, GST_AUDIO_CHANNEL_POSITION_INVALID}, /* TOP_FRONT_CENTER */
  {
  0x04000, GST_AUDIO_CHANNEL_POSITION_INVALID}, /* TOP_FRONT_RIGHT  */
  {
  0x08000, GST_AUDIO_CHANNEL_POSITION_INVALID}, /* TOP_BACK_LEFT    */
  {
  0x10000, GST_AUDIO_CHANNEL_POSITION_INVALID}, /* TOP_BACK_CENTER  */
  {
  0x20000, GST_AUDIO_CHANNEL_POSITION_INVALID}  /* TOP_BACK_RIGHT   */
};

#define MAX_CHANNEL_POSITIONS G_N_ELEMENTS (layout_mapping)

static gboolean
gst_riff_wavext_add_channel_layout (GstCaps * caps, guint32 layout)
{
  GstAudioChannelPosition pos[MAX_CHANNEL_POSITIONS];
  GstStructure *s;
  gint num_channels, i, p;

  s = gst_caps_get_structure (caps, 0);
  if (!gst_structure_get_int (s, "channels", &num_channels))
    g_return_val_if_reached (FALSE);

925 926 927 928
  /* In theory this should be done for 1 and 2 channels too but
   * apparently breaks too many things currently.
   */
  if (num_channels <= 2 || num_channels > MAX_CHANNEL_POSITIONS) {
929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954