示例#1
0
static GstElement *
gst_switch_select (GstSwitch * swit,
    GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
{
  GList *item = GST_BIN_CHILDREN (GST_BIN (swit));
  GstElement *swcase = NULL;

  for (; item; item = g_list_next (item)) {
    GList *paditem = GST_ELEMENT_PADS (GST_ELEMENT (item->data));
    GstPad *basepad = NULL, *pad = NULL;
    for (; paditem; paditem = g_list_next (paditem)) {
      pad = GST_PAD (paditem->data);
      if (GST_PAD_IS_SINK (pad) && !gst_pad_is_linked (pad) &&
          !GST_OBJECT_FLAG_IS_SET (GST_OBJECT (pad),
              GST_SWITCH_PAD_FLAG_GHOSTED)) {
        basepad = pad;
        break;
      }
    }

    if (basepad) {
      swcase = GST_ELEMENT (item->data);
      break;
    }
  }

  if (!swcase) {
    swcase = gst_switch_request_new_case (swit, templ, caps);
  }

  return swcase;
}
示例#2
0
/*
 * Method: get_child(index)
 * Method: get_child(name, recurse=false)
 * Method: get_child(interface)
 * index: an index.
 * name: a name.
 * recurse: search recursively.
 * interface: an interface (Ruby class).
 *
 * 1st: Gets the index-th element.
 *
 * 2nd: Gets the element with the given name from the
 * bin, as a reference to a Gst::Element object. If the
 * element is not found and recurse is true, a recursion is
 * performed on the parent bin.
 *
 * 3nd: Looks for the first element inside the bin that implements the
 * given interface. If such an element is found, it returns the element.
 * If you want all elements that implement the interface, use
 * Gst::Bin#get_all_by_interface. The method recurses bins inside bins.
 *
 * Returns: a Gst::Element reference, or nil if the bin does not contain
 * an element with the given name nor implementing the interface.
 */
static VALUE
rb_gst_bin_get(int argc, VALUE *argv, VALUE self)
{
    VALUE index_or_name_or_interface, recurse;
    GstElement *element = NULL;

    rb_scan_args(argc, argv, "11", &index_or_name_or_interface, &recurse);

    if (RVAL2CBOOL(rb_obj_is_kind_of(index_or_name_or_interface, rb_cInteger))) {
        int index;
        GList *node;
        index = NUM2INT(index_or_name_or_interface);
        node = g_list_nth(GST_BIN_CHILDREN(SELF(self)), index);
        if (node)
            element = node->data;
    } else if (RVAL2CBOOL(rb_obj_is_kind_of(index_or_name_or_interface,
                                            rb_cString))) {
        char *name;
        name = RVAL2CSTR(index_or_name_or_interface);

        if (RVAL2CBOOL(recurse)) {
            element = gst_bin_get_by_name_recurse_up(SELF(self), name);
        } else {
            element = gst_bin_get_by_name(SELF(self), name);
        }
    } else {
        GType iface;
        iface = CLASS2GTYPE(index_or_name_or_interface);
        element = gst_bin_get_by_interface(SELF(self), iface);
    }

    return GST_ELEMENT2RVAL(element);
}
示例#3
0
/*
 * Method: clear
 *
 * Removes all Gst::Element objects in the bin.
 *
 * Returns: nil.
 */
static VALUE
rb_gst_bin_clear(VALUE self)
{
    GstBin *bin;
    GList *node, *children;

    bin = SELF(self);
    children = g_list_copy(GST_BIN_CHILDREN(bin));
    for (node = children; node; node = g_list_next(node)) {
        gst_bin_remove(bin, node->data);
    }
    g_list_free(children);
    return Qnil;
}
示例#4
0
GstElement *
GstUtils::get_first_element_from_factory_name(GstBin *bin,
                                              const std::string &factory_name) {
  if (!GST_IS_BIN(bin)) {
    g_warning("%s: first argument is not a bin", __FUNCTION__);
    return nullptr;
  }

  if (g_list_length(GST_BIN_CHILDREN(bin)) == 0) {
    g_warning("%s: bin has no child", __FUNCTION__);
    return nullptr;
  }

  GList *child = nullptr, *children = GST_BIN_CHILDREN(GST_BIN(bin));
  for (child = children; child != nullptr; child = g_list_next(child)) {
    GstElement *current_element = GST_ELEMENT(child->data);
    GstElementFactory *factory = gst_element_get_factory(current_element);
    if (factory_name == gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory))) {
      return current_element;
    }
  }
  g_warning("%s: no element found for %s", __FUNCTION__, factory_name.c_str());
  return nullptr;
}
示例#5
0
void
GstUtils::set_element_property_in_bin(GstElement *bin,
                                      const gchar *factory_name,
                                      const gchar *property_name,
                                      gboolean property_value) {
  if (!GST_IS_BIN(bin))
    return;

  if (g_list_length(GST_BIN_CHILDREN(GST_BIN(bin))) > 0) {
    GList *child = nullptr, *children = GST_BIN_CHILDREN(GST_BIN(bin));
    for (child = children; child != nullptr; child = g_list_next(child)) {
      GstElement *current_element = GST_ELEMENT(child->data);
      GstElementFactory *factory = gst_element_get_factory(current_element);
      // g_print ("The '%s' element is a member of the category %s.\n"
      //  "Description: %s\n",
      //  gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (sub_factory)),
      //  gst_element_factory_get_klass (sub_factory),
      //  gst_element_factory_get_description (sub_factory));
      if (g_strcmp0(factory_name,
                    gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory)))
          == 0) {
        g_debug("GstUtils: setting property for %s", factory_name);
        g_object_set(G_OBJECT(current_element), property_name,
                     property_value, nullptr);
      }

      if (GST_IS_BIN(current_element)) {  // recursive
        GstUtils::set_element_property_in_bin(current_element,
                                              factory_name,
                                              property_name,
                                              property_value);
      }
      
    }
  }
}
示例#6
0
static GstElement *
get_sink_element (GstBin * bin)
{
  GstElement *e;
  GList *node;

  GST_INFO_OBJECT (bin, "looking for audio_sink");
  for (node = GST_BIN_CHILDREN (bin); node; node = g_list_next (node)) {
    e = (GstElement *) node->data;
    if (GST_IS_BIN (e) && GST_OBJECT_FLAG_IS_SET (e, GST_ELEMENT_FLAG_SINK)) {
      return get_sink_element ((GstBin *) e);
    }
    if (GST_OBJECT_FLAG_IS_SET (e, GST_ELEMENT_FLAG_SINK)) {
      return e;
    }
  }
  return NULL;
}
示例#7
0
/*
 * Method: children(interface=nil)
 * interface: an interface (Ruby class).
 *
 * Returns: If interface is nil, an array of all
 * Gst::Element objects in the container. Otherwise, an
 * array of Gst::Element objects in the container that
 * implements the interface.
 */
static VALUE
rb_gst_bin_get_children(int argc, VALUE *argv, VALUE self)
{
    VALUE children, iface;

    rb_scan_args(argc, argv, "01", &iface);

    if (NIL_P(iface)) {
        const GList *node;
        children = rb_ary_new();
        for (node = GST_BIN_CHILDREN(SELF(self));
                node;
                node = g_list_next(node)) {
            rb_ary_push(children, GST_ELEMENT2RVAL(node->data));
        }
    } else {
        GstIterator *iter;
        iter = gst_bin_iterate_all_by_interface(SELF(self),
                                                CLASS2GTYPE(iface));
        children = _rbgst_collect_elements(iter);
    }

    return children;
}
示例#8
0
/**
 * bt_edit_application_load_song:
 * @self: the application instance to load a new song in
 * @file_name: the song filename to load
 * @err: where to store the error message in case of an error, or %NULL
 *
 * Loads a new song. If there is a previous song instance it will be freed.
 *
 * Returns: true for success
 */
gboolean
bt_edit_application_load_song (const BtEditApplication * self,
    const char *file_name, GError ** err)
{
  gboolean res = FALSE;
  BtSongIO *loader;
  BtSong *song;

  g_return_val_if_fail (BT_IS_EDIT_APPLICATION (self), FALSE);

  GST_INFO ("song name = %s", file_name);

  if ((loader = bt_song_io_from_file (file_name, err))) {
    BtSetup *setup;
    GList *missing_machines, *missing_waves;

    bt_edit_application_ui_lock (self);
    g_signal_connect (loader, "notify::status",
        G_CALLBACK (on_songio_status_changed), (gpointer) self);

    // create new song and release the previous one
    song = bt_song_new (BT_APPLICATION (self));
    g_object_set ((gpointer) self, "song", NULL, NULL);

#ifdef USE_DEBUG
    // do sanity check that bin is empty
    {
      GstBin *bin;
      g_object_get ((gpointer) self, "bin", &bin, NULL);

      if (GST_BIN_NUMCHILDREN (bin)) {
        GList *node = GST_BIN_CHILDREN (bin);
        GST_WARNING ("bin.num_children=%d has left-overs",
            GST_BIN_NUMCHILDREN (bin));

        while (node) {
          GST_WARNING_OBJECT (node->data, "removing object %"
              G_OBJECT_REF_COUNT_FMT, G_OBJECT_LOG_REF_COUNT (node->data));
          gst_bin_remove (bin, GST_ELEMENT (node->data));
          node = GST_BIN_CHILDREN (bin);
        }
      }
      gst_object_unref (bin);
    }
#endif

    // this is synchronous execution
    // https://github.com/Buzztrax/buzztrax/issues/52
    // if we bump glib from 2.32 -> 2.36 we can use GTask and
    // g_task_run_in_thread()
    if (bt_song_io_load (loader, song, err)) {
      BtMachine *machine;

      // get sink-machine
      g_object_get (song, "setup", &setup, NULL);
      if ((machine =
              bt_setup_get_machine_by_type (setup, BT_TYPE_SINK_MACHINE))) {
        if (bt_machine_enable_input_post_level (machine)) {
          // DEBUG
          //bt_song_write_to_highlevel_dot_file(song);
          // DEBUG
          // set new song
          g_object_set ((gpointer) self, "song", song, NULL);
          res = TRUE;
          GST_INFO ("new song activated");
        } else {
          GST_WARNING ("Can't add input level/gain element in sink machine");
        }
        GST_DEBUG ("unreffing stuff after loading");
        g_object_unref (machine);
      } else {
        GST_WARNING ("Can't look up sink machine");
      }
      g_object_unref (setup);
    } else {
      GST_WARNING ("could not load song \"%s\"", file_name);
    }
    self->priv->unsaved = FALSE;
    g_object_notify (G_OBJECT (self), "unsaved");

    bt_edit_application_ui_unlock (self);

    // get missing element info
    bt_child_proxy_get (song, "setup::missing-machines", &missing_machines,
        "wavetable::missing-waves", &missing_waves, NULL);
    // tell about missing machines and/or missing waves
    if (missing_machines || missing_waves) {
      GtkWidget *dialog;

      if ((dialog =
              GTK_WIDGET (bt_missing_song_elements_dialog_new (missing_machines,
                      missing_waves)))) {
        bt_edit_application_attach_child_window (self, GTK_WINDOW (dialog));
        gtk_widget_show_all (dialog);

        gtk_dialog_run (GTK_DIALOG (dialog));
        gtk_widget_destroy (dialog);
      }
    }
    g_object_unref (song);
    g_object_unref (loader);
  } else {
    GST_WARNING ("Unknown extension \"%s\"", file_name);
  }
  return res;
}
gchar *
ges_effect_assect_id_get_type_and_bindesc (const char *id,
    GESTrackType * track_type, GError ** error)
{
  GList *tmp;
  GstElement *effect;
  gchar **typebin_desc = NULL;
  gchar *bindesc = NULL;

  *track_type = GES_TRACK_TYPE_UNKNOWN;
  typebin_desc = g_strsplit (id, " ", 2);
  if (!g_strcmp0 (typebin_desc[0], "audio")) {
    *track_type = GES_TRACK_TYPE_AUDIO;
    bindesc = g_strdup (typebin_desc[1]);
  } else if (!g_strcmp0 (typebin_desc[0], "video")) {
    *track_type = GES_TRACK_TYPE_VIDEO;
    bindesc = g_strdup (typebin_desc[1]);
  } else {
    bindesc = g_strdup (id);
  }

  g_strfreev (typebin_desc);

  effect = gst_parse_bin_from_description (bindesc, TRUE, error);
  if (effect == NULL) {
    g_free (bindesc);

    GST_ERROR ("Could not create element from: %s", id);

    return NULL;
  }

  if (*track_type != GES_TRACK_TYPE_UNKNOWN) {
    gst_object_unref (effect);

    return bindesc;
  }

  for (tmp = GST_BIN_CHILDREN (effect); tmp; tmp = tmp->next) {
    GstElementFactory *factory =
        gst_element_get_factory (GST_ELEMENT (tmp->data));
    const gchar *klass =
        gst_element_factory_get_metadata (factory, GST_ELEMENT_METADATA_KLASS);

    if (g_strrstr (klass, "Effect")) {
      if (g_strrstr (klass, "Audio")) {
        *track_type = GES_TRACK_TYPE_AUDIO;
        break;
      } else if (g_strrstr (klass, "Video")) {
        *track_type = GES_TRACK_TYPE_VIDEO;
        break;
      }
    }
  }

  gst_object_unref (effect);

  if (*track_type == GES_TRACK_TYPE_UNKNOWN) {
    *track_type = GES_TRACK_TYPE_VIDEO;
    GST_ERROR ("Could not determine track type for %s, defaulting to video",
        id);
  }

  return bindesc;
}