pulseaudiosink: port to 0.11

This commit is contained in:
Thiago Santos 2011-10-09 21:17:24 -03:00
parent 358767e217
commit 4517eb28c0

View file

@ -115,40 +115,19 @@ static gboolean gst_pulse_audio_sink_sink_event (GstPad * pad,
GstEvent * event);
static gboolean gst_pulse_audio_sink_sink_acceptcaps (GstPad * pad,
GstCaps * caps);
static gboolean gst_pulse_audio_sink_sink_setcaps (GstPad * pad,
GstCaps * caps);
static GstStateChangeReturn
gst_pulse_audio_sink_change_state (GstElement * element,
GstStateChange transition);
static gboolean gst_pulse_audio_sink_set_caps (GstPulseAudioSink * pbin,
GstCaps * caps);
static void
gst_pulse_audio_sink_do_init (GType type)
{
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);
#define gst_pulse_audio_sink_parent_class parent_class
G_DEFINE_TYPE (GstPulseAudioSink, gst_pulse_audio_sink, GST_TYPE_BIN);
static GstStaticPadTemplate sink_template =
GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
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 *
param_spec_copy (GParamSpec * spec)
{
@ -272,11 +251,6 @@ param_spec_copy (GParamSpec * spec)
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'",
(long) G_PARAM_SPEC_TYPE (spec), name);
g_assert_not_reached ();
@ -292,6 +266,17 @@ gst_pulse_audio_sink_class_init (GstPulseAudioSinkClass * klass)
GParamSpec **specs;
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->set_property = gst_pulse_audio_sink_set_property;
gobject_class->dispose = gst_pulse_audio_sink_dispose;
@ -353,9 +338,10 @@ notify_cb (GObject * selector, GParamSpec * pspec, GstPulseAudioSink * pbin)
}
static void
gst_pulse_audio_sink_init (GstPulseAudioSink * pbin,
GstPulseAudioSinkClass * klass)
gst_pulse_audio_sink_init (GstPulseAudioSink * pbin)
{
GstPulseAudioSinkClass *klass =
GST_PULSE_AUDIO_SINK_CLASS (G_OBJECT_GET_CLASS (pbin));
GstPad *pad = NULL;
GParamSpec **specs;
GString *prop;
@ -381,8 +367,6 @@ gst_pulse_audio_sink_init (GstPulseAudioSink * pbin,
pbin->sinkpad_old_eventfunc = GST_PAD_EVENTFUNC (pbin->sinkpad);
gst_pad_set_event_function (pbin->sinkpad,
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_DEBUG_FUNCPTR (gst_pulse_audio_sink_sink_acceptcaps));
@ -518,28 +502,27 @@ distribute_running_time (GstElement * element, const GstSegment * segment)
}
#endif
event = gst_event_new_new_segment_full (FALSE, segment->rate,
segment->applied_rate, segment->format,
segment->start, segment->stop, segment->time);
/* TODO review this copy, see if it can be avoided */
event = gst_event_new_segment (gst_segment_copy (segment));
gst_pad_send_event (pad, event);
gst_object_unref (pad);
}
static gboolean
dbin2_event_probe (GstPad * pad, GstMiniObject * obj, gpointer data)
static GstProbeReturn
dbin2_event_probe (GstPad * pad, GstProbeType ptype, GstEvent * event,
gpointer 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_pad_remove_event_probe (pad, pbin->event_probe_id);
gst_pad_remove_probe (pad, pbin->event_probe_id);
gst_object_unref (pbin);
return FALSE;
return GST_PROBE_DROP;
}
return TRUE;
return GST_PROBE_OK;
}
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 */
sinkpad = gst_element_get_static_pad (GST_ELEMENT (pbin->psink), "sink");
pbin->event_probe_id = gst_pad_add_event_probe (sinkpad,
G_CALLBACK (dbin2_event_probe), gst_object_ref (pbin));
pbin->event_probe_id = gst_pad_add_probe (sinkpad, GST_PROBE_TYPE_EVENT,
(GstPadProbeCallback) dbin2_event_probe, gst_object_ref (pbin), NULL);
gst_object_unref (sinkpad);
sinkpad = NULL;
@ -614,7 +597,7 @@ out:
static void
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;
if (!caps)
@ -634,18 +617,21 @@ update_eac3_alignment (GstPulseAudioSink * pbin)
gst_caps_unref (caps);
}
static void
proxypad_blocked_cb (GstPad * pad, gboolean blocked, gpointer data)
static GstProbeReturn
proxypad_blocked_cb (GstPad * pad, GstProbeType ptype, gpointer type_data,
gpointer data)
{
GstPulseAudioSink *pbin = GST_PULSE_AUDIO_SINK (data);
GstCaps *caps;
GstPad *sinkpad = NULL;
#if 0
if (!blocked) {
/* Unblocked, don't need to do anything */
GST_DEBUG_OBJECT (pbin, "unblocked");
return;
}
#endif
GST_DEBUG_OBJECT (pbin, "blocked");
@ -653,7 +639,7 @@ proxypad_blocked_cb (GstPad * pad, gboolean blocked, gpointer data)
if (!pbin->format_lost) {
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 (pbin->dbin2) {
@ -687,10 +673,8 @@ proxypad_blocked_cb (GstPad * pad, gboolean blocked, gpointer data)
done:
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);
return GST_PROBE_PASS;
}
static gboolean
@ -722,7 +706,7 @@ gst_pulse_audio_sink_src_event (GstPad * pad, GstEvent * event)
pbin->format_lost = TRUE;
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_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));
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_NEWSEGMENT:
case GST_EVENT_CAPS:
{
GstFormat format;
gdouble rate, arate;
gint64 start, stop, time;
gboolean update;
GstCaps *caps;
gst_event_parse_caps (event, &caps);
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_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
&start, &stop, &time);
gst_event_parse_segment (event, &segment);
GST_DEBUG_OBJECT (pbin,
"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));
GST_DEBUG_OBJECT (pbin, "newsegment: %" GST_SEGMENT_FORMAT, segment);
if (format == GST_FORMAT_TIME) {
if (segment->format == GST_FORMAT_TIME) {
/* Store the values for feeding to sub-elements */
gst_segment_set_newsegment_full (&pbin->segment, update,
rate, arate, format, start, stop, time);
gst_segment_copy_into (segment, &pbin->segment);
} else {
GST_WARNING_OBJECT (pbin, "Got a non-TIME format segment");
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;
gboolean ret = FALSE;
pad_caps = gst_pad_get_caps_reffed (pad);
if (!pad_caps || !gst_caps_can_intersect (pad_caps, caps))
pad_caps = gst_pad_get_caps (pad, caps);
if (!pad_caps || !gst_caps_is_empty (pad_caps))
goto out;
/* If we've not got fixed caps, creating a stream might fail, so let's just
@ -849,22 +833,19 @@ out:
}
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;
GST_PULSE_AUDIO_SINK_LOCK (pbin);
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),
(GDestroyNotify) gst_object_unref);
GST_PULSE_AUDIO_SINK_UNLOCK (pbin);
gst_object_unref (pbin);
return ret;
}
@ -880,7 +861,7 @@ gst_pulse_audio_sink_change_state (GstElement * element,
case GST_STATE_CHANGE_PAUSED_TO_READY:
GST_PULSE_AUDIO_SINK_LOCK (pbin);
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),
(GDestroyNotify) gst_object_unref);
}