Ejemplo n.º 1
0
EXPORT_C
#endif

GstCaps *
gst_type_find_helper_for_extension (GstObject * obj, const gchar * extension)
{
    GList *l, *type_list;
    GstCaps *result = NULL;

    g_return_val_if_fail (extension != NULL, NULL);

    GST_LOG_OBJECT (obj, "finding caps for extension %s", extension);

    type_list = gst_type_find_factory_get_list ();
    type_list = g_list_sort (type_list, type_find_factory_rank_cmp);

    for (l = type_list; l; l = g_list_next (l)) {
        GstTypeFindFactory *factory;
        gchar **ext;
        gint i;

        factory = GST_TYPE_FIND_FACTORY (l->data);

        /* get the extension that this typefind factory can handle */
        ext = gst_type_find_factory_get_extensions (factory);
        if (ext == NULL)
            continue;

        /* we only want to check those factories without a function */
        if (factory->function != NULL)
            continue;

        /* there are extension, see if one of them matches the requested
         * extension */
        for (i = 0; ext[i]; i++) {
            if (strcmp (ext[i], extension) == 0) {
                /* we found a matching extension, take the caps */
                if ((result = gst_type_find_factory_get_caps (factory))) {
                    gst_caps_ref (result);
                    goto done;
                }
            }
        }
    }
done:
    gst_plugin_feature_list_free (type_list);

    GST_LOG_OBJECT (obj, "Returning %" GST_PTR_FORMAT, result);

    return result;
}
Ejemplo n.º 2
0
static GList *
prioritize_extension (GstObject * obj, GList * type_list,
    const gchar * extension)
{
  gint pos = 0;
  GList *next, *l;

  if (!extension)
    return type_list;

  /* move the typefinders for the extension first in the list. The idea is that
   * when one of them returns MAX we don't need to search further as there is a
   * very high chance we got the right type. */

  GST_LOG_OBJECT (obj, "sorting typefind for extension %s to head", extension);

  for (l = type_list; l; l = next) {
    const gchar *const *ext;
    GstTypeFindFactory *factory;

    next = l->next;

    factory = GST_TYPE_FIND_FACTORY (l->data);

    ext = gst_type_find_factory_get_extensions (factory);
    if (ext == NULL)
      continue;

    GST_LOG_OBJECT (obj, "testing factory %s for extension %s",
        GST_OBJECT_NAME (factory), extension);

    while (*ext != NULL) {
      if (strcmp (*ext, extension) == 0) {
        /* found extension, move in front */
        GST_LOG_OBJECT (obj, "moving typefind for extension %s to head",
            extension);
        /* remove entry from list */
        type_list = g_list_delete_link (type_list, l);
        /* insert at the position */
        type_list = g_list_insert (type_list, factory, pos);
        /* next element will be inserted after this one */
        pos++;
        break;
      }
      ++ext;
    }
  }

  return type_list;
}
Ejemplo n.º 3
0
/*
 * Method: extensions
 *
 * Gets the extensions associated with a type find factory.
 *
 * Returns: an Array of String objects, or nil if no extensions are 
 * associated with the type find factory.
 */
static VALUE
rg_extensions(VALUE self)
{
    VALUE ary;
    gchar **extensions;

    ary = rb_ary_new ();
    extensions = gst_type_find_factory_get_extensions(SELF(self));

    if (!extensions)
        return ary;

    while (*extensions) {
        rb_ary_push(ary, CSTR2RVAL(*extensions));
        extensions++;
    }

    return ary;
}
Ejemplo n.º 4
0
/**
 * gst_type_find_helper_get_range_ext:
 * @obj: A #GstObject that will be passed as first argument to @func
 * @func: (scope call): A generic #GstTypeFindHelperGetRangeFunction that will
 *        be used to access data at random offsets when doing the typefinding
 * @size: The length in bytes
 * @extension: extension of the media
 * @prob: (out) (allow-none): location to store the probability of the found
 *     caps, or #NULL
 *
 * Utility function to do pull-based typefinding. Unlike gst_type_find_helper()
 * however, this function will use the specified function @func to obtain the
 * data needed by the typefind functions, rather than operating on a given
 * source pad. This is useful mostly for elements like tag demuxers which
 * strip off data at the beginning and/or end of a file and want to typefind
 * the stripped data stream before adding their own source pad (the specified
 * callback can then call the upstream peer pad with offsets adjusted for the
 * tag size, for example).
 *
 * When @extension is not NULL, this function will first try the typefind
 * functions for the given extension, which might speed up the typefinding
 * in many cases.
 *
 * Free-function: gst_caps_unref
 *
 * Returns: (transfer full): the #GstCaps corresponding to the data stream.
 *     Returns #NULL if no #GstCaps matches the data stream.
 *
 * Since: 0.10.26
 */
