gstffmpegcodecmap.c 87.3 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
      caps = gst_ff_vid_caps_new (context, "video/x-dv",
402 403
          "systemstream", G_TYPE_BOOLEAN, FALSE,
          NULL);
404
      break;
405

406 407
    case CODEC_ID_WMAV1:
    case CODEC_ID_WMAV2:
408
      {
409 410
        gint version = (codec_id == CODEC_ID_WMAV1) ? 1 : 2;

411
        if (context) {
412
          caps = gst_ff_aud_caps_new (context, "audio/x-wma",
413 414 415
             "wmaversion", G_TYPE_INT, version,
             "block_align", G_TYPE_INT, context->block_align,
             "bitrate", G_TYPE_INT, context->bit_rate, NULL);
416
        } else {
417
          caps = gst_ff_aud_caps_new (context, "audio/x-wma",
418 419 420 421
             "wmaversion", G_TYPE_INT, version,
             "block_align", GST_TYPE_INT_RANGE, 0, G_MAXINT,
             "bitrate", GST_TYPE_INT_RANGE, 0, G_MAXINT, NULL);
        }
422
      }
423
      break;
424

425 426
    case CODEC_ID_MACE3:
    case CODEC_ID_MACE6:
427
      {
428 429
        gint version = (codec_id == CODEC_ID_MACE3) ? 3 : 6;

430
        caps = gst_ff_aud_caps_new (context, "audio/x-mace",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
431
            "maceversion", G_TYPE_INT, version, NULL);
432
      }
433
      break;
434

Wim Taymans's avatar
Wim Taymans committed
435
    case CODEC_ID_HUFFYUV:
436
      caps = gst_ff_vid_caps_new (context, "video/x-huffyuv", NULL);
437 438 439 440
      if (context) {
        gst_caps_set_simple (caps,
            "bpp", G_TYPE_INT, context->bits_per_sample, NULL);
      }
441 442 443
      break;

    case CODEC_ID_CYUV:
444
      caps = gst_ff_vid_caps_new (context, "video/x-compressed-yuv", NULL);
445 446 447
      break;

    case CODEC_ID_H264:
448
      caps = gst_ff_vid_caps_new (context, "video/x-h264", NULL);
449 450 451
      break;

    case CODEC_ID_INDEO3:
452
      caps = gst_ff_vid_caps_new (context, "video/x-indeo",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
453
          "indeoversion", G_TYPE_INT, 3, NULL);
454 455
      break;

456
    case CODEC_ID_INDEO2:
457
      caps = gst_ff_vid_caps_new (context, "video/x-indeo",
458 459 460
          "indeoversion", G_TYPE_INT, 2, NULL);
      break;

461 462 463 464
    case CODEC_ID_FLASHSV:
      caps = gst_ff_vid_caps_new (context, "video/x-flash-screen", NULL);
      break;

465
    case CODEC_ID_VP3:
466
      caps = gst_ff_vid_caps_new (context, "video/x-vp3", NULL);
467 468
      break;

469 470 471 472 473 474 475 476 477 478 479 480
    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;

481
    case CODEC_ID_THEORA:
482
      caps = gst_ff_vid_caps_new (context, "video/x-theora", NULL);
483 484
      break;

485
    case CODEC_ID_AAC:
486
    case CODEC_ID_MPEG4AAC:
487
      caps = gst_ff_aud_caps_new (context, "audio/mpeg",
488
          "mpegversion", G_TYPE_INT, 4, NULL);
489 490 491
      break;

    case CODEC_ID_ASV1:
492
      caps = gst_ff_vid_caps_new (context, "video/x-asus",
493 494
				  "asusversion", G_TYPE_INT, 1, NULL);
      break;
495
    case CODEC_ID_ASV2:
496
      caps = gst_ff_vid_caps_new (context, "video/x-asus",
497
				  "asusversion", G_TYPE_INT, 2, NULL);
498 499
      break;

500
    case CODEC_ID_FFV1:
501
      caps = gst_ff_vid_caps_new (context, "video/x-ffv",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
502
          "ffvversion", G_TYPE_INT, 1, NULL);
503 504 505
      break;

    case CODEC_ID_4XM:
506
      caps = gst_ff_vid_caps_new (context, "video/x-4xm", NULL);
507 508
      break;

509 510
    case CODEC_ID_XAN_WC3:
    case CODEC_ID_XAN_WC4:
511
      caps = gst_ff_vid_caps_new (context, "video/x-xan",
512 513 514
          "wcversion", G_TYPE_INT, 3 - CODEC_ID_XAN_WC3 + codec_id, NULL);
      break;

515
    case CODEC_ID_CLJR:
516
      caps = gst_ff_vid_caps_new (context, "video/x-cirrus-logic-accupak", NULL);
517 518 519
      break;

    case CODEC_ID_FRAPS:
520 521 522 523 524 525
    case CODEC_ID_MDEC:
    case CODEC_ID_ROQ:
    case CODEC_ID_INTERPLAY_VIDEO:
      buildcaps = TRUE;
      break;

526
    case CODEC_ID_VCR1:
527
      caps = gst_ff_vid_caps_new (context, "video/x-ati-vcr", 
528 529 530
				  "vcrversion", G_TYPE_INT, 1, NULL);
      break;

531
    case CODEC_ID_RPZA:
532
      caps = gst_ff_vid_caps_new (context, "video/x-apple-video", NULL);
533 534
      break;

535
    case CODEC_ID_CINEPAK:
536
      caps = gst_ff_vid_caps_new (context, "video/x-cinepak", NULL);
537 538
      break;

539 540 541
    /* WS_VQA belogns here (order) */

    case CODEC_ID_MSRLE:
542
      caps = gst_ff_vid_caps_new (context, "video/x-rle",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
543
          "layout", G_TYPE_STRING, "microsoft", NULL);
544 545
      if (context) {
        gst_caps_set_simple (caps,
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
546
            "depth", G_TYPE_INT, (gint) context->bits_per_sample, NULL);
547 548 549 550 551
      } else {
        gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 1, 64, NULL);
      }
      break;

552
    case CODEC_ID_QTRLE:
553
      caps = gst_ff_vid_caps_new (context, "video/x-rle",
554 555 556 557 558 559 560 561 562
          "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;

563
    case CODEC_ID_MSVIDEO1:
564
      caps = gst_ff_vid_caps_new (context, "video/x-msvideocodec",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
565
          "msvideoversion", G_TYPE_INT, 1, NULL);
566 567
      break;

568
    case CODEC_ID_WMV3:
569
    case CODEC_ID_VC1:
570
      caps = gst_ff_vid_caps_new (context, "video/x-wmv",
571 572
          "wmvversion", G_TYPE_INT, 3, NULL);
      break;
573
    case CODEC_ID_QDM2:
574
      caps = gst_ff_aud_caps_new (context, "audio/x-qdm2", NULL);
575
      break;  
576

577
    case CODEC_ID_MSZH:
578
      caps = gst_ff_vid_caps_new (context, "video/x-mszh", NULL);
579 580 581
      break;

    case CODEC_ID_ZLIB:
582
      caps = gst_ff_vid_caps_new (context, "video/x-zlib", NULL);
583 584 585
      break;

    case CODEC_ID_TRUEMOTION1:
586
      caps = gst_ff_vid_caps_new (context, "video/x-truemotion",
587 588 589
				  "trueversion", G_TYPE_INT, 1, NULL);
      break;
    case CODEC_ID_TRUEMOTION2:
590
      caps = gst_ff_vid_caps_new (context, "video/x-truemotion",
591 592 593 594
				  "trueversion", G_TYPE_INT, 2, NULL);
      break;

    case CODEC_ID_ULTI:
595
      caps = gst_ff_vid_caps_new (context, "video/x-ultimotion",
596 597 598 599
				  NULL);
      break;

    case CODEC_ID_TSCC:
600
      caps = gst_ff_vid_caps_new (context, "video/x-camtasia", NULL);
601 602 603
      break;

    case CODEC_ID_PNG:
604
      caps = gst_ff_vid_caps_new (context, "image/png", NULL);
605 606
      break;

607
    case CODEC_ID_SMC:
608
      caps = gst_ff_vid_caps_new (context, "video/x-smc", NULL);
609 610
      break;

611
    case CODEC_ID_QDRAW:
612
      caps = gst_ff_vid_caps_new (context, "video/x-qdrw", NULL);
613 614
      break;

615 616 617 618 619 620
    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:
621 622 623 624 625 626 627 628 629 630 631 632
    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_PPM:
    case CODEC_ID_PBM:
    case CODEC_ID_PGM:
    case CODEC_ID_PGMYUV:
    case CODEC_ID_PAM:
    case CODEC_ID_FFVHUFF:
633 634 635 636 637 638
    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:
639 640 641 642 643
    case CODEC_ID_CSCD:
    case CODEC_ID_MMVIDEO:
    case CODEC_ID_ZMBV:
    case CODEC_ID_AVS:
    case CODEC_ID_TRUESPEECH:
644
    case CODEC_ID_CAVS:
645 646 647
      buildcaps = TRUE;
      break;

Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
648
      /* weird quasi-codecs for the demuxers only */
649 650 651 652 653 654
    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:
655
      {
656
        gint width = 0, depth = 0, endianness = 0;
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
657
        gboolean signedness = FALSE;    /* blabla */
658 659 660

        switch (codec_id) {
          case CODEC_ID_PCM_S16LE:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
661 662
            width = 16;
            depth = 16;
663 664 665 666
            endianness = G_LITTLE_ENDIAN;
            signedness = TRUE;
            break;
          case CODEC_ID_PCM_S16BE:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
667 668
            width = 16;
            depth = 16;
669 670 671 672
            endianness = G_BIG_ENDIAN;
            signedness = TRUE;
            break;
          case CODEC_ID_PCM_U16LE:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
673 674
            width = 16;
            depth = 16;
675 676 677 678
            endianness = G_LITTLE_ENDIAN;
            signedness = FALSE;
            break;
          case CODEC_ID_PCM_U16BE:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
679 680
            width = 16;
            depth = 16;
681 682 683 684
            endianness = G_BIG_ENDIAN;
            signedness = FALSE;
            break;
          case CODEC_ID_PCM_S8:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
685 686
            width = 8;
            depth = 8;
687 688 689 690
            endianness = G_BYTE_ORDER;
            signedness = TRUE;
            break;
          case CODEC_ID_PCM_U8:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
691 692
            width = 8;
            depth = 8;
693 694 695 696
            endianness = G_BYTE_ORDER;
            signedness = FALSE;
            break;
          default:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
697
            g_assert (0);       /* don't worry, we never get here */
698 699 700
            break;
        }

701
        caps = gst_ff_aud_caps_new (context, "audio/x-raw-int",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
702 703 704 705
            "width", G_TYPE_INT, width,
            "depth", G_TYPE_INT, depth,
            "endianness", G_TYPE_INT, endianness,
            "signed", G_TYPE_BOOLEAN, signedness, NULL);
706
      }
707 708
      break;

709
    case CODEC_ID_PCM_MULAW:
710
      caps = gst_ff_aud_caps_new (context, "audio/x-mulaw", NULL);
711 712 713
      break;

    case CODEC_ID_PCM_ALAW:
714
      caps = gst_ff_aud_caps_new (context, "audio/x-alaw", NULL);
715 716
      break;

717 718
    case CODEC_ID_ADPCM_IMA_QT:
    case CODEC_ID_ADPCM_IMA_WAV:
719 720 721 722
    case CODEC_ID_ADPCM_IMA_DK3:
    case CODEC_ID_ADPCM_IMA_DK4:
    case CODEC_ID_ADPCM_IMA_WS:
    case CODEC_ID_ADPCM_IMA_SMJPEG:
723
    case CODEC_ID_ADPCM_MS:
724
    case CODEC_ID_ADPCM_4XM:
725 726 727 728
    case CODEC_ID_ADPCM_XA:
    case CODEC_ID_ADPCM_ADX:
    case CODEC_ID_ADPCM_EA:
    case CODEC_ID_ADPCM_G726:
729
    case CODEC_ID_ADPCM_CT:
730
    case CODEC_ID_ADPCM_SWF:
731
    case CODEC_ID_ADPCM_YAMAHA:
732 733 734
    case CODEC_ID_ADPCM_SBPRO_2:
    case CODEC_ID_ADPCM_SBPRO_3:
    case CODEC_ID_ADPCM_SBPRO_4:
735
      {
736 737 738 739 740 741 742
        gchar *layout = NULL;

        switch (codec_id) {
          case CODEC_ID_ADPCM_IMA_QT:
            layout = "quicktime";
            break;
          case CODEC_ID_ADPCM_IMA_WAV:
743
            layout = "dvi";
744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774
            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;
775 776 777
          case CODEC_ID_ADPCM_CT:
            layout = "ct";
            break;
778 779 780
          case CODEC_ID_ADPCM_SWF:
            layout = "swf";
            break;
781 782 783
          case CODEC_ID_ADPCM_YAMAHA:
            layout = "yamaha";
            break;
784 785 786 787 788 789 790 791 792
          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;
793
          default:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
794
            g_assert (0);       /* don't worry, we never get here */
795 796 797 798 799
            break;
        }

        /* FIXME: someone please check whether we need additional properties
         * in this caps definition. */
800
        caps = gst_ff_aud_caps_new (context, "audio/x-adpcm",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
801
            "layout", G_TYPE_STRING, layout, NULL);
802 803 804 805
        if (context)
          gst_caps_set_simple (caps,
              "block_align", G_TYPE_INT, context->block_align,
              "bitrate", G_TYPE_INT, context->bit_rate, NULL);
806
      }
807 808 809
      break;

    case CODEC_ID_AMR_NB:
810
      caps = gst_ff_aud_caps_new (context, "audio/x-amr-nb", NULL);
811 812
      break;

813
    case CODEC_ID_AMR_WB:
814
      caps = gst_ff_aud_caps_new (context, "audio/x-amr-wb", NULL);
815 816
      break;

817
    case CODEC_ID_RA_144:
818
    case CODEC_ID_RA_288:
819
    case CODEC_ID_COOK:
820
      {
821
        gint version = 0;
822 823 824 825 826 827 828 829 830 831
        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;
832 833
          default:
            break;
834
        }
835 836

        /* FIXME: properties? */
837
        caps = gst_ff_aud_caps_new (context, "audio/x-pn-realaudio",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
838
            "raversion", G_TYPE_INT, version, NULL);
839 840 841 842 843
        if (context) {
          gst_caps_set_simple (caps,
              "leaf_size", G_TYPE_INT, context->block_align,
              "bitrate", G_TYPE_INT, context->bit_rate, NULL);
        }
844
      }
