riff-media.c 23.1 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
36
37
38
39
40
41
42
/**
 * 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.
 */

43
GstCaps *
44
gst_riff_create_video_caps (guint32 codec_fcc,
45
46
    gst_riff_strh * strh, gst_riff_strf_vids * strf,
    GstBuffer * strf_data, GstBuffer * strd_data, char **codec_name)
47
48
{
  GstCaps *caps = NULL;
49
  GstBuffer *palette = NULL;
50
51

  switch (codec_fcc) {
52
53
54
55
56
57
58
59
60
61
    case GST_MAKE_FOURCC ('D', 'I', 'B', ' '):
      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);
      palette = strf_data;
      strf_data = NULL;
      if (codec_name)
        *codec_name = g_strdup ("Palettized 8-bit RGB");
      break;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
62
    case GST_MAKE_FOURCC ('I', '4', '2', '0'):
63
      caps = gst_caps_new_simple ("video/x-raw-yuv",
64
          "format", GST_TYPE_FOURCC, codec_fcc, NULL);
65
      if (codec_name)
66
        *codec_name = g_strdup ("Uncompressed planar YUV 4:2:0");
67
      break;
68

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
69
    case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
David Schleef's avatar
David Schleef committed
70
      caps = gst_caps_new_simple ("video/x-raw-yuv",
71
          "format", GST_TYPE_FOURCC, codec_fcc, NULL);
72
      if (codec_name)
73
        *codec_name = g_strdup ("Uncompressed packed YUV 4:2:2");
74
75
      break;

76
    case GST_MAKE_FOURCC ('M', 'J', 'P', 'G'): /* YUY2 MJPEG */
77
      caps = gst_caps_new_simple ("image/jpeg", NULL);
78
      if (codec_name)
79
        *codec_name = g_strdup ("Motion JPEG");
80
      break;
81

82
    case GST_MAKE_FOURCC ('J', 'P', 'E', 'G'): /* generic (mostly RGB) MJPEG */
83
      caps = gst_caps_new_simple ("image/jpeg", NULL);
84
      if (codec_name)
85
        *codec_name = g_strdup ("JPEG Still Image");
86
      break;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
87

88
89
    case GST_MAKE_FOURCC ('P', 'I', 'X', 'L'): /* Miro/Pinnacle fourccs */
    case GST_MAKE_FOURCC ('V', 'I', 'X', 'L'): /* Miro/Pinnacle fourccs */
90
      caps = gst_caps_new_simple ("image/jpeg", NULL);
91
      if (codec_name)
92
        *codec_name = g_strdup ("Miro/Pinnacle Motion JPEG Video");
93
      break;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
94
95
96

    case GST_MAKE_FOURCC ('H', 'F', 'Y', 'U'):
      caps = gst_caps_new_simple ("video/x-huffyuv", NULL);
97
98
99
100
      if (strf) {
        gst_caps_set_simple (caps, "bpp",
            G_TYPE_INT, (int) strf->bit_cnt, NULL);
      }
101
      if (codec_name)
102
        *codec_name = g_strdup ("Huffman Lossless Codec");
103
      break;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
104
105
106

    case GST_MAKE_FOURCC ('M', 'P', 'E', 'G'):
    case GST_MAKE_FOURCC ('M', 'P', 'G', 'I'):
107
108
    case GST_MAKE_FOURCC ('m', 'p', 'g', '1'):
    case GST_MAKE_FOURCC ('M', 'P', 'G', '1'):
David Schleef's avatar
David Schleef committed
109
      caps = gst_caps_new_simple ("video/mpeg",
110
          "systemstream", G_TYPE_BOOLEAN, FALSE,
111
          "mpegversion", G_TYPE_INT, 1, NULL);
112
      if (codec_name)
113
        *codec_name = g_strdup ("MPEG-1 video");
114
      break;
115
116
117
118
119
120
    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)
121
        *codec_name = g_strdup ("MPEG-2 video");
122
      break;
123

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
124
    case GST_MAKE_FOURCC ('H', '2', '6', '3'):
125
126
      caps = gst_caps_new_simple ("video/x-h263", NULL);
      if (codec_name)