GstCaps *
gst_type_find_helper_get_range_ext (GstObject * obj,
    GstTypeFindHelperGetRangeFunction func, guint64 size,
    const gchar * extension, GstTypeFindProbability * prob)
{
  GstTypeFindHelper helper;
  GstTypeFind find;
  GSList *walk;
  GList *l, *type_list;
  GstCaps *result = NULL;
  gint pos = 0;

  g_return_val_if_fail (GST_IS_OBJECT (obj), NULL);
  g_return_val_if_fail (func != NULL, NULL);

  helper.buffers = NULL;
  helper.size = size;
  helper.last_offset = 0;
  helper.func = func;
  helper.best_probability = GST_TYPE_FIND_NONE;
  helper.caps = NULL;
  helper.obj = obj;

  find.data = &helper;
  find.peek = helper_find_peek;
  find.suggest = helper_find_suggest;

  if (size == 0 || size == (guint64) - 1) {
    find.get_length = NULL;
  } else {
    find.get_length = helper_find_get_length;
  }

  type_list = gst_type_find_factory_get_list ();

  /* move the typefinders for the extension first in the list. The idea is that
   * when one of them returns MAX we don't need to search further as there is a
   * very high chance we got the right type. */
  if (extension) {
    GList *next;

    GST_LOG_OBJECT (obj, "sorting typefind for extension %s to head",
        extension);

    for (l = type_list; l; l = next) {
      GstTypeFindFactory *factory;
      gint i;
      gchar **ext;

      next = l->next;

      factory = GST_TYPE_FIND_FACTORY (l->data);

      ext = gst_type_find_factory_get_extensions (factory);
      if (ext == NULL)
        continue;

      GST_LOG_OBJECT (obj, "testing factory %s for extension %s",
          GST_PLUGIN_FEATURE_NAME (factory), extension);

      for (i = 0; ext[i]; i++) {
        if (strcmp (ext[i], extension) == 0) {
          /* found extension, move in front */
          GST_LOG_OBJECT (obj, "moving typefind for extension %s to head",
              extension);
          /* remove entry from list */
          type_list = g_list_delete_link (type_list, l);
          /* insert at the position */
          type_list = g_list_insert (type_list, factory, pos);
          /* next element will be inserted after this one */
          pos++;
          break;
        }
      }
    }
  }

  for (l = type_list; l; l = l->next) {
    helper.factory = GST_TYPE_FIND_FACTORY (l->data);
    gst_type_find_factory_call_function (helper.factory, &find);
    if (helper.best_probability >= GST_TYPE_FIND_MAXIMUM)
      break;
  }
  gst_plugin_feature_list_free (type_list);

  for (walk = helper.buffers; walk; walk = walk->next)
    gst_buffer_unref (GST_BUFFER_CAST (walk->data));
  g_slist_free (helper.buffers);

  if (helper.best_probability > 0)
    result = helper.caps;

  if (prob)
    *prob = helper.best_probability;

  GST_LOG_OBJECT (obj, "Returning %" GST_PTR_FORMAT " (probability = %u)",
      result, (guint) helper.best_probability);

  return result;
}
/*virtual*/ nsresult 
sbGStreamerMediacoreFactory::OnGetCapabilities(
                             sbIMediacoreCapabilities **aCapabilities)
{
  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
  nsAutoMonitor mon(mMonitor);

  // TODO: This function is now a _huge_ mess. We should talk to product about
  // what files we want to import / etc, some time soon - e.g. the current
  // approach is to treat anything even vaguely-plausibly audio-related as
  // audio (even if we can't play it!), but to only import a small list of fixed
  // extensions for videos (excluding many things we might be able to play).

  nsresult rv;
  if (!mCapabilities) {
    nsRefPtr<sbMediacoreCapabilities> caps;
    NS_NEWXPCOM(caps, sbMediacoreCapabilities);
    NS_ENSURE_TRUE(caps, NS_ERROR_OUT_OF_MEMORY);

    rv = caps->Init();
    NS_ENSURE_SUCCESS(rv, rv);

    // Build a big list of extensions based on everything gstreamer knows about,
    // plus some known ones, minus a few known non-media-file extensions that
    // gstreamer has typefinders for.

    nsCOMPtr<nsIPrefBranch> rootPrefBranch =
      do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    nsTArray<nsString> audioExtensions;
    nsTArray<nsString> videoExtensions;
    
    // XXX Mook: we have a silly list of blacklisted extensions because we don't
    // support them and we're being stupid and guessing things based on them.
    // This crap should really look for a plugin that may possibly actually decode
    // these things, or something better.  Whatever the real solution is, this
    // isn't it :(
    nsCString blacklistExtensions;
    { // for scope
      const char defaultBlacklistExtensions[] =
        "txt,htm,html,xml,pdf,cpl,msstyles,scr,sys,ocx,bz2,gz,zip,Z,rar,tar,dll,"
        "exe,a,bmp,png,gif,jpeg,jpg,jpe,tif,tiff,xpm,dat,swf,swfl,stm,cgi,sf,xcf,"
        "far,wvc,mpc,mpp,mp+,ra,rm,rmvb";
      char* blacklistExtensionsPtr = nsnull;
      rv = rootPrefBranch->GetCharPref(BLACKLIST_EXTENSIONS_PREF,
                                       &blacklistExtensionsPtr);
      if (NS_SUCCEEDED(rv)) {
        blacklistExtensions.Adopt(blacklistExtensionsPtr);
      } else {
        blacklistExtensions.Assign(defaultBlacklistExtensions);
      }
      blacklistExtensions.Insert(',', 0);
      blacklistExtensions.Append(',');
      LOG(("sbGStreamerMediacoreFactory: blacklisted extensions: %s\n",
           blacklistExtensions.BeginReading()));
    }

    const char *extraAudioExtensions[] = {"m4r", "m4p", "oga",
                                          "ogg", "aac", "3gp"};
#ifdef XP_WIN
    const char *extraWindowsAudioExtensions[] = {"wma" };
#endif

    { // for scope

      // Per bug 19550 -
      // Severly limit the video extensions that are imported by default to:
      //   * ogv (all platforms)
      //   * wmv (windows only)
      //   * mp4/m4v/mov (w/ qtvideowrapper plugin)
      //   * divx/avi/mkv (w/ ewmpeg4dec plugin)
      videoExtensions.AppendElement(NS_LITERAL_STRING("ogv"));
#ifdef XP_WIN
      videoExtensions.AppendElement(NS_LITERAL_STRING("wmv"));
#endif

      char* knownVideoExtensionsPtr = nsnull;
      rv = rootPrefBranch->GetCharPref(VIDEO_EXTENSIONS_PREF,
                                       &knownVideoExtensionsPtr);
      if (NS_SUCCEEDED(rv)) {
        // The override video extension pref contains a CSV string.
        nsString_Split(NS_ConvertUTF8toUTF16(knownVideoExtensionsPtr),
                       NS_LITERAL_STRING(","),
                       videoExtensions);
      }

#ifdef PR_LOGGING
      nsString videoExtensionStr;
      for (PRUint32 i = 0; i < videoExtensions.Length(); i++) {
        videoExtensionStr.Append(videoExtensions[i]);
        if (i < videoExtensions.Length() - 1) {
          videoExtensionStr.AppendLiteral(", ");
        }
      }

      LOG(("sbGStreamerMediacoreFactory: video file extensions: %s\n",
            videoExtensionStr.get()));
#endif

      // Check for the 'qtvideowrapper' plugin to add mp4/m4v extensions.
      PRBool foundQTPlugin = PR_FALSE;
      GstPlugin *plugin = gst_default_registry_find_plugin("qtvideowrapper");
      if (plugin) {
        foundQTPlugin = PR_TRUE;
        videoExtensions.AppendElement(NS_LITERAL_STRING("mp4"));
        videoExtensions.AppendElement(NS_LITERAL_STRING("m4v"));
        videoExtensions.AppendElement(NS_LITERAL_STRING("mov"));
        gst_object_unref(plugin);
      }

      // Check for the 'ewmpeg4dec' plugin to add divx/avi extensions.
      plugin = gst_default_registry_find_plugin("ewmpeg4dec");
      if (plugin) {
        videoExtensions.AppendElement(NS_LITERAL_STRING("divx"));
        videoExtensions.AppendElement(NS_LITERAL_STRING("avi"));
        videoExtensions.AppendElement(NS_LITERAL_STRING("mkv"));

        // This plugin will also handle "mp4" and "m4v", only append those
        // extensions if they haven't been added already.
        if (!foundQTPlugin) {
          videoExtensions.AppendElement(NS_LITERAL_STRING("mp4"));
          videoExtensions.AppendElement(NS_LITERAL_STRING("m4v"));
        }

        gst_object_unref(plugin);
      }
    }

    GList *walker, *list;

    list = gst_type_find_factory_get_list ();
    walker = list;
    while (walker) {
      GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (walker->data);
      gboolean blacklisted = FALSE;
      const gchar* factoryName = gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory));
      gboolean isAudioFactory = g_str_has_prefix(factoryName, "audio/");

      gchar **factoryexts = gst_type_find_factory_get_extensions (factory);
      if (factoryexts) {
        while (*factoryexts) {
          gboolean isAudioExtension = isAudioFactory;
          nsCString extension(*factoryexts);
          nsCString delimitedExtension(extension);
          delimitedExtension.Insert(',', 0);
          delimitedExtension.Append(',');
          
          blacklisted = (blacklistExtensions.Find(delimitedExtension) != -1);
          #if PR_LOGGING
            if (blacklisted) {
                LOG(("sbGStreamerMediacoreFactory: Ignoring extension '%s'", *factoryexts));
            }
          #endif /* PR_LOGGING */

          if (!blacklisted && isAudioExtension) {
            audioExtensions.AppendElement(NS_ConvertUTF8toUTF16(*factoryexts));
            LOG(("sbGStreamerMediacoreFactory: registering audio extension %s\n",
                  *factoryexts));
          }

          factoryexts++;
        }
      }
      walker = g_list_next (walker);
    }
    g_list_free (list);

    for (unsigned int i = 0; i < NS_ARRAY_LENGTH(extraAudioExtensions); i++) {
      nsString ext = NS_ConvertUTF8toUTF16(extraAudioExtensions[i]);
      if(!audioExtensions.Contains(ext))
        audioExtensions.AppendElement(ext);
    }

#if XP_WIN
    for (unsigned int i = 0; i < NS_ARRAY_LENGTH(extraWindowsAudioExtensions); i++) {
      nsString ext = NS_ConvertUTF8toUTF16(extraWindowsAudioExtensions[i]);
      if(!audioExtensions.Contains(ext))
        audioExtensions.AppendElement(ext);
    }
#endif

    rv = caps->SetAudioExtensions(audioExtensions);
    NS_ENSURE_SUCCESS(rv, rv);

    // Audio playback is always allowed.
    rv = caps->SetSupportsAudioPlayback(PR_TRUE);
    NS_ENSURE_SUCCESS(rv, rv);

    PRBool videoDisabled = PR_FALSE;
    rv = rootPrefBranch->GetBoolPref(
                                    "songbird.mediacore.gstreamer.disablevideo",
                                    &videoDisabled);
    NS_ENSURE_SUCCESS(rv, rv);
    if (!videoDisabled) {
      rv = caps->SetVideoExtensions(videoExtensions);
      NS_ENSURE_SUCCESS(rv, rv);

      rv = caps->SetSupportsVideoPlayback(PR_TRUE);
      NS_ENSURE_SUCCESS(rv, rv);
    }

    mCapabilities = caps;
  }

  rv = CallQueryInterface(mCapabilities.get(), aCapabilities);
  NS_ENSURE_SUCCESS(rv, rv);

  return NS_OK;
}
Ejemplo n.º 6
0
static void
print_element_list (gboolean print_all)
{
  int plugincount = 0, featurecount = 0, blacklistcount = 0;
  GList *plugins, *orig_plugins;

  orig_plugins = plugins = gst_registry_get_plugin_list (gst_registry_get ());
  while (plugins) {
    GList *features, *orig_features;
    GstPlugin *plugin;

    plugin = (GstPlugin *) (plugins->data);
    plugins = g_list_next (plugins);
    plugincount++;

    if (GST_OBJECT_FLAG_IS_SET (plugin, GST_PLUGIN_FLAG_BLACKLISTED)) {
      blacklistcount++;
      continue;
    }

    orig_features = features =
        gst_registry_get_feature_list_by_plugin (gst_registry_get (),
        gst_plugin_get_name (plugin));
    while (features) {
      GstPluginFeature *feature;

      if (G_UNLIKELY (features->data == NULL))
        goto next;
      feature = GST_PLUGIN_FEATURE (features->data);
      featurecount++;

      if (GST_IS_ELEMENT_FACTORY (feature)) {
        GstElementFactory *factory;

        factory = GST_ELEMENT_FACTORY (feature);
        if (print_all)
          print_element_info (factory, TRUE);
        else
          g_print ("%s:  %s: %s\n", gst_plugin_get_name (plugin),
              GST_OBJECT_NAME (factory),
              gst_element_factory_get_metadata (factory,
                  GST_ELEMENT_METADATA_LONGNAME));
      } else if (GST_IS_TYPE_FIND_FACTORY (feature)) {
        GstTypeFindFactory *factory;
        const gchar *const *extensions;

        factory = GST_TYPE_FIND_FACTORY (feature);
        if (!print_all)
          g_print ("%s: %s: ", gst_plugin_get_name (plugin),
              gst_plugin_feature_get_name (feature));

        extensions = gst_type_find_factory_get_extensions (factory);
        if (extensions != NULL) {
          guint i = 0;

          while (extensions[i]) {
            if (!print_all)
              g_print ("%s%s", i > 0 ? ", " : "", extensions[i]);
            i++;
          }
          if (!print_all)
            g_print ("\n");
        } else {
          if (!print_all)
            g_print ("no extensions\n");
        }
      } else {
        if (!print_all)
          n_print ("%s:  %s (%s)\n", gst_plugin_get_name (plugin),
              GST_OBJECT_NAME (feature), g_type_name (G_OBJECT_TYPE (feature)));
      }

    next:
      features = g_list_next (features);
    }

    gst_plugin_feature_list_free (orig_features);
  }

  gst_plugin_list_free (orig_plugins);

  g_print ("\n");
  g_print (_("Total count: "));
  g_print (ngettext ("%d plugin", "%d plugins", plugincount), plugincount);
  if (blacklistcount) {
    g_print (" (");
    g_print (ngettext ("%d blacklist entry", "%d blacklist entries",
            blacklistcount), blacklistcount);
    g_print (" not shown)");
  }
  g_print (", ");
  g_print (ngettext ("%d feature", "%d features", featurecount), featurecount);
  g_print ("\n");
}
Ejemplo n.º 7
0
static void
print_plugin_features (GstPlugin * plugin)
{
  GList *features, *origlist;
  gint num_features = 0;
  gint num_elements = 0;
  gint num_tracers = 0;
  gint num_typefinders = 0;
  gint num_devproviders = 0;
  gint num_other = 0;

  origlist = features =
      gst_registry_get_feature_list_by_plugin (gst_registry_get (),
      gst_plugin_get_name (plugin));

  while (features) {
    GstPluginFeature *feature;

    feature = GST_PLUGIN_FEATURE (features->data);

    if (GST_IS_ELEMENT_FACTORY (feature)) {
      GstElementFactory *factory;

      factory = GST_ELEMENT_FACTORY (feature);
      n_print ("  %s: %s\n", GST_OBJECT_NAME (factory),
          gst_element_factory_get_metadata (factory,
              GST_ELEMENT_METADATA_LONGNAME));
      num_elements++;
    } else if (GST_IS_TYPE_FIND_FACTORY (feature)) {
      GstTypeFindFactory *factory;
      const gchar *const *extensions;

      factory = GST_TYPE_FIND_FACTORY (feature);
      extensions = gst_type_find_factory_get_extensions (factory);
      if (extensions) {
        guint i = 0;

        g_print ("  %s: %s: ", gst_plugin_get_name (plugin),
            gst_plugin_feature_get_name (feature));
        while (extensions[i]) {
          g_print ("%s%s", i > 0 ? ", " : "", extensions[i]);
          i++;
        }
        g_print ("\n");
      } else
        g_print ("  %s: %s: no extensions\n", gst_plugin_get_name (plugin),
            gst_plugin_feature_get_name (feature));

      num_typefinders++;
    } else if (GST_IS_DEVICE_PROVIDER_FACTORY (feature)) {
      GstDeviceProviderFactory *factory;

      factory = GST_DEVICE_PROVIDER_FACTORY (feature);
      n_print ("  %s: %s\n", GST_OBJECT_NAME (factory),
          gst_device_provider_factory_get_metadata (factory,
              GST_ELEMENT_METADATA_LONGNAME));
      num_devproviders++;
    } else if (GST_IS_TRACER_FACTORY (feature)) {
      n_print ("  %s (%s)\n", gst_object_get_name (GST_OBJECT (feature)),
          g_type_name (G_OBJECT_TYPE (feature)));
      num_tracers++;
    } else if (feature) {
      n_print ("  %s (%s)\n", gst_object_get_name (GST_OBJECT (feature)),
          g_type_name (G_OBJECT_TYPE (feature)));
      num_other++;
    }
    num_features++;
    features = g_list_next (features);
  }

  gst_plugin_feature_list_free (origlist);

  n_print ("\n");
  n_print ("  %d features:\n", num_features);
  if (num_elements > 0)
    n_print ("  +-- %d elements\n", num_elements);
  if (num_typefinders > 0)
    n_print ("  +-- %d typefinders\n", num_typefinders);
  if (num_devproviders > 0)
    n_print ("  +-- %d device providers\n", num_devproviders);
  if (num_tracers > 0)
    n_print ("  +-- %d tracers\n", num_tracers);
  if (num_other > 0)
    n_print ("  +-- %d other objects\n", num_other);

  n_print ("\n");
}
Ejemplo n.º 8
0
// Obtains a list of supported extensions from typefind factories
// TODO: improve the list. It is obviously incomplete.
wxArrayString
GStreamerImportPlugin::GetSupportedExtensions()
{
   // We refresh the extensions each time this is called in case the
   // user had installed additional gstreamer plugins while Audacity
   // was active.
   mExtensions.Empty();

   // Gather extensions from all factories that support audio
   GList *factories = gst_type_find_factory_get_list();
   for (GList *list = factories; list != NULL; list = g_list_next(list))
   {
      GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY(list->data);

      // We need the capabilities to determine if it handles audio
      GstCaps *caps = gst_type_find_factory_get_caps(factory);
      if (!caps)
      {
         continue;
      }

      // Check each structure in the caps for audio
      for (guint c = 0, clen = gst_caps_get_size(caps); c < clen; c++)
      {
         // Bypass if it isn't for audio
         GstStructure *str = gst_caps_get_structure(caps, c);
         if (!g_str_has_prefix(gst_structure_get_name(str), "audio"))
         {
            continue;
         }

         // This factory can handle audio, so get the extensions
         const gchar *const *extensions = gst_type_find_factory_get_extensions(factory);
         if (!extensions)
         {
            continue;
         }

         // Add each extension to the list
         for (guint i = 0; extensions[i] != NULL; i++)
         {
            wxString extension = wxString::FromUTF8(extensions[i]);
            if (mExtensions.Index(extension.c_str(), false) == wxNOT_FOUND)
            {
               mExtensions.Add(extension);
            }
         }
      }
   }
   gst_plugin_feature_list_free(factories);

   // Get them in a decent order
   mExtensions.Sort();

   // Log it for debugging
   wxString extensions = wxT("Extensions:");
   for (size_t i = 0; i < mExtensions.GetCount(); i++)
   {
      extensions = extensions + wxT(" ") + mExtensions[i];
   }
   wxLogMessage(wxT("%s"), extensions.c_str());

   return mExtensions;
}