예제 #1
0
static void gst_a2dp_sink_get_property(GObject *object, guint prop_id,
					GValue *value, GParamSpec *pspec)
{
	GstA2dpSink *self = GST_A2DP_SINK(object);
	gchar *device;

	switch (prop_id) {
	case PROP_DEVICE:
		if (self->sink != NULL) {
			device = gst_avdtp_sink_get_device(self->sink);
			if (device != NULL)
				g_value_take_string(value, device);
		}
		break;
	case PROP_AUTOCONNECT:
		if (self->sink != NULL)
			g_object_get(G_OBJECT(self->sink), "auto-connect",
				&self->autoconnect, NULL);

		g_value_set_boolean(value, self->autoconnect);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
		break;
	}
}
예제 #2
0
/* used for catching newsegment events while we don't have a sink, for
 * later forwarding it to the sink */
static gboolean gst_a2dp_sink_handle_event(GstPad *pad, GstEvent *event)
{
	GstA2dpSink *self;
	GstTagList *taglist = NULL;
	GstObject *parent;

	self = GST_A2DP_SINK(GST_PAD_PARENT(pad));
	parent = gst_element_get_parent(GST_ELEMENT(self->sink));

	if (GST_EVENT_TYPE(event) == GST_EVENT_NEWSEGMENT &&
			parent != GST_OBJECT_CAST(self)) {
		if (self->newseg_event != NULL)
			gst_event_unref(self->newseg_event);
		self->newseg_event = gst_event_ref(event);

	} else if (GST_EVENT_TYPE(event) == GST_EVENT_TAG &&
			parent != GST_OBJECT_CAST(self)) {
		if (self->taglist == NULL)
			gst_event_parse_tag(event, &self->taglist);
		else {
			gst_event_parse_tag(event, &taglist);
			gst_tag_list_insert(self->taglist, taglist,
					GST_TAG_MERGE_REPLACE);
		}
	}

	if (parent != NULL)
		gst_object_unref(GST_OBJECT(parent));

	return self->ghostpad_eventfunc(GST_PAD(self->ghostpad), event);
}
예제 #3
0
static gboolean
gst_a2dp_sink_handle_event (GstPad * pad, GstObject * pad_parent,
    GstEvent * event)
{
  GstA2dpSink *self;
  GstTagList *taglist = NULL;

  self = GST_A2DP_SINK (pad_parent);

  if (GST_EVENT_TYPE (event) == GST_EVENT_TAG) {
    if (self->taglist == NULL)
      gst_event_parse_tag (event, &self->taglist);
    else {
      gst_event_parse_tag (event, &taglist);
      gst_tag_list_insert (self->taglist, taglist, GST_TAG_MERGE_REPLACE);
    }
  } else if (GST_EVENT_TYPE (event) == GST_EVENT_CAPS) {
    GstCaps *caps = NULL;

    gst_event_parse_caps (event, &caps);
    gst_a2dp_sink_init_dynamic_elements (self, caps);
  }

  return gst_pad_event_default (pad, pad_parent, event);
}
예제 #4
0
static void gst_a2dp_sink_finalize(GObject *obj)
{
	GstA2dpSink *self = GST_A2DP_SINK(obj);

	g_mutex_free(self->cb_mutex);

	G_OBJECT_CLASS(parent_class)->finalize(obj);
}
예제 #5
0
static gboolean gst_a2dp_sink_set_caps(GstPad *pad, GstCaps *caps)
{
	GstA2dpSink *self;

	self = GST_A2DP_SINK(GST_PAD_PARENT(pad));
	GST_INFO_OBJECT(self, "setting caps");

	/* now we know the caps */
	gst_a2dp_sink_init_dynamic_elements(self, caps);

	return self->ghostpad_setcapsfunc(GST_PAD(self->ghostpad), caps);
}
예제 #6
0
static GstStateChangeReturn
gst_a2dp_sink_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret;
  GstA2dpSink *self = GST_A2DP_SINK (element);

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      self->taglist = gst_tag_list_new_empty ();
      break;

    case GST_STATE_CHANGE_NULL_TO_READY:
      if (self->device != NULL)
        gst_avdtp_sink_set_device (self->sink, self->device);

      if (self->transport != NULL)
        gst_avdtp_sink_set_transport (self->sink, self->transport);

      g_object_set (G_OBJECT (self->sink), "auto-connect",
          self->autoconnect, NULL);

      break;

    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      if (self->taglist) {
        gst_tag_list_unref (self->taglist);
        self->taglist = NULL;
      }
      break;

    case GST_STATE_CHANGE_READY_TO_NULL:
      gst_a2dp_sink_remove_dynamic_elements (self);

      break;
    default:
      break;
  }

  return ret;
}
예제 #7
0
static gboolean
gst_a2dp_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  GstA2dpSink *sink = GST_A2DP_SINK (parent);
  gboolean ret;

  if (GST_QUERY_TYPE (query) == GST_QUERY_CAPS) {
    GstCaps *caps;

    caps = gst_a2dp_sink_get_caps (sink);
    gst_query_set_caps_result (query, caps);
    gst_caps_unref (caps);
    ret = TRUE;
  } else {
    ret = gst_pad_query_default (pad, parent, query);
  }

  return ret;
}
예제 #8
0
static GstCaps *gst_a2dp_sink_get_caps(GstPad *pad)
{
	GstCaps *caps;
	GstCaps *caps_aux;
	GstA2dpSink *self = GST_A2DP_SINK(GST_PAD_PARENT(pad));

	if (self->sink == NULL) {
		GST_DEBUG_OBJECT(self, "a2dpsink isn't initialized "
			"returning template caps");
		caps = gst_static_pad_template_get_caps(
				&gst_a2dp_sink_factory);
	} else {
		GST_LOG_OBJECT(self, "Getting device caps");
		caps = gst_a2dp_sink_get_device_caps(self);
		if (caps == NULL)
			caps = gst_static_pad_template_get_caps(
					&gst_a2dp_sink_factory);
	}
	caps_aux = gst_caps_copy(caps);
	g_object_set(self->capsfilter, "caps", caps_aux, NULL);
	gst_caps_unref(caps_aux);
	return caps;
}
예제 #9
0
static void
gst_a2dp_sink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstA2dpSink *self = GST_A2DP_SINK (object);

  switch (prop_id) {
    case PROP_DEVICE:
      if (self->sink != NULL)
        gst_avdtp_sink_set_device (self->sink, g_value_get_string (value));

      g_free (self->device);
      self->device = g_value_dup_string (value);
      break;

    case PROP_TRANSPORT:
      if (self->sink != NULL)
        gst_avdtp_sink_set_transport (self->sink, g_value_get_string (value));

      g_free (self->transport);
      self->transport = g_value_dup_string (value);
      break;

    case PROP_AUTOCONNECT:
      self->autoconnect = g_value_get_boolean (value);

      if (self->sink != NULL)
        g_object_set (G_OBJECT (self->sink), "auto-connect",
            self->autoconnect, NULL);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}
