baseaudiosink: Allow subclasses to provide payloaders

This allows subclasses to provide a "payload" function to prepare
buffers for consumption. The immediate use for this is for sinks that
can handle compressed formats - parsers are directly connected to the
sink, and for formats such as AC3, DTS, and MPEG, IEC 61937 patyloading
might be used.

API: GstBaseAudioSinkClass:payload()

https://bugzilla.gnome.org/show_bug.cgi?id=642730
This commit is contained in:
Arun Raghavan 2011-03-09 11:12:39 +05:30
parent 9615081f9c
commit 643e5f586c
2 changed files with 44 additions and 7 deletions

View file

@ -1375,6 +1375,7 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
guint64 in_offset;
GstClockTime time, stop, render_start, render_stop, sample_offset;
GstClockTimeDiff sync_offset, ts_offset;
GstBaseAudioSinkClass *bclass;
GstBaseAudioSink *sink;
GstRingBuffer *ringbuf;
gint64 diff, align, ctime, cstop;
@ -1390,8 +1391,10 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
GstFlowReturn ret;
GstSegment clip_seg;
gint64 time_offset;
GstBuffer *out = NULL;
sink = GST_BASE_AUDIO_SINK (bsink);
bclass = GST_BASE_AUDIO_SINK_GET_CLASS (sink);
ringbuf = sink->ringbuffer;
@ -1415,6 +1418,17 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
GST_OBJECT_UNLOCK (sink);
}
/* Before we go on, let's see if we need to payload the data. If yes, we also
* need to unref the output buffer before leaving. */
if (bclass->payload) {
out = bclass->payload (sink, buf);
if (!out)
goto payload_failed;
buf = out;
}
bps = ringbuf->spec.bytes_per_sample;
size = GST_BUFFER_SIZE (buf);
@ -1697,7 +1711,13 @@ no_sync:
gst_ring_buffer_start (ringbuf);
}
return GST_FLOW_OK;
ret = GST_FLOW_OK;
done:
if (out)
gst_buffer_unref (out);
return ret;
/* SPECIAL cases */
out_of_segment:
@ -1706,32 +1726,41 @@ out_of_segment:
"dropping sample out of segment time %" GST_TIME_FORMAT ", start %"
GST_TIME_FORMAT, GST_TIME_ARGS (time),
GST_TIME_ARGS (bsink->segment.start));
return GST_FLOW_OK;
ret = GST_FLOW_OK;
goto done;
}
/* ERRORS */
payload_failed:
{
GST_ELEMENT_ERROR (sink, STREAM, FORMAT, (NULL), ("failed to payload."));
ret = GST_FLOW_ERROR;
goto done;
}
wrong_state:
{
GST_DEBUG_OBJECT (sink, "ringbuffer not negotiated");
GST_ELEMENT_ERROR (sink, STREAM, FORMAT, (NULL), ("sink not negotiated."));
return GST_FLOW_NOT_NEGOTIATED;
ret = GST_FLOW_NOT_NEGOTIATED;
goto done;
}
wrong_size:
{
GST_DEBUG_OBJECT (sink, "wrong size");
GST_ELEMENT_ERROR (sink, STREAM, WRONG_TYPE,
(NULL), ("sink received buffer of wrong size."));
return GST_FLOW_ERROR;
ret = GST_FLOW_ERROR;
goto done;
}
stopping:
{
GST_DEBUG_OBJECT (sink, "preroll got interrupted: %d (%s)", ret,
gst_flow_get_name (ret));
return ret;
goto done;
}
sync_latency_failed:
{
GST_DEBUG_OBJECT (sink, "failed waiting for latency");
return ret;
goto done;
}
}

View file

@ -141,6 +141,10 @@ struct _GstBaseAudioSink {
* GstBaseAudioSinkClass:
* @parent_class: the parent class.
* @create_ringbuffer: create and return a #GstRingBuffer to write to.
* @payload: payload data in a format suitable to write to the sink. If no
* payloading is required, returns a reffed copy of the original
* buffer, else returns the payloaded buffer with all other metadata
* copied. (Since: 0.10.35)
*
* #GstBaseAudioSink class. Override the vmethod to implement
* functionality.
@ -151,8 +155,12 @@ struct _GstBaseAudioSinkClass {
/* subclass ringbuffer allocation */
GstRingBuffer* (*create_ringbuffer) (GstBaseAudioSink *sink);
/* subclass payloader */
GstBuffer* (*payload) (GstBaseAudioSink *sink,
GstBuffer *buffer);
/*< private >*/
gpointer _gst_reserved[GST_PADDING];
gpointer _gst_reserved[GST_PADDING - 1];
};
GType gst_base_audio_sink_get_type(void);