gstffmpegcodecmap.c 101 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
  /* fixed, non probing context */
  if (context != NULL && context->width != -1) {
188 189 190 191
    caps = gst_caps_new_simple (mimetype,
        "width", G_TYPE_INT, context->width,
        "height", G_TYPE_INT, context->height,
        "framerate", GST_TYPE_FRACTION,
192
        context->time_base.den, context->time_base.num, NULL);
193 194
  } else if (context) {
    /* so we are after restricted caps in this case */
195
    switch (codec_id) {
196 197 198 199 200 201 202 203 204 205 206 207
      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;
      }
208 209 210 211 212 213 214 215 216
      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);
217

218 219 220 221 222 223
        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);
224

225 226 227 228
          gst_caps_append (caps, temp);
        }
        break;
      }
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
      case CODEC_ID_DVVIDEO:
      {
        const static gint widths[] = { 720, 720 };
        const static gint heights[] = { 576, 480 };
        GstCaps *temp;
        gint n_sizes = G_N_ELEMENTS (widths);

        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);

          gst_caps_append (caps, temp);
244
        }
245 246
        break;
      }
247 248
      case CODEC_ID_DNXHD:
      {
249
        caps = gst_caps_new_simple (mimetype,
250 251
            "width", G_TYPE_INT, 1920,
            "height", G_TYPE_INT, 1080,
252
            "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
253 254 255 256 257 258 259
        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:
260 261 262 263
        break;
    }
  }

264 265 266 267 268 269 270 271
  /* no fixed caps or special restrictions applied;
   * default unfixed setting */
  if (!caps)
    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);

272
  for (i = 0; i < gst_caps_get_size (caps); i++) {
273
    va_start (var_args, fieldname);
274
    structure = gst_caps_get_structure (caps, i);
275 276 277 278 279 280
    gst_structure_set_valist (structure, fieldname, var_args);
    va_end (var_args);
  }

  return caps;
}
281 282 283 284

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

285
static GstCaps *
286 287
gst_ff_aud_caps_new (AVCodecContext * context, enum CodecID codec_id,
    const char *mimetype, const char *fieldname, ...)
288 289 290
{
  GstCaps *caps = NULL;
  GstStructure *structure = NULL;
291
  gint i;
292 293
  va_list var_args;

294 295
  /* fixed, non-probing context */
  if (context != NULL && context->channels != -1) {
296 297
    GstAudioChannelPosition *pos;

298 299
    caps = gst_caps_new_simple (mimetype,
        "rate", G_TYPE_INT, context->sample_rate,
300
        "channels", G_TYPE_INT, context->channels, NULL);
301 302 303 304 305 306 307 308

    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);
    }
309
  } else {
310 311 312
    gint maxchannels = 2;
    const gint *rates = NULL;
    gint n_rates = 0;
313

314
    if (context) {
315 316 317 318 319 320 321 322 323 324
      /* 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;
        }
325
        case CODEC_ID_EAC3:
326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
        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;
        default:
          break;
      }
353 354 355 356 357

      /* TODO: handle context->channel_layouts here to set
       * the list of channel layouts supported by the encoder.
       * Unfortunately no encoder uses this yet....
       */
358 359 360 361 362 363 364
    }

    /* 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:
365
      case CODEC_ID_EAC3:
366 367 368 369 370 371 372
      case CODEC_ID_AAC:
      case CODEC_ID_DTS:
        maxchannels = 6;
        break;
      default:
        break;
    }
373

374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397
    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
      gst_caps_set_simple (caps, "rate", GST_TYPE_INT_RANGE, 8000, 96000, NULL);
398 399
  }

400
  for (i = 0; i < gst_caps_get_size (caps); i++) {
401
    va_start (var_args, fieldname);
402
    structure = gst_caps_get_structure (caps, i);
403 404 405 406 407 408
    gst_structure_set_valist (structure, fieldname, var_args);
    va_end (var_args);
  }

  return caps;
}
409 410 411 412 413 414

/* 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!
415 416 417 418 419 420 421 422 423
 *
 * 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.
424 425
 */

426
GstCaps *
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
427 428
gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
    AVCodecContext * context, gboolean encode)
