gstffmpegcodecmap.c 98.4 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 325 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
      /* 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;
        }
        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;
      }
352 353 354 355 356

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

    /* 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:
      case CODEC_ID_AAC:
      case CODEC_ID_DTS:
        maxchannels = 6;
        break;
      default:
        break;
    }
371

372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395
    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);
396 397
  }

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

  return caps;
}
407 408 409 410 411 412

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

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

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

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

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

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

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

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

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

487
    case CODEC_ID_RV10:
488
    case CODEC_ID_RV20:
489
    case CODEC_ID_RV30:
490
    case CODEC_ID_RV40:
491 492
    {
      gint version;
493

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

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

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

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

544 545 546 547 548 549 550
    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;

551 552 553 554 555 556 557
    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;

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

563 564
    case CODEC_ID_ATRAC3:
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/atrac3", NULL);
565
      break;
566

567
    case CODEC_ID_DTS:
568
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-dts", NULL);
569
      break;
570

571 572 573 574 575 576
    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,
577
            "depth", G_TYPE_INT, context->bits_per_coded_sample, NULL);
578 579 580
      }
      break;

Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
581 582 583 584 585
      /* 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...)? */
586
    case CODEC_ID_MJPEG:
587
    case CODEC_ID_LJPEG:
588
      caps = gst_ff_vid_caps_new (context, codec_id, "image/jpeg", NULL);
Wim Taymans's avatar
Wim Taymans committed
589
      break;
590

591
    case CODEC_ID_SP5X:
592
      caps = gst_ff_vid_caps_new (context, codec_id, "video/sp5x", NULL);
593 594
      break;

595
    case CODEC_ID_MJPEGB:
596
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-mjpeg-b", NULL);
597 598
      break;

599
    case CODEC_ID_MPEG4:
600
      if (encode && context != NULL) {
601 602
        /* I'm not exactly sure what ffmpeg outputs... ffmpeg itself uses
         * the AVI fourcc 'DIVX', but 'mp4v' for Quicktime... */
603
        switch (context->codec_tag) {
604
          case GST_MAKE_FOURCC ('D', 'I', 'V', 'X'):
605
            caps = gst_ff_vid_caps_new (context, codec_id, "video/x-divx",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
606
                "divxversion", G_TYPE_INT, 5, NULL);
607 608 609 610
            break;
          case GST_MAKE_FOURCC ('m', 'p', '4', 'v'):
          default:
            /* FIXME: bitrate */
611
            caps = gst_ff_vid_caps_new (context, codec_id, "video/mpeg",
612 613 614 615
                "systemstream", G_TYPE_BOOLEAN, FALSE,
                "mpegversion", G_TYPE_INT, 4, NULL);
            break;
        }
616 617
      } else {
        /* The trick here is to separate xvid, divx, mpeg4, 3ivx et al */
618
        caps = gst_ff_vid_caps_new (context, codec_id, "video/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
619 620
            "mpegversion", G_TYPE_INT, 4,
            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
621
        if (encode) {
622 623
          gst_caps_append (caps, gst_ff_vid_caps_new (context, codec_id,
                  "video/x-divx", "divxversion", G_TYPE_INT, 5, NULL));
624
        } else {
625 626 627 628 629 630 631
          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));
632
        }
633
      }
634
      break;
635

636
    case CODEC_ID_RAWVIDEO:
637 638
      caps = gst_ffmpeg_codectype_to_caps (CODEC_TYPE_VIDEO, context, codec_id,
          encode);
639
      break;
640

641
    case CODEC_ID_MSMPEG4V1:
642 643
    case CODEC_ID_MSMPEG4V2:
    case CODEC_ID_MSMPEG4V3:
644 645 646 647 648 649 650 651 652
    {
      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));
653
      }
654
    }
655
      break;
656

657
    case CODEC_ID_WMV1:
658
    case CODEC_ID_WMV2:
659 660
    {
      gint version = (codec_id == CODEC_ID_WMV1) ? 1 : 2;
661

662 663 664
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-wmv",
          "wmvversion", G_TYPE_INT, version, NULL);
    }
665
      break;
666