127
        *codec_name = g_strdup ("ITU H.26n");
128
      break;
129

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
130
    case GST_MAKE_FOURCC ('i', '2', '6', '3'):
131
132
      caps = gst_caps_new_simple ("video/x-h263", NULL);
      if (codec_name)
133
        *codec_name = g_strdup ("ITU H.263");
134
      break;
135

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
136
    case GST_MAKE_FOURCC ('L', '2', '6', '3'):
137
138
      caps = gst_caps_new_simple ("video/x-h263", NULL);
      if (codec_name)
139
        *codec_name = g_strdup ("Lead H.263");
140
      break;
141

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
142
    case GST_MAKE_FOURCC ('M', '2', '6', '3'):
143
    case GST_MAKE_FOURCC ('m', '2', '6', '3'):
144
145
      caps = gst_caps_new_simple ("video/x-h263", NULL);
      if (codec_name)
146
        *codec_name = g_strdup ("Microsoft H.263");
147
      break;
148

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
149
    case GST_MAKE_FOURCC ('V', 'D', 'O', 'W'):
150
151
      caps = gst_caps_new_simple ("video/x-h263", NULL);
      if (codec_name)
152
        *codec_name = g_strdup ("VDOLive");
153
      break;
154

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
155
    case GST_MAKE_FOURCC ('V', 'I', 'V', 'O'):
156
157
      caps = gst_caps_new_simple ("video/x-h263", NULL);
      if (codec_name)
158
        *codec_name = g_strdup ("Vivo H.263");
159
      break;
160

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
161
    case GST_MAKE_FOURCC ('x', '2', '6', '3'):
David Schleef's avatar
David Schleef committed
162
      caps = gst_caps_new_simple ("video/x-h263", NULL);
163
      if (codec_name)
164
        *codec_name = g_strdup ("Xirlink H.263");
165
166
      break;

167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
      /* apparently not standard H.263...? */
    case GST_MAKE_FOURCC ('I', '2', '6', '3'):
      caps = gst_caps_new_simple ("video/x-intel-h263", NULL);
      if (codec_name)
        *codec_name = g_strdup ("Intel H.263");
      break;

    case GST_MAKE_FOURCC ('h', '2', '6', '4'):
      caps = gst_caps_new_simple ("video/x-h264", NULL);
      if (codec_name)
        *codec_name = g_strdup ("ITU H.264");
      break;

    case GST_MAKE_FOURCC ('V', 'S', 'S', 'H'):
      caps = gst_caps_new_simple ("video/x-h264", NULL);
      if (codec_name)
        *codec_name = g_strdup ("VideoSoft H.264");
      break;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
186
    case GST_MAKE_FOURCC ('D', 'I', 'V', '3'):
187
    case GST_MAKE_FOURCC ('d', 'i', 'v', '3'):
188
    case GST_MAKE_FOURCC ('D', 'I', 'V', '4'):
189
    case GST_MAKE_FOURCC ('d', 'i', 'v', '4'):
190
    case GST_MAKE_FOURCC ('D', 'I', 'V', '5'):
191
    case GST_MAKE_FOURCC ('d', 'i', 'v', '5'):
192
    case GST_MAKE_FOURCC ('D', 'I', 'V', '6'):
193
    case GST_MAKE_FOURCC ('d', 'i', 'v', '6'):
David Schleef's avatar
David Schleef committed
194
      caps = gst_caps_new_simple ("video/x-divx",
195
          "divxversion", G_TYPE_INT, 3, NULL);
196
      if (codec_name)
197
        *codec_name = g_strdup ("DivX MS-MPEG-4 Version 3");
198
      break;
199

200
201
    case GST_MAKE_FOURCC ('d', 'i', 'v', 'x'):
    case GST_MAKE_FOURCC ('D', 'I', 'V', 'X'):
202
      caps = gst_caps_new_simple ("video/x-divx",
203
          "divxversion", G_TYPE_INT, 4, NULL);
204
      if (codec_name)
205
        *codec_name = g_strdup ("DivX MPEG-4 Version 4");
206
      break;
207

208
209
210
211
212
213
214
    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
