Example #1
0
/**
 * Link a pad internally
 *
 * @self: The #KmsAgnosticBin2 owner of the pad
 * @pad: (transfer full): The pad to be linked
 * @peer: (transfer full): The peer pad
 */
static void
kms_agnostic_bin2_link_pad (KmsAgnosticBin2 * self, GstPad * pad, GstPad * peer)
{
  GstCaps *caps;
  GstBin *bin;

  GST_INFO_OBJECT (self, "Linking: %" GST_PTR_FORMAT, pad);

  caps = gst_pad_query_caps (peer, NULL);

  if (caps == NULL) {
    goto end;
  }

  GST_DEBUG ("Query caps are: %" GST_PTR_FORMAT, caps);
  bin = kms_agnostic_bin2_find_bin_for_caps (self, caps);

  if (bin == NULL) {
    bin = kms_agnostic_bin2_create_bin_for_caps (self, caps);
    GST_DEBUG_OBJECT (self, "Created bin: %" GST_PTR_FORMAT, bin);
  }

  if (bin != NULL) {
    GstElement *tee = kms_tree_bin_get_output_tee (KMS_TREE_BIN (bin));

    kms_utils_drop_until_keyframe (pad, TRUE);
    kms_agnostic_bin2_link_to_tee (self, pad, tee, caps);
  }

  gst_caps_unref (caps);

end:
  g_object_unref (peer);
}
Example #2
0
static gboolean
kms_rtp_pay_tree_bin_configure (KmsRtpPayTreeBin * self, const GstCaps * caps)
{
  KmsTreeBin *tree_bin = KMS_TREE_BIN (self);
  GstElement *pay, *output_tee;
  GstPad *pad;

  pay = create_payloader_for_caps (caps);
  if (pay == NULL) {
    GST_WARNING_OBJECT (self, "Cannot find payloader for caps %" GST_PTR_FORMAT,
        caps);
    return FALSE;
  }
  GST_DEBUG_OBJECT (self, "Payloader found: %" GST_PTR_FORMAT, pay);

  pad = gst_element_get_static_pad (pay, "sink");
  kms_utils_drop_until_keyframe (pad, TRUE);
  gst_object_unref (pad);

  gst_bin_add (GST_BIN (self), pay);
  gst_element_sync_state_with_parent (pay);

  kms_tree_bin_set_input_element (tree_bin, pay);
  output_tee = kms_tree_bin_get_output_tee (tree_bin);
  gst_element_link (pay, output_tee);

  return TRUE;
}
Example #3
0
static GstPadProbeReturn
tee_src_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
  if (GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_EVENT_UPSTREAM) {
    GstEvent *event = gst_pad_probe_info_get_event (info);

    if (GST_EVENT_TYPE (event) == GST_EVENT_RECONFIGURE) {
      // Request key frame to upstream elements
      kms_utils_drop_until_keyframe (pad, TRUE);
      return GST_PAD_PROBE_DROP;
    }
  }

  return GST_PAD_PROBE_OK;
}
Example #4
0
static GstPadProbeReturn
discont_detection_probe (GstPad * pad, GstPadProbeInfo * info, gpointer data)
{
  GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER (info);

  if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) {
    if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT)) {
      GST_WARNING_OBJECT (pad, "Discont detected");
      kms_utils_drop_until_keyframe (pad, FALSE);

      return GST_PAD_PROBE_DROP;
    }
  }

  return GST_PAD_PROBE_OK;
}
Example #5
0
GstPad *
kms_element_connect_sink_target_full (KmsElement * self, GstPad * target,
    KmsElementPadType type, const gchar * description)
{
  GstPad *pad;
  gchar *pad_name;
  GstPadTemplate *templ;

  templ = gst_static_pad_template_get (&sink_factory);

  pad_name = get_pad_name (type, description);

  pad = gst_ghost_pad_new_from_template (pad_name, target, templ);
  g_free (pad_name);
  g_object_unref (templ);

  if (type == KMS_ELEMENT_PAD_TYPE_VIDEO) {
    kms_utils_drop_until_keyframe (pad, TRUE);
    kms_utils_manage_gaps (pad);
  }

  gst_pad_set_query_function (pad, kms_element_pad_query);
  gst_pad_add_probe (pad,
      GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | GST_PAD_PROBE_TYPE_EVENT_FLUSH,
      accept_eos_probe, self, NULL);
  g_signal_connect (G_OBJECT (pad), "unlinked",
      G_CALLBACK (send_flush_on_unlink), NULL);

  if (GST_STATE (self) >= GST_STATE_PAUSED
      || GST_STATE_PENDING (self) >= GST_STATE_PAUSED
      || GST_STATE_TARGET (self) >= GST_STATE_PAUSED) {
    gst_pad_set_active (pad, TRUE);
  }

  if (gst_element_add_pad (GST_ELEMENT (self), pad)) {
    kms_element_set_sink_input_stats (self, pad, type);
    return pad;
  }

  g_object_unref (pad);

  return NULL;
}