667
    case CODEC_ID_FLV1:
668 669
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-flash-video",
          "flvversion", G_TYPE_INT, 1, NULL);
670
      break;
671

672
    case CODEC_ID_SVQ1:
673
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-svq",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
674
          "svqversion", G_TYPE_INT, 1, NULL);
675
      break;
676 677

    case CODEC_ID_SVQ3:
678
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-svq",
679
          "svqversion", G_TYPE_INT, 3, NULL);
680
      break;
681

682
    case CODEC_ID_DVAUDIO:
683
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-dv", NULL);
684
      break;
685

686
    case CODEC_ID_DVVIDEO:
687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719
    {
      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);
720
      }
721
    }
722
      break;
723

724 725
    case CODEC_ID_WMAV1:
    case CODEC_ID_WMAV2:
726 727
    {
      gint version = (codec_id == CODEC_ID_WMAV1) ? 1 : 2;
728

729 730 731 732 733 734 735 736 737 738
      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);
739
      }
740
    }
741
      break;
742

743 744
    case CODEC_ID_MACE3:
    case CODEC_ID_MACE6:
745 746
    {
      gint version = (codec_id == CODEC_ID_MACE3) ? 3 : 6;
747

748 749 750
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-mace",
          "maceversion", G_TYPE_INT, version, NULL);
    }
751
      break;
752

Wim Taymans's avatar
Wim Taymans committed
753
    case CODEC_ID_HUFFYUV:
754
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-huffyuv", NULL);
755 756
      if (context) {
        gst_caps_set_simple (caps,
757
            "bpp", G_TYPE_INT, context->bits_per_coded_sample, NULL);
758
      }
759 760 761
      break;

    case CODEC_ID_CYUV:
762 763 764
      caps =
          gst_ff_vid_caps_new (context, codec_id, "video/x-compressed-yuv",
          NULL);
765 766 767
      break;

    case CODEC_ID_H264:
768
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-h264", NULL);
769 770 771
      break;

    case CODEC_ID_INDEO3:
772
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-indeo",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
773
          "indeoversion", G_TYPE_INT, 3, NULL);
774 775
      break;

776
    case CODEC_ID_INDEO2:
777
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-indeo",
778 779 780
          "indeoversion", G_TYPE_INT, 2, NULL);
      break;

781
    case CODEC_ID_FLASHSV:
782 783
      caps =
          gst_ff_vid_caps_new (context, codec_id, "video/x-flash-screen", NULL);
784 785
      break;

786
    case CODEC_ID_VP3:
787
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp3", NULL);
788 789
      break;

790
    case CODEC_ID_VP5:
791
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp5", NULL);
792 793 794
      break;

    case CODEC_ID_VP6:
795
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp6", NULL);
796 797 798
      break;

    case CODEC_ID_VP6F:
799
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp6-flash", NULL);
800 801
      break;

802 803 804 805
    case CODEC_ID_VP6A:
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp6-alpha", NULL);
      break;

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

810
    case CODEC_ID_AAC:
811
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/mpeg",
812
          "mpegversion", G_TYPE_INT, 4, NULL);
813 814 815
      break;

    case CODEC_ID_ASV1:
816 817
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-asus",
          "asusversion", G_TYPE_INT, 1, NULL);
818
      break;
819
    case CODEC_ID_ASV2:
820 821
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-asus",
          "asusversion", G_TYPE_INT, 2, NULL);
822 823
      break;

824
    case CODEC_ID_FFV1:
825
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-ffv",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
826
          "ffvversion", G_TYPE_INT, 1, NULL);
827 828 829
      break;

    case CODEC_ID_4XM:
830
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-4xm", NULL);
831 832
      break;

833 834
    case CODEC_ID_XAN_WC3:
    case CODEC_ID_XAN_WC4:
835
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-xan",
836 837 838
          "wcversion", G_TYPE_INT, 3 - CODEC_ID_XAN_WC3 + codec_id, NULL);
      break;

839
    case CODEC_ID_CLJR:
840 841 842
      caps =
          gst_ff_vid_caps_new (context, codec_id,
          "video/x-cirrus-logic-accupak", NULL);