215
    case GST_MAKE_FOURCC ('D', 'X', '5', '0'):
David Schleef's avatar
David Schleef committed
216
      caps = gst_caps_new_simple ("video/x-divx",
217
          "divxversion", G_TYPE_INT, 5, NULL);
218
      if (codec_name)
219
        *codec_name = g_strdup ("DivX MPEG-4 Version 5");
220
221
      break;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
222
223
    case GST_MAKE_FOURCC ('X', 'V', 'I', 'D'):
    case GST_MAKE_FOURCC ('x', 'v', 'i', 'd'):
David Schleef's avatar
David Schleef committed
224
      caps = gst_caps_new_simple ("video/x-xvid", NULL);
225
      if (codec_name)
226
        *codec_name = g_strdup ("XVID MPEG-4");
227
228
      break;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
229
    case GST_MAKE_FOURCC ('M', 'P', 'G', '4'):
230
    case GST_MAKE_FOURCC ('M', 'P', '4', 'S'):
David Schleef's avatar
David Schleef committed
231
      caps = gst_caps_new_simple ("video/x-msmpeg",
232
          "msmpegversion", G_TYPE_INT, 41, NULL);
233
      if (codec_name)
234
        *codec_name = g_strdup ("Microsoft MPEG-4 4.1");
235
236
      break;

237
    case GST_MAKE_FOURCC ('m', 'p', '4', '2'):
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
238
    case GST_MAKE_FOURCC ('M', 'P', '4', '2'):
David Schleef's avatar
David Schleef committed
239
      caps = gst_caps_new_simple ("video/x-msmpeg",
240
          "msmpegversion", G_TYPE_INT, 42, NULL);
241
      if (codec_name)
242
        *codec_name = g_strdup ("Microsoft MPEG-4 4.2");
243
244
      break;

245
    case GST_MAKE_FOURCC ('m', 'p', '4', '3'):
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
246
    case GST_MAKE_FOURCC ('M', 'P', '4', '3'):
David Schleef's avatar
David Schleef committed
247
      caps = gst_caps_new_simple ("video/x-msmpeg",
248
          "msmpegversion", G_TYPE_INT, 43, NULL);
249
      if (codec_name)
250
        *codec_name = g_strdup ("Microsoft MPEG-4 4.3");
251
252
      break;

253
254
255
256
257
258
259
260
261
262
263
264
265
266
    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'):
      caps = gst_caps_new_simple ("video/mpeg",
          "mpegversion", G_TYPE_INT, 4, NULL);
      if (codec_name)
        *codec_name = g_strdup ("FFmpeg MPEG-4");
      break;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
267
268
269
    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);
270
      if (codec_name)
271
        *codec_name = g_strdup ("3ivx");
272
273
      break;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
274
275
    case GST_MAKE_FOURCC ('D', 'V', 'S', 'D'):
    case GST_MAKE_FOURCC ('d', 'v', 's', 'd'):
David Schleef's avatar
David Schleef committed
276
      caps = gst_caps_new_simple ("video/x-dv",
277
          "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
278
      if (codec_name)
279
        *codec_name = g_strdup ("Generic DV");
280
281
      break;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
282
    case GST_MAKE_FOURCC ('W', 'M', 'V', '1'):
David Schleef's avatar
David Schleef committed
283
      caps = gst_caps_new_simple ("video/x-wmv",
284
          "wmvversion", G_TYPE_INT, 1, NULL);
285
      if (codec_name)
286
        *codec_name = g_strdup ("Microsoft Windows Media 7");
287
288
      break;

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
289
    case GST_MAKE_FOURCC ('W', 'M', 'V', '2'):
David Schleef's avatar
David Schleef committed
290
      caps = gst_caps_new_simple ("video/x-wmv",
291
          "wmvversion", G_TYPE_INT, 2, NULL);
292
      if (codec_name)
293
        *codec_name = g_strdup ("Microsoft Windows Media 8");
294
      break;
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
295
296

    case GST_MAKE_FOURCC ('W', 'M', 'V', '3'):
297
      caps = gst_caps_new_simple ("video/x-wmv",
298
          "wmvversion", G_TYPE_INT, 3, NULL);
299
      if (codec_name)
300
        *codec_name = g_strdup ("Microsoft Windows Media 9");
301
302
      break;

303
304
305
306
307
308
    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;

309
310
311
312
313
314
315
316
317
318
319
320
    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");
      break;

321
322
323
324
325
    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);
