riff-media.c 42.5 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 32 33 34 35
#include <gst/audio/multichannel.h>

#include <string.h>

GST_DEBUG_CATEGORY_EXTERN (riff_debug);
#define GST_CAT_DEFAULT riff_debug

36 37 38 39 40 41 42 43 44 45 46 47 48 49
/**
 * gst_riff_create_video_caps_with_data:
 * @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.
 */

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

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

60
  switch (codec_fcc) {
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
    case GST_MAKE_FOURCC ('D', 'I', 'B', ' '):{
      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);
        } else {
          GST_WARNING ("Unhandled DIB RGB depth: %d", bpp);
        }
      } else {
        /* for template */
        caps = gst_caps_from_string ("video/x-raw-rgb, bpp = (int) { 8, 24 }, "
            "depth = (int) { 8, 24}");
      }

84 85 86
      palette = strf_data;
      strf_data = NULL;
      if (codec_name)
87
        *codec_name = g_strdup_printf ("Palettized %d-bit RGB", bpp);
88
      break;
89
    }
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
90
    case GST_MAKE_FOURCC ('I', '4', '2', '0'):
91
      caps = gst_caps_new_simple ("video/x-raw-yuv",
92
          "format", GST_TYPE_FOURCC, codec_fcc, NULL);
93
      if (codec_name)
94
        *codec_name = g_strdup ("Uncompressed planar YUV 4:2:0");
95
      break;
96

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
97
    case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
David Schleef's avatar
David Schleef committed
98
      caps = gst_caps_new_simple ("video/x-raw-yuv",
99
          "format", GST_TYPE_FOURCC, codec_fcc, NULL);
100
      if (codec_name)
101
        *codec_name = g_strdup ("Uncompressed packed YUV 4:2:2");
102 103
      break;

104 105 106 107 108 109 110
    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;

111
    case GST_MAKE_FOURCC ('M', 'J', 'P', 'G'): /* YUY2 MJPEG */
112 113 114 115
    case GST_MAKE_FOURCC ('A', 'V', 'R', 'n'):
    case GST_MAKE_FOURCC ('I', 'J', 'P', 'G'):
    case GST_MAKE_FOURCC ('i', 'j', 'p', 'g'):
    case GST_MAKE_FOURCC ('J', 'P', 'G', 'L'):
116
      caps = gst_caps_new_simple ("image/jpeg", NULL);
117
      if (codec_name)
118
        *codec_name = g_strdup ("Motion JPEG");
119
      break;
120

121
    case GST_MAKE_FOURCC ('J', 'P', 'E', 'G'): /* generic (mostly RGB) MJPEG */
122
      caps = gst_caps_new_simple ("image/jpeg", NULL);
123
      if (codec_name)
124
        *codec_name = g_strdup ("JPEG Still Image");
125
      break;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
126

127 128
    case GST_MAKE_FOURCC ('P', 'I', 'X', 'L'): /* Miro/Pinnacle fourccs */
    case GST_MAKE_FOURCC ('V', 'I', 'X', 'L'): /* Miro/Pinnacle fourccs */
129
      caps = gst_caps_new_simple ("image/jpeg", NULL);
130
      if (codec_name)
131
        *codec_name = g_strdup ("Miro/Pinnacle Motion JPEG Video");
132
      break;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
133

134 135 136 137 138 139 140 141 142 143 144
    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
145 146
    case GST_MAKE_FOURCC ('H', 'F', 'Y', 'U'):
      caps = gst_caps_new_simple ("video/x-huffyuv", NULL);
147 148 149 150
      if (strf) {
        gst_caps_set_simple (caps, "bpp",
            G_TYPE_INT, (int) strf->bit_cnt, NULL);
      }
151
      if (codec_name)
152
        *codec_name = g_strdup ("Huffman Lossless Codec");
153
      break;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
