gstffmpegcodecmap.c 86.1 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
    case CODEC_ID_THEORA:
466
      caps = gst_ff_vid_caps_new (context, "video/x-theora", NULL);
467 468
      break;

469
    case CODEC_ID_AAC:
470
    case CODEC_ID_MPEG4AAC:
471
      caps = gst_ff_aud_caps_new (context, "audio/mpeg",
472
          "mpegversion", G_TYPE_INT, 4, NULL);
473 474 475
      break;

    case CODEC_ID_ASV1:
476
      caps = gst_ff_vid_caps_new (context, "video/x-asus",
477 478
				  "asusversion", G_TYPE_INT, 1, NULL);
      break;
479
    case CODEC_ID_ASV2:
480
      caps = gst_ff_vid_caps_new (context, "video/x-asus",
481
				  "asusversion", G_TYPE_INT, 2, NULL);
482 483
      break;

484
    case CODEC_ID_FFV1:
485
      caps = gst_ff_vid_caps_new (context, "video/x-ffv",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
486
          "ffvversion", G_TYPE_INT, 1, NULL);
487 488 489
      break;

    case CODEC_ID_4XM:
490
      caps = gst_ff_vid_caps_new (context, "video/x-4xm", NULL);
491 492
      break;

493 494
    case CODEC_ID_XAN_WC3:
    case CODEC_ID_XAN_WC4:
495
      caps = gst_ff_vid_caps_new (context, "video/x-xan",
496 497 498
          "wcversion", G_TYPE_INT, 3 - CODEC_ID_XAN_WC3 + codec_id, NULL);
      break;

499
    case CODEC_ID_CLJR:
500
      caps = gst_ff_vid_caps_new (context, "video/x-cirrus-logic-accupak", NULL);
501 502 503
      break;

    case CODEC_ID_FRAPS:
504 505 506 507 508 509
    case CODEC_ID_MDEC:
    case CODEC_ID_ROQ:
    case CODEC_ID_INTERPLAY_VIDEO:
      buildcaps = TRUE;
      break;

510
    case CODEC_ID_VCR1:
511
      caps = gst_ff_vid_caps_new (context, "video/x-ati-vcr", 
512 513 514
				  "vcrversion", G_TYPE_INT, 1, NULL);
      break;

515
    case CODEC_ID_RPZA:
516
      caps = gst_ff_vid_caps_new (context, "video/x-apple-video", NULL);
517 518
      break;

519
    case CODEC_ID_CINEPAK:
520
      caps = gst_ff_vid_caps_new (context, "video/x-cinepak", NULL);
521 522
      break;

523 524 525
    /* WS_VQA belogns here (order) */

    case CODEC_ID_MSRLE:
526
      caps = gst_ff_vid_caps_new (context, "video/x-rle",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
527
          "layout", G_TYPE_STRING, "microsoft", NULL);
528 529
      if (context) {
        gst_caps_set_simple (caps,
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
530
            "depth", G_TYPE_INT, (gint) context->bits_per_sample, NULL);
531 532 533 534 535
      } else {
        gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 1, 64, NULL);
      }
      break;

536
    case CODEC_ID_QTRLE:
537
      caps = gst_ff_vid_caps_new (context, "video/x-rle",
538 539 540 541 542 543 544 545 546
          "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;

547
    case CODEC_ID_MSVIDEO1:
548
      caps = gst_ff_vid_caps_new (context, "video/x-msvideocodec",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
549
          "msvideoversion", G_TYPE_INT, 1, NULL);
550 551
      break;

552
    case CODEC_ID_WMV3:
553
    case CODEC_ID_VC1:
554
      caps = gst_ff_vid_caps_new (context, "video/x-wmv",
555 556
          "wmvversion", G_TYPE_INT, 3, NULL);
      break;
557
    case CODEC_ID_QDM2:
558
      caps = gst_ff_aud_caps_new (context, "audio/x-qdm2", NULL);
559
      break;  
560

561
    case CODEC_ID_MSZH:
562
      caps = gst_ff_vid_caps_new (context, "video/x-mszh", NULL);
563 564 565
      break;

    case CODEC_ID_ZLIB:
566
      caps = gst_ff_vid_caps_new (context, "video/x-zlib", NULL);
567 568 569
      break;

    case CODEC_ID_TRUEMOTION1:
570
      caps = gst_ff_vid_caps_new (context, "video/x-truemotion",
571 572 573
				  "trueversion", G_TYPE_INT, 1, NULL);
      break;
    case CODEC_ID_TRUEMOTION2:
574
      caps = gst_ff_vid_caps_new (context, "video/x-truemotion",
575 576 577 578
				  "trueversion", G_TYPE_INT, 2, NULL);
      break;

    case CODEC_ID_ULTI:
579
      caps = gst_ff_vid_caps_new (context, "video/x-ultimotion",
580 581 582 583
				  NULL);
      break;

    case CODEC_ID_TSCC:
584
      caps = gst_ff_vid_caps_new (context, "video/x-camtasia", NULL);
585 586 587
      break;

    case CODEC_ID_PNG:
588
      caps = gst_ff_vid_caps_new (context, "image/png", NULL);
589 590
      break;

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

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

599 600 601 602 603 604
    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:
605 606 607 608 609 610 611 612 613 614 615 616
    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:
617 618 619 620 621 622
    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:
623 624 625 626 627
    case CODEC_ID_CSCD:
    case CODEC_ID_MMVIDEO:
    case CODEC_ID_ZMBV:
    case CODEC_ID_AVS:
    case CODEC_ID_TRUESPEECH:
628 629 630
      buildcaps = TRUE;
      break;

Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
631
      /* weird quasi-codecs for the demuxers only */
632 633 634 635 636 637
    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:
638
      {
639
        gint width = 0, depth = 0, endianness = 0;
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
640
        gboolean signedness = FALSE;    /* blabla */
641 642 643

        switch (codec_id) {
          case CODEC_ID_PCM_S16LE:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
644 645
            width = 16;
            depth = 16;
646 647 648 649
            endianness = G_LITTLE_ENDIAN;
            signedness = TRUE;
            break;
          case CODEC_ID_PCM_S16BE:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
650 651
            width = 16;
            depth = 16;
652 653 654 655
            endianness = G_BIG_ENDIAN;
            signedness = TRUE;
            break;
          case CODEC_ID_PCM_U16LE:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
656 657
            width = 16;
            depth = 16;
658 659 660 661
            endianness = G_LITTLE_ENDIAN;
            signedness = FALSE;
            break;
          case CODEC_ID_PCM_U16BE:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
662 663
            width = 16;
            depth = 16;
664 665 666 667
            endianness = G_BIG_ENDIAN;
            signedness = FALSE;
            break;
          case CODEC_ID_PCM_S8:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
668 669
            width = 8;
            depth = 8;
670 671 672 673
            endianness = G_BYTE_ORDER;
            signedness = TRUE;
            break;
          case CODEC_ID_PCM_U8:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
674 675
            width = 8;
            depth = 8;
676 677 678 679
            endianness = G_BYTE_ORDER;
            signedness = FALSE;
            break;
          default:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
680
            g_assert (0);       /* don't worry, we never get here */
681 682 683
            break;
        }

684
        caps = gst_ff_aud_caps_new (context, "audio/x-raw-int",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
685 686 687 688
            "width", G_TYPE_INT, width,
            "depth", G_TYPE_INT, depth,
            "endianness", G_TYPE_INT, endianness,
            "signed", G_TYPE_BOOLEAN, signedness, NULL);
689
      }
690 691
      break;

692
    case CODEC_ID_PCM_MULAW:
693
      caps = gst_ff_aud_caps_new (context, "audio/x-mulaw", NULL);
694 695 696
      break;

    case CODEC_ID_PCM_ALAW:
697
      caps = gst_ff_aud_caps_new (context, "audio/x-alaw", NULL);
698 699
      break;

700 701
    case CODEC_ID_ADPCM_IMA_QT:
    case CODEC_ID_ADPCM_IMA_WAV:
702 703 704 705
    case CODEC_ID_ADPCM_IMA_DK3:
    case CODEC_ID_ADPCM_IMA_DK4:
    case CODEC_ID_ADPCM_IMA_WS:
    case CODEC_ID_ADPCM_IMA_SMJPEG:
706
    case CODEC_ID_ADPCM_MS:
707
    case CODEC_ID_ADPCM_4XM:
708 709 710 711
    case CODEC_ID_ADPCM_XA:
    case CODEC_ID_ADPCM_ADX:
    case CODEC_ID_ADPCM_EA:
    case CODEC_ID_ADPCM_G726:
712
    case CODEC_ID_ADPCM_CT:
713
    case CODEC_ID_ADPCM_SWF:
714
    case CODEC_ID_ADPCM_YAMAHA:
715 716 717
    case CODEC_ID_ADPCM_SBPRO_2:
    case CODEC_ID_ADPCM_SBPRO_3:
    case CODEC_ID_ADPCM_SBPRO_4:
718
      {
719 720 721 722 723 724 725
        gchar *layout = NULL;

        switch (codec_id) {
          case CODEC_ID_ADPCM_IMA_QT:
            layout = "quicktime";
            break;
          case CODEC_ID_ADPCM_IMA_WAV:
726
            layout = "dvi";
727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757
            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;
758 759 760
          case CODEC_ID_ADPCM_CT:
            layout = "ct";
            break;
761 762 763
          case CODEC_ID_ADPCM_SWF:
            layout = "swf";
            break;
764 765 766
          case CODEC_ID_ADPCM_YAMAHA:
            layout = "yamaha";
            break;
767 768 769 770 771 772 773 774 775
          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;
776
          default:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
777
            g_assert (0);       /* don't worry, we never get here */
778 779 780 781 782
            break;
        }

        /* FIXME: someone please check whether we need additional properties
         * in this caps definition. */
783
        caps = gst_ff_aud_caps_new (context, "audio/x-adpcm",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
784
            "layout", G_TYPE_STRING, layout, NULL);
785 786 787 788
        if (context)
          gst_caps_set_simple (caps,
              "block_align", G_TYPE_INT, context->block_align,
              "bitrate", G_TYPE_INT, context->bit_rate, NULL);
789
      }
790 791 792
      break;

    case CODEC_ID_AMR_NB:
793
      caps = gst_ff_aud_caps_new (context, "audio/x-amr-nb", NULL);
794 795
      break;

796
    case CODEC_ID_AMR_WB:
797
      caps = gst_ff_aud_caps_new (context, "audio/x-amr-wb", NULL);
798 799
      break;

800
    case CODEC_ID_RA_144:
801
    case CODEC_ID_RA_288:
802
    case CODEC_ID_COOK:
803
      {
804
        gint version = 0;
805 806 807 808 809 810 811 812 813 814
        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;
815 816
          default:
            break;
817
        }
818 819

        /* FIXME: properties? */
820
        caps = gst_ff_aud_caps_new (context, "audio/x-pn-realaudio",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
821
            "raversion", G_TYPE_INT, version, NULL);
822 823 824 825 826
        if (context) {
          gst_caps_set_simple (caps,
              "leaf_size", G_TYPE_INT, context->block_align,
              "bitrate", G_TYPE_INT, context->bit_rate, NULL);
        }
827
      }
