gst-plugins-nuvdemux/typefind/gsttypefindfunctions.c
branchtrunk
changeset 612 81f031485b52
parent 611 aa1f309ec686
child 613 289e2d11d16c
     1.1 --- a/gst-plugins-nuvdemux/typefind/gsttypefindfunctions.c	Tue May 01 17:03:38 2007 +0100
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,2808 +0,0 @@
     1.4 -/* GStreamer
     1.5 - * Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de>
     1.6 - *
     1.7 - * gsttypefindfunctions.c: collection of various typefind functions
     1.8 - *
     1.9 - * This library is free software; you can redistribute it and/or
    1.10 - * modify it under the terms of the GNU Library General Public
    1.11 - * License as published by the Free Software Foundation; either
    1.12 - * version 2 of the License, or (at your option) any later version.
    1.13 - *
    1.14 - * This library is distributed in the hope that it will be useful,
    1.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1.17 - * Library General Public License for more details.
    1.18 - *
    1.19 - * You should have received a copy of the GNU Library General Public
    1.20 - * License along with this library; if not, write to the
    1.21 - * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    1.22 - * Boston, MA 02111-1307, USA.
    1.23 - */
    1.24 -
    1.25 -#ifdef HAVE_CONFIG_H
    1.26 -#include "config.h"
    1.27 -#endif
    1.28 -
    1.29 -#include <glib/gstrfuncs.h>
    1.30 -
    1.31 -#include <gst/gsttypefind.h>
    1.32 -#include <gst/gstelement.h>
    1.33 -#include <gst/gstversion.h>
    1.34 -#include <gst/gstinfo.h>
    1.35 -#include <gst/gstutils.h>
    1.36 -
    1.37 -#include <string.h>
    1.38 -#include <ctype.h>
    1.39 -
    1.40 -GST_DEBUG_CATEGORY_STATIC (type_find_debug);
    1.41 -#define GST_CAT_DEFAULT type_find_debug
    1.42 -
    1.43 -/*** text/plain ***/
    1.44 -static gboolean xml_check_first_element (GstTypeFind * tf,
    1.45 -    const gchar * element, guint elen, gboolean strict);
    1.46 -
    1.47 -
    1.48 -static GstStaticCaps utf8_caps = GST_STATIC_CAPS ("text/plain");
    1.49 -
    1.50 -#define UTF8_CAPS gst_static_caps_get(&utf8_caps)
    1.51 -
    1.52 -static gboolean
    1.53 -utf8_type_find_have_valid_utf8_at_offset (GstTypeFind * tf, guint64 offset,
    1.54 -    GstTypeFindProbability * prob)
    1.55 -{
    1.56 -  guint8 *data;
    1.57 -
    1.58 -  /* randomly decided values */
    1.59 -  guint min_size = 16;          /* minimum size  */
    1.60 -  guint size = 32 * 1024;       /* starting size */
    1.61 -  guint probability = 95;       /* starting probability */
    1.62 -  guint step = 10;              /* how much we reduce probability in each
    1.63 -                                 * iteration */
    1.64 -
    1.65 -  while (probability > step && size > min_size) {
    1.66 -    data = gst_type_find_peek (tf, offset, size);
    1.67 -    if (data) {
    1.68 -      gchar *end;
    1.69 -      gchar *start = (gchar *) data;
    1.70 -
    1.71 -      if (g_utf8_validate (start, size, (const gchar **) &end) || (end - start + 4 > size)) {   /* allow last char to be cut off */
    1.72 -        *prob = probability;
    1.73 -        return TRUE;
    1.74 -      }
    1.75 -      *prob = 0;
    1.76 -      return FALSE;
    1.77 -    }
    1.78 -    size /= 2;
    1.79 -    probability -= step;
    1.80 -  }
    1.81 -  *prob = 0;
    1.82 -  return FALSE;
    1.83 -}
    1.84 -
    1.85 -static void
    1.86 -utf8_type_find (GstTypeFind * tf, gpointer unused)
    1.87 -{
    1.88 -  GstTypeFindProbability start_prob, mid_prob;
    1.89 -  guint64 length;
    1.90 -
    1.91 -  /* leave xml to the xml typefinders */
    1.92 -  if (xml_check_first_element (tf, "", 0, TRUE))
    1.93 -    return;
    1.94 -
    1.95 -  /* check beginning of stream */
    1.96 -  if (!utf8_type_find_have_valid_utf8_at_offset (tf, 0, &start_prob))
    1.97 -    return;
    1.98 -
    1.99 -  GST_LOG ("start is plain text with probability of %u", start_prob);
   1.100 -
   1.101 -  /* POSSIBLE is the highest probability we ever return if we can't
   1.102 -   * probe into the middle of the file and don't know its length */
   1.103 -
   1.104 -  length = gst_type_find_get_length (tf);
   1.105 -  if (length == 0 || length == (guint64) - 1) {
   1.106 -    gst_type_find_suggest (tf, MIN (start_prob, GST_TYPE_FIND_POSSIBLE),
   1.107 -        UTF8_CAPS);
   1.108 -    return;
   1.109 -  }
   1.110 -
   1.111 -  if (length < 64 * 1024) {
   1.112 -    gst_type_find_suggest (tf, start_prob, UTF8_CAPS);
   1.113 -    return;
   1.114 -  }
   1.115 -
   1.116 -  /* check middle of stream */
   1.117 -  if (!utf8_type_find_have_valid_utf8_at_offset (tf, length / 2, &mid_prob))
   1.118 -    return;
   1.119 -
   1.120 -  GST_LOG ("middle is plain text with probability of %u", mid_prob);
   1.121 -  gst_type_find_suggest (tf, (start_prob + mid_prob) / 2, UTF8_CAPS);
   1.122 -}
   1.123 -
   1.124 -/*** text/uri-list ***/
   1.125 -
   1.126 -static GstStaticCaps uri_caps = GST_STATIC_CAPS ("text/uri-list");
   1.127 -
   1.128 -#define URI_CAPS (gst_static_caps_get(&uri_caps))
   1.129 -#define BUFFER_SIZE 16          /* If the string is < 16 bytes we're screwed */
   1.130 -#define INC_BUFFER {                                                    \
   1.131 -  pos++;                                                                \
   1.132 -  if (pos == BUFFER_SIZE) {                                             \
   1.133 -    pos = 0;                                                            \
   1.134 -    offset += BUFFER_SIZE;                                              \
   1.135 -    data = gst_type_find_peek (tf, offset, BUFFER_SIZE);                \
   1.136 -    if (data == NULL) return;                                           \
   1.137 -  } else {                                                              \
   1.138 -    data++;                                                             \
   1.139 -  }                                                                     \
   1.140 -}
   1.141 -static void
   1.142 -uri_type_find (GstTypeFind * tf, gpointer unused)
   1.143 -{
   1.144 -  guint8 *data = gst_type_find_peek (tf, 0, BUFFER_SIZE);
   1.145 -  guint pos = 0;
   1.146 -  guint offset = 0;
   1.147 -
   1.148 -  if (data) {
   1.149 -    /* Search for # comment lines */
   1.150 -    while (*data == '#') {
   1.151 -      /* Goto end of line */
   1.152 -      while (*data != '\n') {
   1.153 -        INC_BUFFER;
   1.154 -      }
   1.155 -
   1.156 -      INC_BUFFER;
   1.157 -    }
   1.158 -
   1.159 -    if (!g_ascii_isalpha (*data)) {
   1.160 -      /* Had a non alpha char - can't be uri-list */
   1.161 -      return;
   1.162 -    }
   1.163 -
   1.164 -    INC_BUFFER;
   1.165 -
   1.166 -    while (g_ascii_isalnum (*data)) {
   1.167 -      INC_BUFFER;
   1.168 -    }
   1.169 -
   1.170 -    if (*data != ':') {
   1.171 -      /* First non alpha char is not a : */
   1.172 -      return;
   1.173 -    }
   1.174 -
   1.175 -    /* Get the next 2 bytes as well */
   1.176 -    data = gst_type_find_peek (tf, offset + pos, 3);
   1.177 -    if (data == NULL)
   1.178 -      return;
   1.179 -
   1.180 -    if (data[1] != '/' && data[2] != '/') {
   1.181 -      return;
   1.182 -    }
   1.183 -
   1.184 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, URI_CAPS);
   1.185 -  }
   1.186 -}
   1.187 -
   1.188 -
   1.189 -/*** application/xml **********************************************************/
   1.190 -
   1.191 -#define XML_BUFFER_SIZE 16
   1.192 -#define XML_INC_BUFFER {                                                \
   1.193 -  pos++;                                                                \
   1.194 -  if (pos == XML_BUFFER_SIZE) {                                         \
   1.195 -    pos = 0;                                                            \
   1.196 -    offset += XML_BUFFER_SIZE;                                          \
   1.197 -    data = gst_type_find_peek (tf, offset, XML_BUFFER_SIZE);            \
   1.198 -    if (data == NULL) return FALSE;                                     \
   1.199 -  } else {                                                              \
   1.200 -    data++;                                                             \
   1.201 -  }                                                                     \
   1.202 -}
   1.203 -
   1.204 -static gboolean
   1.205 -xml_check_first_element (GstTypeFind * tf, const gchar * element, guint elen,
   1.206 -    gboolean strict)
   1.207 -{
   1.208 -  gboolean got_xmldec;
   1.209 -  guint8 *data;
   1.210 -  guint offset = 0;
   1.211 -  guint pos = 0;
   1.212 -
   1.213 -  data = gst_type_find_peek (tf, 0, XML_BUFFER_SIZE);
   1.214 -  if (!data)
   1.215 -    return FALSE;
   1.216 -
   1.217 -  /* look for the XMLDec
   1.218 -   * see XML spec 2.8, Prolog and Document Type Declaration
   1.219 -   * http://www.w3.org/TR/2004/REC-xml-20040204/#sec-prolog-dtd */
   1.220 -  got_xmldec = (memcmp (data, "<?xml", 5) == 0);
   1.221 -
   1.222 -  if (strict && !got_xmldec)
   1.223 -    return FALSE;
   1.224 -
   1.225 -  /* skip XMLDec in any case if we've got one */
   1.226 -  if (got_xmldec) {
   1.227 -    pos += 5;
   1.228 -    data += 5;
   1.229 -  }
   1.230 -
   1.231 -  /* look for the first element, it has to be the requested element. Bail
   1.232 -   * out if it is not within the first 4kB. */
   1.233 -  while (data && (offset + pos) < 4096) {
   1.234 -    while (*data != '<' && (offset + pos) < 4096) {
   1.235 -      XML_INC_BUFFER;
   1.236 -    }
   1.237 -
   1.238 -    XML_INC_BUFFER;
   1.239 -    if (!g_ascii_isalpha (*data)) {
   1.240 -      /* if not alphabetic, it's a PI or an element / attribute declaration
   1.241 -       * like <?xxx or <!xxx */
   1.242 -      XML_INC_BUFFER;
   1.243 -      continue;
   1.244 -    }
   1.245 -
   1.246 -    /* the first normal element, check if it's the one asked for */
   1.247 -    data = gst_type_find_peek (tf, offset + pos, elen + 1);
   1.248 -    return (data && element && strncmp ((char *) data, element, elen) == 0);
   1.249 -  }
   1.250 -
   1.251 -  return FALSE;
   1.252 -}
   1.253 -
   1.254 -static GstStaticCaps generic_xml_caps = GST_STATIC_CAPS ("application/xml");
   1.255 -
   1.256 -#define GENERIC_XML_CAPS (gst_static_caps_get(&generic_xml_caps))
   1.257 -static void
   1.258 -xml_type_find (GstTypeFind * tf, gpointer unused)
   1.259 -{
   1.260 -  if (xml_check_first_element (tf, "", 0, TRUE)) {
   1.261 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MINIMUM, GENERIC_XML_CAPS);
   1.262 -  }
   1.263 -}
   1.264 -
   1.265 -/*** application/smil *********************************************************/
   1.266 -
   1.267 -static GstStaticCaps smil_caps = GST_STATIC_CAPS ("application/smil");
   1.268 -
   1.269 -#define SMIL_CAPS (gst_static_caps_get(&smil_caps))
   1.270 -static void
   1.271 -smil_type_find (GstTypeFind * tf, gpointer unused)
   1.272 -{
   1.273 -  if (xml_check_first_element (tf, "smil", 4, FALSE)) {
   1.274 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, SMIL_CAPS);
   1.275 -  }
   1.276 -}
   1.277 -
   1.278 -/*** text/html ***/
   1.279 -
   1.280 -static GstStaticCaps html_caps = GST_STATIC_CAPS ("text/html");
   1.281 -
   1.282 -#define HTML_CAPS gst_static_caps_get (&html_caps)
   1.283 -
   1.284 -static void
   1.285 -html_type_find (GstTypeFind * tf, gpointer unused)
   1.286 -{
   1.287 -  gchar *d, *data;
   1.288 -
   1.289 -  data = (gchar *) gst_type_find_peek (tf, 0, 16);
   1.290 -  if (!data)
   1.291 -    return;
   1.292 -
   1.293 -  if (!g_ascii_strncasecmp (data, "<!DOCTYPE HTML", 14)) {
   1.294 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, HTML_CAPS);
   1.295 -  } else if (xml_check_first_element (tf, "html", 4, FALSE)) {
   1.296 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, HTML_CAPS);
   1.297 -  } else if ((d = memchr (data, '<', 16))) {
   1.298 -    data = (gchar *) gst_type_find_peek (tf, d - data, 6);
   1.299 -    if (data && g_ascii_strncasecmp (data, "<html>", 6) == 0) {
   1.300 -      gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, HTML_CAPS);
   1.301 -    }
   1.302 -  }
   1.303 -}
   1.304 -
   1.305 -/*** video/x-fli ***/
   1.306 -
   1.307 -static GstStaticCaps flx_caps = GST_STATIC_CAPS ("video/x-fli");
   1.308 -
   1.309 -#define FLX_CAPS gst_static_caps_get(&flx_caps)
   1.310 -static void
   1.311 -flx_type_find (GstTypeFind * tf, gpointer unused)
   1.312 -{
   1.313 -  guint8 *data = gst_type_find_peek (tf, 0, 134);
   1.314 -
   1.315 -  if (data) {
   1.316 -    /* check magic and the frame type of the first frame */
   1.317 -    if ((data[4] == 0x11 || data[4] == 0x12 ||
   1.318 -            data[4] == 0x30 || data[4] == 0x44) &&
   1.319 -        data[5] == 0xaf &&
   1.320 -        ((data[132] == 0x00 || data[132] == 0xfa) && data[133] == 0xf1)) {
   1.321 -      gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, FLX_CAPS);
   1.322 -    }
   1.323 -    return;
   1.324 -  }
   1.325 -  data = gst_type_find_peek (tf, 0, 6);
   1.326 -  if (data) {
   1.327 -    /* check magic only */
   1.328 -    if ((data[4] == 0x11 || data[4] == 0x12 ||
   1.329 -            data[4] == 0x30 || data[4] == 0x44) && data[5] == 0xaf) {
   1.330 -      gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, FLX_CAPS);
   1.331 -    }
   1.332 -    return;
   1.333 -  }
   1.334 -}
   1.335 -
   1.336 -/*** application/x-id3 ***/
   1.337 -
   1.338 -static GstStaticCaps id3_caps = GST_STATIC_CAPS ("application/x-id3");
   1.339 -
   1.340 -#define ID3_CAPS gst_static_caps_get(&id3_caps)
   1.341 -static void
   1.342 -id3v2_type_find (GstTypeFind * tf, gpointer unused)
   1.343 -{
   1.344 -  guint8 *data = gst_type_find_peek (tf, 0, 10);
   1.345 -
   1.346 -  if (data && memcmp (data, "ID3", 3) == 0 &&
   1.347 -      data[3] != 0xFF && data[4] != 0xFF &&
   1.348 -      (data[6] & 0x80) == 0 && (data[7] & 0x80) == 0 &&
   1.349 -      (data[8] & 0x80) == 0 && (data[9] & 0x80) == 0) {
   1.350 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, ID3_CAPS);
   1.351 -  }
   1.352 -}
   1.353 -
   1.354 -static void
   1.355 -id3v1_type_find (GstTypeFind * tf, gpointer unused)
   1.356 -{
   1.357 -  guint8 *data = gst_type_find_peek (tf, -128, 3);
   1.358 -
   1.359 -  if (data && memcmp (data, "TAG", 3) == 0) {
   1.360 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, ID3_CAPS);
   1.361 -  }
   1.362 -}
   1.363 -
   1.364 -/*** application/x-ape ***/
   1.365 -
   1.366 -static GstStaticCaps apetag_caps = GST_STATIC_CAPS ("application/x-apetag");
   1.367 -
   1.368 -#define APETAG_CAPS gst_static_caps_get(&apetag_caps)
   1.369 -static void
   1.370 -apetag_type_find (GstTypeFind * tf, gpointer unused)
   1.371 -{
   1.372 -  guint8 *data;
   1.373 -
   1.374 -  /* APEv1/2 at start of file */
   1.375 -  data = gst_type_find_peek (tf, 0, 8);
   1.376 -  if (data && !memcmp (data, "APETAGEX", 8)) {
   1.377 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, APETAG_CAPS);
   1.378 -    return;
   1.379 -  }
   1.380 -
   1.381 -  /* APEv1/2 at end of file */
   1.382 -  data = gst_type_find_peek (tf, -32, 8);
   1.383 -  if (data && !memcmp (data, "APETAGEX", 8)) {
   1.384 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, APETAG_CAPS);
   1.385 -    return;
   1.386 -  }
   1.387 -}
   1.388 -
   1.389 -/*** audio/x-ttafile ***/
   1.390 -
   1.391 -static GstStaticCaps tta_caps = GST_STATIC_CAPS ("audio/x-ttafile");
   1.392 -
   1.393 -#define TTA_CAPS gst_static_caps_get(&tta_caps)
   1.394 -static void
   1.395 -tta_type_find (GstTypeFind * tf, gpointer unused)
   1.396 -{
   1.397 -  guint8 *data = gst_type_find_peek (tf, 0, 3);
   1.398 -
   1.399 -  if (data) {
   1.400 -    if (memcmp (data, "TTA", 3) == 0) {
   1.401 -      gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, TTA_CAPS);
   1.402 -      return;
   1.403 -    }
   1.404 -  }
   1.405 -}
   1.406 -
   1.407 -/*** audio/mpeg version 2, 4 ***/
   1.408 -
   1.409 -static GstStaticCaps aac_caps = GST_STATIC_CAPS ("audio/mpeg, "
   1.410 -    "mpegversion = (int) { 2, 4 }, framed = (bool) false");
   1.411 -#define AAC_CAPS (gst_static_caps_get(&aac_caps))
   1.412 -#define AAC_AMOUNT (4096)
   1.413 -static void
   1.414 -aac_type_find (GstTypeFind * tf, gpointer unused)
   1.415 -{
   1.416 -  guint8 *data = gst_type_find_peek (tf, 0, AAC_AMOUNT);
   1.417 -  gint snc;
   1.418 -
   1.419 -  /* detect adts header or adif header.
   1.420 -   * The ADIF header is 4 bytes, that should be OK. The ADTS header, on
   1.421 -   * the other hand, is 14 bits only, so we require one valid frame with
   1.422 -   * again a valid syncpoint on the next one (28 bits) for certainty. We
   1.423 -   * require 4 kB, which is quite a lot, since frames are generally 200-400
   1.424 -   * bytes.
   1.425 -   */
   1.426 -  if (data) {
   1.427 -    gint n;
   1.428 -
   1.429 -    for (n = 0; n < AAC_AMOUNT - 3; n++) {
   1.430 -      snc = GST_READ_UINT16_BE (&data[n]);
   1.431 -      if ((snc & 0xfff6) == 0xfff0) {
   1.432 -        /* ADTS header - find frame length */
   1.433 -        gint len;
   1.434 -
   1.435 -        GST_DEBUG ("Found one ADTS syncpoint at offset 0x%x, tracing next...",
   1.436 -            n);
   1.437 -        if (AAC_AMOUNT - n < 5) {
   1.438 -          GST_DEBUG ("Not enough data to parse ADTS header");
   1.439 -          break;
   1.440 -        }
   1.441 -        len = ((data[n + 3] & 0x03) << 11) |
   1.442 -            (data[n + 4] << 3) | ((data[n + 5] & 0xe0) >> 5);
   1.443 -        if (n + len + 2 >= AAC_AMOUNT) {
   1.444 -          GST_DEBUG ("Next frame is not within reach");
   1.445 -          break;
   1.446 -        } else if (len == 0) {
   1.447 -          continue;
   1.448 -        }
   1.449 -
   1.450 -        snc = GST_READ_UINT16_BE (&data[n + len]);
   1.451 -        if ((snc & 0xfff6) == 0xfff0) {
   1.452 -          gint mpegversion = (data[n + 1] & 0x08) ? 2 : 4;
   1.453 -          GstCaps *caps = gst_caps_new_simple ("audio/mpeg",
   1.454 -              "framed", G_TYPE_BOOLEAN, FALSE,
   1.455 -              "mpegversion", G_TYPE_INT, mpegversion,
   1.456 -              NULL);
   1.457 -
   1.458 -          gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, caps);
   1.459 -          gst_caps_unref (caps);
   1.460 -
   1.461 -          GST_DEBUG ("Found ADTS-%d syncpoint at offset 0x%x (framelen %u)",
   1.462 -              mpegversion, n, len);
   1.463 -          break;
   1.464 -        }
   1.465 -
   1.466 -        GST_DEBUG ("No next frame found... (should be at 0x%x)", n + len);
   1.467 -      } else if (!memcmp (&data[n], "ADIF", 4)) {
   1.468 -        /* ADIF header */
   1.469 -        GstCaps *caps = gst_caps_new_simple ("audio/mpeg",
   1.470 -            "framed", G_TYPE_BOOLEAN, FALSE,
   1.471 -            "mpegversion", G_TYPE_INT, 4,
   1.472 -            NULL);
   1.473 -
   1.474 -        gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, caps);
   1.475 -        gst_caps_unref (caps);
   1.476 -      }
   1.477 -    }
   1.478 -  }
   1.479 -}
   1.480 -
   1.481 -/*** audio/mpeg version 1 ***/
   1.482 -
   1.483 -/*
   1.484 - * The chance that random data is identified as a valid mp3 header is 63 / 2^18
   1.485 - * (0.024%) per try. This makes the function for calculating false positives
   1.486 - *   1 - (1 - ((63 / 2 ^18) ^ GST_MP3_TYPEFIND_MIN_HEADERS)) ^ buffersize)
   1.487 - * This has the following probabilities of false positives:
   1.488 - * datasize               MIN_HEADERS
   1.489 - * (bytes)      1       2       3       4
   1.490 - * 4096         62.6%    0.02%   0%      0%
   1.491 - * 16384        98%      0.09%   0%      0%
   1.492 - * 1 MiB       100%      5.88%   0%      0%
   1.493 - * 1 GiB       100%    100%      1.44%   0%
   1.494 - * 1 TiB       100%    100%    100%      0.35%
   1.495 - * This means that the current choice (3 headers by most of the time 4096 byte
   1.496 - * buffers is pretty safe for now.
   1.497 - *
   1.498 - * The max. size of each frame is 1440 bytes, which means that for N frames to
   1.499 - * be detected, we need 1440 * GST_MP3_TYPEFIND_MIN_HEADERS + 3 bytes of data.
   1.500 - * Assuming we step into the stream right after the frame header, this
   1.501 - * means we need 1440 * (GST_MP3_TYPEFIND_MIN_HEADERS + 1) - 1 + 3 bytes
   1.502 - * of data (5762) to always detect any mp3.
   1.503 - */
   1.504 -
   1.505 -static const guint mp3types_bitrates[2][3][16] =
   1.506 -    { {{0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,},
   1.507 -    {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,},
   1.508 -    {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,}},
   1.509 -{{0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,},
   1.510 -    {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,},
   1.511 -    {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}},
   1.512 -};
   1.513 -
   1.514 -static const guint mp3types_freqs[3][3] = { {11025, 12000, 8000},
   1.515 -{22050, 24000, 16000},
   1.516 -{44100, 48000, 32000}
   1.517 -};
   1.518 -
   1.519 -static inline guint
   1.520 -mp3_type_frame_length_from_header (guint32 header, guint * put_layer,
   1.521 -    guint * put_channels, guint * put_bitrate, guint * put_samplerate,
   1.522 -    gboolean * may_be_free_format, gint possible_free_framelen)
   1.523 -{
   1.524 -  guint bitrate, layer, length, mode, samplerate, version, channels;
   1.525 -
   1.526 -  if ((header & 0xffe00000) != 0xffe00000)
   1.527 -    return 0;
   1.528 -
   1.529 -  /* we don't need extension, copyright, original or
   1.530 -   * emphasis for the frame length */
   1.531 -  header >>= 6;
   1.532 -
   1.533 -  /* mode */
   1.534 -  mode = header & 0x3;
   1.535 -  header >>= 3;
   1.536 -
   1.537 -  /* padding */
   1.538 -  length = header & 0x1;
   1.539 -  header >>= 1;
   1.540 -
   1.541 -  /* sampling frequency */
   1.542 -  samplerate = header & 0x3;
   1.543 -  if (samplerate == 3)
   1.544 -    return 0;
   1.545 -  header >>= 2;
   1.546 -
   1.547 -  /* bitrate index */
   1.548 -  bitrate = header & 0xF;
   1.549 -  if (bitrate == 0 && possible_free_framelen == -1) {
   1.550 -    GST_LOG ("Possibly a free format mp3 - signalling");
   1.551 -    *may_be_free_format = TRUE;
   1.552 -  }
   1.553 -  if (bitrate == 15 || (bitrate == 0 && possible_free_framelen == -1))
   1.554 -    return 0;
   1.555 -
   1.556 -  /* ignore error correction, too */
   1.557 -  header >>= 5;
   1.558 -
   1.559 -  /* layer */
   1.560 -  layer = 4 - (header & 0x3);
   1.561 -  if (layer == 4)
   1.562 -    return 0;
   1.563 -  header >>= 2;
   1.564 -
   1.565 -  /* version 0=MPEG2.5; 2=MPEG2; 3=MPEG1 */
   1.566 -  version = header & 0x3;
   1.567 -  if (version == 1)
   1.568 -    return 0;
   1.569 -
   1.570 -  /* lookup */
   1.571 -  channels = (mode == 3) ? 1 : 2;
   1.572 -  samplerate = mp3types_freqs[version > 0 ? version - 1 : 0][samplerate];
   1.573 -  if (bitrate == 0) {
   1.574 -    if (layer == 1) {
   1.575 -      length *= 4;
   1.576 -      length += possible_free_framelen;
   1.577 -      bitrate = length * samplerate / 48000;
   1.578 -    } else {
   1.579 -      length += possible_free_framelen;
   1.580 -      bitrate = length * samplerate /
   1.581 -          ((layer == 3 && version != 3) ? 72000 : 144000);
   1.582 -    }
   1.583 -  } else {
   1.584 -    /* calculating */
   1.585 -    bitrate = mp3types_bitrates[version == 3 ? 0 : 1][layer - 1][bitrate];
   1.586 -    if (layer == 1) {
   1.587 -      length = ((12000 * bitrate / samplerate) + length) * 4;
   1.588 -    } else {
   1.589 -      length += ((layer == 3
   1.590 -              && version != 3) ? 72000 : 144000) * bitrate / samplerate;
   1.591 -    }
   1.592 -  }
   1.593 -
   1.594 -  GST_LOG ("mp3typefind: calculated mp3 frame length of %u bytes", length);
   1.595 -  GST_LOG
   1.596 -      ("mp3typefind: samplerate = %u - bitrate = %u - layer = %u - version = %u"
   1.597 -      " - channels = %u", samplerate, bitrate, layer, version, channels);
   1.598 -
   1.599 -  if (put_layer)
   1.600 -    *put_layer = layer;
   1.601 -  if (put_channels)
   1.602 -    *put_channels = channels;
   1.603 -  if (put_bitrate)
   1.604 -    *put_bitrate = bitrate;
   1.605 -  if (put_samplerate)
   1.606 -    *put_samplerate = samplerate;
   1.607 -
   1.608 -  return length;
   1.609 -}
   1.610 -
   1.611 -
   1.612 -static GstStaticCaps mp3_caps = GST_STATIC_CAPS ("audio/mpeg, "
   1.613 -    "mpegversion = (int) 1, layer = (int) [ 1, 3 ]");
   1.614 -#define MP3_CAPS (gst_static_caps_get(&mp3_caps))
   1.615 -/*
   1.616 - * random values for typefinding
   1.617 - * if no more data is available, we will return a probability of
   1.618 - * (found_headers/TRY_HEADERS) * (MAXIMUM * (TRY_SYNC - bytes_skipped)
   1.619 - *        / TRY_SYNC)
   1.620 - * if found_headers >= MIN_HEADERS
   1.621 - */
   1.622 -#define GST_MP3_TYPEFIND_MIN_HEADERS (2)
   1.623 -#define GST_MP3_TYPEFIND_TRY_HEADERS (5)
   1.624 -#define GST_MP3_TYPEFIND_TRY_SYNC (GST_TYPE_FIND_MAXIMUM * 100) /* 10kB */
   1.625 -#define GST_MP3_TYPEFIND_SYNC_SIZE (2048)
   1.626 -#define GST_MP3_WRONG_HEADER (10)
   1.627 -
   1.628 -static void
   1.629 -mp3_type_find_at_offset (GstTypeFind * tf, guint64 start_off,
   1.630 -    guint * found_layer, GstTypeFindProbability * found_prob)
   1.631 -{
   1.632 -  guint8 *data = NULL;
   1.633 -  guint8 *data_end = NULL;
   1.634 -  guint size;
   1.635 -  guint64 skipped;
   1.636 -  gint last_free_offset = -1;
   1.637 -  gint last_free_framelen = -1;
   1.638 -  gboolean headerstart = TRUE;
   1.639 -
   1.640 -  *found_layer = 0;
   1.641 -  *found_prob = 0;
   1.642 -
   1.643 -  size = 0;
   1.644 -  skipped = 0;
   1.645 -  while (skipped < GST_MP3_TYPEFIND_TRY_SYNC) {
   1.646 -    if (size <= 0) {
   1.647 -      size = GST_MP3_TYPEFIND_SYNC_SIZE * 2;
   1.648 -      do {
   1.649 -        size /= 2;
   1.650 -        data = gst_type_find_peek (tf, skipped + start_off, size);
   1.651 -      } while (size > 10 && !data);
   1.652 -      if (!data)
   1.653 -        break;
   1.654 -      data_end = data + size;
   1.655 -    }
   1.656 -    if (*data == 0xFF) {
   1.657 -      guint8 *head_data = NULL;
   1.658 -      guint layer = 0, bitrate, samplerate, channels;
   1.659 -      guint found = 0;          /* number of valid headers found */
   1.660 -      guint64 offset = skipped;
   1.661 -
   1.662 -      while (found < GST_MP3_TYPEFIND_TRY_HEADERS) {
   1.663 -        guint32 head;
   1.664 -        guint length;
   1.665 -        guint prev_layer = 0, prev_bitrate = 0;
   1.666 -        guint prev_channels = 0, prev_samplerate = 0;
   1.667 -        gboolean free = FALSE;
   1.668 -
   1.669 -        if ((gint64) (offset - skipped + 4) >= 0 &&
   1.670 -            data + offset - skipped + 4 < data_end) {
   1.671 -          head_data = data + offset - skipped;
   1.672 -        } else {
   1.673 -          head_data = gst_type_find_peek (tf, offset + start_off, 4);
   1.674 -        }
   1.675 -        if (!head_data)
   1.676 -          break;
   1.677 -        head = GST_READ_UINT32_BE (head_data);
   1.678 -        if (!(length = mp3_type_frame_length_from_header (head, &layer,
   1.679 -                    &channels, &bitrate, &samplerate, &free,
   1.680 -                    last_free_framelen))) {
   1.681 -          if (free) {
   1.682 -            if (last_free_offset == -1)
   1.683 -              last_free_offset = offset;
   1.684 -            else {
   1.685 -              last_free_framelen = offset - last_free_offset;
   1.686 -              offset = last_free_offset;
   1.687 -              continue;
   1.688 -            }
   1.689 -          } else {
   1.690 -            last_free_framelen = -1;
   1.691 -          }
   1.692 -
   1.693 -          /* Mark the fact that we didn't find a valid header at the beginning */
   1.694 -          if (found == 0)
   1.695 -            headerstart = FALSE;
   1.696 -
   1.697 -          GST_LOG ("%d. header at offset %" G_GUINT64_FORMAT
   1.698 -              " (0x%" G_GINT64_MODIFIER "x) was not an mp3 header "
   1.699 -              "(possibly-free: %s)", found + 1, start_off + offset,
   1.700 -              start_off + offset, free ? "yes" : "no");
   1.701 -          break;
   1.702 -        }
   1.703 -        if ((prev_layer && prev_layer != layer) ||
   1.704 -            /* (prev_bitrate && prev_bitrate != bitrate) || <-- VBR */
   1.705 -            (prev_samplerate && prev_samplerate != samplerate) ||
   1.706 -            (prev_channels && prev_channels != channels)) {
   1.707 -          /* this means an invalid property, or a change, which might mean
   1.708 -           * that this is not a mp3 but just a random bytestream. It could
   1.709 -           * be a freaking funky encoded mp3 though. We'll just not count
   1.710 -           * this header*/
   1.711 -          prev_layer = layer;
   1.712 -          prev_bitrate = bitrate;
   1.713 -          prev_channels = channels;
   1.714 -          prev_samplerate = samplerate;
   1.715 -        } else {
   1.716 -          found++;
   1.717 -          GST_LOG ("found %d. header at offset %" G_GUINT64_FORMAT " (0x%"
   1.718 -              G_GINT64_MODIFIER "X)", found, start_off + offset,
   1.719 -              start_off + offset);
   1.720 -        }
   1.721 -        offset += length;
   1.722 -      }
   1.723 -      g_assert (found <= GST_MP3_TYPEFIND_TRY_HEADERS);
   1.724 -      if (found == GST_MP3_TYPEFIND_TRY_HEADERS ||
   1.725 -          (found >= GST_MP3_TYPEFIND_MIN_HEADERS && head_data == NULL)) {
   1.726 -        /* we can make a valid guess */
   1.727 -        guint probability = found * GST_TYPE_FIND_MAXIMUM *
   1.728 -            (GST_MP3_TYPEFIND_TRY_SYNC - skipped) /
   1.729 -            GST_MP3_TYPEFIND_TRY_HEADERS / GST_MP3_TYPEFIND_TRY_SYNC;
   1.730 -
   1.731 -        if (!headerstart
   1.732 -            && ((probability - GST_MP3_WRONG_HEADER) > GST_TYPE_FIND_MINIMUM))
   1.733 -          probability -= GST_MP3_WRONG_HEADER;
   1.734 -        if (probability < GST_TYPE_FIND_MINIMUM)
   1.735 -          probability = GST_TYPE_FIND_MINIMUM;
   1.736 -        if (start_off > 0)
   1.737 -          probability /= 2;
   1.738 -
   1.739 -        GST_INFO
   1.740 -            ("audio/mpeg calculated %u  =  %u  *  %u / %u  *  (%u - %"
   1.741 -            G_GUINT64_FORMAT ") / %u", probability, GST_TYPE_FIND_MAXIMUM,
   1.742 -            found, GST_MP3_TYPEFIND_TRY_HEADERS, GST_MP3_TYPEFIND_TRY_SYNC,
   1.743 -            (guint64) skipped, GST_MP3_TYPEFIND_TRY_SYNC);
   1.744 -        /* make sure we're not id3 tagged */
   1.745 -        head_data = gst_type_find_peek (tf, -128, 3);
   1.746 -        if (head_data && (memcmp (head_data, "TAG", 3) == 0)) {
   1.747 -          probability = 0;
   1.748 -        }
   1.749 -        g_assert (probability <= GST_TYPE_FIND_MAXIMUM);
   1.750 -
   1.751 -        *found_prob = probability;
   1.752 -        if (probability > 0)
   1.753 -          *found_layer = layer;
   1.754 -        return;
   1.755 -      }
   1.756 -    }
   1.757 -    data++;
   1.758 -    skipped++;
   1.759 -    size--;
   1.760 -  }
   1.761 -}
   1.762 -
   1.763 -static void
   1.764 -mp3_type_find (GstTypeFind * tf, gpointer unused)
   1.765 -{
   1.766 -  GstTypeFindProbability prob, mid_prob;
   1.767 -  guint8 *data;
   1.768 -  guint layer, mid_layer;
   1.769 -  guint64 length;
   1.770 -
   1.771 -  mp3_type_find_at_offset (tf, 0, &layer, &prob);
   1.772 -  length = gst_type_find_get_length (tf);
   1.773 -
   1.774 -  if (length == 0 || length == (guint64) - 1) {
   1.775 -    if (prob != 0)
   1.776 -      goto suggest;
   1.777 -    return;
   1.778 -  }
   1.779 -
   1.780 -  /* if we're pretty certain already, skip the additional check */
   1.781 -  if (prob >= GST_TYPE_FIND_LIKELY)
   1.782 -    goto suggest;
   1.783 -
   1.784 -  mp3_type_find_at_offset (tf, length / 2, &mid_layer, &mid_prob);
   1.785 -
   1.786 -  if (mid_prob > 0) {
   1.787 -    if (prob == 0) {
   1.788 -      GST_LOG ("detected audio/mpeg only in the middle (p=%u)", mid_prob);
   1.789 -      layer = mid_layer;
   1.790 -      prob = mid_prob;
   1.791 -      goto suggest;
   1.792 -    }
   1.793 -
   1.794 -    if (layer != mid_layer) {
   1.795 -      GST_WARNING ("audio/mpeg layer discrepancy: %u vs. %u", layer, mid_layer);
   1.796 -      return;                   /* FIXME: or should we just go with the one in the middle? */
   1.797 -    }
   1.798 -
   1.799 -    /* detected mpeg audio both in middle of the file and at the start */
   1.800 -    prob = (prob + mid_prob) / 2;
   1.801 -    goto suggest;
   1.802 -  }
   1.803 -
   1.804 -  /* let's see if there's a valid header right at the start */
   1.805 -  data = gst_type_find_peek (tf, 0, 4); /* use min. frame size? */
   1.806 -  if (data && mp3_type_frame_length_from_header (GST_READ_UINT32_BE (data),
   1.807 -          &layer, NULL, NULL, NULL, NULL, 0) != 0) {
   1.808 -    if (prob == 0)
   1.809 -      prob = GST_TYPE_FIND_POSSIBLE - 10;
   1.810 -    else
   1.811 -      prob = MAX (GST_TYPE_FIND_POSSIBLE - 10, prob + 10);
   1.812 -  }
   1.813 -
   1.814 -  if (prob > 0)
   1.815 -    goto suggest;
   1.816 -
   1.817 -  return;
   1.818 -
   1.819 -suggest:
   1.820 -  {
   1.821 -    GstCaps *caps;
   1.822 -
   1.823 -    g_assert (layer > 0);
   1.824 -
   1.825 -    caps = gst_caps_make_writable (MP3_CAPS);
   1.826 -    gst_structure_set (gst_caps_get_structure (caps, 0), "layer",
   1.827 -        G_TYPE_INT, layer, NULL);
   1.828 -    gst_type_find_suggest (tf, prob, caps);
   1.829 -    gst_caps_unref (caps);
   1.830 -    return;
   1.831 -  }
   1.832 -}
   1.833 -
   1.834 -/*** audio/x-musepack ***/
   1.835 -
   1.836 -static GstStaticCaps musepack_caps = GST_STATIC_CAPS ("audio/x-musepack");
   1.837 -
   1.838 -#define MUSEPACK_CAPS (gst_static_caps_get(&musepack_caps))
   1.839 -static void
   1.840 -musepack_type_find (GstTypeFind * tf, gpointer unused)
   1.841 -{
   1.842 -  guint8 *data = gst_type_find_peek (tf, 0, 4);
   1.843 -
   1.844 -  if (data && memcmp (data, "MP+", 3) == 0) {
   1.845 -    if ((data[3] & 0x7f) == 7) {
   1.846 -      gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, MUSEPACK_CAPS);
   1.847 -    } else {
   1.848 -      gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY + 10, MUSEPACK_CAPS);
   1.849 -    }
   1.850 -  }
   1.851 -}
   1.852 -
   1.853 -/*** audio/x-ac3 ***/
   1.854 -static GstStaticCaps ac3_caps = GST_STATIC_CAPS ("audio/x-ac3");
   1.855 -
   1.856 -#define AC3_CAPS (gst_static_caps_get(&ac3_caps))
   1.857 -
   1.858 -static void
   1.859 -ac3_type_find (GstTypeFind * tf, gpointer unused)
   1.860 -{
   1.861 -  guint8 *data = gst_type_find_peek (tf, 0, 2);
   1.862 -
   1.863 -  if (data) {
   1.864 -    /* pretty lame method... */
   1.865 -    if (data[0] == 0x0b && data[1] == 0x77) {
   1.866 -      gst_type_find_suggest (tf, GST_TYPE_FIND_POSSIBLE, AC3_CAPS);
   1.867 -      return;
   1.868 -    }
   1.869 -  }
   1.870 -}
   1.871 -
   1.872 -/*** wavpack ***/
   1.873 -
   1.874 -static GstStaticCaps wavpack_caps =
   1.875 -GST_STATIC_CAPS ("audio/x-wavpack, framed = (boolean) false");
   1.876 -
   1.877 -#define WAVPACK_CAPS (gst_static_caps_get(&wavpack_caps))
   1.878 -
   1.879 -static GstStaticCaps wavpack_correction_caps =
   1.880 -GST_STATIC_CAPS ("audio/x-wavpack-correction, framed = (boolean) false");
   1.881 -
   1.882 -#define WAVPACK_CORRECTION_CAPS (gst_static_caps_get(&wavpack_correction_caps))
   1.883 -
   1.884 -static void
   1.885 -wavpack_type_find (GstTypeFind * tf, gpointer unused)
   1.886 -{
   1.887 -  guint64 offset;
   1.888 -  guint32 blocksize;
   1.889 -  guint8 *data;
   1.890 -
   1.891 -  data = gst_type_find_peek (tf, 0, 32);
   1.892 -  if (!data)
   1.893 -    return;
   1.894 -
   1.895 -  if (data[0] != 'w' || data[1] != 'v' || data[2] != 'p' || data[3] != 'k')
   1.896 -    return;
   1.897 -
   1.898 -  /* Note: wavpack blocks can be fairly large (easily 60-110k), possibly
   1.899 -   * larger than the max. limits imposed by certain typefinding elements
   1.900 -   * like id3demux or apedemux, so typefinding is most likely only going to
   1.901 -   * work in pull-mode */
   1.902 -  blocksize = GST_READ_UINT32_LE (data + 4);
   1.903 -  GST_LOG ("wavpack header, blocksize=0x%04x", blocksize);
   1.904 -  offset = 32;
   1.905 -  while (offset < 32 + blocksize) {
   1.906 -    guint32 sublen;
   1.907 -
   1.908 -    /* get chunk header */
   1.909 -    GST_LOG ("peeking at chunk at offset 0x%04x", (guint) offset);
   1.910 -    data = gst_type_find_peek (tf, offset, 4);
   1.911 -    if (data == NULL)
   1.912 -      break;
   1.913 -    sublen = ((guint32) data[1]) << 1;
   1.914 -    if (data[0] & 0x80) {
   1.915 -      sublen |= (((guint32) data[2]) << 9) | (((guint32) data[3]) << 17);
   1.916 -      sublen += 1 + 3;          /* id + length */
   1.917 -    } else {
   1.918 -      sublen += 1 + 1;          /* id + length */
   1.919 -    }
   1.920 -    if (sublen > blocksize - offset + 32) {
   1.921 -      GST_LOG ("chunk length too big (%u > %" G_GUINT64_FORMAT ")", sublen,
   1.922 -          blocksize - offset);
   1.923 -      break;
   1.924 -    }
   1.925 -    if ((data[0] & 0x20) == 0) {
   1.926 -      switch (data[0] & 0x0f) {
   1.927 -        case 0xa:              /* ID_WV_BITSTREAM  */
   1.928 -        case 0xc:              /* ID_WVX_BITSTREAM */
   1.929 -          gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, WAVPACK_CAPS);
   1.930 -          return;
   1.931 -        case 0xb:              /* ID_WVC_BITSTREAM */
   1.932 -          gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY,
   1.933 -              WAVPACK_CORRECTION_CAPS);
   1.934 -          return;
   1.935 -        default:
   1.936 -          break;
   1.937 -      }
   1.938 -    }
   1.939 -    offset += sublen;
   1.940 -  }
   1.941 -}
   1.942 -
   1.943 -/*** multipart/x-mixed-replace mimestream ***/
   1.944 -
   1.945 -static GstStaticCaps multipart_caps =
   1.946 -GST_STATIC_CAPS ("multipart/x-mixed-replace");
   1.947 -#define MULTIPART_CAPS gst_static_caps_get(&multipart_caps)
   1.948 -
   1.949 -/* multipart/x-mixed replace is: 
   1.950 - *   <maybe some whitespace>--<some ascii chars>[\r]\n
   1.951 - *   <more ascii chars>[\r]\nContent-type:<more ascii>[\r]\n */
   1.952 -static void
   1.953 -multipart_type_find (GstTypeFind * tf, gpointer unused)
   1.954 -{
   1.955 -  guint8 *data;
   1.956 -  guint8 *x;
   1.957 -
   1.958 -#define MULTIPART_MAX_BOUNDARY_OFFSET 16
   1.959 -  data = gst_type_find_peek (tf, 0, MULTIPART_MAX_BOUNDARY_OFFSET);
   1.960 -  if (!data)
   1.961 -    return;
   1.962 -
   1.963 -  for (x = data;
   1.964 -      x - data < MULTIPART_MAX_BOUNDARY_OFFSET - 2 && g_ascii_isspace (*x);
   1.965 -      x++);
   1.966 -  if (x[0] != '-' || x[1] != '-')
   1.967 -    return;
   1.968 -
   1.969 -  /* Could be okay, peek what should be enough for a complete header */
   1.970 -#define MULTIPART_MAX_HEADER_SIZE 256
   1.971 -  data = gst_type_find_peek (tf, 0, MULTIPART_MAX_HEADER_SIZE);
   1.972 -  if (!data)
   1.973 -    return;
   1.974 -
   1.975 -  for (x = data; x - data < MULTIPART_MAX_HEADER_SIZE - 14; x++) {
   1.976 -    if (!isascii (*x)) {
   1.977 -      return;
   1.978 -    }
   1.979 -    if (*x == '\n' &&
   1.980 -        !g_ascii_strncasecmp ("content-type:", (gchar *) x + 1, 13)) {
   1.981 -      GstCaps *caps = gst_caps_copy (MULTIPART_CAPS);
   1.982 -
   1.983 -      gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, caps);
   1.984 -      gst_caps_unref (caps);
   1.985 -      return;
   1.986 -    }
   1.987 -  }
   1.988 -}
   1.989 -
   1.990 -/*** video/mpeg systemstream ***/
   1.991 -static GstStaticCaps mpeg_sys_caps = GST_STATIC_CAPS ("video/mpeg, "
   1.992 -    "systemstream = (boolean) true, mpegversion = (int) [ 1, 2 ]");
   1.993 -
   1.994 -#define MPEG_SYS_CAPS gst_static_caps_get(&mpeg_sys_caps)
   1.995 -#define IS_MPEG_HEADER(data)            ((((guint8 *)(data))[0] == 0x00) &&  \
   1.996 -                                         (((guint8 *)(data))[1] == 0x00) &&  \
   1.997 -                                         (((guint8 *)(data))[2] == 0x01))
   1.998 -
   1.999 -#define IS_MPEG_PACK_HEADER(data)       (IS_MPEG_HEADER (data) &&            \
  1.1000 -                                         (((guint8 *)(data))[3] == 0xBA))
  1.1001 -
  1.1002 -#define IS_MPEG_SYSTEM_HEADER(data)     (IS_MPEG_HEADER (data) &&            \
  1.1003 -                                         (((guint8 *)(data))[3] == 0xBB))
  1.1004 -#define IS_MPEG_PACKET_HEADER(data)     (IS_MPEG_HEADER (data) &&            \
  1.1005 -                                         ((((guint8 *)(data))[3] & 0x80) == 0x80))
  1.1006 -
  1.1007 -#define IS_MPEG_PES_HEADER(data)        (IS_MPEG_HEADER (data) &&            \
  1.1008 -                                         ((((guint8 *)(data))[3] == 0xE0) || \
  1.1009 -                                          (((guint8 *)(data))[3] == 0xC0) || \
  1.1010 -                                          (((guint8 *)(data))[3] == 0xBD)))
  1.1011 -
  1.1012 -static void
  1.1013 -mpeg2_sys_type_find (GstTypeFind * tf, gpointer unused)
  1.1014 -{
  1.1015 -  guint8 *data = gst_type_find_peek (tf, 0, 5);
  1.1016 -  gint mpegversion;
  1.1017 -
  1.1018 -  if (data && IS_MPEG_PACK_HEADER (data)) {
  1.1019 -    if ((data[4] & 0xC0) == 0x40) {
  1.1020 -      /* type 2 */
  1.1021 -      mpegversion = 2;
  1.1022 -      goto suggest;
  1.1023 -    } else if ((data[4] & 0xF0) == 0x20) {
  1.1024 -      mpegversion = 1;
  1.1025 -      goto suggest;
  1.1026 -    }
  1.1027 -  } else if (data && IS_MPEG_PES_HEADER (data)) {
  1.1028 -    /* PES stream */
  1.1029 -    mpegversion = 2;
  1.1030 -    goto suggest;
  1.1031 -  }
  1.1032 -
  1.1033 -  return;
  1.1034 -suggest:
  1.1035 -  {
  1.1036 -    GstCaps *caps = gst_caps_copy (MPEG_SYS_CAPS);
  1.1037 -
  1.1038 -    gst_structure_set (gst_caps_get_structure (caps, 0), "mpegversion",
  1.1039 -        G_TYPE_INT, mpegversion, NULL);
  1.1040 -    gst_type_find_suggest (tf, GST_TYPE_FIND_POSSIBLE, caps);
  1.1041 -    gst_caps_unref (caps);
  1.1042 -  }
  1.1043 -};
  1.1044 -
  1.1045 -/* ATTENTION: ugly return value:
  1.1046 - * 0 -  invalid data
  1.1047 - * 1 - not enough data
  1.1048 - * anything else - size until next package
  1.1049 - */
  1.1050 -static guint
  1.1051 -mpeg1_parse_header (GstTypeFind * tf, guint64 offset)
  1.1052 -{
  1.1053 -  guint8 *data = gst_type_find_peek (tf, offset, 4);
  1.1054 -  guint size;
  1.1055 -
  1.1056 -  if (!data) {
  1.1057 -    GST_LOG ("couldn't get MPEG header bytes");
  1.1058 -    return 1;
  1.1059 -  }
  1.1060 -
  1.1061 -  if (data[0] != 0 || data[1] != 0 || data[2] != 1) {
  1.1062 -    GST_LOG ("no sync");
  1.1063 -    return 0;
  1.1064 -  }
  1.1065 -  offset += 4;
  1.1066 -
  1.1067 -  GST_LOG ("sync %02x", data[3]);
  1.1068 -
  1.1069 -  switch (data[3]) {
  1.1070 -    case 0xBA:                 /* pack header */
  1.1071 -      data = gst_type_find_peek (tf, offset, 8);
  1.1072 -      if (!data) {
  1.1073 -        GST_LOG ("couldn't get MPEG pack header bytes");
  1.1074 -        return 1;
  1.1075 -      }
  1.1076 -      size = 12;
  1.1077 -      /* check marker bits */
  1.1078 -      if ((data[0] & 0xF1) != 0x21 ||
  1.1079 -          (data[2] & 0x01) != 0x01 ||
  1.1080 -          (data[4] & 0x01) != 0x01 ||
  1.1081 -          (data[5] & 0x80) != 0x80 || (data[7] & 0x01) != 0x01) {
  1.1082 -        GST_LOG ("wrong marker bits");
  1.1083 -        return 0;
  1.1084 -      }
  1.1085 -      break;
  1.1086 -
  1.1087 -    case 0xB9:                 /* ISO end code */
  1.1088 -      size = 4;
  1.1089 -      break;
  1.1090 -
  1.1091 -    case 0xBB:                 /* system header */
  1.1092 -      data = gst_type_find_peek (tf, offset, 2);
  1.1093 -      if (!data) {
  1.1094 -        GST_LOG ("couldn't get MPEG pack header bytes");
  1.1095 -        return 1;
  1.1096 -      }
  1.1097 -      size = GST_READ_UINT16_BE (data) + 6;
  1.1098 -      offset += 2;
  1.1099 -      data = gst_type_find_peek (tf, offset, size - 6);
  1.1100 -      if (!data) {
  1.1101 -        GST_LOG ("couldn't get MPEG pack header bytes");
  1.1102 -        return 1;
  1.1103 -      }
  1.1104 -      /* check marker bits */
  1.1105 -      if ((data[0] & 0x80) != 0x80 ||
  1.1106 -          (data[2] & 0x01) != 0x01 || (data[4] & 0x20) != 0x20) {
  1.1107 -        GST_LOG ("wrong marker bits");
  1.1108 -        return 0;
  1.1109 -      }
  1.1110 -      /* check stream marker bits */
  1.1111 -      for (offset = 6; offset < (size - 6); offset += 3) {
  1.1112 -        if (data[offset] <= 0xBB || (data[offset + 1] & 0xC0) != 0xC0) {
  1.1113 -          GST_LOG ("wrong marker bits");
  1.1114 -          return 0;
  1.1115 -        }
  1.1116 -      }
  1.1117 -      break;
  1.1118 -
  1.1119 -    default:
  1.1120 -      if (data[3] < 0xB9)
  1.1121 -        return 0;
  1.1122 -      data = gst_type_find_peek (tf, offset, 2);
  1.1123 -      if (!data) {
  1.1124 -        GST_LOG ("couldn't get MPEG pack header bytes");
  1.1125 -        return 1;
  1.1126 -      }
  1.1127 -      size = GST_READ_UINT16_BE (data) + 6;
  1.1128 -      /* FIXME: we could check PTS/DTS marker bits here... (bit overkill) */
  1.1129 -      break;
  1.1130 -  }
  1.1131 -
  1.1132 -  return size;
  1.1133 -}
  1.1134 -
  1.1135 -/* calculation of possibility to identify random data as mpeg systemstream:
  1.1136 - * bits that must match in header detection:            32 (or more)
  1.1137 - * chance that random data is identifed:                1/2^32
  1.1138 - * chance that GST_MPEG_TYPEFIND_TRY_HEADERS headers are identified:
  1.1139 - *                                      1/2^(32*GST_MPEG_TYPEFIND_TRY_HEADERS)
  1.1140 - * chance that this happens in GST_MPEG_TYPEFIND_TRY_SYNC bytes:
  1.1141 - *                                      1-(1+1/2^(32*GST_MPEG_TYPEFIND_TRY_HEADERS)^GST_MPEG_TYPEFIND_TRY_SYNC)
  1.1142 - * for current values:
  1.1143 - *                                      1-(1+1/2^(32*4)^101024)
  1.1144 - *                                    = <some_number>
  1.1145 - */
  1.1146 -#define GST_MPEG_TYPEFIND_TRY_HEADERS 4
  1.1147 -#define GST_MPEG_TYPEFIND_TRY_SYNC (100 * 1024) /* 100kB */
  1.1148 -#define GST_MPEG_TYPEFIND_SYNC_SIZE 2048
  1.1149 -static void
  1.1150 -mpeg1_sys_type_find (GstTypeFind * tf, gpointer unused)
  1.1151 -{
  1.1152 -  guint8 *data = NULL;
  1.1153 -  guint size = 0;
  1.1154 -  guint64 skipped = 0;
  1.1155 -  GstCaps *caps;
  1.1156 -
  1.1157 -  while (skipped < GST_MPEG_TYPEFIND_TRY_SYNC) {
  1.1158 -    if (size < 4) {
  1.1159 -      data = gst_type_find_peek (tf, skipped, GST_MPEG_TYPEFIND_SYNC_SIZE);
  1.1160 -      if (!data)
  1.1161 -        break;
  1.1162 -      size = GST_MPEG_TYPEFIND_SYNC_SIZE;
  1.1163 -    }
  1.1164 -    if (IS_MPEG_PACK_HEADER (data)) {
  1.1165 -      /* found packet start code */
  1.1166 -      guint found = 0;
  1.1167 -      guint packet_size = 0;
  1.1168 -      guint64 offset = skipped;
  1.1169 -
  1.1170 -      while (found < GST_MPEG_TYPEFIND_TRY_HEADERS) {
  1.1171 -        packet_size = mpeg1_parse_header (tf, offset);
  1.1172 -        if (packet_size <= 1)
  1.1173 -          break;
  1.1174 -        offset += packet_size;
  1.1175 -        found++;
  1.1176 -      }
  1.1177 -      g_assert (found <= GST_MPEG_TYPEFIND_TRY_HEADERS);
  1.1178 -      if (found == GST_MPEG_TYPEFIND_TRY_HEADERS || packet_size == 1) {
  1.1179 -        GST_LOG ("suggesting mpeg1 system steeam");
  1.1180 -        caps = gst_caps_copy (MPEG_SYS_CAPS);
  1.1181 -        gst_structure_set (gst_caps_get_structure (caps, 0), "mpegversion",
  1.1182 -            G_TYPE_INT, 1, NULL);
  1.1183 -        gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM - 1, caps);
  1.1184 -        gst_caps_unref (caps);
  1.1185 -        return;
  1.1186 -      }
  1.1187 -    }
  1.1188 -    data++;
  1.1189 -    skipped++;
  1.1190 -    size--;
  1.1191 -  }
  1.1192 -}
  1.1193 -
  1.1194 -/** video/mpegts Transport Stream **/
  1.1195 -static GstStaticCaps mpegts_caps = GST_STATIC_CAPS ("video/mpegts, "
  1.1196 -    "systemstream = (boolean) true, packetsize = (int) [ 188, 208 ]");
  1.1197 -#define MPEGTS_CAPS gst_static_caps_get(&mpegts_caps)
  1.1198 -
  1.1199 -#define GST_MPEGTS_TYPEFIND_MIN_HEADERS 4
  1.1200 -#define GST_MPEGTS_TYPEFIND_MAX_HEADERS 10
  1.1201 -#define GST_MPEGTS_MAX_PACKET_SIZE 204
  1.1202 -#define GST_MPEGTS_TYPEFIND_SYNC_SIZE \
  1.1203 -            (GST_MPEGTS_TYPEFIND_MIN_HEADERS * GST_MPEGTS_MAX_PACKET_SIZE)
  1.1204 -#define GST_MPEGTS_TYPEFIND_MAX_SYNC \
  1.1205 -            (GST_MPEGTS_TYPEFIND_MAX_HEADERS * GST_MPEGTS_MAX_PACKET_SIZE)
  1.1206 -
  1.1207 -#define MPEGTS_HDR_SIZE 4
  1.1208 -#define IS_MPEGTS_HEADER(data) (((data)[0] == 0x47) && \
  1.1209 -                                (((data)[1] & 0x80) == 0x00) && \
  1.1210 -                                (((data)[3] & 0x10) == 0x10))
  1.1211 -
  1.1212 -/* Helper function to search ahead at intervals of packet_size for mpegts
  1.1213 - * headers */
  1.1214 -gint
  1.1215 -mpeg_ts_probe_headers (GstTypeFind * tf, guint64 offset, gint packet_size)
  1.1216 -{
  1.1217 -  /* We always enter this function having found at least one header already */
  1.1218 -  gint found = 1;
  1.1219 -  guint8 *data = NULL;
  1.1220 -
  1.1221 -  while (found < GST_MPEGTS_TYPEFIND_MAX_HEADERS) {
  1.1222 -    offset += packet_size;
  1.1223 -
  1.1224 -    data = gst_type_find_peek (tf, offset, MPEGTS_HDR_SIZE);
  1.1225 -    if (data == NULL || !IS_MPEGTS_HEADER (data))
  1.1226 -      return found;
  1.1227 -
  1.1228 -    found++;
  1.1229 -  }
  1.1230 -
  1.1231 -  return found;
  1.1232 -}
  1.1233 -
  1.1234 -/* Try and detect at least 4 packets in at most 10 packets worth of
  1.1235 - * data. Need to try several possible packet sizes */
  1.1236 -static void
  1.1237 -mpeg_ts_type_find (GstTypeFind * tf, gpointer unused)
  1.1238 -{
  1.1239 -  /* TS packet sizes to test: normal, DVHS packet size and 
  1.1240 -   * FEC with 16 or 20 byte codes packet size. */
  1.1241 -  const gint pack_sizes[] = { 188, 192, 204, 208 };
  1.1242 -  const gint n_pack_sizes = sizeof (pack_sizes) / sizeof (gint);
  1.1243 -
  1.1244 -  guint8 *data = NULL;
  1.1245 -  guint size = 0;
  1.1246 -  guint64 skipped = 0;
  1.1247 -
  1.1248 -  while (skipped < GST_MPEGTS_TYPEFIND_MAX_SYNC) {
  1.1249 -    if (size < MPEGTS_HDR_SIZE) {
  1.1250 -      data = gst_type_find_peek (tf, skipped, GST_MPEGTS_TYPEFIND_SYNC_SIZE);
  1.1251 -      if (!data)
  1.1252 -        break;
  1.1253 -      size = GST_MPEGTS_TYPEFIND_SYNC_SIZE;
  1.1254 -    }
  1.1255 -
  1.1256 -    /* Have at least MPEGTS_HDR_SIZE bytes at this point */
  1.1257 -    if (IS_MPEGTS_HEADER (data)) {
  1.1258 -      gint p;
  1.1259 -
  1.1260 -      for (p = 0; p < n_pack_sizes; p++) {
  1.1261 -        gint found;
  1.1262 -
  1.1263 -        /* Probe ahead at size pack_sizes[p] */
  1.1264 -        found = mpeg_ts_probe_headers (tf, skipped, pack_sizes[p]);
  1.1265 -        if (found >= GST_MPEGTS_TYPEFIND_MIN_HEADERS) {
  1.1266 -          gint probability;
  1.1267 -          GstCaps *caps = gst_caps_copy (MPEGTS_CAPS);
  1.1268 -
  1.1269 -          gst_structure_set (gst_caps_get_structure (caps, 0), "packetsize",
  1.1270 -              G_TYPE_INT, pack_sizes[p], NULL);
  1.1271 -
  1.1272 -          /* found at least 4 headers. 10 headers = MAXIMUM probability. 
  1.1273 -           * Arbitrarily, I assigned 10% probability for each header we
  1.1274 -           * found, 40% -> 100% */
  1.1275 -
  1.1276 -          probability = 10 * MIN (found, 10);
  1.1277 -
  1.1278 -          gst_type_find_suggest (tf, probability, caps);
  1.1279 -          gst_caps_unref (caps);
  1.1280 -          return;
  1.1281 -        }
  1.1282 -      }
  1.1283 -    }
  1.1284 -    data++;
  1.1285 -    skipped++;
  1.1286 -    size--;
  1.1287 -  }
  1.1288 -}
  1.1289 -
  1.1290 -/*** video/mpeg MPEG-4 elementary video stream ***/
  1.1291 -
  1.1292 -static GstStaticCaps mpeg4_video_caps = GST_STATIC_CAPS ("video/mpeg, "
  1.1293 -    "systemstream = (boolean) false, mpegversion = 4");
  1.1294 -#define MPEG4_VIDEO_CAPS gst_static_caps_get(&mpeg4_video_caps)
  1.1295 -static void
  1.1296 -mpeg4_video_type_find (GstTypeFind * tf, gpointer unused)
  1.1297 -{
  1.1298 -  /* Header consists of: a series of start codes (00 00 01 xx), some with 
  1.1299 -   * associated data.
  1.1300 -   * Optionally, we start with a visual_object_sequence_start_code, followed by
  1.1301 -   * (optionally) visual_object_start_code), then the mandatory 
  1.1302 -   * video_object_start_code and video_object_layer_start_code)
  1.1303 -   */
  1.1304 -  guint8 *data = NULL;
  1.1305 -  int offset = 0;
  1.1306 -  gboolean seen_vos = FALSE;
  1.1307 -
  1.1308 -  while (TRUE) {
  1.1309 -    data = gst_type_find_peek (tf, offset, 4);
  1.1310 -    if (data && data[0] == 0 && data[1] == 0 && data[2] == 1) {
  1.1311 -      int sc = data[3];
  1.1312 -
  1.1313 -      if (sc == 0xB0)           /* visual_object_sequence_start_code */
  1.1314 -        offset += 5;
  1.1315 -      else if (sc == 0xB5)      /* visual_object_start_code */
  1.1316 -        offset += 5;
  1.1317 -      else if (sc >= 0x00 && sc <= 0x1F) {      /* video_object_start_code */
  1.1318 -        offset += 4;
  1.1319 -        seen_vos = TRUE;
  1.1320 -      } else if (sc >= 0x20 && sc <= 0x2F) {    /* video_object_layer_start_code */
  1.1321 -        if (seen_vos) {
  1.1322 -          GstCaps *caps = gst_caps_copy (MPEG4_VIDEO_CAPS);
  1.1323 -
  1.1324 -          gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM - 1, caps);
  1.1325 -          gst_caps_unref (caps);
  1.1326 -          return;
  1.1327 -        }
  1.1328 -      } else
  1.1329 -        return;
  1.1330 -    } else
  1.1331 -      return;
  1.1332 -  }
  1.1333 -}
  1.1334 -
  1.1335 -/*** video/mpeg video stream ***/
  1.1336 -
  1.1337 -static GstStaticCaps mpeg_video_caps = GST_STATIC_CAPS ("video/mpeg, "
  1.1338 -    "systemstream = (boolean) false");
  1.1339 -#define MPEG_VIDEO_CAPS gst_static_caps_get(&mpeg_video_caps)
  1.1340 -static void
  1.1341 -mpeg_video_type_find (GstTypeFind * tf, gpointer unused)
  1.1342 -{
  1.1343 -  static const guint8 sequence_header[] = { 0x00, 0x00, 0x01, 0xb3 };
  1.1344 -  guint8 *data = NULL;
  1.1345 -
  1.1346 -  data = gst_type_find_peek (tf, 0, 8);
  1.1347 -
  1.1348 -  if (data && memcmp (data, sequence_header, 4) == 0) {
  1.1349 -    GstCaps *caps = gst_caps_copy (MPEG_VIDEO_CAPS);
  1.1350 -
  1.1351 -    gst_structure_set (gst_caps_get_structure (caps, 0), "mpegversion",
  1.1352 -        G_TYPE_INT, 1, NULL);
  1.1353 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM - 1, caps);
  1.1354 -    gst_caps_unref (caps);
  1.1355 -  }
  1.1356 -}
  1.1357 -
  1.1358 -/*
  1.1359 - * Idea is the same as MPEG system stream typefinding: We check each
  1.1360 - * byte of the stream to see if - from that point on - the stream
  1.1361 - * matches a predefined set of marker bits as defined in the MPEG
  1.1362 - * video specs.
  1.1363 - *
  1.1364 - * I'm sure someone will do a chance calculation here too.
  1.1365 - */
  1.1366 -
  1.1367 -#define GST_MPEGVID_TYPEFIND_TRY_PICTURES 6
  1.1368 -#define GST_MPEGVID_TYPEFIND_TRY_SYNC (100 * 1024)      /* 100 kB */
  1.1369 -#define GST_MPEGVID_TYPEFIND_SYNC_SIZE 2048
  1.1370 -
  1.1371 -static void
  1.1372 -mpeg_video_stream_type_find (GstTypeFind * tf, gpointer unused)
  1.1373 -{
  1.1374 -  gint size = 0, found = 0;
  1.1375 -  guint64 skipped = 0;
  1.1376 -  guint8 *data = NULL;
  1.1377 -
  1.1378 -  while (1) {
  1.1379 -    if (found >= GST_MPEGVID_TYPEFIND_TRY_PICTURES) {
  1.1380 -      GstCaps *caps = gst_caps_copy (MPEG_VIDEO_CAPS);
  1.1381 -
  1.1382 -      gst_structure_set (gst_caps_get_structure (caps, 0), "mpegversion",
  1.1383 -          G_TYPE_INT, 1, NULL);
  1.1384 -      gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM - 2, caps);
  1.1385 -      gst_caps_unref (caps);
  1.1386 -      return;
  1.1387 -    }
  1.1388 -
  1.1389 -    if (skipped > GST_MPEGVID_TYPEFIND_TRY_SYNC)
  1.1390 -      break;
  1.1391 -
  1.1392 -    if (size < 5) {
  1.1393 -      data = gst_type_find_peek (tf, skipped, GST_MPEGVID_TYPEFIND_SYNC_SIZE);
  1.1394 -      if (!data)
  1.1395 -        break;
  1.1396 -      size = GST_MPEGVID_TYPEFIND_SYNC_SIZE;
  1.1397 -    }
  1.1398 -
  1.1399 -    /* are we a sequence (0xB3) or GOP (0xB8) header? */
  1.1400 -    if (data[0] == 0x0 && data[1] == 0x0 && data[2] == 0x1 &&
  1.1401 -        (data[3] == 0xB3 || data[3] == 0xB8)) {
  1.1402 -      size -= 8;
  1.1403 -      data += 8;
  1.1404 -      skipped += 8;
  1.1405 -      if (data[3] == 0xB3)
  1.1406 -        continue;
  1.1407 -      else if (size < 4) {
  1.1408 -        data = gst_type_find_peek (tf, skipped, GST_MPEGVID_TYPEFIND_SYNC_SIZE);
  1.1409 -        size = GST_MPEGVID_TYPEFIND_SYNC_SIZE;
  1.1410 -        if (!data)
  1.1411 -          break;
  1.1412 -      }
  1.1413 -      /* else, we should now see an image */
  1.1414 -    }
  1.1415 -
  1.1416 -    /* image header (and, when found, slice header) */
  1.1417 -    if (data[0] == 0x0 && data[1] == 0x0 && data[2] == 0x1 && data[4] == 0x0) {
  1.1418 -      size -= 8;
  1.1419 -      data += 8;
  1.1420 -      skipped += 8;
  1.1421 -      if (size < 5) {
  1.1422 -        data = gst_type_find_peek (tf, skipped, GST_MPEGVID_TYPEFIND_SYNC_SIZE);
  1.1423 -        size = GST_MPEGVID_TYPEFIND_SYNC_SIZE;
  1.1424 -        if (!data)
  1.1425 -          break;
  1.1426 -      }
  1.1427 -      if ((data[0] == 0x0 && data[1] == 0x0 &&
  1.1428 -              data[2] == 0x1 && data[3] == 0x1) ||
  1.1429 -          (data[1] == 0x0 && data[2] == 0x0 &&
  1.1430 -              data[3] == 0x1 && data[4] == 0x1)) {
  1.1431 -        size -= 4;
  1.1432 -        data += 4;
  1.1433 -        skipped += 4;
  1.1434 -        found += 1;
  1.1435 -        continue;
  1.1436 -      }
  1.1437 -    }
  1.1438 -
  1.1439 -    size--;
  1.1440 -    data++;
  1.1441 -    skipped++;
  1.1442 -  }
  1.1443 -}
  1.1444 -
  1.1445 -/*** audio/x-aiff ***/
  1.1446 -
  1.1447 -static GstStaticCaps aiff_caps = GST_STATIC_CAPS ("audio/x-aiff");
  1.1448 -
  1.1449 -#define AIFF_CAPS gst_static_caps_get(&aiff_caps)
  1.1450 -static void
  1.1451 -aiff_type_find (GstTypeFind * tf, gpointer unused)
  1.1452 -{
  1.1453 -  guint8 *data = gst_type_find_peek (tf, 0, 4);
  1.1454 -
  1.1455 -  if (data && memcmp (data, "FORM", 4) == 0) {
  1.1456 -    data += 8;
  1.1457 -    if (memcmp (data, "AIFF", 4) == 0 || memcmp (data, "AIFC", 4) == 0)
  1.1458 -      gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, AIFF_CAPS);
  1.1459 -  }
  1.1460 -}
  1.1461 -
  1.1462 -/*** audio/x-aiff ***/
  1.1463 -
  1.1464 -static GstStaticCaps svx_caps = GST_STATIC_CAPS ("audio/x-svx");
  1.1465 -
  1.1466 -#define SVX_CAPS gst_static_caps_get(&svx_caps)
  1.1467 -static void
  1.1468 -svx_type_find (GstTypeFind * tf, gpointer unused)
  1.1469 -{
  1.1470 -  guint8 *data = gst_type_find_peek (tf, 0, 4);
  1.1471 -
  1.1472 -  if (data && memcmp (data, "FORM", 4) == 0) {
  1.1473 -    data += 8;
  1.1474 -    if (memcmp (data, "8SVX", 4) == 0 || memcmp (data, "16SV", 4) == 0)
  1.1475 -      gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, SVX_CAPS);
  1.1476 -  }
  1.1477 -}
  1.1478 -
  1.1479 -/*** audio/x-shorten ***/
  1.1480 -
  1.1481 -static GstStaticCaps shn_caps = GST_STATIC_CAPS ("audio/x-shorten");
  1.1482 -
  1.1483 -#define SHN_CAPS gst_static_caps_get(&shn_caps)
  1.1484 -static void
  1.1485 -shn_type_find (GstTypeFind * tf, gpointer unused)
  1.1486 -{
  1.1487 -  guint8 *data = gst_type_find_peek (tf, 0, 4);
  1.1488 -
  1.1489 -  if (data && memcmp (data, "ajkg", 4) == 0) {
  1.1490 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, SHN_CAPS);
  1.1491 -  }
  1.1492 -  data = gst_type_find_peek (tf, -8, 8);
  1.1493 -  if (data && memcmp (data, "SHNAMPSK", 8) == 0) {
  1.1494 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, SHN_CAPS);
  1.1495 -  }
  1.1496 -}
  1.1497 -
  1.1498 -/*** application/x-ape ***/
  1.1499 -
  1.1500 -static GstStaticCaps ape_caps = GST_STATIC_CAPS ("application/x-ape");
  1.1501 -
  1.1502 -#define APE_CAPS gst_static_caps_get(&ape_caps)
  1.1503 -static void
  1.1504 -ape_type_find (GstTypeFind * tf, gpointer unused)
  1.1505 -{
  1.1506 -  guint8 *data = gst_type_find_peek (tf, 0, 4);
  1.1507 -
  1.1508 -  if (data && memcmp (data, "MAC ", 4) == 0) {
  1.1509 -    gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY + 10, APE_CAPS);
  1.1510 -  }
  1.1511 -}
  1.1512 -
  1.1513 -/*** ISO FORMATS ***/
  1.1514 -
  1.1515 -/*** audio/x-m4a ***/
  1.1516 -
  1.1517 -static GstStaticCaps m4a_caps = GST_STATIC_CAPS ("audio/x-m4a");
  1.1518 -
  1.1519 -#define M4A_CAPS (gst_static_caps_get(&m4a_caps))
  1.1520 -static void
  1.1521 -m4a_type_find (GstTypeFind * tf, gpointer unused)
  1.1522 -{
  1.1523 -  guint8 *data = gst_type_find_peek (tf, 4, 8);
  1.1524 -
  1.1525 -  if (data &&
  1.1526 -      (memcmp (data, "ftypM4A ", 8) == 0 ||
  1.1527 -          memcmp (data, "ftypmp42", 8) == 0)) {
  1.1528 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, M4A_CAPS);
  1.1529 -  }
  1.1530 -}
  1.1531 -
  1.1532 -/*** application/x-3gp ***/
  1.1533 -
  1.1534 -/* The Q is there because variables can't start with a number. */
  1.1535 -
  1.1536 -
  1.1537 -static GstStaticCaps q3gp_caps = GST_STATIC_CAPS ("application/x-3gp");
  1.1538 -
  1.1539 -#define Q3GP_CAPS (gst_static_caps_get(&q3gp_caps))
  1.1540 -static void
  1.1541 -q3gp_type_find (GstTypeFind * tf, gpointer unused)
  1.1542 -{
  1.1543 -
  1.1544 -  guint32 ftyp_size = 0;
  1.1545 -  gint offset = 0;
  1.1546 -  guint8 *data = NULL;
  1.1547 -
  1.1548 -  if ((data = gst_type_find_peek (tf, 0, 12)) == NULL) {
  1.1549 -    return;
  1.1550 -  }
  1.1551 -
  1.1552 -  data += 4;
  1.1553 -  if (memcmp (data, "ftyp", 4) != 0) {
  1.1554 -    return;
  1.1555 -  }
  1.1556 -
  1.1557 -  /* check major brand */
  1.1558 -  data += 4;
  1.1559 -  if (memcmp (data, "3gp", 3) == 0 ||
  1.1560 -      memcmp (data, "3gr", 3) == 0 ||
  1.1561 -      memcmp (data, "3gs", 3) == 0 || memcmp (data, "3gg", 3) == 0) {
  1.1562 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, Q3GP_CAPS);
  1.1563 -    return;
  1.1564 -  }
  1.1565 -
  1.1566 -  /* check compatible brands */
  1.1567 -  if ((data = gst_type_find_peek (tf, 0, 4)) != NULL) {
  1.1568 -    ftyp_size = GST_READ_UINT32_BE (data);
  1.1569 -  }
  1.1570 -  for (offset = 16; offset < ftyp_size; offset += 4) {
  1.1571 -    if ((data = gst_type_find_peek (tf, offset, 3)) == NULL) {
  1.1572 -      break;
  1.1573 -    }
  1.1574 -    if (memcmp (data, "3gp", 3) == 0 ||
  1.1575 -        memcmp (data, "3gr", 3) == 0 ||
  1.1576 -        memcmp (data, "3gs", 3) == 0 || memcmp (data, "3gg", 3) == 0) {
  1.1577 -      gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, Q3GP_CAPS);
  1.1578 -      break;
  1.1579 -    }
  1.1580 -  }
  1.1581 -
  1.1582 -  return;
  1.1583 -
  1.1584 -}
  1.1585 -
  1.1586 -/*** video/quicktime ***/
  1.1587 -
  1.1588 -static GstStaticCaps qt_caps = GST_STATIC_CAPS ("video/quicktime");
  1.1589 -
  1.1590 -#define QT_CAPS gst_static_caps_get(&qt_caps)
  1.1591 -#define STRNCMP(x,y,z) (strncmp ((char*)(x), (char*)(y), z))
  1.1592 -
  1.1593 -static void
  1.1594 -qt_type_find (GstTypeFind * tf, gpointer unused)
  1.1595 -{
  1.1596 -  guint8 *data;
  1.1597 -  guint tip = 0;
  1.1598 -  guint64 offset = 0;
  1.1599 -  guint64 size;
  1.1600 -
  1.1601 -  while ((data = gst_type_find_peek (tf, offset, 8)) != NULL) {
  1.1602 -    /* box/atom types that are in common with ISO base media file format */
  1.1603 -    if (STRNCMP (&data[4], "moov", 4) == 0 ||
  1.1604 -        STRNCMP (&data[4], "mdat", 4) == 0 ||
  1.1605 -        STRNCMP (&data[4], "ftyp", 4) == 0 ||
  1.1606 -        STRNCMP (&data[4], "free", 4) == 0 ||
  1.1607 -        STRNCMP (&data[4], "uuid", 4) == 0 ||
  1.1608 -        STRNCMP (&data[4], "skip", 4) == 0) {
  1.1609 -      if (tip == 0) {
  1.1610 -        tip = GST_TYPE_FIND_LIKELY;
  1.1611 -      } else {
  1.1612 -        tip = GST_TYPE_FIND_NEARLY_CERTAIN;
  1.1613 -      }
  1.1614 -    }
  1.1615 -    /* other box/atom types, apparently quicktime specific */
  1.1616 -    else if (STRNCMP (&data[4], "pnot", 4) == 0 ||
  1.1617 -        STRNCMP (&data[4], "PICT", 4) == 0 ||
  1.1618 -        STRNCMP (&data[4], "wide", 4) == 0 ||
  1.1619 -        STRNCMP (&data[4], "prfl", 4) == 0) {
  1.1620 -      tip = GST_TYPE_FIND_MAXIMUM;
  1.1621 -      break;
  1.1622 -    } else {
  1.1623 -      tip = 0;
  1.1624 -      break;
  1.1625 -    }
  1.1626 -    size = GST_READ_UINT32_BE (data);
  1.1627 -    if (size == 1) {
  1.1628 -      guint8 *sizedata;
  1.1629 -
  1.1630 -      sizedata = gst_type_find_peek (tf, offset + 8, 8);
  1.1631 -      if (sizedata == NULL)
  1.1632 -        break;
  1.1633 -
  1.1634 -      size = GST_READ_UINT64_BE (sizedata);
  1.1635 -    } else {
  1.1636 -      if (size < 8)
  1.1637 -        break;
  1.1638 -    }
  1.1639 -    offset += size;
  1.1640 -  }
  1.1641 -  if (tip > 0) {
  1.1642 -    gst_type_find_suggest (tf, tip, QT_CAPS);
  1.1643 -  }
  1.1644 -};
  1.1645 -
  1.1646 -
  1.1647 -/*** image/x-quicktime ***/
  1.1648 -
  1.1649 -static GstStaticCaps qtif_caps = GST_STATIC_CAPS ("image/x-quicktime");
  1.1650 -
  1.1651 -#define QTIF_CAPS gst_static_caps_get(&qtif_caps)
  1.1652 -
  1.1653 -/* how many atoms we check before we give up */
  1.1654 -#define QTIF_MAXROUNDS 25
  1.1655 -
  1.1656 -static void
  1.1657 -qtif_type_find (GstTypeFind * tf, gpointer unused)
  1.1658 -{
  1.1659 -  const guint8 *data;
  1.1660 -  gboolean found_idsc = FALSE;
  1.1661 -  gboolean found_idat = FALSE;
  1.1662 -  guint64 offset = 0;
  1.1663 -  guint rounds = 0;
  1.1664 -
  1.1665 -  while ((data = gst_type_find_peek (tf, offset, 8)) != NULL) {
  1.1666 -    guint64 size;
  1.1667 -
  1.1668 -    size = GST_READ_UINT32_BE (data);
  1.1669 -    if (size == 1) {
  1.1670 -      const guint8 *sizedata;
  1.1671 -
  1.1672 -      sizedata = gst_type_find_peek (tf, offset + 8, 8);
  1.1673 -      if (sizedata == NULL)
  1.1674 -        break;
  1.1675 -
  1.1676 -      size = GST_READ_UINT64_BE (sizedata);
  1.1677 -    }
  1.1678 -    if (size < 8)
  1.1679 -      break;
  1.1680 -
  1.1681 -    if (STRNCMP (data + 4, "idsc", 4) == 0)
  1.1682 -      found_idsc = TRUE;
  1.1683 -    if (STRNCMP (data + 4, "idat", 4) == 0)
  1.1684 -      found_idat = TRUE;
  1.1685 -
  1.1686 -    if (found_idsc && found_idat) {
  1.1687 -      gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, QTIF_CAPS);
  1.1688 -      return;
  1.1689 -    }
  1.1690 -
  1.1691 -    offset += size;
  1.1692 -    if (++rounds > QTIF_MAXROUNDS)
  1.1693 -      break;
  1.1694 -  }
  1.1695 -
  1.1696 -  if (found_idsc || found_idat) {
  1.1697 -    gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, QTIF_CAPS);
  1.1698 -    return;
  1.1699 -  }
  1.1700 -};
  1.1701 -
  1.1702 -/*** audio/x-mod ***/
  1.1703 -
  1.1704 -static GstStaticCaps mod_caps = GST_STATIC_CAPS ("audio/x-mod");
  1.1705 -
  1.1706 -#define MOD_CAPS gst_static_caps_get(&mod_caps)
  1.1707 -/* FIXME: M15 CheckType to do */
  1.1708 -static void
  1.1709 -mod_type_find (GstTypeFind * tf, gpointer unused)
  1.1710 -{
  1.1711 -  guint8 *data;
  1.1712 -
  1.1713 -  /* MOD */
  1.1714 -  if ((data = gst_type_find_peek (tf, 1080, 4)) != NULL) {
  1.1715 -    /* Protracker and variants */
  1.1716 -    if ((memcmp (data, "M.K.", 4) == 0) || (memcmp (data, "M!K!", 4) == 0) ||
  1.1717 -        /* Star Tracker */
  1.1718 -        (memcmp (data, "FLT", 3) == 0 && isdigit (data[3])) ||
  1.1719 -        (memcmp (data, "EXO", 3) == 0 && isdigit (data[3])) ||
  1.1720 -        /* Oktalyzer (Amiga) */
  1.1721 -        (memcmp (data, "OKTA", 4) == 0) ||
  1.1722 -        /* Oktalyser (Atari) */
  1.1723 -        (memcmp (data, "CD81", 4) == 0) ||
  1.1724 -        /* Fasttracker */
  1.1725 -        (memcmp (data + 1, "CHN", 3) == 0 && isdigit (data[0])) ||
  1.1726 -        /* Fasttracker or Taketracker */
  1.1727 -        (memcmp (data + 2, "CH", 2) == 0 && isdigit (data[0])
  1.1728 -            && isdigit (data[1])) || (memcmp (data + 2, "CN", 2) == 0
  1.1729 -            && isdigit (data[0]) && isdigit (data[1]))) {
  1.1730 -      gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, MOD_CAPS);
  1.1731 -      return;
  1.1732 -    }
  1.1733 -  }
  1.1734 -  /* XM */
  1.1735 -  if ((data = gst_type_find_peek (tf, 0, 38)) != NULL) {
  1.1736 -    if (memcmp (data, "Extended Module: ", 17) == 0 && data[37] == 0x1A) {
  1.1737 -      gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, MOD_CAPS);
  1.1738 -      return;
  1.1739 -    }
  1.1740 -  }
  1.1741 -  /* OKT */
  1.1742 -  if (data || (data = gst_type_find_peek (tf, 0, 8)) != NULL) {
  1.1743 -    if (memcmp (data, "OKTASONG", 8) == 0) {
  1.1744 -      gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, MOD_CAPS);
  1.1745 -      return;
  1.1746 -    }
  1.1747 -  }
  1.1748 -  if (data || (data = gst_type_find_peek (tf, 0, 4)) != NULL) {
  1.1749 -    /* 669 */
  1.1750 -    if ((memcmp (data, "if", 2) == 0) || (memcmp (data, "JN", 2) == 0)) {
  1.1751 -      gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, MOD_CAPS);
  1.1752 -      return;
  1.1753 -    }
  1.1754 -    /* AMF */
  1.1755 -    if ((memcmp (data, "AMF", 3) == 0 && data[3] > 10 && data[3] < 14) ||
  1.1756 -        /* IT */
  1.1757 -        (memcmp (data, "IMPM", 4) == 0) ||
  1.1758 -        /* MED */
  1.1759 -        (memcmp (data, "MMD0", 4) == 0) || (memcmp (data, "MMD1", 4) == 0) ||
  1.1760 -        /* MTM */
  1.1761 -        (memcmp (data, "MTM", 3) == 0)) {
  1.1762 -      gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, MOD_CAPS);
  1.1763 -      return;
  1.1764 -    }
  1.1765 -    /* DSM */
  1.1766 -    if (memcmp (data, "RIFF", 4) == 0) {
  1.1767 -      guint8 *data2 = gst_type_find_peek (tf, 8, 4);
  1.1768 -
  1.1769 -      if (data2) {
  1.1770 -        if (memcmp (data2, "DSMF", 4) == 0) {
  1.1771 -          gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, MOD_CAPS);
  1.1772 -          return;
  1.1773 -        }
  1.1774 -      }
  1.1775 -    }
  1.1776 -    /* FAM */
  1.1777 -    if (memcmp (data, "FAM\xFE", 4) == 0) {
  1.1778 -      guint8 *data2 = gst_type_find_peek (tf, 44, 3);
  1.1779 -
  1.1780 -      if (data2) {
  1.1781 -        if (memcmp (data2, "compare", 3) == 0) {
  1.1782 -          gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, MOD_CAPS);
  1.1783 -          return;
  1.1784 -        }
  1.1785 -      } else {
  1.1786 -        gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, MOD_CAPS);
  1.1787 -        return;
  1.1788 -      }
  1.1789 -    }
  1.1790 -    /* GDM */
  1.1791 -    if (memcmp (data, "GDM\xFE", 4) == 0) {
  1.1792 -      guint8 *data2 = gst_type_find_peek (tf, 71, 4);
  1.1793 -
  1.1794 -      if (data2) {
  1.1795 -        if (memcmp (data2, "GMFS", 4) == 0) {
  1.1796 -          gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, MOD_CAPS);
  1.1797 -          return;
  1.1798 -        }
  1.1799 -      } else {
  1.1800 -        gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, MOD_CAPS);
  1.1801 -        return;
  1.1802 -      }
  1.1803 -    }
  1.1804 -  }
  1.1805 -  /* IMF */
  1.1806 -  if ((data = gst_type_find_peek (tf, 60, 4)) != NULL) {
  1.1807 -    if (memcmp (data, "IM10", 4) == 0) {
  1.1808 -      gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, MOD_CAPS);
  1.1809 -      return;
  1.1810 -    }
  1.1811 -  }
  1.1812 -  /* S3M */
  1.1813 -  if ((data = gst_type_find_peek (tf, 44, 4)) != NULL) {
  1.1814 -    if (memcmp (data, "SCRM", 4) == 0) {
  1.1815 -      gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, MOD_CAPS);
  1.1816 -      return;
  1.1817 -    }
  1.1818 -  }
  1.1819 -}
  1.1820 -
  1.1821 -/*** application/x-shockwave-flash ***/
  1.1822 -
  1.1823 -static GstStaticCaps swf_caps =
  1.1824 -GST_STATIC_CAPS ("application/x-shockwave-flash");
  1.1825 -#define SWF_CAPS (gst_static_caps_get(&swf_caps))
  1.1826 -static void
  1.1827 -swf_type_find (GstTypeFind * tf, gpointer unused)
  1.1828 -{
  1.1829 -  guint8 *data = gst_type_find_peek (tf, 0, 4);
  1.1830 -
  1.1831 -  if (data && (data[0] == 'F' || data[0] == 'C') &&
  1.1832 -      data[1] == 'W' && data[2] == 'S') {
  1.1833 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, SWF_CAPS);
  1.1834 -  }
  1.1835 -}
  1.1836 -
  1.1837 -/*** image/jpeg ***/
  1.1838 -
  1.1839 -static GstStaticCaps jpeg_caps = GST_STATIC_CAPS ("image/jpeg");
  1.1840 -
  1.1841 -#define JPEG_CAPS (gst_static_caps_get(&jpeg_caps))
  1.1842 -static void
  1.1843 -jpeg_type_find (GstTypeFind * tf, gpointer unused)
  1.1844 -{
  1.1845 -  guint8 *data = gst_type_find_peek (tf, 0, 10);
  1.1846 -  guint8 header[2] = { 0xFF, 0xD8 };
  1.1847 -
  1.1848 -  if (data && memcmp (data, header, 2) == 0) {
  1.1849 -    if (memcmp (data + 6, "JFIF", 4) == 0) {
  1.1850 -      gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, JPEG_CAPS);
  1.1851 -    } else if (memcmp (data + 6, "Exif", 4) == 0) {
  1.1852 -      gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, JPEG_CAPS);
  1.1853 -    } else {
  1.1854 -      gst_type_find_suggest (tf, GST_TYPE_FIND_POSSIBLE, JPEG_CAPS);
  1.1855 -    }
  1.1856 -  }
  1.1857 -}
  1.1858 -
  1.1859 -/*** image/bmp ***/
  1.1860 -
  1.1861 -static GstStaticCaps bmp_caps = GST_STATIC_CAPS ("image/bmp");
  1.1862 -
  1.1863 -#define BMP_CAPS (gst_static_caps_get(&bmp_caps))
  1.1864 -static void
  1.1865 -bmp_type_find (GstTypeFind * tf, gpointer unused)
  1.1866 -{
  1.1867 -  guint8 *data = gst_type_find_peek (tf, 0, 18);
  1.1868 -
  1.1869 -  if (data && memcmp (data, "BM", 2) == 0) {
  1.1870 -    if ((data[14] == 0x0C ||
  1.1871 -            data[14] == 0x28 ||
  1.1872 -            data[14] == 0xF0) &&
  1.1873 -        data[15] == 0 && data[16] == 0 && data[17] == 0) {
  1.1874 -      gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, BMP_CAPS);
  1.1875 -    }
  1.1876 -  }
  1.1877 -}
  1.1878 -
  1.1879 -/*** image/tiff ***/
  1.1880 -static GstStaticCaps tiff_caps = GST_STATIC_CAPS ("image/tiff, "
  1.1881 -    "endianness = (int) { BIG_ENDIAN, LITTLE_ENDIAN }");
  1.1882 -#define TIFF_CAPS (gst_static_caps_get(&tiff_caps))
  1.1883 -static GstStaticCaps tiff_be_caps = GST_STATIC_CAPS ("image/tiff, "
  1.1884 -    "endianness = (int) BIG_ENDIAN");
  1.1885 -#define TIFF_BE_CAPS (gst_static_caps_get(&tiff_be_caps))
  1.1886 -static GstStaticCaps tiff_le_caps = GST_STATIC_CAPS ("image/tiff, "
  1.1887 -    "endianness = (int) LITTLE_ENDIAN");
  1.1888 -#define TIFF_LE_CAPS (gst_static_caps_get(&tiff_le_caps))
  1.1889 -static void
  1.1890 -tiff_type_find (GstTypeFind * tf, gpointer ununsed)
  1.1891 -{
  1.1892 -  guint8 *data = gst_type_find_peek (tf, 0, 8);
  1.1893 -  guint8 le_header[4] = { 0x49, 0x49, 0x2A, 0x00 };
  1.1894 -  guint8 be_header[4] = { 0x4D, 0x4D, 0x00, 0x2A };
  1.1895 -
  1.1896 -  if (data) {
  1.1897 -    if (memcmp (data, le_header, 4) == 0) {
  1.1898 -      gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, TIFF_LE_CAPS);
  1.1899 -    } else if (memcmp (data, be_header, 4) == 0) {
  1.1900 -      gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, TIFF_BE_CAPS);
  1.1901 -    }
  1.1902 -  }
  1.1903 -}
  1.1904 -
  1.1905 -static GstStaticCaps sds_caps = GST_STATIC_CAPS ("audio/x-sds");
  1.1906 -
  1.1907 -#define SDS_CAPS (gst_static_caps_get(&sds_caps))
  1.1908 -static void
  1.1909 -sds_type_find (GstTypeFind * tf, gpointer ununsed)
  1.1910 -{
  1.1911 -  guint8 *data = gst_type_find_peek (tf, 0, 4);
  1.1912 -  guint8 mask[4] = { 0xFF, 0xFF, 0x80, 0xFF };
  1.1913 -  guint8 match[4] = { 0xF0, 0x7E, 0, 0x01 };
  1.1914 -  gint x;
  1.1915 -
  1.1916 -  if (data) {
  1.1917 -    for (x = 0; x < 4; x++) {
  1.1918 -      if ((data[x] & mask[x]) != match[x]) {
  1.1919 -        return;
  1.1920 -      }
  1.1921 -    }
  1.1922 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, SDS_CAPS);
  1.1923 -  }
  1.1924 -}
  1.1925 -
  1.1926 -static GstStaticCaps ircam_caps = GST_STATIC_CAPS ("audio/x-ircam");
  1.1927 -
  1.1928 -#define IRCAM_CAPS (gst_static_caps_get(&ircam_caps))
  1.1929 -static void
  1.1930 -ircam_type_find (GstTypeFind * tf, gpointer ununsed)
  1.1931 -{
  1.1932 -  guint8 *data = gst_type_find_peek (tf, 0, 4);
  1.1933 -  guint8 mask[4] = { 0xFF, 0xFF, 0xF8, 0xFF };
  1.1934 -  guint8 match[4] = { 0x64, 0xA3, 0x00, 0x00 };
  1.1935 -  gint x;
  1.1936 -  gboolean matched = TRUE;
  1.1937 -
  1.1938 -  if (!data) {
  1.1939 -    return;
  1.1940 -  }
  1.1941 -  for (x = 0; x < 4; x++) {
  1.1942 -    if ((data[x] & mask[x]) != match[x]) {
  1.1943 -      matched = FALSE;
  1.1944 -    }
  1.1945 -  }
  1.1946 -  if (matched) {
  1.1947 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, IRCAM_CAPS);
  1.1948 -    return;
  1.1949 -  }
  1.1950 -  /* now try the reverse version */
  1.1951 -  matched = TRUE;
  1.1952 -  for (x = 0; x < 4; x++) {
  1.1953 -    if ((data[x] & mask[3 - x]) != match[3 - x]) {
  1.1954 -      matched = FALSE;
  1.1955 -    }
  1.1956 -  }
  1.1957 -}
  1.1958 -
  1.1959 -
  1.1960 -/*** video/x-matroska ***/
  1.1961 -static GstStaticCaps matroska_caps = GST_STATIC_CAPS ("video/x-matroska");
  1.1962 -
  1.1963 -#define MATROSKA_CAPS (gst_static_caps_get(&matroska_caps))
  1.1964 -static void
  1.1965 -matroska_type_find (GstTypeFind * tf, gpointer ununsed)
  1.1966 -{
  1.1967 -  /* 4 bytes for EBML ID, 1 byte for header length identifier */
  1.1968 -  guint8 *data = gst_type_find_peek (tf, 0, 4 + 1);
  1.1969 -  gint len_mask = 0x80, size = 1, n = 1, total;
  1.1970 -  guint8 probe_data[] = { 'm', 'a', 't', 'r', 'o', 's', 'k', 'a' };
  1.1971 -
  1.1972 -  if (!data)
  1.1973 -    return;
  1.1974 -
  1.1975 -  /* ebml header? */
  1.1976 -  if (data[0] != 0x1A || data[1] != 0x45 || data[2] != 0xDF || data[3] != 0xA3)
  1.1977 -    return;
  1.1978 -
  1.1979 -  /* length of header */
  1.1980 -  total = data[4];
  1.1981 -  while (size <= 8 && !(total & len_mask)) {
  1.1982 -    size++;
  1.1983 -    len_mask >>= 1;
  1.1984 -  }
  1.1985 -  if (size > 8)
  1.1986 -    return;
  1.1987 -  total &= (len_mask - 1);
  1.1988 -  while (n < size)
  1.1989 -    total = (total << 8) | data[4 + n++];
  1.1990 -
  1.1991 -  /* get new data for full header, 4 bytes for EBML ID,
  1.1992 -   * EBML length tag and the actual header */
  1.1993 -  data = gst_type_find_peek (tf, 0, 4 + size + total);
  1.1994 -  if (!data)
  1.1995 -    return;
  1.1996 -
  1.1997 -  /* the header must contain the document type 'matroska'. For now,
  1.1998 -   * we don't parse the whole header but simply check for the
  1.1999 -   * availability of that array of characters inside the header.
  1.2000 -   * Not fully fool-proof, but good enough. */
  1.2001 -  for (n = 4 + size; n <= 4 + size + total - sizeof (probe_data); n++)
  1.2002 -    if (!memcmp (&data[n], probe_data, sizeof (probe_data))) {
  1.2003 -      gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, MATROSKA_CAPS);
  1.2004 -      break;
  1.2005 -    }
  1.2006 -}
  1.2007 -
  1.2008 -/*** video/x-dv ***/
  1.2009 -
  1.2010 -static GstStaticCaps dv_caps = GST_STATIC_CAPS ("video/x-dv, "
  1.2011 -    "systemstream = (boolean) true");
  1.2012 -#define DV_CAPS (gst_static_caps_get(&dv_caps))
  1.2013 -static void
  1.2014 -dv_type_find (GstTypeFind * tf, gpointer private)
  1.2015 -{
  1.2016 -  guint8 *data;
  1.2017 -
  1.2018 -  data = gst_type_find_peek (tf, 0, 5);
  1.2019 -
  1.2020 -  /* check for DIF  and DV flag */
  1.2021 -  if (data && (data[0] == 0x1f) && (data[1] == 0x07) && (data[2] == 0x00) &&
  1.2022 -      ((data[4] & 0x01) == 0)) {
  1.2023 -    gchar *format;
  1.2024 -    GstCaps *caps = gst_caps_copy (DV_CAPS);
  1.2025 -
  1.2026 -    if (data[3] & 0x80) {
  1.2027 -      format = "PAL";
  1.2028 -    } else {
  1.2029 -      format = "NTSC";
  1.2030 -    }
  1.2031 -    gst_structure_set (gst_caps_get_structure (caps, 0), "format",
  1.2032 -        G_TYPE_STRING, format, NULL);
  1.2033 -
  1.2034 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, caps);
  1.2035 -    gst_caps_unref (caps);
  1.2036 -  }
  1.2037 -}
  1.2038 -
  1.2039 -
  1.2040 -/*** application/ogg and application/x-annodex ***/
  1.2041 -static GstStaticCaps ogg_caps = GST_STATIC_CAPS ("application/ogg");
  1.2042 -static GstStaticCaps annodex_caps = GST_STATIC_CAPS ("application/x-annodex");
  1.2043 -
  1.2044 -#define OGGANX_CAPS (gst_static_caps_get(&annodex_caps))
  1.2045 -
  1.2046 -static void
  1.2047 -ogganx_type_find (GstTypeFind * tf, gpointer private)
  1.2048 -{
  1.2049 -  guint8 *data = gst_type_find_peek (tf, 0, 4);
  1.2050 -
  1.2051 -  if ((data != NULL) && (memcmp (data, "OggS", 4) == 0)) {
  1.2052 -
  1.2053 -    /* Check for an annodex fishbone header */
  1.2054 -    data = gst_type_find_peek (tf, 28, 8);
  1.2055 -    if (data && memcmp (data, "fishead\0", 8) == 0)
  1.2056 -      gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, OGGANX_CAPS);
  1.2057 -
  1.2058 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM,
  1.2059 -        gst_static_caps_get (&ogg_caps));
  1.2060 -  }
  1.2061 -}
  1.2062 -
  1.2063 -/*** audio/x-vorbis ***/
  1.2064 -static GstStaticCaps vorbis_caps = GST_STATIC_CAPS ("audio/x-vorbis");
  1.2065 -
  1.2066 -#define VORBIS_CAPS (gst_static_caps_get(&vorbis_caps))
  1.2067 -static void
  1.2068 -vorbis_type_find (GstTypeFind * tf, gpointer private)
  1.2069 -{
  1.2070 -  guint8 *data = gst_type_find_peek (tf, 0, 30);
  1.2071 -
  1.2072 -  if (data) {
  1.2073 -    guint blocksize_0;
  1.2074 -    guint blocksize_1;
  1.2075 -
  1.2076 -    /* 1 byte packet type (identification=0x01)
  1.2077 -       6 byte string "vorbis"
  1.2078 -       4 byte vorbis version */
  1.2079 -    if (memcmp (data, "\001vorbis\000\000\000\000", 11) != 0)
  1.2080 -      return;
  1.2081 -    data += 11;
  1.2082 -    /* 1 byte channels must be != 0 */
  1.2083 -    if (data[0] == 0)
  1.2084 -      return;
  1.2085 -    data++;
  1.2086 -    /* 4 byte samplerate must be != 0 */
  1.2087 -    if (*((guint32 *) data) == 0)
  1.2088 -      return;
  1.2089 -    data += 16;
  1.2090 -    /* blocksize checks */
  1.2091 -    blocksize_0 = data[0] & 0x0F;
  1.2092 -    blocksize_1 = (data[0] & 0xF0) >> 4;
  1.2093 -    if (blocksize_0 > blocksize_1)
  1.2094 -      return;
  1.2095 -    if (blocksize_0 < 6 || blocksize_0 > 13)
  1.2096 -      return;
  1.2097 -    if (blocksize_1 < 6 || blocksize_1 > 13)
  1.2098 -      return;
  1.2099 -    data++;
  1.2100 -    /* framing bit */
  1.2101 -    if ((data[0] & 0x01) != 1)
  1.2102 -      return;
  1.2103 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, VORBIS_CAPS);
  1.2104 -  }
  1.2105 -}
  1.2106 -
  1.2107 -/*** video/x-theora ***/
  1.2108 -
  1.2109 -static GstStaticCaps theora_caps = GST_STATIC_CAPS ("video/x-theora");
  1.2110 -
  1.2111 -#define THEORA_CAPS (gst_static_caps_get(&theora_caps))
  1.2112 -static void
  1.2113 -theora_type_find (GstTypeFind * tf, gpointer private)
  1.2114 -{
  1.2115 -  guint8 *data = gst_type_find_peek (tf, 0, 7); //42);
  1.2116 -
  1.2117 -  if (data) {
  1.2118 -    if (data[0] != 0x80)
  1.2119 -      return;
  1.2120 -    if (memcmp (&data[1], "theora", 6) != 0)
  1.2121 -      return;
  1.2122 -    /* FIXME: make this more reliable when specs are out */
  1.2123 -
  1.2124 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, THEORA_CAPS);
  1.2125 -  }
  1.2126 -}
  1.2127 -
  1.2128 -/*** application/x-ogm-video or audio***/
  1.2129 -
  1.2130 -static GstStaticCaps ogmvideo_caps =
  1.2131 -GST_STATIC_CAPS ("application/x-ogm-video");
  1.2132 -#define OGMVIDEO_CAPS (gst_static_caps_get(&ogmvideo_caps))
  1.2133 -static void
  1.2134 -ogmvideo_type_find (GstTypeFind * tf, gpointer private)
  1.2135 -{
  1.2136 -  guint8 *data = gst_type_find_peek (tf, 0, 9);
  1.2137 -
  1.2138 -  if (data) {
  1.2139 -    if (memcmp (data, "\001video\000\000\000", 9) != 0)
  1.2140 -      return;
  1.2141 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, OGMVIDEO_CAPS);
  1.2142 -  }
  1.2143 -}
  1.2144 -
  1.2145 -static GstStaticCaps ogmaudio_caps =
  1.2146 -GST_STATIC_CAPS ("application/x-ogm-audio");
  1.2147 -#define OGMAUDIO_CAPS (gst_static_caps_get(&ogmaudio_caps))
  1.2148 -static void
  1.2149 -ogmaudio_type_find (GstTypeFind * tf, gpointer private)
  1.2150 -{
  1.2151 -  guint8 *data = gst_type_find_peek (tf, 0, 9);
  1.2152 -
  1.2153 -  if (data) {
  1.2154 -    if (memcmp (data, "\001audio\000\000\000", 9) != 0)
  1.2155 -      return;
  1.2156 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, OGMAUDIO_CAPS);
  1.2157 -  }
  1.2158 -}
  1.2159 -
  1.2160 -static GstStaticCaps ogmtext_caps = GST_STATIC_CAPS ("application/x-ogm-text");
  1.2161 -
  1.2162 -#define OGMTEXT_CAPS (gst_static_caps_get(&ogmtext_caps))
  1.2163 -static void
  1.2164 -ogmtext_type_find (GstTypeFind * tf, gpointer private)
  1.2165 -{
  1.2166 -  guint8 *data = gst_type_find_peek (tf, 0, 9);
  1.2167 -
  1.2168 -  if (data) {
  1.2169 -    if (memcmp (data, "\001text\000\000\000\000", 9) != 0)
  1.2170 -      return;
  1.2171 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, OGMTEXT_CAPS);
  1.2172 -  }
  1.2173 -}
  1.2174 -
  1.2175 -/*** audio/x-speex ***/
  1.2176 -
  1.2177 -static GstStaticCaps speex_caps = GST_STATIC_CAPS ("audio/x-speex");
  1.2178 -
  1.2179 -#define SPEEX_CAPS (gst_static_caps_get(&speex_caps))
  1.2180 -static void
  1.2181 -speex_type_find (GstTypeFind * tf, gpointer private)
  1.2182 -{
  1.2183 -  guint8 *data = gst_type_find_peek (tf, 0, 80);
  1.2184 -
  1.2185 -  if (data) {
  1.2186 -    /* 8 byte string "Speex   "
  1.2187 -       24 byte speex version string + int */
  1.2188 -    if (memcmp (data, "Speex   ", 8) != 0)
  1.2189 -      return;
  1.2190 -    data += 32;
  1.2191 -
  1.2192 -    /* 4 byte header size >= 80 */
  1.2193 -    if (GST_READ_UINT32_LE (data) < 80)
  1.2194 -      return;
  1.2195 -    data += 4;
  1.2196 -
  1.2197 -    /* 4 byte sample rate <= 48000 */
  1.2198 -    if (GST_READ_UINT32_LE (data) > 48000)
  1.2199 -      return;
  1.2200 -    data += 4;
  1.2201 -
  1.2202 -    /* currently there are only 3 speex modes. */
  1.2203 -    if (GST_READ_UINT32_LE (data) > 3)
  1.2204 -      return;
  1.2205 -    data += 12;
  1.2206 -
  1.2207 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, SPEEX_CAPS);
  1.2208 -  }
  1.2209 -}
  1.2210 -
  1.2211 -/*** application/x-ogg-skeleton ***/
  1.2212 -static GstStaticCaps ogg_skeleton_caps =
  1.2213 -GST_STATIC_CAPS ("application/x-ogg-skeleton, parsed=(boolean)FALSE");
  1.2214 -#define OGG_SKELETON_CAPS (gst_static_caps_get(&ogg_skeleton_caps))
  1.2215 -static void
  1.2216 -oggskel_type_find (GstTypeFind * tf, gpointer private)
  1.2217 -{
  1.2218 -  guint8 *data = gst_type_find_peek (tf, 0, 12);
  1.2219 -
  1.2220 -  if (data) {
  1.2221 -    /* 8 byte string "fishead\0" for the ogg skeleton stream */
  1.2222 -    if (memcmp (data, "fishead\0", 8) != 0)
  1.2223 -      return;
  1.2224 -    data += 8;
  1.2225 -
  1.2226 -    /* Require that the header contains version 3.0 */
  1.2227 -    if (GST_READ_UINT16_LE (data) != 3)
  1.2228 -      return;
  1.2229 -    data += 2;
  1.2230 -    if (GST_READ_UINT16_LE (data) != 0)
  1.2231 -      return;
  1.2232 -
  1.2233 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, OGG_SKELETON_CAPS);
  1.2234 -  }
  1.2235 -}
  1.2236 -
  1.2237 -static GstStaticCaps cmml_caps = GST_STATIC_CAPS ("text/x-cmml");
  1.2238 -
  1.2239 -#define CMML_CAPS (gst_static_caps_get(&cmml_caps))
  1.2240 -static void
  1.2241 -cmml_type_find (GstTypeFind * tf, gpointer private)
  1.2242 -{
  1.2243 -  /* Header is 12 bytes minimum (though we don't check the minor version */
  1.2244 -  guint8 *data = gst_type_find_peek (tf, 0, 12);
  1.2245 -
  1.2246 -  if (data) {
  1.2247 -
  1.2248 -    /* 8 byte string "CMML\0\0\0\0" for the magic number */
  1.2249 -    if (memcmp (data, "CMML\0\0\0\0", 8) != 0)
  1.2250 -      return;
  1.2251 -    data += 8;
  1.2252 -
  1.2253 -    /* Require that the header contains at least version 2.0 */
  1.2254 -    if (GST_READ_UINT16_LE (data) < 2)
  1.2255 -      return;
  1.2256 -
  1.2257 -    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, CMML_CAPS);
  1.2258 -  }
  1.2259 -}
  1.2260 -
  1.2261 -/*** application/x-tar ***/
  1.2262 -
  1.2263 -static GstStaticCaps tar_caps = GST_STATIC_CAPS ("application/x-tar");
  1.2264 -
  1.2265 -#define TAR_CAPS (gst_static_caps_get(&tar_caps))
  1.2266 -#define OLDGNU_MAGIC "ustar  "  /* 7 chars and a NUL */
  1.2267 -#define NEWGNU_MAGIC "ustar"    /* 5 chars and a NUL */
  1.2268 -static void
  1.2269 -tar_type_find (GstTypeFind * tf, gpointer unused)
  1.2270 -{
  1.2271 -  guint8 *data = gst_type_find_peek (tf, 257, 8);
  1.2272 -
  1.2273 -  /* of course we are not certain, but we don't want other typefind funcs
  1.2274 -   * to detect formats of files within the tar archive, e.g. mp3s */
  1.2275 -  if (data) {
  1.2276 -    if (memcmp (data, OLDGNU_MAGIC, 8) == 0) {  /* sic */
  1.2277 -      gst_type_find_suggest (tf, GST_TYPE_FIND_NEARLY_CERTAIN, TAR_CAPS);
  1.2278 -    } else if (memcmp (data, NEWGNU_MAGIC, 6) == 0 &&   /* sic */
  1.2279 -        g_ascii_isdigit (data[6]) && g_ascii_isdigit (data[7])) {
  1.2280 -      gst_type_find_suggest (tf, GST_TYPE_FIND_NEARLY_CERTAIN, TAR_CAPS);
  1.2281 -    }
  1.2282 -  }
  1.2283 -}
  1.2284 -
  1.2285 -/*** application/x-ar ***/
  1.2286 -
  1.2287 -static GstStaticCaps ar_caps = GST_STATIC_CAPS ("application/x-ar");
  1.2288 -
  1.2289 -#define AR_CAPS (gst_static_caps_get(&ar_caps))
  1.2290 -static void
  1.2291 -ar_type_find (GstTypeFind * tf, gpointer unused)
  1.2292 -{
  1.2293 -  guint8 *data = gst_type_find_peek (tf, 0, 24);
  1.2294 -
  1.2295 -  if (data && memcmp (data, "!<arch>", 7) == 0) {
  1.2296 -    gint i;
  1.2297 -
  1.2298 -    for (i = 7; i < 24; ++i) {
  1.2299 -      if (!g_ascii_isprint (data[i]) && data[i] != '\n') {
  1.2300 -        gst_type_find_suggest (tf, GST_TYPE_FIND_POSSIBLE, AR_CAPS);
  1.2301 -      }
  1.2302 -    }
  1.2303 -
  1.2304 -    gst_type_find_suggest (tf, GST_TYPE_FIND_NEARLY_CERTAIN, AR_CAPS);
  1.2305 -  }
  1.2306 -}
  1.2307 -
  1.2308 -/*** audio/x-au ***/
  1.2309 -
  1.2310 -/* NOTE: we cannot replace this function with TYPE_FIND_REGISTER_START_WITH,
  1.2311 - * as it is only possible to register one typefind factory per 'name'
  1.2312 - * (which is in this case the caps), and the first one would be replaced by
  1.2313 - * the second one. */
  1.2314 -static GstStaticCaps au_caps = GST_STATIC_CAPS ("audio/x-au");
  1.2315 -
  1.2316 -#define AU_CAPS (gst_static_caps_get(&au_caps))
  1.2317 -static void
  1.2318 -au_type_find (GstTypeFind * tf, gpointer unused)
  1.2319 -{
  1.2320 -  guint8 *data = gst_type_find_peek (tf, 0, 4);
  1.2321 -
  1.2322 -  if (data) {
  1.2323 -    if (memcmp (data, ".snd", 4) == 0 || memcmp (data, "dns.", 4) == 0) {
  1.2324 -      gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, AU_CAPS);
  1.2325 -    }
  1.2326 -  }
  1.2327 -}
  1.2328 -
  1.2329 -
  1.2330 -/*** video/x-nuv ***/
  1.2331 -
  1.2332 -/* NOTE: we cannot replace this function with TYPE_FIND_REGISTER_START_WITH,
  1.2333 - * as it is only possible to register one typefind factory per 'name'
  1.2334 - * (which is in this case the caps), and the first one would be replaced by
  1.2335 - * the second one. */
  1.2336 -static GstStaticCaps nuv_caps = GST_STATIC_CAPS ("video/x-nuv");
  1.2337 -
  1.2338 -#define NUV_CAPS (gst_static_caps_get(&nuv_caps))
  1.2339 -static void
  1.2340 -nuv_type_find (GstTypeFind * tf, gpointer unused)
  1.2341 -{
  1.2342 -  guint8 *data = gst_type_find_peek (tf, 0, 11);
  1.2343 -
  1.2344 -  if (data) {
  1.2345 -    if (memcmp (data, "MythTVVideo", 11) == 0
  1.2346 -        || memcmp (data, "NuppelVideo", 11) == 0) {
  1.2347 -      gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, NUV_CAPS);
  1.2348 -    }
  1.2349 -  }
  1.2350 -}
  1.2351 -
  1.2352 -/*** audio/x-paris ***/
  1.2353 -/* NOTE: do not replace this function with two TYPE_FIND_REGISTER_START_WITH */
  1.2354 -static GstStaticCaps paris_caps = GST_STATIC_CAPS ("audio/x-paris");
  1.2355 -
  1.2356 -#define PARIS_CAPS (gst_static_caps_get(&paris_caps))
  1.2357 -static void
  1.2358 -paris_type_find (GstTypeFind * tf, gpointer unused)
  1.2359 -{
  1.2360 -  guint8 *data = gst_type_find_peek (tf, 0, 4);
  1.2361 -
  1.2362 -  if (data) {
  1.2363 -    if (memcmp (data, " paf", 4) == 0 || memcmp (data, "fap ", 4) == 0) {
  1.2364 -      gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, PARIS_CAPS);
  1.2365 -    }
  1.2366 -  }
  1.2367 -}
  1.2368 -
  1.2369 -/*** audio/iLBC-sh ***/
  1.2370 -/* NOTE: do not replace this function with two TYPE_FIND_REGISTER_START_WITH */
  1.2371 -static GstStaticCaps ilbc_caps = GST_STATIC_CAPS ("audio/iLBC-sh");
  1.2372 -
  1.2373 -#define ILBC_CAPS (gst_static_caps_get(&ilbc_caps))
  1.2374 -static void
  1.2375 -ilbc_type_find (GstTypeFind * tf, gpointer unused)
  1.2376 -{
  1.2377 -  guint8 *data = gst_type_find_peek (tf, 0, 8);
  1.2378 -
  1.2379 -  if (data) {
  1.2380 -    if (memcmp (data, "#!iLBC30", 8) == 0 || memcmp (data, "#!iLBC20", 8) == 0) {
  1.2381 -      gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, ILBC_CAPS);
  1.2382 -    }
  1.2383 -  }
  1.2384 -}
  1.2385 -
  1.2386 -/*** application/x-ms-dos-executable ***/
  1.2387 -
  1.2388 -static GstStaticCaps msdos_caps =
  1.2389 -GST_STATIC_CAPS ("application/x-ms-dos-executable");
  1.2390 -#define MSDOS_CAPS (gst_static_caps_get(&msdos_caps))
  1.2391 -/* see http://www.madchat.org/vxdevl/papers/winsys/pefile/pefile.htm */
  1.2392 -static void
  1.2393 -msdos_type_find (GstTypeFind * tf, gpointer unused)
  1.2394 -{
  1.2395 -  guint8 *data = gst_type_find_peek (tf, 0, 64);
  1.2396 -
  1.2397 -  if (data && data[0] == 'M' && data[1] == 'Z' &&
  1.2398 -      GST_READ_UINT16_LE (data + 8) == 4) {
  1.2399 -    guint32 pe_offset = GST_READ_UINT32_LE (data + 60);
  1.2400 -
  1.2401 -    data = gst_type_find_peek (tf, pe_offset, 2);
  1.2402 -    if (data && data[0] == 'P' && data[1] == 'E') {
  1.2403 -      gst_type_find_suggest (tf, GST_TYPE_FIND_NEARLY_CERTAIN, MSDOS_CAPS);
  1.2404 -    }
  1.2405 -  }
  1.2406 -}
  1.2407 -
  1.2408 -/*** application/x-mmsh ***/
  1.2409 -
  1.2410 -static GstStaticCaps mmsh_caps = GST_STATIC_CAPS ("application/x-mmsh");
  1.2411 -
  1.2412 -#define MMSH_CAPS gst_static_caps_get(&mmsh_caps)
  1.2413 -
  1.2414 -/* This is to recognise mssh-over-http */
  1.2415 -static void
  1.2416 -mmsh_type_find (GstTypeFind * tf, gpointer unused)
  1.2417 -{
  1.2418 -  static const guint8 asf_marker[16] = { 0x30, 0x26, 0xb2, 0x75, 0x8e, 0x66,
  1.2419 -    0xcf, 0x11, 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c
  1.2420 -  };
  1.2421 -
  1.2422 -  guint8 *data;
  1.2423 -
  1.2424 -  data = gst_type_find_peek (tf, 0, 2 + 2 + 4 + 2 + 2 + 16);
  1.2425 -  if (data && data[0] == 0x24 && data[1] == 0x48 &&
  1.2426 -      GST_READ_UINT16_LE (data + 2) > 2 + 2 + 4 + 2 + 2 + 16 &&
  1.2427 -      memcmp (data + 2 + 2 + 4 + 2 + 2, asf_marker, 16) == 0) {
  1.2428 -    GstCaps *caps = gst_caps_copy (MMSH_CAPS);
  1.2429 -
  1.2430 -    gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, caps);
  1.2431 -    gst_caps_unref (caps);
  1.2432 -    return;
  1.2433 -  }
  1.2434 -}
  1.2435 -
  1.2436 -/*** generic typefind for streams that have some data at a specific position***/
  1.2437 -typedef struct
  1.2438 -{
  1.2439 -  const guint8 *data;
  1.2440 -  guint size;
  1.2441 -  guint probability;
  1.2442 -  GstCaps *caps;
  1.2443 -}
  1.2444 -GstTypeFindData;
  1.2445 -
  1.2446 -static void
  1.2447 -start_with_type_find (GstTypeFind * tf, gpointer private)
  1.2448 -{
  1.2449 -  GstTypeFindData *start_with = (GstTypeFindData *) private;
  1.2450 -  guint8 *data;
  1.2451 -
  1.2452 -  GST_LOG ("trying to find mime type %s with the first %u bytes of data",
  1.2453 -      gst_structure_get_name (gst_caps_get_structure (start_with->caps, 0)),
  1.2454 -      start_with->size);
  1.2455 -  data = gst_type_find_peek (tf, 0, start_with->size);
  1.2456 -  if (data && memcmp (data, start_with->data, start_with->size) == 0) {
  1.2457 -    gst_type_find_suggest (tf, start_with->probability, start_with->caps);
  1.2458 -  }
  1.2459 -}
  1.2460 -
  1.2461 -static void
  1.2462 -sw_data_destroy (GstTypeFindData * sw_data)
  1.2463 -{
  1.2464 -  if (G_LIKELY (sw_data->caps != NULL))
  1.2465 -    gst_caps_unref (sw_data->caps);
  1.2466 -  g_free (sw_data);
  1.2467 -}
  1.2468 -
  1.2469 -#define TYPE_FIND_REGISTER_START_WITH(plugin,name,rank,ext,_data,_size,_probability)\
  1.2470 -G_BEGIN_DECLS{                                                          \
  1.2471 -  GstTypeFindData *sw_data = g_new (GstTypeFindData, 1);                \
  1.2472 -  sw_data->data = (const guint8 *)_data;                                \
  1.2473 -  sw_data->size = _size;                                                \
  1.2474 -  sw_data->probability = _probability;                                  \
  1.2475 -  sw_data->caps = gst_caps_new_simple (name, NULL);                     \
  1.2476 -  if (!gst_type_find_register (plugin, name, rank, start_with_type_find,\
  1.2477 -                      ext, sw_data->caps, sw_data,                      \
  1.2478 -                     (GDestroyNotify) (sw_data_destroy))) {             \
  1.2479 -    gst_caps_unref (sw_data->caps);                                     \
  1.2480 -    g_free (sw_data);                                                   \
  1.2481 -  }                                                                     \
  1.2482 -}G_END_DECLS
  1.2483 -
  1.2484 -/*** same for riff types ***/
  1.2485 -
  1.2486 -static void
  1.2487 -riff_type_find (GstTypeFind * tf, gpointer private)
  1.2488 -{
  1.2489 -  GstTypeFindData *riff_data = (GstTypeFindData *) private;
  1.2490 -  guint8 *data = gst_type_find_peek (tf, 0, 12);
  1.2491 -
  1.2492 -  if (data && memcmp (data, "RIFF", 4) == 0) {
  1.2493 -    data += 8;
  1.2494 -    if (memcmp (data, riff_data->data, 4) == 0)
  1.2495 -      gst_type_find_suggest (tf, riff_data->probability, riff_data->caps);
  1.2496 -  }
  1.2497 -}
  1.2498 -
  1.2499 -#define TYPE_FIND_REGISTER_RIFF(plugin,name,rank,ext,_data)             \
  1.2500 -G_BEGIN_DECLS{                                                          \
  1.2501 -  GstTypeFindData *sw_data = g_new (GstTypeFindData, 1);                \
  1.2502 -  sw_data->data = (gpointer)_data;                                      \
  1.2503 -  sw_data->size = 4;                                                    \
  1.2504 -  sw_data->probability = GST_TYPE_FIND_MAXIMUM;                         \
  1.2505 -  sw_data->caps = gst_caps_new_simple (name, NULL);                     \
  1.2506 -  if (!gst_type_find_register (plugin, name, rank, riff_type_find,      \
  1.2507 -                      ext, sw_data->caps, sw_data,                      \
  1.2508 -                      (GDestroyNotify) (sw_data_destroy))) {            \
  1.2509 -    gst_caps_unref (sw_data->caps);                                     \
  1.2510 -    g_free (sw_data);                                                   \
  1.2511 -  }                                                                     \
  1.2512 -}G_END_DECLS
  1.2513 -
  1.2514 -
  1.2515 -
  1.2516 -/*** plugin initialization ***/
  1.2517 -
  1.2518 -#define TYPE_FIND_REGISTER(plugin,name,rank,func,ext,caps,priv,notify) \
  1.2519 -G_BEGIN_DECLS{\
  1.2520 -  if (!gst_type_find_register (plugin, name, rank, func, ext, caps, priv, notify))\
  1.2521 -    return FALSE; \
  1.2522 -}G_END_DECLS
  1.2523 -static gboolean
  1.2524 -plugin_init (GstPlugin * plugin)
  1.2525 -{
  1.2526 -  /* can't initialize this via a struct as caps can't be statically initialized */
  1.2527 -
  1.2528 -  /* note: asx/wax/wmx are XML files, asf doesn't handle them */
  1.2529 -  /* FIXME-0.11: these should be const,
  1.2530 -     this requires gstreamer/gst/gsttypefind::gst_type_find_register()
  1.2531 -     to have define the parameter as const
  1.2532 -   */
  1.2533 -  static gchar *asf_exts[] = { "asf", "wm", "wma", "wmv", NULL };
  1.2534 -  static gchar *au_exts[] = { "au", "snd", NULL };
  1.2535 -  static gchar *avi_exts[] = { "avi", NULL };
  1.2536 -  static gchar *cdxa_exts[] = { "dat", NULL };
  1.2537 -  static gchar *flac_exts[] = { "flac", NULL };
  1.2538 -  static gchar *flx_exts[] = { "flc", "fli", NULL };
  1.2539 -  static gchar *id3_exts[] =
  1.2540 -      { "mp3", "mp2", "mp1", "mpga", "ogg", "flac", "tta", NULL };
  1.2541 -  static gchar *apetag_exts[] = { "ape", "mpc", "wv", NULL };   /* and mp3 and wav? */
  1.2542 -  static gchar *tta_exts[] = { "tta", NULL };
  1.2543 -  static gchar *mod_exts[] = { "669", "amf", "dsm", "gdm", "far", "imf",
  1.2544 -    "it", "med", "mod", "mtm", "okt", "sam",
  1.2545 -    "s3m", "stm", "stx", "ult", "xm", NULL
  1.2546 -  };
  1.2547 -  static gchar *mp3_exts[] = { "mp3", "mp2", "mp1", "mpga", NULL };
  1.2548 -  static gchar *ac3_exts[] = { "ac3", NULL };
  1.2549 -  static gchar *musepack_exts[] = { "mpc", NULL };
  1.2550 -  static gchar *mpeg_sys_exts[] = { "mpe", "mpeg", "mpg", NULL };
  1.2551 -  static gchar *mpeg_video_exts[] = { "mpv", "mpeg", "mpg", NULL };
  1.2552 -  static gchar *mpeg_ts_exts[] = { "ts", NULL };
  1.2553 -  static gchar *ogg_exts[] = { "anx", "ogg", "ogm", NULL };
  1.2554 -  static gchar *qt_exts[] = { "mov", NULL };
  1.2555 -  static gchar *qtif_exts[] = { "qif", "qtif", "qti", NULL };
  1.2556 -  static gchar *rm_exts[] = { "ra", "ram", "rm", "rmvb", NULL };
  1.2557 -  static gchar *swf_exts[] = { "swf", "swfl", NULL };
  1.2558 -  static gchar *utf8_exts[] = { "txt", NULL };
  1.2559 -  static gchar *wav_exts[] = { "wav", NULL };
  1.2560 -  static gchar *aiff_exts[] = { "aiff", "aif", "aifc", NULL };
  1.2561 -  static gchar *svx_exts[] = { "iff", "svx", NULL };
  1.2562 -  static gchar *paris_exts[] = { "paf", NULL };
  1.2563 -  static gchar *nist_exts[] = { "nist", NULL };
  1.2564 -  static gchar *voc_exts[] = { "voc", NULL };
  1.2565 -  static gchar *sds_exts[] = { "sds", NULL };
  1.2566 -  static gchar *ircam_exts[] = { "sf", NULL };
  1.2567 -  static gchar *w64_exts[] = { "w64", NULL };
  1.2568 -  static gchar *shn_exts[] = { "shn", NULL };
  1.2569 -  static gchar *ape_exts[] = { "ape", NULL };
  1.2570 -  static gchar *uri_exts[] = { "ram", NULL };
  1.2571 -  static gchar *smil_exts[] = { "smil", NULL };
  1.2572 -  static gchar *html_exts[] = { "htm", "html", NULL };
  1.2573 -  static gchar *xml_exts[] = { "xml", NULL };
  1.2574 -  static gchar *jpeg_exts[] = { "jpg", "jpe", "jpeg", NULL };
  1.2575 -  static gchar *gif_exts[] = { "gif", NULL };
  1.2576 -  static gchar *png_exts[] = { "png", NULL };
  1.2577 -  static gchar *bmp_exts[] = { "bmp", NULL };
  1.2578 -  static gchar *tiff_exts[] = { "tif", "tiff", NULL };
  1.2579 -  static gchar *matroska_exts[] = { "mkv", "mka", NULL };
  1.2580 -  static gchar *mve_exts[] = { "mve", NULL };
  1.2581 -  static gchar *dv_exts[] = { "dv", "dif", NULL };
  1.2582 -  static gchar *amr_exts[] = { "amr", NULL };
  1.2583 -  static gchar *ilbc_exts[] = { "ilbc", NULL };
  1.2584 -  static gchar *sid_exts[] = { "sid", NULL };
  1.2585 -  static gchar *xcf_exts[] = { "xcf", NULL };
  1.2586 -  static gchar *mng_exts[] = { "mng", NULL };
  1.2587 -  static gchar *jng_exts[] = { "jng", NULL };
  1.2588 -  static gchar *xpm_exts[] = { "xpm", NULL };
  1.2589 -  static gchar *ras_exts[] = { "ras", NULL };
  1.2590 -  static gchar *bz2_exts[] = { "bz2", NULL };
  1.2591 -  static gchar *gz_exts[] = { "gz", NULL };
  1.2592 -  static gchar *zip_exts[] = { "zip", NULL };
  1.2593 -  static gchar *compress_exts[] = { "Z", NULL };
  1.2594 -  static gchar *m4a_exts[] = { "m4a", NULL };
  1.2595 -  static gchar *q3gp_exts[] = { "3gp", NULL };
  1.2596 -  static gchar *aac_exts[] = { "aac", NULL };
  1.2597 -  static gchar *spc_exts[] = { "spc", NULL };
  1.2598 -  static gchar *wavpack_exts[] = { "wv", "wvp", NULL };
  1.2599 -  static gchar *wavpack_correction_exts[] = { "wvc", NULL };
  1.2600 -  static gchar *rar_exts[] = { "rar", NULL };
  1.2601 -  static gchar *tar_exts[] = { "tar", NULL };
  1.2602 -  static gchar *ar_exts[] = { "a", NULL };
  1.2603 -  static gchar *msdos_exts[] = { "dll", "exe", "ocx", "sys", "scr",
  1.2604 -    "msstyles", "cpl", NULL
  1.2605 -  };
  1.2606 -  static gchar *flv_exts[] = { "flv", NULL };
  1.2607 -  static gchar *m4v_exts[] = { "m4v", NULL };
  1.2608 -  static gchar *nuv_exts[] = { "nuv", NULL };
  1.2609 -
  1.2610 -  GST_DEBUG_CATEGORY_INIT (type_find_debug, "typefindfunctions",
  1.2611 -      GST_DEBUG_FG_GREEN | GST_DEBUG_BG_RED, "generic type find functions");
  1.2612 -
  1.2613 -  /* must use strings, macros don't accept initializers */
  1.2614 -  TYPE_FIND_REGISTER_START_WITH (plugin, "video/x-ms-asf", GST_RANK_SECONDARY,
  1.2615 -      asf_exts,
  1.2616 -      "\060\046\262\165\216\146\317\021\246\331\000\252\000\142\316\154", 16,
  1.2617 -      GST_TYPE_FIND_MAXIMUM);
  1.2618 -  TYPE_FIND_REGISTER (plugin, "audio/x-musepack", GST_RANK_PRIMARY,
  1.2619 -      musepack_type_find, musepack_exts, MUSEPACK_CAPS, NULL, NULL);
  1.2620 -  TYPE_FIND_REGISTER (plugin, "audio/x-au", GST_RANK_MARGINAL,
  1.2621 -      au_type_find, au_exts, AU_CAPS, NULL, NULL);
  1.2622 -  TYPE_FIND_REGISTER_RIFF (plugin, "video/x-msvideo", GST_RANK_PRIMARY,
  1.2623 -      avi_exts, "AVI ");
  1.2624 -  TYPE_FIND_REGISTER_RIFF (plugin, "video/x-cdxa", GST_RANK_PRIMARY,
  1.2625 -      cdxa_exts, "CDXA");
  1.2626 -  TYPE_FIND_REGISTER_START_WITH (plugin, "video/x-vcd", GST_RANK_PRIMARY,
  1.2627 -      cdxa_exts, "\000\377\377\377\377\377\377\377\377\377\377\000", 12,
  1.2628 -      GST_TYPE_FIND_MAXIMUM);
  1.2629 -  TYPE_FIND_REGISTER_START_WITH (plugin, "audio/x-flac", GST_RANK_PRIMARY,
  1.2630 -      flac_exts, "fLaC", 4, GST_TYPE_FIND_MAXIMUM);
  1.2631 -  TYPE_FIND_REGISTER (plugin, "video/x-fli", GST_RANK_MARGINAL, flx_type_find,
  1.2632 -      flx_exts, FLX_CAPS, NULL, NULL);
  1.2633 -  TYPE_FIND_REGISTER (plugin, "application/x-id3v2", GST_RANK_PRIMARY + 3,
  1.2634 -      id3v2_type_find, id3_exts, ID3_CAPS, NULL, NULL);
  1.2635 -  TYPE_FIND_REGISTER (plugin, "application/x-id3v1", GST_RANK_PRIMARY + 1,
  1.2636 -      id3v1_type_find, id3_exts, ID3_CAPS, NULL, NULL);
  1.2637 -  TYPE_FIND_REGISTER (plugin, "application/x-apetag", GST_RANK_PRIMARY + 2,
  1.2638 -      apetag_type_find, apetag_exts, APETAG_CAPS, NULL, NULL);
  1.2639 -  TYPE_FIND_REGISTER (plugin, "audio/x-ttafile", GST_RANK_PRIMARY,
  1.2640 -      tta_type_find, tta_exts, TTA_CAPS, NULL, NULL);
  1.2641 -  TYPE_FIND_REGISTER (plugin, "audio/x-mod", GST_RANK_SECONDARY, mod_type_find,
  1.2642 -      mod_exts, MOD_CAPS, NULL, NULL);
  1.2643 -  TYPE_FIND_REGISTER (plugin, "audio/mpeg", GST_RANK_PRIMARY, mp3_type_find,
  1.2644 -      mp3_exts, MP3_CAPS, NULL, NULL);
  1.2645 -  TYPE_FIND_REGISTER (plugin, "audio/x-ac3", GST_RANK_PRIMARY, ac3_type_find,
  1.2646 -      ac3_exts, AC3_CAPS, NULL, NULL);
  1.2647 -  TYPE_FIND_REGISTER (plugin, "video/mpeg1", GST_RANK_PRIMARY,
  1.2648 -      mpeg1_sys_type_find, mpeg_sys_exts, MPEG_SYS_CAPS, NULL, NULL);
  1.2649 -  TYPE_FIND_REGISTER (plugin, "video/mpeg2", GST_RANK_SECONDARY,
  1.2650 -      mpeg2_sys_type_find, mpeg_sys_exts, MPEG_SYS_CAPS, NULL, NULL);
  1.2651 -  TYPE_FIND_REGISTER (plugin, "video/mpegts", GST_RANK_PRIMARY,
  1.2652 -      mpeg_ts_type_find, mpeg_ts_exts, MPEGTS_CAPS, NULL, NULL);
  1.2653 -  TYPE_FIND_REGISTER (plugin, "application/ogg", GST_RANK_PRIMARY,
  1.2654 -      ogganx_type_find, ogg_exts, OGGANX_CAPS, NULL, NULL);
  1.2655 -  TYPE_FIND_REGISTER (plugin, "video/mpeg", GST_RANK_SECONDARY,
  1.2656 -      mpeg_video_type_find, mpeg_video_exts, MPEG_VIDEO_CAPS, NULL, NULL);
  1.2657 -  TYPE_FIND_REGISTER (plugin, "video/mpeg-stream", GST_RANK_MARGINAL,
  1.2658 -      mpeg_video_stream_type_find, mpeg_video_exts, MPEG_VIDEO_CAPS, NULL,
  1.2659 -      NULL);
  1.2660 -  TYPE_FIND_REGISTER (plugin, "video/mpeg4", GST_RANK_PRIMARY,
  1.2661 -      mpeg4_video_type_find, m4v_exts, MPEG_VIDEO_CAPS, NULL, NULL);
  1.2662 -  TYPE_FIND_REGISTER (plugin, "video/x-nuv", GST_RANK_SECONDARY,
  1.2663 -      nuv_type_find, nuv_exts, NUV_CAPS, NULL, NULL);
  1.2664 -
  1.2665 -  /* ISO formats */
  1.2666 -  TYPE_FIND_REGISTER (plugin, "audio/x-m4a", GST_RANK_PRIMARY, m4a_type_find,
  1.2667 -      m4a_exts, M4A_CAPS, NULL, NULL);
  1.2668 -  TYPE_FIND_REGISTER (plugin, "application/x-3gp", GST_RANK_PRIMARY,
  1.2669 -      q3gp_type_find, q3gp_exts, Q3GP_CAPS, NULL, NULL);
  1.2670 -  TYPE_FIND_REGISTER (plugin, "video/quicktime", GST_RANK_SECONDARY,
  1.2671 -      qt_type_find, qt_exts, QT_CAPS, NULL, NULL);
  1.2672 -  TYPE_FIND_REGISTER (plugin, "image/x-quicktime", GST_RANK_SECONDARY,
  1.2673 -      qtif_type_find, qtif_exts, QTIF_CAPS, NULL, NULL);
  1.2674 -
  1.2675 -  TYPE_FIND_REGISTER (plugin, "text/html", GST_RANK_SECONDARY, html_type_find,
  1.2676 -      html_exts, HTML_CAPS, NULL, NULL);
  1.2677 -  TYPE_FIND_REGISTER_START_WITH (plugin, "application/vnd.rn-realmedia",
  1.2678 -      GST_RANK_SECONDARY, rm_exts, ".RMF", 4, GST_TYPE_FIND_MAXIMUM);
  1.2679 -  TYPE_FIND_REGISTER_START_WITH (plugin, "application/x-pn-realaudio",
  1.2680 -      GST_RANK_SECONDARY, rm_exts, ".ra\375", 4, GST_TYPE_FIND_MAXIMUM);
  1.2681 -  TYPE_FIND_REGISTER (plugin, "application/x-shockwave-flash",
  1.2682 -      GST_RANK_SECONDARY, swf_type_find, swf_exts, SWF_CAPS, NULL, NULL);
  1.2683 -  TYPE_FIND_REGISTER_START_WITH (plugin, "video/x-flv", GST_RANK_SECONDARY,
  1.2684 -      flv_exts, "FLV", 3, GST_TYPE_FIND_MAXIMUM);
  1.2685 -  TYPE_FIND_REGISTER (plugin, "text/plain", GST_RANK_MARGINAL, utf8_type_find,
  1.2686 -      utf8_exts, UTF8_CAPS, NULL, NULL);
  1.2687 -  TYPE_FIND_REGISTER (plugin, "text/uri-list", GST_RANK_MARGINAL, uri_type_find,
  1.2688 -      uri_exts, URI_CAPS, NULL, NULL);
  1.2689 -  TYPE_FIND_REGISTER (plugin, "application/smil", GST_RANK_SECONDARY,
  1.2690 -      smil_type_find, smil_exts, SMIL_CAPS, NULL, NULL);
  1.2691 -  TYPE_FIND_REGISTER (plugin, "application/xml", GST_RANK_MARGINAL,
  1.2692 -      xml_type_find, xml_exts, GENERIC_XML_CAPS, NULL, NULL);
  1.2693 -  TYPE_FIND_REGISTER_RIFF (plugin, "audio/x-wav", GST_RANK_PRIMARY, wav_exts,
  1.2694 -      "WAVE");
  1.2695 -  TYPE_FIND_REGISTER (plugin, "audio/x-aiff", GST_RANK_SECONDARY,
  1.2696 -      aiff_type_find, aiff_exts, AIFF_CAPS, NULL, NULL);
  1.2697 -  TYPE_FIND_REGISTER (plugin, "audio/x-svx", GST_RANK_SECONDARY, svx_type_find,
  1.2698 -      svx_exts, SVX_CAPS, NULL, NULL);
  1.2699 -  TYPE_FIND_REGISTER (plugin, "audio/x-paris", GST_RANK_SECONDARY,
  1.2700 -      paris_type_find, paris_exts, PARIS_CAPS, NULL, NULL);
  1.2701 -  TYPE_FIND_REGISTER_START_WITH (plugin, "audio/x-nist", GST_RANK_SECONDARY,
  1.2702 -      nist_exts, "NIST", 4, GST_TYPE_FIND_MAXIMUM);
  1.2703 -  TYPE_FIND_REGISTER_START_WITH (plugin, "audio/x-voc", GST_RANK_SECONDARY,
  1.2704 -      voc_exts, "Creative", 8, GST_TYPE_FIND_MAXIMUM);
  1.2705 -  TYPE_FIND_REGISTER (plugin, "audio/x-sds", GST_RANK_SECONDARY, sds_type_find,
  1.2706 -      sds_exts, SDS_CAPS, NULL, NULL);
  1.2707 -  TYPE_FIND_REGISTER (plugin, "audio/x-ircam", GST_RANK_SECONDARY,
  1.2708 -      ircam_type_find, ircam_exts, IRCAM_CAPS, NULL, NULL);
  1.2709 -  TYPE_FIND_REGISTER_START_WITH (plugin, "audio/x-w64", GST_RANK_SECONDARY,
  1.2710 -      w64_exts, "riff", 4, GST_TYPE_FIND_MAXIMUM);
  1.2711 -  TYPE_FIND_REGISTER (plugin, "audio/x-shorten", GST_RANK_SECONDARY,
  1.2712 -      shn_type_find, shn_exts, SHN_CAPS, NULL, NULL);
  1.2713 -  TYPE_FIND_REGISTER (plugin, "application/x-ape", GST_RANK_SECONDARY,
  1.2714 -      ape_type_find, ape_exts, APE_CAPS, NULL, NULL);
  1.2715 -  TYPE_FIND_REGISTER (plugin, "image/jpeg", GST_RANK_PRIMARY, jpeg_type_find,
  1.2716 -      jpeg_exts, JPEG_CAPS, NULL, NULL);
  1.2717 -  TYPE_FIND_REGISTER_START_WITH (plugin, "image/gif", GST_RANK_PRIMARY,
  1.2718 -      gif_exts, "GIF8", 4, GST_TYPE_FIND_MAXIMUM);
  1.2719 -  TYPE_FIND_REGISTER_START_WITH (plugin, "image/png", GST_RANK_PRIMARY,
  1.2720 -      png_exts, "\211PNG\015\012\032\012", 8, GST_TYPE_FIND_MAXIMUM);
  1.2721 -  TYPE_FIND_REGISTER (plugin, "image/bmp", GST_RANK_PRIMARY, bmp_type_find,
  1.2722 -      bmp_exts, BMP_CAPS, NULL, NULL);
  1.2723 -  TYPE_FIND_REGISTER (plugin, "image/tiff", GST_RANK_PRIMARY, tiff_type_find,
  1.2724 -      tiff_exts, TIFF_CAPS, NULL, NULL);
  1.2725 -  TYPE_FIND_REGISTER (plugin, "video/x-matroska", GST_RANK_PRIMARY,
  1.2726 -      matroska_type_find, matroska_exts, MATROSKA_CAPS, NULL, NULL);
  1.2727 -  TYPE_FIND_REGISTER_START_WITH (plugin, "video/x-mve", GST_RANK_SECONDARY,
  1.2728 -      mve_exts, "Interplay MVE File\032\000\032\000\000\001\063\021", 26,
  1.2729 -      GST_TYPE_FIND_MAXIMUM);
  1.2730 -  TYPE_FIND_REGISTER (plugin, "video/x-dv", GST_RANK_SECONDARY, dv_type_find,
  1.2731 -      dv_exts, DV_CAPS, NULL, NULL);
  1.2732 -  TYPE_FIND_REGISTER_START_WITH (plugin, "audio/x-amr-nb-sh", GST_RANK_PRIMARY,
  1.2733 -      amr_exts, "#!AMR", 5, GST_TYPE_FIND_LIKELY);
  1.2734 -  TYPE_FIND_REGISTER_START_WITH (plugin, "audio/x-amr-wb-sh", GST_RANK_PRIMARY,
  1.2735 -      amr_exts, "#!AMR-WB", 7, GST_TYPE_FIND_MAXIMUM);
  1.2736 -  TYPE_FIND_REGISTER (plugin, "audio/iLBC-sh", GST_RANK_PRIMARY,
  1.2737 -      ilbc_type_find, ilbc_exts, ILBC_CAPS, NULL, NULL);
  1.2738 -  TYPE_FIND_REGISTER_START_WITH (plugin, "audio/x-sid", GST_RANK_MARGINAL,
  1.2739 -      sid_exts, "PSID", 4, GST_TYPE_FIND_MAXIMUM);
  1.2740 -  TYPE_FIND_REGISTER_START_WITH (plugin, "image/x-xcf", GST_RANK_SECONDARY,
  1.2741 -      xcf_exts, "gimp xcf", 8, GST_TYPE_FIND_MAXIMUM);
  1.2742 -  TYPE_FIND_REGISTER_START_WITH (plugin, "video/x-mng", GST_RANK_SECONDARY,
  1.2743 -      mng_exts, "\212MNG\015\012\032\012", 8, GST_TYPE_FIND_MAXIMUM);
  1.2744 -  TYPE_FIND_REGISTER_START_WITH (plugin, "image/x-jng", GST_RANK_SECONDARY,
  1.2745 -      jng_exts, "\213JNG\015\012\032\012", 8, GST_TYPE_FIND_MAXIMUM);
  1.2746 -  TYPE_FIND_REGISTER_START_WITH (plugin, "image/x-xpixmap", GST_RANK_SECONDARY,
  1.2747 -      xpm_exts, "/* XPM */", 9, GST_TYPE_FIND_MAXIMUM);
  1.2748 -  TYPE_FIND_REGISTER_START_WITH (plugin, "image/x-sun-raster",
  1.2749 -      GST_RANK_SECONDARY, ras_exts, "\131\246\152\225", 4,
  1.2750 -      GST_TYPE_FIND_MAXIMUM);
  1.2751 -  TYPE_FIND_REGISTER_START_WITH (plugin, "application/x-bzip",
  1.2752 -      GST_RANK_SECONDARY, bz2_exts, "BZh", 3, GST_TYPE_FIND_LIKELY);
  1.2753 -  TYPE_FIND_REGISTER_START_WITH (plugin, "application/x-gzip",
  1.2754 -      GST_RANK_SECONDARY, gz_exts, "\037\213", 2, GST_TYPE_FIND_LIKELY);
  1.2755 -  TYPE_FIND_REGISTER_START_WITH (plugin, "application/zip", GST_RANK_SECONDARY,
  1.2756 -      zip_exts, "PK\003\004", 4, GST_TYPE_FIND_LIKELY);
  1.2757 -  TYPE_FIND_REGISTER_START_WITH (plugin, "application/x-compress",
  1.2758 -      GST_RANK_SECONDARY, compress_exts, "\037\235", 2, GST_TYPE_FIND_LIKELY);
  1.2759 -  TYPE_FIND_REGISTER (plugin, "audio/x-vorbis", GST_RANK_PRIMARY,
  1.2760 -      vorbis_type_find, NULL, VORBIS_CAPS, NULL, NULL);
  1.2761 -  TYPE_FIND_REGISTER (plugin, "video/x-theora", GST_RANK_PRIMARY,
  1.2762 -      theora_type_find, NULL, THEORA_CAPS, NULL, NULL);
  1.2763 -  TYPE_FIND_REGISTER (plugin, "application/x-ogm-video", GST_RANK_PRIMARY,
  1.2764 -      ogmvideo_type_find, NULL, OGMVIDEO_CAPS, NULL, NULL);
  1.2765 -  TYPE_FIND_REGISTER (plugin, "application/x-ogm-audio", GST_RANK_PRIMARY,
  1.2766 -      ogmaudio_type_find, NULL, OGMAUDIO_CAPS, NULL, NULL);
  1.2767 -  TYPE_FIND_REGISTER (plugin, "application/x-ogm-text", GST_RANK_PRIMARY,
  1.2768 -      ogmtext_type_find, NULL, OGMTEXT_CAPS, NULL, NULL);
  1.2769 -  TYPE_FIND_REGISTER (plugin, "audio/x-speex", GST_RANK_PRIMARY,
  1.2770 -      speex_type_find, NULL, SPEEX_CAPS, NULL, NULL);
  1.2771 -  TYPE_FIND_REGISTER (plugin, "application/x-ogg-skeleton", GST_RANK_PRIMARY,
  1.2772 -      oggskel_type_find, NULL, OGG_SKELETON_CAPS, NULL, NULL);
  1.2773 -  TYPE_FIND_REGISTER (plugin, "text/x-cmml", GST_RANK_PRIMARY, cmml_type_find,
  1.2774 -      NULL, CMML_CAPS, NULL, NULL);
  1.2775 -  TYPE_FIND_REGISTER_START_WITH (plugin, "application/x-executable",
  1.2776 -      GST_RANK_MARGINAL, NULL, "\177ELF", 4, GST_TYPE_FIND_MAXIMUM);
  1.2777 -  TYPE_FIND_REGISTER (plugin, "adts_mpeg_stream", GST_RANK_SECONDARY,
  1.2778 -      aac_type_find, aac_exts, AAC_CAPS, NULL, NULL);
  1.2779 -  TYPE_FIND_REGISTER_START_WITH (plugin, "audio/x-spc", GST_RANK_SECONDARY,
  1.2780 -      spc_exts, "SNES-SPC700 Sound File Data", 27, GST_TYPE_FIND_MAXIMUM);
  1.2781 -  TYPE_FIND_REGISTER (plugin, "audio/x-wavpack", GST_RANK_SECONDARY,
  1.2782 -      wavpack_type_find, wavpack_exts, WAVPACK_CAPS, NULL, NULL);
  1.2783 -  TYPE_FIND_REGISTER (plugin, "audio/x-wavpack-correction", GST_RANK_SECONDARY,
  1.2784 -      wavpack_type_find, wavpack_correction_exts, WAVPACK_CORRECTION_CAPS, NULL,
  1.2785 -      NULL);
  1.2786 -  TYPE_FIND_REGISTER_START_WITH (plugin, "application/x-rar",
  1.2787 -      GST_RANK_SECONDARY, rar_exts, "Rar!", 4, GST_TYPE_FIND_LIKELY);
  1.2788 -  TYPE_FIND_REGISTER (plugin, "application/x-tar", GST_RANK_SECONDARY,
  1.2789 -      tar_type_find, tar_exts, TAR_CAPS, NULL, NULL);
  1.2790 -  TYPE_FIND_REGISTER (plugin, "application/x-ar", GST_RANK_SECONDARY,
  1.2791 -      ar_type_find, ar_exts, AR_CAPS, NULL, NULL);
  1.2792 -  TYPE_FIND_REGISTER (plugin, "application/x-ms-dos-executable",
  1.2793 -      GST_RANK_SECONDARY, msdos_type_find, msdos_exts, MSDOS_CAPS, NULL, NULL);
  1.2794 -#if 0
  1.2795 -  TYPE_FIND_REGISTER_START_WITH (plugin, "video/x-dirac",
  1.2796 -      GST_RANK_PRIMARY, NULL, "BBCD", 4, GST_TYPE_FIND_MAXIMUM);
  1.2797 -#endif
  1.2798 -  TYPE_FIND_REGISTER_START_WITH (plugin, "video/x-dirac",
  1.2799 -      GST_RANK_PRIMARY, NULL, "KW-DIRAC", 8, GST_TYPE_FIND_MAXIMUM);
  1.2800 -  TYPE_FIND_REGISTER (plugin, "multipart/x-mixed-replace", GST_RANK_SECONDARY,
  1.2801 -      multipart_type_find, NULL, MULTIPART_CAPS, NULL, NULL);
  1.2802 -  TYPE_FIND_REGISTER (plugin, "application/x-mmsh", GST_RANK_SECONDARY,
  1.2803 -      mmsh_type_find, NULL, MMSH_CAPS, NULL, NULL);
  1.2804 -  return TRUE;
  1.2805 -}
  1.2806 -
  1.2807 -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
  1.2808 -    GST_VERSION_MINOR,
  1.2809 -    "typefindfunctions",
  1.2810 -    "default typefind functions",
  1.2811 -    plugin_init, VERSION, "LGPL", "GStreamer Base Plug-ins CVS/prerelease", "Gstreamer CVS")