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 87 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
    case CODEC_ID_VP3:
462
      caps = gst_ff_vid_caps_new (context, "video/x-vp3", NULL);
463 464
      break;

465 466 467 468 469 470 471 472 473 474 475 476
    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;

477
    case CODEC_ID_THEORA:
478
      caps = gst_ff_vid_caps_new (context, "video/x-theora", NULL);
479 480
      break;

481
    case CODEC_ID_AAC:
482
    case CODEC_ID_MPEG4AAC:
483
      caps = gst_ff_aud_caps_new (context, "audio/mpeg",
484
          "mpegversion", G_TYPE_INT, 4, NULL);
485 486 487
      break;

    case CODEC_ID_ASV1:
488
      caps = gst_ff_vid_caps_new (context, "video/x-asus",
489 490
				  "asusversion", G_TYPE_INT, 1, NULL);
      break;
491
    case CODEC_ID_ASV2:
492
      caps = gst_ff_vid_caps_new (context, "video/x-asus",
493
				  "asusversion", G_TYPE_INT, 2, NULL);
494 495
      break;

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

    case CODEC_ID_4XM:
502
      caps = gst_ff_vid_caps_new (context, "video/x-4xm", NULL);
503 504
      break;

505 506
    case CODEC_ID_XAN_WC3:
    case CODEC_ID_XAN_WC4:
507
      caps = gst_ff_vid_caps_new (context, "video/x-xan",
508 509 510
          "wcversion", G_TYPE_INT, 3 - CODEC_ID_XAN_WC3 + codec_id, NULL);
      break;

511
    case CODEC_ID_CLJR:
512
      caps = gst_ff_vid_caps_new (context, "video/x-cirrus-logic-accupak", NULL);
513 514 515
      break;

    case CODEC_ID_FRAPS:
516 517 518 519 520 521
    case CODEC_ID_MDEC:
    case CODEC_ID_ROQ:
    case CODEC_ID_INTERPLAY_VIDEO:
      buildcaps = TRUE;
      break;

522
    case CODEC_ID_VCR1:
523
      caps = gst_ff_vid_caps_new (context, "video/x-ati-vcr", 
524 525 526
				  "vcrversion", G_TYPE_INT, 1, NULL);
      break;

527
    case CODEC_ID_RPZA:
528
      caps = gst_ff_vid_caps_new (context, "video/x-apple-video", NULL);
529 530
      break;

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

535 536 537
    /* WS_VQA belogns here (order) */

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

548
    case CODEC_ID_QTRLE:
549
      caps = gst_ff_vid_caps_new (context, "video/x-rle",
550 551 552 553 554 555 556 557 558
          "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;

559
    case CODEC_ID_MSVIDEO1:
560
      caps = gst_ff_vid_caps_new (context, "video/x-msvideocodec",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
561
          "msvideoversion", G_TYPE_INT, 1, NULL);
562 563
      break;

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

573
    case CODEC_ID_MSZH:
574
      caps = gst_ff_vid_caps_new (context, "video/x-mszh", NULL);
575 576 577
      break;

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

    case CODEC_ID_TRUEMOTION1:
582
      caps = gst_ff_vid_caps_new (context, "video/x-truemotion",
583 584 585
				  "trueversion", G_TYPE_INT, 1, NULL);
      break;
    case CODEC_ID_TRUEMOTION2:
586
      caps = gst_ff_vid_caps_new (context, "video/x-truemotion",
587 588 589 590
				  "trueversion", G_TYPE_INT, 2, NULL);
      break;

    case CODEC_ID_ULTI:
591
      caps = gst_ff_vid_caps_new (context, "video/x-ultimotion",
592 593 594 595
				  NULL);
      break;

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

    case CODEC_ID_PNG:
600
      caps = gst_ff_vid_caps_new (context, "image/png", NULL);
601 602
      break;

603
    case CODEC_ID_SMC:
604
      caps = gst_ff_vid_caps_new (context, "video/x-smc", NULL);
605 606
      break;

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

611 612 613 614 615 616
    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:
617 618 619 620 621 622 623 624 625 626 627 628
    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:
629 630 631 632 633 634
    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:
635 636 637 638 639
    case CODEC_ID_CSCD:
    case CODEC_ID_MMVIDEO:
    case CODEC_ID_ZMBV:
    case CODEC_ID_AVS:
    case CODEC_ID_TRUESPEECH:
640
    case CODEC_ID_CAVS:
641 642 643
      buildcaps = TRUE;
      break;

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

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

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

705
    case CODEC_ID_PCM_MULAW:
706
      caps = gst_ff_aud_caps_new (context, "audio/x-mulaw", NULL);
707 708 709
      break;

    case CODEC_ID_PCM_ALAW:
710
      caps = gst_ff_aud_caps_new (context, "audio/x-alaw", NULL);
711 712
      break;

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

        switch (codec_id) {
          case CODEC_ID_ADPCM_IMA_QT:
            layout = "quicktime";
            break;
          case CODEC_ID_ADPCM_IMA_WAV:
739
            layout = "dvi";
740 741 742 743 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
            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;
771 772 773
          case CODEC_ID_ADPCM_CT:
            layout = "ct";
            break;
774 775 776
          case CODEC_ID_ADPCM_SWF:
            layout = "swf";
            break;
777 778 779
          case CODEC_ID_ADPCM_YAMAHA:
            layout = "yamaha";
            break;
780 781 782 783 784 785 786 787 788
          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;
789
          default:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
790
            g_assert (0);       /* don't worry, we never get here */
791 792 793 794 795
            break;
        }

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

    case CODEC_ID_AMR_NB:
806
      caps = gst_ff_aud_caps_new (context, "audio/x-amr-nb", NULL);
807 808
      break;

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

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

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

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

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

879 880 881 882 883
    case CODEC_ID_SHORTEN:
      caps = gst_caps_new_simple ("audio/x-shorten", NULL);
      break;

    case CODEC_ID_ALAC:
884
      caps = gst_ff_aud_caps_new (context, "audio/x-alac", NULL);
885 886 887 888 889 890
      if (context) {
        gst_caps_set_simple (caps,
            "samplesize", G_TYPE_INT, context->bits_per_sample, NULL);
      }
      break;

891 892 893 894 895 896
    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);
      }
897 898
      break;

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

918 919 920 921 922 923 924
  if (buildcaps) {
    AVCodec *codec;

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

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