gstffmpegcodecmap.c 97.9 KB
Newer Older
1 2
/* GStreamer
 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3
 * This file:
4
 * Copyright (c) 2002-2004 Ronald Bultje <rbultje@ronald.bitfreak.net>
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

22
#ifdef HAVE_CONFIG_H
23
#include "config.h"
24
#endif
25
#include <gst/gst.h>
26 27 28
#ifdef HAVE_FFMPEG_UNINSTALLED
#include <avcodec.h>
#else
29
#include <libavcodec/avcodec.h>
30
#endif
31
#include <string.h>
32

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

Wim Taymans's avatar
Wim Taymans committed
36
#include <gst/video/video.h>
Wim Taymans's avatar
Wim Taymans committed
37
#include <gst/audio/audio.h>
38 39
#include <gst/pbutils/codec-utils.h>

40 41 42 43 44
/*
 * Read a palette from a caps.
 */

static void
45
gst_ffmpeg_get_palette (const GstCaps * caps, AVCodecContext * context)
46 47 48
{
  GstStructure *str = gst_caps_get_structure (caps, 0);
  const GValue *palette_v;
Wim Taymans's avatar
Wim Taymans committed
49
  GstBuffer *palette;
50 51

  /* do we have a palette? */
52
  if ((palette_v = gst_structure_get_value (str, "palette_data")) && context) {
53
    palette = gst_value_get_buffer (palette_v);
Wim Taymans's avatar
Wim Taymans committed
54
    if (gst_buffer_get_size (palette) >= AVPALETTE_SIZE) {
55 56 57 58
      if (context->palctrl)
        av_free (context->palctrl);
      context->palctrl = av_malloc (sizeof (AVPaletteControl));
      context->palctrl->palette_changed = 1;
Wim Taymans's avatar
Wim Taymans committed
59
      gst_buffer_extract (palette, 0, context->palctrl->palette,
60 61 62 63 64 65
          AVPALETTE_SIZE);
    }
  }
}

static void
66
gst_ffmpeg_set_palette (GstCaps * caps, AVCodecContext * context)
67 68
{
  if (context->palctrl) {
69
    GstBuffer *palette = gst_buffer_new_and_alloc (AVPALETTE_SIZE);
70

Wim Taymans's avatar
Wim Taymans committed
71
    gst_buffer_fill (palette, 0, context->palctrl->palette, AVPALETTE_SIZE);
72
    gst_caps_set_simple (caps, "palette_data", GST_TYPE_BUFFER, palette, NULL);
73 74 75
  }
}

76 77 78 79 80 81 82 83 84 85
/* 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}, {
86
  CH_LOW_FREQUENCY, GST_AUDIO_CHANNEL_POSITION_LFE1}, {
87 88 89 90 91 92 93
  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}, {
94 95 96 97 98 99 100
  CH_TOP_CENTER, GST_AUDIO_CHANNEL_POSITION_TOP_CENTER}, {
  CH_TOP_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT}, {
  CH_TOP_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER}, {
  CH_TOP_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT}, {
  CH_TOP_BACK_LEFT, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT}, {
  CH_TOP_BACK_CENTER, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER}, {
  CH_TOP_BACK_RIGHT, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT}, {
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
  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;
  }

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

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

167 168 169 170 171
  if (nchannels == 1 && pos[0] == GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER) {
    GST_DEBUG ("mono common case; won't set channel positions");
    g_free (pos);
    pos = NULL;
  }
172 173 174 175

  return pos;
}

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

193 194
  GST_LOG ("context:%p, codec_id:%d, mimetype:%s", context, codec_id, mimetype);

195 196
  /* fixed, non probing context */
  if (context != NULL && context->width != -1) {
197 198
    gint num, denom;

199 200
    caps = gst_caps_new_simple (mimetype,
        "width", G_TYPE_INT, context->width,
201 202 203 204 205
        "height", G_TYPE_INT, context->height, NULL);

    num = context->time_base.den / context->ticks_per_frame;
    denom = context->time_base.num;

206 207 208 209
    if (!denom) {
      GST_LOG ("invalid framerate: %d/0, -> %d/1", num, num);
      denom = 1;
    }
210 211 212 213 214 215 216 217
    if (gst_util_fraction_compare (num, denom, 1000, 1) > 0) {
      GST_LOG ("excessive framerate: %d/%d, -> 0/1", num, denom);
      num = 0;
      denom = 1;
    }
    GST_LOG ("setting framerate: %d/%d", num, denom);
    gst_caps_set_simple (caps,
        "framerate", GST_TYPE_FRACTION, num, denom, NULL);
218
  } else {
219
    /* so we are after restricted caps in this case */
220
    switch (codec_id) {
221 222 223 224 225 226 227 228 229 230 231 232
      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;
      }
233 234 235 236 237 238 239 240 241
      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);