예제 #10
0
static GstStateChangeReturn gst_a2dp_sink_change_state(GstElement *element,
			GstStateChange transition)
{
	GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
	GstA2dpSink *self = GST_A2DP_SINK(element);

	switch (transition) {
	case GST_STATE_CHANGE_READY_TO_PAUSED:
		self->taglist = gst_tag_list_new();

		gst_a2dp_sink_init_fakesink(self);
		break;

	case GST_STATE_CHANGE_NULL_TO_READY:
		self->sink_is_in_bin = FALSE;
		self->sink = GST_AVDTP_SINK(gst_element_factory_make(
				"avdtpsink", "avdtpsink"));
		if (self->sink == NULL) {
			GST_WARNING_OBJECT(self, "failed to create avdtpsink");
			return GST_STATE_CHANGE_FAILURE;
		}

		if (self->device != NULL)
			gst_avdtp_sink_set_device(self->sink,
					self->device);

		g_object_set(G_OBJECT(self->sink), "auto-connect",
					self->autoconnect, NULL);

		ret = gst_element_set_state(GST_ELEMENT(self->sink),
			GST_STATE_READY);
		break;
	default:
		break;
	}

	if (ret == GST_STATE_CHANGE_FAILURE)
		return ret;

	ret = GST_ELEMENT_CLASS(parent_class)->change_state(element,
								transition);

	switch (transition) {
	case GST_STATE_CHANGE_PAUSED_TO_READY:
		if (self->taglist) {
			gst_tag_list_free(self->taglist);
			self->taglist = NULL;
		}
		if (self->newseg_event != NULL) {
			gst_event_unref(self->newseg_event);
			self->newseg_event = NULL;
		}
		gst_a2dp_sink_remove_fakesink(self);
		break;

	case GST_STATE_CHANGE_READY_TO_NULL:
		if (self->sink_is_in_bin) {
			if (!gst_bin_remove(GST_BIN(self),
						GST_ELEMENT(self->sink)))
				GST_WARNING_OBJECT(self, "Failed to remove "
						"avdtpsink from bin");
		} else if (self->sink != NULL) {
			gst_element_set_state(GST_ELEMENT(self->sink),
					GST_STATE_NULL);
			g_object_unref(G_OBJECT(self->sink));
		}

		self->sink = NULL;

		gst_a2dp_sink_remove_dynamic_elements(self);
		break;
	default:
		break;
	}

	return ret;
}