845
      break;
846

847 848 849
    case CODEC_ID_ROQ_DPCM:
    case CODEC_ID_INTERPLAY_DPCM:
    case CODEC_ID_XAN_DPCM:
850
    case CODEC_ID_SOL_DPCM:
851
      {
852 853 854 855 856 857 858 859 860 861 862 863
        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;
864 865 866
          case CODEC_ID_SOL_DPCM:
            layout = "sol";
            break;
867
          default:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
868
            g_assert (0);       /* don't worry, we never get here */
869 870 871 872 873
            break;
        }

        /* FIXME: someone please check whether we need additional properties
         * in this caps definition. */
874
        caps = gst_ff_aud_caps_new (context, "audio/x-dpcm",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
875
            "layout", G_TYPE_STRING, layout, NULL);
876 877 878 879
        if (context)
          gst_caps_set_simple (caps,
              "block_align", G_TYPE_INT, context->block_align,
              "bitrate", G_TYPE_INT, context->bit_rate, NULL);
880
      }
881
      break;
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
882

883 884 885 886 887
    case CODEC_ID_SHORTEN:
      caps = gst_caps_new_simple ("audio/x-shorten", NULL);
      break;

    case CODEC_ID_ALAC:
888
      caps = gst_ff_aud_caps_new (context, "audio/x-alac", NULL);
889 890 891 892 893 894
      if (context) {
        gst_caps_set_simple (caps,
            "samplesize", G_TYPE_INT, context->bits_per_sample, NULL);
      }
      break;

895 896 897 898 899 900
    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);
      }
901 902
      break;

903 904 905 906
    case CODEC_ID_DVD_SUBTITLE:
    case CODEC_ID_DVB_SUBTITLE:
      caps = NULL;
      break;
907 908 909 910
    case CODEC_ID_BMP:
      caps = gst_caps_new_simple ("image/bmp", NULL);
      break;
    case CODEC_ID_TTA:
911
      caps = gst_ff_aud_caps_new (context, "audio/x-tta", NULL);
912 913 914 915 916
      if (context) {
        gst_caps_set_simple (caps,
            "samplesize", G_TYPE_INT, context->bits_per_sample, NULL);
      }
      break;
917
    default:
918
      g_warning ("Unknown codec ID %d, please add here", codec_id);
919 920 921
      break;
  }

922 923 924 925 926 927 928
  if (buildcaps) {
    AVCodec *codec;

    if ((codec = avcodec_find_decoder (codec_id)) ||
        (codec = avcodec_find_encoder (codec_id))) {
      gchar *mime = NULL;

929 930
      GST_LOG ("Could not create stream format caps for %s",
	       codec->name);
931
      
932 933 934
      switch (codec->type) {
        case CODEC_TYPE_VIDEO:
          mime = g_strdup_printf ("video/x-gst_ff-%s", codec->name);
935
          caps = gst_ff_vid_caps_new (context, mime, NULL<