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; } }
/* 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); }
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); }
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); }
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); }
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; }
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; }
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; }
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; } }
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; }