242

243 244 245 246 247 248
        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);
249

250 251 252 253
          gst_caps_append (caps, temp);
        }
        break;
      }
254 255
      case CODEC_ID_DVVIDEO:
      {
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
        static struct
        {
          guint32 csp;
          gint width, height;
          gint par_n, par_d;
          gint framerate_n, framerate_d;
        } profiles[] = {
          {
          GST_MAKE_FOURCC ('Y', '4', '1', 'B'), 720, 480, 10, 11, 30000, 1001}, {
          GST_MAKE_FOURCC ('Y', '4', '1', 'B'), 720, 480, 40, 33, 30000, 1001}, {
          GST_MAKE_FOURCC ('I', '4', '2', '0'), 720, 576, 59, 54, 25, 1}, {
          GST_MAKE_FOURCC ('I', '4', '2', '0'), 720, 576, 118, 81, 25, 1}, {
          GST_MAKE_FOURCC ('Y', '4', '1', 'B'), 720, 576, 59, 54, 25, 1}, {
          GST_MAKE_FOURCC ('Y', '4', '1', 'B'), 720, 576, 118, 81, 25, 1}
        };
271
        GstCaps *temp;
272
        gint n_sizes = G_N_ELEMENTS (profiles);
273 274 275 276

        caps = gst_caps_new_empty ();
        for (i = 0; i < n_sizes; i++) {
          temp = gst_caps_new_simple (mimetype,
277 278 279 280 281
              "width", G_TYPE_INT, profiles[i].width,
              "height", G_TYPE_INT, profiles[i].height,
              "framerate", GST_TYPE_FRACTION, profiles[i].framerate_n,
              profiles[i].framerate_d, "pixel-aspect-ratio", GST_TYPE_FRACTION,
              profiles[i].par_n, profiles[i].par_d, NULL);
282 283

          gst_caps_append (caps, temp);
284
        }
285 286
        break;
      }
287 288
      case CODEC_ID_DNXHD:
      {
289
        caps = gst_caps_new_simple (mimetype,
290 291
            "width", G_TYPE_INT, 1920,
            "height", G_TYPE_INT, 1080,
292
            "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
293 294 295 296 297 298 299
        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:
300 301 302 303
        break;
    }
  }

304 305
  /* no fixed caps or special restrictions applied;
   * default unfixed setting */
306 307
  if (!caps) {
    GST_DEBUG ("Creating default caps");
308 309 310 311
    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);
312
  }
313

314
  for (i = 0; i < gst_caps_get_size (caps); i++) {
315
    va_start (var_args, fieldname);
316
    structure = gst_caps_get_structure (caps, i);
317 318 319 320 321 322
    gst_structure_set_valist (structure, fieldname, var_args);
    va_end (var_args);
  }

  return caps;
}
323 324 325

/* same for audio - now with channels/sample rate
 */
326
static GstCaps *
327 328
gst_ff_aud_caps_new (AVCodecContext * context, enum CodecID codec_id,
    const char *mimetype, const char *fieldname, ...)
