We are currently experiencing downtime impacting viewing & cloning the Mesa repo, and some GitLab pages returning 503. Please see #freedesktop on IRC for more updates.

gstffmpegcodecmap.c 94 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
    } else {
      for (i = 0; i < nchannels; i++)
        pos[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
    }
  }

163 164 165 166 167 168 169 170 171 172
  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;
  } else if (nchannels == 2 && pos[0] == GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT
      && pos[1] == GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT) {
    GST_DEBUG ("stereo common case; won't set channel positions");
    g_free (pos);
    pos = NULL;
  }
173 174 175 176

  return pos;
}

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

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

196 197
  /* fixed, non probing context */
  if (context != NULL && context->width != -1) {
198 199 200 201
    caps = gst_caps_new_simple (mimetype,
        "width", G_TYPE_INT, context->width,
        "height", G_TYPE_INT, context->height,
        "framerate", GST_TYPE_FRACTION,
202 203
        context->time_base.den / context->ticks_per_frame,
        context->time_base.num, NULL);
204
  } else {
205
    /* so we are after restricted caps in this case */
206
    switch (codec_id) {
207 208 209 210 211 212 213 214 215 216 217 218
      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;
      }
219 220 221 222 223 224 225 226 227
      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);
228

229 230 231 232 233 234
        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);
235

236 237 238 239
          gst_caps_append (caps, temp);
        }
        break;
      }
240 241
      case CODEC_ID_DVVIDEO:
      {
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
        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}
        };
257
        GstCaps *temp;
258
        gint n_sizes = G_N_ELEMENTS (profiles);
259 260 261 262

        caps = gst_caps_new_empty ();
        for (i = 0; i < n_sizes; i++) {
          temp = gst_caps_new_simple (mimetype,
263 264 265 266 267
              "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);
268 269

          gst_caps_append (caps, temp);
270
        }
271 272
        break;
      }
273 274
      case CODEC_ID_DNXHD:
      {
275
        caps = gst_caps_new_simple (mimetype,
276 277
            "width", G_TYPE_INT, 1920,
            "height", G_TYPE_INT, 1080,
278
            "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
279 280 281 282 283 284 285
        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:
286 287 288 289
        break;
    }
  }

290 291
  /* no fixed caps or special restrictions applied;
   * default unfixed setting */
292 293
  if (!caps) {
    GST_DEBUG ("Creating default caps");
294 295 296 297
    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);
298
  }
299

300
  for (i = 0; i < gst_caps_get_size (caps); i++) {
301
    va_start (var_args, fieldname);
302
    structure = gst_caps_get_structure (caps, i);
303 304 305 306 307 308
    gst_structure_set_valist (structure, fieldname, var_args);
    va_end (var_args);
  }

  return caps;
}
309 310 311

/* same for audio - now with channels/sample rate
 */
312
static GstCaps *
313 314
gst_ff_aud_caps_new (AVCodecContext * context, enum CodecID codec_id,
    const char *mimetype, const char *fieldname, ...)
315 316 317
{
  GstCaps *caps = NULL;
  GstStructure *structure = NULL;
318
  gint i;
319 320
  va_list var_args;

321 322
  /* fixed, non-probing context */
  if (context != NULL && context->channels != -1) {
323
    GstAudioChannelPosition *pos;
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
    guint64 channel_layout = context->channel_layout;

    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;
      }
    }
344

345 346
    caps = gst_caps_new_simple (mimetype,
        "rate", G_TYPE_INT, context->sample_rate,
347
        "channels", G_TYPE_INT, context->channels, NULL);
348

349
    pos = gst_ff_channel_layout_to_gst (channel_layout, context->channels);
350 351 352 353
    if (pos != NULL) {
      gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos);
      g_free (pos);
    }
354
  } else {
355 356 357
    gint maxchannels = 2;
    const gint *rates = NULL;
    gint n_rates = 0;
358

359
    if (context) {
360 361 362 363 364 365 366 367 368 369
      /* 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;
        }
370
        case CODEC_ID_EAC3:
371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394
        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;
395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410
        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;
        }
411 412 413
        default:
          break;
      }
414 415 416 417 418

      /* TODO: handle context->channel_layouts here to set
       * the list of channel layouts supported by the encoder.
       * Unfortunately no encoder uses this yet....
       */
419 420 421 422 423 424 425
    }

    /* 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:
426
      case CODEC_ID_EAC3:
427 428 429 430 431 432 433
      case CODEC_ID_AAC:
      case CODEC_ID_DTS:
        maxchannels = 6;
        break;
      default:
        break;
    }
434

435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457
    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
458
      gst_caps_set_simple (caps, "rate", GST_TYPE_INT_RANGE, 4000, 96000, NULL);
459 460
  }

461
  for (i = 0; i < gst_caps_get_size (caps); i++) {
462
    va_start (var_args, fieldname);
463
    structure = gst_caps_get_structure (caps, i);
464 465 466 467 468 469
    gst_structure_set_valist (structure, fieldname, var_args);
    va_end (var_args);
  }

  return caps;
}
470 471 472 473 474 475

/* 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!
476 477 478 479 480 481 482 483 484
 *
 * 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.
485 486
 */

487
GstCaps *
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
488 489
gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
    AVCodecContext * context, gboolean encode)
