gstffmpegcodecmap.c 93.7 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 29 30
#ifdef HAVE_FFMPEG_UNINSTALLED
#include <avcodec.h>
#else
#include <ffmpeg/avcodec.h>
#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
/* 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.
77 78 79
 *
 * We should actually do this stuff at the end, like in riff-media.c,
 * but I'm too lazy today. Maybe later.
80
 */
81
static GstCaps *
82 83
gst_ff_vid_caps_new (AVCodecContext * context, enum CodecID codec_id,
    const char *mimetype, const char *fieldname, ...)
84 85 86 87
{
  GstStructure *structure = NULL;
  GstCaps *caps = NULL;
  va_list var_args;
88
  gint i;
89

90 91
  /* fixed, non probing context */
  if (context != NULL && context->width != -1) {
92 93 94 95
    caps = gst_caps_new_simple (mimetype,
        "width", G_TYPE_INT, context->width,
        "height", G_TYPE_INT, context->height,
        "framerate", GST_TYPE_FRACTION,
96
        context->time_base.den, context->time_base.num, NULL);
97 98
  } else if (context) {
    /* so we are after restricted caps in this case */
99
    switch (codec_id) {
100 101 102 103 104 105 106 107 108 109 110 111
      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;
      }
112 113 114 115 116 117 118 119 120
      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);
121

122 123 124 125 126 127
        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);
128

129 130 131 132
          gst_caps_append (caps, temp);
        }
        break;
      }
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
      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);
148
        }
149 150
        break;
      }
151 152
      case CODEC_ID_DNXHD:
      {
153
        caps = gst_caps_new_simple (mimetype,
154 155
            "width", G_TYPE_INT, 1920,
            "height", G_TYPE_INT, 1080,
156
            "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
157 158 159 160 161 162 163
        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:
164 165 166 167
        break;
    }
  }

168 169 170 171 172 173 174 175
  /* 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);

176
  for (i = 0; i < gst_caps_get_size (caps); i++) {
177
    va_start (var_args, fieldname);
178
    structure = gst_caps_get_structure (caps, i);
179 180 181 182 183 184
    gst_structure_set_valist (structure, fieldname, var_args);
    va_end (var_args);
  }

  return caps;
}
185 186 187 188

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

189
static GstCaps *
190 191
gst_ff_aud_caps_new (AVCodecContext * context, enum CodecID codec_id,
    const char *mimetype, const char *fieldname, ...)
192 193 194
{
  GstCaps *caps = NULL;
  GstStructure *structure = NULL;
195
  gint i;
196 197
  va_list var_args;

198 199
  /* fixed, non-probing context */
  if (context != NULL && context->channels != -1) {
200 201
    caps = gst_caps_new_simple (mimetype,
        "rate", G_TYPE_INT, context->sample_rate,
202
        "channels", G_TYPE_INT, context->channels, NULL);
203
  } else {
204 205 206
    gint maxchannels = 2;
    const gint *rates = NULL;
    gint n_rates = 0;
207

208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252
    if (context)
      /* 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;
          maxchannels = 6;
          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;
        case CODEC_ID_AAC:
        case CODEC_ID_DTS:
          /* Until decoders/encoders expose the maximum number of channels
           * they support, we whitelist them here. */
          maxchannels = 6;
          break;
        default:
          break;
      }
253

254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
    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);
278 279
  }

280
  for (i = 0; i < gst_caps_get_size (caps); i++) {
281
    va_start (var_args, fieldname);
282
    structure = gst_caps_get_structure (caps, i);
283 284 285 286 287 288
    gst_structure_set_valist (structure, fieldname, var_args);
    va_end (var_args);
  }

  return caps;
}
289 290 291 292 293 294

/* 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!
295 296 297 298 299 300 301 302 303
 *
 * 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.
304 305
 */

306
GstCaps *
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
307 308
gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
    AVCodecContext * context, gboolean encode)