326
327
      palette = strf_data;
      strf_data = NULL;
328
329
330
331
332
333
334
      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)
335
336
337
338
339
340
341
342
        *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");
343
344
      break;

345
346
347
348
349
350
351
    case GST_MAKE_FOURCC ('I', 'V', '3', '2'):
      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;

352
353
354
355
356
357
358
    case GST_MAKE_FOURCC ('I', 'V', '5', '0'):
      caps = gst_caps_new_simple ("video/x-intel",
          "ivversion", G_TYPE_INT, 5, NULL);
      if (codec_name)
        *codec_name = g_strdup ("Intel Video 5");
      break;

359
    default:
360
      GST_WARNING ("Unknown video fourcc %" GST_FOURCC_FORMAT,
361
          GST_FOURCC_ARGS (codec_fcc));
David Schleef's avatar
David Schleef committed
362
      return NULL;
363
364
  }

David Schleef's avatar
David Schleef committed
365
  if (strh != NULL) {
366
    gdouble fps = 1. * strh->rate / strh->scale;
David Schleef's avatar
David Schleef committed
367
368
369
370

    gst_caps_set_simple (caps, "framerate", G_TYPE_DOUBLE, fps, NULL);
  } else {
    gst_caps_set_simple (caps,
371
        "framerate", GST_TYPE_DOUBLE_RANGE, 0., G_MAXDOUBLE, NULL);
David Schleef's avatar
David Schleef committed
372
373
374
375
  }

  if (strf != NULL) {
    gst_caps_set_simple (caps,
376
377
        "width", G_TYPE_INT, strf->width,
        "height", G_TYPE_INT, strf->height, NULL);
David Schleef's avatar
David Schleef committed
378
379
  } else {
    gst_caps_set_simple (caps,
380
381
        "width", GST_TYPE_INT_RANGE, 16, 4096,
        "height", GST_TYPE_INT_RANGE, 16, 4096, NULL);
382
383
  }

384
385
386
387
388
389
  /* extradata */
  if (strf_data || strd_data) {
    gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER,
        strf_data ? strf_data : strd_data, NULL);
  }

390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
  /* palette */
  if (palette && GST_BUFFER_SIZE (palette) >= 256 * 4) {
    GstBuffer *copy = gst_buffer_copy (palette);

#if (G_BYTE_ORDER == G_BIG_ENDIAN)
    gint n;
    guint32 *data = (guint32 *) GST_BUFFER_DATA (copy);

    /* own endianness */
    for (n = 0; n < 256; n++)
      data[n] = GUINT32_FROM_LE (data[n]);
#endif
    gst_caps_set_simple (caps, "palette_data", GST_TYPE_BUFFER, copy, NULL);
    gst_buffer_unref (copy);
  }

406
407
408
  return caps;
}

409
GstCaps *
410
gst_riff_create_audio_caps (guint16 codec_id,
411
412
    gst_riff_strh * strh, gst_riff_strf_auds * strf,
    GstBuffer * strf_data, GstBuffer * strd_data, char **codec_name)
