baseaudiosink: Allow subclasses to provide payloaders
authorArun Raghavan <arun.raghavan@collabora.co.uk>
Wed, 9 Mar 2011 05:42:39 +0000 (11:12 +0530)
committerArun Raghavan <arun.raghavan@collabora.co.uk>
Sat, 14 May 2011 12:53:18 +0000 (18:23 +0530)
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

gst-libs/gst/audio/gstbaseaudiosink.c
gst-libs/gst/audio/gstbaseaudiosink.h

index 6093092..6322004 100644 (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;
   }
 }
 
index 12a90f9..95c0774 100644 (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);