gstffmpegcodecmap.c 90.6 KB
Newer Older
1 2
/* GStreamer
 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3
 * This file:
4
 * Copyright (c) 2002-2004 Ronald Bultje <rbultje@ronald.bitfreak.net>
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 *
 * 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.
 */

22
#ifdef HAVE_CONFIG_H
23
#include "config.h"
24
#endif
25
#include <gst/gst.h>
26 27 28 29 30
#ifdef HAVE_FFMPEG_UNINSTALLED
#include <avcodec.h>
#else
#include <ffmpeg/avcodec.h>
#endif
31
#include <string.h>
32

33
#include "gstffmpeg.h"
34 35
#include "gstffmpegcodecmap.h"

36 37 38 39 40 41 42 43 44 45 46 47 48 49
/*
 * Read a palette from a caps.
 */

static void
gst_ffmpeg_get_palette (const GstCaps *caps, AVCodecContext *context)
{
  GstStructure *str = gst_caps_get_structure (caps, 0);
  const GValue *palette_v;
  const GstBuffer *palette;

  /* do we have a palette? */
  if ((palette_v = gst_structure_get_value (str,
          "palette_data")) && context) {
50
    palette = gst_value_get_buffer (palette_v);
51
    if (GST_BUFFER_SIZE (palette) >= AVPALETTE_SIZE) {
52 53 54 55 56 57 58 59 60 61 62 63 64 65
      if (context->palctrl)
        av_free (context->palctrl);
      context->palctrl = av_malloc (sizeof (AVPaletteControl));
      context->palctrl->palette_changed = 1;
      memcpy (context->palctrl->palette, GST_BUFFER_DATA (palette),
          AVPALETTE_SIZE);
    }
  }
}

static void
gst_ffmpeg_set_palette (GstCaps *caps, AVCodecContext *context)
{
  if (context->palctrl) {
66
    GstBuffer *palette = gst_buffer_new_and_alloc (AVPALETTE_SIZE);
67 68 69 70 71 72 73 74

    memcpy (GST_BUFFER_DATA (palette), context->palctrl->palette,
        AVPALETTE_SIZE);
    gst_caps_set_simple (caps,
        "palette_data", GST_TYPE_BUFFER, palette, NULL);
  }
}

75 76 77 78
/* this macro makes a caps width fixed or unfixed width/height
 * properties depending on whether we've got a context.
 *
 * See below for why we use this.
79 80 81
 *
 * We should actually do this stuff at the end, like in riff-media.c,
 * but I'm too lazy today. Maybe later.
82 83
 */

84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
static GstCaps *
gst_ff_vid_caps_new (AVCodecContext * context, const char *mimetype,
    const char *fieldname, ...)
{
  GstStructure *structure = NULL;
  GstCaps *caps = NULL;
  va_list var_args;

  if (context != NULL) {
    caps = gst_caps_new_simple (mimetype,
        "width", G_TYPE_INT, context->width,
        "height", G_TYPE_INT, context->height,
        "framerate", GST_TYPE_FRACTION,
        context->time_base.den, context->time_base.num,
        NULL);
  } else {
    caps = gst_caps_new_simple (mimetype,
        "width", GST_TYPE_INT_RANGE, 16, 4096,
        "height", GST_TYPE_INT_RANGE, 16, 4096,
        "framerate", GST_TYPE_FRACTION_RANGE, 0, 1,
        G_MAXINT, 1, NULL);
  }

  structure = gst_caps_get_structure (caps, 0);

  if (structure) {
    va_start (var_args, fieldname);
    gst_structure_set_valist (structure, fieldname, var_args);
    va_end (var_args);
  }

  return caps;
}
117 118 119 120

/* same for audio - now with channels/sample rate
 */

121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
static GstCaps *
gst_ff_aud_caps_new (AVCodecContext * context, const char *mimetype,
    const char *fieldname, ...)
{
  GstCaps *caps = NULL;
  GstStructure *structure = NULL;
  va_list var_args;

  if (context != NULL) {
    caps = gst_caps_new_simple (mimetype,
        "rate", G_TYPE_INT, context->sample_rate,
        "channels", G_TYPE_INT, context->channels,
        NULL);
  } else {
    caps = gst_caps_new_simple (mimetype,
        "rate", GST_TYPE_INT_RANGE, 8000, 96000,
        "channels", GST_TYPE_INT_RANGE, 1, 2,
        NULL);

  }

  structure = gst_caps_get_structure (caps, 0);

  if (structure) {
    va_start (var_args, fieldname);
    gst_structure_set_valist (structure, fieldname, var_args);
    va_end (var_args);
  }

  return caps;
}
152 153 154 155 156 157

/* Convert a FFMPEG codec ID and optional AVCodecContext
 * to a GstCaps. If the context is ommitted, no fixed values
 * for video/audio size will be included in the GstCaps
 *
 * CodecID is primarily meant for compressed data GstCaps!
158 159 160 161 162 163 164 165 166
 *
 * encode is a special parameter. gstffmpegdec will say
 * FALSE, gstffmpegenc will say TRUE. The output caps
 * depends on this, in such a way that it will be very
 * specific, defined, fixed and correct caps for encoders,
 * yet very wide, "forgiving" caps for decoders. Example
 * for mp3: decode: audio/mpeg,mpegversion=1,layer=[1-3]
 * but encode: audio/mpeg,mpegversion=1,layer=3,bitrate=x,
 * rate=x,channels=x.
167 168
 */

169
GstCaps *
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
170 171
gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
    AVCodecContext * context, gboolean encode)
172
{
173
  GstCaps *caps = NULL;
174
  gboolean buildcaps = FALSE;
175

176
  switch (codec_id) {
177
    case CODEC_ID_MPEG1VIDEO:
178 179 180
      /* For decoding, CODEC_ID_MPEG2VIDEO is preferred... So omit here */
      if (encode) {
        /* FIXME: bitrate */
181
        caps = gst_ff_vid_caps_new (context, "video/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
182 183
            "mpegversion", G_TYPE_INT, 1,
            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
184 185 186 187 188 189
      }
      break;

    case CODEC_ID_MPEG2VIDEO:
      if (encode) {
        /* FIXME: bitrate */
190
        caps = gst_ff_vid_caps_new (context, "video/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
191 192
            "mpegversion", G_TYPE_INT, 2,
            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
193 194 195 196
      } else {
        /* decode both MPEG-1 and MPEG-2; width/height/fps are all in
         * the MPEG video stream headers, so may be omitted from caps. */
        caps = gst_caps_new_simple ("video/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
197 198
            "mpegversion", GST_TYPE_INT_RANGE, 1, 2,
            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
199
      }
200
      break;
201 202 203 204 205 206

    case CODEC_ID_MPEG2VIDEO_XVMC:
      /* this is a special ID - don't need it in GStreamer, I think */
      break;

    case CODEC_ID_H263:
207
      caps = gst_ff_vid_caps_new (context, "video/x-h263", NULL);
208 209 210
      break;

    case CODEC_ID_H263P:
211
      caps = gst_ff_vid_caps_new (context, "video/x-h263", 
212
          "variant", G_TYPE_STRING, "h263p", NULL);
213
      break;
214

215
    case CODEC_ID_H263I:
216
      caps = gst_ff_vid_caps_new (context, "video/x-intel-h263", NULL);
217 218
      break;

219
    case CODEC_ID_H261:
220
      caps = gst_ff_vid_caps_new (context, "video/x-h261", NULL);
221 222
      break;

223
    case CODEC_ID_RV10:
224
    case CODEC_ID_RV20:
225
    case CODEC_ID_RV40:
226
      {
227 228 229 230 231 232 233 234 235 236 237 238 239
        gint version;

        switch (codec_id) {
          case CODEC_ID_RV40:
            version = 4;
            break;
          case CODEC_ID_RV20:
            version = 2;
            break;
          default:
            version = 1;
            break;
        }
240 241

        /* FIXME: context->sub_id must be filled in during decoding */
242
        caps = gst_ff_vid_caps_new (context, "video/x-pn-realvideo",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
243 244
            "systemstream", G_TYPE_BOOLEAN, FALSE,
            "rmversion", G_TYPE_INT, version, NULL);
245 246 247 248
        if (context) {
          gst_caps_set_simple (caps,
              "rmsubid", GST_TYPE_FOURCC, context->sub_id, NULL);
        }
249
      }
250
      break;
251

252
    case CODEC_ID_MP2:
253 254 255
      /* we use CODEC_ID_MP3 for decoding */
      if (encode) {
        /* FIXME: bitrate */
256
        caps = gst_ff_aud_caps_new (context, "audio/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
257
            "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 2, NULL);
258
      }
259
      break;
260

261 262 263
    case CODEC_ID_MP3:
      if (encode) {
        /* FIXME: bitrate */
264
        caps = gst_ff_aud_caps_new (context, "audio/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
265
            "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 3, NULL);
266 267 268 269
      } else {
        /* Decodes MPEG-1 layer 1/2/3. Samplerate, channels et al are
         * in the MPEG audio header, so may be omitted from caps. */
        caps = gst_caps_new_simple ("audio/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
270 271
            "mpegversion", G_TYPE_INT, 1,
            "layer", GST_TYPE_INT_RANGE, 1, 3, NULL);
272
      }
273
      break;
274

David Schleef's avatar
David Schleef committed
275
    case CODEC_ID_VORBIS:
276 277 278 279 280 281 282
      /* This one is disabled for several reasons:
       * - GStreamer already has perfect Ogg and Vorbis support
       * - The ffmpeg implementation depends on libvorbis/libogg,
       *   which are not included in the ffmpeg that GStreamer ships.
       * - The ffmpeg implementation depends on shared objects between
       *   the ogg demuxer and vorbis decoder, which GStreamer doesn't.
       */
283
      break;
284

285
    case CODEC_ID_AC3:
286 287 288 289 290 291
      /* Decoding is disabled, because:
       * - it depends on liba52, which we don't ship in ffmpeg.
       * - we already have a liba52 plugin ourselves.
       */
      if (encode) {
        /* FIXME: bitrate */
292
        caps = gst_ff_aud_caps_new (context, "audio/x-ac3", NULL);
293
      }
294
      break;
295
    case CODEC_ID_DTS:
296
      caps = gst_ff_aud_caps_new (context, "audio/x-dts", NULL);
297
      break;
298

Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
299 300 301 302 303
      /* MJPEG is normal JPEG, Motion-JPEG and Quicktime MJPEG-A. MJPEGB
       * is Quicktime's MJPEG-B. LJPEG is lossless JPEG. I don't know what
       * sp5x is, but it's apparently something JPEG... We don't separate
       * between those in GStreamer. Should we (at least between MJPEG,
       * MJPEG-B and sp5x decoding...)? */
304
    case CODEC_ID_MJPEG:
305
    case CODEC_ID_LJPEG:
306
      caps = gst_ff_vid_caps_new (context, "image/jpeg", NULL);
Wim Taymans's avatar
Wim Taymans committed
307
      break;
308

309
    case CODEC_ID_SP5X:
310
      caps = gst_ff_vid_caps_new (context, "video/sp5x", NULL);
311 312
      break;

313
    case CODEC_ID_MJPEGB:
314
      caps = gst_ff_vid_caps_new (context, "video/x-mjpeg-b", NULL);
315 316
      break;

317
    case CODEC_ID_MPEG4:
318
      if (encode && context != NULL) {
319 320
        /* I'm not exactly sure what ffmpeg outputs... ffmpeg itself uses
         * the AVI fourcc 'DIVX', but 'mp4v' for Quicktime... */
321
        switch (context->codec_tag) {
322
          case GST_MAKE_FOURCC ('D', 'I', 'V', 'X'):
323
            caps = gst_ff_vid_caps_new (context, "video/x-divx",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
324
                "divxversion", G_TYPE_INT, 5, NULL);
325 326 327 328
            break;
          case GST_MAKE_FOURCC ('m', 'p', '4', 'v'):
          default:
            /* FIXME: bitrate */
329
            caps = gst_ff_vid_caps_new (context, "video/mpeg",
330 331 332 333
                "systemstream", G_TYPE_BOOLEAN, FALSE,
                "mpegversion", G_TYPE_INT, 4, NULL);
            break;
        }
334 335
      } else {
        /* The trick here is to separate xvid, divx, mpeg4, 3ivx et al */
336
        caps = gst_ff_vid_caps_new (context, "video/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
337 338
            "mpegversion", G_TYPE_INT, 4,
            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
339
        if (encode) {
340
          gst_caps_append (caps, gst_ff_vid_caps_new (context, "video/x-divx",
341 342
              "divxversion", G_TYPE_INT, 5, NULL));
        } else {
343
          gst_caps_append (caps, gst_ff_vid_caps_new (context, "video/x-divx",
344
              "divxversion", GST_TYPE_INT_RANGE, 4, 5, NULL));
345 346
          gst_caps_append (caps, gst_ff_vid_caps_new (context, "video/x-xvid", NULL));
          gst_caps_append (caps, gst_ff_vid_caps_new (context, "video/x-3ivx", NULL));
347
        }
348
      }
349
      break;
350

351
    case CODEC_ID_RAWVIDEO:
352
      caps = gst_ffmpeg_codectype_to_caps (CODEC_TYPE_VIDEO, context);
353
      break;
354

355
    case CODEC_ID_MSMPEG4V1:
356 357
    case CODEC_ID_MSMPEG4V2:
    case CODEC_ID_MSMPEG4V3:
358
      {
359 360 361
        gint version = 41 + codec_id - CODEC_ID_MSMPEG4V1;

        /* encode-FIXME: bitrate */
362
        caps = gst_ff_vid_caps_new (context, "video/x-msmpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
363
            "msmpegversion", G_TYPE_INT, version, NULL);
364
        if (!encode && codec_id == CODEC_ID_MSMPEG4V3) {
365
          gst_caps_append (caps, gst_ff_vid_caps_new (context, "video/x-divx",
366
              "divxversion", G_TYPE_INT, 3, NULL));
367
        }
368
      }
369
      break;
370

371
    case CODEC_ID_WMV1:
372
    case CODEC_ID_WMV2:
373
      {
374 375
        gint version = (codec_id == CODEC_ID_WMV1) ? 1 : 2;

376
        caps = gst_ff_vid_caps_new (context, "video/x-wmv",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
377
            "wmvversion", G_TYPE_INT, version, NULL);
378
      }
379
      break;
380

381
    case CODEC_ID_FLV1:
382
      caps = gst_ff_vid_caps_new (context, "video/x-flash-video",
383
				  "flvversion", G_TYPE_INT, 1, NULL);
384
      break;
385

386
    case CODEC_ID_SVQ1:
387
      caps = gst_ff_vid_caps_new (context, "video/x-svq",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
388
          "svqversion", G_TYPE_INT, 1, NULL);
389
      break;
390 391

    case CODEC_ID_SVQ3:
392
      caps = gst_ff_vid_caps_new (context, "video/x-svq",
393
          "svqversion", G_TYPE_INT, 3, NULL);
394
      break;
395

396
    case CODEC_ID_DVAUDIO:
397
      caps = gst_ff_aud_caps_new (context, "audio/x-dv", NULL);
398
      break;
399

400
    case CODEC_ID_DVVIDEO:
401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435
      {
	if (encode && context) {
	  guint32 fourcc;

	  switch (context->pix_fmt) {
	  case PIX_FMT_YUV422:
	    fourcc = GST_MAKE_FOURCC ('Y', 'U', 'Y', '2');
	    break;
	  case PIX_FMT_YUV420P:
	    fourcc = GST_MAKE_FOURCC ('I', '4', '2', '0');
	    break;
	  case PIX_FMT_YUV411P:
	    fourcc = GST_MAKE_FOURCC ('Y', '4', '1', 'B');
	    break;
	  case PIX_FMT_YUV422P:
	    fourcc = GST_MAKE_FOURCC ('Y', '4', '2', 'B');
	    break;
	  case PIX_FMT_YUV410P:
	    fourcc = GST_MAKE_FOURCC ('Y', 'U', 'V', '9');
	    break;
	  default:
	    GST_WARNING ("Couldnt' find fourcc for pixfmt %d, defaulting to I420", context->pix_fmt);
	    fourcc = GST_MAKE_FOURCC ('I', '4', '2', '0');
	    break;
	  }
	  caps = gst_ff_vid_caps_new (context, "video/x-dv",
				      "systemstream", G_TYPE_BOOLEAN, FALSE,
				      "format", GST_TYPE_FOURCC, fourcc,
				      NULL);
	} else {
	  caps = gst_ff_vid_caps_new (context, "video/x-dv",
				      "systemstream", G_TYPE_BOOLEAN, FALSE,
				      NULL);
	}
      }
436
      break;
437

438 439
    case CODEC_ID_WMAV1:
    case CODEC_ID_WMAV2:
440
      {
441 442
        gint version = (codec_id == CODEC_ID_WMAV1) ? 1 : 2;

443
        if (context) {
444
          caps = gst_ff_aud_caps_new (context, "audio/x-wma",
445 446 447
             "wmaversion", G_TYPE_INT, version,
             "block_align", G_TYPE_INT, context->block_align,
             "bitrate", G_TYPE_INT, context->bit_rate, NULL);
448
        } else {
449
          caps = gst_ff_aud_caps_new (context, "audio/x-wma",
450 451 452 453
             "wmaversion", G_TYPE_INT, version,
             "block_align", GST_TYPE_INT_RANGE, 0, G_MAXINT,
             "bitrate", GST_TYPE_INT_RANGE, 0, G_MAXINT, NULL);
        }
454
      }
455
      break;
456

457 458
    case CODEC_ID_MACE3:
    case CODEC_ID_MACE6:
459
      {
460 461
        gint version = (codec_id == CODEC_ID_MACE3) ? 3 : 6;

462
        caps = gst_ff_aud_caps_new (context, "audio/x-mace",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
463
            "maceversion", G_TYPE_INT, version, NULL);
464
      }
465
      break;
466

Wim Taymans's avatar
Wim Taymans committed
467
    case CODEC_ID_HUFFYUV:
468
      caps = gst_ff_vid_caps_new (context, "video/x-huffyuv", NULL);
469 470 471 472
      if (context) {
        gst_caps_set_simple (caps,
            "bpp", G_TYPE_INT, context->bits_per_sample, NULL);
      }
473 474 475
      break;

    case CODEC_ID_CYUV:
476
      caps = gst_ff_vid_caps_new (context, "video/x-compressed-yuv", NULL);
477 478 479
      break;

    case CODEC_ID_H264:
480
      caps = gst_ff_vid_caps_new (context, "video/x-h264", NULL);
481 482 483
      break;

    case CODEC_ID_INDEO3:
484
      caps = gst_ff_vid_caps_new (context, "video/x-indeo",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
485
          "indeoversion", G_TYPE_INT, 3, NULL);
486 487
      break;

488
    case CODEC_ID_INDEO2:
489
      caps = gst_ff_vid_caps_new (context, "video/x-indeo",
490 491 492
          "indeoversion", G_TYPE_INT, 2, NULL);
      break;

493 494 495 496
    case CODEC_ID_FLASHSV:
      caps = gst_ff_vid_caps_new (context, "video/x-flash-screen", NULL);
      break;

497
    case CODEC_ID_VP3:
498
      caps = gst_ff_vid_caps_new (context, "video/x-vp3", NULL);
499 500
      break;

501 502 503 504 505 506 507 508 509 510 511 512
    case CODEC_ID_VP5:
      caps = gst_ff_vid_caps_new (context, "video/x-vp5", NULL);
      break;

    case CODEC_ID_VP6:
      caps = gst_ff_vid_caps_new (context, "video/x-vp6", NULL);
      break;

    case CODEC_ID_VP6F:
      caps = gst_ff_vid_caps_new (context, "video/x-vp6-flash", NULL);
      break;

513
    case CODEC_ID_THEORA:
514
      caps = gst_ff_vid_caps_new (context, "video/x-theora", NULL);
515 516
      break;

517
    case CODEC_ID_AAC:
518
    case CODEC_ID_MPEG4AAC:
519
      caps = gst_ff_aud_caps_new (context, "audio/mpeg",
520
          "mpegversion", G_TYPE_INT, 4, NULL);
521 522 523
      break;

    case CODEC_ID_ASV1:
524
      caps = gst_ff_vid_caps_new (context, "video/x-asus",
525 526
				  "asusversion", G_TYPE_INT, 1, NULL);
      break;
527
    case CODEC_ID_ASV2:
528
      caps = gst_ff_vid_caps_new (context, "video/x-asus",
529
				  "asusversion", G_TYPE_INT, 2, NULL);
530 531
      break;

532
    case CODEC_ID_FFV1:
533
      caps = gst_ff_vid_caps_new (context, "video/x-ffv",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
534
          "ffvversion", G_TYPE_INT, 1, NULL);
535 536 537
      break;

    case CODEC_ID_4XM:
538
      caps = gst_ff_vid_caps_new (context, "video/x-4xm", NULL);
539 540
      break;

541 542
    case CODEC_ID_XAN_WC3:
    case CODEC_ID_XAN_WC4:
543
      caps = gst_ff_vid_caps_new (context, "video/x-xan",
544 545 546
          "wcversion", G_TYPE_INT, 3 - CODEC_ID_XAN_WC3 + codec_id, NULL);
      break;

547
    case CODEC_ID_CLJR:
548
      caps = gst_ff_vid_caps_new (context, "video/x-cirrus-logic-accupak", NULL);
549 550 551
      break;

    case CODEC_ID_FRAPS:
552 553 554 555 556 557
    case CODEC_ID_MDEC:
    case CODEC_ID_ROQ:
    case CODEC_ID_INTERPLAY_VIDEO:
      buildcaps = TRUE;
      break;

558
    case CODEC_ID_VCR1:
559
      caps = gst_ff_vid_caps_new (context, "video/x-ati-vcr", 
560 561 562
				  "vcrversion", G_TYPE_INT, 1, NULL);
      break;

563
    case CODEC_ID_RPZA:
564
      caps = gst_ff_vid_caps_new (context, "video/x-apple-video", NULL);
565 566
      break;

567
    case CODEC_ID_CINEPAK:
568
      caps = gst_ff_vid_caps_new (context, "video/x-cinepak", NULL);
569 570
      break;

571 572 573
    /* WS_VQA belogns here (order) */

    case CODEC_ID_MSRLE:
574
      caps = gst_ff_vid_caps_new (context, "video/x-rle",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
575
          "layout", G_TYPE_STRING, "microsoft", NULL);
576 577
      if (context) {
        gst_caps_set_simple (caps,
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
578
            "depth", G_TYPE_INT, (gint) context->bits_per_sample, NULL);
579 580 581 582 583
      } else {
        gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 1, 64, NULL);
      }
      break;

584
    case CODEC_ID_QTRLE:
585
      caps = gst_ff_vid_caps_new (context, "video/x-rle",
586 587 588 589 590 591 592 593 594
          "layout", G_TYPE_STRING, "quicktime", NULL);
      if (context) {
        gst_caps_set_simple (caps,
            "depth", G_TYPE_INT, (gint) context->bits_per_sample, NULL);
      } else {
        gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 1, 64, NULL);
      }
      break;

595
    case CODEC_ID_MSVIDEO1:
596
      caps = gst_ff_vid_caps_new (context, "video/x-msvideocodec",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
597
          "msvideoversion", G_TYPE_INT, 1, NULL);
598 599
      break;

600
    case CODEC_ID_WMV3:
601
    case CODEC_ID_VC1:
602
      caps = gst_ff_vid_caps_new (context, "video/x-wmv",
603 604
          "wmvversion", G_TYPE_INT, 3, NULL);
      break;
605
    case CODEC_ID_QDM2:
606
      caps = gst_ff_aud_caps_new (context, "audio/x-qdm2", NULL);
607
      break;  
608

609
    case CODEC_ID_MSZH:
610
      caps = gst_ff_vid_caps_new (context, "video/x-mszh", NULL);
611 612 613
      break;

    case CODEC_ID_ZLIB:
614
      caps = gst_ff_vid_caps_new (context, "video/x-zlib", NULL);
615 616 617
      break;

    case CODEC_ID_TRUEMOTION1:
618
      caps = gst_ff_vid_caps_new (context, "video/x-truemotion",
619 620 621
				  "trueversion", G_TYPE_INT, 1, NULL);
      break;
    case CODEC_ID_TRUEMOTION2:
622
      caps = gst_ff_vid_caps_new (context, "video/x-truemotion",
623 624 625 626
				  "trueversion", G_TYPE_INT, 2, NULL);
      break;

    case CODEC_ID_ULTI:
627
      caps = gst_ff_vid_caps_new (context, "video/x-ultimotion",
628 629 630 631
				  NULL);
      break;

    case CODEC_ID_TSCC:
632
      caps = gst_ff_vid_caps_new (context, "video/x-camtasia", NULL);
633 634 635
      break;

    case CODEC_ID_PNG:
636
      caps = gst_ff_vid_caps_new (context, "image/png", NULL);
637 638
      break;

639 640 641 642 643 644 645 646
    case CODEC_ID_PPM:
      caps = gst_ff_vid_caps_new (context, "image/ppm", NULL);
      break;
      
    case CODEC_ID_PBM:
      caps = gst_ff_vid_caps_new (context, "image/pbm", NULL);
      break;
      
647
    case CODEC_ID_SMC:
648
      caps = gst_ff_vid_caps_new (context, "video/x-smc", NULL);
649 650
      break;

651
    case CODEC_ID_QDRAW:
652
      caps = gst_ff_vid_caps_new (context, "video/x-qdrw", NULL);
653 654
      break;

655 656 657 658 659 660
    case CODEC_ID_WS_VQA:
    case CODEC_ID_IDCIN:
    case CODEC_ID_8BPS:
    case CODEC_ID_FLIC:
    case CODEC_ID_VMDVIDEO:
    case CODEC_ID_VMDAUDIO:
661 662 663 664 665 666 667 668 669 670
    case CODEC_ID_SONIC:
    case CODEC_ID_SONIC_LS:
    case CODEC_ID_SNOW:
    case CODEC_ID_VIXL:
    case CODEC_ID_QPEG:
    case CODEC_ID_XVID:
    case CODEC_ID_PGM:
    case CODEC_ID_PGMYUV:
    case CODEC_ID_PAM:
    case CODEC_ID_FFVHUFF:
671 672 673 674 675 676
    case CODEC_ID_LOCO:
    case CODEC_ID_WNV1:
    case CODEC_ID_AASC:
    case CODEC_ID_MP3ADU:
    case CODEC_ID_MP3ON4:
    case CODEC_ID_WESTWOOD_SND1:
677 678 679 680 681
    case CODEC_ID_CSCD:
    case CODEC_ID_MMVIDEO:
    case CODEC_ID_ZMBV:
    case CODEC_ID_AVS:
    case CODEC_ID_TRUESPEECH:
682
    case CODEC_ID_CAVS:
683 684 685
      buildcaps = TRUE;
      break;

Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
686
      /* weird quasi-codecs for the demuxers only */
687 688 689 690 691 692
    case CODEC_ID_PCM_S16LE:
    case CODEC_ID_PCM_S16BE:
    case CODEC_ID_PCM_U16LE:
    case CODEC_ID_PCM_U16BE:
    case CODEC_ID_PCM_S8:
    case CODEC_ID_PCM_U8:
693
      {
694
        gint width = 0, depth = 0, endianness = 0;
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
695
        gboolean signedness = FALSE;    /* blabla */
696 697 698

        switch (codec_id) {
          case CODEC_ID_PCM_S16LE:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
699 700
            width = 16;
            depth = 16;
701 702 703 704
            endianness = G_LITTLE_ENDIAN;
            signedness = TRUE;
            break;
          case CODEC_ID_PCM_S16BE:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
705 706
            width = 16;
            depth = 16;
707 708 709 710
            endianness = G_BIG_ENDIAN;
            signedness = TRUE;
            break;
          case CODEC_ID_PCM_U16LE:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
711 712
            width = 16;
            depth = 16;
713 714 715 716
            endianness = G_LITTLE_ENDIAN;
            signedness = FALSE;
            break;
          case CODEC_ID_PCM_U16BE:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
717 718
            width = 16;
            depth = 16;
719 720 721 722
            endianness = G_BIG_ENDIAN;
            signedness = FALSE;
            break;
          case CODEC_ID_PCM_S8:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
723 724
            width = 8;
            depth = 8;
725 726 727 728
            endianness = G_BYTE_ORDER;
            signedness = TRUE;
            break;
          case CODEC_ID_PCM_U8:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
729 730
            width = 8;
            depth = 8;
731 732 733 734
            endianness = G_BYTE_ORDER;
            signedness = FALSE;
            break;
          default:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
735
            g_assert (0);       /* don't worry, we never get here */
736 737 738
            break;
        }

739
        caps = gst_ff_aud_caps_new (context, "audio/x-raw-int",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
740 741 742 743
            "width", G_TYPE_INT, width,
            "depth", G_TYPE_INT, depth,
            "endianness", G_TYPE_INT, endianness,
            "signed", G_TYPE_BOOLEAN, signedness, NULL);
744
      }
745 746
      break;

747
    case CODEC_ID_PCM_MULAW:
748
      caps = gst_ff_aud_caps_new (context, "audio/x-mulaw", NULL);
749 750 751
      break;

    case CODEC_ID_PCM_ALAW:
752
      caps = gst_ff_aud_caps_new (context, "audio/x-alaw", NULL);
753 754
      break;

755 756
    case CODEC_ID_ADPCM_IMA_QT:
    case CODEC_ID_ADPCM_IMA_WAV:
757 758 759 760
    case CODEC_ID_ADPCM_IMA_DK3:
    case CODEC_ID_ADPCM_IMA_DK4:
    case CODEC_ID_ADPCM_IMA_WS:
    case CODEC_ID_ADPCM_IMA_SMJPEG:
761
    case CODEC_ID_ADPCM_MS:
762
    case CODEC_ID_ADPCM_4XM:
763 764 765 766
    case CODEC_ID_ADPCM_XA:
    case CODEC_ID_ADPCM_ADX:
    case CODEC_ID_ADPCM_EA:
    case CODEC_ID_ADPCM_G726:
767
    case CODEC_ID_ADPCM_CT:
768
    case CODEC_ID_ADPCM_SWF:
769
    case CODEC_ID_ADPCM_YAMAHA:
770 771 772
    case CODEC_ID_ADPCM_SBPRO_2:
    case CODEC_ID_ADPCM_SBPRO_3:
    case CODEC_ID_ADPCM_SBPRO_4:
773
      {
774 775 776 777 778 779 780
        gchar *layout = NULL;

        switch (codec_id) {
          case CODEC_ID_ADPCM_IMA_QT:
            layout = "quicktime";
            break;
          case CODEC_ID_ADPCM_IMA_WAV:
781
            layout = "dvi";
782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812
            break;
          case CODEC_ID_ADPCM_IMA_DK3:
            layout = "dk3";
            break;
          case CODEC_ID_ADPCM_IMA_DK4:
            layout = "dk4";
            break;
          case CODEC_ID_ADPCM_IMA_WS:
            layout = "westwood";
            break;
          case CODEC_ID_ADPCM_IMA_SMJPEG:
            layout = "smjpeg";
            break;
          case CODEC_ID_ADPCM_MS:
            layout = "microsoft";
            break;
          case CODEC_ID_ADPCM_4XM:
            layout = "4xm";
            break;
          case CODEC_ID_ADPCM_XA:
            layout = "xa";
            break;
          case CODEC_ID_ADPCM_ADX:
            layout = "adx";
            break;
          case CODEC_ID_ADPCM_EA:
            layout = "ea";
            break;
          case CODEC_ID_ADPCM_G726:
            layout = "g726";
            break;
813 814 815
          case CODEC_ID_ADPCM_CT:
            layout = "ct";
            break;
816 817 818
          case CODEC_ID_ADPCM_SWF:
            layout = "swf";
            break;
819 820 821
          case CODEC_ID_ADPCM_YAMAHA:
            layout = "yamaha";
            break;
822 823 824 825 826 827 828 829 830
          case CODEC_ID_ADPCM_SBPRO_2:
            layout = "sbpro2";
            break;
          case CODEC_ID_ADPCM_SBPRO_3:
            layout = "sbpro3";
            break;
          case CODEC_ID_ADPCM_SBPRO_4:
            layout = "sbpro4";
            break;
831
          default:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
832
            g_assert (0);       /* don't worry, we never get here */
833 834 835 836 837
            break;
        }

        /* FIXME: someone please check whether we need additional properties
         * in this caps definition. */
838
        caps = gst_ff_aud_caps_new (context, "audio/x-adpcm",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
839
            "layout", G_TYPE_STRING, layout, NULL);
840 841 842 843
        if (context)
          gst_caps_set_simple (caps,
              "block_align", G_TYPE_INT, context->block_align,
              "bitrate", G_TYPE_INT, context->bit_rate, NULL);
844
      }
845 846 847
      break;

    case CODEC_ID_AMR_NB:
848
      caps = gst_ff_aud_caps_new (context, "audio/AMR", NULL);
849 850
      break;

851
    case CODEC_ID_AMR_WB:
852
      caps = gst_ff_aud_caps_new (context, "audio/AMR-WB", NULL);
853 854
      break;

855
    case CODEC_ID_RA_144:
856
    case CODEC_ID_RA_288:
857
    case CODEC_ID_COOK:
858
      {
859
        gint version = 0;
860 861 862 863 864 865 866 867 868 869
        switch (codec_id) {
          case CODEC_ID_RA_144:
            version = 1;
            break;
          case CODEC_ID_RA_288:
            version = 2;
            break;
          case CODEC_ID_COOK:
            version = 8;
            break;
870 871
          default:
            break;
872
        }
873 874

        /* FIXME: properties? */
875
        caps = gst_ff_aud_caps_new (context, "audio/x-pn-realaudio",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
876
            "raversion", G_TYPE_INT, version, NULL);
877 878 879 880 881
        if (context) {
          gst_caps_set_simple (caps,
              "leaf_size", G_TYPE_INT, context->block_align,
              "bitrate", G_TYPE_INT, context->bit_rate, NULL);
        }
882
      }
883
      break;
884

885 886 887
    case CODEC_ID_ROQ_DPCM:
    case CODEC_ID_INTERPLAY_DPCM:
    case CODEC_ID_XAN_DPCM:
888
    case CODEC_ID_SOL_DPCM:
889
      {
890 891 892 893 894 895 896 897 898 899 900 901
        gchar *layout = NULL;

        switch (codec_id) {
          case CODEC_ID_ROQ_DPCM:
            layout = "roq";
            break;
          case CODEC_ID_INTERPLAY_DPCM:
            layout = "interplay";
            break;
          case CODEC_ID_XAN_DPCM:
            layout = "xan";
            break;
902 903 904
          case CODEC_ID_SOL_DPCM:
            layout = "sol";
            break;
905
          default:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
906
            g_assert (0);       /* don't worry, we never get here */
907 908 909 910 911
            break;
        }

        /* FIXME: someone please check whether we need additional properties
         * in this caps definition. */
912
        caps = gst_ff_aud_caps_new (context, "audio/x-dpcm",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
913
            "layout", G_TYPE_STRING, layout, NULL);
914 915 916 917
        if (context)
          gst_caps_set_simple (caps,
              "block_align", G_TYPE_INT, context->block_align,
              "bitrate", G_TYPE_INT, context->bit_rate, NULL);
918
      }
919
      break;
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
920

921 922 923 924 925
    case CODEC_ID_SHORTEN:
      caps = gst_caps_new_simple ("audio/x-shorten", NULL);
      break;

    case CODEC_ID_ALAC:
926
      caps = gst_ff_aud_caps_new (context, "audio/x-alac", NULL);
927 928 929 930 931 932
      if (context) {
        gst_caps_set_simple (caps,
            "samplesize", G_TYPE_INT, context->bits_per_sample, NULL);
      }
      break;

933 934 935 936 937 938
    case CODEC_ID_FLAC:
      /* Note that ffmpeg has no encoder yet, but just for safety. In the
       * encoder case, we want to add things like samplerate, channels... */
      if (!encode) {
        caps = gst_caps_new_simple ("audio/x-flac", NULL);
      }
939 940
      break;

941 942 943 944
    case CODEC_ID_DVD_SUBTITLE:
    case CODEC_ID_DVB_SUBTITLE:
      caps = NULL;
      break;
945 946 947 948
    case CODEC_ID_BMP:
      caps = gst_caps_new_simple ("image/bmp", NULL);
      break;
    case CODEC_ID_TTA:
949
      caps = gst_ff_aud_caps_new (context, "audio/x-tta", NULL);
950 951 952 953 954
      if (context) {
        gst_caps_set_simple (caps,
            "samplesize", G_TYPE_INT, context->bits_per_sample, NULL);
      }
      break;
955
    default:
956
      g_warning ("Unknown codec ID %d, please add here", codec_id);
957