429
{
430
  GstCaps *caps = NULL;
431
  gboolean buildcaps = FALSE;
432

433
  switch (codec_id) {
434
    case CODEC_ID_MPEG1VIDEO:
435 436 437 438
      /* FIXME: bitrate */
      caps = gst_ff_vid_caps_new (context, codec_id, "video/mpeg",
          "mpegversion", G_TYPE_INT, 1,
          "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
439 440 441 442 443
      break;

    case CODEC_ID_MPEG2VIDEO:
      if (encode) {
        /* FIXME: bitrate */
444
        caps = gst_ff_vid_caps_new (context, codec_id, "video/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
445 446
            "mpegversion", G_TYPE_INT, 2,
            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
447 448 449 450
      } 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
451 452
            "mpegversion", GST_TYPE_INT_RANGE, 1, 2,
            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
453
      }
454
      break;
455 456 457 458 459 460

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

    case CODEC_ID_H263:
461
      if (encode) {
462
        caps = gst_ff_vid_caps_new (context, codec_id, "video/x-h263",
463 464 465
            "variant", G_TYPE_STRING, "itu",
            "h263version", G_TYPE_STRING, "h263", NULL);
      } else {
466 467 468 469
        /* 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",
470 471
            "variant", G_TYPE_STRING, "itu", NULL);
      }
472 473 474
      break;

    case CODEC_ID_H263P:
475
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-h263",
476 477
          "variant", G_TYPE_STRING, "itu",
          "h263version", G_TYPE_STRING, "h263p", NULL);
478
      break;
479

480
    case CODEC_ID_H263I:
481
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-intel-h263",
482
          "variant", G_TYPE_STRING, "intel", NULL);
483 484
      break;

485
    case CODEC_ID_H261:
486
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-h261", NULL);
487 488
      break;

489
    case CODEC_ID_RV10:
490
    case CODEC_ID_RV20:
491
    case CODEC_ID_RV30:
492
    case CODEC_ID_RV40:
493 494
    {
      gint version;
495

496 497 498 499
      switch (codec_id) {
        case CODEC_ID_RV40:
          version = 4;
          break;
500 501 502
        case CODEC_ID_RV30:
          version = 3;
          break;
503 504 505 506 507 508 509
        case CODEC_ID_RV20:
          version = 2;
          break;
        default:
          version = 1;
          break;
      }
510

511 512 513 514 515
      /* 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) {
516
        gst_caps_set_simple (caps, "format", G_TYPE_INT, context->sub_id, NULL);
517 518
        if (context->extradata_size >= 8) {
          gst_caps_set_simple (caps,
519 520 521
              "subformat", G_TYPE_INT, GST_READ_UINT32_BE (context->extradata),
              NULL);
        }
522
      }
523
    }
524
      break;
525

526
    case CODEC_ID_MP2:
527 528 529
      /* FIXME: bitrate */
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/mpeg",
          "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 2, NULL);
530
      break;
531

532 533 534
    case CODEC_ID_MP3:
      if (encode) {
        /* FIXME: bitrate */
535
        caps = gst_ff_aud_caps_new (context, codec_id, "audio/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
536
            "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 3, NULL);
537 538 539 540
      } 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
541 542
            "mpegversion", G_TYPE_INT, 1,
            "layer", GST_TYPE_INT_RANGE, 1, 3, NULL);
543
      }
544
      break;
545

546 547 548 549 550 551 552
    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;

553 554 555 556 557 558 559
    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;

560 561 562
    case CODEC_ID_AC3:
      /* FIXME: bitrate */
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-ac3", NULL);
563
      break;
564

565 566 567 568 569
    case CODEC_ID_EAC3:
      /* FIXME: bitrate */
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-eac3", NULL);
      break;

570 571
    case CODEC_ID_ATRAC3:
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/atrac3", NULL);
572
      break;
573

574
    case CODEC_ID_DTS:
575
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-dts", NULL);
576
      break;
577

578 579 580 581 582 583
    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,
584
            "depth", G_TYPE_INT, context->bits_per_coded_sample, NULL);
585 586 587
      }
      break;

588 589 590 591 592 593 594 595
  case CODEC_ID_MLP:
    caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-mlp", NULL);
    break;

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

Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
596 597 598 599 600
      /* 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...)? */
601
    case CODEC_ID_MJPEG:
602
    case CODEC_ID_LJPEG:
603
      caps = gst_ff_vid_caps_new (context, codec_id, "image/jpeg", NULL);
Wim Taymans's avatar
Wim Taymans committed
604
      break;
605

606
    case CODEC_ID_SP5X:
607
      caps = gst_ff_vid_caps_new (context, codec_id, "video/sp5x", NULL);
608 609
      break;

610
    case CODEC_ID_MJPEGB:
611
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-mjpeg-b", NULL);
612 613
      break;

614
    case CODEC_ID_MPEG4:
615
      if (encode && context != NULL) {
616 617
        /* I'm not exactly sure what ffmpeg outputs... ffmpeg itself uses
         * the AVI fourcc 'DIVX', but 'mp4v' for Quicktime... */
618
        switch (context->codec_tag) {
619
          case GST_MAKE_FOURCC ('D', 'I', 'V', 'X'):
620
            caps = gst_ff_vid_caps_new (context, codec_id, "video/x-divx",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
621
                "divxversion", G_TYPE_INT, 5, NULL);
622 623 624 625
            break;
          case GST_MAKE_FOURCC ('m', 'p', '4', 'v'):
          default:
            /* FIXME: bitrate */
626
            caps = gst_ff_vid_caps_new (context, codec_id, "video/mpeg",
627 628 629 630
                "systemstream", G_TYPE_BOOLEAN, FALSE,
                "mpegversion", G_TYPE_INT, 4, NULL);
            break;
        }
631 632
      } else {
        /* The trick here is to separate xvid, divx, mpeg4, 3ivx et al */
633
        caps = gst_ff_vid_caps_new (context, codec_id, "video/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
634 635
            "mpegversion", G_TYPE_INT, 4,
            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
636
        if (encode) {
637 638
          gst_caps_append (caps, gst_ff_vid_caps_new (context, codec_id,
                  "video/x-divx", "divxversion", G_TYPE_INT, 5, NULL));
639
        } else {
640 641 642 643 644 645 646
          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));
647
        }
648
      }
