gstffmpegcodecmap.c 91.9 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
#ifdef HAVE_FFMPEG_UNINSTALLED
#include <avcodec.h>
#else
29
#include <libavcodec/avcodec.h>
30
#endif
31
#include <string.h>
32

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

36 37 38 39 40
/*
 * Read a palette from a caps.
 */

static void
41
gst_ffmpeg_get_palette (const GstCaps * caps, AVCodecContext * context)
42 43 44 45 46 47
{
  GstStructure *str = gst_caps_get_structure (caps, 0);
  const GValue *palette_v;
  const GstBuffer *palette;

  /* do we have a palette? */
48
  if ((palette_v = gst_structure_get_value (str, "palette_data")) && context) {
49
    palette = gst_value_get_buffer (palette_v);
50
    if (GST_BUFFER_SIZE (palette) >= AVPALETTE_SIZE) {
51 52 53 54 55 56 57 58 59 60 61
      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
62
gst_ffmpeg_set_palette (GstCaps * caps, AVCodecContext * context)
63 64
{
  if (context->palctrl) {
65
    GstBuffer *palette = gst_buffer_new_and_alloc (AVPALETTE_SIZE);
66 67 68

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

73 74 75 76 77 78 79 80 81 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 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
/* IMPORTANT: Keep this sorted by the ffmpeg channel masks */
static const struct
{
  guint64 ff;
  GstAudioChannelPosition gst;
} _ff_to_gst_layout[] = {
  {
  CH_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT}, {
  CH_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}, {
  CH_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER}, {
  CH_LOW_FREQUENCY, GST_AUDIO_CHANNEL_POSITION_LFE}, {
  CH_BACK_LEFT, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT}, {
  CH_BACK_RIGHT, GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}, {
  CH_FRONT_LEFT_OF_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER}, {
  CH_FRONT_RIGHT_OF_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER}, {
  CH_BACK_CENTER, GST_AUDIO_CHANNEL_POSITION_REAR_CENTER}, {
  CH_SIDE_LEFT, GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT}, {
  CH_SIDE_RIGHT, GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT}, {
  CH_TOP_CENTER, GST_AUDIO_CHANNEL_POSITION_NONE}, {
  CH_TOP_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_NONE}, {
  CH_TOP_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_NONE}, {
  CH_TOP_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_NONE}, {
  CH_TOP_BACK_LEFT, GST_AUDIO_CHANNEL_POSITION_NONE}, {
  CH_TOP_BACK_CENTER, GST_AUDIO_CHANNEL_POSITION_NONE}, {
  CH_TOP_BACK_RIGHT, GST_AUDIO_CHANNEL_POSITION_NONE}, {
  CH_STEREO_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT}, {
  CH_STEREO_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}
};

static GstAudioChannelPosition *
gst_ff_channel_layout_to_gst (guint64 channel_layout, guint channels)
{
  guint nchannels = 0, i, j;
  GstAudioChannelPosition *pos = NULL;
  gboolean none_layout = FALSE;

  for (i = 0; i < 64; i++) {
    if ((channel_layout & (G_GUINT64_CONSTANT (1) << i)) != 0) {
      nchannels++;
    }
  }

  if (channel_layout == 0) {
    nchannels = channels;
    none_layout = TRUE;
  }

  if (nchannels != channels) {
    GST_ERROR ("Number of channels is different (%u != %u)", channels,
        nchannels);
    return NULL;
  }

  pos = g_new (GstAudioChannelPosition, nchannels);

  for (i = 0, j = 0; i < G_N_ELEMENTS (_ff_to_gst_layout); i++) {
    if ((channel_layout & _ff_to_gst_layout[i].ff) != 0) {
      pos[j++] = _ff_to_gst_layout[i].gst;

      if (_ff_to_gst_layout[i].gst == GST_AUDIO_CHANNEL_POSITION_NONE)
        none_layout = TRUE;
    }
  }

  if (j != nchannels) {
    GST_WARNING ("Unknown channels in channel layout - assuming NONE layout");
    none_layout = TRUE;
  }

142 143 144
  if (!none_layout && !gst_audio_check_channel_positions (pos, nchannels)) {
    GST_ERROR ("Invalid channel layout %" G_GUINT64_FORMAT
        " - assuming NONE layout", channel_layout);
145 146 147 148 149 150 151 152 153
    none_layout = TRUE;
  }

  if (none_layout) {
    if (nchannels == 1) {
      pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_MONO;
    } else if (nchannels == 2) {
      pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
      pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
154 155 156
    } else if (channel_layout == 0) {
      g_free (pos);
      pos = NULL;
157 158 159 160 161 162 163 164 165 166 167 168
    } else {
      for (i = 0; i < nchannels; i++)
        pos[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
    }
  }

  if (nchannels == 1 && pos[0] == GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER)
    pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_MONO;

  return pos;
}

169 170 171 172
/* 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.
173 174 175
 *
 * We should actually do this stuff at the end, like in riff-media.c,
 * but I'm too lazy today. Maybe later.
176
 */
177
static GstCaps *
178 179
gst_ff_vid_caps_new (AVCodecContext * context, enum CodecID codec_id,
    const char *mimetype, const char *fieldname, ...)
180 181 182 183
{
  GstStructure *structure = NULL;
  GstCaps *caps = NULL;
  va_list var_args;
184
  gint i;
185

186 187
  GST_LOG ("context:%p, codec_id:%d, mimetype:%s", context, codec_id, mimetype);

188 189
  /* fixed, non probing context */
  if (context != NULL && context->width != -1) {
190 191 192 193
    caps = gst_caps_new_simple (mimetype,
        "width", G_TYPE_INT, context->width,
        "height", G_TYPE_INT, context->height,
        "framerate", GST_TYPE_FRACTION,
194 195
        context->time_base.den / context->ticks_per_frame,
        context->time_base.num, NULL);
196 197
  } else if (context) {
    /* so we are after restricted caps in this case */
198
    switch (codec_id) {
199 200 201 202 203 204 205 206 207 208 209 210
      case CODEC_ID_H261:
      {
        caps = gst_caps_new_simple (mimetype,
            "width", G_TYPE_INT, 352,
            "height", G_TYPE_INT, 288,
            "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
        gst_caps_append (caps, gst_caps_new_simple (mimetype,
                "width", G_TYPE_INT, 176,
                "height", G_TYPE_INT, 144,
                "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL));
        break;
      }
211 212 213 214 215 216 217 218 219
      case CODEC_ID_H263:
      {
        /* 128x96, 176x144, 352x288, 704x576, and 1408x1152. slightly reordered
         * because we want automatic negotiation to go as close to 320x240 as
         * possible. */
        const static gint widths[] = { 352, 704, 176, 1408, 128 };
        const static gint heights[] = { 288, 576, 144, 1152, 96 };
        GstCaps *temp;
        gint n_sizes = G_N_ELEMENTS (widths);
220

221 222 223 224 225 226
        caps = gst_caps_new_empty ();
        for (i = 0; i < n_sizes; i++) {
          temp = gst_caps_new_simple (mimetype,
              "width", G_TYPE_INT, widths[i],
              "height", G_TYPE_INT, heights[i],
              "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
227

228 229 230 231
          gst_caps_append (caps, temp);
        }
        break;
      }
232 233
      case CODEC_ID_DVVIDEO:
      {
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
        static struct
        {
          guint32 csp;
          gint width, height;
          gint par_n, par_d;
          gint framerate_n, framerate_d;
        } profiles[] = {
          {
          GST_MAKE_FOURCC ('Y', '4', '1', 'B'), 720, 480, 10, 11, 30000, 1001}, {
          GST_MAKE_FOURCC ('Y', '4', '1', 'B'), 720, 480, 40, 33, 30000, 1001}, {
          GST_MAKE_FOURCC ('I', '4', '2', '0'), 720, 576, 59, 54, 25, 1}, {
          GST_MAKE_FOURCC ('I', '4', '2', '0'), 720, 576, 118, 81, 25, 1}, {
          GST_MAKE_FOURCC ('Y', '4', '1', 'B'), 720, 576, 59, 54, 25, 1}, {
          GST_MAKE_FOURCC ('Y', '4', '1', 'B'), 720, 576, 118, 81, 25, 1}
        };
249
        GstCaps *temp;
250
        gint n_sizes = G_N_ELEMENTS (profiles);
251 252 253 254

        caps = gst_caps_new_empty ();
        for (i = 0; i < n_sizes; i++) {
          temp = gst_caps_new_simple (mimetype,
255 256 257 258 259
              "width", G_TYPE_INT, profiles[i].width,
              "height", G_TYPE_INT, profiles[i].height,
              "framerate", GST_TYPE_FRACTION, profiles[i].framerate_n,
              profiles[i].framerate_d, "pixel-aspect-ratio", GST_TYPE_FRACTION,
              profiles[i].par_n, profiles[i].par_d, NULL);
260 261

          gst_caps_append (caps, temp);
262
        }
263 264
        break;
      }
265 266
      case CODEC_ID_DNXHD:
      {
267
        caps = gst_caps_new_simple (mimetype,
268 269
            "width", G_TYPE_INT, 1920,
            "height", G_TYPE_INT, 1080,
270
            "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
271 272 273 274 275 276 277
        gst_caps_append (caps, gst_caps_new_simple (mimetype,
                "width", G_TYPE_INT, 1280,
                "height", G_TYPE_INT, 720,
                "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL));
        break;
      }
      default:
278 279 280 281
        break;
    }
  }

282 283
  /* no fixed caps or special restrictions applied;
   * default unfixed setting */
284 285
  if (!caps) {
    GST_DEBUG ("Creating default caps");
286 287 288 289
    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);
290
  }
291

292
  for (i = 0; i < gst_caps_get_size (caps); i++) {
293
    va_start (var_args, fieldname);
294
    structure = gst_caps_get_structure (caps, i);
295 296 297 298 299 300
    gst_structure_set_valist (structure, fieldname, var_args);
    va_end (var_args);
  }

  return caps;
}
301 302 303 304

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

305
static GstCaps *
306 307
gst_ff_aud_caps_new (AVCodecContext * context, enum CodecID codec_id,
    const char *mimetype, const char *fieldname, ...)
308 309 310
{
  GstCaps *caps = NULL;
  GstStructure *structure = NULL;
311
  gint i;
312 313
  va_list var_args;

314 315
  /* fixed, non-probing context */
  if (context != NULL && context->channels != -1) {
316 317
    GstAudioChannelPosition *pos;

318 319
    caps = gst_caps_new_simple (mimetype,
        "rate", G_TYPE_INT, context->sample_rate,
320
        "channels", G_TYPE_INT, context->channels, NULL);
321 322 323 324 325 326 327 328

    pos =
        gst_ff_channel_layout_to_gst (context->channel_layout,
        context->channels);
    if (pos != NULL) {
      gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos);
      g_free (pos);
    }
329
  } else {
330 331 332
    gint maxchannels = 2;
    const gint *rates = NULL;
    gint n_rates = 0;
333

334
    if (context) {
335 336 337 338 339 340 341 342 343 344
      /* so we must be after restricted caps in this particular case */
      switch (codec_id) {
        case CODEC_ID_MP2:
        {
          const static gint l_rates[] =
              { 48000, 44100, 32000, 24000, 22050, 16000 };
          n_rates = G_N_ELEMENTS (l_rates);
          rates = l_rates;
          break;
        }
345
        case CODEC_ID_EAC3:
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369
        case CODEC_ID_AC3:
        {
          const static gint l_rates[] = { 48000, 44100, 32000 };
          n_rates = G_N_ELEMENTS (l_rates);
          rates = l_rates;
          break;
        }
        case CODEC_ID_ADPCM_SWF:
        {
          const static gint l_rates[] = { 11025, 22050, 44100 };
          n_rates = G_N_ELEMENTS (l_rates);
          rates = l_rates;
          break;
        }
        case CODEC_ID_ROQ_DPCM:
        {
          const static gint l_rates[] = { 22050 };
          n_rates = G_N_ELEMENTS (l_rates);
          rates = l_rates;
          break;
        }
        case CODEC_ID_ADPCM_G726:
          maxchannels = 1;
          break;
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
        case CODEC_ID_AMR_NB:
        {
          const static gint l_rates[] = { 8000 };
          maxchannels = 1;
          n_rates = G_N_ELEMENTS (l_rates);
          rates = l_rates;
          break;
        }
        case CODEC_ID_AMR_WB:
        {
          const static gint l_rates[] = { 16000 };
          maxchannels = 1;
          n_rates = G_N_ELEMENTS (l_rates);
          rates = l_rates;
          break;
        }
386 387 388
        default:
          break;
      }
389 390 391 392 393

      /* TODO: handle context->channel_layouts here to set
       * the list of channel layouts supported by the encoder.
       * Unfortunately no encoder uses this yet....
       */
394 395 396 397 398 399 400
    }

    /* regardless of encode/decode, open up channels if applicable */
    /* Until decoders/encoders expose the maximum number of channels
     * they support, we whitelist them here. */
    switch (codec_id) {
      case CODEC_ID_AC3:
401
      case CODEC_ID_EAC3:
402 403 404 405 406 407 408
      case CODEC_ID_AAC:
      case CODEC_ID_DTS:
        maxchannels = 6;
        break;
      default:
        break;
    }
409

410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432
    if (maxchannels == 1)
      caps = gst_caps_new_simple (mimetype,
          "channels", G_TYPE_INT, maxchannels, NULL);
    else
      caps = gst_caps_new_simple (mimetype,
          "channels", GST_TYPE_INT_RANGE, 1, maxchannels, NULL);
    if (n_rates) {
      GValue list = { 0, };
      GstStructure *structure;

      g_value_init (&list, GST_TYPE_LIST);
      for (i = 0; i < n_rates; i++) {
        GValue v = { 0, };

        g_value_init (&v, G_TYPE_INT);
        g_value_set_int (&v, rates[i]);
        gst_value_list_append_value (&list, &v);
        g_value_unset (&v);
      }
      structure = gst_caps_get_structure (caps, 0);
      gst_structure_set_value (structure, "rate", &list);
      g_value_unset (&list);
    } else
433
      gst_caps_set_simple (caps, "rate", GST_TYPE_INT_RANGE, 4000, 96000, NULL);
434 435
  }

436
  for (i = 0; i < gst_caps_get_size (caps); i++) {
437
    va_start (var_args, fieldname);
438
    structure = gst_caps_get_structure (caps, i);
439 440 441 442 443 444
    gst_structure_set_valist (structure, fieldname, var_args);
    va_end (var_args);
  }

  return caps;
}
445 446 447 448 449 450

/* 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!
451 452 453 454 455 456 457 458 459
 *
 * 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.
460 461
 */

462
GstCaps *
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
463 464
gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
    AVCodecContext * context, gboolean encode)
465
{
466
  GstCaps *caps = NULL;
467
  gboolean buildcaps = FALSE;
468

469 470
  GST_LOG ("codec_id:%d, context:%p, encode:%d", codec_id, context, encode);

471
  switch (codec_id) {
472
    case CODEC_ID_MPEG1VIDEO:
473 474 475 476
      /* FIXME: bitrate */
      caps = gst_ff_vid_caps_new (context, codec_id, "video/mpeg",
          "mpegversion", G_TYPE_INT, 1,
          "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
477 478 479 480 481
      break;

    case CODEC_ID_MPEG2VIDEO:
      if (encode) {
        /* FIXME: bitrate */
482
        caps = gst_ff_vid_caps_new (context, codec_id, "video/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
483 484
            "mpegversion", G_TYPE_INT, 2,
            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
485 486 487 488
      } 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
489 490
            "mpegversion", GST_TYPE_INT_RANGE, 1, 2,
            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
491
      }
492
      break;
493 494 495 496 497 498

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

    case CODEC_ID_H263:
499
      if (encode) {
500
        caps = gst_ff_vid_caps_new (context, codec_id, "video/x-h263",
501 502 503
            "variant", G_TYPE_STRING, "itu",
            "h263version", G_TYPE_STRING, "h263", NULL);
      } else {
504 505 506 507
        /* don't pass codec_id, we can decode other variants with the H263
         * decoder that don't have specific size requirements
         */
        caps = gst_ff_vid_caps_new (context, CODEC_ID_NONE, "video/x-h263",
508 509
            "variant", G_TYPE_STRING, "itu", NULL);
      }
510 511 512
      break;

    case CODEC_ID_H263P:
513
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-h263",
514 515
          "variant", G_TYPE_STRING, "itu",
          "h263version", G_TYPE_STRING, "h263p", NULL);
516
      break;
517

518
    case CODEC_ID_H263I:
519
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-intel-h263",
520
          "variant", G_TYPE_STRING, "intel", NULL);
521 522
      break;

523
    case CODEC_ID_H261:
524
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-h261", NULL);
525 526
      break;

527
    case CODEC_ID_RV10:
528
    case CODEC_ID_RV20:
529
    case CODEC_ID_RV30:
530
    case CODEC_ID_RV40:
531 532
    {
      gint version;
533

534 535 536 537
      switch (codec_id) {
        case CODEC_ID_RV40:
          version = 4;
          break;
538 539 540
        case CODEC_ID_RV30:
          version = 3;
          break;
541 542 543 544 545 546 547
        case CODEC_ID_RV20:
          version = 2;
          break;
        default:
          version = 1;
          break;
      }
548

549 550 551 552 553
      /* FIXME: context->sub_id must be filled in during decoding */
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-pn-realvideo",
          "systemstream", G_TYPE_BOOLEAN, FALSE,
          "rmversion", G_TYPE_INT, version, NULL);
      if (context) {
554
        gst_caps_set_simple (caps, "format", G_TYPE_INT, context->sub_id, NULL);
555 556
        if (context->extradata_size >= 8) {
          gst_caps_set_simple (caps,
557 558 559
              "subformat", G_TYPE_INT, GST_READ_UINT32_BE (context->extradata),
              NULL);
        }
560
      }
561
    }
562
      break;
563

564 565 566 567 568 569
    case CODEC_ID_MP1:
      /* FIXME: bitrate */
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/mpeg",
          "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 1, NULL);
      break;

570
    case CODEC_ID_MP2:
571 572 573
      /* FIXME: bitrate */
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/mpeg",
          "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 2, NULL);
574
      break;
575

576 577 578
    case CODEC_ID_MP3:
      if (encode) {
        /* FIXME: bitrate */
579
        caps = gst_ff_aud_caps_new (context, codec_id, "audio/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
580
            "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 3, NULL);
581 582 583 584
      } 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
585 586
            "mpegversion", G_TYPE_INT, 1,
            "layer", GST_TYPE_INT_RANGE, 1, 3, NULL);
587
      }
588
      break;
589

590 591 592 593 594 595 596
    case CODEC_ID_MUSEPACK7:
      caps =
          gst_ff_aud_caps_new (context, codec_id,
          "audio/x-ffmpeg-parsed-musepack", "streamversion", G_TYPE_INT, 7,
          NULL);
      break;

597 598 599 600 601 602 603
    case CODEC_ID_MUSEPACK8:
      caps =
          gst_ff_aud_caps_new (context, codec_id,
          "audio/x-ffmpeg-parsed-musepack", "streamversion", G_TYPE_INT, 8,
          NULL);
      break;

604 605 606
    case CODEC_ID_AC3:
      /* FIXME: bitrate */
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-ac3", NULL);
607
      break;
608

609 610 611 612 613
    case CODEC_ID_EAC3:
      /* FIXME: bitrate */
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-eac3", NULL);
      break;

614
    case CODEC_ID_ATRAC3:
615 616 617
      caps =
          gst_ff_aud_caps_new (context, codec_id, "audio/x-vnd.sony.atrac3",
          NULL);
618
      break;
619

620
    case CODEC_ID_DTS:
621
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-dts", NULL);
622
      break;
623

624 625 626 627 628 629
    case CODEC_ID_APE:
      caps =
          gst_ff_aud_caps_new (context, codec_id, "audio/x-ffmpeg-parsed-ape",
          NULL);
      if (context) {
        gst_caps_set_simple (caps,
630
            "depth", G_TYPE_INT, context->bits_per_coded_sample, NULL);
631 632 633
      }
      break;

634 635 636
    case CODEC_ID_MLP:
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-mlp", NULL);
      break;
637

638 639 640
    case CODEC_ID_IMC:
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-imc", NULL);
      break;
641

Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
642 643 644 645 646
      /* 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...)? */
647
    case CODEC_ID_MJPEG:
648
    case CODEC_ID_LJPEG:
649
      caps = gst_ff_vid_caps_new (context, codec_id, "image/jpeg", NULL);
Wim Taymans's avatar
Wim Taymans committed
650
      break;
651

652
    case CODEC_ID_SP5X:
653
      caps = gst_ff_vid_caps_new (context, codec_id, "video/sp5x", NULL);
654 655
      break;

656
    case CODEC_ID_MJPEGB:
657
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-mjpeg-b", NULL);
658 659
      break;

660
    case CODEC_ID_MPEG4:
661
      if (encode && context != NULL) {
662 663
        /* I'm not exactly sure what ffmpeg outputs... ffmpeg itself uses
         * the AVI fourcc 'DIVX', but 'mp4v' for Quicktime... */
664
        switch (context->codec_tag) {
665
          case GST_MAKE_FOURCC ('D', 'I', 'V', 'X'):
666
            caps = gst_ff_vid_caps_new (context, codec_id, "video/x-divx",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
667
                "divxversion", G_TYPE_INT, 5, NULL);
668 669 670 671
            break;
          case GST_MAKE_FOURCC ('m', 'p', '4', 'v'):
          default:
            /* FIXME: bitrate */
672
            caps = gst_ff_vid_caps_new (context, codec_id, "video/mpeg",
673 674 675 676
                "systemstream", G_TYPE_BOOLEAN, FALSE,
                "mpegversion", G_TYPE_INT, 4, NULL);
            break;
        }
677 678
      } else {
        /* The trick here is to separate xvid, divx, mpeg4, 3ivx et al */
679
        caps = gst_ff_vid_caps_new (context, codec_id, "video/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
680 681
            "mpegversion", G_TYPE_INT, 4,
            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
682
        if (encode) {
683 684
          gst_caps_append (caps, gst_ff_vid_caps_new (context, codec_id,
                  "video/x-divx", "divxversion", G_TYPE_INT, 5, NULL));
685
        } else {
686 687 688 689 690 691 692
          gst_caps_append (caps, gst_ff_vid_caps_new (context, codec_id,
                  "video/x-divx", "divxversion", GST_TYPE_INT_RANGE, 4, 5,
                  NULL));
          gst_caps_append (caps, gst_ff_vid_caps_new (context, codec_id,
                  "video/x-xvid", NULL));
          gst_caps_append (caps, gst_ff_vid_caps_new (context, codec_id,
                  "video/x-3ivx", NULL));
693
        }
694
      }
695
      break;
696

697
    case CODEC_ID_RAWVIDEO:
698 699
      caps = gst_ffmpeg_codectype_to_caps (CODEC_TYPE_VIDEO, context, codec_id,
          encode);
700
      break;
701

702
    case CODEC_ID_MSMPEG4V1:
703 704
    case CODEC_ID_MSMPEG4V2:
    case CODEC_ID_MSMPEG4V3:
705 706 707 708 709 710 711 712 713
    {
      gint version = 41 + codec_id - CODEC_ID_MSMPEG4V1;

      /* encode-FIXME: bitrate */
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-msmpeg",
          "msmpegversion", G_TYPE_INT, version, NULL);
      if (!encode && codec_id == CODEC_ID_MSMPEG4V3) {
        gst_caps_append (caps, gst_ff_vid_caps_new (context, codec_id,
                "video/x-divx", "divxversion", G_TYPE_INT, 3, NULL));
714
      }
715
    }
716
      break;
717

718
    case CODEC_ID_WMV1:
719
    case CODEC_ID_WMV2:
720 721
    {
      gint version = (codec_id == CODEC_ID_WMV1) ? 1 : 2;
722

723 724 725
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-wmv",
          "wmvversion", G_TYPE_INT, version, NULL);
    }
726
      break;
727

728
    case CODEC_ID_FLV1:
729 730
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-flash-video",
          "flvversion", G_TYPE_INT, 1, NULL);
731
      break;
732

733
    case CODEC_ID_SVQ1:
734
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-svq",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
735
          "svqversion", G_TYPE_INT, 1, NULL);
736
      break;
737 738

    case CODEC_ID_SVQ3:
739
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-svq",
740
          "svqversion", G_TYPE_INT, 3, NULL);
741
      break;
742

743
    case CODEC_ID_DVAUDIO:
744
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-dv", NULL);
745
      break;
746

747
    case CODEC_ID_DVVIDEO:
748 749 750 751 752
    {
      if (encode && context) {
        guint32 fourcc;

        switch (context->pix_fmt) {
753
          case PIX_FMT_YUYV422:
754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780
            fourcc = GST_MAKE_FOURCC ('Y', 'U', 'Y', '2');
            break;
          case PIX_FMT_YUV420P:
            fourcc = GST_MAKE_FOURCC ('I', '4', '2', '0');
            break;
          case PIX_FMT_YUV411P:
            fourcc = GST_MAKE_FOURCC ('Y', '4', '1', 'B');
            break;
          case PIX_FMT_YUV422P:
            fourcc = GST_MAKE_FOURCC ('Y', '4', '2', 'B');
            break;
          case PIX_FMT_YUV410P:
            fourcc = GST_MAKE_FOURCC ('Y', 'U', 'V', '9');
            break;
          default:
            GST_WARNING
                ("Couldnt' find fourcc for pixfmt %d, defaulting to I420",
                context->pix_fmt);
            fourcc = GST_MAKE_FOURCC ('I', '4', '2', '0');
            break;
        }
        caps = gst_ff_vid_caps_new (context, codec_id, "video/x-dv",
            "systemstream", G_TYPE_BOOLEAN, FALSE,
            "format", GST_TYPE_FOURCC, fourcc, NULL);
      } else {
        caps = gst_ff_vid_caps_new (context, codec_id, "video/x-dv",
            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
781
      }
782
    }
783
      break;
784

785 786
    case CODEC_ID_WMAV1:
    case CODEC_ID_WMAV2:
787 788
    {
      gint version = (codec_id == CODEC_ID_WMAV1) ? 1 : 2;
789

790 791 792 793 794 795 796 797 798 799
      if (context) {
        caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-wma",
            "wmaversion", G_TYPE_INT, version,
            "block_align", G_TYPE_INT, context->block_align,
            "bitrate", G_TYPE_INT, context->bit_rate, NULL);
      } else {
        caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-wma",
            "wmaversion", G_TYPE_INT, version,
            "block_align", GST_TYPE_INT_RANGE, 0, G_MAXINT,
            "bitrate", GST_TYPE_INT_RANGE, 0, G_MAXINT, NULL);
800
      }
801
    }
802
      break;
803

804 805
    case CODEC_ID_MACE3:
    case CODEC_ID_MACE6:
806 807
    {
      gint version = (codec_id == CODEC_ID_MACE3) ? 3 : 6;
808

809 810 811
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-mace",
          "maceversion", G_TYPE_INT, version, NULL);
    }
812
      break;
813

Wim Taymans's avatar
Wim Taymans committed
814
    case CODEC_ID_HUFFYUV:
815
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-huffyuv", NULL);
816 817
      if (context) {
        gst_caps_set_simple (caps,
818
            "bpp", G_TYPE_INT, context->bits_per_coded_sample, NULL);
819
      }
820 821 822
      break;

    case CODEC_ID_CYUV:
823 824 825
      caps =
          gst_ff_vid_caps_new (context, codec_id, "video/x-compressed-yuv",
          NULL);
826 827 828
      break;

    case CODEC_ID_H264:
829
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-h264", NULL);
830 831 832
      break;

    case CODEC_ID_INDEO3:
833
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-indeo",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
834
          "indeoversion", G_TYPE_INT, 3, NULL);
835 836
      break;

837
    case CODEC_ID_INDEO2:
838
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-indeo",
839 840 841
          "indeoversion", G_TYPE_INT, 2, NULL);
      break;

842
    case CODEC_ID_FLASHSV:
843 844
      caps =
          gst_ff_vid_caps_new (context, codec_id, "video/x-flash-screen", NULL);
845 846
      break;

847
    case CODEC_ID_VP3:
848
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp3", NULL);
849 850
      break;

851
    case CODEC_ID_VP5:
852
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp5", NULL);
853 854 855
      break;

    case CODEC_ID_VP6:
856
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp6", NULL);
857 858 859
      break;

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

863 864 865 866
    case CODEC_ID_VP6A:
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp6-alpha", NULL);
      break;

867
    case CODEC_ID_THEORA:
868
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-theora", NULL);
869 870
      break;

871
    case CODEC_ID_AAC:
872
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/mpeg",
873
          "mpegversion", G_TYPE_INT, 4, NULL);