309
{
310
  GstCaps *caps = NULL;
311
  gboolean buildcaps = FALSE;
312

313
  switch (codec_id) {
314
    case CODEC_ID_MPEG1VIDEO:
315 316 317 318
      /* FIXME: bitrate */
      caps = gst_ff_vid_caps_new (context, codec_id, "video/mpeg",
          "mpegversion", G_TYPE_INT, 1,
          "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
319 320 321 322 323
      break;

    case CODEC_ID_MPEG2VIDEO:
      if (encode) {
        /* FIXME: bitrate */
324
        caps = gst_ff_vid_caps_new (context, codec_id, "video/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
325 326
            "mpegversion", G_TYPE_INT, 2,
            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
327 328 329 330
      } 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
331 332
            "mpegversion", GST_TYPE_INT_RANGE, 1, 2,
            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
333
      }
334
      break;
335 336 337 338 339 340

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

    case CODEC_ID_H263:
341
      if (encode) {
342
        caps = gst_ff_vid_caps_new (context, codec_id, "video/x-h263",
343 344 345
            "variant", G_TYPE_STRING, "itu",
            "h263version", G_TYPE_STRING, "h263", NULL);
      } else {
346 347 348 349
        /* 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",
350 351
            "variant", G_TYPE_STRING, "itu", NULL);
      }
352 353 354
      break;

    case CODEC_ID_H263P:
355
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-h263",
356 357
          "variant", G_TYPE_STRING, "itu",
          "h263version", G_TYPE_STRING, "h263p", NULL);
358
      break;
359

360
    case CODEC_ID_H263I:
361
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-intel-h263",
362
          "variant", G_TYPE_STRING, "intel", NULL);
363 364
      break;

365
    case CODEC_ID_H261:
366
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-h261", NULL);
367 368
      break;

369
    case CODEC_ID_RV10:
370
    case CODEC_ID_RV20:
371
    case CODEC_ID_RV30:
372
    case CODEC_ID_RV40:
373 374
    {
      gint version;
375

376 377 378 379
      switch (codec_id) {
        case CODEC_ID_RV40:
          version = 4;
          break;
380 381 382
        case CODEC_ID_RV30:
          version = 3;
          break;
383 384 385 386 387 388 389
        case CODEC_ID_RV20:
          version = 2;
          break;
        default:
          version = 1;
          break;
      }
390

391 392 393 394 395
      /* 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) {
396
        gst_caps_set_simple (caps, "format", G_TYPE_INT, context->sub_id, NULL);
397 398
        if (context->extradata_size >= 8) {
          gst_caps_set_simple (caps,
399 400 401
              "subformat", G_TYPE_INT, GST_READ_UINT32_BE (context->extradata),
              NULL);
        }
402
      }
403
    }
404
      break;
405

406
    case CODEC_ID_MP2:
407 408 409
      /* FIXME: bitrate */
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/mpeg",
          "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 2, NULL);
410
      break;
411

412 413 414
    case CODEC_ID_MP3:
      if (encode) {
        /* FIXME: bitrate */
415
        caps = gst_ff_aud_caps_new (context, codec_id, "audio/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
416
            "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 3, NULL);
417 418 419 420
      } 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
421 422
            "mpegversion", G_TYPE_INT, 1,
            "layer", GST_TYPE_INT_RANGE, 1, 3, NULL);
423
      }
424
      break;
425

426 427 428 429 430 431 432
    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;

433 434 435 436 437 438 439
    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;

440 441 442
    case CODEC_ID_AC3:
      /* FIXME: bitrate */
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-ac3", NULL);
443
      break;
444

445 446
    case CODEC_ID_ATRAC3:
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/atrac3", NULL);
447
      break;
448

449
    case CODEC_ID_DTS:
450
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-dts", NULL);
451
      break;
452

453 454 455 456 457 458 459 460 461 462
    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,
            "depth", G_TYPE_INT, context->bits_per_sample, NULL);
      }
      break;

Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
463 464 465 466 467
      /* 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...)? */
468
    case CODEC_ID_MJPEG:
469
    case CODEC_ID_LJPEG:
470
      caps = gst_ff_vid_caps_new (context, codec_id, "image/jpeg", NULL);
Wim Taymans's avatar
Wim Taymans committed
471
      break;
472

473
    case CODEC_ID_SP5X:
474
      caps = gst_ff_vid_caps_new (context, codec_id, "video/sp5x", NULL);
475 476
      break;

477
    case CODEC_ID_MJPEGB:
478
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-mjpeg-b", NULL);
479 480
      break;

481
    case CODEC_ID_MPEG4:
482
      if (encode && context != NULL) {
483 484
        /* I'm not exactly sure what ffmpeg outputs... ffmpeg itself uses
         * the AVI fourcc 'DIVX', but 'mp4v' for Quicktime... */
485
        switch (context->codec_tag) {
486
          case GST_MAKE_FOURCC ('D', 'I', 'V', 'X'):
487
            caps = gst_ff_vid_caps_new (context, codec_id, "video/x-divx",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
488
                "divxversion", G_TYPE_INT, 5, NULL);
489 490 491 492
            break;
          case GST_MAKE_FOURCC ('m', 'p', '4', 'v'):
          default:
            /* FIXME: bitrate */
493
            caps = gst_ff_vid_caps_new (context, codec_id, "video/mpeg",
494 495 496 497
                "systemstream", G_TYPE_BOOLEAN, FALSE,
                "mpegversion", G_TYPE_INT, 4, NULL);
            break;
        }
498 499
      } else {
        /* The trick here is to separate xvid, divx, mpeg4, 3ivx et al */
500
        caps = gst_ff_vid_caps_new (context, codec_id, "video/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
501 502
            "mpegversion", G_TYPE_INT, 4,
            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
503
        if (encode) {
504 505
          gst_caps_append (caps, gst_ff_vid_caps_new (context, codec_id,
                  "video/x-divx", "divxversion", G_TYPE_INT, 5, NULL));
506
        } else {
507 508 509 510 511 512 513
          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));
514
        }
515
      }
516
      break;
517

518
    case CODEC_ID_RAWVIDEO:
519 520
      caps = gst_ffmpeg_codectype_to_caps (CODEC_TYPE_VIDEO, context, codec_id,
          encode);
521
      break;
522

523
    case CODEC_ID_MSMPEG4V1:
524 525
    case CODEC_ID_MSMPEG4V2:
    case CODEC_ID_MSMPEG4V3:
526 527 528 529 530 531 532 533 534
    {
      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));
535
      }
536
    }
537
      break;
538

539
    case CODEC_ID_WMV1:
540
    case CODEC_ID_WMV2:
541 542
    {
      gint version = (codec_id == CODEC_ID_WMV1) ? 1 : 2;
543

544 545 546
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-wmv",
          "wmvversion", G_TYPE_INT, version, NULL);
    }
547
      break;
548

549
    case CODEC_ID_FLV1:
550 551
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-flash-video",
          "flvversion", G_TYPE_INT, 1, NULL);
552
      break;
553

554
    case CODEC_ID_SVQ1:
555
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-svq",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
556
          "svqversion", G_TYPE_INT, 1, NULL);
557
      break;
558 559

    case CODEC_ID_SVQ3:
560
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-svq",
561
          "svqversion", G_TYPE_INT, 3, NULL);
562
      break;
563

564
    case CODEC_ID_DVAUDIO:
565
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-dv", NULL);
566
      break;
567

568
    case CODEC_ID_DVVIDEO:
569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601
    {
      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);
602
      }
603
    }
604
      break;
605

606 607
    case CODEC_ID_WMAV1:
    case CODEC_ID_WMAV2:
608 609
    {
      gint version = (codec_id == CODEC_ID_WMAV1) ? 1 : 2;
610

611 612 613 614 615 616 617 618 619 620
      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);
621
      }
622
    }
623
      break;
624

625 626
    case CODEC_ID_MACE3:
    case CODEC_ID_MACE6:
627 628
    {
      gint version = (codec_id == CODEC_ID_MACE3) ? 3 : 6;
629

630 631 632
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-mace",
          "maceversion", G_TYPE_INT, version, NULL);
    }
633
      break;
634

Wim Taymans's avatar
Wim Taymans committed
635
    case CODEC_ID_HUFFYUV:
636
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-huffyuv", NULL);
637 638 639 640
      if (context) {
        gst_caps_set_simple (caps,
            "bpp", G_TYPE_INT, context->bits_per_sample, NULL);
      }
641 642 643
      break;

    case CODEC_ID_CYUV:
644 645 646
      caps =
          gst_ff_vid_caps_new (context, codec_id, "video/x-compressed-yuv",
          NULL);
647 648 649
      break;

    case CODEC_ID_H264:
650
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-h264", NULL);
651 652 653
      break;

    case CODEC_ID_INDEO3:
654
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-indeo",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
655
          "indeoversion", G_TYPE_INT, 3, NULL);
656 657
      break;

658
    case CODEC_ID_INDEO2:
659
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-indeo",
660 661 662
          "indeoversion", G_TYPE_INT, 2, NULL);
      break;

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

668
    case CODEC_ID_VP3:
669
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp3", NULL);
670 671
      break;

672
    case CODEC_ID_VP5:
673
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp5", NULL);
674 675 676
      break;

    case CODEC_ID_VP6:
677
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp6", NULL);
678 679 680
      break;

    case CODEC_ID_VP6F:
681
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp6-flash", NULL);
682 683
      break;

684 685 686 687
    case CODEC_ID_VP6A:
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp6-alpha", NULL);
      break;

688
    case CODEC_ID_THEORA:
689
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-theora", NULL);
690 691
      break;

692
    case CODEC_ID_AAC:
693
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/mpeg",
694
          "mpegversion", G_TYPE_INT, 4, NULL);
695 696 697
      break;

    case CODEC_ID_ASV1:
698 699
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-asus",
          "asusversion", G_TYPE_INT, 1, NULL);
700
      break;
701
    case CODEC_ID_ASV2:
702 703
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-asus",
          "asusversion", G_TYPE_INT, 2, NULL);
704 705
      break;

706
    case CODEC_ID_FFV1:
707
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-ffv",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
708
          "ffvversion", G_TYPE_INT, 1, NULL);
709 710 711
      break;

    case CODEC_ID_4XM:
712
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-4xm", NULL);
713 714
      break;

715 716
    case CODEC_ID_XAN_WC3:
    case CODEC_ID_XAN_WC4:
717
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-xan",
718 719 720
          "wcversion", G_TYPE_INT, 3 - CODEC_ID_XAN_WC3 + codec_id, NULL);
      break;

721
    case CODEC_ID_CLJR:
722 723 724
      caps =
          gst_ff_vid_caps_new (context, codec_id,
          "video/x-cirrus-logic-accupak", NULL);
725 726 727
      break;

    case CODEC_ID_FRAPS:
728 729 730 731 732 733
    case CODEC_ID_MDEC:
    case CODEC_ID_ROQ:
    case CODEC_ID_INTERPLAY_VIDEO:
      buildcaps = TRUE;
      break;

734
    case CODEC_ID_VCR1:
735 736
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-ati-vcr",
          "vcrversion", G_TYPE_INT, 1, NULL);
737 738
      break;

739
    case CODEC_ID_RPZA:
740 741
      caps =
          gst_ff_vid_caps_new (context, codec_id, "video/x-apple-video", NULL);
742 743
      break;

744
    case CODEC_ID_CINEPAK:
745
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-cinepak", NULL);
746 747
      break;

748
      /* WS_VQA belogns here (order) */
749 750

    case CODEC_ID_MSRLE:
751
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-rle",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
752
          "layout", G_TYPE_STRING, "microsoft", NULL);
753 754
      if (context) {
        gst_caps_set_simple (caps,
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
755
            "depth", G_TYPE_INT, (gint) context->bits_per_sample, NULL);
756 757 758 759 760
      } else {
        gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 1, 64, NULL);
      }
      break;

761
    case CODEC_ID_QTRLE:
762
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-rle",
763 764 765 766 767 768 769 770 771
          "layout", G_TYPE_STRING, "quicktime", NULL);
      if (context) {
        gst_caps_set_simple (caps,
            "depth", G_TYPE_INT, (gint) context->bits_per_sample, NULL);
      } else {
        gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 1, 64, NULL);
      }
      break;

772
    case CODEC_ID_MSVIDEO1:
773
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-msvideocodec",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
774
          "msvideoversion", G_TYPE_INT, 1, NULL);
775 776
      break;

777
    case CODEC_ID_WMV3:
778
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-wmv",
779 780
          "wmvversion", G_TYPE_INT, 3, NULL);
      break;
781 782
    case CODEC_ID_VC1:
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-wmv",
783 784
          "wmvversion", G_TYPE_INT, 3, "fourcc", GST_TYPE_FOURCC,
          GST_MAKE_FOURCC ('W', 'V', 'C', '1'), NULL);
785
      break;
786
    case CODEC_ID_QDM2:
787 788
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-qdm2", NULL);
      break;
789

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

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

    case CODEC_ID_TRUEMOTION1:
799 800
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-truemotion",
          "trueversion", G_TYPE_INT, 1, NULL);
801 802
      break;
    case CODEC_ID_TRUEMOTION2:
803 804
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-truemotion",
          "trueversion", G_TYPE_INT, 2, NULL);
805 806 807
      break;

    case CODEC_ID_ULTI:
808 809
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-ultimotion",
          NULL);
810 811 812
      break;

    case CODEC_ID_TSCC:
813
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-camtasia", NULL);
814 815 816 817 818 819
      if (context) {
        gst_caps_set_simple (caps,
            "depth", G_TYPE_INT, (gint) context->bits_per_sample, NULL);
      } else {
        gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 8, 32, NULL);
      }
820 821
      break;

822 823 824 825 826 827 828 829
    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;

830 831 832 833
    case CODEC_ID_GIF:
      caps = gst_ff_vid_caps_new (context, codec_id, "image/gif", NULL);
      break;

834
    case CODEC_ID_PNG:
835
      caps = gst_ff_vid_caps_new (context, codec_id, "image/png", NULL);
836 837
      break;

838
    case CODEC_ID_PPM:
839
      caps = gst_ff_vid_caps_new (context, codec_id, "image/ppm", NULL);
840
      break;
841

842
    case CODEC_ID_PBM:
843
      caps = gst_ff_vid_caps_new (context, codec_id, "image/pbm", NULL);
844
      break;
845

846
    case CODEC_ID_SMC:
847
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-smc", NULL);
848 849
      break;

850
    case CODEC_ID_QDRAW:
851
      caps = gst_ff_vid_caps_new (context, codec_id, "video/x-qdrw", NULL);
852 853
      break;

854 855 856 857 858 859 860 861 862 863 864 865
  case CODEC_ID_DNXHD:
    caps = gst_ff_vid_caps_new (context, codec_id, "video/x-dnxhd", NULL);
    break;

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

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

866 867 868 869
    case CODEC_ID_TRUESPEECH:
    caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-truespeech", NULL);
    break;

870 871 872 873 874 875
    case CODEC_ID_WS_VQA:
    case CODEC_ID_IDCIN:
    case CODEC_ID_8BPS:
    case CODEC_ID_FLIC:
    case CODEC_ID_VMDVIDEO:
    case CODEC_ID_VMDAUDIO:
876 877 878 879 880 881 882 883 884 885
    case CODEC_ID_SONIC:
    case CODEC_ID_SONIC_LS:
    case CODEC_ID_SNOW:
    case CODEC_ID_VIXL:
    case CODEC_ID_QPEG:
    case CODEC_ID_XVID:
    case CODEC_ID_PGM:
    case CODEC_ID_PGMYUV:
    case CODEC_ID_PAM:
    case CODEC_ID_FFVHUFF:
886 887 888 889 890 891
    case CODEC_ID_LOCO:
    case CODEC_ID_WNV1:
    case CODEC_ID_AASC:
    case CODEC_ID_MP3ADU:
    case CODEC_ID_MP3ON4:
    case CODEC_ID_WESTWOOD_SND1:
892 893 894 895
    case CODEC_ID_CSCD:
    case CODEC_ID_MMVIDEO:
    case CODEC_ID_ZMBV:
    case CODEC_ID_AVS:
896
    case CODEC_ID_CAVS:
897 898 899
      buildcaps = TRUE;
      break;

Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
900
      /* weird quasi-codecs for the demuxers only */
901 902 903 904 905 906
    case CODEC_ID_PCM_S16LE:
    case CODEC_ID_PCM_S16BE:
    case CODEC_ID_PCM_U16LE:
    case CODEC_ID_PCM_U16BE:
    case CODEC_ID_PCM_S8:
    case CODEC_ID_PCM_U8:
907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950
    {
      gint width = 0, depth = 0, endianness = 0;
      gboolean signedness = FALSE;      /* blabla */

      switch (codec_id) {
        case CODEC_ID_PCM_S16LE:
          width = 16;
          depth = 16;
          endianness = G_LITTLE_ENDIAN;
          signedness = TRUE;
          break;
        case CODEC_ID_PCM_S16BE:
          width = 16;
          depth = 16;
          endianness = G_BIG_ENDIAN;
          signedness = TRUE;
          break;
        case CODEC_ID_PCM_U16LE:
          width = 16;
          depth = 16;
          endianness = G_LITTLE_ENDIAN;
          signedness = FALSE;
          break;
        case CODEC_ID_PCM_U16BE:
          width = 16;
          depth = 16;
          endianness = G_BIG_ENDIAN;
          signedness = FALSE;
          break;
        case CODEC_ID_PCM_S8:
          width = 8;
          depth = 8;
          endianness = G_BYTE_ORDER;
          signedness = TRUE;
          break;
        case CODEC_ID_PCM_U8:
          width = 8;
          depth = 8;
          endianness = G_BYTE_ORDER;
          signedness = FALSE;
          break;
        default:
          g_assert (0);         /* don't worry, we never get here */
          break;
951
      }
952 953 954 955 956 957 958

      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-raw-int",
          "width", G_TYPE_INT, width,
          "depth", G_TYPE_INT, depth,
          "endianness", G_TYPE_INT, endianness,
          "signed", G_TYPE_BOOLEAN, signedness, NULL);
    }
959 960
      break;

961
    case CODEC_ID_PCM_MULAW:
962
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-mulaw", NULL);
963 964 965
      break;

    case CODEC_ID_PCM_ALAW:
966
      caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-alaw", NULL);
967 968
      break;

969 970
    case CODEC_ID_ADPCM_IMA_QT:
    case CODEC_ID_ADPCM_IMA_WAV:
971 972 973 974
    case CODEC_ID_ADPCM_IMA_DK3:
    case CODEC_ID_ADPCM_IMA_DK4:
    case CODEC_ID_ADPCM_IMA_WS:
    case CODEC_ID_ADPCM_IMA_SMJPEG:
975
    case CODEC_ID_ADPCM_IMA_AMV:
976
    case CODEC_ID_ADPCM_MS:
977
    case CODEC_ID_ADPCM_4XM:
Ronald S. Bultje's avatar