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 82 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 41 42 43 44 45 46 47 48 49
/*
 * Read a palette from a caps.
 */

static void
gst_ffmpeg_get_palette (const GstCaps *caps, AVCodecContext *context)
{
  GstStructure *str = gst_caps_get_structure (caps, 0);
  const GValue *palette_v;
  const GstBuffer *palette;

  /* do we have a palette? */
  if ((palette_v = gst_structure_get_value (str,
          "palette_data")) && context) {
50
    palette = gst_value_get_buffer (palette_v);
51
    if (GST_BUFFER_SIZE (palette) >= AVPALETTE_SIZE) {
52 53 54 55 56 57 58 59 60 61 62 63 64 65
      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
gst_ffmpeg_set_palette (GstCaps *caps, AVCodecContext *context)
{
  if (context->palctrl) {
66
    GstBuffer *palette = gst_buffer_new_and_alloc (AVPALETTE_SIZE);
67 68 69 70 71 72 73 74

    memcpy (GST_BUFFER_DATA (palette), context->palctrl->palette,
        AVPALETTE_SIZE);
    gst_caps_set_simple (caps,
        "palette_data", GST_TYPE_BUFFER, palette, NULL);
  }
}

75 76 77 78
/* 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.
79 80 81
 *
 * We should actually do this stuff at the end, like in riff-media.c,
 * but I'm too lazy today. Maybe later.
82 83
 */

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
84 85 86 87 88 89 90 91 92 93 94 95
#define GST_FF_VID_CAPS_NEW(mimetype, ...)                      \
    (context != NULL) ?                                         \
    gst_caps_new_simple (mimetype,                              \
        "width",     G_TYPE_INT,   context->width,              \
        "height",    G_TYPE_INT,   context->height,             \
        "framerate", GST_TYPE_FRACTION, context->time_base.den, \
        context->time_base.num, __VA_ARGS__, NULL)                                      \
    :                                                           \
    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,             \
96
        G_MAXINT, 1, __VA_ARGS__, NULL)
97 98 99 100

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

Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
101 102 103 104 105 106 107 108 109 110 111
#define GST_FF_AUD_CAPS_NEW(mimetype, ...)                      \
    (context != NULL) ?                                         \
    gst_caps_new_simple (mimetype,                              \
        "rate", G_TYPE_INT, context->sample_rate,               \
        "channels", G_TYPE_INT, context->channels,              \
        __VA_ARGS__, NULL)                                      \
    :                                                           \
    gst_caps_new_simple (mimetype,                              \
        "rate", GST_TYPE_INT_RANGE, 8000, 96000,                \
        "channels", GST_TYPE_INT_RANGE, 1, 2,                   \
        __VA_ARGS__, NULL)
112 113 114 115 116 117

/* 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!
118 119 120 121 122 123 124 125 126
 *
 * 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.
127 128
 */

129
GstCaps *
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
130 131
gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
    AVCodecContext * context, gboolean encode)
132
{
133
  GstCaps *caps = NULL;
134
  gboolean buildcaps = FALSE;
135

136
  switch (codec_id) {
137
    case CODEC_ID_MPEG1VIDEO:
138 139 140 141
      /* For decoding, CODEC_ID_MPEG2VIDEO is preferred... So omit here */
      if (encode) {
        /* FIXME: bitrate */
        caps = GST_FF_VID_CAPS_NEW ("video/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
142 143
            "mpegversion", G_TYPE_INT, 1,
            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
144 145 146 147 148 149 150
      }
      break;

    case CODEC_ID_MPEG2VIDEO:
      if (encode) {
        /* FIXME: bitrate */
        caps = GST_FF_VID_CAPS_NEW ("video/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
151 152
            "mpegversion", G_TYPE_INT, 2,
            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
153 154 155 156
      } 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
157 158
            "mpegversion", GST_TYPE_INT_RANGE, 1, 2,
            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
159
      }
160
      break;
161 162 163 164 165

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

Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
166
      /* I don't know the exact differences between those... Anyone? */
167
    case CODEC_ID_H263:
168
    case CODEC_ID_H263P:
169
      caps = GST_FF_VID_CAPS_NEW ("video/x-h263", NULL);
170
      break;
171

172 173 174 175
    case CODEC_ID_H263I:
      caps = GST_FF_VID_CAPS_NEW ("video/x-intel-h263", NULL);
      break;

176 177 178 179
    case CODEC_ID_H261:
      caps = GST_FF_VID_CAPS_NEW ("video/x-h261", NULL);
      break;

180
    case CODEC_ID_RV10:
181
    case CODEC_ID_RV20:
182
    case CODEC_ID_RV40:
183
      {
184 185 186 187 188 189 190 191 192 193 194 195 196
        gint version;

        switch (codec_id) {
          case CODEC_ID_RV40:
            version = 4;
            break;
          case CODEC_ID_RV20:
            version = 2;
            break;
          default:
            version = 1;
            break;
        }
197 198 199

        /* FIXME: context->sub_id must be filled in during decoding */
        caps = GST_FF_VID_CAPS_NEW ("video/x-pn-realvideo",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
200 201
            "systemstream", G_TYPE_BOOLEAN, FALSE,
            "rmversion", G_TYPE_INT, version, NULL);
202 203 204 205
        if (context) {
          gst_caps_set_simple (caps,
              "rmsubid", GST_TYPE_FOURCC, context->sub_id, NULL);
        }
206
      }
207
      break;
208

209
    case CODEC_ID_MP2:
210 211 212 213
      /* we use CODEC_ID_MP3 for decoding */
      if (encode) {
        /* FIXME: bitrate */
        caps = GST_FF_AUD_CAPS_NEW ("audio/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
214
            "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 2, NULL);
215
      }
216
      break;
217

218 219 220 221
    case CODEC_ID_MP3:
      if (encode) {
        /* FIXME: bitrate */
        caps = GST_FF_AUD_CAPS_NEW ("audio/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
222
            "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 3, NULL);
223 224 225 226
      } 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
227 228
            "mpegversion", G_TYPE_INT, 1,
            "layer", GST_TYPE_INT_RANGE, 1, 3, NULL);
229
      }
230
      break;
231

David Schleef's avatar
David Schleef committed
232
    case CODEC_ID_VORBIS:
233 234 235 236 237 238 239
      /* This one is disabled for several reasons:
       * - GStreamer already has perfect Ogg and Vorbis support
       * - The ffmpeg implementation depends on libvorbis/libogg,
       *   which are not included in the ffmpeg that GStreamer ships.
       * - The ffmpeg implementation depends on shared objects between
       *   the ogg demuxer and vorbis decoder, which GStreamer doesn't.
       */
240
      break;
241

242
    case CODEC_ID_AC3:
243 244 245 246 247 248
      /* Decoding is disabled, because:
       * - it depends on liba52, which we don't ship in ffmpeg.
       * - we already have a liba52 plugin ourselves.
       */
      if (encode) {
        /* FIXME: bitrate */
249
        caps = GST_FF_AUD_CAPS_NEW ("audio/x-ac3", NULL);
250
      }
251
      break;
252 253 254
    case CODEC_ID_DTS:
      caps = GST_FF_AUD_CAPS_NEW ("audio/x-dts", NULL);
      break;
255

Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
256 257 258 259 260
      /* 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...)? */
261
    case CODEC_ID_MJPEG:
262
    case CODEC_ID_LJPEG:
263
      caps = GST_FF_VID_CAPS_NEW ("image/jpeg", NULL);
Wim Taymans's avatar
Wim Taymans committed
264
      break;
265

266 267 268 269
    case CODEC_ID_SP5X:
      caps = GST_FF_VID_CAPS_NEW ("video/sp5x", NULL);
      break;

270 271 272 273
    case CODEC_ID_MJPEGB:
      caps = GST_FF_VID_CAPS_NEW ("video/x-mjpeg-b", NULL);
      break;

274
    case CODEC_ID_MPEG4:
275
      if (encode && context != NULL) {
276 277
        /* I'm not exactly sure what ffmpeg outputs... ffmpeg itself uses
         * the AVI fourcc 'DIVX', but 'mp4v' for Quicktime... */
278
        switch (context->codec_tag) {
279 280
          case GST_MAKE_FOURCC ('D', 'I', 'V', 'X'):
            caps = GST_FF_VID_CAPS_NEW ("video/x-divx",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
281
                "divxversion", G_TYPE_INT, 5, NULL);
282 283 284 285 286 287 288 289 290
            break;
          case GST_MAKE_FOURCC ('m', 'p', '4', 'v'):
          default:
            /* FIXME: bitrate */
            caps = GST_FF_VID_CAPS_NEW ("video/mpeg",
                "systemstream", G_TYPE_BOOLEAN, FALSE,
                "mpegversion", G_TYPE_INT, 4, NULL);
            break;
        }
291 292 293
      } else {
        /* The trick here is to separate xvid, divx, mpeg4, 3ivx et al */
        caps = GST_FF_VID_CAPS_NEW ("video/mpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
294 295
            "mpegversion", G_TYPE_INT, 4,
            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
296 297 298 299 300 301 302 303 304
        if (encode) {
          gst_caps_append (caps, GST_FF_VID_CAPS_NEW ("video/x-divx",
              "divxversion", G_TYPE_INT, 5, NULL));
        } else {
          gst_caps_append (caps, GST_FF_VID_CAPS_NEW ("video/x-divx",
              "divxversion", GST_TYPE_INT_RANGE, 4, 5, NULL));
          gst_caps_append (caps, GST_FF_VID_CAPS_NEW ("video/x-xvid", NULL));
          gst_caps_append (caps, GST_FF_VID_CAPS_NEW ("video/x-3ivx", NULL));
        }
305
      }
306
      break;
307

308
    case CODEC_ID_RAWVIDEO:
309
      caps = gst_ffmpeg_codectype_to_caps (CODEC_TYPE_VIDEO, context);
310
      break;
311

312
    case CODEC_ID_MSMPEG4V1:
313 314
    case CODEC_ID_MSMPEG4V2:
    case CODEC_ID_MSMPEG4V3:
315
      {
316 317 318 319
        gint version = 41 + codec_id - CODEC_ID_MSMPEG4V1;

        /* encode-FIXME: bitrate */
        caps = GST_FF_VID_CAPS_NEW ("video/x-msmpeg",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
320
            "msmpegversion", G_TYPE_INT, version, NULL);
321 322
        if (!encode && codec_id == CODEC_ID_MSMPEG4V3) {
          gst_caps_append (caps, GST_FF_VID_CAPS_NEW ("video/x-divx",
323
              "divxversion", G_TYPE_INT, 3, NULL));
324
        }
325
      }
326
      break;
327

328
    case CODEC_ID_WMV1:
329
    case CODEC_ID_WMV2:
330
      {
331 332
        gint version = (codec_id == CODEC_ID_WMV1) ? 1 : 2;

333
        caps = GST_FF_VID_CAPS_NEW ("video/x-wmv",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
334
            "wmvversion", G_TYPE_INT, version, NULL);
335
      }
336
      break;
337

338
    case CODEC_ID_FLV1:
339 340
      caps = GST_FF_VID_CAPS_NEW ("video/x-flash-video",
				  "flvversion", G_TYPE_INT, 1, NULL);
341
      break;
342

343
    case CODEC_ID_SVQ1:
David Schleef's avatar
David Schleef committed
344
      caps = GST_FF_VID_CAPS_NEW ("video/x-svq",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
345
          "svqversion", G_TYPE_INT, 1, NULL);
346
      break;
347 348

    case CODEC_ID_SVQ3:
David Schleef's avatar
David Schleef committed
349
      caps = GST_FF_VID_CAPS_NEW ("video/x-svq",
350
          "svqversion", G_TYPE_INT, 3, NULL);
351
      break;
352

353
    case CODEC_ID_DVAUDIO:
354
      caps = GST_FF_AUD_CAPS_NEW ("audio/x-dv", NULL);
355
      break;
356

357
    case CODEC_ID_DVVIDEO:
358 359 360
      caps = GST_FF_VID_CAPS_NEW ("video/x-dv",
          "systemstream", G_TYPE_BOOLEAN, FALSE,
          NULL);
361
      break;
362

363 364
    case CODEC_ID_WMAV1:
    case CODEC_ID_WMAV2:
365
      {
366 367
        gint version = (codec_id == CODEC_ID_WMAV1) ? 1 : 2;

368
        if (context) {
369 370 371 372
          caps = GST_FF_AUD_CAPS_NEW ("audio/x-wma",
             "wmaversion", G_TYPE_INT, version,
             "block_align", G_TYPE_INT, context->block_align,
             "bitrate", G_TYPE_INT, context->bit_rate, NULL);
373
        } else {
374 375 376 377 378
          caps = GST_FF_AUD_CAPS_NEW ("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);
        }
379
      }
380
      break;
381

382 383
    case CODEC_ID_MACE3:
    case CODEC_ID_MACE6:
384
      {
385 386 387
        gint version = (codec_id == CODEC_ID_MACE3) ? 3 : 6;

        caps = GST_FF_AUD_CAPS_NEW ("audio/x-mace",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
388
            "maceversion", G_TYPE_INT, version, NULL);
389
      }
390
      break;
391

Wim Taymans's avatar
Wim Taymans committed
392
    case CODEC_ID_HUFFYUV:
393
      caps = GST_FF_VID_CAPS_NEW ("video/x-huffyuv", NULL);
394 395 396 397
      if (context) {
        gst_caps_set_simple (caps,
            "bpp", G_TYPE_INT, context->bits_per_sample, NULL);
      }
398 399 400
      break;

    case CODEC_ID_CYUV:
401
      caps = GST_FF_VID_CAPS_NEW ("video/x-compressed-yuv", NULL);
402 403 404
      break;

    case CODEC_ID_H264:
405
      caps = GST_FF_VID_CAPS_NEW ("video/x-h264", NULL);
406 407 408
      break;

    case CODEC_ID_INDEO3:
David Schleef's avatar
David Schleef committed
409
      caps = GST_FF_VID_CAPS_NEW ("video/x-indeo",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
410
          "indeoversion", G_TYPE_INT, 3, NULL);
411 412
      break;

413 414 415 416 417
    case CODEC_ID_INDEO2:
      caps = GST_FF_VID_CAPS_NEW ("video/x-indeo",
          "indeoversion", G_TYPE_INT, 2, NULL);
      break;

418
    case CODEC_ID_VP3:
419
      caps = GST_FF_VID_CAPS_NEW ("video/x-vp3", NULL);
420 421
      break;

422
    case CODEC_ID_THEORA:
423
      caps = GST_FF_VID_CAPS_NEW ("video/x-theora", NULL);
424 425
      break;

426
    case CODEC_ID_AAC:
427
    case CODEC_ID_MPEG4AAC:
428 429
      caps = GST_FF_AUD_CAPS_NEW ("audio/mpeg",
          "mpegversion", G_TYPE_INT, 4, NULL);
430 431 432
      break;

    case CODEC_ID_ASV1:
433 434 435
      caps = GST_FF_VID_CAPS_NEW ("video/x-asus",
				  "asusversion", G_TYPE_INT, 1, NULL);
      break;
436
    case CODEC_ID_ASV2:
437 438
      caps = GST_FF_VID_CAPS_NEW ("video/x-asus",
				  "asusversion", G_TYPE_INT, 2, NULL);
439 440
      break;

441
    case CODEC_ID_FFV1:
David Schleef's avatar
David Schleef committed
442
      caps = GST_FF_VID_CAPS_NEW ("video/x-ffv",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
443
          "ffvversion", G_TYPE_INT, 1, NULL);
444 445 446
      break;

    case CODEC_ID_4XM:
447
      caps = GST_FF_VID_CAPS_NEW ("video/x-4xm", NULL);
448 449
      break;

450 451 452 453 454 455
    case CODEC_ID_XAN_WC3:
    case CODEC_ID_XAN_WC4:
      caps = GST_FF_VID_CAPS_NEW ("video/x-xan",
          "wcversion", G_TYPE_INT, 3 - CODEC_ID_XAN_WC3 + codec_id, NULL);
      break;

456
    case CODEC_ID_CLJR:
457 458 459 460
      caps = GST_FF_VID_CAPS_NEW ("video/x-cirrus-logic-accupak", NULL);
      break;

    case CODEC_ID_FRAPS:
461 462 463 464 465 466
    case CODEC_ID_MDEC:
    case CODEC_ID_ROQ:
    case CODEC_ID_INTERPLAY_VIDEO:
      buildcaps = TRUE;
      break;

467 468 469 470 471
    case CODEC_ID_VCR1:
      caps = GST_FF_VID_CAPS_NEW ("video/x-ati-vcr", 
				  "vcrversion", G_TYPE_INT, 1, NULL);
      break;

472 473 474 475
    case CODEC_ID_RPZA:
      caps = GST_FF_VID_CAPS_NEW ("video/x-apple-video", NULL);
      break;

476
    case CODEC_ID_CINEPAK:
477
      caps = GST_FF_VID_CAPS_NEW ("video/x-cinepak", NULL);
478 479
      break;

480 481 482 483
    /* WS_VQA belogns here (order) */

    case CODEC_ID_MSRLE:
      caps = GST_FF_VID_CAPS_NEW ("video/x-rle",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
484
          "layout", G_TYPE_STRING, "microsoft", NULL);
485 486
      if (context) {
        gst_caps_set_simple (caps,
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
487
            "depth", G_TYPE_INT, (gint) context->bits_per_sample, NULL);
488 489 490 491 492
      } else {
        gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 1, 64, NULL);
      }
      break;

493 494 495 496 497 498 499 500 501 502 503
    case CODEC_ID_QTRLE:
      caps = GST_FF_VID_CAPS_NEW ("video/x-rle",
          "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;

504 505
    case CODEC_ID_MSVIDEO1:
      caps = GST_FF_VID_CAPS_NEW ("video/x-msvideocodec",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
506
          "msvideoversion", G_TYPE_INT, 1, NULL);
507 508
      break;

509 510 511 512 513
    case CODEC_ID_WMV3:
    case CODEC_ID_VC9:
      caps = GST_FF_VID_CAPS_NEW ("video/x-wmv",
          "wmvversion", G_TYPE_INT, 3, NULL);
      break;
514 515 516
    case CODEC_ID_QDM2:
      caps = GST_FF_AUD_CAPS_NEW ("audio/x-qdm2", NULL);
      break;  
517

518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547
    case CODEC_ID_MSZH:
      caps = GST_FF_VID_CAPS_NEW ("video/x-mszh", NULL);
      break;

    case CODEC_ID_ZLIB:
      caps = GST_FF_VID_CAPS_NEW ("video/x-zlib", NULL);
      break;

    case CODEC_ID_TRUEMOTION1:
      caps = GST_FF_VID_CAPS_NEW ("video/x-truemotion",
				  "trueversion", G_TYPE_INT, 1, NULL);
      break;
    case CODEC_ID_TRUEMOTION2:
      caps = GST_FF_VID_CAPS_NEW ("video/x-truemotion",
				  "trueversion", G_TYPE_INT, 2, NULL);
      break;

    case CODEC_ID_ULTI:
      caps = GST_FF_VID_CAPS_NEW ("video/x-ultimotion",
				  NULL);
      break;

    case CODEC_ID_TSCC:
      caps = GST_FF_VID_CAPS_NEW ("video/x-camtasia", NULL);
      break;

    case CODEC_ID_PNG:
      caps = GST_FF_VID_CAPS_NEW ("image/png", NULL);
      break;

548 549 550 551
    case CODEC_ID_SMC:
      caps = GST_FF_VID_CAPS_NEW ("video/x-smc", NULL);
      break;

552 553 554 555
    case CODEC_ID_QDRAW:
      caps = GST_FF_VID_CAPS_NEW ("video/x-qdrw", NULL);
      break;

556 557 558 559 560 561
    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:
562 563 564 565 566 567 568 569 570 571 572 573
    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_PPM:
    case CODEC_ID_PBM:
    case CODEC_ID_PGM:
    case CODEC_ID_PGMYUV:
    case CODEC_ID_PAM:
    case CODEC_ID_FFVHUFF:
574 575 576 577 578 579
    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:
580 581 582 583 584
    case CODEC_ID_CSCD:
    case CODEC_ID_MMVIDEO:
    case CODEC_ID_ZMBV:
    case CODEC_ID_AVS:
    case CODEC_ID_TRUESPEECH:
585 586 587
      buildcaps = TRUE;
      break;

Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
588
      /* weird quasi-codecs for the demuxers only */
589 590 591 592 593 594
    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:
595
      {
596
        gint width = 0, depth = 0, endianness = 0;
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
597
        gboolean signedness = FALSE;    /* blabla */
598 599 600

        switch (codec_id) {
          case CODEC_ID_PCM_S16LE:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
601 602
            width = 16;
            depth = 16;
603 604 605 606
            endianness = G_LITTLE_ENDIAN;
            signedness = TRUE;
            break;
          case CODEC_ID_PCM_S16BE:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
607 608
            width = 16;
            depth = 16;
609 610 611 612
            endianness = G_BIG_ENDIAN;
            signedness = TRUE;
            break;
          case CODEC_ID_PCM_U16LE:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
613 614
            width = 16;
            depth = 16;
615 616 617 618
            endianness = G_LITTLE_ENDIAN;
            signedness = FALSE;
            break;
          case CODEC_ID_PCM_U16BE:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
619 620
            width = 16;
            depth = 16;
621 622 623 624
            endianness = G_BIG_ENDIAN;
            signedness = FALSE;
            break;
          case CODEC_ID_PCM_S8:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
625 626
            width = 8;
            depth = 8;
627 628 629 630
            endianness = G_BYTE_ORDER;
            signedness = TRUE;
            break;
          case CODEC_ID_PCM_U8:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
631 632
            width = 8;
            depth = 8;
633 634 635 636
            endianness = G_BYTE_ORDER;
            signedness = FALSE;
            break;
          default:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
637
            g_assert (0);       /* don't worry, we never get here */
638 639 640
            break;
        }

David Schleef's avatar
David Schleef committed
641
        caps = GST_FF_AUD_CAPS_NEW ("audio/x-raw-int",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
642 643 644 645
            "width", G_TYPE_INT, width,
            "depth", G_TYPE_INT, depth,
            "endianness", G_TYPE_INT, endianness,
            "signed", G_TYPE_BOOLEAN, signedness, NULL);
646
      }
647 648
      break;

649
    case CODEC_ID_PCM_MULAW:
650
      caps = GST_FF_AUD_CAPS_NEW ("audio/x-mulaw", NULL);
651 652 653
      break;

    case CODEC_ID_PCM_ALAW:
654
      caps = GST_FF_AUD_CAPS_NEW ("audio/x-alaw", NULL);
655 656
      break;

657 658
    case CODEC_ID_ADPCM_IMA_QT:
    case CODEC_ID_ADPCM_IMA_WAV:
659 660 661 662
    case CODEC_ID_ADPCM_IMA_DK3:
    case CODEC_ID_ADPCM_IMA_DK4:
    case CODEC_ID_ADPCM_IMA_WS:
    case CODEC_ID_ADPCM_IMA_SMJPEG:
663
    case CODEC_ID_ADPCM_MS:
664
    case CODEC_ID_ADPCM_4XM:
665 666 667 668
    case CODEC_ID_ADPCM_XA:
    case CODEC_ID_ADPCM_ADX:
    case CODEC_ID_ADPCM_EA:
    case CODEC_ID_ADPCM_G726:
669
    case CODEC_ID_ADPCM_CT:
670
    case CODEC_ID_ADPCM_SWF:
671
    case CODEC_ID_ADPCM_YAMAHA:
672 673 674
    case CODEC_ID_ADPCM_SBPRO_2:
    case CODEC_ID_ADPCM_SBPRO_3:
    case CODEC_ID_ADPCM_SBPRO_4:
675
      {
676 677 678 679 680 681 682
        gchar *layout = NULL;

        switch (codec_id) {
          case CODEC_ID_ADPCM_IMA_QT:
            layout = "quicktime";
            break;
          case CODEC_ID_ADPCM_IMA_WAV:
683
            layout = "dvi";
684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714
            break;
          case CODEC_ID_ADPCM_IMA_DK3:
            layout = "dk3";
            break;
          case CODEC_ID_ADPCM_IMA_DK4:
            layout = "dk4";
            break;
          case CODEC_ID_ADPCM_IMA_WS:
            layout = "westwood";
            break;
          case CODEC_ID_ADPCM_IMA_SMJPEG:
            layout = "smjpeg";
            break;
          case CODEC_ID_ADPCM_MS:
            layout = "microsoft";
            break;
          case CODEC_ID_ADPCM_4XM:
            layout = "4xm";
            break;
          case CODEC_ID_ADPCM_XA:
            layout = "xa";
            break;
          case CODEC_ID_ADPCM_ADX:
            layout = "adx";
            break;
          case CODEC_ID_ADPCM_EA:
            layout = "ea";
            break;
          case CODEC_ID_ADPCM_G726:
            layout = "g726";
            break;
715 716 717
          case CODEC_ID_ADPCM_CT:
            layout = "ct";
            break;
718 719 720
          case CODEC_ID_ADPCM_SWF:
            layout = "swf";
            break;
721 722 723
          case CODEC_ID_ADPCM_YAMAHA:
            layout = "yamaha";
            break;
724 725 726 727 728 729 730 731 732
          case CODEC_ID_ADPCM_SBPRO_2:
            layout = "sbpro2";
            break;
          case CODEC_ID_ADPCM_SBPRO_3:
            layout = "sbpro3";
            break;
          case CODEC_ID_ADPCM_SBPRO_4:
            layout = "sbpro4";
            break;
733
          default:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
734
            g_assert (0);       /* don't worry, we never get here */
735 736 737 738 739 740
            break;
        }

        /* FIXME: someone please check whether we need additional properties
         * in this caps definition. */
        caps = GST_FF_AUD_CAPS_NEW ("audio/x-adpcm",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
741
            "layout", G_TYPE_STRING, layout, NULL);
742 743 744 745
        if (context)
          gst_caps_set_simple (caps,
              "block_align", G_TYPE_INT, context->block_align,
              "bitrate", G_TYPE_INT, context->bit_rate, NULL);
746
      }
747 748 749
      break;

    case CODEC_ID_AMR_NB:
750 751 752
      caps = GST_FF_AUD_CAPS_NEW ("audio/x-amr-nb", NULL);
      break;

753
    case CODEC_ID_AMR_WB:
754
      caps = GST_FF_AUD_CAPS_NEW ("audio/x-amr-wb", NULL);
755 756
      break;

757
    case CODEC_ID_RA_144:
758
    case CODEC_ID_RA_288:
759
    case CODEC_ID_COOK:
760
      {
761
        gint version = 0;
762 763 764 765 766 767 768 769 770 771
        switch (codec_id) {
          case CODEC_ID_RA_144:
            version = 1;
            break;
          case CODEC_ID_RA_288:
            version = 2;
            break;
          case CODEC_ID_COOK:
            version = 8;
            break;
772 773
          default:
            break;
774
        }
775 776 777

        /* FIXME: properties? */
        caps = GST_FF_AUD_CAPS_NEW ("audio/x-pn-realaudio",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
778
            "raversion", G_TYPE_INT, version, NULL);
779 780 781 782 783
        if (context) {
          gst_caps_set_simple (caps,
              "leaf_size", G_TYPE_INT, context->block_align,
              "bitrate", G_TYPE_INT, context->bit_rate, NULL);
        }
784
      }
785
      break;
786

787 788 789
    case CODEC_ID_ROQ_DPCM:
    case CODEC_ID_INTERPLAY_DPCM:
    case CODEC_ID_XAN_DPCM:
790
    case CODEC_ID_SOL_DPCM:
791
      {
792 793 794 795 796 797 798 799 800 801 802 803
        gchar *layout = NULL;

        switch (codec_id) {
          case CODEC_ID_ROQ_DPCM:
            layout = "roq";
            break;
          case CODEC_ID_INTERPLAY_DPCM:
            layout = "interplay";
            break;
          case CODEC_ID_XAN_DPCM:
            layout = "xan";
            break;
804 805 806
          case CODEC_ID_SOL_DPCM:
            layout = "sol";
            break;
807
          default:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
808
            g_assert (0);       /* don't worry, we never get here */
809 810 811 812 813 814
            break;
        }

        /* FIXME: someone please check whether we need additional properties
         * in this caps definition. */
        caps = GST_FF_AUD_CAPS_NEW ("audio/x-dpcm",
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
815
            "layout", G_TYPE_STRING, layout, NULL);
816 817 818 819
        if (context)
          gst_caps_set_simple (caps,
              "block_align", G_TYPE_INT, context->block_align,
              "bitrate", G_TYPE_INT, context->bit_rate, NULL);
820
      }
821
      break;
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
822

823 824 825 826 827 828 829 830 831 832 833 834
    case CODEC_ID_SHORTEN:
      caps = gst_caps_new_simple ("audio/x-shorten", NULL);
      break;

    case CODEC_ID_ALAC:
      caps = GST_FF_AUD_CAPS_NEW ("audio/x-alac", NULL);
      if (context) {
        gst_caps_set_simple (caps,
            "samplesize", G_TYPE_INT, context->bits_per_sample, NULL);
      }
      break;

835 836 837 838 839 840
    case CODEC_ID_FLAC:
      /* Note that ffmpeg has no encoder yet, but just for safety. In the
       * encoder case, we want to add things like samplerate, channels... */
      if (!encode) {
        caps = gst_caps_new_simple ("audio/x-flac", NULL);
      }
841 842
      break;

843 844 845 846
    case CODEC_ID_DVD_SUBTITLE:
    case CODEC_ID_DVB_SUBTITLE:
      caps = NULL;
      break;
847 848 849 850 851 852 853 854 855 856
    case CODEC_ID_BMP:
      caps = gst_caps_new_simple ("image/bmp", NULL);
      break;
    case CODEC_ID_TTA:
      caps = GST_FF_AUD_CAPS_NEW ("audio/x-tta", NULL);
      if (context) {
        gst_caps_set_simple (caps,
            "samplesize", G_TYPE_INT, context->bits_per_sample, NULL);
      }
      break;
857
    default:
858
      g_warning ("Unknown codec ID %d, please add here", codec_id);
859 860 861
      break;
  }

862 863 864 865 866 867 868
  if (buildcaps) {
    AVCodec *codec;

    if ((codec = avcodec_find_decoder (codec_id)) ||
        (codec = avcodec_find_encoder (codec_id))) {
      gchar *mime = NULL;

869 870 871
      GST_WARNING ("Could not create stream format caps for %s",
		   codec->name);
      
872 873 874
      switch (codec->type) {
        case CODEC_TYPE_VIDEO:
          mime = g_strdup_printf ("video/x-gst_ff-%s", codec->name);
875
          caps = GST_FF_VID_CAPS_NEW (mime, NULL);
876 877 878 879
          g_free (mime);
          break;
        case CODEC_TYPE_AUDIO:
          mime = g_strdup_printf ("audio/x-gst_ff-%s", codec->name);
880
          caps = GST_FF_AUD_CAPS_NEW (mime, NULL);
881
          if (context)
882 883 884
            gst_caps_set_simple (caps,
                "block_align", G_TYPE_INT, context->block_align,
                "bitrate", G_TYPE_INT, context->bit_rate, NULL);
885 886 887 888 889 890 891 892
          g_free (mime);
          break;
        default:
          break;
      }
    }
  }

893
  if (caps != NULL) {
894 895 896 897

    /* set private data */
    if (context && context->extradata_size > 0) {
      GstBuffer *data = gst_buffer_new_and_alloc (context->extradata_size);
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
898

899 900 901 902 903 904 905
      memcpy (GST_BUFFER_DATA (data), context->extradata,
          context->extradata_size);
      gst_caps_set_simple (caps,
          "codec_data", GST_TYPE_BUFFER, data, NULL);
      gst_buffer_unref (data);
    }

906 907 908 909 910
    /* palette */
    if (context) {
      gst_ffmpeg_set_palette (caps, context);
    }

911
    GST_LOG ("caps for codec_id=%d: %" GST_PTR_FORMAT, codec_id, caps);
912

913
  } else {
David Schleef's avatar
David Schleef committed
914
    GST_WARNING ("No caps found for codec_id=%d", codec_id);
915 916 917 918 919 920 921 922 923 924 925 926 927
  }

  return caps;
}

/* Convert a FFMPEG Pixel Format and optional AVCodecContext
 * to a GstCaps. If the context is ommitted, no fixed values
 * for video/audio size will be included in the GstCaps
 *
 * See below for usefullness
 */

static GstCaps *
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
928
gst_ffmpeg_pixfmt_to_caps (enum PixelFormat pix_fmt, AVCodecContext * context)
929 930 931 932
{
  GstCaps *caps = NULL;

  int bpp = 0, depth = 0, endianness = 0;
933
  gulong g_mask = 0, r_mask = 0, b_mask = 0, a_mask = 0;
934
  guint32 fmt = 0;
935
  
936
  switch (pix_fmt) {
937
    case PIX_FMT_YUVJ420P:
938
    case PIX_FMT_YUV420P:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
939
      fmt = GST_MAKE_FOURCC ('I', '4', '2', '0');
940 941
      break;
    case PIX_FMT_YUV422:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
942
      fmt = GST_MAKE_FOURCC ('Y', 'U', 'Y', '2');
943 944 945 946
      break;
    case PIX_FMT_RGB24:
      bpp = depth = 24;
      endianness = G_BIG_ENDIAN;
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
947 948 949
      r_mask = 0xff0000;
      g_mask = 0x00ff00;
      b_mask = 0x0000ff;
950 951 952
      break;
    case PIX_FMT_BGR24:
      bpp = depth = 24;
953
      endianness = G_BIG_ENDIAN;
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
954 955 956
      r_mask = 0x0000ff;
      g_mask = 0x00ff00;
      b_mask = 0xff0000;
957
      break;
958
    case PIX_FMT_YUVJ422P:
959
    case PIX_FMT_YUV422P:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
960
      fmt = GST_MAKE_FOURCC ('Y', '4', '2', 'B');
961
      break;
962
    case PIX_FMT_YUVJ444P:
963
    case PIX_FMT_YUV444P:
964
      fmt = GST_MAKE_FOURCC ('Y', '4', '4', '4');
965 966
      break;
    case PIX_FMT_RGBA32:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
967
      bpp = 32;
968
      depth = 32;
969 970
      endianness = G_BIG_ENDIAN;
#if (G_BYTE_ORDER == G_BIG_ENDIAN)
971
      r_mask = 0x000000ff;
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
972
      g_mask = 0x0000ff00;
973 974
      b_mask = 0x00ff0000;
      a_mask = 0xff000000;
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
975
#else
976
      r_mask = 0xff000000;
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
977
      g_mask = 0x00ff0000;
978 979
      b_mask = 0x0000ff00;
      a_mask = 0x000000ff;
980
#endif
981 982
      break;
    case PIX_FMT_YUV410P:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
983
      fmt = GST_MAKE_FOURCC ('Y', 'U', 'V', '9');
984 985
      break;
    case PIX_FMT_YUV411P:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
986
      fmt = GST_MAKE_FOURCC ('Y', '4', '1', 'B');
987 988 989 990
      break;
    case PIX_FMT_RGB565:
      bpp = depth = 16;
      endianness = G_BYTE_ORDER;
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
991 992 993
      r_mask = 0xf800;
      g_mask = 0x07e0;
      b_mask = 0x001f;
994 995
      break;
    case PIX_FMT_RGB555:
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
996 997
      bpp = 16;
      depth = 15;
998
      endianness = G_BYTE_ORDER;
Thomas Vander Stichele's avatar
indent  
Thomas Vander Stichele committed
999 1000 1001
      r_mask = 0x7c00;
      g_mask = 0x03e0;
      b_mask = 0x001f;
1002
      break;
1003 1004 1005 1006
    case PIX_FMT_PAL8:
      bpp = depth = 8;
      endianness = G_BYTE_ORDER;
      break;
1007 1008 1009
    case PIX_FMT_GRAY8:
      bpp = depth = 8;
      caps = GST_FF_VID_CAPS_NEW ("video/x-raw-gray",
Thomas Vander Stichele's avatar
Thomas Vander Stichele committed
1010 1011
                                  "bpp", G_TYPE_INT, bpp,