874 875 876
      break;

    case CODEC_ID_ASV1:
877 878
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-asus",
          "asusversion", G_TYPE_INT, 1, NULL);
879
      break;
880
    case CODEC_ID_ASV2:
881 882
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-asus",
          "asusversion", G_TYPE_INT, 2, NULL);
883 884
      break;

885
    case CODEC_ID_FFV1:
886
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-ffv",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
887
          "ffvversion", G_TYPE_INT, 1, NULL);
888 889 890
      break;

    case CODEC_ID_4XM:
891
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-4xm", NULL);
892 893
      break;

894 895
    case CODEC_ID_XAN_WC3:
    case CODEC_ID_XAN_WC4:
896
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-xan",
897 898 899
          "wcversion", G_TYPE_INT, 3 - CODEC_ID_XAN_WC3 + codec_id, NULL);
      break;

900
    case CODEC_ID_CLJR:
901 902 903
      caps =
          gst_ff_vid_caps_new (context, codec_id,
          "video/x-cirrus-logic-accupak", NULL);
904 905 906
      break;

    case CODEC_ID_FRAPS:
907 908 909
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-fraps", NULL);
      break;

910 911 912 913 914 915
    case CODEC_ID_MDEC:
    case CODEC_ID_ROQ:
    case CODEC_ID_INTERPLAY_VIDEO:
      buildcaps = TRUE;
      break;

916
    case CODEC_ID_VCR1:
917 918
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-ati-vcr",
          "vcrversion", G_TYPE_INT, 1, NULL);
919 920
      break;

921
    case CODEC_ID_RPZA:
922 923
      caps =
          gst_ff_vid_caps_new (context, codec_id, "video/x-apple-video", NULL);
924 925
      break;

926
    case CODEC_ID_CINEPAK:
927
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-cinepak", NULL);
928 929
      break;

930
      /* WS_VQA belogns here (order) */
931 932

    case CODEC_ID_MSRLE:
933
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-rle",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
934
          "layout", G_TYPE_STRING, "microsoft", NULL);
935 936
      if (context) {
        gst_caps_set_simple (caps,
937
            "depth", G_TYPE_INT, (gint) context->bits_per_coded_sample, NULL);
938 939 940 941 942
      } else {
        gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 1, 64, NULL);
      }
      break;

943
    case CODEC_ID_QTRLE:
944
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-rle",
945 946 947
          "layout", G_TYPE_STRING, "quicktime", NULL);
      if (context) {
        gst_caps_set_simple (caps,
948
            "depth", G_TYPE_INT, (gint) context->bits_per_coded_sample, NULL);
949 950 951 952 953
      } else {
        gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 1, 64, NULL);
      }
      break;

954
    case CODEC_ID_MSVIDEO1:
955
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-msvideocodec",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
956
          "msvideoversion", G_TYPE_INT, 1, NULL);
957 958
      break;

959
    case CODEC_ID_WMV3:
960
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-wmv",
961 962
          "wmvversion", G_TYPE_INT, 3, NULL);
      break;
963 964
    case CODEC_ID_VC1:
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-wmv",
965 966
          "wmvversion", G_TYPE_INT, 3, "fourcc", GST_TYPE_FOURCC,
          GST_MAKE_FOURCC ('W', 'V', 'C', '1'), NULL);
967
      break;
968
    case CODEC_ID_QDM2:
969 970
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-qdm2", NULL);
      break;
971

972
    case CODEC_ID_MSZH:
973
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-mszh", NULL);
974 975 976
      break;

    case CODEC_ID_ZLIB:
977
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-zlib", NULL);
978 979 980
      break;

    case CODEC_ID_TRUEMOTION1:
981 982
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-truemotion",
          "trueversion", G_TYPE_INT, 1