329 330 331
{
  GstCaps *caps = NULL;
  GstStructure *structure = NULL;
332
  gint i;
333 334
  va_list var_args;

335 336
  /* fixed, non-probing context */
  if (context != NULL && context->channels != -1) {
337
    GstAudioInfo info;
338
    GstAudioChannelPosition *pos;
339 340
    guint64 channel_layout = context->channel_layout;

341 342 343
    gst_audio_info_init (&info);


344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361
    if (channel_layout == 0) {
      const guint64 default_channel_set[] = {
        0, 0, CH_LAYOUT_SURROUND, CH_LAYOUT_QUAD, CH_LAYOUT_5POINT0,
        CH_LAYOUT_5POINT1, 0, CH_LAYOUT_7POINT1
      };

      switch (codec_id) {
        case CODEC_ID_EAC3:
        case CODEC_ID_AC3:
        case CODEC_ID_DTS:
          if (context->channels > 0
              && context->channels < G_N_ELEMENTS (default_channel_set))
            channel_layout = default_channel_set[context->channels - 1];
          break;
        default:
          break;
      }
    }
362

363 364
    caps = gst_caps_new_simple (mimetype,
        "rate", G_TYPE_INT, context->sample_rate,
365
        "channels", G_TYPE_INT, context->channels, NULL);
366

367
    pos = gst_ff_channel_layout_to_gst (channel_layout, context->channels);
368
    if (pos != NULL) {
369 370 371
      guint64 mask;

      if (gst_audio_channel_positions_to_mask (pos, context->channels, &mask)) {
372
        gst_caps_set_simple (caps, "channel-mask", GST_TYPE_BITMASK, mask,
373 374
            NULL);
      }
375 376
      g_free (pos);
    }
377
  } else {
378 379 380
    gint maxchannels = 2;
    const gint *rates = NULL;
    gint n_rates = 0;
381

382
    /* so we must be after restricted caps in this case */
383 384
    switch (codec_id) {
      case CODEC_ID_AAC:
385
      case CODEC_ID_AAC_LATM:
386 387 388
      case CODEC_ID_DTS:
        maxchannels = 6;
        break;
389 390 391 392 393 394 395
      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;
396
      }
397 398 399 400 401 402 403 404 405 406
      case CODEC_ID_EAC3:
      case CODEC_ID_AC3:
      {
        const static gint l_rates[] = { 48000, 44100, 32000 };
        maxchannels = 6;
        n_rates = G_N_ELEMENTS (l_rates);
        rates = l_rates;
        break;
      }
      case CODEC_ID_ADPCM_G722:
407 408 409 410 411 412 413
      {
        const static gint l_rates[] = { 16000 };
        n_rates = G_N_ELEMENTS (l_rates);
        rates = l_rates;
        maxchannels = 1;
        break;
      }
414
      case CODEC_ID_ADPCM_G726:
415 416 417 418
      {
        const static gint l_rates[] = { 8000 };
        n_rates = G_N_ELEMENTS (l_rates);
        rates = l_rates;
419 420
        maxchannels = 1;
        break;
421
      }
422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453
      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_AMR_NB:
      {
        const static gint l_rates[] = { 8000 };
        maxchannels = 1;
        n_rates = G_N_ELEMENTS (l_rates);
        rates = l_rates;
        break;
      }
      case CODEC_ID_AMR_WB:
      {
        const static gint l_rates[] = { 16000 };
        maxchannels = 1;
        n_rates = G_N_ELEMENTS (l_rates);
        rates = l_rates;
        break;
      }
      default:
        break;
454 455
    }

456 457 458 459
    /* TODO: handle context->channel_layouts here to set
     * the list of channel layouts supported by the encoder.
     * Unfortunately no encoder uses this yet....
     */
460 461 462 463
    /* 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) {
464 465 466 467
      case CODEC_ID_WMAPRO:
      case CODEC_ID_TRUEHD:
        maxchannels = 8;
        break;
468 469 470
      default:
        break;
    }
471

472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494
    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
495
      gst_caps_set_simple (caps, "rate", GST_TYPE_INT_RANGE, 4000, 96000, NULL);
496 497
  }

498
  for (i = 0; i < gst_caps_get_size (caps); i++) {
499
    va_start (var_args, fieldname);
500
    structure = gst_caps_get_structure (caps, i);
501 502 503 504 505 506
    gst_structure_set_valist (structure, fieldname, var_args);
    va_end (var_args);
  }

  return caps;
}
507 508 509 510 511 512

/* 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!
513 514 515 516 517 518 519 520 521
 *
 * 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.
522 523
 */

524
GstCaps *
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
525 526
gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
    AVCodecContext * context, gboolean encode)
527
{
528
  GstCaps *caps = NULL;
529
  gboolean buildcaps = FALSE;
530

531 532
  GST_LOG ("codec_id:%d, context:%p, encode:%d", codec_id, context, encode);

533
  switch (codec_id) {
534
    case CODEC_ID_MPEG1VIDEO:
535 536 537 538
      /* FIXME: bitrate */
      caps = gst_ff_vid_caps_new (context, codec_id, "video/mpeg",
          "mpegversion", G_TYPE_INT, 1,
          "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
539 540 541 542 543
      break;

    case CODEC_ID_MPEG2VIDEO:
      if (encode) {
        /* FIXME: bitrate */
544
        caps = gst_ff_vid_caps_new (context, codec_id, "video/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
545 546
            "mpegversion", G_TYPE_INT, 2,
            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
547 548 549 550
      } 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
551 552
            "mpegversion", GST_TYPE_INT_RANGE, 1, 2,
            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
553
      }
554
      break;
555 556 557 558 559 560

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

    case CODEC_ID_H263:
561
      if (encode) {
562
        caps = gst_ff_vid_caps_new (context, codec_id, "video/x-h263",
563 564 565
            "variant", G_TYPE_STRING, "itu",
            "h263version", G_TYPE_STRING, "h263", NULL);
      } else {
566 567 568 569
        /* 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",
570 571
            "variant", G_TYPE_STRING, "itu", NULL);
      }
572 573 574
      break;

    case CODEC_ID_H263P:
575
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-h263",
576 577
          "variant", G_TYPE_STRING, "itu",
          "h263version", G_TYPE_STRING, "h263p", NULL);
578 579 580 581 582 583 584 585 586
      if (encode && context) {

        gst_caps_set_simple (caps,
            "annex-f", G_TYPE_BOOLEAN, context->flags & CODEC_FLAG_4MV,
            "annex-j", G_TYPE_BOOLEAN, context->flags & CODEC_FLAG_LOOP_FILTER,
            "annex-i", G_TYPE_BOOLEAN, context->flags & CODEC_FLAG_AC_PRED,
            "annex-t", G_TYPE_BOOLEAN, context->flags & CODEC_FLAG_AC_PRED,
            NULL);
      }
587
      break;
588

589
    case CODEC_ID_H263I:
590
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-intel-h263",
591
          "variant", G_TYPE_STRING, "intel", NULL);
592 593
      break;

594
    case CODEC_ID_H261:
595
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-h261", NULL);
596 597
      break;

598
    case CODEC_ID_RV10:
599
    case CODEC_ID_RV20:
600
    case CODEC_ID_RV30:
601
    case CODEC_ID_RV40:
602 603
    {
      gint version;
604

605 606 607 608
      switch (codec_id) {
        case CODEC_ID_RV40:
          version = 4;
          break;
609 610 611
        case CODEC_ID_RV30:
          version = 3;
          break;
612 613 614 615 616 617 618
        case CODEC_ID_RV20:
          version = 2;
          break;
        default:
          version = 1;
          break;
      }
619

620 621 622 623 624
      /* 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) {
625
        gst_caps_set_simple (caps, "format", G_TYPE_INT, context->sub_id, NULL);
626 627
        if (context->extradata_size >= 8) {
          gst_caps_set_simple (caps,
628 629 630
              "subformat", G_TYPE_INT, GST_READ_UINT32_BE (context->extradata),
              NULL);
        }
631
      }
632
    }
633
      break;
634

635 636 637 638 639 640
    case CODEC_ID_MP1:
      /* FIXME: bitrate */
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/mpeg",
          "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 1, NULL);
      break;

641
    case CODEC_ID_MP2:
642 643 644
      /* FIXME: bitrate */
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/mpeg",
          "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 2, NULL);
645
      break;
646

647 648 649
    case CODEC_ID_MP3:
      if (encode) {
        /* FIXME: bitrate */
650
        caps = gst_ff_aud_caps_new (context, codec_id, "audio/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
651
            "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 3, NULL);
652 653 654 655
      } 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
656 657
            "mpegversion", G_TYPE_INT, 1,
            "layer", GST_TYPE_INT_RANGE, 1, 3, NULL);
658
      }
659
      break;
660

661 662 663 664 665 666 667
    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;

668 669 670 671 672 673 674
    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;

675 676 677
    case CODEC_ID_AC3:
      /* FIXME: bitrate */
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-ac3", NULL);
678
      break;
679

680 681 682 683 684
    case CODEC_ID_EAC3:
      /* FIXME: bitrate */
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-eac3", NULL);
      break;

685 686 687 688 689
    case CODEC_ID_TRUEHD:
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-true-hd", NULL);
      break;

    case CODEC_ID_ATRAC1:
690
      caps =
691
          gst_ff_aud_caps_new (context, codec_id, "audio/x-vnd.sony.atrac1",
692
          NULL);
693
      break;
694

695 696
    case CODEC_ID_ATRAC3:
      caps =
697
          gst_ff_aud_caps_new (context, codec_id, "audio/x-vnd.sony.atrac3",
698 699 700
          NULL);
      break;

701
    case CODEC_ID_DTS:
702
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-dts", NULL);
703
      break;
704

705 706 707 708 709 710
    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,
711
            "depth", G_TYPE_INT, context->bits_per_coded_sample, NULL);
712 713 714
      }
      break;

715 716 717
    case CODEC_ID_MLP:
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-mlp", NULL);
      break;
718

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

Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
723 724 725 726 727
      /* 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...)? */
728
    case CODEC_ID_MJPEG:
729
    case CODEC_ID_LJPEG:
730
      caps = gst_ff_vid_caps_new (context, codec_id, "image/jpeg", NULL);
Wim Taymans's avatar
Wim Taymans committed
731
      break;
732

733
    case CODEC_ID_SP5X:
734
      caps = gst_ff_vid_caps_new (context, codec_id, "video/sp5x", NULL);
735 736
      break;

737
    case CODEC_ID_MJPEGB:
738
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-mjpeg-b", NULL);
739 740
      break;

741
    case CODEC_ID_MPEG4:
742
      if (encode && context != NULL) {
743 744
        /* I'm not exactly sure what ffmpeg outputs... ffmpeg itself uses
         * the AVI fourcc 'DIVX', but 'mp4v' for Quicktime... */
745
        switch (context->codec_tag) {
746
          case GST_MAKE_FOURCC ('D', 'I', 'V', 'X'):
747
            caps = gst_ff_vid_caps_new (context, codec_id, "video/x-divx",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
748
                "divxversion", G_TYPE_INT, 5, NULL);
749 750 751 752
            break;
          case GST_MAKE_FOURCC ('m', 'p', '4', 'v'):
          default:
            /* FIXME: bitrate */
753
            caps = gst_ff_vid_caps_new (context, codec_id, "video/mpeg",
754 755 756 757
                "systemstream", G_TYPE_BOOLEAN, FALSE,
                "mpegversion", G_TYPE_INT, 4, NULL);
            break;
        }
758 759
      } else {
        /* The trick here is to separate xvid, divx, mpeg4, 3ivx et al */
760
        caps = gst_ff_vid_caps_new (context, codec_id, "video/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
761 762
            "mpegversion", G_TYPE_INT, 4,
            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
763
        if (encode) {
764 765
          gst_caps_append (caps, gst_ff_vid_caps_new (context, codec_id,
                  "video/x-divx", "divxversion", G_TYPE_INT, 5, NULL));
766
        } else {
767 768 769 770 771 772 773
          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));
774
        }
775
      }
776
      break;
777

778
    case CODEC_ID_RAWVIDEO:
779 780
      caps =
          gst_ffmpeg_codectype_to_caps (AVMEDIA_TYPE_VIDEO, context, codec_id,
781
          encode);
782
      break;
783

784
    case CODEC_ID_MSMPEG4V1:
785 786
    case CODEC_ID_MSMPEG4V2:
    case CODEC_ID_MSMPEG4V3:
787 788 789 790 791 792 793 794 795
    {
      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));
796
      }
797
    }
798
      break;
799

800
    case CODEC_ID_WMV1:
801
    case CODEC_ID_WMV2:
802 803
    {
      gint version = (codec_id == CODEC_ID_WMV1) ? 1 : 2;
804

805 806 807
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-wmv",
          "wmvversion", G_TYPE_INT, version, NULL);
    }
808
      break;
809

810
    case CODEC_ID_FLV1:
811 812
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-flash-video",
          "flvversion", G_TYPE_INT, 1, NULL);
813
      break;
814

815
    case CODEC_ID_SVQ1:
816
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-svq",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
817
          "svqversion", G_TYPE_INT, 1, NULL);
818
      break;
819 820

    case CODEC_ID_SVQ3:
821
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-svq",
822
          "svqversion", G_TYPE_INT, 3, NULL);
823
      break;
824

825
    case CODEC_ID_DVAUDIO:
826
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-dv", NULL);
827
      break;
828

829
    case CODEC_ID_DVVIDEO:
830 831
    {
      if (encode && context) {
Wim Taymans's avatar
Wim Taymans committed
832
        const gchar *format;
833 834

        switch (context->pix_fmt) {
835
          case PIX_FMT_YUYV422:
Wim Taymans's avatar
Wim Taymans committed
836
            format = "YUY2";
837 838
            break;
          case PIX_FMT_YUV420P:
Wim Taymans's avatar
Wim Taymans committed
839
            format = "I420";
840
            break;
841
          case PIX_FMT_YUVA420P:
Wim Taymans's avatar
Wim Taymans committed
842
            format = "A420";
843
            break;
844
          case PIX_FMT_YUV411P:
Wim Taymans's avatar
Wim Taymans committed
845
            format = "Y41B";
846 847
            break;
          case PIX_FMT_YUV422P:
Wim Taymans's avatar
Wim Taymans committed
848
            format = "Y42B";
849 850
            break;
          case PIX_FMT_YUV410P:
Wim Taymans's avatar
Wim Taymans committed
851
            format = "YUV9";
852 853 854
            break;
          default:
            GST_WARNING
Wim Taymans's avatar
Wim Taymans committed
855
                ("Couldnt' find format for pixfmt %d, defaulting to I420",
856
                context->pix_fmt);
Wim Taymans's avatar
Wim Taymans committed
857
            format = "I420";
858 859 860 861
            break;
        }
        caps = gst_ff_vid_caps_new (context, codec_id, "video/x-dv",
            "systemstream", G_TYPE_BOOLEAN, FALSE,
Wim Taymans's avatar
Wim Taymans committed
862
            "format", G_TYPE_STRING, format, NULL);
863 864 865
      } else {
        caps = gst_ff_vid_caps_new (context, codec_id, "video/x-dv",
            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
866
      }
867
    }
868
      break;
869

870 871
    case CODEC_ID_WMAV1:
    case CODEC_ID_WMAV2:
872 873
    {
      gint version = (codec_id == CODEC_ID_WMAV1) ? 1 : 2;
874

875 876 877 878 879 880 881 882 883 884
      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);
885
      }
886
    }
887
      break;
888 889 890 891 892 893
    case CODEC_ID_WMAPRO:
    {
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-wma",
          "wmaversion", G_TYPE_INT, 3, NULL);
      break;
    }
894

895 896 897 898 899 900
    case CODEC_ID_WMAVOICE:
    {
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-wms", NULL);
      break;
    }

901 902
    case CODEC_ID_MACE3:
    case CODEC_ID_MACE6:
903 904
    {
      gint version = (codec_id == CODEC_ID_MACE3) ? 3 : 6;
905

906 907 908
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-mace",
          "maceversion", G_TYPE_INT, version, NULL);
    }
909
      break;
910

Wim Taymans's avatar
Wim Taymans committed
911
    case CODEC_ID_HUFFYUV:
912
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-huffyuv", NULL);
913 914
      if (context) {
        gst_caps_set_simple (caps,
915
            "bpp", G_TYPE_INT, context->bits_per_coded_sample, NULL);
916
      }
917 918 919
      break;

    case CODEC_ID_CYUV:
920 921 922
      caps =
          gst_ff_vid_caps_new (context, codec_id, "video/x-compressed-yuv",
          NULL);
923 924 925
      break;

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

929 930 931 932 933
    case CODEC_ID_INDEO5:
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-indeo",
          "indeoversion", G_TYPE_INT, 5, NULL);
      break;

934
    case CODEC_ID_INDEO3:
935
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-indeo",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
936
          "indeoversion", G_TYPE_INT, 3, NULL);
937 938
      break;

939
    case CODEC_ID_INDEO2:
940
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-indeo",
941 942 943
          "indeoversion", G_TYPE_INT, 2, NULL);
      break;

944
    case CODEC_ID_FLASHSV:
945 946
      caps =
          gst_ff_vid_caps_new (context, codec_id, "video/x-flash-screen", NULL);
947 948
      break;

949
    case CODEC_ID_VP3:
950
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp3", NULL);
951 952
      break;

953
    case CODEC_ID_VP5:
954
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp5", NULL);
955 956 957
      break;

    case CODEC_ID_VP6:
958
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp6", NULL);
959 960 961
      break;

    case CODEC_ID_VP6F:
962
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp6-flash", NULL);
963 964
      break;

965 966 967 968
    case CODEC_ID_VP6A:
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp6-alpha", NULL);
      break;

969 970 971