843 844 845
      break;

    case CODEC_ID_FRAPS:
846 847 848 849 850 851
    case CODEC_ID_MDEC:
    case CODEC_ID_ROQ:
    case CODEC_ID_INTERPLAY_VIDEO:
      buildcaps = TRUE;
      break;

852
    case CODEC_ID_VCR1:
853 854
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-ati-vcr",
          "vcrversion", G_TYPE_INT, 1, NULL);
855 856
      break;

857
    case CODEC_ID_RPZA:
858 859
      caps =
          gst_ff_vid_caps_new (context, codec_id, "video/x-apple-video", NULL);
860 861
      break;

862
    case CODEC_ID_CINEPAK:
863
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-cinepak", NULL);
864 865
      break;

866
      /* WS_VQA belogns here (order) */
867 868

    case CODEC_ID_MSRLE:
869
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-rle",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
870
          "layout", G_TYPE_STRING, "microsoft", NULL);
871 872
      if (context) {
        gst_caps_set_simple (caps,
873
            "depth", G_TYPE_INT, (gint) context->bits_per_coded_sample, NULL);
874 875 876 877 878
      } else {
        gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 1, 64, NULL);
      }
      break;

879
    case CODEC_ID_QTRLE:
880
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-rle",
881 882 883
          "layout", G_TYPE_STRING, "quicktime", NULL);
      if (context) {
        gst_caps_set_simple (caps,
884
            "depth", G_TYPE_INT, (gint) context->bits_per_coded_sample, NULL);
885 886 887 888 889
      } else {
        gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 1, 64, NULL);
      }
      break;

890
    case CODEC_ID_MSVIDEO1:
891
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-msvideocodec",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
892
          "msvideoversion", G_TYPE_INT, 1, NULL);
893 894
      break;

895
    case CODEC_ID_WMV3:
896
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-wmv",
897 898
          "wmvversion", G_TYPE_INT, 3, NULL);
      break;
899 900
    case CODEC_ID_VC1:
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-wmv",
901 902
          "wmvversion", G_TYPE_INT, 3, "fourcc", GST_TYPE_FOURCC,
          GST_MAKE_FOURCC ('W', 'V', 'C', '1'), NULL);
903
      break;
904
    case CODEC_ID_QDM2:
905 906
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-qdm2", NULL);
      break;
907

908
    case CODEC_ID_MSZH:
909
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-mszh", NULL);
910 911 912
      break;

    case CODEC_ID_ZLIB:
913
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-zlib", NULL);
914 915 916
      break;

    case CODEC_ID_TRUEMOTION1:
917 918
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-truemotion",
          "trueversion", G_TYPE_INT, 1, NULL);
919 920
      break;
    case CODEC_ID_TRUEMOTION2:
921 922
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-truemotion",
          "trueversion", G_TYPE_INT, 2, NULL);
923 924 925
      break;

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

    case CODEC_ID_TSCC:
931
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-camtasia", NULL);
932 933
      if (context) {
        gst_caps_set_simple (caps,
934
            "depth", G_TYPE_INT, (gint) context->bits_per_coded_sample, NULL);
935 936 937
      } else {
        gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 8, 32, NULL);
      }
938 939
      break;

940 941 942 943 944 945 946 947
    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;

948 949 950 951
    case CODEC_ID_GIF:
      caps = gst_ff_vid_caps_new (context, codec_id, "image/gif", NULL);
      break;

952
    case CODEC_ID_PNG:
953
      caps = gst_ff_vid_caps_new (context, codec_id, "image/png", NULL);
954 955
      break;

956
    case CODEC_ID_PPM:
957
      caps = gst_ff_vid_caps_new (context, codec_id, "image/ppm", NULL);
958
      break;
959

960
    case CODEC_ID_PBM:
961
      caps = gst_ff_vid_caps_new (context, codec_id, "image/pbm", NULL);
962
      break;
963

964
    case CODEC_ID_SMC:
965
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-smc", NULL);
966 967
      break;

968
    case CODEC_ID_QDRAW:
969
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-qdrw", NULL);
970 971
      break;

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