649
      break;
650

651
    case CODEC_ID_RAWVIDEO:
652 653
      caps = gst_ffmpeg_codectype_to_caps (CODEC_TYPE_VIDEO, context, codec_id,
          encode);
654
      break;
655

656
    case CODEC_ID_MSMPEG4V1:
657 658
    case CODEC_ID_MSMPEG4V2:
    case CODEC_ID_MSMPEG4V3:
659 660 661 662 663 664 665 666 667
    {
      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));
668
      }
669
    }
670
      break;
671

672
    case CODEC_ID_WMV1:
673
    case CODEC_ID_WMV2:
674 675
    {
      gint version = (codec_id == CODEC_ID_WMV1) ? 1 : 2;
676

677 678 679
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-wmv",
          "wmvversion", G_TYPE_INT, version, NULL);
    }
680
      break;
681

682
    case CODEC_ID_FLV1:
683 684
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-flash-video",
          "flvversion", G_TYPE_INT, 1, NULL);
685
      break;
686

687
    case CODEC_ID_SVQ1:
688
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-svq",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
689
          "svqversion", G_TYPE_INT, 1, NULL);
690
      break;
691 692

    case CODEC_ID_SVQ3:
693
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-svq",
694
          "svqversion", G_TYPE_INT, 3, NULL);
695
      break;
696

697
    case CODEC_ID_DVAUDIO:
698
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-dv", NULL);
699
      break;
700

701
    case CODEC_ID_DVVIDEO:
702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734
    {
      if (encode && context) {
        guint32 fourcc;

        switch (context->pix_fmt) {
          case PIX_FMT_YUV422:
            fourcc = GST_MAKE_FOURCC ('Y', 'U', 'Y', '2');
            break;
          case PIX_FMT_YUV420P:
            fourcc = GST_MAKE_FOURCC ('I', '4', '2', '0');
            break;
          case PIX_FMT_YUV411P:
            fourcc = GST_MAKE_FOURCC ('Y', '4', '1', 'B');
            break;
          case PIX_FMT_YUV422P:
            fourcc = GST_MAKE_FOURCC ('Y', '4', '2', 'B');
            break;
          case PIX_FMT_YUV410P:
            fourcc = GST_MAKE_FOURCC ('Y', 'U', 'V', '9');
            break;
          default:
            GST_WARNING
                ("Couldnt' find fourcc for pixfmt %d, defaulting to I420",
                context->pix_fmt);
            fourcc = GST_MAKE_FOURCC ('I', '4', '2', '0');
            break;
        }
        caps = gst_ff_vid_caps_new (context, 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);
735
      }
736
    }
737
      break;
738

739 740
    case CODEC_ID_WMAV1:
    case CODEC_ID_WMAV2:
741 742
    {
      gint version = (codec_id == CODEC_ID_WMAV1) ? 1 : 2;
743

744 745 746 747 748 749 750 751 752 753
      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);
754
      }
755
    }
756
      break;
757

758 759
    case CODEC_ID_MACE3:
    case CODEC_ID_MACE6:
760 761
    {
      gint version = (codec_id == CODEC_ID_MACE3) ? 3 : 6;
762

763 764 765
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-mace",
          "maceversion", G_TYPE_INT, version, NULL);
    }
766
      break;
767

Wim Taymans's avatar
Wim Taymans committed
768
    case CODEC_ID_HUFFYUV:
769
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-huffyuv", NULL);
770 771
      if (context) {
        gst_caps_set_simple (caps,
772
            "bpp", G_TYPE_INT, context->bits_per_coded_sample, NULL);
773
      }
774 775 776
      break;

    case CODEC_ID_CYUV:
777 778 779
      caps =
          gst_ff_vid_caps_new (context, codec_id, "video/x-compressed-yuv",
          NULL);
780 781 782
      break;

    case CODEC_ID_H264:
783
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-h264", NULL);
784 785 786
      break;

    case CODEC_ID_INDEO3:
787
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-indeo",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
788
          "indeoversion", G_TYPE_INT, 3, NULL);
789 790
      break;

791
    case CODEC_ID_INDEO2:
792
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-indeo",
793 794 795
          "indeoversion", G_TYPE_INT, 2, NULL);
      break;

796
    case CODEC_ID_FLASHSV:
797 798
      caps =
          gst_ff_vid_caps_new (context, codec_id, "video/x-flash-screen", NULL);
799 800
      break;

801
    case CODEC_ID_VP3:
802
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp3", NULL);
803 804
      break;

805
    case CODEC_ID_VP5:
806
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp5", NULL);
807 808 809
      break;

    case CODEC_ID_VP6:
810
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp6", NULL);
811 812 813
      break;

    case CODEC_ID_VP6F:
814
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp6-flash", NULL);
815 816
      break;

817 818 819 820
    case CODEC_ID_VP6A:
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp6-alpha", NULL);
      break;

821
    case CODEC_ID_THEORA:
822
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-theora", NULL);
823 824
      break;

825
    case CODEC_ID_AAC:
826
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/mpeg",
827
          "mpegversion", G_TYPE_INT, 4, NULL);
828 829 830
      break;

    case CODEC_ID_ASV1:
831 832
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-asus",
          "asusversion", G_TYPE_INT, 1, NULL);
833
      break;
834
    case CODEC_ID_ASV2:
835 836
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-asus",
          "asusversion", G_TYPE_INT, 2, NULL);
837 838
      break;

839
    case CODEC_ID_FFV1:
840
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-ffv",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
841
          "ffvversion", G_TYPE_INT, 1, NULL);
842 843 844
      break;

    case CODEC_ID_4XM:
845
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-4xm", NULL);
846 847
      break;

848 849
    case CODEC_ID_XAN_WC3:
    case CODEC_ID_XAN_WC4:
850
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-xan",
851 852 853
          "wcversion", G_TYPE_INT, 3 - CODEC_ID_XAN_WC3 + codec_id, NULL);
      break;

854
    case CODEC_ID_CLJR:
855 856 857
      caps =
          gst_ff_vid_caps_new (context, codec_id,
          "video/x-cirrus-logic-accupak", NULL);