490
{
491
  GstCaps *caps = NULL;
492
  gboolean buildcaps = FALSE;
493

494 495
  GST_LOG ("codec_id:%d, context:%p, encode:%d", codec_id, context, encode);

496
  switch (codec_id) {
497
    case CODEC_ID_MPEG1VIDEO:
498 499 500 501
      /* FIXME: bitrate */
      caps = gst_ff_vid_caps_new (context, codec_id, "video/mpeg",
          "mpegversion", G_TYPE_INT, 1,
          "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
502 503 504 505 506
      break;

    case CODEC_ID_MPEG2VIDEO:
      if (encode) {
        /* FIXME: bitrate */
507
        caps = gst_ff_vid_caps_new (context, codec_id, "video/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
508 509
            "mpegversion", G_TYPE_INT, 2,
            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
510 511 512 513
      } 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
514 515
            "mpegversion", GST_TYPE_INT_RANGE, 1, 2,
            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
516
      }
517
      break;
518 519 520 521 522 523

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

    case CODEC_ID_H263:
524
      if (encode) {
525
        caps = gst_ff_vid_caps_new (context, codec_id, "video/x-h263",
526 527 528
            "variant", G_TYPE_STRING, "itu",
            "h263version", G_TYPE_STRING, "h263", NULL);
      } else {
529 530 531 532
        /* 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",
533 534
            "variant", G_TYPE_STRING, "itu", NULL);
      }
535 536 537
      break;

    case CODEC_ID_H263P:
538
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-h263",
539 540
          "variant", G_TYPE_STRING, "itu",
          "h263version", G_TYPE_STRING, "h263p", NULL);
541
      break;
542

543
    case CODEC_ID_H263I:
544
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-intel-h263",
545
          "variant", G_TYPE_STRING, "intel", NULL);
546 547
      break;

548
    case CODEC_ID_H261:
549
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-h261", NULL);
550 551
      break;

552
    case CODEC_ID_RV10:
553
    case CODEC_ID_RV20:
554
    case CODEC_ID_RV30:
555
    case CODEC_ID_RV40:
556 557
    {
      gint version;
558

559 560 561 562
      switch (codec_id) {
        case CODEC_ID_RV40:
          version = 4;
          break;
563 564 565
        case CODEC_ID_RV30:
          version = 3;
          break;
566 567 568 569 570 571 572
        case CODEC_ID_RV20:
          version = 2;
          break;
        default:
          version = 1;
          break;
      }
573

574 575 576 577 578
      /* 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) {
579
        gst_caps_set_simple (caps, "format", G_TYPE_INT, context->sub_id, NULL);
580 581
        if (context->extradata_size >= 8) {
          gst_caps_set_simple (caps,
582 583 584
              "subformat", G_TYPE_INT, GST_READ_UINT32_BE (context->extradata),
              NULL);
        }
585
      }
586
    }
587
      break;
588

589 590 591 592 593 594
    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;

595
    case CODEC_ID_MP2:
596 597 598
      /* FIXME: bitrate */
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/mpeg",
          "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 2, NULL);
599
      break;
600

601 602 603
    case CODEC_ID_MP3:
      if (encode) {
        /* FIXME: bitrate */
604
        caps = gst_ff_aud_caps_new (context, codec_id, "audio/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
605
            "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 3, NULL);
606 607 608 609
      } 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
610 611
            "mpegversion", G_TYPE_INT, 1,
            "layer", GST_TYPE_INT_RANGE, 1, 3, NULL);
612
      }
613
      break;
614

615 616 617 618 619 620 621
    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;

622 623 624 625 626 627 628
    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;

629 630 631
    case CODEC_ID_AC3:
      /* FIXME: bitrate */
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-ac3", NULL);
632
      break;
633

634 635 636 637 638
    case CODEC_ID_EAC3:
      /* FIXME: bitrate */
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-eac3", NULL);
      break;

639
    case CODEC_ID_ATRAC3:
640 641 642
      caps =
          gst_ff_aud_caps_new (context, codec_id, "audio/x-vnd.sony.atrac3",
          NULL);
643
      break;
644

645
    case CODEC_ID_DTS:
646
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-dts", NULL);
647
      break;
648

649 650 651 652 653 654
    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,
655
            "depth", G_TYPE_INT, context->bits_per_coded_sample, NULL);
656 657 658
      }
      break;

659 660 661
    case CODEC_ID_MLP:
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-mlp", NULL);
      break;
662

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

Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
667 668 669 670 671
      /* 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...)? */
672
    case CODEC_ID_MJPEG:
673
    case CODEC_ID_LJPEG:
674
      caps = gst_ff_vid_caps_new (context, codec_id, "image/jpeg", NULL);
Wim Taymans's avatar
Wim Taymans committed
675
      break;
676

677
    case CODEC_ID_SP5X:
678
      caps = gst_ff_vid_caps_new (context, codec_id, "video/sp5x", NULL);
679 680
      break;

681
    case CODEC_ID_MJPEGB:
682
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-mjpeg-b", NULL);
683 684
      break;

685
    case CODEC_ID_MPEG4:
686
      if (encode && context != NULL) {
687 688
        /* I'm not exactly sure what ffmpeg outputs... ffmpeg itself uses
         * the AVI fourcc 'DIVX', but 'mp4v' for Quicktime... */
689
        switch (context->codec_tag) {
690
          case GST_MAKE_FOURCC ('D', 'I', 'V', 'X'):
691
            caps = gst_ff_vid_caps_new (context, codec_id, "video/x-divx",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
692
                "divxversion", G_TYPE_INT, 5, NULL);
693 694 695 696
            break;
          case GST_MAKE_FOURCC ('m', 'p', '4', 'v'):
          default:
            /* FIXME: bitrate */
697
            caps = gst_ff_vid_caps_new (context, codec_id, "video/mpeg",
698 699 700 701
                "systemstream", G_TYPE_BOOLEAN, FALSE,
                "mpegversion", G_TYPE_INT, 4, NULL);
            break;
        }
702 703
      } else {
        /* The trick here is to separate xvid, divx, mpeg4, 3ivx et al */
704
        caps = gst_ff_vid_caps_new (context, codec_id, "video/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
705 706
            "mpegversion", G_TYPE_INT, 4,
            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
707
        if (encode) {
708 709
          gst_caps_append (caps, gst_ff_vid_caps_new (context, codec_id,
                  "video/x-divx", "divxversion", G_TYPE_INT, 5, NULL));
710
        } else {
711 712 713 714 715 716 717
          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));
718
        }
719
      }