154 155 156

    case GST_MAKE_FOURCC ('M', 'P', 'E', 'G'):
    case GST_MAKE_FOURCC ('M', 'P', 'G', 'I'):
157 158
    case GST_MAKE_FOURCC ('m', 'p', 'g', '1'):
    case GST_MAKE_FOURCC ('M', 'P', 'G', '1'):
159
    case GST_MAKE_FOURCC ('P', 'I', 'M', '1'):
David Schleef's avatar
David Schleef committed
160
      caps = gst_caps_new_simple ("video/mpeg",
161
          "systemstream", G_TYPE_BOOLEAN, FALSE,
162
          "mpegversion", G_TYPE_INT, 1, NULL);
163
      if (codec_name)
164
        *codec_name = g_strdup ("MPEG-1 video");
165
      break;
166 167 168 169 170 171
    case GST_MAKE_FOURCC ('M', 'P', 'G', '2'):
    case GST_MAKE_FOURCC ('m', 'p', 'g', '2'):
      caps = gst_caps_new_simple ("video/mpeg",
          "systemstream", G_TYPE_BOOLEAN, FALSE,
          "mpegversion", G_TYPE_INT, 2, NULL);
      if (codec_name)
172
        *codec_name = g_strdup ("MPEG-2 video");
173
      break;
174

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
175
    case GST_MAKE_FOURCC ('H', '2', '6', '3'):
176
    case GST_MAKE_FOURCC ('h', '2', '6', '3'):
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
177
    case GST_MAKE_FOURCC ('i', '2', '6', '3'):
178
    case GST_MAKE_FOURCC ('U', '2', '6', '3'):
179 180
      caps = gst_caps_new_simple ("video/x-h263",
          "variant", G_TYPE_STRING, "itu", NULL);
181
      if (codec_name)
182
        *codec_name = g_strdup ("ITU H.26n");
183
      break;
184

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
185
    case GST_MAKE_FOURCC ('L', '2', '6', '3'):
186 187 188
      /* http://www.leadcodecs.com/Codecs/LEAD-H263.htm */
      caps = gst_caps_new_simple ("video/x-h263",
          "variant", G_TYPE_STRING, "lead", NULL);
189
      if (codec_name)
190
        *codec_name = g_strdup ("Lead H.263");
191
      break;
192

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
193
    case GST_MAKE_FOURCC ('M', '2', '6', '3'):
194
    case GST_MAKE_FOURCC ('m', '2', '6', '3'):
195 196
      caps = gst_caps_new_simple ("video/x-h263",
          "variant", G_TYPE_STRING, "microsoft", NULL);
197
      if (codec_name)
198
        *codec_name = g_strdup ("Microsoft H.263");
199
      break;
200

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
201
    case GST_MAKE_FOURCC ('V', 'D', 'O', 'W'):
202 203
      caps = gst_caps_new_simple ("video/x-h263",
          "variant", G_TYPE_STRING, "vdolive", NULL);
204
      if (codec_name)
205
        *codec_name = g_strdup ("VDOLive");
206
      break;
207

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
208
    case GST_MAKE_FOURCC ('V', 'I', 'V', 'O'):
209 210
      caps = gst_caps_new_simple ("video/x-h263",
          "variant", G_TYPE_STRING, "vivo", NULL);
211
      if (codec_name)
212
        *codec_name = g_strdup ("Vivo H.263");
213
      break;
214

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
215
    case GST_MAKE_FOURCC ('x', '2', '6', '3'):
216 217
      caps = gst_caps_new_simple ("video/x-h263",
          "variant", G_TYPE_STRING, "xirlink", NULL);
218
      if (codec_name)
219
        *codec_name = g_strdup ("Xirlink H.263");
220 221
      break;

222 223
      /* apparently not standard H.263...? */
    case GST_MAKE_FOURCC ('I', '2', '6', '3'):
224 225
      caps = gst_caps_new_simple ("video/x-intel-h263",
          "variant", G_TYPE_STRING, "intel", NULL);
