Exemple #1
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;
  }
}
Exemple #2
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;
  }
}
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);
}
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;
}
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;
}
Exemple #6
0
static void
kms_agnostic_bin2_src_unlinked (GstPad * pad, GstPad * peer,
    KmsAgnosticBin2 * self)
{
  GST_DEBUG_OBJECT (pad, "Unlinked");
  KMS_AGNOSTIC_BIN2_LOCK (self);
  GST_OBJECT_FLAG_UNSET (pad, KMS_AGNOSTIC_PAD_STARTED);
  remove_target_pad (pad);
  KMS_AGNOSTIC_BIN2_UNLOCK (self);
}
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;
  }
}
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;
}
static void
kms_agnostic_bin2_configure_input (KmsAgnosticBin2 * self, const GstCaps * caps)
{
  KmsParseTreeBin *parse_bin;
  GstElement *parser;
  GstPad *parser_src;
  GstElement *input_element;

  KMS_AGNOSTIC_BIN2_LOCK (self);

  if (self->priv->input_bin != NULL) {
    kms_tree_bin_unlink_input_element_from_tee (KMS_TREE_BIN (self->
            priv->input_bin));
  }

  parse_bin = kms_parse_tree_bin_new (caps);
  self->priv->input_bin = GST_BIN (parse_bin);

  parser = kms_parse_tree_bin_get_parser (KMS_PARSE_TREE_BIN (parse_bin));
  parser_src = gst_element_get_static_pad (parser, "src");
  gst_pad_add_probe (parser_src, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
      input_bin_src_caps_probe, g_object_ref (parse_bin), g_object_unref);
  g_object_unref (parser_src);

  gst_bin_add (GST_BIN (self), GST_ELEMENT (parse_bin));
  gst_element_sync_state_with_parent (GST_ELEMENT (parse_bin));

  input_element = kms_tree_bin_get_input_element (KMS_TREE_BIN (parse_bin));
  link_element_to_tee (self->priv->input_tee, input_element);

  self->priv->started = FALSE;

  GST_DEBUG ("Removing old treebins");
  g_hash_table_foreach (self->priv->bins, remove_bin, self);
  g_hash_table_remove_all (self->priv->bins);

  KMS_AGNOSTIC_BIN2_UNLOCK (self);
}
Exemple #10
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;
}