summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThiago Santos <thiagoss@osg.samsung.com>2015-05-06 15:25:40 -0300
committerThiago Santos <thiagoss@osg.samsung.com>2015-06-08 11:05:00 -0300
commit3c81a42d49f48a65597ebaed390c79977600469a (patch)
tree185e629066215757148b652bfe434fd20347db2a
parente8682cabcbc7726006d0156bfc0579af1c1539c6 (diff)
basemixer: add prepare and adjust_time virtual functions
Those 2 functions are a need from videoaggregator. The prepare can be used for subclasses do some extra operation before the mixing code is executed. The adjust_time can be used to change the mixing start and end times. Start can be increased to skip some data while end can be reduced to make it mix up to a certain point in time. This is used in videoaggregator to mix with a constant output framerate that might be different from the input.
-rw-r--r--gst-libs/gst/base/gstbasemixer.c49
-rw-r--r--gst-libs/gst/base/gstbasemixer.h8
2 files changed, 57 insertions, 0 deletions
diff --git a/gst-libs/gst/base/gstbasemixer.c b/gst-libs/gst/base/gstbasemixer.c
index cd4275296..d768e0197 100644
--- a/gst-libs/gst/base/gstbasemixer.c
+++ b/gst-libs/gst/base/gstbasemixer.c
@@ -205,13 +205,62 @@ gst_base_mixer_mix (GstBaseMixer * bmixer, GstClockTime start, GstClockTime end)
}
static GstFlowReturn
+gst_base_mixer_prepare (GstBaseMixer * bmixer, gboolean timeout)
+{
+ GstBaseMixerClass *bmixer_class = GST_BASE_MIXER_GET_CLASS (bmixer);
+
+ if (bmixer_class->prepare)
+ return bmixer_class->prepare (bmixer, timeout);
+ return GST_FLOW_OK;
+}
+
+/* TODO write unit tests for this feature */
+/* FIXME - design: by reducing the 'end' time the class will be
+ * forced to mix again the same data, which will likely waste CPU.
+ * It might make more sense to make subclasses push multiple buffers
+ * from the same mix() call as it would be possible to push the same
+ * buffer reference over again */
+static void
+gst_base_mixer_adjust_times (GstBaseMixer * bmixer, GstClockTime * start,
+ GstClockTime * end)
+{
+ GstBaseMixerClass *bmixer_class = GST_BASE_MIXER_GET_CLASS (bmixer);
+
+ if (bmixer_class->adjust_times)
+ bmixer_class->adjust_times (bmixer, start, end);
+}
+
+static GstFlowReturn
gst_base_mixer_aggregate (GstAggregator * agg, gboolean timeout)
{
GstBaseMixer *bmixer = GST_BASE_MIXER_CAST (agg);
GstClockTime start, end;
+ GstClockTime suggested_start, suggested_end;
GstFlowReturn ret;
+ ret = gst_base_mixer_prepare (bmixer, timeout);
+ if (ret != GST_FLOW_OK)
+ return ret;
+
gst_base_mixer_find_time_alignment (bmixer, &start, &end);
+ suggested_start = start;
+ suggested_end = end;
+
+ /* check if subclass wants a different mixing time */
+ gst_base_mixer_adjust_times (bmixer, &start, &end);
+
+ /* Subclass should only increase start and/or decrease end,
+ * Decreasing start means returning in time and we might not
+ * have that data anymore.
+ * Increasing end will go beyond the mixing limit of the current
+ * data and will lead to incorrect results */
+ g_assert (start >= suggested_start);
+ g_assert (end <= suggested_end);
+
+ if (start > suggested_start) {
+ /* TODO implement this -
+ * subclass wants to skip some data */
+ }
ret = gst_base_mixer_mix (bmixer, start, end);
diff --git a/gst-libs/gst/base/gstbasemixer.h b/gst-libs/gst/base/gstbasemixer.h
index 1dd160bfc..ae0c9801c 100644
--- a/gst-libs/gst/base/gstbasemixer.h
+++ b/gst-libs/gst/base/gstbasemixer.h
@@ -140,6 +140,14 @@ struct _GstBaseMixerClass {
GstFlowReturn (*mix) (GstBaseMixer * bmixer, GstClockTime start, GstClockTime end);
+ /* Subclass can do extra work before mix is called */
+ GstFlowReturn (*prepare) (GstBaseMixer * bmixer, gboolean timeout);
+
+ /* Subclass can adjust the start and end times of the next mix call to their liking.
+ * It is only allowed to increase @start if it wants to skip some data and to reduce
+ * @end if it wants to mix less data in this turn */
+ void (*adjust_times) (GstBaseMixer * bmixer, GstClockTime * start, GstClockTime * end);
+
/*< private >*/
gpointer _gst_reserved[GST_PADDING_LARGE];
};