858 859 860
      break;

    case CODEC_ID_FRAPS:
861 862 863 864 865 866
    case CODEC_ID_MDEC:
    case CODEC_ID_ROQ:
    case CODEC_ID_INTERPLAY_VIDEO:
      buildcaps = TRUE;
      break;

867
    case CODEC_ID_VCR1:
868 869
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-ati-vcr",
          "vcrversion", G_TYPE_INT, 1, NULL);
870 871
      break;

872
    case CODEC_ID_RPZA:
873 874
      caps =
          gst_ff_vid_caps_new (context, codec_id, "video/x-apple-video", NULL);
875 876
      break;

877
    case CODEC_ID_CINEPAK:
878
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-cinepak", NULL);
879 880
      break;

881
      /* WS_VQA belogns here (order) */
882 883

    case CODEC_ID_MSRLE:
884
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-rle",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
885
          "layout", G_TYPE_STRING, "microsoft", NULL);
886 887
      if (context) {
        gst_caps_set_simple (caps,
888
            "depth", G_TYPE_INT, (gint) context->bits_per_coded_sample, NULL);
889 890 891 892 893
      } else {
        gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 1, 64, NULL);
      }
      break;

894
    case CODEC_ID_QTRLE:
895
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-rle",
896 897 898
          "layout", G_TYPE_STRING, "quicktime", NULL);
      if (context) {
        gst_caps_set_simple (caps,
899
            "depth", G_TYPE_INT, (gint) context->bits_per_coded_sample, NULL);
900 901 902 903 904
      } else {
        gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 1, 64, NULL);
      }
      break;

905
    case CODEC_ID_MSVIDEO1:
906
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-msvideocodec",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
907
          "msvideoversion", G_TYPE_INT, 1, NULL);
908 909
      break;

910
    case CODEC_ID_WMV3:
911
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-wmv",
912 913
          "wmvversion", G_TYPE_INT, 3, NULL);
      break;
914 915
    case CODEC_ID_VC1:
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-wmv",
916 917
          "wmvversion", G_TYPE_INT, 3, "fourcc", GST_TYPE_FOURCC,
          GST_MAKE_FOURCC ('W', 'V', 'C', '1'), NULL);
918
      break;
919
    case CODEC_ID_QDM2:
920 921
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-qdm2", NULL);
      break;
922

923
    case CODEC_ID_MSZH:
924
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-mszh", NULL);
925 926 927
      break;

    case CODEC_ID_ZLIB:
928
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-zlib", NULL);
929 930 931
      break;

    case CODEC_ID_TRUEMOTION1:
932 933
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-truemotion",
          "trueversion", G_TYPE_INT, 1, NULL);
934 935
      break;
    case CODEC_ID_TRUEMOTION2:
936 937
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-truemotion",
          "trueversion", G_TYPE_INT, 2, NULL);
938 939 940
      break;

    case CODEC_ID_ULTI:
941 942
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-ultimotion",
          NULL);
943 944 945
      break;

    case CODEC_ID_TSCC:
946
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-camtasia", NULL);
947 948
      if (context) {
        gst_caps_set_simple (caps,
949
            "depth", G_TYPE_INT, (gint) context->bits_per_coded_sample, NULL);
950 951 952
      } else {
        gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 8, 32, NULL);
      }
953 954
      break;

955 956 957 958 959 960 961 962
    case CODEC_ID_KMVC:
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-kmvc", NULL);
      break;

    case CODEC_ID_NUV:
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-nuv", NULL);
      break;

963 964 965 966
    case CODEC_ID_GIF:
      caps = gst_ff_vid_caps_new (context, codec_id, "image/gif", NULL);
      break;

967
    case CODEC_ID_PNG:
968
      caps = gst_ff_vid_caps_new (context, codec_id, "image/png", NULL);
969 970
      break;

971
    case CODEC_ID_PPM:
972
      caps = gst_ff_vid_caps_new (context, codec_id, "image/ppm", NULL);
973
      break;
974

975
    case CODEC_ID_PBM:
976
      caps = gst_ff_vid_caps_new (context, codec_id, "image/pbm", NULL);
977
      break;
978

979
    case CODEC_ID_SMC: