GST_END_TEST
GST_START_TEST (test_merge_modes)
{
  GstTagMergeMode mode;

  for (mode = GST_TAG_MERGE_REPLACE_ALL; mode < GST_TAG_MERGE_COUNT; mode++) {
    gint i;

    for (i = 0; i < 4; i++) {
      GstElement *enc;
      GstTagSetter *setter;
      GstTagList *list1, *list2, *merged;

      enc = g_object_new (GST_TYPE_DUMMY_ENC, NULL);
      fail_unless (enc != NULL);

      setter = GST_TAG_SETTER (enc);
      list1 = gst_tag_list_new_empty ();
      list2 = gst_tag_list_new_empty ();

      /* i = 0: -     -
       * i = 1: list1 -
       * i = 2: -     list2
       * i = 3: list1 list2 */

      if (i % 2 == 1) {
        gst_tag_list_add (list1, GST_TAG_MERGE_APPEND, GST_TAG_ARTIST,
            "artist1", NULL);
      }
      if (i > 1) {
        gst_tag_list_add (list2, GST_TAG_MERGE_APPEND, GST_TAG_ARTIST,
            "artist2", NULL);
      }

      gst_tag_setter_merge_tags (setter, list1, GST_TAG_MERGE_APPEND);
      gst_tag_setter_merge_tags (setter, list2, mode);

      merged = gst_tag_list_merge (list1, list2, mode);

      fail_unless_equals_int (tag_list_length (gst_tag_setter_get_tag_list
              (setter)), tag_list_length (merged));

      gst_tag_list_unref (list1);
      gst_tag_list_unref (list2);
      gst_tag_list_unref (merged);
      gst_object_unref (enc);
    }
  }
}
Beispiel #2
0
static gboolean
gst_opus_enc_sink_event (GstAudioEncoder * benc, GstEvent * event)
{
  GstOpusEnc *enc;

  enc = GST_OPUS_ENC (benc);

  GST_DEBUG_OBJECT (enc, "sink event: %s", GST_EVENT_TYPE_NAME (event));
  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_TAG:
    {
      GstTagList *list;
      GstTagSetter *setter = GST_TAG_SETTER (enc);
      const GstTagMergeMode mode = gst_tag_setter_get_tag_merge_mode (setter);

      gst_event_parse_tag (event, &list);
      gst_tag_setter_merge_tags (setter, list, mode);
      break;
    }
    default:
      break;
  }

  return FALSE;
}
static gboolean
gst_ffmpegmux_sink_event (GstPad * pad, GstEvent * event)
{
  GstFFMpegMux *ffmpegmux = (GstFFMpegMux *) gst_pad_get_parent (pad);
  gboolean res = TRUE;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_TAG:{
      GstTagList *taglist;
      GstTagSetter *setter = GST_TAG_SETTER (ffmpegmux);
      const GstTagMergeMode mode = gst_tag_setter_get_tag_merge_mode (setter);

      gst_event_parse_tag (event, &taglist);
      gst_tag_setter_merge_tags (setter, taglist, mode);
      break;
    }
    default:
      break;
  }

  /* chaining up to collectpads default event function */
  res = ffmpegmux->event_function (pad, event);

  gst_object_unref (ffmpegmux);
  return res;
}
Beispiel #4
0
static gboolean
gst_celt_enc_sink_event (GstAudioEncoder * benc, GstEvent * event)
{
  GstCeltEnc *enc;

  enc = GST_CELT_ENC (benc);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_TAG:
    {
      GstTagList *list;
      GstTagSetter *setter = GST_TAG_SETTER (enc);
      const GstTagMergeMode mode = gst_tag_setter_get_tag_merge_mode (setter);

      gst_event_parse_tag (event, &list);
      gst_tag_setter_merge_tags (setter, list, mode);
      break;
    }
    default:
      break;
  }

  /* we only peeked, let base class handle it */
  return FALSE;
}
Beispiel #5
0
static gboolean
gst_ffmpegmux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstFFMpegMux *ffmpegmux = (GstFFMpegMux *) parent;
  gboolean res = TRUE;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_TAG:{
      GstTagList *taglist;
      GstTagSetter *setter = GST_TAG_SETTER (ffmpegmux);
      const GstTagMergeMode mode = gst_tag_setter_get_tag_merge_mode (setter);

      gst_event_parse_tag (event, &taglist);
      gst_tag_setter_merge_tags (setter, taglist, mode);
      break;
    }
    case GST_EVENT_CAPS:{
      GstCaps *caps;
      gst_event_parse_caps (event, &caps);
      if (!(res = gst_ffmpegmux_setcaps (pad, caps)))
        goto beach;
      break;
    }
    default:
      break;
  }

  /* chaining up to collectpads default event function */
  res = ffmpegmux->event_function (pad, parent, event);

beach:
  return res;
}
Beispiel #6
0
/*
 * Method: merge(structure, merge_mode)
 * structure: a Ruby hash representing the tag list of merge from.
 * merge_mode: the mode to merge with (see Gst::Tag::MergeMode).
 *
 * Merges the given tag list in the setter's list using the given mode.
 *
 * Returns: self.
 */
static VALUE
rg_merge (VALUE self, VALUE structure, VALUE merge_mode)
{
    gst_tag_setter_merge_tags(RGST_TAG_SETTER(self),
                              RVAL2GST_STRUCT(structure),
                              RVAL2GENUM(merge_mode, GST_TYPE_TAG_MERGE_MODE));
    return self;
}
Beispiel #7
0
static gboolean rc_plugin_tag_vorbis_change(const gchar *src_path,
    const gchar *target_path, const GstTagList *tag_list)
{
    GstElement *tag_filesrc = NULL;
    GstElement *tag_filesink = NULL;
    GstElement *tag_demux = NULL;
    GstElement *tag_mux = NULL;
    GstElement *tagger = NULL;
    GstBus *bus = NULL;
    if(src_path==NULL) return FALSE;
    if(target_path==NULL) return FALSE;
    if(tag_list==NULL) return FALSE;
    if(g_access(src_path, W_OK)!=0) return FALSE;
    tagger = gst_element_factory_make("vorbistag", "vorbis-tagger");
    tag_demux = gst_element_factory_make("oggdemux", "ogg-demux");
    tag_mux = gst_element_factory_make("oggmux", "ogg-mux");
    if(tagger==NULL || tag_demux==NULL || tag_mux==NULL)
        goto error_out;
    tag_filesrc = gst_element_factory_make("filesrc", "tag-filesrc");
    if(tag_filesrc==NULL) goto error_out;
    tag_filesink = gst_element_factory_make("filesink", "tag-filesink");
    if(tag_filesink==NULL) goto error_out;
    g_object_set(G_OBJECT(tag_filesrc), "location", src_path, NULL);
    g_object_set(G_OBJECT(tag_filesink), "location", target_path, NULL);
    tagger_pipeline = gst_pipeline_new("tagger-pipeline");
    gst_tag_setter_merge_tags(GST_TAG_SETTER(tagger), tag_list,
        GST_TAG_MERGE_REPLACE);
    gst_bin_add_many(GST_BIN(tagger_pipeline), tag_filesrc,
        tag_demux, tagger, tag_mux, tag_filesink, NULL);
    g_signal_connect(tag_demux, "pad-added",
        G_CALLBACK(rc_plugin_tag_writer_pad_added_cb), tagger);
    if(!gst_element_link(tag_filesrc, tag_demux))
        goto error_out;
    if(!gst_element_link_many(tagger, tag_mux, tag_filesink,
        NULL))
        goto error_out;
    bus = gst_pipeline_get_bus(GST_PIPELINE(tagger_pipeline));
    gst_bus_add_watch(bus, (GstBusFunc)rc_plugin_tag_writer_bus_cb, NULL);
    gst_object_unref(bus);
    gst_element_set_state(tagger_pipeline, GST_STATE_NULL);
    gst_element_set_state(tagger_pipeline, GST_STATE_READY);
    if(gst_element_set_state(tagger_pipeline, GST_STATE_PLAYING)
        ==GST_STATE_CHANGE_FAILURE)
        goto error_out;
    return TRUE;
    error_out:
        if(tagger!=NULL) gst_object_unref(tagger);
        if(tag_demux!=NULL) gst_object_unref(tag_demux);
        if(tag_mux!=NULL) gst_object_unref(tag_mux);
        if(tag_filesrc!=NULL) gst_object_unref(tag_filesrc);
        if(tag_filesink!=NULL) gst_object_unref(tag_filesink);
        if(tagger_pipeline!=NULL) gst_object_unref(tagger_pipeline);
        tagger_pipeline = NULL;
        return FALSE;
}
Beispiel #8
0
/*
 * Creates a pipeline in the form:
 * fakesrc num-buffers=1 ! caps ! muxer ! filesink location=file
 *
 * And sets the tags in tag_str into the muxer via tagsetter.
 */
static void
test_mux_tags (const gchar * tag_str, const gchar * caps,
    const gchar * muxer, const gchar * file)
{
  GstElement *pipeline;
  GstBus *bus;
  GMainLoop *loop;
  GstTagList *sent_tags;
  GstElement *mux;
  GstTagSetter *setter;
  gchar *launch_str;
  guint bus_watch = 0;

  GST_DEBUG ("testing xmp muxing on : %s", muxer);

  launch_str = g_strdup_printf ("fakesrc num-buffers=1 format=time ! "
      "%s ! %s name=mux ! filesink location=%s name=sink", caps, muxer, file);
  pipeline = gst_parse_launch (launch_str, NULL);
  g_free (launch_str);
  fail_unless (pipeline != NULL);

  mux = gst_bin_get_by_name (GST_BIN (pipeline), "mux");
  fail_unless (mux != NULL);

  loop = g_main_loop_new (NULL, TRUE);
  fail_unless (loop != NULL);

  bus = gst_element_get_bus (pipeline);
  fail_unless (bus != NULL);
  bus_watch = gst_bus_add_watch (bus, bus_handler, loop);
  gst_object_unref (bus);

  gst_element_set_state (pipeline, GST_STATE_READY);

  setter = GST_TAG_SETTER (mux);
  fail_unless (setter != NULL);
  sent_tags = gst_tag_list_new_from_string (tag_str);
  fail_unless (sent_tags != NULL);
  gst_tag_setter_merge_tags (setter, sent_tags, GST_TAG_MERGE_REPLACE);
  gst_tag_list_free (sent_tags);

  gst_element_set_state (pipeline, GST_STATE_PLAYING);
  g_main_loop_run (loop);

  gst_element_set_state (pipeline, GST_STATE_NULL);

  g_main_loop_unref (loop);
  g_object_unref (mux);
  g_object_unref (pipeline);
  g_source_remove (bus_watch);
}
static gboolean
gst_vp8_enc_sink_event (GstBaseVideoEncoder * benc, GstEvent * event)
{
  GstVP8Enc *enc = GST_VP8_ENC (benc);

  if (GST_EVENT_TYPE (event) == GST_EVENT_TAG) {
    GstTagList *list;
    GstTagSetter *setter = GST_TAG_SETTER (enc);
    const GstTagMergeMode mode = gst_tag_setter_get_tag_merge_mode (setter);

    gst_event_parse_tag (event, &list);
    gst_tag_setter_merge_tags (setter, list, mode);
  }

  /* just peeked, baseclass handles the rest */
  return FALSE;
}
Beispiel #10
0
static gboolean
gst_vp8_enc_sink_event (GstPad * pad, GstEvent * event)
{
  GstVP8Enc *enc = GST_VP8_ENC (gst_pad_get_parent (pad));
  gboolean ret;

  if (GST_EVENT_TYPE (event) == GST_EVENT_TAG) {
    GstTagList *list;
    GstTagSetter *setter = GST_TAG_SETTER (enc);
    const GstTagMergeMode mode = gst_tag_setter_get_tag_merge_mode (setter);

    gst_event_parse_tag (event, &list);
    gst_tag_setter_merge_tags (setter, list, mode);
  }

  ret = enc->base_sink_event_func (pad, event);
  gst_object_unref (enc);

  return ret;
}
Beispiel #11
0
static gboolean
gst_jif_mux_sink_event (GstPad * pad, GstEvent * event)
{
    GstJifMux *self = GST_JIF_MUX (GST_PAD_PARENT (pad));
    gboolean ret;

    switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_TAG: {
        GstTagList *list;
        GstTagSetter *setter = GST_TAG_SETTER (self);
        const GstTagMergeMode mode = gst_tag_setter_get_tag_merge_mode (setter);

        gst_event_parse_tag (event, &list);

        gst_tag_setter_merge_tags (setter, list, mode);
        break;
    }
    default:
        break;
    }
    ret = gst_pad_event_default (pad, event);
    return ret;
}
Beispiel #12
0
static void
test_tags (const gchar * tag_str)
{
  GstElement *pipeline;
  GstBus *bus;
  GMainLoop *loop;
  GstTagList *sent_tags;
  gint i, j, n_recv, n_sent;
  const gchar *name_sent, *name_recv;
  const GValue *value_sent, *value_recv;
  gboolean found, ok;
  gint comparison;
  GstElement *videotestsrc, *jpegenc, *metadatamux, *metadatademux, *fakesink;
  GstTagSetter *setter;

  GST_DEBUG ("testing tags : %s", tag_str);

  if (received_tags) {
    gst_tag_list_free (received_tags);
    received_tags = NULL;
  }

  pipeline = gst_pipeline_new ("pipeline");
  fail_unless (pipeline != NULL);

  videotestsrc = gst_element_factory_make ("videotestsrc", "src");
  fail_unless (videotestsrc != NULL);
  g_object_set (G_OBJECT (videotestsrc), "num-buffers", 1, NULL);

  jpegenc = gst_element_factory_make ("jpegenc", "enc");
  if (jpegenc == NULL) {
    g_print ("Cannot test - jpegenc not available\n");
    return;
  }

  metadatamux = gst_element_factory_make ("metadatamux", "mux");
  g_object_set (G_OBJECT (metadatamux), "exif", TRUE, NULL);
  fail_unless (metadatamux != NULL);

  metadatademux = gst_element_factory_make ("metadatademux", "demux");
  fail_unless (metadatademux != NULL);

  fakesink = gst_element_factory_make ("fakesink", "sink");
  fail_unless (fakesink != NULL);

  gst_bin_add_many (GST_BIN (pipeline), videotestsrc, jpegenc, metadatamux,
      metadatademux, fakesink, NULL);

  ok = gst_element_link_many (videotestsrc, jpegenc, metadatamux, metadatademux,
      fakesink, NULL);
  fail_unless (ok == TRUE);

  loop = g_main_loop_new (NULL, TRUE);
  fail_unless (loop != NULL);

  bus = gst_element_get_bus (pipeline);
  fail_unless (bus != NULL);
  gst_bus_add_watch (bus, bus_handler, loop);
  gst_object_unref (bus);

  gst_element_set_state (pipeline, GST_STATE_READY);

  setter = GST_TAG_SETTER (metadatamux);
  fail_unless (setter != NULL);
  sent_tags = gst_structure_from_string (tag_str, NULL);
  fail_unless (sent_tags != NULL);
  gst_tag_setter_merge_tags (setter, sent_tags, GST_TAG_MERGE_REPLACE);

  gst_element_set_state (pipeline, GST_STATE_PLAYING);
  g_main_loop_run (loop);

  GST_DEBUG ("mainloop done : %p", received_tags);

  /* verify tags */
  fail_unless (received_tags != NULL);
  n_recv = gst_structure_n_fields (received_tags);
  n_sent = gst_structure_n_fields (sent_tags);
  /* we also get e.g. an exif binary block */
  fail_unless (n_recv >= n_sent);
  /* FIXME: compare taglits values */
  for (i = 0; i < n_sent; i++) {
    name_sent = gst_structure_nth_field_name (sent_tags, i);
    value_sent = gst_structure_get_value (sent_tags, name_sent);
    found = FALSE;
    for (j = 0; j < n_recv; j++) {
      name_recv = gst_structure_nth_field_name (received_tags, j);
      if (!strcmp (name_sent, name_recv)) {
        value_recv = gst_structure_get_value (received_tags, name_recv);
        comparison = gst_value_compare (value_sent, value_recv);
        if (comparison != GST_VALUE_EQUAL) {
          gchar *vs = g_strdup_value_contents (value_sent);
          gchar *vr = g_strdup_value_contents (value_recv);
          GST_DEBUG ("sent = %s:'%s', recv = %s:'%s'",
              G_VALUE_TYPE_NAME (value_sent), vs,
              G_VALUE_TYPE_NAME (value_recv), vr);
          g_free (vs);
          g_free (vr);
        }
        fail_unless (comparison == GST_VALUE_EQUAL,
            "tag item %s has been received with different type or value",
            name_sent);
        found = TRUE;
        break;
      }
    }
    fail_unless (found, "tag item %s is lost", name_sent);
  }

  gst_tag_list_free (received_tags);
  received_tags = NULL;
  gst_tag_list_free (sent_tags);

  gst_element_set_state (pipeline, GST_STATE_NULL);

  g_main_loop_unref (loop);
  g_object_unref (pipeline);
}
Beispiel #13
0
static void
test_taglib_id3mux_with_tags (GstTagList * tags, guint32 mask)
{
    GstMessage *msg;
    GstTagList *tags_read = NULL;
    GstElement *pipeline, *id3mux, *id3demux, *fakesrc, *identity, *fakesink;
    GstBus *bus;
    guint64 offset;
    GstBuffer *outbuf = NULL;
    GstBuffer *tagbuf = NULL;
    GstStateChangeReturn state_result;

    pipeline = gst_pipeline_new ("pipeline");
    g_assert (pipeline != NULL);

    fakesrc = gst_element_factory_make ("fakesrc", "fakesrc");
    g_assert (fakesrc != NULL);

    id3mux = gst_element_factory_make ("id3v2mux", "id3v2mux");
    g_assert (id3mux != NULL);

    identity = gst_element_factory_make ("identity", "identity");
    g_assert (identity != NULL);

    id3demux = gst_element_factory_make ("id3demux", "id3demux");
    g_assert (id3demux != NULL);

    fakesink = gst_element_factory_make ("fakesink", "fakesink");
    g_assert (fakesink != NULL);

    /* set up sink */
    outbuf = NULL;
    g_object_set (fakesink, "signal-handoffs", TRUE, NULL);
    g_signal_connect (fakesink, "handoff", G_CALLBACK (got_buffer), &outbuf);

    gst_bin_add (GST_BIN (pipeline), fakesrc);
    gst_bin_add (GST_BIN (pipeline), id3mux);
    gst_bin_add (GST_BIN (pipeline), identity);
    gst_bin_add (GST_BIN (pipeline), id3demux);
    gst_bin_add (GST_BIN (pipeline), fakesink);

    gst_tag_setter_merge_tags (GST_TAG_SETTER (id3mux), tags,
                               GST_TAG_MERGE_APPEND);

    gst_element_link_many (fakesrc, id3mux, identity, id3demux, fakesink, NULL);

    /* set up source */
    g_object_set (fakesrc, "signal-handoffs", TRUE, "can-activate-pull", FALSE,
                  "filltype", 2, "sizetype", 2, "sizemax", MP3_FRAME_SIZE,
                  "num-buffers", 16, NULL);

    offset = 0;
    g_signal_connect (fakesrc, "handoff", G_CALLBACK (fill_mp3_buffer), &offset);

    /* set up identity to catch tag buffer */
    g_signal_connect (identity, "handoff", G_CALLBACK (identity_cb), &tagbuf);

    GST_LOG ("setting and getting state ...");
    gst_element_set_state (pipeline, GST_STATE_PLAYING);
    state_result = gst_element_get_state (pipeline, NULL, NULL, -1);
    fail_unless (state_result == GST_STATE_CHANGE_SUCCESS,
                 "Unexpected result from get_state(). Expected success, got %d",
                 state_result);

    bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));

    GST_LOG ("Waiting for tag ...");
    msg =
        gst_bus_poll (bus, GST_MESSAGE_TAG | GST_MESSAGE_EOS | GST_MESSAGE_ERROR,
                      -1);
    if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) {
        GError *err;
        gchar *dbg;

        gst_message_parse_error (msg, &err, &dbg);
        g_printerr ("ERROR from element %s: %s\n%s\n",
                    GST_OBJECT_NAME (msg->src), err->message, GST_STR_NULL (dbg));
        g_error_free (err);
        g_free (dbg);
    } else if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_EOS) {
        g_printerr ("EOS message, but were waiting for TAGS!\n");
    }
    fail_unless (msg->type == GST_MESSAGE_TAG);

    gst_message_parse_tag (msg, &tags_read);
    gst_message_unref (msg);

    GST_LOG ("Got tags: %" GST_PTR_FORMAT, tags_read);
    test_taglib_id3mux_check_tags (tags_read, mask);
    gst_tag_list_unref (tags_read);

    fail_unless (tagbuf != NULL);
    test_taglib_id3mux_check_tag_buffer (tagbuf, mask);
    gst_buffer_unref (tagbuf);

    GST_LOG ("Waiting for EOS ...");
    msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1);
    if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) {
        GError *err;
        gchar *dbg;

        gst_message_parse_error (msg, &err, &dbg);
        g_printerr ("ERROR from element %s: %s\n%s\n",
                    GST_OBJECT_NAME (msg->src), err->message, GST_STR_NULL (dbg));
        g_error_free (err);
        g_free (dbg);
    }
    fail_unless (msg->type == GST_MESSAGE_EOS);
    gst_message_unref (msg);

    gst_object_unref (bus);

    GST_LOG ("Got EOS, shutting down ...");
    gst_element_set_state (pipeline, GST_STATE_NULL);
    gst_object_unref (pipeline);

    test_taglib_id3mux_check_output_buffer (outbuf);
    gst_buffer_unref (outbuf);

    GST_LOG ("Done");
}