pulseaudiosink: port to 0.11
This commit is contained in:
parent
358767e217
commit
4517eb28c0
@ -115,40 +115,19 @@ static gboolean gst_pulse_audio_sink_sink_event (GstPad * pad,
|
|||||||
GstEvent * event);
|
GstEvent * event);
|
||||||
static gboolean gst_pulse_audio_sink_sink_acceptcaps (GstPad * pad,
|
static gboolean gst_pulse_audio_sink_sink_acceptcaps (GstPad * pad,
|
||||||
GstCaps * caps);
|
GstCaps * caps);
|
||||||
static gboolean gst_pulse_audio_sink_sink_setcaps (GstPad * pad,
|
|
||||||
GstCaps * caps);
|
|
||||||
static GstStateChangeReturn
|
static GstStateChangeReturn
|
||||||
gst_pulse_audio_sink_change_state (GstElement * element,
|
gst_pulse_audio_sink_change_state (GstElement * element,
|
||||||
GstStateChange transition);
|
GstStateChange transition);
|
||||||
|
static gboolean gst_pulse_audio_sink_set_caps (GstPulseAudioSink * pbin,
|
||||||
|
GstCaps * caps);
|
||||||
|
|
||||||
static void
|
#define gst_pulse_audio_sink_parent_class parent_class
|
||||||
gst_pulse_audio_sink_do_init (GType type)
|
G_DEFINE_TYPE (GstPulseAudioSink, gst_pulse_audio_sink, GST_TYPE_BIN);
|
||||||
{
|
|
||||||
GST_DEBUG_CATEGORY_INIT (pulseaudiosink_debug, "pulseaudiosink", 0,
|
|
||||||
"Bin that wraps pulsesink for handling compressed formats");
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_BOILERPLATE_FULL (GstPulseAudioSink, gst_pulse_audio_sink, GstBin,
|
|
||||||
GST_TYPE_BIN, gst_pulse_audio_sink_do_init);
|
|
||||||
|
|
||||||
static GstStaticPadTemplate sink_template =
|
static GstStaticPadTemplate sink_template =
|
||||||
GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
|
GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
|
||||||
GST_STATIC_CAPS (PULSE_SINK_TEMPLATE_CAPS));
|
GST_STATIC_CAPS (PULSE_SINK_TEMPLATE_CAPS));
|
||||||
|
|
||||||
static void
|
|
||||||
gst_pulse_audio_sink_base_init (gpointer klass)
|
|
||||||
{
|
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
|
||||||
|
|
||||||
gst_element_class_add_pad_template (element_class,
|
|
||||||
gst_static_pad_template_get (&sink_template));
|
|
||||||
|
|
||||||
gst_element_class_set_details_simple (element_class,
|
|
||||||
"Bin wrapping pulsesink", "Sink/Audio/Bin",
|
|
||||||
"Correctly handles sink changes when streaming compressed formats to "
|
|
||||||
"pulsesink", "Arun Raghavan <arun.raghavan@collabora.co.uk>");
|
|
||||||
}
|
|
||||||
|
|
||||||
static GParamSpec *
|
static GParamSpec *
|
||||||
param_spec_copy (GParamSpec * spec)
|
param_spec_copy (GParamSpec * spec)
|
||||||
{
|
{
|
||||||
@ -272,11 +251,6 @@ param_spec_copy (GParamSpec * spec)
|
|||||||
vspec->default_value, flags);
|
vspec->default_value, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (G_PARAM_SPEC_TYPE (spec) == GST_TYPE_PARAM_MINI_OBJECT) {
|
|
||||||
return gst_param_spec_mini_object (name, nick, blurb, spec->value_type,
|
|
||||||
flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_warning ("Unknown param type %ld for '%s'",
|
g_warning ("Unknown param type %ld for '%s'",
|
||||||
(long) G_PARAM_SPEC_TYPE (spec), name);
|
(long) G_PARAM_SPEC_TYPE (spec), name);
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
@ -292,6 +266,17 @@ gst_pulse_audio_sink_class_init (GstPulseAudioSinkClass * klass)
|
|||||||
GParamSpec **specs;
|
GParamSpec **specs;
|
||||||
guint n, i, j;
|
guint n, i, j;
|
||||||
|
|
||||||
|
GST_DEBUG_CATEGORY_INIT (pulseaudiosink_debug, "pulseaudiosink", 0,
|
||||||
|
"Bin that wraps pulsesink for handling compressed formats");
|
||||||
|
|
||||||
|
gst_element_class_add_pad_template (element_class,
|
||||||
|
gst_static_pad_template_get (&sink_template));
|
||||||
|
|
||||||
|
gst_element_class_set_details_simple (element_class,
|
||||||
|
"Bin wrapping pulsesink", "Sink/Audio/Bin",
|
||||||
|
"Correctly handles sink changes when streaming compressed formats to "
|
||||||
|
"pulsesink", "Arun Raghavan <arun.raghavan@collabora.co.uk>");
|
||||||
|
|
||||||
gobject_class->get_property = gst_pulse_audio_sink_get_property;
|
gobject_class->get_property = gst_pulse_audio_sink_get_property;
|
||||||
gobject_class->set_property = gst_pulse_audio_sink_set_property;
|
gobject_class->set_property = gst_pulse_audio_sink_set_property;
|
||||||
gobject_class->dispose = gst_pulse_audio_sink_dispose;
|
gobject_class->dispose = gst_pulse_audio_sink_dispose;
|
||||||
@ -353,9 +338,10 @@ notify_cb (GObject * selector, GParamSpec * pspec, GstPulseAudioSink * pbin)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_pulse_audio_sink_init (GstPulseAudioSink * pbin,
|
gst_pulse_audio_sink_init (GstPulseAudioSink * pbin)
|
||||||
GstPulseAudioSinkClass * klass)
|
|
||||||
{
|
{
|
||||||
|
GstPulseAudioSinkClass *klass =
|
||||||
|
GST_PULSE_AUDIO_SINK_CLASS (G_OBJECT_GET_CLASS (pbin));
|
||||||
GstPad *pad = NULL;
|
GstPad *pad = NULL;
|
||||||
GParamSpec **specs;
|
GParamSpec **specs;
|
||||||
GString *prop;
|
GString *prop;
|
||||||
@ -381,8 +367,6 @@ gst_pulse_audio_sink_init (GstPulseAudioSink * pbin,
|
|||||||
pbin->sinkpad_old_eventfunc = GST_PAD_EVENTFUNC (pbin->sinkpad);
|
pbin->sinkpad_old_eventfunc = GST_PAD_EVENTFUNC (pbin->sinkpad);
|
||||||
gst_pad_set_event_function (pbin->sinkpad,
|
gst_pad_set_event_function (pbin->sinkpad,
|
||||||
GST_DEBUG_FUNCPTR (gst_pulse_audio_sink_sink_event));
|
GST_DEBUG_FUNCPTR (gst_pulse_audio_sink_sink_event));
|
||||||
gst_pad_set_setcaps_function (pbin->sinkpad,
|
|
||||||
GST_DEBUG_FUNCPTR (gst_pulse_audio_sink_sink_setcaps));
|
|
||||||
gst_pad_set_acceptcaps_function (pbin->sinkpad,
|
gst_pad_set_acceptcaps_function (pbin->sinkpad,
|
||||||
GST_DEBUG_FUNCPTR (gst_pulse_audio_sink_sink_acceptcaps));
|
GST_DEBUG_FUNCPTR (gst_pulse_audio_sink_sink_acceptcaps));
|
||||||
|
|
||||||
@ -518,28 +502,27 @@ distribute_running_time (GstElement * element, const GstSegment * segment)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
event = gst_event_new_new_segment_full (FALSE, segment->rate,
|
/* TODO review this copy, see if it can be avoided */
|
||||||
segment->applied_rate, segment->format,
|
event = gst_event_new_segment (gst_segment_copy (segment));
|
||||||
segment->start, segment->stop, segment->time);
|
|
||||||
gst_pad_send_event (pad, event);
|
gst_pad_send_event (pad, event);
|
||||||
|
|
||||||
gst_object_unref (pad);
|
gst_object_unref (pad);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static GstProbeReturn
|
||||||
dbin2_event_probe (GstPad * pad, GstMiniObject * obj, gpointer data)
|
dbin2_event_probe (GstPad * pad, GstProbeType ptype, GstEvent * event,
|
||||||
|
gpointer data)
|
||||||
{
|
{
|
||||||
GstPulseAudioSink *pbin = GST_PULSE_AUDIO_SINK (data);
|
GstPulseAudioSink *pbin = GST_PULSE_AUDIO_SINK (data);
|
||||||
GstEvent *event = GST_EVENT (obj);
|
|
||||||
|
|
||||||
if (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) {
|
if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
|
||||||
GST_DEBUG_OBJECT (pbin, "Got newsegment - dropping");
|
GST_DEBUG_OBJECT (pbin, "Got newsegment - dropping");
|
||||||
gst_pad_remove_event_probe (pad, pbin->event_probe_id);
|
gst_pad_remove_probe (pad, pbin->event_probe_id);
|
||||||
gst_object_unref (pbin);
|
gst_object_unref (pbin);
|
||||||
return FALSE;
|
return GST_PROBE_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return GST_PROBE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -594,8 +577,8 @@ gst_pulse_audio_sink_add_dbin2 (GstPulseAudioSink * pbin)
|
|||||||
|
|
||||||
/* Trap the newsegment events that we feed the decodebin and discard them */
|
/* Trap the newsegment events that we feed the decodebin and discard them */
|
||||||
sinkpad = gst_element_get_static_pad (GST_ELEMENT (pbin->psink), "sink");
|
sinkpad = gst_element_get_static_pad (GST_ELEMENT (pbin->psink), "sink");
|
||||||
pbin->event_probe_id = gst_pad_add_event_probe (sinkpad,
|
pbin->event_probe_id = gst_pad_add_probe (sinkpad, GST_PROBE_TYPE_EVENT,
|
||||||
G_CALLBACK (dbin2_event_probe), gst_object_ref (pbin));
|
(GstPadProbeCallback) dbin2_event_probe, gst_object_ref (pbin), NULL);
|
||||||
gst_object_unref (sinkpad);
|
gst_object_unref (sinkpad);
|
||||||
sinkpad = NULL;
|
sinkpad = NULL;
|
||||||
|
|
||||||
@ -614,7 +597,7 @@ out:
|
|||||||
static void
|
static void
|
||||||
update_eac3_alignment (GstPulseAudioSink * pbin)
|
update_eac3_alignment (GstPulseAudioSink * pbin)
|
||||||
{
|
{
|
||||||
GstCaps *caps = gst_pad_peer_get_caps_reffed (pbin->sinkpad);
|
GstCaps *caps = gst_pad_peer_get_caps (pbin->sinkpad, NULL);
|
||||||
GstStructure *st;
|
GstStructure *st;
|
||||||
|
|
||||||
if (!caps)
|
if (!caps)
|
||||||
@ -634,18 +617,21 @@ update_eac3_alignment (GstPulseAudioSink * pbin)
|
|||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static GstProbeReturn
|
||||||
proxypad_blocked_cb (GstPad * pad, gboolean blocked, gpointer data)
|
proxypad_blocked_cb (GstPad * pad, GstProbeType ptype, gpointer type_data,
|
||||||
|
gpointer data)
|
||||||
{
|
{
|
||||||
GstPulseAudioSink *pbin = GST_PULSE_AUDIO_SINK (data);
|
GstPulseAudioSink *pbin = GST_PULSE_AUDIO_SINK (data);
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
GstPad *sinkpad = NULL;
|
GstPad *sinkpad = NULL;
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (!blocked) {
|
if (!blocked) {
|
||||||
/* Unblocked, don't need to do anything */
|
/* Unblocked, don't need to do anything */
|
||||||
GST_DEBUG_OBJECT (pbin, "unblocked");
|
GST_DEBUG_OBJECT (pbin, "unblocked");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (pbin, "blocked");
|
GST_DEBUG_OBJECT (pbin, "blocked");
|
||||||
|
|
||||||
@ -653,7 +639,7 @@ proxypad_blocked_cb (GstPad * pad, gboolean blocked, gpointer data)
|
|||||||
|
|
||||||
if (!pbin->format_lost) {
|
if (!pbin->format_lost) {
|
||||||
sinkpad = gst_element_get_static_pad (GST_ELEMENT (pbin->psink), "sink");
|
sinkpad = gst_element_get_static_pad (GST_ELEMENT (pbin->psink), "sink");
|
||||||
caps = gst_pad_get_caps_reffed (pad);
|
caps = gst_pad_get_caps (pad, NULL);
|
||||||
|
|
||||||
if (gst_pad_accept_caps (sinkpad, caps)) {
|
if (gst_pad_accept_caps (sinkpad, caps)) {
|
||||||
if (pbin->dbin2) {
|
if (pbin->dbin2) {
|
||||||
@ -687,10 +673,8 @@ proxypad_blocked_cb (GstPad * pad, gboolean blocked, gpointer data)
|
|||||||
done:
|
done:
|
||||||
update_eac3_alignment (pbin);
|
update_eac3_alignment (pbin);
|
||||||
|
|
||||||
gst_pad_set_blocked_async_full (pad, FALSE, proxypad_blocked_cb,
|
|
||||||
gst_object_ref (pbin), (GDestroyNotify) gst_object_unref);
|
|
||||||
|
|
||||||
GST_PULSE_AUDIO_SINK_UNLOCK (pbin);
|
GST_PULSE_AUDIO_SINK_UNLOCK (pbin);
|
||||||
|
return GST_PROBE_PASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -722,7 +706,7 @@ gst_pulse_audio_sink_src_event (GstPad * pad, GstEvent * event)
|
|||||||
pbin->format_lost = TRUE;
|
pbin->format_lost = TRUE;
|
||||||
|
|
||||||
if (!gst_pad_is_blocked (pad))
|
if (!gst_pad_is_blocked (pad))
|
||||||
gst_pad_set_blocked_async_full (pad, TRUE, proxypad_blocked_cb,
|
gst_pad_add_probe (pad, GST_PROBE_TYPE_BLOCK, proxypad_blocked_cb,
|
||||||
gst_object_ref (pbin), (GDestroyNotify) gst_object_unref);
|
gst_object_ref (pbin), (GDestroyNotify) gst_object_unref);
|
||||||
GST_PULSE_AUDIO_SINK_UNLOCK (pbin);
|
GST_PULSE_AUDIO_SINK_UNLOCK (pbin);
|
||||||
|
|
||||||
@ -752,27 +736,27 @@ gst_pulse_audio_sink_sink_event (GstPad * pad, GstEvent * event)
|
|||||||
ret = pbin->sinkpad_old_eventfunc (pad, gst_event_ref (event));
|
ret = pbin->sinkpad_old_eventfunc (pad, gst_event_ref (event));
|
||||||
|
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_CAPS:
|
||||||
{
|
{
|
||||||
GstFormat format;
|
GstCaps *caps;
|
||||||
gdouble rate, arate;
|
|
||||||
gint64 start, stop, time;
|
gst_event_parse_caps (event, &caps);
|
||||||
gboolean update;
|
ret = gst_pulse_audio_sink_set_caps (pbin, caps);
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GST_EVENT_SEGMENT:
|
||||||
|
{
|
||||||
|
const GstSegment *segment = NULL;
|
||||||
|
|
||||||
GST_PULSE_AUDIO_SINK_LOCK (pbin);
|
GST_PULSE_AUDIO_SINK_LOCK (pbin);
|
||||||
gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
|
gst_event_parse_segment (event, &segment);
|
||||||
&start, &stop, &time);
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (pbin,
|
GST_DEBUG_OBJECT (pbin, "newsegment: %" GST_SEGMENT_FORMAT, segment);
|
||||||
"newsegment: update %d, rate %g, arate %g, start %" GST_TIME_FORMAT
|
|
||||||
", stop %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT,
|
|
||||||
update, rate, arate, GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
|
|
||||||
GST_TIME_ARGS (time));
|
|
||||||
|
|
||||||
if (format == GST_FORMAT_TIME) {
|
if (segment->format == GST_FORMAT_TIME) {
|
||||||
/* Store the values for feeding to sub-elements */
|
/* Store the values for feeding to sub-elements */
|
||||||
gst_segment_set_newsegment_full (&pbin->segment, update,
|
gst_segment_copy_into (segment, &pbin->segment);
|
||||||
rate, arate, format, start, stop, time);
|
|
||||||
} else {
|
} else {
|
||||||
GST_WARNING_OBJECT (pbin, "Got a non-TIME format segment");
|
GST_WARNING_OBJECT (pbin, "Got a non-TIME format segment");
|
||||||
gst_segment_init (&pbin->segment, GST_FORMAT_TIME);
|
gst_segment_init (&pbin->segment, GST_FORMAT_TIME);
|
||||||
@ -811,8 +795,8 @@ gst_pulse_audio_sink_sink_acceptcaps (GstPad * pad, GstCaps * caps)
|
|||||||
GstCaps *pad_caps = NULL;
|
GstCaps *pad_caps = NULL;
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
|
|
||||||
pad_caps = gst_pad_get_caps_reffed (pad);
|
pad_caps = gst_pad_get_caps (pad, caps);
|
||||||
if (!pad_caps || !gst_caps_can_intersect (pad_caps, caps))
|
if (!pad_caps || !gst_caps_is_empty (pad_caps))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* If we've not got fixed caps, creating a stream might fail, so let's just
|
/* If we've not got fixed caps, creating a stream might fail, so let's just
|
||||||
@ -849,22 +833,19 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_pulse_audio_sink_sink_setcaps (GstPad * pad, GstCaps * caps)
|
gst_pulse_audio_sink_set_caps (GstPulseAudioSink * pbin, GstCaps * caps)
|
||||||
{
|
{
|
||||||
GstPulseAudioSink *pbin = GST_PULSE_AUDIO_SINK (gst_pad_get_parent (pad));
|
|
||||||
gboolean ret = TRUE;
|
gboolean ret = TRUE;
|
||||||
|
|
||||||
GST_PULSE_AUDIO_SINK_LOCK (pbin);
|
GST_PULSE_AUDIO_SINK_LOCK (pbin);
|
||||||
|
|
||||||
if (!gst_pad_is_blocked (pbin->sinkpad))
|
if (!gst_pad_is_blocked (pbin->sinkpad))
|
||||||
gst_pad_set_blocked_async_full (pbin->sink_proxypad, TRUE,
|
gst_pad_add_probe (pbin->sink_proxypad, GST_PROBE_TYPE_BLOCK,
|
||||||
proxypad_blocked_cb, gst_object_ref (pbin),
|
proxypad_blocked_cb, gst_object_ref (pbin),
|
||||||
(GDestroyNotify) gst_object_unref);
|
(GDestroyNotify) gst_object_unref);
|
||||||
|
|
||||||
GST_PULSE_AUDIO_SINK_UNLOCK (pbin);
|
GST_PULSE_AUDIO_SINK_UNLOCK (pbin);
|
||||||
|
|
||||||
gst_object_unref (pbin);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -880,7 +861,7 @@ gst_pulse_audio_sink_change_state (GstElement * element,
|
|||||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||||
GST_PULSE_AUDIO_SINK_LOCK (pbin);
|
GST_PULSE_AUDIO_SINK_LOCK (pbin);
|
||||||
if (gst_pad_is_blocked (pbin->sinkpad)) {
|
if (gst_pad_is_blocked (pbin->sinkpad)) {
|
||||||
gst_pad_set_blocked_async_full (pbin->sink_proxypad, FALSE,
|
gst_pad_add_probe (pbin->sink_proxypad, GST_PROBE_TYPE_BLOCK,
|
||||||
proxypad_blocked_cb, gst_object_ref (pbin),
|
proxypad_blocked_cb, gst_object_ref (pbin),
|
||||||
(GDestroyNotify) gst_object_unref);
|
(GDestroyNotify) gst_object_unref);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user