226 227 228 229
      if (codec_name)
        *codec_name = g_strdup ("Intel H.263");
      break;

230
    case GST_MAKE_FOURCC ('H', '2', '6', '4'):
231
    case GST_MAKE_FOURCC ('h', '2', '6', '4'):
232 233
      caps = gst_caps_new_simple ("video/x-h264",
          "variant", G_TYPE_STRING, "itu", NULL);
234 235 236 237 238
      if (codec_name)
        *codec_name = g_strdup ("ITU H.264");
      break;

    case GST_MAKE_FOURCC ('V', 'S', 'S', 'H'):
239 240
      caps = gst_caps_new_simple ("video/x-h264",
          "variant", G_TYPE_STRING, "videosoft", NULL);
241 242 243 244
      if (codec_name)
        *codec_name = g_strdup ("VideoSoft H.264");
      break;

245 246 247 248 249 250 251
    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;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
252
    case GST_MAKE_FOURCC ('D', 'I', 'V', '3'):
253
    case GST_MAKE_FOURCC ('d', 'i', 'v', '3'):
254
    case GST_MAKE_FOURCC ('D', 'I', 'V', '4'):
255
    case GST_MAKE_FOURCC ('d', 'i', 'v', '4'):
256
    case GST_MAKE_FOURCC ('D', 'I', 'V', '5'):
257
    case GST_MAKE_FOURCC ('d', 'i', 'v', '5'):
258
    case GST_MAKE_FOURCC ('D', 'I', 'V', '6'):
259
    case GST_MAKE_FOURCC ('d', 'i', 'v', '6'):
260 261 262 263 264 265 266
    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
267
      caps = gst_caps_new_simple ("video/x-divx",
268
          "divxversion", G_TYPE_INT, 3, NULL);
269
      if (codec_name)
270
        *codec_name = g_strdup ("DivX MS-MPEG-4 Version 3");
271
      break;
272

273 274
    case GST_MAKE_FOURCC ('d', 'i', 'v', 'x'):
    case GST_MAKE_FOURCC ('D', 'I', 'V', 'X'):
275
      caps = gst_caps_new_simple ("video/x-divx",
276
          "divxversion", G_TYPE_INT, 4, NULL);
277
      if (codec_name)
278
        *codec_name = g_strdup ("DivX MPEG-4 Version 4");
279
      break;
280

281 282 283 284 285 286 287
    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
288
    case GST_MAKE_FOURCC ('D', 'X', '5', '0'):
David Schleef's avatar
David Schleef committed
289
      caps = gst_caps_new_simple ("video/x-divx",
290
          "divxversion", G_TYPE_INT, 5, NULL);
291
      if (codec_name)
292
        *codec_name = g_strdup ("DivX MPEG-4 Version 5");
293 294
      break;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
295 296
    case GST_MAKE_FOURCC ('X', 'V', 'I', 'D'):
    case GST_MAKE_FOURCC ('x', 'v', 'i', 'd'):
David Schleef's avatar
David Schleef committed
297
      caps = gst_caps_new_simple ("video/x-xvid", NULL);
298
      if (codec_name)
299
        *codec_name = g_strdup ("XVID MPEG-4");
300 301
      break;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
302
    case GST_MAKE_FOURCC ('M', 'P', 'G', '4'):
303
    case GST_MAKE_FOURCC ('M', 'P', '4', 'S'):
David Schleef's avatar
David Schleef committed
304
      caps = gst_caps_new_simple ("video/x-msmpeg",
305
          "msmpegversion", G_TYPE_INT, 41, NULL);
306
      if (codec_name)
307
        *codec_name = g_strdup ("Microsoft MPEG-4 4.1");
308 309
      break;

310
    case GST_MAKE_FOURCC ('m', 'p', '4', '2'):
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
311
    case GST_MAKE_FOURCC ('M', 'P', '4', '2'):