828
      break;
829

830 831 832
    case CODEC_ID_ROQ_DPCM:
    case CODEC_ID_INTERPLAY_DPCM:
    case CODEC_ID_XAN_DPCM:
833
    case CODEC_ID_SOL_DPCM:
834
      {
835 836 837 838 839 840 841 842 843 844 845 846
        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;
847 848 849
          case CODEC_ID_SOL_DPCM:
            layout = "sol";
            break;
850
          default:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
851
            g_assert (0);       /* don't worry, we never get here */
852 853 854 855 856
            break;
        }

        /* FIXME: someone please check whether we need additional properties
         * in this caps definition. */
857
        caps = gst_ff_aud_caps_new (context, "audio/x-dpcm",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
858
            "layout", G_TYPE_STRING, layout, NULL);
859 860 861 862
        if (context)
          gst_caps_set_simple (caps,
              "block_align", G_TYPE_INT, context->block_align,
              "bitrate", G_TYPE_INT, context->bit_rate, NULL);
863
      }
864
      break;
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
865

866 867 868 869 870
    case CODEC_ID_SHORTEN:
      caps = gst_caps_new_simple ("audio/x-shorten", NULL);
      break;

    case CODEC_ID_ALAC:
871
      caps = gst_ff_aud_caps_new (context, "audio/x-alac", NULL);
872 873 874 875 876 877
      if (context) {
        gst_caps_set_simple (caps,
            "samplesize", G_TYPE_INT, context->bits_per_sample, NULL);
      }
      break;

878 879 880 881 882 883
    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);
      }
884 885
      break;

886 887 888 889
    case CODEC_ID_DVD_SUBTITLE:
    case CODEC_ID_DVB_SUBTITLE:
      caps = NULL;
      break;
890 891 892 893
    case CODEC_ID_BMP:
      caps = gst_caps_new_simple ("image/bmp", NULL);
      break;
    case CODEC_ID_TTA:
894
      caps = gst_ff_aud_caps_new (context, "audio/x-tta", NULL);
895 896 897 898 899
      if (context) {
        gst_caps_set_simple (caps,
            "samplesize", G_TYPE_INT, context->bits_per_sample, NULL);
      }
      break;
900
    default:
901
      g_warning ("Unknown codec ID %d, please add here", codec_id);
902 903 904
      break;
  }

905 906 907 908 909 910 911
  if (buildcaps) {
    AVCodec *codec;

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

912 913
      GST_LOG ("Could not create stream format caps for %s",
	       codec->name);
914
      
915 916 917
      switch (codec->type) {
        case CODEC_TYPE_VIDEO:
          mime = g_strdup_printf ("video/x-gst_ff-%s", codec->name);
918
          caps = gst_ff_vid_caps_new (context, mime, NULL);
919 920 921 922
          g_free (mime);
          break;
        case CODEC_TYPE_AUDIO:
          mime = g_strdup_printf ("audio/x-gst_ff-%s", codec->name);
923
          caps = gst_ff_aud_caps_new (context, mime, NULL);
924
          if (context)
925 926 927
            gst_caps_set_simple (caps,
                "block_align", G_TYPE_INT, context->block_align,
                "bitrate", G_TYPE_INT, context->bit_rate, NULL);