720
      break;
721

722
    case CODEC_ID_RAWVIDEO:
723 724
      caps = gst_ffmpeg_codectype_to_caps (CODEC_TYPE_VIDEO, context, codec_id,
          encode);
725
      break;
726

727
    case CODEC_ID_MSMPEG4V1:
728 729
    case CODEC_ID_MSMPEG4V2:
    case CODEC_ID_MSMPEG4V3:
730 731 732 733 734 735 736 737 738
    {
      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));
739
      }
740
    }
741
      break;
742

743
    case CODEC_ID_WMV1:
744
    case CODEC_ID_WMV2:
745 746
    {
      gint version = (codec_id == CODEC_ID_WMV1) ? 1 : 2;
747

748 749 750
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-wmv",
          "wmvversion", G_TYPE_INT, version, NULL);
    }
751
      break;
752

753
    case CODEC_ID_FLV1:
754 755
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-flash-video",
          "flvversion", G_TYPE_INT, 1, NULL);
756
      break;
757

758
    case CODEC_ID_SVQ1:
759
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-svq",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
760
          "svqversion", G_TYPE_INT, 1, NULL);
761
      break;
762 763

    case CODEC_ID_SVQ3:
764
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-svq",
765
          "svqversion", G_TYPE_INT, 3, NULL);
766
      break;
767

768
    case CODEC_ID_DVAUDIO:
769
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-dv", NULL);
770
      break;
771

772
    case CODEC_ID_DVVIDEO:
773 774 775 776 777
    {
      if (encode && context) {
        guint32 fourcc;

        switch (context->pix_fmt) {
778
          case PIX_FMT_YUYV422:
779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805
            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);
806
      }
807
    }
808
      break;
809

810 811
    case CODEC_ID_WMAV1:
    case CODEC_ID_WMAV2:
812 813
    {
      gint version = (codec_id == CODEC_ID_WMAV1) ? 1 : 2;
814

815 816 817 818 819 820 821 822 823 824
      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);
825
      }
826
    }
827
      break;
828

829 830
    case CODEC_ID_MACE3:
    case CODEC_ID_MACE6:
831 832
    {
      gint version = (codec_id == CODEC_ID_MACE3) ? 3 : 6;
833

834 835 836
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-mace",
          "maceversion", G_TYPE_INT, version, NULL);
    }
837
      break;
838

Wim Taymans's avatar
Wim Taymans committed
839
    case CODEC_ID_HUFFYUV:
840
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-huffyuv", NULL);
841 842
      if (context) {
        gst_caps_set_simple (caps,
843
            "bpp", G_TYPE_INT, context->bits_per_coded_sample, NULL);
844
      }
845 846 847
      break;

    case CODEC_ID_CYUV:
848 849 850
      caps =
          gst_ff_vid_caps_new (context, codec_id, "video/x-compressed-yuv",
          NULL);
851 852 853
      break;

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

    case CODEC_ID_INDEO3:
858
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-indeo",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
859
          "indeoversion", G_TYPE_INT, 3, NULL);
860 861
      break;

862
    case CODEC_ID_INDEO2:
863
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-indeo",
864 865 866
          "indeoversion", G_TYPE_INT, 2, NULL);
      break;

867
    case CODEC_ID_FLASHSV:
868 869
      caps =
          gst_ff_vid_caps_new (context, codec_id, "video/x-flash-screen", NULL);
870 871
      break;

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

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

    case CODEC_ID_VP6:
881
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp6", NULL);
882 883 884
      break;

    case CODEC_ID_VP6F:
885
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp6-flash", NULL);
886 887
      break;

888 889 890 891
    case CODEC_ID_VP6A:
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp6-alpha", NULL);
      break;

892
    case CODEC_ID_THEORA:
893
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-theora", NULL);
894 895
      break;

896
    case CODEC_ID_AAC:
897
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/mpeg",
898
          "mpegversion", G_TYPE_INT, 4, NULL);
899 900 901
      break;

    case CODEC_ID_ASV1:
902 903
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-asus",
          "asusversion", G_TYPE_INT, 1, NULL);
904
      break;
905
    case CODEC_ID_ASV2:
906 907
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-asus",
          "asusversion", G_TYPE_INT, 2, NULL);
908 909
      break;

910
    case CODEC_ID_FFV1:
911
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-ffv",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
912
          "ffvversion", G_TYPE_INT, 1, NULL);
913 914 915
      break;

    case CODEC_ID_4XM:
916
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-4xm", NULL);
917 918
      break;

919 920
    case CODEC_ID_XAN_WC3:
    case CODEC_ID_XAN_WC4:
921
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-xan",
922 923 924
          "wcversion", G_TYPE_INT, 3 - CODEC_ID_XAN_WC3 + codec_id, NULL);
      break;

925
    case CODEC_ID_CLJR:
926 927 928
      caps =
          gst_ff_vid_caps_new (context, codec_id,
          "video/x-cirrus-logic-accupak", NULL);
929 930 931
      break;

    case CODEC_ID_FRAPS:
932 933 934
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-fraps", NULL);
      break;

935 936 937 938 939 940
    case CODEC_ID_MDEC:
    case CODEC_ID_ROQ:
    case CODEC_ID_INTERPLAY_VIDEO:
      buildcaps = TRUE;
      break;

941
    case CODEC_ID_VCR1:
942 943
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-ati-vcr",
          "vcrversion", G_TYPE_INT, 1, NULL);
944 945
      break;

946
    case CODEC_ID_RPZA:
947 948
      caps =
          gst_ff_vid_caps_new (context, codec_id, "video/x-apple-video", NULL);
949 950
      break;

951
    case CODEC_ID_CINEPAK:
952
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-cinepak", NULL);
953 954
      break;

955
      /* WS_VQA belogns here (order) */
956 957

    case CODEC_ID_MSRLE:
958
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-rle",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
959
          "layout", G_TYPE_STRING, "microsoft", NULL);
960 961
      if (context) {
        gst_caps_set_simple (caps,
962
            "depth", G_TYPE_INT, (gint) context->bits_per_coded_sample, NULL);
963 964 965 966 967
      } else {
        gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 1, 64, NULL);
      }
      break;

968
    case CODEC_ID_QTRLE:
969
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-rle",
970 971 972
          "layout", G_TYPE_STRING, "quicktime", NULL);
      if (context) {
        gst_caps_set_simple (caps,
973
            "depth", G_TYPE_INT, (gint) context->bits_per_coded_sample, NULL);
974 975 976 977 978
      } else {
        gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 1, 64, NULL);
      }
      break;

979
    case CODEC_ID_MSVIDEO1:
980
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-msvideocodec",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
981
          "msvideoversion", G_TYPE_INT, 1, NULL);
982 983
      break;

984
    case CODEC_ID_WMV3:
985
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-wmv",
Jan Schmidt's avatar
Jan Schmidt committed
986 987
          "wmvversion", G_TYPE_INT, 3, "format", GST_TYPE_FOURCC,
          GST_MAKE_FOURCC ('W', 'M', 'V', '3'), NULL);
988
      break;
989 990
    case CODEC_ID_VC1:
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-wmv",