David Schleef's avatar
David Schleef committed
312
      caps = gst_caps_new_simple ("video/x-msmpeg",
313
          "msmpegversion", G_TYPE_INT, 42, NULL);
314
      if (codec_name)
315
        *codec_name = g_strdup ("Microsoft MPEG-4 4.2");
316 317
      break;

318
    case GST_MAKE_FOURCC ('m', 'p', '4', '3'):
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
319
    case GST_MAKE_FOURCC ('M', 'P', '4', '3'):
David Schleef's avatar
David Schleef committed
320
      caps = gst_caps_new_simple ("video/x-msmpeg",
321
          "msmpegversion", G_TYPE_INT, 43, NULL);
322
      if (codec_name)
323
        *codec_name = g_strdup ("Microsoft MPEG-4 4.3");
324 325
      break;

326 327 328 329 330 331 332 333
    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'):
334
    case GST_MAKE_FOURCC ('U', 'M', 'P', '4'):
335 336 337 338 339 340
      caps = gst_caps_new_simple ("video/mpeg",
          "mpegversion", G_TYPE_INT, 4, NULL);
      if (codec_name)
        *codec_name = g_strdup ("FFmpeg MPEG-4");
      break;

341 342 343 344 345 346
    case GST_MAKE_FOURCC ('3', 'i', 'v', 'd'):
    case GST_MAKE_FOURCC ('3', 'I', 'V', 'D'):
      if (codec_name)
        *codec_name = g_strdup ("Microsoft MPEG-4 4.3");        /* FIXME? */
      return gst_caps_from_string ("video/x-msmpeg, msmpegversion = (int) 43");

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
347 348 349
    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);
350
      if (codec_name)
351
        *codec_name = g_strdup ("3ivx");
352 353
      break;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
354 355
    case GST_MAKE_FOURCC ('D', 'V', 'S', 'D'):
    case GST_MAKE_FOURCC ('d', 'v', 's', 'd'):
356
    case GST_MAKE_FOURCC ('C', 'D', 'V', 'C'):
David Schleef's avatar
David Schleef committed
357
      caps = gst_caps_new_simple ("video/x-dv",
358
          "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
359
      if (codec_name)
360
        *codec_name = g_strdup ("Generic DV");
361 362
      break;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
363
    case GST_MAKE_FOURCC ('W', 'M', 'V', '1'):
David Schleef's avatar
David Schleef committed
364
      caps = gst_caps_new_simple ("video/x-wmv",
365
          "wmvversion", G_TYPE_INT, 1, NULL);
366
      if (codec_name)
367
        *codec_name = g_strdup ("Microsoft Windows Media 7");
368 369
      break;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
370
    case GST_MAKE_FOURCC ('W', 'M', 'V', '2'):
David Schleef's avatar
David Schleef committed
371
      caps = gst_caps_new_simple ("video/x-wmv",
372
          "wmvversion", G_TYPE_INT, 2, NULL);
373
      if (codec_name)
374
        *codec_name = g_strdup ("Microsoft Windows Media 8");
375
      break;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
376 377

    case GST_MAKE_FOURCC ('W', 'M', 'V', '3'):
378
      caps = gst_caps_new_simple ("video/x-wmv",
379
          "wmvversion", G_TYPE_INT, 3, NULL);
380
      if (codec_name)
381
        *codec_name = g_strdup ("Microsoft Windows Media 9");
382 383
      break;

384 385 386 387 388 389 390 391
    case GST_MAKE_FOURCC ('W', 'M', 'V', 'A'):
      caps = gst_caps_new_simple ("video/x-wmv",
          "wmvversion", G_TYPE_INT, 3, "fourcc", GST_TYPE_FOURCC,
          codec_fcc, NULL);
      if (codec_name)
        *codec_name = g_strdup ("Microsoft Windows Media Advanced Profile");
      break;

392 393 394 395 396 397
    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;

398 399 400 401 402 403 404 405 406 407
    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");
408 409
      palette = strf_data;
      strf_data = NULL;
410 411
      break;

412 413 414 415 416
    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? */
      caps = gst_caps_new_simple ("video/x-rle",
          "layout", G_TYPE_STRING, "microsoft", NULL);
417 418
      palette = strf_data;
      strf_data = NULL;
419 420 421 422 423 424 425
      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)
426 427 428 429 430 431 432 433
        *codec_name = g_strdup ("Microsoft RLE");
      break;

    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");
434 435
      break;

436 437 438 439 440 441 442 443
    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'):
444
    case GST_MAKE_FOURCC ('I', 'V', '3', '2'):
445 446
    case GST_MAKE_FOURCC ('i', 'v', '3', '1'):
    case GST_MAKE_FOURCC ('i', 'v', '3', '2'):
447 448 449 450 451 452
      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;

453 454 455 456 457 458 459 460
    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;

461
    case GST_MAKE_FOURCC ('I', 'V', '5', '0'):
462 463
      caps = gst_caps_new_simple ("video/x-indeo",
          "indeoversion", G_TYPE_INT, 5, NULL);
464 465 466 467
      if (codec_name)
        *codec_name = g_strdup ("Intel Video 5");
      break;

468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523
    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'):
      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'):
      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'):
524 525
    case GST_MAKE_FOURCC ('t', 's', 'c', 'c'):{
      if (strf) {
526
        gint depth = (strf->bit_cnt != 0) ? (gint) strf->bit_cnt : 24;
527

528 529
        caps = gst_caps_new_simple ("video/x-camtasia", "depth", G_TYPE_INT,
            depth, NULL);
530 531 532 533
      } else {
        /* template caps */
        caps = gst_caps_new_simple ("video/x-camtasia", NULL);
      }
534 535 536
      if (codec_name)
        *codec_name = g_strdup ("TechSmith Camtasia");
      break;
537
    }
538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574

    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;

575 576 577 578 579 580 581
    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;

582 583 584 585 586 587 588
    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;

589 590 591 592 593 594
    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;

595
    default:
596
      GST_WARNING ("Unknown video fourcc %" GST_FOURCC_FORMAT,
597
          GST_FOURCC_ARGS (codec_fcc));
David Schleef's avatar
David Schleef committed
598
      return NULL;
599 600
  }

David Schleef's avatar
David Schleef committed
601
  if (strh != NULL) {
602 603
    gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION,
        strh->rate, strh->scale, NULL);
David Schleef's avatar
David Schleef committed
604 605
  } else {
    gst_caps_set_simple (caps,
606
        "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
David Schleef's avatar
David Schleef committed
607 608 609 610
  }

  if (strf != NULL) {
    gst_caps_set_simple (caps,
611 612
        "width", G_TYPE_INT, strf->width,
        "height", G_TYPE_INT, strf->height, NULL);
David Schleef's avatar
David Schleef committed
613 614
  } else {
    gst_caps_set_simple (caps,
615 616
        "width", GST_TYPE_INT_RANGE, 16, 4096,
        "height", GST_TYPE_INT_RANGE, 16, 4096, NULL);
617 618
  }

619 620 621 622 623 624
  /* extradata */
  if (strf_data || strd_data) {
    gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER,
        strf_data ? strf_data : strd_data, NULL);
  }

625
  /* palette */
626 627 628 629 630 631 632 633 634
  if (palette) {
    GstBuffer *copy;
    guint num_colors;

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

635 636
    if (GST_BUFFER_SIZE (palette) >= (num_colors * 4)) {
      /* palette is always at least 256*4 bytes */
637 638
      copy =
          gst_buffer_new_and_alloc (MAX (GST_BUFFER_SIZE (palette), 256 * 4));
639 640
      memcpy (GST_BUFFER_DATA (copy), GST_BUFFER_DATA (palette),
          GST_BUFFER_SIZE (palette));
641 642

#if (G_BYTE_ORDER == G_BIG_ENDIAN)
643 644 645 646 647 648 649 650 651 652
      {
        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);
        }
      }
