Пример #1
0
static void
kms_agnostic_bin2_dispose (GObject * object)
{
  KmsAgnosticBin2 *self = KMS_AGNOSTIC_BIN2 (object);

  GST_DEBUG_OBJECT (object, "dispose");

  KMS_AGNOSTIC_BIN2_LOCK (self);
  g_thread_pool_free (self->priv->remove_pool, FALSE, FALSE);

  if (self->priv->input_bin_src_caps) {
    gst_caps_unref (self->priv->input_bin_src_caps);
    self->priv->input_bin_src_caps = NULL;
  }

  if (self->priv->input_caps) {
    gst_caps_unref (self->priv->input_caps);
    self->priv->input_caps = NULL;
  }

  KMS_AGNOSTIC_BIN2_UNLOCK (self);

  /* chain up */
  G_OBJECT_CLASS (kms_agnostic_bin2_parent_class)->dispose (object);
}
Пример #2
0
static GstPadProbeReturn
kms_agnostic_bin2_src_reconfigure_probe (GstPad * pad, GstPadProbeInfo * info,
    gpointer user_data)
{
  KmsAgnosticBin2 *self = KMS_AGNOSTIC_BIN2 (gst_pad_get_parent_element (pad));
  GstPadProbeReturn ret = GST_PAD_PROBE_OK;
  GstEvent *event;

  if (self == NULL) {
    return GST_PAD_PROBE_OK;
  }

  if (GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_EVENT_BOTH) {
    event = gst_pad_probe_info_get_event (info);

    if (GST_EVENT_TYPE (event) == GST_EVENT_RECONFIGURE) {
      KmsAgnosticBin2 *self = user_data;

      GST_DEBUG_OBJECT (pad, "Received reconfigure event");

      KMS_AGNOSTIC_BIN2_LOCK (self);
      kms_agnostic_bin2_process_pad (self, pad);
      ret = GST_PAD_PROBE_DROP;
      KMS_AGNOSTIC_BIN2_UNLOCK (self);

      goto end;
    }
  }

end:
  g_object_unref (self);

  return ret;
}
Пример #3
0
static GstPad *
kms_agnostic_bin2_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
{
  GstPad *pad;
  gchar *pad_name;
  KmsAgnosticBin2 *self = KMS_AGNOSTIC_BIN2 (element);

  GST_OBJECT_LOCK (self);
  pad_name = g_strdup_printf ("src_%d", self->priv->pad_count++);
  GST_OBJECT_UNLOCK (self);

  pad = gst_ghost_pad_new_no_target_from_template (pad_name, templ);
  g_free (pad_name);

  gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_UPSTREAM,
      kms_agnostic_bin2_src_reconfigure_probe, element, NULL);

  g_signal_connect (pad, "unlinked",
      G_CALLBACK (kms_agnostic_bin2_src_unlinked), self);

  gst_pad_set_active (pad, TRUE);

  if (gst_element_add_pad (element, pad)) {
    return pad;
  }

  g_object_unref (pad);

  return NULL;
}
Пример #4
0
void
kms_agnostic_bin2_get_property (GObject * object, guint property_id,
    GValue * value, GParamSpec * pspec)
{
  KmsAgnosticBin2 *self = KMS_AGNOSTIC_BIN2 (object);

  switch (property_id) {
    case PROP_MIN_BITRATE:
      KMS_AGNOSTIC_BIN2_LOCK (self);
      g_value_set_int (value, self->priv->min_bitrate);
      KMS_AGNOSTIC_BIN2_UNLOCK (self);
      break;
    case PROP_MAX_BITRATE:
      KMS_AGNOSTIC_BIN2_LOCK (self);
      g_value_set_int (value, self->priv->max_bitrate);
      KMS_AGNOSTIC_BIN2_UNLOCK (self);
      break;
    case PROP_CODEC_CONFIG:
      KMS_AGNOSTIC_BIN2_LOCK (self);
      g_value_set_boxed (value, self->priv->codec_config);
      KMS_AGNOSTIC_BIN2_UNLOCK (self);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}
Пример #5
0
static GstPadProbeReturn
kms_agnostic_bin2_sink_caps_probe (GstPad * pad, GstPadProbeInfo * info,
    gpointer user_data)
{
  KmsAgnosticBin2 *self;
  GstCaps *current_caps;
  GstCaps *new_caps = NULL;
  GstEvent *event = gst_pad_probe_info_get_event (info);

  if (GST_EVENT_TYPE (event) != GST_EVENT_CAPS) {
    return GST_PAD_PROBE_OK;
  }

  GST_TRACE_OBJECT (pad, "Event: %" GST_PTR_FORMAT, event);

  self = KMS_AGNOSTIC_BIN2 (user_data);

  gst_event_parse_caps (event, &new_caps);

  if (new_caps == NULL) {
    GST_ERROR_OBJECT (self, "Unexpected NULL caps");
    return GST_PAD_PROBE_OK;
  }

  KMS_AGNOSTIC_BIN2_LOCK (self);
  current_caps = self->priv->input_caps;
  self->priv->input_caps = gst_caps_copy (new_caps);
  KMS_AGNOSTIC_BIN2_UNLOCK (self);

  GST_TRACE_OBJECT (user_data, "New caps event: %" GST_PTR_FORMAT, event);

  if (current_caps != NULL) {
    GstStructure *st;

    GST_TRACE_OBJECT (user_data, "Current caps: %" GST_PTR_FORMAT,
        current_caps);

    st = gst_caps_get_structure (current_caps, 0);
    // Remove famerate, width, height, streamheader that make unecessary
    // agnostic reconstruction happen

    gst_structure_remove_fields (st, "width", "height", "framerate",
        "streamheader", "codec_data", NULL);

    if (!gst_caps_can_intersect (new_caps, current_caps) &&
        !is_raw_caps (current_caps) && !is_raw_caps (new_caps)) {
      GST_DEBUG_OBJECT (user_data, "Caps differ caps: %" GST_PTR_FORMAT,
          new_caps);
      kms_agnostic_bin2_configure_input (self, new_caps);
    }

    gst_caps_unref (current_caps);
  } else {
    GST_DEBUG_OBJECT (user_data, "No previous caps, starting");
    kms_agnostic_bin2_configure_input (self, new_caps);
  }

  return GST_PAD_PROBE_OK;
}
Пример #6
0
static void
remove_on_unlinked_cb (GstPad * pad, GstPad * peer, gpointer user_data)
{
  GstElement *elem = gst_pad_get_parent_element (pad);
  GstObject *parent;
  KmsAgnosticBin2 *self;

  if (elem == NULL) {
    return;
  }

  parent = GST_OBJECT_PARENT (elem);

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

  if (KMS_IS_AGNOSTIC_BIN2 (parent)) {
    self = KMS_AGNOSTIC_BIN2 (parent);
  } else {
    self = KMS_AGNOSTIC_BIN2 (GST_OBJECT_PARENT (parent));
  }

  if (self != NULL) {
    GstPad *sink = gst_element_get_static_pad (elem, (gchar *) user_data);

    if (sink != NULL) {
      GstPad *peer = gst_pad_get_peer (sink);

      g_object_unref (sink);

      if (peer != NULL) {
        gst_pad_add_probe (peer, GST_PAD_PROBE_TYPE_BLOCK,
            remove_on_unlinked_blocked, g_object_ref (elem), g_object_unref);
        send_dummy_event (peer);
        gst_object_unref (peer);
        goto end;
      }
    }

    g_thread_pool_push (self->priv->remove_pool, g_object_ref (elem), NULL);
  }

end:
  g_object_unref (elem);
}
Пример #7
0
void
kms_agnostic_bin2_set_property (GObject * object, guint property_id,
    const GValue * value, GParamSpec * pspec)
{
  KmsAgnosticBin2 *self = KMS_AGNOSTIC_BIN2 (object);

  switch (property_id) {
    case PROP_MIN_BITRATE:{
      gint v;

      v = g_value_get_int (value);
      KMS_AGNOSTIC_BIN2_LOCK (self);
      if (v > self->priv->max_bitrate) {
        v = self->priv->max_bitrate;

        GST_WARNING_OBJECT (self,
            "Setting min-bitrate bigger than max-bitrate");
      }

      self->priv->min_bitrate = v;
      GST_DEBUG_OBJECT (self, "min_bitrate configured %d",
          self->priv->min_bitrate);
      kms_agnostic_bin_set_encoders_bitrate (self);
      KMS_AGNOSTIC_BIN2_UNLOCK (self);
      break;
    }
    case PROP_MAX_BITRATE:{
      gint v;

      v = g_value_get_int (value);
      KMS_AGNOSTIC_BIN2_LOCK (self);
      if (v < self->priv->min_bitrate) {
        v = self->priv->min_bitrate;

        GST_WARNING_OBJECT (self, "Setting max-bitrate less than min-bitrate");
      }
      self->priv->max_bitrate = v;
      GST_DEBUG ("max_bitrate configured %d", self->priv->max_bitrate);
      kms_agnostic_bin_set_encoders_bitrate (self);
      KMS_AGNOSTIC_BIN2_UNLOCK (self);
      break;
    }
    case PROP_CODEC_CONFIG:
      KMS_AGNOSTIC_BIN2_LOCK (self);
      if (self->priv->codec_config) {
        gst_structure_free (self->priv->codec_config);
        self->priv->codec_config = NULL;
      }
      self->priv->codec_config = g_value_dup_boxed (value);
      KMS_AGNOSTIC_BIN2_UNLOCK (self);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}
Пример #8
0
static void
kms_agnostic_bin2_finalize (GObject * object)
{
  KmsAgnosticBin2 *self = KMS_AGNOSTIC_BIN2 (object);

  GST_DEBUG_OBJECT (object, "finalize");

  g_rec_mutex_clear (&self->priv->thread_mutex);

  g_hash_table_unref (self->priv->bins);

  /* chain up */
  G_OBJECT_CLASS (kms_agnostic_bin2_parent_class)->finalize (object);
}
Пример #9
0
void
kms_agnostic_bin2_get_property (GObject * object, guint property_id,
    GValue * value, GParamSpec * pspec)
{
  KmsAgnosticBin2 *self = KMS_AGNOSTIC_BIN2 (object);

  switch (property_id) {
    case PROP_DEFAULT_BITRATE:
      KMS_AGNOSTIC_BIN2_LOCK (self);
      g_value_set_int (value, self->priv->default_bitrate);
      KMS_AGNOSTIC_BIN2_UNLOCK (self);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}
Пример #10
0
static GstPadProbeReturn
remove_on_unlinked_blocked (GstPad * pad, GstPadProbeInfo * info, gpointer elem)
{
  KmsAgnosticBin2 *self;
  GstPad *sink;

  if (elem == NULL) {
    return GST_PAD_PROBE_REMOVE;
  }

  GST_DEBUG_OBJECT (pad, "Unlinking pad");

  GST_OBJECT_LOCK (pad);
  if (g_object_get_qdata (G_OBJECT (pad), unlinking_data_quark ())) {
    GST_OBJECT_UNLOCK (pad);
    if (GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_QUERY_BOTH) {
      /* Queries must be answered */
      return GST_PAD_PROBE_PASS;
    } else {
      return GST_PAD_PROBE_DROP;
    }
  }

  g_object_set_qdata (G_OBJECT (pad), unlinking_data_quark (),
      GINT_TO_POINTER (TRUE));

  GST_OBJECT_UNLOCK (pad);

  sink = gst_pad_get_peer (pad);
  if (sink != NULL) {
    gst_pad_unlink (pad, sink);
    g_object_unref (sink);
  }

  self = KMS_AGNOSTIC_BIN2 (GST_OBJECT_PARENT (elem));

  g_thread_pool_push (self->priv->remove_pool, g_object_ref (elem), NULL);

  return GST_PAD_PROBE_PASS;
}
Пример #11
0
static GstPadProbeReturn
input_bin_src_caps_probe (GstPad * pad, GstPadProbeInfo * info, gpointer bin)
{
  KmsAgnosticBin2 *self = KMS_AGNOSTIC_BIN2 (GST_OBJECT_PARENT (bin));
  GstEvent *event = gst_pad_probe_info_get_event (info);
  GstCaps *current_caps;

  if (self == NULL) {
    GST_WARNING_OBJECT (bin, "Parent agnosticbin seems to be released");
    return GST_PAD_PROBE_OK;
  }

  GST_TRACE_OBJECT (self, "Event in parser pad: %" GST_PTR_FORMAT, event);

  if (GST_EVENT_TYPE (event) != GST_EVENT_CAPS) {
    return GST_PAD_PROBE_OK;
  }

  KMS_AGNOSTIC_BIN2_LOCK (self);

  self->priv->started = TRUE;
  if (self->priv->input_bin_src_caps != NULL) {
    gst_caps_unref (self->priv->input_bin_src_caps);
  }

  gst_event_parse_caps (event, &current_caps);
  self->priv->input_bin_src_caps = gst_caps_copy (current_caps);
  kms_agnostic_bin2_insert_bin (self, GST_BIN (bin));

  GST_INFO_OBJECT (self, "Setting current caps to: %" GST_PTR_FORMAT,
      current_caps);

  kms_element_for_each_src_pad (GST_ELEMENT (self),
      (KmsPadIterationAction) add_linked_pads, self);

  KMS_AGNOSTIC_BIN2_UNLOCK (self);

  return GST_PAD_PROBE_REMOVE;
}
Пример #12
0
static gboolean
proxy_src_pad_query_function (GstPad * pad, GstObject * parent,
    GstQuery * query)
{
  gboolean ret = gst_pad_query_default (pad, parent, query);

  if (!ret) {
    return ret;
  }

  if (GST_QUERY_TYPE (query) == GST_QUERY_ACCEPT_CAPS) {
    gboolean accepted;

    gst_query_parse_accept_caps_result (query, &accepted);

    if (!accepted) {
      GstProxyPad *gp = gst_proxy_pad_get_internal (GST_PROXY_PAD (pad));
      KmsAgnosticBin2 *self = NULL;

      GST_ERROR_OBJECT (pad, "Caps not accepted: %" GST_PTR_FORMAT, query);

      if (gp) {
        self = KMS_AGNOSTIC_BIN2 (GST_OBJECT_PARENT (gp));
      }

      if (self) {
        KMS_AGNOSTIC_BIN2_LOCK (self);
        remove_target_pad (GST_PAD_CAST (gp));
        kms_agnostic_bin2_process_pad (self, GST_PAD_CAST (gp));
        KMS_AGNOSTIC_BIN2_UNLOCK (self);
      }

      g_object_unref (gp);
    }
  }

  return ret;
}