413
{
414
  gboolean block_align = FALSE, rate_chan = TRUE;
415
  GstCaps *caps = NULL;
416
  gint rate_min = 1000, rate_max = 96000;
417
  gint channels_max = 2;
418
419

  switch (codec_id) {
420
    case GST_RIFF_WAVE_FORMAT_MPEGL3:  /* mp3 */
David Schleef's avatar
David Schleef committed
421
      caps = gst_caps_new_simple ("audio/mpeg",
422
          "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 3, NULL);
423
      if (codec_name)
424
        *codec_name = g_strdup ("MPEG-1 layer 3");
425
426
      break;

427
    case GST_RIFF_WAVE_FORMAT_MPEGL12: /* mp1 or mp2 */
David Schleef's avatar
David Schleef committed
428
      caps = gst_caps_new_simple ("audio/mpeg",
429
          "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 2, NULL);
430
      if (codec_name)
431
        *codec_name = g_strdup ("MPEG-1 layer 2");
432
433
      break;

434
    case GST_RIFF_WAVE_FORMAT_PCM:     /* PCM */
435
      if (strf != NULL) {
436
437
438
        gint ba = strf->blockalign;
        gint ch = strf->channels;
        gint ws = strf->size;
439
440
441
442
443

        caps = gst_caps_new_simple ("audio/x-raw-int",
            "endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
            "width", G_TYPE_INT, (int) (ba * 8 / ch),
            "depth", G_TYPE_INT, ws, "signed", G_TYPE_BOOLEAN, ws != 8, NULL);
444
      } else {
445
446
447
        caps = gst_caps_from_string ("audio/x-raw-int, "
            "endianness = (int) LITTLE_ENDIAN, "
            "signed = (boolean) { true, false }, "
448
449
            "width = (int) { 8, 16, 24, 32 }, "
            "depth = (int) { 8, 16, 24, 32 }");
450
      }
451
452
453
      if (codec_name && strf)
        *codec_name = g_strdup_printf ("Uncompressed %d-bit PCM audio",
            strf->size);
454
455
      break;

456
457
458
459
460
    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");
461
462
463
464
465
466
467
468
469
      block_align = TRUE;
      break;

    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;
470
471
      break;

472
473
    case GST_RIFF_WAVE_FORMAT_MULAW:
      if (strf != NULL && strf->size != 8) {
474
475
        GST_WARNING ("invalid depth (%d) of mulaw audio, overwriting.",
            strf->size);
476
477
478
479
480
481
482
483
484
        strf->size = 8;
        strf->av_bps = 8;
        strf->blockalign = strf->av_bps * strf->channels;
      }
      if (strf != NULL && (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;
485
      }
David Schleef's avatar
David Schleef committed
486
      caps = gst_caps_new_simple ("audio/x-mulaw", NULL);
487
      if (codec_name)
488
        *codec_name = g_strdup ("Mu-law audio");
489
490
491
492
      break;

    case GST_RIFF_WAVE_FORMAT_ALAW:
      if (strf != NULL && strf->size != 8) {
493
494
        GST_WARNING ("invalid depth (%d) of alaw audio, overwriting.",
            strf->size);
495
496
497
498
499
500
501
502
503
        strf->size = 8;
        strf->av_bps = 8;
        strf->blockalign = strf->av_bps * strf->channels;
      }
      if (strf != NULL && (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;
504
      }
David Schleef's avatar
David Schleef committed
505
      caps = gst_caps_new_simple ("audio/x-alaw", NULL);
506
      if (codec_name)
507
        *codec_name = g_strdup ("A-law audio");
508
509
      break;

510
511
512
513
514
515
    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
516
      caps = gst_caps_new_simple ("audio/x-vorbis", NULL);
517
      if (codec_name)
518
        *codec_name = g_strdup ("Vorbis");
519
520
521
      break;

    case GST_RIFF_WAVE_FORMAT_A52:
522
      channels_max = 6;
David Schleef's avatar
David Schleef committed
523
      caps = gst_caps_new_simple ("audio/x-ac3", NULL);
524
      if (codec_name)
525
        *codec_name = g_strdup ("AC-3 audio");
526
      break;
527
528
    case GST_RIFF_WAVE_FORMAT_WMAV1:
    case GST_RIFF_WAVE_FORMAT_WMAV2:
529
    case GST_RIFF_WAVE_FORMAT_WMAV3:
530
    {
531
      gint version = (codec_id - GST_RIFF_WAVE_FORMAT_WMAV1) + 1;
532

533
534
      channels_max = 6;

535
536
537
538
539
540
      block_align = TRUE;

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

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

543
544
545
546
547
548
549
550
551
      if (strf != NULL) {
        gst_caps_set_simple (caps,
            "bitrate", G_TYPE_INT, strf->av_bps * 8, NULL);
      } else {
        gst_caps_set_simple (caps,
            "bitrate", GST_TYPE_INT_RANGE, 0, G_MAXINT, NULL);
      }
      break;
    }
552
553
554
555
556
557
    case GST_RIFF_WAVE_FORMAT_SONY_ATRAC3:
      caps = gst_caps_new_simple ("audio/x-vnd.sony.atrac3", NULL);
      if (codec_name)
        *codec_name = g_strdup ("Sony ATRAC3");
      break;

558
    default:
559
      GST_WARNING ("Unknown audio tag 0x%04x", codec_id);
Benjamin Otte's avatar
Benjamin Otte committed
560
      return NULL;
561
562
  }

David Schleef's avatar
David Schleef committed
563
  if (strf != NULL) {
564
565
566
567
568
569
    if (rate_chan) {
      gst_caps_set_simple (caps,
          "rate", G_TYPE_INT, strf->rate,
          "channels", G_TYPE_INT, strf->channels, NULL);
    }
    if (block_align) {
570
571
      gst_caps_set_simple (caps,
          "block_align", G_TYPE_INT, strf->blockalign, NULL);
572
    }
David Schleef's avatar
David Schleef committed
573
  } else {
574
575
576
577
578
579
    if (rate_chan) {
      gst_caps_set_simple (caps,
          "rate", GST_TYPE_INT_RANGE, rate_min, rate_max,
          "channels", GST_TYPE_INT_RANGE, 1, channels_max, NULL);
    }
    if (block_align) {
580
      gst_caps_set_simple (caps,
581
          "block_align", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
582
    }
583
584
  }

585
586
587
588
589
590
  /* extradata */
  if (strf_data || strd_data) {
    gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER,
        strf_data ? strf_data : strd_data, NULL);
  }

591
592
593
594
  return caps;
}

GstCaps *
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
595
gst_riff_create_iavs_caps (guint32 codec_fcc,
596
597
    gst_riff_strh * strh, gst_riff_strf_iavs * strf,
    GstBuffer * init_data, GstBuffer * extra_data, char **codec_name)
598
599
600
601
{
  GstCaps *caps = NULL;

  switch (codec_fcc) {
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
602
603
604
605
      /* is this correct? */
    case GST_MAKE_FOURCC ('D', 'V', 'S', 'D'):
    case GST_MAKE_FOURCC ('d', 'v', 's', 'd'):
      caps = gst_caps_new_simple ("video/x-dv",
606
          "systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
607
      if (codec_name)
608
        *codec_name = g_strdup ("Generic DV");
609
      break;
610
611

    default:
612
      GST_WARNING ("Unknown IAVS fourcc %" GST_FOURCC_FORMAT,
613
          GST_FOURCC_ARGS (codec_fcc));
David Schleef's avatar
David Schleef committed
614
      return NULL;
615
616
617
618
619
620
621
622
623
624
625
626
627
  }

  return caps;
}

/*
 * Functions below are for template caps. All is variable.
 */

GstCaps *
gst_riff_create_video_template_caps (void)
{
  guint32 tags[] = {
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
628
629
630
631
632
633
    GST_MAKE_FOURCC ('I', '4', '2', '0'),
    GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'),
    GST_MAKE_FOURCC ('M', 'J', 'P', 'G'),
    GST_MAKE_FOURCC ('D', 'V', 'S', 'D'),
    GST_MAKE_FOURCC ('W', 'M', 'V', '1'),
    GST_MAKE_FOURCC ('W', 'M', 'V', '2'),
634
    GST_MAKE_FOURCC ('W', 'M', 'V', '3'),
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
635
636
637
638
639
640
641
    GST_MAKE_FOURCC ('M', 'P', 'G', '4'),
    GST_MAKE_FOURCC ('M', 'P', '4', '2'),
    GST_MAKE_FOURCC ('M', 'P', '4', '3'),
    GST_MAKE_FOURCC ('H', 'F', 'Y', 'U'),
    GST_MAKE_FOURCC ('D', 'I', 'V', '3'),
    GST_MAKE_FOURCC ('M', 'P', 'E', 'G'),
    GST_MAKE_FOURCC ('H', '2', '6', '3'),
642
643
    GST_MAKE_FOURCC ('I', '2', '6', '3'),
    GST_MAKE_FOURCC ('h', '2', '6', '4'),
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
644
    GST_MAKE_FOURCC ('D', 'I', 'V', 'X'),
645
    GST_MAKE_FOURCC ('D', 'X', '5', '0'),
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
646
647
    GST_MAKE_FOURCC ('X', 'V', 'I', 'D'),
    GST_MAKE_FOURCC ('3', 'I', 'V', '1'),
648
649
    GST_MAKE_FOURCC ('c', 'v', 'i', 'd'),
    GST_MAKE_FOURCC ('m', 's', 'v', 'c'),
650
    GST_MAKE_FOURCC ('R', 'L', 'E', ' '),
651
    GST_MAKE_FOURCC ('D', 'I', 'B', ' '),
652
    GST_MAKE_FOURCC ('X', 'x', 'a', 'n'),
653
    GST_MAKE_FOURCC ('I', 'V', '3', '2'),
654
    GST_MAKE_FOURCC ('I', 'V', '5', '0'),
655
    GST_MAKE_FOURCC ('M', '4', 'S', '2'),
656
657
658
659
    /* FILL ME */
    0
  };
  guint i;
David Schleef's avatar
David Schleef committed
660
  GstCaps *caps, *one;
661

David Schleef's avatar
David Schleef committed
662
  caps = gst_caps_new_empty ();
663
  for (i = 0; tags[i] != 0; i++) {
664
    one = gst_riff_create_video_caps (tags[i], NULL, NULL, NULL, NULL, NULL);
665
    if (one)
David Schleef's avatar
David Schleef committed
666
      gst_caps_append (caps, one);
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
  }

  return caps;
}

GstCaps *
gst_riff_create_audio_template_caps (void)
{
  guint16 tags[] = {
    GST_RIFF_WAVE_FORMAT_MPEGL3,
    GST_RIFF_WAVE_FORMAT_MPEGL12,
    GST_RIFF_WAVE_FORMAT_PCM,
    GST_RIFF_WAVE_FORMAT_VORBIS1,
    GST_RIFF_WAVE_FORMAT_A52,
    GST_RIFF_WAVE_FORMAT_ALAW,
    GST_RIFF_WAVE_FORMAT_MULAW,
683
    GST_RIFF_WAVE_FORMAT_ADPCM,
684
    GST_RIFF_WAVE_FORMAT_DVI_ADPCM,
685
686
    GST_RIFF_WAVE_FORMAT_WMAV1,
    GST_RIFF_WAVE_FORMAT_WMAV2,
687
    GST_RIFF_WAVE_FORMAT_WMAV3,
688
689
690
691
    /* FILL ME */
    0
  };
  guint i;
David Schleef's avatar
David Schleef committed
692
  GstCaps *caps, *one;
693

David Schleef's avatar
David Schleef committed
694
  caps = gst_caps_new_empty ();
695
  for (i = 0; tags[i] != 0; i++) {
696
    one = gst_riff_create_audio_caps (tags[i], NULL, NULL, NULL, NULL, NULL);
697
    if (one)
David Schleef's avatar
David Schleef committed
698
      gst_caps_append (caps, one);
699
700
701
702
703
704
705
706
707
  }

  return caps;
}

GstCaps *
gst_riff_create_iavs_template_caps (void)
{
  guint32 tags[] = {
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
708
    GST_MAKE_FOURCC ('D', 'V', 'S', 'D'),
709
710
711
712
    /* FILL ME */
    0
  };
  guint i;
David Schleef's avatar
David Schleef committed
713
  GstCaps *caps, *one;
714

David Schleef's avatar
David Schleef committed
715
  caps = gst_caps_new_empty ();
716
  for (i = 0; tags[i] != 0; i++) {
717
    one = gst_riff_create_iavs_caps (tags[i], NULL, NULL, NULL, NULL, NULL);
718
    if (one)
David Schleef's avatar
David Schleef committed
719
      gst_caps_append (caps, one);
720
721
722
723
  }

  return caps;
}