653
#endif
654 655 656 657 658
      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");
    }
659 660
  }

661 662 663
  return caps;
}

664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 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 738 739 740 741 742
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);

  if (num_channels < 2 || num_channels > MAX_CHANNEL_POSITIONS) {
    GST_DEBUG ("invalid number of channels: %d", num_channels);
    return FALSE;
  }

  p = 0;
  for (i = 0; i < MAX_CHANNEL_POSITIONS; ++i) {
    if ((layout & layout_mapping[i].ms_mask) != 0) {
      if (p >= num_channels) {
        GST_WARNING ("More bits set in the channel layout map than there "
            "are channels! Broken file");
        return FALSE;
      }
      if (layout_mapping[i].gst_pos == GST_AUDIO_CHANNEL_POSITION_INVALID) {
        GST_WARNING ("Unsupported channel position (mask 0x%08x) in channel "
            "layout map - ignoring those channels", layout_mapping[i].ms_mask);
        /* what to do? just ignore it and let downstream deal with a channel
         * layout that has INVALID positions in it for now ... */
      }
      pos[p] = layout_mapping[i].gst_pos;
      ++p;
    }
  }

  if (p != num_channels) {
    GST_WARNING ("Only %d bits set in the channel layout map, but there are "
        "supposed to be %d channels! Broken file", p, num_channels);
    return FALSE;
  }

  gst_audio_set_channel_positions (s, pos);
  return TRUE;
}

743
GstCaps *
744
gst_riff_create_audio_caps (guint16 codec_id,
745 746
    gst_riff_strh * strh, gst_riff_strf_auds * strf,
    GstBuffer * strf_data, GstBuffer * strd_data, char **codec_name)
747
{
748
  gboolean block_align = FALSE, rate_chan = TRUE;
749
  GstCaps *caps = NULL;
750
  gint rate_min = 1000, rate_max = 96000;
751
  gint channels_max = 2;
752 753

  switch (codec_id) {
754
    case GST_RIFF_WAVE_FORMAT_PCM:     /* PCM */
755
      if (strf != NULL) {
756 757 758
        gint ba = strf->blockalign;
        gint ch = strf->channels;
        gint ws = strf->size;
759
        gint wd = ba * 8 / ch;
760

761 762 763
        caps = gst_caps_new_simple ("audio/x-raw-int",
            "endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
            "channels", G_TYPE_INT, ch,
764 765
            "width", G_TYPE_INT, wd,
            "depth", G_TYPE_INT, ws, "signed", G_TYPE_BOOLEAN, wd != 8, NULL);
766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794

        /* Add default MS channel layout if we have more than 2 channels,
         * but the layout isn't specified like with WAVEEXT below. Not sure
         * if this is right, but at least it makes sound output work at all
         * in those cases. Somebody with a a 5.1 setup should double-check
         * with chan-id.wav */
        if (ch > 2) {
          guint32 channel_mask;

          switch (ch) {
            case 4:
              channel_mask = 0x33;
              break;
            case 6:
              channel_mask = 0x3f;
              break;
            default:
              GST_WARNING ("don't know default layout for %d channels", ch);
              channel_mask = 0;
              break;
          }

          if (channel_mask) {
            GST_DEBUG ("using default channel layout for %d channels", ch);
            if (!gst_riff_wavext_add_channel_layout (caps, channel_mask)) {
              GST_WARNING ("failed to add channel layout");
            }
          }
        }
795
      } else {
796
        /* FIXME: this is pretty useless - we need fixed caps */
797 798 799
        caps = gst_caps_from_string ("audio/x-raw-int, "
            "endianness = (int) LITTLE_ENDIAN, "
            "signed = (boolean) { true, false }, "
800 801
            "width = (int) { 8, 16, 24, 32 }, "
            "depth = (int) { 8, 16, 24, 32 }");
802
      }
803 804 805
      if (codec_name && strf)
        *codec_name = g_strdup_printf ("Uncompressed %d-bit PCM audio",
            strf->size);
806 807
      break;

808 809 810 811 812
    case GST_RIFF_WAVE_FORMAT_ADPCM:
      caps = gst_caps_new_simple ("audio/x-adpcm",
          "layout", G_TYPE_STRING, "microsoft", NULL);
      if (codec_name)
        *codec_name = g_strdup ("ADPCM audio");
813 814 815
      block_align = TRUE;
      break;

816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839
    case GST_RIFF_WAVE_FORMAT_IBM_CVSD:
      goto unknown;

    case GST_RIFF_WAVE_FORMAT_ALAW:
      if (strf != NULL) {
        if (strf->size != 8) {
          GST_WARNING ("invalid depth (%d) of alaw audio, overwriting.",
              strf->size);
          strf->size = 8;
          strf->av_bps = 8;
          strf->blockalign = strf->av_bps * strf->channels;
        }
        if (strf->av_bps == 0 || strf->blockalign == 0) {
          GST_WARNING ("fixing av_bps (%d) and blockalign (%d) of alaw audio",
              strf->av_bps, strf->blockalign);
          strf->av_bps = strf->size;
          strf->blockalign = strf->av_bps * strf->channels;
        }
      }
      caps = gst_caps_new_simple ("audio/x-alaw", NULL);
      if (codec_name)
        *codec_name = g_strdup ("A-law audio");
      break;

840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855
    case GST_RIFF_WAVE_FORMAT_WMS:
      caps = gst_caps_new_simple ("audio/x-wms", NULL);
      if (strf != NULL) {
        gst_caps_set_simple (caps,
            "bitrate", G_TYPE_INT, strf->av_bps * 8,
            "width", G_TYPE_INT, strf->size,
            "depth", G_TYPE_INT, strf->size, NULL);
      } else {
        gst_caps_set_simple (caps,
            "bitrate", GST_TYPE_INT_RANGE, 0, G_MAXINT, NULL);
      }
      if (codec_name)
        *codec_name = g_strdup ("Windows Media Audio Speech");
      block_align = TRUE;
      break;

856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879
    case GST_RIFF_WAVE_FORMAT_MULAW:
      if (strf != NULL) {
        if (strf->size != 8) {
          GST_WARNING ("invalid depth (%d) of mulaw audio, overwriting.",
              strf->size);
          strf->size = 8;
          strf->av_bps = 8;
          strf->blockalign = strf->av_bps * strf->channels;
        }
        if (strf->av_bps == 0 || strf->blockalign == 0) {
          GST_WARNING ("fixing av_bps (%d) and blockalign (%d) of mulaw audio",
              strf->av_bps, strf->blockalign);
          strf->av_bps = strf->size;
          strf->blockalign = strf->av_bps * strf->channels;
        }
      }
      caps = gst_caps_new_simple ("audio/x-mulaw", NULL);
      if (codec_name)
        *codec_name = g_strdup ("Mu-law audio");
      break;

    case GST_RIFF_WAVE_FORMAT_OKI_ADPCM:
      goto unknown;

880 881 882 883 884 885
    case GST_RIFF_WAVE_FORMAT_DVI_ADPCM:
      caps = gst_caps_new_simple ("audio/x-adpcm",
          "layout", G_TYPE_STRING, "dvi", NULL);
      if (codec_name)
        *codec_name = g_strdup ("DVI ADPCM audio");
      block_align = TRUE;
886 887
      break;

888 889 890
    case GST_RIFF_WAVE_FORMAT_GSM610:
    case GST_RIFF_WAVE_FORMAT_MSN:
      caps = gst_caps_new_simple ("audio/ms-gsm", NULL);
891
      if (codec_name)
892
        *codec_name = g_strdup ("MS GSM audio");
893 894
      break;

895 896 897
    case GST_RIFF_WAVE_FORMAT_MPEGL12: /* mp1 or mp2 */
      caps = gst_caps_new_simple ("audio/mpeg",
          "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 2, NULL);
898
      if (codec_name)
899 900 901 902 903 904 905 906
        *codec_name = g_strdup ("MPEG-1 layer 2");
      break;

    case GST_RIFF_WAVE_FORMAT_MPEGL3:  /* mp3 */
      caps = gst_caps_new_simple ("audio/mpeg",
          "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 3, NULL);
      if (codec_name)
        *codec_name = g_strdup ("MPEG-1 layer 3");
907 908
      break;

909 910 911 912 913 914
    case GST_RIFF_WAVE_FORMAT_VORBIS1: /* ogg/vorbis mode 1 */
    case GST_RIFF_WAVE_FORMAT_VORBIS2: /* ogg/vorbis mode 2 */
    case GST_RIFF_WAVE_FORMAT_VORBIS3: /* ogg/vorbis mode 3 */
    case GST_RIFF_WAVE_FORMAT_VORBIS1PLUS:     /* ogg/vorbis mode 1+ */
    case GST_RIFF_WAVE_FORMAT_VORBIS2PLUS:     /* ogg/vorbis mode 2+ */
    case GST_RIFF_WAVE_FORMAT_VORBIS3PLUS:     /* ogg/vorbis mode 3+ */
David Schleef's avatar
David Schleef committed
915
      caps = gst_caps_new_simple ("audio/x-vorbis", NULL);
916
      if (codec_name)
917
        *codec_name = g_strdup ("Vorbis");
918 919 920
      break;

    case GST_RIFF_WAVE_FORMAT_A52:
921
      channels_max = 6;
David Schleef's avatar
David Schleef committed
922
      caps = gst_caps_new_simple ("audio/x-ac3", NULL);
923
      if (codec_name)
924
        *codec_name = g_strdup ("AC-3 audio");
925
      break;
926 927 928 929 930 931
    case GST_RIFF_WAVE_FORMAT_DTS:
      channels_max = 6;
      caps = gst_caps_new_simple ("audio/x-dts", NULL);
      if (codec_name)
        *codec_name = g_strdup ("DTS audio");
      break;
932 933 934 935 936 937 938 939 940
    case GST_RIFF_WAVE_FORMAT_AAC:
    {
      channels_max = 8;
      caps = gst_caps_new_simple ("audio/mpeg",
          "mpegversion", G_TYPE_INT, 4, NULL);
      if (codec_name)
        *codec_name = g_strdup ("MPEG-4 AAC audio");
      break;
    }
941 942
    case GST_RIFF_WAVE_FORMAT_WMAV1:
    case GST_RIFF_WAVE_FORMAT_WMAV2:
943
    case GST_RIFF_WAVE_FORMAT_WMAV3:
944
    {
945
      gint version = (codec_id - GST_RIFF_WAVE_FORMAT_WMAV1) + 1;
946

947
      channels_max = 6;
948 949 950 951 952 953
      block_align = TRUE;

      caps = gst_caps_new_simple ("audio/x-wma",
          "wmaversion", G_TYPE_INT, version, NULL);

      if (codec_name)
954
        *codec_name = g_strdup_printf ("WMA Version %d", version + 6);
955

956 957
      if (strf != NULL) {
        gst_caps_set_simple (caps,
Fabrizio's avatar
Fabrizio committed
958 959
            "bitrate", G_TYPE_INT, strf->av_bps * 8,
            "depth", G_TYPE_INT, strf->size, NULL);
960 961 962 963 964 965
      } else {
        gst_caps_set_simple (caps,
            "bitrate", GST_TYPE_INT_RANGE, 0, G_MAXINT, NULL);
      }
      break;
    }
Young-Ho Cha's avatar