gstffmpegcodecmap.c 98.2 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 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
/* 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;
  }

  if (!gst_audio_check_channel_positions (pos, nchannels)) {
    GST_ERROR ("Invalid channel layout - assuming NONE layout");
    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;
    } 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;
}

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

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

214 215 216 217 218 219
        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);
220

221 222 223 224
          gst_caps_append (caps, temp);
        }
        break;
      }
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
      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);
240
        }
241 242
        break;
      }
243 244
      case CODEC_ID_DNXHD:
      {
245
        caps = gst_caps_new_simple (mimetype,
246 247
            "width", G_TYPE_INT, 1920,
            "height", G_TYPE_INT, 1080,
248
            "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
249 250 251 252 253 254 255
        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:
256 257 258 259
        break;
    }
  }

260 261 262 263 264 265 266 267
  /* 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);

268
  for (i = 0; i < gst_caps_get_size (caps); i++) {
269
    va_start (var_args, fieldname);
270
    structure = gst_caps_get_structure (caps, i);
271 272 273 274 275 276
    gst_structure_set_valist (structure, fieldname, var_args);
    va_end (var_args);
  }

  return caps;
}
277 278 279 280

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

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

290 291
  /* fixed, non-probing context */
  if (context != NULL && context->channels != -1) {
292 293
    GstAudioChannelPosition *pos;

294 295
    caps = gst_caps_new_simple (mimetype,
        "rate", G_TYPE_INT, context->sample_rate,
296
        "channels", G_TYPE_INT, context->channels, NULL);
297 298 299 300 301 302 303 304

    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);
    }
305
  } else {
306 307 308
    gint maxchannels = 2;
    const gint *rates = NULL;
    gint n_rates = 0;
309

310
    if (context) {
311 312 313 314 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
      /* 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;
      }
348 349 350 351 352

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

    /* 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;
    }
367

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

394
  for (i = 0; i < gst_caps_get_size (caps); i++) {
395
    va_start (var_args, fieldname);
396
    structure = gst_caps_get_structure (caps, i);
397 398 399 400 401 402
    gst_structure_set_valist (structure, fieldname, var_args);
    va_end (var_args);
  }

  return caps;
}
403 404 405 406 407 408

/* 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!
409 410 411 412 413 414 415 416 417
 *
 * 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.
418 419
 */

420
GstCaps *
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
421 422
gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
    AVCodecContext * context, gboolean encode)
423
{
424
  GstCaps *caps = NULL;
425
  gboolean buildcaps = FALSE;
426

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

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

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

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

    case CODEC_ID_H263P:
469
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-h263",
470 471
          "variant", G_TYPE_STRING, "itu",
          "h263version", G_TYPE_STRING, "h263p", NULL);
472
      break;
473

474
    case CODEC_ID_H263I:
475
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-intel-h263",
476
          "variant", G_TYPE_STRING, "intel", NULL);
477 478
      break;

479
    case CODEC_ID_H261:
480
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-h261", NULL);
481 482
      break;

483
    case CODEC_ID_RV10:
484
    case CODEC_ID_RV20:
485
    case CODEC_ID_RV30:
486
    case CODEC_ID_RV40:
487 488
    {
      gint version;
489

490 491 492 493
      switch (codec_id) {
        case CODEC_ID_RV40:
          version = 4;
          break;
494 495 496
        case CODEC_ID_RV30:
          version = 3;
          break;
497 498 499 500 501 502 503
        case CODEC_ID_RV20:
          version = 2;
          break;
        default:
          version = 1;
          break;
      }
504

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

520
    case CODEC_ID_MP2:
521 522 523
      /* FIXME: bitrate */
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/mpeg",
          "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 2, NULL);
524
      break;
525

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

540 541 542 543 544 545 546
    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;

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

554 555 556
    case CODEC_ID_AC3:
      /* FIXME: bitrate */
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-ac3", NULL);
557
      break;
558

559 560
    case CODEC_ID_ATRAC3:
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/atrac3", NULL);
561
      break;
562

563
    case CODEC_ID_DTS:
564
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-dts", NULL);
565
      break;
566

567 568 569 570 571 572
    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,
573
            "depth", G_TYPE_INT, context->bits_per_coded_sample, NULL);
574 575 576
      }
      break;

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

587
    case CODEC_ID_SP5X:
588
      caps = gst_ff_vid_caps_new (context, codec_id, "video/sp5x", NULL);
589 590
      break;

591
    case CODEC_ID_MJPEGB:
592
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-mjpeg-b", NULL);
593 594
      break;

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

632
    case CODEC_ID_RAWVIDEO:
633 634
      caps = gst_ffmpeg_codectype_to_caps (CODEC_TYPE_VIDEO, context, codec_id,
          encode);
635
      break;
636

637
    case CODEC_ID_MSMPEG4V1:
638 639
    case CODEC_ID_MSMPEG4V2:
    case CODEC_ID_MSMPEG4V3:
640 641 642 643 644 645 646 647 648
    {
      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));
649
      }
650
    }
651
      break;
652

653
    case CODEC_ID_WMV1:
654
    case CODEC_ID_WMV2:
655 656
    {
      gint version = (codec_id == CODEC_ID_WMV1) ? 1 : 2;
657

658 659 660
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-wmv",
          "wmvversion", G_TYPE_INT, version, NULL);
    }
661
      break;
662

663
    case CODEC_ID_FLV1:
664 665
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-flash-video",
          "flvversion", G_TYPE_INT, 1, NULL);
666
      break;
667

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

    case CODEC_ID_SVQ3:
674
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-svq",
675
          "svqversion", G_TYPE_INT, 3, NULL);
676
      break;
677

678
    case CODEC_ID_DVAUDIO:
679
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-dv", NULL);
680
      break;
681

682
    case CODEC_ID_DVVIDEO:
683 684 685 686 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
    {
      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);
716
      }
717
    }
718
      break;
719

720 721
    case CODEC_ID_WMAV1:
    case CODEC_ID_WMAV2:
722 723
    {
      gint version = (codec_id == CODEC_ID_WMAV1) ? 1 : 2;
724

725 726 727 728 729 730 731 732 733 734
      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);
735
      }
736
    }
737
      break;
738

739 740
    case CODEC_ID_MACE3:
    case CODEC_ID_MACE6:
741 742
    {
      gint version = (codec_id == CODEC_ID_MACE3) ? 3 : 6;
743

744 745 746
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-mace",
          "maceversion", G_TYPE_INT, version, NULL);
    }
747
      break;
748

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

    case CODEC_ID_CYUV:
758 759 760
      caps =
          gst_ff_vid_caps_new (context, codec_id, "video/x-compressed-yuv",
          NULL);
761 762 763
      break;

    case CODEC_ID_H264:
764
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-h264", NULL);
765 766 767
      break;

    case CODEC_ID_INDEO3:
768
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-indeo",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
769
          "indeoversion", G_TYPE_INT, 3, NULL);
770 771
      break;

772
    case CODEC_ID_INDEO2:
773
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-indeo",
774 775 776
          "indeoversion", G_TYPE_INT, 2, NULL);
      break;

777
    case CODEC_ID_FLASHSV:
778 779
      caps =
          gst_ff_vid_caps_new (context, codec_id, "video/x-flash-screen", NULL);
780 781
      break;

782
    case CODEC_ID_VP3:
783
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp3", NULL);
784 785
      break;

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

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

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

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

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

806
    case CODEC_ID_AAC:
807
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/mpeg",
808
          "mpegversion", G_TYPE_INT, 4, NULL);
809 810 811
      break;

    case CODEC_ID_ASV1:
812 813
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-asus",
          "asusversion", G_TYPE_INT, 1, NULL);
814
      break;
815
    case CODEC_ID_ASV2:
816 817
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-asus",
          "asusversion", G_TYPE_INT, 2, NULL);
818 819
      break;

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

    case CODEC_ID_4XM:
826
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-4xm", NULL);
827 828
      break;

829 830
    case CODEC_ID_XAN_WC3:
    case CODEC_ID_XAN_WC4:
831
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-xan",
832 833 834
          "wcversion", G_TYPE_INT, 3 - CODEC_ID_XAN_WC3 + codec_id, NULL);
      break;

835
    case CODEC_ID_CLJR:
836 837 838
      caps =
          gst_ff_vid_caps_new (context, codec_id,
          "video/x-cirrus-logic-accupak", NULL);
839 840 841
      break;

    case CODEC_ID_FRAPS:
842 843 844 845 846 847
    case CODEC_ID_MDEC:
    case CODEC_ID_ROQ:
    case CODEC_ID_INTERPLAY_VIDEO:
      buildcaps = TRUE;
      break;

848
    case CODEC_ID_VCR1:
849 850
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-ati-vcr",
          "vcrversion", G_TYPE_INT, 1, NULL);
851 852
      break;

853
    case CODEC_ID_RPZA:
854 855
      caps =
          gst_ff_vid_caps_new (context, codec_id, "video/x-apple-video", NULL);
856 857
      break;

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

862
      /* WS_VQA belogns here (order) */
863 864

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

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

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

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

904
    case CODEC_ID_MSZH:
905
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-mszh", NULL);
906 907 908
      break;

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

    case CODEC_ID_TRUEMOTION1:
913 914
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-truemotion",
          "trueversion", G_TYPE_INT, 1, NULL);
915 916
      break;
    case CODEC_ID_TRUEMOTION2:
917 918
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-truemotion",
          "trueversion", G_TYPE_INT, 2, NULL);
919 920 921
      break;

    case CODEC_ID_ULTI:
922 923
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-ultimotion",
          NULL);
924 925 926
      break;

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

936 937 938 939 940 941 942 943
    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;

944 945 946 947
    case CODEC_ID_GIF:
      caps = gst_ff_vid_caps_new (context, codec_id, "image/gif", NULL);
      break;

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

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

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

960
    case CODEC_ID_SMC:
961
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-smc", NULL);
962 963
      break;

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

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

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

976 977 978
    case CODEC_ID_VMNC:
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vmnc", NULL);
      break;