We are currently experiencing downtime impacting viewing & cloning the Mesa repo, and some GitLab pages returning 503. Please see #freedesktop on IRC for more updates.

gstffmpegcodecmap.c 91.7 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 208 209 210 211 212 213 214
      if (encode) {
        caps = gst_ff_vid_caps_new (context, "video/x-h263",
            "variant", G_TYPE_STRING, "itu",
            "h263version", G_TYPE_STRING, "h263", NULL);
      } else {
        caps = gst_ff_vid_caps_new (context, "video/x-h263",
            "variant", G_TYPE_STRING, "itu", NULL);
      }
215 216 217
      break;

    case CODEC_ID_H263P:
218
      caps = gst_ff_vid_caps_new (context, "video/x-h263", 
219 220
          "variant", G_TYPE_STRING, "itu",
          "h263version", G_TYPE_STRING, "h263p", NULL);
221
      break;
222

223
    case CODEC_ID_H263I:
224 225
      caps = gst_ff_vid_caps_new (context, "video/x-intel-h263",
          "variant", G_TYPE_STRING, "intel", NULL);
226 227
      break;

228
    case CODEC_ID_H261:
229
      caps = gst_ff_vid_caps_new (context, "video/x-h261", NULL);
230 231
      break;

232
    case CODEC_ID_RV10:
233
    case CODEC_ID_RV20:
234
    case CODEC_ID_RV40:
235
      {
236 237 238 239 240 241 242 243 244 245 246 247 248
        gint version;

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

        /* FIXME: context->sub_id must be filled in during decoding */
251
        caps = gst_ff_vid_caps_new (context, "video/x-pn-realvideo",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
252 253
            "systemstream", G_TYPE_BOOLEAN, FALSE,
            "rmversion", G_TYPE_INT, version, NULL);
254 255 256 257
        if (context) {
          gst_caps_set_simple (caps,
              "rmsubid", GST_TYPE_FOURCC, context->sub_id, NULL);
        }
258
      }
259
      break;
260

261
    case CODEC_ID_MP2:
262 263 264
      /* we use CODEC_ID_MP3 for decoding */
      if (encode) {
        /* FIXME: bitrate */
265
        caps = gst_ff_aud_caps_new (context, "audio/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
266
            "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 2, NULL);
267
      }
268
      break;
269

270 271 272
    case CODEC_ID_MP3:
      if (encode) {
        /* FIXME: bitrate */
273
        caps = gst_ff_aud_caps_new (context, "audio/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
274
            "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 3, NULL);
275 276 277 278
      } 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
279 280
            "mpegversion", G_TYPE_INT, 1,
            "layer", GST_TYPE_INT_RANGE, 1, 3, NULL);
281
      }
282
      break;
283

David Schleef's avatar
David Schleef committed
284
    case CODEC_ID_VORBIS:
285 286 287 288 289 290 291
      /* 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.
       */
292
      break;
293

294
    case CODEC_ID_AC3:
295 296 297 298 299 300
      /* 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 */
301
        caps = gst_ff_aud_caps_new (context, "audio/x-ac3", NULL);
302
      }
303
      break;
304
    case CODEC_ID_DTS:
305
      caps = gst_ff_aud_caps_new (context, "audio/x-dts", NULL);
306
      break;
307

Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
308 309 310 311 312
      /* 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...)? */
313
    case CODEC_ID_MJPEG:
314
    case CODEC_ID_LJPEG:
315
      caps = gst_ff_vid_caps_new (context, "image/jpeg", NULL);
Wim Taymans's avatar
Wim Taymans committed
316
      break;
317

318
    case CODEC_ID_SP5X:
319
      caps = gst_ff_vid_caps_new (context, "video/sp5x", NULL);
320 321
      break;

322
    case CODEC_ID_MJPEGB:
323
      caps = gst_ff_vid_caps_new (context, "video/x-mjpeg-b", NULL);
324 325
      break;

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

360
    case CODEC_ID_RAWVIDEO:
361
      caps = gst_ffmpeg_codectype_to_caps (CODEC_TYPE_VIDEO, context);
362
      break;
363

364
    case CODEC_ID_MSMPEG4V1:
365 366
    case CODEC_ID_MSMPEG4V2:
    case CODEC_ID_MSMPEG4V3:
367
      {
368 369 370
        gint version = 41 + codec_id - CODEC_ID_MSMPEG4V1;

        /* encode-FIXME: bitrate */
371
        caps = gst_ff_vid_caps_new (context, "video/x-msmpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
372
            "msmpegversion", G_TYPE_INT, version, NULL);
373
        if (!encode && codec_id == CODEC_ID_MSMPEG4V3) {
374
          gst_caps_append (caps, gst_ff_vid_caps_new (context, "video/x-divx",
375
              "divxversion", G_TYPE_INT, 3, NULL));
376
        }
377
      }
378
      break;
379

380
    case CODEC_ID_WMV1:
381
    case CODEC_ID_WMV2:
382
      {
383 384
        gint version = (codec_id == CODEC_ID_WMV1) ? 1 : 2;

385
        caps = gst_ff_vid_caps_new (context, "video/x-wmv",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
386
            "wmvversion", G_TYPE_INT, version, NULL);
387
      }
388
      break;
389

390
    case CODEC_ID_FLV1:
391
      caps = gst_ff_vid_caps_new (context, "video/x-flash-video",
392
				  "flvversion", G_TYPE_INT, 1, NULL);
393
      break;
394

395
    case CODEC_ID_SVQ1:
396
      caps = gst_ff_vid_caps_new (context, "video/x-svq",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
397
          "svqversion", G_TYPE_INT, 1, NULL);
398
      break;
399 400

    case CODEC_ID_SVQ3:
401
      caps = gst_ff_vid_caps_new (context, "video/x-svq",
402
          "svqversion", G_TYPE_INT, 3, NULL);
403
      break;
404

405
    case CODEC_ID_DVAUDIO:
406
      caps = gst_ff_aud_caps_new (context, "audio/x-dv", NULL);
407
      break;
408

409
    case CODEC_ID_DVVIDEO:
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 436 437 438 439 440 441 442 443 444
      {
	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);
	}
      }
445
      break;
446

447 448
    case CODEC_ID_WMAV1:
    case CODEC_ID_WMAV2:
449
      {
450 451
        gint version = (codec_id == CODEC_ID_WMAV1) ? 1 : 2;

452
        if (context) {
453
          caps = gst_ff_aud_caps_new (context, "audio/x-wma",
454 455 456
             "wmaversion", G_TYPE_INT, version,
             "block_align", G_TYPE_INT, context->block_align,
             "bitrate", G_TYPE_INT, context->bit_rate, NULL);
457
        } else {
458
          caps = gst_ff_aud_caps_new (context, "audio/x-wma",
459 460 461 462
             "wmaversion", G_TYPE_INT, version,
             "block_align", GST_TYPE_INT_RANGE, 0, G_MAXINT,
             "bitrate", GST_TYPE_INT_RANGE, 0, G_MAXINT, NULL);
        }
463
      }
464
      break;
465

466 467
    case CODEC_ID_MACE3:
    case CODEC_ID_MACE6:
468
      {
469 470
        gint version = (codec_id == CODEC_ID_MACE3) ? 3 : 6;

471
        caps = gst_ff_aud_caps_new (context, "audio/x-mace",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
472
            "maceversion", G_TYPE_INT, version, NULL);
473
      }
474
      break;
475

Wim Taymans's avatar
Wim Taymans committed
476
    case CODEC_ID_HUFFYUV:
477
      caps = gst_ff_vid_caps_new (context, "video/x-huffyuv", NULL);
478 479 480 481
      if (context) {
        gst_caps_set_simple (caps,
            "bpp", G_TYPE_INT, context->bits_per_sample, NULL);
      }
482 483 484
      break;

    case CODEC_ID_CYUV:
485
      caps = gst_ff_vid_caps_new (context, "video/x-compressed-yuv", NULL);
486 487 488
      break;

    case CODEC_ID_H264:
489
      caps = gst_ff_vid_caps_new (context, "video/x-h264", NULL);
490 491 492
      break;

    case CODEC_ID_INDEO3:
493
      caps = gst_ff_vid_caps_new (context, "video/x-indeo",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
494
          "indeoversion", G_TYPE_INT, 3, NULL);
495 496
      break;

497
    case CODEC_ID_INDEO2:
498
      caps = gst_ff_vid_caps_new (context, "video/x-indeo",
499 500 501
          "indeoversion", G_TYPE_INT, 2, NULL);
      break;

502 503 504 505
    case CODEC_ID_FLASHSV:
      caps = gst_ff_vid_caps_new (context, "video/x-flash-screen", NULL);
      break;

506
    case CODEC_ID_VP3:
507
      caps = gst_ff_vid_caps_new (context, "video/x-vp3", NULL);
508 509
      break;

510 511 512 513 514 515 516 517 518 519 520 521
    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;

522
    case CODEC_ID_THEORA:
523
      caps = gst_ff_vid_caps_new (context, "video/x-theora", NULL);
524 525
      break;

526
    case CODEC_ID_AAC:
527
    case CODEC_ID_MPEG4AAC:
528
      caps = gst_ff_aud_caps_new (context, "audio/mpeg",
529
          "mpegversion", G_TYPE_INT, 4, NULL);
530 531 532
      break;

    case CODEC_ID_ASV1:
533
      caps = gst_ff_vid_caps_new (context, "video/x-asus",
534 535
				  "asusversion", G_TYPE_INT, 1, NULL);
      break;
536
    case CODEC_ID_ASV2:
537
      caps = gst_ff_vid_caps_new (context, "video/x-asus",
538
				  "asusversion", G_TYPE_INT, 2, NULL);
539 540
      break;

541
    case CODEC_ID_FFV1:
542
      caps = gst_ff_vid_caps_new (context, "video/x-ffv",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
543
          "ffvversion", G_TYPE_INT, 1, NULL);
544 545 546
      break;

    case CODEC_ID_4XM:
547
      caps = gst_ff_vid_caps_new (context, "video/x-4xm", NULL);
548 549
      break;

550 551
    case CODEC_ID_XAN_WC3:
    case CODEC_ID_XAN_WC4:
552
      caps = gst_ff_vid_caps_new (context, "video/x-xan",
553 554 555
          "wcversion", G_TYPE_INT, 3 - CODEC_ID_XAN_WC3 + codec_id, NULL);
      break;

556
    case CODEC_ID_CLJR:
557
      caps = gst_ff_vid_caps_new (context, "video/x-cirrus-logic-accupak", NULL);
558 559 560
      break;

    case CODEC_ID_FRAPS:
561 562 563 564 565 566
    case CODEC_ID_MDEC:
    case CODEC_ID_ROQ:
    case CODEC_ID_INTERPLAY_VIDEO:
      buildcaps = TRUE;
      break;

567
    case CODEC_ID_VCR1:
568
      caps = gst_ff_vid_caps_new (context, "video/x-ati-vcr", 
569 570 571
				  "vcrversion", G_TYPE_INT, 1, NULL);
      break;

572
    case CODEC_ID_RPZA:
573
      caps = gst_ff_vid_caps_new (context, "video/x-apple-video", NULL);
574 575
      break;

576
    case CODEC_ID_CINEPAK:
577
      caps = gst_ff_vid_caps_new (context, "video/x-cinepak", NULL);
578 579
      break;

580 581 582
    /* WS_VQA belogns here (order) */

    case CODEC_ID_MSRLE:
583
      caps = gst_ff_vid_caps_new (context, "video/x-rle",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
584
          "layout", G_TYPE_STRING, "microsoft", NULL);
585 586
      if (context) {
        gst_caps_set_simple (caps,
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
587
            "depth", G_TYPE_INT, (gint) context->bits_per_sample, NULL);
588 589 590 591 592
      } else {
        gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 1, 64, NULL);
      }
      break;

593
    case CODEC_ID_QTRLE:
594
      caps = gst_ff_vid_caps_new (context, "video/x-rle",
595 596 597 598 599 600 601 602 603
          "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;

604
    case CODEC_ID_MSVIDEO1:
605
      caps = gst_ff_vid_caps_new (context, "video/x-msvideocodec",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
606
          "msvideoversion", G_TYPE_INT, 1, NULL);
607 608
      break;

609
    case CODEC_ID_WMV3:
610
    case CODEC_ID_VC1:
611
      caps = gst_ff_vid_caps_new (context, "video/x-wmv",
612 613
          "wmvversion", G_TYPE_INT, 3, NULL);
      break;
614
    case CODEC_ID_QDM2:
615
      caps = gst_ff_aud_caps_new (context, "audio/x-qdm2", NULL);
616
      break;  
617

618
    case CODEC_ID_MSZH:
619
      caps = gst_ff_vid_caps_new (context, "video/x-mszh", NULL);
620 621 622
      break;

    case CODEC_ID_ZLIB:
623
      caps = gst_ff_vid_caps_new (context, "video/x-zlib", NULL);
624 625 626
      break;

    case CODEC_ID_TRUEMOTION1:
627
      caps = gst_ff_vid_caps_new (context, "video/x-truemotion",
628 629 630
				  "trueversion", G_TYPE_INT, 1, NULL);
      break;
    case CODEC_ID_TRUEMOTION2:
631
      caps = gst_ff_vid_caps_new (context, "video/x-truemotion",
632 633 634 635
				  "trueversion", G_TYPE_INT, 2, NULL);
      break;

    case CODEC_ID_ULTI:
636
      caps = gst_ff_vid_caps_new (context, "video/x-ultimotion",
637 638 639 640
				  NULL);
      break;

    case CODEC_ID_TSCC:
641
      caps = gst_ff_vid_caps_new (context, "video/x-camtasia", NULL);
642 643 644
      break;

    case CODEC_ID_PNG:
645
      caps = gst_ff_vid_caps_new (context, "image/png", NULL);
646 647
      break;

648 649 650 651 652 653 654 655
    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;
      
656
    case CODEC_ID_SMC:
657
      caps = gst_ff_vid_caps_new (context, "video/x-smc", NULL);
658 659
      break;

660
    case CODEC_ID_QDRAW:
661
      caps = gst_ff_vid_caps_new (context, "video/x-qdrw", NULL);
662 663
      break;

664 665 666 667 668 669
    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:
670 671 672 673 674 675 676 677 678 679
    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:
680 681 682 683 684 685
    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:
686 687 688 689 690
    case CODEC_ID_CSCD:
    case CODEC_ID_MMVIDEO:
    case CODEC_ID_ZMBV:
    case CODEC_ID_AVS:
    case CODEC_ID_TRUESPEECH:
691
    case CODEC_ID_CAVS:
692 693 694
      buildcaps = TRUE;
      break;

Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
695
      /* weird quasi-codecs for the demuxers only */
696 697 698 699 700 701
    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:
702
      {
703
        gint width = 0, depth = 0, endianness = 0;
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
704
        gboolean signedness = FALSE;    /* blabla */
705 706 707

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

748
        caps = gst_ff_aud_caps_new (context, "audio/x-raw-int",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
749 750 751 752
            "width", G_TYPE_INT, width,
            "depth", G_TYPE_INT, depth,
            "endianness", G_TYPE_INT, endianness,
            "signed", G_TYPE_BOOLEAN, signedness, NULL);
753
      }
754 755
      break;

756
    case CODEC_ID_PCM_MULAW:
757
      caps = gst_ff_aud_caps_new (context, "audio/x-mulaw", NULL);
758 759 760
      break;

    case CODEC_ID_PCM_ALAW:
761
      caps = gst_ff_aud_caps_new (context, "audio/x-alaw", NULL);
762 763
      break;

764 765
    case CODEC_ID_ADPCM_IMA_QT:
    case CODEC_ID_ADPCM_IMA_WAV:
766 767 768 769
    case CODEC_ID_ADPCM_IMA_DK3:
    case CODEC_ID_ADPCM_IMA_DK4:
    case CODEC_ID_ADPCM_IMA_WS:
    case CODEC_ID_ADPCM_IMA_SMJPEG:
770
    case CODEC_ID_ADPCM_MS:
771
    case CODEC_ID_ADPCM_4XM:
772 773 774 775
    case CODEC_ID_ADPCM_XA:
    case CODEC_ID_ADPCM_ADX:
    case CODEC_ID_ADPCM_EA:
    case CODEC_ID_ADPCM_G726:
776
    case CODEC_ID_ADPCM_CT:
777
    case CODEC_ID_ADPCM_SWF:
778
    case CODEC_ID_ADPCM_YAMAHA:
779 780 781
    case CODEC_ID_ADPCM_SBPRO_2:
    case CODEC_ID_ADPCM_SBPRO_3:
    case CODEC_ID_ADPCM_SBPRO_4:
782
      {
783 784 785 786 787 788 789
        gchar *layout = NULL;

        switch (codec_id) {
          case CODEC_ID_ADPCM_IMA_QT:
            layout = "quicktime";
            break;
          case CODEC_ID_ADPCM_IMA_WAV:
790
            layout = "dvi";
791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821
            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;
822 823 824
          case CODEC_ID_ADPCM_CT:
            layout = "ct";
            break;
825 826 827
          case CODEC_ID_ADPCM_SWF:
            layout = "swf";
            break;
828 829 830
          case CODEC_ID_ADPCM_YAMAHA:
            layout = "yamaha";
            break;
831 832 833 834 835 836 837 838 839
          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;
840
          default:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
841
            g_assert (0);       /* don't worry, we never get here */
842 843 844 845 846
            break;
        }

        /* FIXME: someone please check whether we need additional properties
         * in this caps definition. */
847
        caps = gst_ff_aud_caps_new (context, "audio/x-adpcm",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
848
            "layout", G_TYPE_STRING, layout, NULL);
849 850 851 852
        if (context)
          gst_caps_set_simple (caps,
              "block_align", G_TYPE_INT, context->block_align,
              "bitrate", G_TYPE_INT, context->bit_rate, NULL);
853
      }
854 855 856
      break;

    case CODEC_ID_AMR_NB:
857
      caps = gst_ff_aud_caps_new (context, "audio/AMR", NULL);
858 859
      break;

860
    case CODEC_ID_AMR_WB:
861
      caps = gst_ff_aud_caps_new (context, "audio/AMR-WB", NULL);
862 863
      break;

864
    case CODEC_ID_RA_144:
865
    case CODEC_ID_RA_288:
866
    case CODEC_ID_COOK:
867
      {
868
        gint version = 0;
869 870 871 872 873 874 875 876 877 878
        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;
879 880
          default:
            break;
881
        }
882 883

        /* FIXME: properties? */
884
        caps = gst_ff_aud_caps_new (context, "audio/x-pn-realaudio",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
885
            "raversion", G_TYPE_INT, version, NULL);
886 887 888 889 890
        if (context) {
          gst_caps_set_simple (caps,
              "leaf_size", G_TYPE_INT, context->block_align,
              "bitrate", G_TYPE_INT, context->bit_rate, NULL);
        }
891
      }
892
      break;
893

894 895 896
    case CODEC_ID_ROQ_DPCM:
    case CODEC_ID_INTERPLAY_DPCM:
    case CODEC_ID_XAN_DPCM:
897
    case CODEC_ID_SOL_DPCM:
898
      {
899 900 901 902 903 904 905 906 907 908 909 910
        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;
911 912 913
          case CODEC_ID_SOL_DPCM:
            layout = "sol";
            break;
914
          default:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
915
            g_assert (0);       /* don't worry, we never get here */
916 917 918 919 920
            break;
        }

        /* FIXME: someone please check whether we need additional properties
         * in this caps definition. */
921
        caps = gst_ff_aud_caps_new (context, "audio/x-dpcm",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
922
            "layout", G_TYPE_STRING, layout, NULL);
923 924 925 926
        if (context)
          gst_caps_set_simple (caps,
              "block_align", G_TYPE_INT, context->block_align,
              "bitrate", G_TYPE_INT, context->bit_rate, NULL);
927
      }
928
      break;
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
929

930 931 932 933 934
    case CODEC_ID_SHORTEN:
      caps = gst_caps_new_simple ("audio/x-shorten", NULL);
      break;

    case CODEC_ID_ALAC:
935
      caps = gst_ff_aud_caps_new (context, "audio/x-alac", NULL);
936 937 938 939 940 941
      if (context) {
        gst_caps_set_simple (caps,
            "samplesize", G_TYPE_INT, context->bits_per_sample, NULL);
      }
      break;

942 943 944 945 946 947
    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);
      }
948 949
      break;

950 951 952 953
    case CODEC_ID_DVD_SUBTITLE:
    case CODEC_ID_DVB_SUBTITLE:
      caps = NULL;
      break;
954 955 956 957
    case CODEC_ID_BMP:
      caps = gst_caps_new_simple ("image/bmp", NULL);
      break;
    case CODEC_ID_TTA:
958
      caps = gst_ff_aud_caps_new (context, "audio/x-tta", NULL);
959 960 961 962