summaryrefslogtreecommitdiff
path: root/include/gst/base
diff options
context:
space:
mode:
Diffstat (limited to 'include/gst/base')
-rw-r--r--include/gst/base/base-prelude.h35
-rw-r--r--include/gst/base/base.h44
-rw-r--r--include/gst/base/gstadapter.h149
-rw-r--r--include/gst/base/gstaggregator.h462
-rw-r--r--include/gst/base/gstbaseparse.h385
-rw-r--r--include/gst/base/gstbasesink.h345
-rw-r--r--include/gst/base/gstbasesrc.h346
-rw-r--r--include/gst/base/gstbasetransform.h372
-rw-r--r--include/gst/base/gstbitreader.h328
-rw-r--r--include/gst/base/gstbitwriter.h384
-rw-r--r--include/gst/base/gstbytereader.h684
-rw-r--r--include/gst/base/gstbytewriter.h468
-rw-r--r--include/gst/base/gstcollectpads.h456
-rw-r--r--include/gst/base/gstdataqueue.h184
-rw-r--r--include/gst/base/gstflowcombiner.h82
-rw-r--r--include/gst/base/gstpushsrc.h102
-rw-r--r--include/gst/base/gstqueuearray.h109
-rw-r--r--include/gst/base/gsttypefindhelper.h105
18 files changed, 5040 insertions, 0 deletions
diff --git a/include/gst/base/base-prelude.h b/include/gst/base/base-prelude.h
new file mode 100644
index 0000000000..87defde34e
--- /dev/null
+++ b/include/gst/base/base-prelude.h
@@ -0,0 +1,35 @@
+/* GStreamer Base Library
+ * Copyright (C) 2018 GStreamer developers
+ *
+ * base-prelude.h: prelude include header for gst-base library
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_BASE_PRELUDE_H__
+#define __GST_BASE_PRELUDE_H__
+
+#include <gst/gst.h>
+
+#ifndef GST_BASE_API
+#ifdef BUILDING_GST_BASE
+#define GST_BASE_API GST_API_EXPORT /* from config.h */
+#else
+#define GST_BASE_API GST_API_IMPORT
+#endif
+#endif
+
+#endif /* __GST_BASE_PRELUDE_H__ */
diff --git a/include/gst/base/base.h b/include/gst/base/base.h
new file mode 100644
index 0000000000..5ad42c11b2
--- /dev/null
+++ b/include/gst/base/base.h
@@ -0,0 +1,44 @@
+/* GStreamer
+ * Copyright (C) 2012 GStreamer developers
+ *
+ * base.h: single include header for gst-base library
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_BASE_H__
+#define __GST_BASE_H__
+
+#include <gst/base/base-prelude.h>
+
+#include <gst/base/gstadapter.h>
+#include <gst/base/gstaggregator.h>
+#include <gst/base/gstbaseparse.h>
+#include <gst/base/gstbasesink.h>
+#include <gst/base/gstbasesrc.h>
+#include <gst/base/gstbasetransform.h>
+#include <gst/base/gstbitreader.h>
+#include <gst/base/gstbitwriter.h>
+#include <gst/base/gstbytereader.h>
+#include <gst/base/gstbytewriter.h>
+#include <gst/base/gstcollectpads.h>
+#include <gst/base/gstdataqueue.h>
+#include <gst/base/gstflowcombiner.h>
+#include <gst/base/gstpushsrc.h>
+#include <gst/base/gstqueuearray.h>
+#include <gst/base/gsttypefindhelper.h>
+
+#endif /* __GST_BASE_H__ */
diff --git a/include/gst/base/gstadapter.h b/include/gst/base/gstadapter.h
new file mode 100644
index 0000000000..3945085a49
--- /dev/null
+++ b/include/gst/base/gstadapter.h
@@ -0,0 +1,149 @@
+/* GStreamer
+ * Copyright (C) 2004 Benjamin Otte <otte@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gst/gst.h>
+
+#ifndef __GST_ADAPTER_H__
+#define __GST_ADAPTER_H__
+
+#include <gst/base/base-prelude.h>
+
+G_BEGIN_DECLS
+
+
+#define GST_TYPE_ADAPTER \
+ (gst_adapter_get_type())
+#define GST_ADAPTER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_ADAPTER, GstAdapter))
+#define GST_ADAPTER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_ADAPTER, GstAdapterClass))
+#define GST_ADAPTER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_ADAPTER, GstAdapterClass))
+#define GST_IS_ADAPTER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_ADAPTER))
+#define GST_IS_ADAPTER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_ADAPTER))
+
+/**
+ * GstAdapter:
+ *
+ * The opaque #GstAdapter data structure.
+ */
+typedef struct _GstAdapter GstAdapter;
+typedef struct _GstAdapterClass GstAdapterClass;
+
+GST_BASE_API
+GType gst_adapter_get_type (void);
+
+GST_BASE_API
+GstAdapter * gst_adapter_new (void) G_GNUC_MALLOC;
+
+GST_BASE_API
+void gst_adapter_clear (GstAdapter *adapter);
+
+GST_BASE_API
+void gst_adapter_push (GstAdapter *adapter, GstBuffer* buf);
+
+GST_BASE_API
+gconstpointer gst_adapter_map (GstAdapter *adapter, gsize size);
+
+GST_BASE_API
+void gst_adapter_unmap (GstAdapter *adapter);
+
+GST_BASE_API
+void gst_adapter_copy (GstAdapter *adapter, gpointer dest,
+ gsize offset, gsize size);
+GST_BASE_API
+GBytes * gst_adapter_copy_bytes (GstAdapter *adapter,
+ gsize offset, gsize size);
+GST_BASE_API
+void gst_adapter_flush (GstAdapter *adapter, gsize flush);
+
+GST_BASE_API
+gpointer gst_adapter_take (GstAdapter *adapter, gsize nbytes);
+
+GST_BASE_API
+GstBuffer* gst_adapter_take_buffer (GstAdapter *adapter, gsize nbytes);
+
+GST_BASE_API
+GList* gst_adapter_take_list (GstAdapter *adapter, gsize nbytes);
+
+GST_BASE_API
+GstBuffer * gst_adapter_take_buffer_fast (GstAdapter *adapter, gsize nbytes);
+
+GST_BASE_API
+GstBufferList * gst_adapter_take_buffer_list (GstAdapter *adapter, gsize nbytes);
+
+GST_BASE_API
+GstBuffer* gst_adapter_get_buffer (GstAdapter *adapter, gsize nbytes);
+
+GST_BASE_API
+GList* gst_adapter_get_list (GstAdapter *adapter, gsize nbytes);
+
+GST_BASE_API
+GstBuffer * gst_adapter_get_buffer_fast (GstAdapter *adapter, gsize nbytes);
+
+GST_BASE_API
+GstBufferList * gst_adapter_get_buffer_list (GstAdapter *adapter, gsize nbytes);
+
+GST_BASE_API
+gsize gst_adapter_available (GstAdapter *adapter);
+
+GST_BASE_API
+gsize gst_adapter_available_fast (GstAdapter *adapter);
+
+GST_BASE_API
+GstClockTime gst_adapter_prev_pts (GstAdapter *adapter, guint64 *distance);
+
+GST_BASE_API
+GstClockTime gst_adapter_prev_dts (GstAdapter *adapter, guint64 *distance);
+
+GST_BASE_API
+GstClockTime gst_adapter_prev_pts_at_offset (GstAdapter * adapter, gsize offset, guint64 * distance);
+
+GST_BASE_API
+GstClockTime gst_adapter_prev_dts_at_offset (GstAdapter * adapter, gsize offset, guint64 * distance);
+
+GST_BASE_API
+guint64 gst_adapter_prev_offset (GstAdapter *adapter, guint64 *distance);
+
+GST_BASE_API
+GstClockTime gst_adapter_pts_at_discont (GstAdapter *adapter);
+
+GST_BASE_API
+GstClockTime gst_adapter_dts_at_discont (GstAdapter *adapter);
+
+GST_BASE_API
+guint64 gst_adapter_offset_at_discont (GstAdapter *adapter);
+
+GST_BASE_API
+guint64 gst_adapter_distance_from_discont (GstAdapter *adapter);
+
+GST_BASE_API
+gssize gst_adapter_masked_scan_uint32 (GstAdapter * adapter, guint32 mask,
+ guint32 pattern, gsize offset, gsize size);
+GST_BASE_API
+gssize gst_adapter_masked_scan_uint32_peek (GstAdapter * adapter, guint32 mask,
+ guint32 pattern, gsize offset, gsize size, guint32 * value);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstAdapter, gst_object_unref)
+
+G_END_DECLS
+
+#endif /* __GST_ADAPTER_H__ */
diff --git a/include/gst/base/gstaggregator.h b/include/gst/base/gstaggregator.h
new file mode 100644
index 0000000000..45ced12d39
--- /dev/null
+++ b/include/gst/base/gstaggregator.h
@@ -0,0 +1,462 @@
+/* GStreamer aggregator base class
+ * Copyright (C) 2014 Mathieu Duponchelle <mathieu.duponchelle@oencreed.com>
+ * Copyright (C) 2014 Thibault Saunier <tsaunier@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_AGGREGATOR_H__
+#define __GST_AGGREGATOR_H__
+
+#include <gst/gst.h>
+#include <gst/base/base-prelude.h>
+
+G_BEGIN_DECLS
+
+/**************************
+ * GstAggregator Structs *
+ *************************/
+
+typedef struct _GstAggregator GstAggregator;
+typedef struct _GstAggregatorPrivate GstAggregatorPrivate;
+typedef struct _GstAggregatorClass GstAggregatorClass;
+
+/************************
+ * GstAggregatorPad API *
+ ***********************/
+
+#define GST_TYPE_AGGREGATOR_PAD (gst_aggregator_pad_get_type())
+#define GST_AGGREGATOR_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AGGREGATOR_PAD, GstAggregatorPad))
+#define GST_AGGREGATOR_PAD_CAST(obj) ((GstAggregatorPad *)(obj))
+#define GST_AGGREGATOR_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AGGREGATOR_PAD, GstAggregatorPadClass))
+#define GST_AGGREGATOR_PAD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),GST_TYPE_AGGREGATOR_PAD, GstAggregatorPadClass))
+#define GST_IS_AGGREGATOR_PAD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AGGREGATOR_PAD))
+#define GST_IS_AGGREGATOR_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AGGREGATOR_PAD))
+
+/****************************
+ * GstAggregatorPad Structs *
+ ***************************/
+
+typedef struct _GstAggregatorPad GstAggregatorPad;
+typedef struct _GstAggregatorPadClass GstAggregatorPadClass;
+typedef struct _GstAggregatorPadPrivate GstAggregatorPadPrivate;
+
+/**
+ * GstAggregatorPad:
+ * @segment: last segment received.
+ *
+ * The implementation the GstPad to use with #GstAggregator
+ *
+ * Since: 1.14
+ */
+struct _GstAggregatorPad
+{
+ GstPad parent;
+
+ /*< public >*/
+ /* Protected by the OBJECT_LOCK */
+ GstSegment segment;
+
+ /* < private > */
+ GstAggregatorPadPrivate * priv;
+
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+/**
+ * GstAggregatorPadClass:
+ * @flush: Optional
+ * Called when the pad has received a flush stop, this is the place
+ * to flush any information specific to the pad, it allows for individual
+ * pads to be flushed while others might not be.
+ * @skip_buffer: Optional
+ * Called before input buffers are queued in the pad, return %TRUE
+ * if the buffer should be skipped.
+ *
+ * Since: 1.14
+ */
+struct _GstAggregatorPadClass
+{
+ GstPadClass parent_class;
+
+ GstFlowReturn (*flush) (GstAggregatorPad * aggpad, GstAggregator * aggregator);
+ gboolean (*skip_buffer) (GstAggregatorPad * aggpad, GstAggregator * aggregator, GstBuffer * buffer);
+
+ /*< private >*/
+ gpointer _gst_reserved[GST_PADDING_LARGE];
+};
+
+GST_BASE_API
+GType gst_aggregator_pad_get_type (void);
+
+/****************************
+ * GstAggregatorPad methods *
+ ***************************/
+
+GST_BASE_API
+GstBuffer * gst_aggregator_pad_pop_buffer (GstAggregatorPad * pad);
+
+GST_BASE_API
+GstBuffer * gst_aggregator_pad_peek_buffer (GstAggregatorPad * pad);
+
+GST_BASE_API
+gboolean gst_aggregator_pad_drop_buffer (GstAggregatorPad * pad);
+
+GST_BASE_API
+gboolean gst_aggregator_pad_has_buffer (GstAggregatorPad * pad);
+
+GST_BASE_API
+gboolean gst_aggregator_pad_is_eos (GstAggregatorPad * pad);
+
+GST_BASE_API
+gboolean gst_aggregator_pad_is_inactive (GstAggregatorPad * pad);
+
+/*********************
+ * GstAggregator API *
+ ********************/
+
+#define GST_TYPE_AGGREGATOR (gst_aggregator_get_type())
+#define GST_AGGREGATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AGGREGATOR,GstAggregator))
+#define GST_AGGREGATOR_CAST(obj) ((GstAggregator *)(obj))
+#define GST_AGGREGATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AGGREGATOR,GstAggregatorClass))
+#define GST_AGGREGATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),GST_TYPE_AGGREGATOR,GstAggregatorClass))
+#define GST_IS_AGGREGATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AGGREGATOR))
+#define GST_IS_AGGREGATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AGGREGATOR))
+
+#define GST_AGGREGATOR_FLOW_NEED_DATA GST_FLOW_CUSTOM_ERROR
+
+/**
+ * GstAggregator:
+ * @srcpad: the aggregator's source pad
+ *
+ * Aggregator base class object structure.
+ *
+ * Since: 1.14
+ */
+struct _GstAggregator
+{
+ GstElement parent;
+
+ /*< public >*/
+ GstPad * srcpad;
+
+ /*< private >*/
+ GstAggregatorPrivate * priv;
+
+ gpointer _gst_reserved[GST_PADDING_LARGE];
+};
+
+/**
+ * GstAggregatorClass:
+ * @flush: Optional.
+ * Called after a successful flushing seek, once all the flush
+ * stops have been received. Flush pad-specific data in
+ * #GstAggregatorPad->flush.
+ * @clip: Optional.
+ * Called when a buffer is received on a sink pad, the task of
+ * clipping it and translating it to the current segment falls
+ * on the subclass. The function should use the segment of data
+ * and the negotiated media type on the pad to perform
+ * clipping of input buffer. This function takes ownership of
+ * buf and should output a buffer or return NULL in
+ * if the buffer should be dropped.
+ * @finish_buffer: Optional.
+ * Called when a subclass calls gst_aggregator_finish_buffer()
+ * from their aggregate function to push out a buffer.
+ * Subclasses can override this to modify or decorate buffers
+ * before they get pushed out. This function takes ownership
+ * of the buffer passed. Subclasses that override this method
+ * should always chain up to the parent class virtual method.
+ * @sink_event: Optional.
+ * Called when an event is received on a sink pad, the subclass
+ * should always chain up.
+ * @sink_query: Optional.
+ * Called when a query is received on a sink pad, the subclass
+ * should always chain up.
+ * @src_event: Optional.
+ * Called when an event is received on the src pad, the subclass
+ * should always chain up.
+ * @src_query: Optional.
+ * Called when a query is received on the src pad, the subclass
+ * should always chain up.
+ * @src_activate: Optional.
+ * Called when the src pad is activated, it will start/stop its
+ * pad task right after that call.
+ * @aggregate: Mandatory.
+ * Called when buffers are queued on all sinkpads. Classes
+ * should iterate the GstElement->sinkpads and peek or steal
+ * buffers from the #GstAggregatorPads. If the subclass returns
+ * GST_FLOW_EOS, sending of the eos event will be taken care
+ * of. Once / if a buffer has been constructed from the
+ * aggregated buffers, the subclass should call _finish_buffer.
+ * @stop: Optional.
+ * Called when the element goes from PAUSED to READY.
+ * The subclass should free all resources and reset its state.
+ * @start: Optional.
+ * Called when the element goes from READY to PAUSED.
+ * The subclass should get ready to process
+ * aggregated buffers.
+ * @get_next_time: Optional.
+ * Called when the element needs to know the running time of the next
+ * rendered buffer for live pipelines. This causes deadline
+ * based aggregation to occur. Defaults to returning
+ * GST_CLOCK_TIME_NONE causing the element to wait for buffers
+ * on all sink pads before aggregating.
+ * @create_new_pad: Optional.
+ * Called when a new pad needs to be created. Allows subclass that
+ * don't have a single sink pad template to provide a pad based
+ * on the provided information.
+ * @update_src_caps: Lets subclasses update the #GstCaps representing
+ * the src pad caps before usage. The result should end up
+ * in @ret. Return %GST_AGGREGATOR_FLOW_NEED_DATA to indicate that the
+ * element needs more information (caps, a buffer, etc) to
+ * choose the correct caps. Should return ANY caps if the
+ * stream has not caps at all.
+ * @fixate_src_caps: Optional.
+ * Fixate and return the src pad caps provided. The function takes
+ * ownership of @caps and returns a fixated version of
+ * @caps. @caps is not guaranteed to be writable.
+ * @negotiated_src_caps: Optional.
+ * Notifies subclasses what caps format has been negotiated
+ * @decide_allocation: Optional.
+ * Allows the subclass to influence the allocation choices.
+ * Setup the allocation parameters for allocating output
+ * buffers. The passed in query contains the result of the
+ * downstream allocation query.
+ * @propose_allocation: Optional.
+ * Allows the subclass to handle the allocation query from upstream.
+ * @negotiate: Optional.
+ * Negotiate the caps with the peer (Since: 1.18).
+ * @sink_event_pre_queue: Optional.
+ * Called when an event is received on a sink pad before queueing up
+ * serialized events. The subclass should always chain up (Since: 1.18).
+ * @sink_query_pre_queue: Optional.
+ * Called when a query is received on a sink pad before queueing up
+ * serialized queries. The subclass should always chain up (Since: 1.18).
+ *
+ * The aggregator base class will handle in a thread-safe way all manners of
+ * concurrent flushes, seeks, pad additions and removals, leaving to the
+ * subclass the responsibility of clipping buffers, and aggregating buffers in
+ * the way the implementor sees fit.
+ *
+ * It will also take care of event ordering (stream-start, segment, eos).
+ *
+ * Basically, a simple implementation will override @aggregate, and call
+ * _finish_buffer from inside that function.
+ *
+ * Since: 1.14
+ */
+struct _GstAggregatorClass {
+ GstElementClass parent_class;
+
+ GstFlowReturn (*flush) (GstAggregator * aggregator);
+
+ GstBuffer * (*clip) (GstAggregator * aggregator,
+ GstAggregatorPad * aggregator_pad,
+ GstBuffer * buf);
+
+ GstFlowReturn (*finish_buffer) (GstAggregator * aggregator,
+ GstBuffer * buffer);
+
+ /* sinkpads virtual methods */
+ gboolean (*sink_event) (GstAggregator * aggregator,
+ GstAggregatorPad * aggregator_pad,
+ GstEvent * event);
+
+ gboolean (*sink_query) (GstAggregator * aggregator,
+ GstAggregatorPad * aggregator_pad,
+ GstQuery * query);
+
+ /* srcpad virtual methods */
+ gboolean (*src_event) (GstAggregator * aggregator,
+ GstEvent * event);
+
+ gboolean (*src_query) (GstAggregator * aggregator,
+ GstQuery * query);
+
+ gboolean (*src_activate) (GstAggregator * aggregator,
+ GstPadMode mode,
+ gboolean active);
+
+ GstFlowReturn (*aggregate) (GstAggregator * aggregator,
+ gboolean timeout);
+
+ gboolean (*stop) (GstAggregator * aggregator);
+
+ gboolean (*start) (GstAggregator * aggregator);
+
+ GstClockTime (*get_next_time) (GstAggregator * aggregator);
+
+ GstAggregatorPad * (*create_new_pad) (GstAggregator * self,
+ GstPadTemplate * templ,
+ const gchar * req_name,
+ const GstCaps * caps);
+
+ /**
+ * GstAggregatorClass::update_src_caps:
+ * @ret: (out) (allow-none):
+ */
+ GstFlowReturn (*update_src_caps) (GstAggregator * self,
+ GstCaps * caps,
+ GstCaps ** ret);
+ GstCaps * (*fixate_src_caps) (GstAggregator * self,
+ GstCaps * caps);
+ gboolean (*negotiated_src_caps) (GstAggregator * self,
+ GstCaps * caps);
+ gboolean (*decide_allocation) (GstAggregator * self,
+ GstQuery * query);
+ gboolean (*propose_allocation) (GstAggregator * self,
+ GstAggregatorPad * pad,
+ GstQuery * decide_query,
+ GstQuery * query);
+
+ gboolean (*negotiate) (GstAggregator * self);
+
+ GstFlowReturn (*sink_event_pre_queue) (GstAggregator * aggregator,
+ GstAggregatorPad * aggregator_pad,
+ GstEvent * event);
+
+ gboolean (*sink_query_pre_queue) (GstAggregator * aggregator,
+ GstAggregatorPad * aggregator_pad,
+ GstQuery * query);
+
+ /**
+ * GstAggregatorClass::finish_buffer_list:
+ *
+ * Optional. Equivalent of #GstAggregatorClass::finish_buffer for
+ * buffer lists.
+ *
+ * Since: 1.18
+ */
+ GstFlowReturn (*finish_buffer_list) (GstAggregator * aggregator,
+ GstBufferList * bufferlist);
+ /**
+ * GstAggregatorClass::peek_next_sample:
+ *
+ * See gst_aggregator_peek_next_sample().
+ *
+ * Since: 1.18
+ */
+ GstSample * (*peek_next_sample) (GstAggregator *aggregator,
+ GstAggregatorPad * aggregator_pad);
+
+ /*< private >*/
+ gpointer _gst_reserved[GST_PADDING_LARGE-5];
+};
+
+/************************************
+ * GstAggregator convenience macros *
+ ***********************************/
+
+/**
+ * GST_AGGREGATOR_SRC_PAD:
+ * @agg: a #GstAggregator
+ *
+ * Convenience macro to access the source pad of #GstAggregator
+ *
+ * Since: 1.6
+ */
+#define GST_AGGREGATOR_SRC_PAD(agg) (((GstAggregator *)(agg))->srcpad)
+
+/*************************
+ * GstAggregator methods *
+ ************************/
+
+GST_BASE_API
+GstFlowReturn gst_aggregator_finish_buffer (GstAggregator * aggregator,
+ GstBuffer * buffer);
+
+GST_BASE_API
+GstFlowReturn gst_aggregator_finish_buffer_list (GstAggregator * aggregator,
+ GstBufferList * bufferlist);
+
+GST_BASE_API
+void gst_aggregator_set_src_caps (GstAggregator * self,
+ GstCaps * caps);
+
+GST_BASE_API
+gboolean gst_aggregator_negotiate (GstAggregator * self);
+
+GST_BASE_API
+void gst_aggregator_set_latency (GstAggregator * self,
+ GstClockTime min_latency,
+ GstClockTime max_latency);
+
+GST_BASE_API
+GType gst_aggregator_get_type(void);
+
+GST_BASE_API
+GstClockTime gst_aggregator_get_latency (GstAggregator * self);
+
+GST_BASE_API
+GstBufferPool * gst_aggregator_get_buffer_pool (GstAggregator * self);
+
+GST_BASE_API
+void gst_aggregator_get_allocator (GstAggregator * self,
+ GstAllocator ** allocator,
+ GstAllocationParams * params);
+
+GST_BASE_API
+GstClockTime gst_aggregator_simple_get_next_time (GstAggregator * self);
+
+GST_BASE_API
+void gst_aggregator_update_segment (GstAggregator * self,
+ const GstSegment * segment);
+
+GST_BASE_API
+GstSample * gst_aggregator_peek_next_sample (GstAggregator *self,
+ GstAggregatorPad * pad);
+
+GST_BASE_API
+void gst_aggregator_selected_samples (GstAggregator * self,
+ GstClockTime pts,
+ GstClockTime dts,
+ GstClockTime duration,
+ GstStructure * info);
+
+GST_BASE_API
+void gst_aggregator_set_ignore_inactive_pads (GstAggregator * self,
+ gboolean ignore);
+
+GST_BASE_API
+gboolean gst_aggregator_get_ignore_inactive_pads (GstAggregator * self);
+
+/**
+ * GstAggregatorStartTimeSelection:
+ * @GST_AGGREGATOR_START_TIME_SELECTION_ZERO: Start at running time 0.
+ * @GST_AGGREGATOR_START_TIME_SELECTION_FIRST: Start at the running time of
+ * the first buffer that is received.
+ * @GST_AGGREGATOR_START_TIME_SELECTION_SET: Start at the running time
+ * selected by the `start-time` property.
+ *
+ * Since: 1.18
+ */
+typedef enum
+{
+ GST_AGGREGATOR_START_TIME_SELECTION_ZERO,
+ GST_AGGREGATOR_START_TIME_SELECTION_FIRST,
+ GST_AGGREGATOR_START_TIME_SELECTION_SET
+} GstAggregatorStartTimeSelection;
+
+GST_BASE_API
+GType gst_aggregator_start_time_selection_get_type (void);
+
+G_END_DECLS
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstAggregator, gst_object_unref)
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstAggregatorPad, gst_object_unref)
+
+#endif /* __GST_AGGREGATOR_H__ */
diff --git a/include/gst/base/gstbaseparse.h b/include/gst/base/gstbaseparse.h
new file mode 100644
index 0000000000..06e4409505
--- /dev/null
+++ b/include/gst/base/gstbaseparse.h
@@ -0,0 +1,385 @@
+/* GStreamer
+ * Copyright (C) 2008 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Stefan Kost <stefan.kost@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_BASE_PARSE_H__
+#define __GST_BASE_PARSE_H__
+
+#include <gst/gst.h>
+#include <gst/base/base-prelude.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_BASE_PARSE (gst_base_parse_get_type())
+#define GST_BASE_PARSE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_BASE_PARSE,GstBaseParse))
+#define GST_BASE_PARSE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_BASE_PARSE,GstBaseParseClass))
+#define GST_BASE_PARSE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_BASE_PARSE,GstBaseParseClass))
+#define GST_IS_BASE_PARSE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_BASE_PARSE))
+#define GST_IS_BASE_PARSE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_BASE_PARSE))
+#define GST_BASE_PARSE_CAST(obj) ((GstBaseParse *)(obj))
+
+/**
+ * GST_BASE_PARSE_SRC_PAD:
+ * @obj: base parse instance
+ *
+ * Gives the pointer to the source #GstPad object of the element.
+ */
+#define GST_BASE_PARSE_SRC_PAD(obj) (GST_BASE_PARSE_CAST (obj)->srcpad)
+
+/**
+ * GST_BASE_PARSE_SINK_PAD:
+ * @obj: base parse instance
+ *
+ * Gives the pointer to the sink #GstPad object of the element.
+ */
+#define GST_BASE_PARSE_SINK_PAD(obj) (GST_BASE_PARSE_CAST (obj)->sinkpad)
+
+/**
+ * GST_BASE_PARSE_FLOW_DROPPED:
+ *
+ * A #GstFlowReturn that can be returned from
+ * #GstBaseParseClass::handle_frame to indicate that no output buffer was
+ * generated, or from #GstBaseParseClass::pre_push_frame to to forego
+ * pushing buffer.
+ */
+#define GST_BASE_PARSE_FLOW_DROPPED GST_FLOW_CUSTOM_SUCCESS
+
+/* not public API, use accessor macros below */
+#define GST_BASE_PARSE_FLAG_LOST_SYNC (1 << 0)
+#define GST_BASE_PARSE_FLAG_DRAINING (1 << 1)
+
+/**
+ * GST_BASE_PARSE_LOST_SYNC:
+ * @parse: base parse instance
+ *
+ * Obtains current sync status.
+ */
+#define GST_BASE_PARSE_LOST_SYNC(parse) (!!(GST_BASE_PARSE_CAST(parse)->flags & GST_BASE_PARSE_FLAG_LOST_SYNC))
+
+/**
+ * GST_BASE_PARSE_DRAINING:
+ * @parse: base parse instance
+ *
+ * Obtains current drain status (ie. whether EOS has been received and
+ * the parser is now processing the frames at the end of the stream)
+ */
+#define GST_BASE_PARSE_DRAINING(parse) (!!(GST_BASE_PARSE_CAST(parse)->flags & GST_BASE_PARSE_FLAG_DRAINING))
+
+/**
+ * GstBaseParseFrameFlags:
+ * @GST_BASE_PARSE_FRAME_FLAG_NONE: no flag
+ * @GST_BASE_PARSE_FRAME_FLAG_NEW_FRAME: set by baseclass if current frame
+ * is passed for processing to the subclass for the first time
+ * (and not set on subsequent calls with same data).
+ * @GST_BASE_PARSE_FRAME_FLAG_NO_FRAME: set to indicate this buffer should not be
+ * counted as frame, e.g. if this frame is dependent on a previous one.
+ * As it is not counted as a frame, bitrate increases but frame to time
+ * conversions are maintained.
+ * @GST_BASE_PARSE_FRAME_FLAG_CLIP: @pre_push_frame can set this to indicate
+ * that regular segment clipping can still be performed (as opposed to
+ * any custom one having been done).
+ * @GST_BASE_PARSE_FRAME_FLAG_DROP: indicates to @finish_frame that the
+ * the frame should be dropped (and might be handled internally by subclass)
+ * @GST_BASE_PARSE_FRAME_FLAG_QUEUE: indicates to @finish_frame that the
+ * the frame should be queued for now and processed fully later
+ * when the first non-queued frame is finished
+ *
+ * Flags to be used in a #GstBaseParseFrame.
+ */
+typedef enum {
+ GST_BASE_PARSE_FRAME_FLAG_NONE = 0,
+ GST_BASE_PARSE_FRAME_FLAG_NEW_FRAME = (1 << 0),
+ GST_BASE_PARSE_FRAME_FLAG_NO_FRAME = (1 << 1),
+ GST_BASE_PARSE_FRAME_FLAG_CLIP = (1 << 2),
+ GST_BASE_PARSE_FRAME_FLAG_DROP = (1 << 3),
+ GST_BASE_PARSE_FRAME_FLAG_QUEUE = (1 << 4)
+} GstBaseParseFrameFlags;
+
+/**
+ * GstBaseParseFrame:
+ * @buffer: input data to be parsed for frames.
+ * @out_buffer: output data.
+ * @offset: media specific offset of input frame
+ * Note that a converter may have a different one on the frame's buffer.
+ * @overhead: subclass can set this to indicates the metadata overhead
+ * for the given frame, which is then used to enable more accurate bitrate
+ * computations. If this is -1, it is assumed that this frame should be
+ * skipped in bitrate calculation.
+ * @flags: a combination of input and output #GstBaseParseFrameFlags that
+ * convey additional context to subclass or allow subclass to tune
+ * subsequent #GstBaseParse actions.
+ *
+ * Frame (context) data passed to each frame parsing virtual methods. In
+ * addition to providing the data to be checked for a valid frame or an already
+ * identified frame, it conveys additional metadata or control information
+ * from and to the subclass w.r.t. the particular frame in question (rather
+ * than global parameters). Some of these may apply to each parsing stage, others
+ * only to some a particular one. These parameters are effectively zeroed at start
+ * of each frame's processing, i.e. parsing virtual method invocation sequence.
+ */
+typedef struct {
+ GstBuffer * buffer;
+ GstBuffer * out_buffer;
+ guint flags;
+ guint64 offset;
+ gint overhead;
+ /*< private >*/
+ gint size;
+ guint _gst_reserved_i[2];
+ gpointer _gst_reserved_p[2];
+ guint _private_flags;
+} GstBaseParseFrame;
+
+typedef struct _GstBaseParse GstBaseParse;
+typedef struct _GstBaseParseClass GstBaseParseClass;
+typedef struct _GstBaseParsePrivate GstBaseParsePrivate;
+
+/**
+ * GstBaseParse:
+ * @element: the parent element.
+ *
+ * The opaque #GstBaseParse data structure.
+ */
+struct _GstBaseParse {
+ /*< public >*/
+ GstElement element;
+
+ /*< protected >*/
+ /* source and sink pads */
+ GstPad *sinkpad;
+ GstPad *srcpad;
+
+ guint flags;
+
+ /* MT-protected (with STREAM_LOCK) */
+ GstSegment segment;
+
+ /*< private >*/
+ gpointer _gst_reserved[GST_PADDING_LARGE];
+ GstBaseParsePrivate *priv;
+};
+
+/**
+ * GstBaseParseClass:
+ * @parent_class: the parent class
+ * @start: Optional.
+ * Called when the element starts processing.
+ * Allows opening external resources.
+ * @stop: Optional.
+ * Called when the element stops processing.
+ * Allows closing external resources.
+ * @set_sink_caps: Optional.
+ * Allows the subclass to be notified of the actual caps set.
+ * @get_sink_caps: Optional.
+ * Allows the subclass to do its own sink get caps if needed.
+ * @handle_frame: Parses the input data into valid frames as defined by subclass
+ * which should be passed to gst_base_parse_finish_frame().
+ * The frame's input buffer is guaranteed writable,
+ * whereas the input frame ownership is held by caller
+ * (so subclass should make a copy if it needs to hang on).
+ * Input buffer (data) is provided by baseclass with as much
+ * metadata set as possible by baseclass according to upstream
+ * information and/or subclass settings,
+ * though subclass may still set buffer timestamp and duration
+ * if desired.
+ * @convert: Optional.
+ * Convert between formats.
+ * @sink_event: Optional.
+ * Event handler on the sink pad. This function should chain
+ * up to the parent implementation to let the default handler
+ * run.
+ * @src_event: Optional.
+ * Event handler on the source pad. Should chain up to the
+ * parent to let the default handler run.
+ * @pre_push_frame: Optional.
+ * Called just prior to pushing a frame (after any pending
+ * events have been sent) to give subclass a chance to perform
+ * additional actions at this time (e.g. tag sending) or to
+ * decide whether this buffer should be dropped or not
+ * (e.g. custom segment clipping).
+ * @detect: Optional.
+ * Called until it doesn't return GST_FLOW_OK anymore for
+ * the first buffers. Can be used by the subclass to detect
+ * the stream format.
+ * @sink_query: Optional.
+ * Query handler on the sink pad. This function should chain
+ * up to the parent implementation to let the default handler
+ * run (Since: 1.2)
+ * @src_query: Optional.
+ * Query handler on the source pad. Should chain up to the
+ * parent to let the default handler run (Since: 1.2)
+ *
+ * Subclasses can override any of the available virtual methods or not, as
+ * needed. At minimum @handle_frame needs to be overridden.
+ */
+struct _GstBaseParseClass {
+ GstElementClass parent_class;
+
+ /*< public >*/
+ /* virtual methods for subclasses */
+
+ gboolean (*start) (GstBaseParse * parse);
+
+ gboolean (*stop) (GstBaseParse * parse);
+
+ gboolean (*set_sink_caps) (GstBaseParse * parse,
+ GstCaps * caps);
+
+ /**
+ * GstBaseParseClass::handle_frame:
+ * @skipsize: (out):
+ *
+ * Parses the input data into valid frames as defined by subclass
+ * which should be passed to gst_base_parse_finish_frame().
+ * The frame's input buffer is guaranteed writable,
+ * whereas the input frame ownership is held by caller
+ * (so subclass should make a copy if it needs to hang on).
+ * Input buffer (data) is provided by baseclass with as much
+ * metadata set as possible by baseclass according to upstream
+ * information and/or subclass settings,
+ * though subclass may still set buffer timestamp and duration
+ * if desired.
+ */
+ GstFlowReturn (*handle_frame) (GstBaseParse * parse,
+ GstBaseParseFrame * frame,
+ gint * skipsize);
+
+ GstFlowReturn (*pre_push_frame) (GstBaseParse * parse,
+ GstBaseParseFrame * frame);
+
+ gboolean (*convert) (GstBaseParse * parse,
+ GstFormat src_format,
+ gint64 src_value,
+ GstFormat dest_format,
+ gint64 * dest_value);
+
+ gboolean (*sink_event) (GstBaseParse * parse,
+ GstEvent * event);
+
+ gboolean (*src_event) (GstBaseParse * parse,
+ GstEvent * event);
+
+ GstCaps * (*get_sink_caps) (GstBaseParse * parse,
+ GstCaps * filter);
+
+ GstFlowReturn (*detect) (GstBaseParse * parse,
+ GstBuffer * buffer);
+
+ gboolean (*sink_query) (GstBaseParse * parse,
+ GstQuery * query);
+
+ gboolean (*src_query) (GstBaseParse * parse,
+ GstQuery * query);
+
+ /*< private >*/
+ gpointer _gst_reserved[GST_PADDING_LARGE - 2];
+};
+
+GST_BASE_API
+GType gst_base_parse_get_type (void);
+
+GST_BASE_API
+GType gst_base_parse_frame_get_type (void);
+
+GST_BASE_API
+GstBaseParseFrame * gst_base_parse_frame_new (GstBuffer * buffer,
+ GstBaseParseFrameFlags flags,
+ gint overhead);
+GST_BASE_API
+void gst_base_parse_frame_init (GstBaseParseFrame * frame);
+
+GST_BASE_API
+GstBaseParseFrame * gst_base_parse_frame_copy (GstBaseParseFrame * frame);
+GST_BASE_API
+void gst_base_parse_frame_free (GstBaseParseFrame * frame);
+
+GST_BASE_API
+GstFlowReturn gst_base_parse_push_frame (GstBaseParse * parse,
+ GstBaseParseFrame * frame);
+GST_BASE_API
+GstFlowReturn gst_base_parse_finish_frame (GstBaseParse * parse,
+ GstBaseParseFrame * frame,
+ gint size);
+GST_BASE_API
+void gst_base_parse_set_duration (GstBaseParse * parse,
+ GstFormat fmt,
+ gint64 duration,
+ gint interval);
+GST_BASE_API
+void gst_base_parse_set_average_bitrate (GstBaseParse * parse,
+ guint bitrate);
+GST_BASE_API
+void gst_base_parse_set_min_frame_size (GstBaseParse * parse,
+ guint min_size);
+GST_BASE_API
+void gst_base_parse_set_has_timing_info (GstBaseParse * parse,
+ gboolean has_timing);
+GST_BASE_API
+void gst_base_parse_drain (GstBaseParse * parse);
+
+GST_BASE_API
+void gst_base_parse_set_syncable (GstBaseParse * parse,
+ gboolean syncable);
+GST_BASE_API
+void gst_base_parse_set_passthrough (GstBaseParse * parse,
+ gboolean passthrough);
+GST_BASE_API
+void gst_base_parse_set_pts_interpolation (GstBaseParse * parse,
+ gboolean pts_interpolate);
+GST_BASE_API
+void gst_base_parse_set_infer_ts (GstBaseParse * parse,
+ gboolean infer_ts);
+GST_BASE_API
+void gst_base_parse_set_frame_rate (GstBaseParse * parse,
+ guint fps_num,
+ guint fps_den,
+ guint lead_in,
+ guint lead_out);
+GST_BASE_API
+void gst_base_parse_set_latency (GstBaseParse * parse,
+ GstClockTime min_latency,
+ GstClockTime max_latency);
+GST_BASE_API
+gboolean gst_base_parse_convert_default (GstBaseParse * parse,
+ GstFormat src_format,
+ gint64 src_value,
+ GstFormat dest_format,
+ gint64 * dest_value);
+GST_BASE_API
+gboolean gst_base_parse_add_index_entry (GstBaseParse * parse,
+ guint64 offset,
+ GstClockTime ts,
+ gboolean key,
+ gboolean force);
+GST_BASE_API
+void gst_base_parse_set_ts_at_offset (GstBaseParse *parse,
+ gsize offset);
+GST_BASE_API
+void gst_base_parse_merge_tags (GstBaseParse * parse,
+ GstTagList * tags,
+ GstTagMergeMode mode);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstBaseParseFrame, gst_base_parse_frame_free)
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstBaseParse, gst_object_unref)
+
+G_END_DECLS
+
+#endif /* __GST_BASE_PARSE_H__ */
diff --git a/include/gst/base/gstbasesink.h b/include/gst/base/gstbasesink.h
new file mode 100644
index 0000000000..e68560c6f5
--- /dev/null
+++ b/include/gst/base/gstbasesink.h
@@ -0,0 +1,345 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ * 2000 Wim Taymans <wtay@chello.be>
+ *
+ * gstbasesink.h:
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_BASE_SINK_H__
+#define __GST_BASE_SINK_H__
+
+#include <gst/gst.h>
+#include <gst/base/base-prelude.h>
+
+G_BEGIN_DECLS
+
+
+#define GST_TYPE_BASE_SINK (gst_base_sink_get_type())
+#define GST_BASE_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_BASE_SINK,GstBaseSink))
+#define GST_BASE_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_BASE_SINK,GstBaseSinkClass))
+#define GST_BASE_SINK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_BASE_SINK, GstBaseSinkClass))
+#define GST_IS_BASE_SINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_BASE_SINK))
+#define GST_IS_BASE_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_BASE_SINK))
+#define GST_BASE_SINK_CAST(obj) ((GstBaseSink *) (obj))
+
+/**
+ * GST_BASE_SINK_PAD:
+ * @obj: base sink instance
+ *
+ * Gives the pointer to the #GstPad object of the element.
+ */
+#define GST_BASE_SINK_PAD(obj) (GST_BASE_SINK_CAST (obj)->sinkpad)
+
+#define GST_BASE_SINK_GET_PREROLL_LOCK(obj) (&GST_BASE_SINK_CAST(obj)->preroll_lock)
+#define GST_BASE_SINK_PREROLL_LOCK(obj) (g_mutex_lock(GST_BASE_SINK_GET_PREROLL_LOCK(obj)))
+#define GST_BASE_SINK_PREROLL_TRYLOCK(obj) (g_mutex_trylock(GST_BASE_SINK_GET_PREROLL_LOCK(obj)))
+#define GST_BASE_SINK_PREROLL_UNLOCK(obj) (g_mutex_unlock(GST_BASE_SINK_GET_PREROLL_LOCK(obj)))
+
+#define GST_BASE_SINK_GET_PREROLL_COND(obj) (&GST_BASE_SINK_CAST(obj)->preroll_cond)
+#define GST_BASE_SINK_PREROLL_WAIT(obj) \
+ g_cond_wait (GST_BASE_SINK_GET_PREROLL_COND (obj), GST_BASE_SINK_GET_PREROLL_LOCK (obj))
+#define GST_BASE_SINK_PREROLL_WAIT_UNTIL(obj, end_time) \
+ g_cond_wait_until (GST_BASE_SINK_GET_PREROLL_COND (obj), GST_BASE_SINK_GET_PREROLL_LOCK (obj), end_time)
+#define GST_BASE_SINK_PREROLL_SIGNAL(obj) g_cond_signal (GST_BASE_SINK_GET_PREROLL_COND (obj));
+#define GST_BASE_SINK_PREROLL_BROADCAST(obj) g_cond_broadcast (GST_BASE_SINK_GET_PREROLL_COND (obj));
+
+typedef struct _GstBaseSink GstBaseSink;
+typedef struct _GstBaseSinkClass GstBaseSinkClass;
+typedef struct _GstBaseSinkPrivate GstBaseSinkPrivate;
+
+/**
+ * GstBaseSink:
+ *
+ * The opaque #GstBaseSink data structure.
+ */
+struct _GstBaseSink {
+ GstElement element;
+
+ /*< protected >*/
+ GstPad *sinkpad;
+ GstPadMode pad_mode;
+
+ /*< protected >*/ /* with LOCK */
+ guint64 offset;
+ gboolean can_activate_pull;
+ gboolean can_activate_push;
+
+ /*< protected >*/ /* with PREROLL_LOCK */
+ GMutex preroll_lock;
+ GCond preroll_cond;
+ gboolean eos;
+ gboolean need_preroll;
+ gboolean have_preroll;
+ gboolean playing_async;
+
+ /*< protected >*/ /* with STREAM_LOCK */
+ gboolean have_newsegment;
+ GstSegment segment;
+
+ /*< private >*/ /* with LOCK */
+ GstClockID clock_id;
+ gboolean sync;
+ gboolean flushing;
+ gboolean running;
+
+ gint64 max_lateness;
+
+ /*< private >*/
+ GstBaseSinkPrivate *priv;
+
+ gpointer _gst_reserved[GST_PADDING_LARGE];
+};
+
+/**
+ * GstBaseSinkClass:
+ * @parent_class: Element parent class
+ * @get_caps: Called to get sink pad caps from the subclass
+ * @set_caps: Notify subclass of changed caps
+ * @fixate: Only useful in pull mode. Implement if you have
+ * ideas about what should be the default values for the caps you support.
+ * @activate_pull: Subclasses should override this when they can provide an
+ * alternate method of spawning a thread to drive the pipeline in pull mode.
+ * Should start or stop the pulling thread, depending on the value of the
+ * "active" argument. Called after actually activating the sink pad in pull
+ * mode. The default implementation starts a task on the sink pad.
+ * @get_times: Called to get the start and end times for synchronising
+ * the passed buffer to the clock
+ * @propose_allocation: configure the allocation query
+ * @start: Start processing. Ideal for opening resources in the subclass
+ * @stop: Stop processing. Subclasses should use this to close resources.
+ * @unlock: Unlock any pending access to the resource. Subclasses should
+ * unblock any blocked function ASAP and call gst_base_sink_wait_preroll()
+ * @unlock_stop: Clear the previous unlock request. Subclasses should clear
+ * any state they set during #GstBaseSinkClass::unlock, and be ready to
+ * continue where they left off after gst_base_sink_wait_preroll(),
+ * gst_base_sink_wait() or gst_wait_sink_wait_clock() return or
+ * #GstBaseSinkClass::render is called again.
+ * @query: perform a #GstQuery on the element.
+ * @event: Override this to handle events arriving on the sink pad
+ * @wait_event: Override this to implement custom logic to wait for the event
+ * time (for events like EOS and GAP). Subclasses should always first
+ * chain up to the default implementation.
+ * @prepare: Called to prepare the buffer for @render and @preroll. This
+ * function is called before synchronisation is performed.
+ * @prepare_list: Called to prepare the buffer list for @render_list. This
+ * function is called before synchronisation is performed.
+ * @preroll: Called to present the preroll buffer if desired.
+ * @render: Called when a buffer should be presented or output, at the
+ * correct moment if the #GstBaseSink has been set to sync to the clock.
+ * @render_list: Same as @render but used with buffer lists instead of
+ * buffers.
+ *
+ * Subclasses can override any of the available virtual methods or not, as
+ * needed. At the minimum, the @render method should be overridden to
+ * output/present buffers.
+ */
+struct _GstBaseSinkClass {
+ GstElementClass parent_class;
+
+ /**
+ * GstBaseSink::get_caps:
+ * @filter: (in) (nullable):
+ *
+ * Called to get sink pad caps from the subclass.
+ */
+ GstCaps* (*get_caps) (GstBaseSink *sink, GstCaps *filter);
+ /* notify subclass of new caps */
+ gboolean (*set_caps) (GstBaseSink *sink, GstCaps *caps);
+
+ /* fixate sink caps during pull-mode negotiation */
+ GstCaps * (*fixate) (GstBaseSink *sink, GstCaps *caps);
+ /* start or stop a pulling thread */
+ gboolean (*activate_pull)(GstBaseSink *sink, gboolean active);
+
+ /**
+ * GstBaseSink::get_times:
+ * @start: (out): the start #GstClockTime
+ * @end: (out): the end #GstClockTime
+ *
+ * Get the start and end times for syncing on this buffer.
+ */
+ void (*get_times) (GstBaseSink *sink, GstBuffer *buffer,
+ GstClockTime *start, GstClockTime *end);
+
+ /* propose allocation parameters for upstream */
+ gboolean (*propose_allocation) (GstBaseSink *sink, GstQuery *query);
+
+ /* start and stop processing, ideal for opening/closing the resource */
+ gboolean (*start) (GstBaseSink *sink);
+ gboolean (*stop) (GstBaseSink *sink);
+
+ /* unlock any pending access to the resource. subclasses should unlock
+ * any function ASAP. */
+ gboolean (*unlock) (GstBaseSink *sink);
+ /* Clear a previously indicated unlock request not that unlocking is
+ * complete. Sub-classes should clear any command queue or indicator they
+ * set during unlock */
+ gboolean (*unlock_stop) (GstBaseSink *sink);
+
+ /* notify subclass of query */
+ gboolean (*query) (GstBaseSink *sink, GstQuery *query);
+
+ /* notify subclass of event */
+ gboolean (*event) (GstBaseSink *sink, GstEvent *event);
+ /* wait for eos or gap, subclasses should chain up to parent first */
+ GstFlowReturn (*wait_event) (GstBaseSink *sink, GstEvent *event);
+
+ /* notify subclass of buffer or list before doing sync */
+ GstFlowReturn (*prepare) (GstBaseSink *sink, GstBuffer *buffer);
+ GstFlowReturn (*prepare_list) (GstBaseSink *sink, GstBufferList *buffer_list);
+
+ /* notify subclass of preroll buffer or real buffer */
+ GstFlowReturn (*preroll) (GstBaseSink *sink, GstBuffer *buffer);
+ GstFlowReturn (*render) (GstBaseSink *sink, GstBuffer *buffer);
+ /* Render a BufferList */
+ GstFlowReturn (*render_list) (GstBaseSink *sink, GstBufferList *buffer_list);
+
+ /*< private >*/
+ gpointer _gst_reserved[GST_PADDING_LARGE];
+};
+
+GST_BASE_API
+GType gst_base_sink_get_type (void);
+
+GST_BASE_API
+GstFlowReturn gst_base_sink_do_preroll (GstBaseSink *sink, GstMiniObject *obj);
+
+GST_BASE_API
+GstFlowReturn gst_base_sink_wait_preroll (GstBaseSink *sink);
+
+/* synchronizing against the clock */
+
+GST_BASE_API
+void gst_base_sink_set_sync (GstBaseSink *sink, gboolean sync);
+
+GST_BASE_API
+gboolean gst_base_sink_get_sync (GstBaseSink *sink);
+
+/* Drop buffers which are out of segment */
+
+GST_BASE_API
+void gst_base_sink_set_drop_out_of_segment (GstBaseSink *sink, gboolean drop_out_of_segment);
+
+GST_BASE_API
+gboolean gst_base_sink_get_drop_out_of_segment (GstBaseSink *sink);
+
+/* dropping late buffers */
+
+GST_BASE_API
+void gst_base_sink_set_max_lateness (GstBaseSink *sink, gint64 max_lateness);
+
+GST_BASE_API
+gint64 gst_base_sink_get_max_lateness (GstBaseSink *sink);
+
+/* performing QoS */
+
+GST_BASE_API
+void gst_base_sink_set_qos_enabled (GstBaseSink *sink, gboolean enabled);
+
+GST_BASE_API
+gboolean gst_base_sink_is_qos_enabled (GstBaseSink *sink);
+
+/* doing async state changes */
+
+GST_BASE_API
+void gst_base_sink_set_async_enabled (GstBaseSink *sink, gboolean enabled);
+
+GST_BASE_API
+gboolean gst_base_sink_is_async_enabled (GstBaseSink *sink);
+
+/* tuning synchronisation */
+
+GST_BASE_API
+void gst_base_sink_set_ts_offset (GstBaseSink *sink, GstClockTimeDiff offset);
+
+GST_BASE_API
+GstClockTimeDiff gst_base_sink_get_ts_offset (GstBaseSink *sink);
+
+/* last sample */
+
+GST_BASE_API
+GstSample * gst_base_sink_get_last_sample (GstBaseSink *sink);
+
+GST_BASE_API
+void gst_base_sink_set_last_sample_enabled (GstBaseSink *sink, gboolean enabled);
+
+GST_BASE_API
+gboolean gst_base_sink_is_last_sample_enabled (GstBaseSink *sink);
+
+/* latency */
+
+GST_BASE_API
+gboolean gst_base_sink_query_latency (GstBaseSink *sink, gboolean *live, gboolean *upstream_live,
+ GstClockTime *min_latency, GstClockTime *max_latency);
+GST_BASE_API
+GstClockTime gst_base_sink_get_latency (GstBaseSink *sink);
+
+/* render delay */
+
+GST_BASE_API
+void gst_base_sink_set_render_delay (GstBaseSink *sink, GstClockTime delay);
+
+GST_BASE_API
+GstClockTime gst_base_sink_get_render_delay (GstBaseSink *sink);
+
+/* blocksize */
+
+GST_BASE_API
+void gst_base_sink_set_blocksize (GstBaseSink *sink, guint blocksize);
+
+GST_BASE_API
+guint gst_base_sink_get_blocksize (GstBaseSink *sink);
+
+/* throttle-time */
+
+GST_BASE_API
+void gst_base_sink_set_throttle_time (GstBaseSink *sink, guint64 throttle);
+
+GST_BASE_API
+guint64 gst_base_sink_get_throttle_time (GstBaseSink *sink);
+
+/* max-bitrate */
+
+GST_BASE_API
+void gst_base_sink_set_max_bitrate (GstBaseSink *sink, guint64 max_bitrate);
+
+GST_BASE_API
+guint64 gst_base_sink_get_max_bitrate (GstBaseSink *sink);
+
+/* processing deadline */
+GST_BASE_API
+void gst_base_sink_set_processing_deadline (GstBaseSink *sink, GstClockTime processing_deadline);
+
+GST_BASE_API
+GstClockTime gst_base_sink_get_processing_deadline (GstBaseSink *sink);
+
+GST_BASE_API
+GstClockReturn gst_base_sink_wait_clock (GstBaseSink *sink, GstClockTime time,
+ GstClockTimeDiff * jitter);
+GST_BASE_API
+GstFlowReturn gst_base_sink_wait (GstBaseSink *sink, GstClockTime time,
+ GstClockTimeDiff *jitter);
+
+GST_BASE_API
+GstStructure *gst_base_sink_get_stats (GstBaseSink * sink);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstBaseSink, gst_object_unref)
+
+G_END_DECLS
+
+#endif /* __GST_BASE_SINK_H__ */
diff --git a/include/gst/base/gstbasesrc.h b/include/gst/base/gstbasesrc.h
new file mode 100644
index 0000000000..38c3ef3d8e
--- /dev/null
+++ b/include/gst/base/gstbasesrc.h
@@ -0,0 +1,346 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ * 2000 Wim Taymans <wtay@chello.be>
+ * 2005 Wim Taymans <wim@fluendo.com>
+ *
+ * gstbasesrc.h:
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_BASE_SRC_H__
+#define __GST_BASE_SRC_H__
+
+#include <gst/gst.h>
+#include <gst/base/base-prelude.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_BASE_SRC (gst_base_src_get_type())
+#define GST_BASE_SRC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_BASE_SRC,GstBaseSrc))
+#define GST_BASE_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_BASE_SRC,GstBaseSrcClass))
+#define GST_BASE_SRC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_BASE_SRC, GstBaseSrcClass))
+#define GST_IS_BASE_SRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_BASE_SRC))
+#define GST_IS_BASE_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_BASE_SRC))
+#define GST_BASE_SRC_CAST(obj) ((GstBaseSrc *)(obj))
+
+/**
+ * GstBaseSrcFlags:
+ * @GST_BASE_SRC_FLAG_STARTING: has source is starting
+ * @GST_BASE_SRC_FLAG_STARTED: has source been started
+ * @GST_BASE_SRC_FLAG_LAST: offset to define more flags
+ *
+ * The #GstElement flags that a basesrc element may have.
+ */
+typedef enum {
+ GST_BASE_SRC_FLAG_STARTING = (GST_ELEMENT_FLAG_LAST << 0),
+ GST_BASE_SRC_FLAG_STARTED = (GST_ELEMENT_FLAG_LAST << 1),
+ /* padding */
+ GST_BASE_SRC_FLAG_LAST = (GST_ELEMENT_FLAG_LAST << 6)
+} GstBaseSrcFlags;
+
+#define GST_BASE_SRC_IS_STARTING(obj) GST_OBJECT_FLAG_IS_SET ((obj), GST_BASE_SRC_FLAG_STARTING)
+#define GST_BASE_SRC_IS_STARTED(obj) GST_OBJECT_FLAG_IS_SET ((obj), GST_BASE_SRC_FLAG_STARTED)
+
+typedef struct _GstBaseSrc GstBaseSrc;
+typedef struct _GstBaseSrcClass GstBaseSrcClass;
+typedef struct _GstBaseSrcPrivate GstBaseSrcPrivate;
+
+/**
+ * GST_BASE_SRC_PAD:
+ * @obj: base source instance
+ *
+ * Gives the pointer to the #GstPad object of the element.
+ */
+#define GST_BASE_SRC_PAD(obj) (GST_BASE_SRC_CAST (obj)->srcpad)
+
+
+/**
+ * GstBaseSrc:
+ *
+ * The opaque #GstBaseSrc data structure.
+ */
+struct _GstBaseSrc {
+ GstElement element;
+
+ /*< protected >*/
+ GstPad *srcpad;
+
+ /* available to subclass implementations */
+ /* MT-protected (with LIVE_LOCK) */
+ GMutex live_lock;
+ GCond live_cond;
+ gboolean is_live;
+ gboolean live_running;
+
+ /* MT-protected (with LOCK) */
+ guint blocksize; /* size of buffers when operating push based */
+ gboolean can_activate_push; /* some scheduling properties */
+ gboolean random_access;
+
+ GstClockID clock_id; /* for syncing */
+
+ /* MT-protected (with STREAM_LOCK *and* OBJECT_LOCK) */
+ GstSegment segment;
+ /* MT-protected (with STREAM_LOCK) */
+ gboolean need_newsegment;
+
+ gint num_buffers;
+ gint num_buffers_left;
+
+#ifndef GST_REMOVE_DEPRECATED
+ gboolean typefind; /* unused */
+#endif
+
+ gboolean running;
+ GstEvent *pending_seek;
+
+ GstBaseSrcPrivate *priv;
+
+ /*< private >*/
+ gpointer _gst_reserved[GST_PADDING_LARGE];
+};
+
+/**
+ * GstBaseSrcClass:
+ * @parent_class: Element parent class
+ * @get_caps: Called to get the caps to report
+ * @negotiate: Negotiated the caps with the peer.
+ * @fixate: Called during negotiation if caps need fixating. Implement instead of
+ * setting a fixate function on the source pad.
+ * @set_caps: Notify subclass of changed output caps
+ * @decide_allocation: configure the allocation query
+ * @start: Start processing. Subclasses should open resources and prepare
+ * to produce data. Implementation should call gst_base_src_start_complete()
+ * when the operation completes, either from the current thread or any other
+ * thread that finishes the start operation asynchronously.
+ * @stop: Stop processing. Subclasses should use this to close resources.
+ * @get_times: Given a buffer, return the start and stop time when it
+ * should be pushed out. The base class will sync on the clock using
+ * these times.
+ * @get_size: Return the total size of the resource, in the format set by
+ * gst_base_src_set_format().
+ * @is_seekable: Check if the source can seek
+ * @prepare_seek_segment: Prepare the #GstSegment that will be passed to the
+ * #GstBaseSrcClass::do_seek vmethod for executing a seek
+ * request. Sub-classes should override this if they support seeking in
+ * formats other than the configured native format. By default, it tries to
+ * convert the seek arguments to the configured native format and prepare a
+ * segment in that format.
+ * @do_seek: Perform seeking on the resource to the indicated segment.
+ * @unlock: Unlock any pending access to the resource. Subclasses should unblock
+ * any blocked function ASAP. In particular, any `create()` function in
+ * progress should be unblocked and should return GST_FLOW_FLUSHING. Any
+ * future #GstBaseSrcClass::create function call should also return
+ * GST_FLOW_FLUSHING until the #GstBaseSrcClass::unlock_stop function has
+ * been called.
+ * @unlock_stop: Clear the previous unlock request. Subclasses should clear any
+ * state they set during #GstBaseSrcClass::unlock, such as clearing command
+ * queues.
+ * @query: Handle a requested query.
+ * @event: Override this to implement custom event handling.
+ * @create: Ask the subclass to create a buffer with offset and size. When the
+ * subclass returns GST_FLOW_OK, it MUST return a buffer of the requested size
+ * unless fewer bytes are available because an EOS condition is near. No
+ * buffer should be returned when the return value is different from
+ * GST_FLOW_OK. A return value of GST_FLOW_EOS signifies that the end of
+ * stream is reached. The default implementation will call
+ * #GstBaseSrcClass::alloc and then call #GstBaseSrcClass::fill.
+ * @alloc: Ask the subclass to allocate a buffer with for offset and size. The
+ * default implementation will create a new buffer from the negotiated allocator.
+ * @fill: Ask the subclass to fill the buffer with data for offset and size. The
+ * passed buffer is guaranteed to hold the requested amount of bytes.
+ *
+ * Subclasses can override any of the available virtual methods or not, as
+ * needed. At the minimum, the @create method should be overridden to produce
+ * buffers.
+ */
+struct _GstBaseSrcClass {
+ GstElementClass parent_class;
+
+ /*< public >*/
+ /* virtual methods for subclasses */
+
+ /**
+ * GstBaseSrcClass::get_caps:
+ * @filter: (in) (nullable):
+ *
+ * Called to get the caps to report.
+ */
+ GstCaps* (*get_caps) (GstBaseSrc *src, GstCaps *filter);
+ /* decide on caps */
+ gboolean (*negotiate) (GstBaseSrc *src);
+ /* called if, in negotiation, caps need fixating */
+ GstCaps * (*fixate) (GstBaseSrc *src, GstCaps *caps);
+ /* notify the subclass of new caps */
+ gboolean (*set_caps) (GstBaseSrc *src, GstCaps *caps);
+
+ /* setup allocation query */
+ gboolean (*decide_allocation) (GstBaseSrc *src, GstQuery *query);
+
+ /* start and stop processing, ideal for opening/closing the resource */
+ gboolean (*start) (GstBaseSrc *src);
+ gboolean (*stop) (GstBaseSrc *src);
+
+ /**
+ * GstBaseSrcClass::get_times:
+ * @start: (out):
+ * @end: (out):
+ *
+ * Given @buffer, return @start and @end time when it should be pushed
+ * out. The base class will sync on the clock using these times.
+ */
+ void (*get_times) (GstBaseSrc *src, GstBuffer *buffer,
+ GstClockTime *start, GstClockTime *end);
+
+ /**
+ * GstBaseSrcClass::get_size:
+ * @size: (out):
+ *
+ * Get the total size of the resource in the format set by
+ * gst_base_src_set_format().
+ *
+ * Returns: %TRUE if the size is available and has been set.
+ */
+ gboolean (*get_size) (GstBaseSrc *src, guint64 *size);
+
+ /* check if the resource is seekable */
+ gboolean (*is_seekable) (GstBaseSrc *src);
+
+ /* Prepare the segment on which to perform do_seek(), converting to the
+ * current basesrc format. */
+ gboolean (*prepare_seek_segment) (GstBaseSrc *src, GstEvent *seek,
+ GstSegment *segment);
+ /* notify subclasses of a seek */
+ gboolean (*do_seek) (GstBaseSrc *src, GstSegment *segment);
+
+ /* unlock any pending access to the resource. subclasses should unlock
+ * any function ASAP. */
+ gboolean (*unlock) (GstBaseSrc *src);
+ /* Clear any pending unlock request, as we succeeded in unlocking */
+ gboolean (*unlock_stop) (GstBaseSrc *src);
+
+ /* notify subclasses of a query */
+ gboolean (*query) (GstBaseSrc *src, GstQuery *query);
+
+ /* notify subclasses of an event */
+ gboolean (*event) (GstBaseSrc *src, GstEvent *event);
+
+ /**
+ * GstBaseSrcClass::create:
+ * @buf: (inout):
+ *
+ * Ask the subclass to create a buffer with @offset and @size, the default
+ * implementation will call alloc if no allocated @buf is provided and then call fill.
+ */
+ GstFlowReturn (*create) (GstBaseSrc *src, guint64 offset, guint size,
+ GstBuffer **buf);
+ /**
+ * GstBaseSrcClass::alloc:
+ * @buf: (out):
+ *
+ * Ask the subclass to allocate an output buffer with @offset and @size, the default
+ * implementation will use the negotiated allocator.
+ */
+ GstFlowReturn (*alloc) (GstBaseSrc *src, guint64 offset, guint size,
+ GstBuffer **buf);
+ /* ask the subclass to fill the buffer with data from offset and size */
+ GstFlowReturn (*fill) (GstBaseSrc *src, guint64 offset, guint size,
+ GstBuffer *buf);
+
+ /*< private >*/
+ gpointer _gst_reserved[GST_PADDING_LARGE];
+};
+
+GST_BASE_API
+GType gst_base_src_get_type (void);
+
+GST_BASE_API
+GstFlowReturn gst_base_src_wait_playing (GstBaseSrc *src);
+
+GST_BASE_API
+void gst_base_src_set_live (GstBaseSrc *src, gboolean live);
+
+GST_BASE_API
+gboolean gst_base_src_is_live (GstBaseSrc *src);
+
+GST_BASE_API
+void gst_base_src_set_format (GstBaseSrc *src, GstFormat format);
+
+GST_BASE_API
+void gst_base_src_set_dynamic_size (GstBaseSrc * src, gboolean dynamic);
+
+GST_BASE_API
+void gst_base_src_set_automatic_eos (GstBaseSrc * src, gboolean automatic_eos);
+
+GST_BASE_API
+void gst_base_src_set_async (GstBaseSrc *src, gboolean async);
+
+GST_BASE_API
+gboolean gst_base_src_is_async (GstBaseSrc *src);
+
+GST_BASE_API
+gboolean gst_base_src_negotiate (GstBaseSrc *src);
+
+GST_BASE_API
+void gst_base_src_start_complete (GstBaseSrc * basesrc, GstFlowReturn ret);
+
+GST_BASE_API
+GstFlowReturn gst_base_src_start_wait (GstBaseSrc * basesrc);
+
+GST_BASE_API
+gboolean gst_base_src_query_latency (GstBaseSrc *src, gboolean * live,
+ GstClockTime * min_latency,
+ GstClockTime * max_latency);
+GST_BASE_API
+void gst_base_src_set_blocksize (GstBaseSrc *src, guint blocksize);
+
+GST_BASE_API
+guint gst_base_src_get_blocksize (GstBaseSrc *src);
+
+GST_BASE_API
+void gst_base_src_set_do_timestamp (GstBaseSrc *src, gboolean timestamp);
+
+GST_BASE_API
+gboolean gst_base_src_get_do_timestamp (GstBaseSrc *src);
+
+GST_BASE_API
+gboolean gst_base_src_new_seamless_segment (GstBaseSrc *src, gint64 start, gint64 stop, gint64 time);
+
+GST_BASE_API
+gboolean gst_base_src_new_segment (GstBaseSrc *src,
+ const GstSegment * segment);
+
+GST_BASE_API
+gboolean gst_base_src_set_caps (GstBaseSrc *src, GstCaps *caps);
+
+GST_BASE_API
+GstBufferPool * gst_base_src_get_buffer_pool (GstBaseSrc *src);
+
+GST_BASE_API
+void gst_base_src_get_allocator (GstBaseSrc *src,
+ GstAllocator **allocator,
+ GstAllocationParams *params);
+
+GST_BASE_API
+void gst_base_src_submit_buffer_list (GstBaseSrc * src,
+ GstBufferList * buffer_list);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstBaseSrc, gst_object_unref)
+
+G_END_DECLS
+
+#endif /* __GST_BASE_SRC_H__ */
diff --git a/include/gst/base/gstbasetransform.h b/include/gst/base/gstbasetransform.h
new file mode 100644
index 0000000000..0457b89bb2
--- /dev/null
+++ b/include/gst/base/gstbasetransform.h
@@ -0,0 +1,372 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ * 2005 Wim Taymans <wim@fluendo.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_BASE_TRANSFORM_H__
+#define __GST_BASE_TRANSFORM_H__
+
+#include <gst/gst.h>
+#include <gst/base/base-prelude.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_BASE_TRANSFORM (gst_base_transform_get_type())
+#define GST_BASE_TRANSFORM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_BASE_TRANSFORM,GstBaseTransform))
+#define GST_BASE_TRANSFORM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_BASE_TRANSFORM,GstBaseTransformClass))
+#define GST_BASE_TRANSFORM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_BASE_TRANSFORM,GstBaseTransformClass))
+#define GST_IS_BASE_TRANSFORM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_BASE_TRANSFORM))
+#define GST_IS_BASE_TRANSFORM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_BASE_TRANSFORM))
+#define GST_BASE_TRANSFORM_CAST(obj) ((GstBaseTransform *)(obj))
+
+/**
+ * GST_BASE_TRANSFORM_SINK_NAME:
+ *
+ * The name of the templates for the sink pad.
+ */
+#define GST_BASE_TRANSFORM_SINK_NAME "sink"
+/**
+ * GST_BASE_TRANSFORM_SRC_NAME:
+ *
+ * The name of the templates for the source pad.
+ */
+#define GST_BASE_TRANSFORM_SRC_NAME "src"
+
+/**
+ * GST_BASE_TRANSFORM_SRC_PAD:
+ * @obj: base transform instance
+ *
+ * Gives the pointer to the source #GstPad object of the element.
+ */
+#define GST_BASE_TRANSFORM_SRC_PAD(obj) (GST_BASE_TRANSFORM_CAST (obj)->srcpad)
+
+/**
+ * GST_BASE_TRANSFORM_SINK_PAD:
+ * @obj: base transform instance
+ *
+ * Gives the pointer to the sink #GstPad object of the element.
+ */
+#define GST_BASE_TRANSFORM_SINK_PAD(obj) (GST_BASE_TRANSFORM_CAST (obj)->sinkpad)
+
+/**
+ * GST_BASE_TRANSFORM_FLOW_DROPPED:
+ *
+ * A #GstFlowReturn that can be returned from transform and transform_ip to
+ * indicate that no output buffer was generated.
+ */
+#define GST_BASE_TRANSFORM_FLOW_DROPPED GST_FLOW_CUSTOM_SUCCESS
+
+typedef struct _GstBaseTransform GstBaseTransform;
+typedef struct _GstBaseTransformClass GstBaseTransformClass;
+typedef struct _GstBaseTransformPrivate GstBaseTransformPrivate;
+
+/**
+ * GstBaseTransform:
+ *
+ * The opaque #GstBaseTransform data structure.
+ */
+struct _GstBaseTransform {
+ GstElement element;
+
+ /*< protected >*/
+ /* source and sink pads */
+ GstPad *sinkpad;
+ GstPad *srcpad;
+
+ /* MT-protected (with STREAM_LOCK) */
+ gboolean have_segment;
+ GstSegment segment;
+ /* Default submit_input_buffer places the buffer here,
+ * for consumption by the generate_output method: */
+ GstBuffer *queued_buf;
+
+ /*< private >*/
+ GstBaseTransformPrivate *priv;
+
+ gpointer _gst_reserved[GST_PADDING_LARGE-1];
+};
+
+/**
+ * GstBaseTransformClass:
+ * @parent_class: Element parent class
+ * @passthrough_on_same_caps: If set to %TRUE, passthrough mode will be
+ * automatically enabled if the caps are the same.
+ * Set to %FALSE by default.
+ * @transform_ip_on_passthrough: If set to %TRUE, @transform_ip will be called in
+ * passthrough mode. The passed buffer might not be
+ * writable. When %FALSE, neither @transform nor
+ * @transform_ip will be called in passthrough mode.
+ * Set to %TRUE by default.
+ * @transform_caps: Optional. Given the pad in this direction and the given
+ * caps, what caps are allowed on the other pad in this
+ * element ?
+ * @fixate_caps: Optional. Given the pad in this direction and the given
+ * caps, fixate the caps on the other pad. The function takes
+ * ownership of @othercaps and returns a fixated version of
+ * @othercaps. @othercaps is not guaranteed to be writable.
+ * @accept_caps: Optional.
+ * Subclasses can override this method to check if @caps can be
+ * handled by the element. The default implementation might not be
+ * the most optimal way to check this in all cases.
+ * @set_caps: Allows the subclass to be notified of the actual caps set.
+ * @query: Optional.
+ * Handle a requested query. Subclasses that implement this
+ * must chain up to the parent if they didn't handle the
+ * query
+ * @decide_allocation: Setup the allocation parameters for allocating output
+ * buffers. The passed in query contains the result of the
+ * downstream allocation query. This function is only called
+ * when not operating in passthrough mode. The default
+ * implementation will remove all memory dependent metadata.
+ * If there is a @filter_meta method implementation, it will
+ * be called for all metadata API in the downstream query,
+ * otherwise the metadata API is removed.
+ * @filter_meta: Return %TRUE if the metadata API should be proposed in the
+ * upstream allocation query. The default implementation is %NULL
+ * and will cause all metadata to be removed.
+ * @propose_allocation: Propose buffer allocation parameters for upstream elements.
+ * This function must be implemented if the element reads or
+ * writes the buffer content. The query that was passed to
+ * the decide_allocation is passed in this method (or %NULL
+ * when the element is in passthrough mode). The default
+ * implementation will pass the query downstream when in
+ * passthrough mode and will copy all the filtered metadata
+ * API in non-passthrough mode.
+ * @transform_size: Optional. Given the size of a buffer in the given direction
+ * with the given caps, calculate the size in bytes of a buffer
+ * on the other pad with the given other caps.
+ * The default implementation uses get_unit_size and keeps
+ * the number of units the same.
+ * @get_unit_size: Required if the transform is not in-place.
+ * Get the size in bytes of one unit for the given caps.
+ * @start: Optional.
+ * Called when the element starts processing.
+ * Allows opening external resources.
+ * @stop: Optional.
+ * Called when the element stops processing.
+ * Allows closing external resources.
+ * @sink_event: Optional.
+ * Event handler on the sink pad. The default implementation
+ * handles the event and forwards it downstream.
+ * @src_event: Optional.
+ * Event handler on the source pad. The default implementation
+ * handles the event and forwards it upstream.
+ * @prepare_output_buffer: Optional.
+ * Subclasses can override this to do their own
+ * allocation of output buffers. Elements that only do
+ * analysis can return a subbuffer or even just
+ * return a reference to the input buffer (if in
+ * passthrough mode). The default implementation will
+ * use the negotiated allocator or bufferpool and
+ * transform_size to allocate an output buffer or it
+ * will return the input buffer in passthrough mode.
+ * @copy_metadata: Optional.
+ * Copy the metadata from the input buffer to the output buffer.
+ * The default implementation will copy the flags, timestamps and
+ * offsets of the buffer.
+ * @transform_meta: Optional. Transform the metadata on the input buffer to the
+ * output buffer. By default this method copies all meta without
+ * tags. Subclasses can implement this method and return %TRUE if
+ * the metadata is to be copied.
+ * @before_transform: Optional.
+ * This method is called right before the base class will
+ * start processing. Dynamic properties or other delayed
+ * configuration could be performed in this method.
+ * @transform: Required if the element does not operate in-place.
+ * Transforms one incoming buffer to one outgoing buffer.
+ * The function is allowed to change size/timestamp/duration
+ * of the outgoing buffer.
+ * @transform_ip: Required if the element operates in-place.
+ * Transform the incoming buffer in-place.
+ * @submit_input_buffer: Function which accepts a new input buffer and pre-processes it.
+ * The default implementation performs caps (re)negotiation, then
+ * QoS if needed, and places the input buffer into the @queued_buf
+ * member variable. If the buffer is dropped due to QoS, it returns
+ * GST_BASE_TRANSFORM_FLOW_DROPPED. If this input buffer is not
+ * contiguous with any previous input buffer, then @is_discont
+ * is set to %TRUE. (Since: 1.6)
+ * @generate_output: Called after each new input buffer is submitted repeatedly
+ * until it either generates an error or fails to generate an output
+ * buffer. The default implementation takes the contents of the
+ * @queued_buf variable, generates an output buffer if needed
+ * by calling the class @prepare_output_buffer, and then
+ * calls either @transform or @transform_ip. Elements that don't
+ * do 1-to-1 transformations of input to output buffers can either
+ * return GST_BASE_TRANSFORM_FLOW_DROPPED or simply not generate
+ * an output buffer until they are ready to do so. (Since: 1.6)
+ *
+ * Subclasses can override any of the available virtual methods or not, as
+ * needed. At minimum either @transform or @transform_ip need to be overridden.
+ * If the element can overwrite the input data with the results (data is of the
+ * same type and quantity) it should provide @transform_ip.
+ */
+struct _GstBaseTransformClass {
+ GstElementClass parent_class;
+
+ /*< public >*/
+ gboolean passthrough_on_same_caps;
+ gboolean transform_ip_on_passthrough;
+
+ /* virtual methods for subclasses */
+ GstCaps* (*transform_caps) (GstBaseTransform *trans,
+ GstPadDirection direction,
+ GstCaps *caps, GstCaps *filter);
+ /**
+ * GstBaseTransformClass::fixate_caps:
+ * @othercaps: (transfer full):
+ */
+ GstCaps* (*fixate_caps) (GstBaseTransform *trans,
+ GstPadDirection direction, GstCaps *caps,
+ GstCaps *othercaps);
+ gboolean (*accept_caps) (GstBaseTransform *trans, GstPadDirection direction,
+ GstCaps *caps);
+ gboolean (*set_caps) (GstBaseTransform *trans, GstCaps *incaps,
+ GstCaps *outcaps);
+ gboolean (*query) (GstBaseTransform *trans, GstPadDirection direction,
+ GstQuery *query);
+
+ /* decide allocation query for output buffers */
+ gboolean (*decide_allocation) (GstBaseTransform *trans, GstQuery *query);
+ gboolean (*filter_meta) (GstBaseTransform *trans, GstQuery *query,
+ GType api, const GstStructure *params);
+
+ /* propose allocation query parameters for input buffers */
+ gboolean (*propose_allocation) (GstBaseTransform *trans, GstQuery *decide_query,
+ GstQuery *query);
+
+ /**
+ * GstBaseTransformClass::transform_size:
+ * @othersize: (out):
+ */
+ gboolean (*transform_size) (GstBaseTransform *trans,
+ GstPadDirection direction,
+ GstCaps *caps, gsize size,
+ GstCaps *othercaps, gsize *othersize);
+
+ /**
+ * GstBaseTransformClass::get_unit_size:
+ * @size: (out):
+ */
+ gboolean (*get_unit_size) (GstBaseTransform *trans, GstCaps *caps,
+ gsize *size);
+
+ /* states */
+ gboolean (*start) (GstBaseTransform *trans);
+ gboolean (*stop) (GstBaseTransform *trans);
+
+ /* sink and src pad event handlers */
+ /**
+ * GstBaseTransformClass::sink_event:
+ * @event: (transfer full):
+ */
+ gboolean (*sink_event) (GstBaseTransform *trans, GstEvent *event);
+ /**
+ * GstBaseTransformClass::src_event:
+ * @event: (transfer full):
+ */
+ gboolean (*src_event) (GstBaseTransform *trans, GstEvent *event);
+
+ /**
+ * GstBaseTransformClass::prepare_output_buffer:
+ * @outbuf: (out):
+ */
+ GstFlowReturn (*prepare_output_buffer) (GstBaseTransform * trans,
+ GstBuffer *input, GstBuffer **outbuf);
+
+ /* metadata */
+ gboolean (*copy_metadata) (GstBaseTransform *trans, GstBuffer *input,
+ GstBuffer *outbuf);
+ gboolean (*transform_meta) (GstBaseTransform *trans, GstBuffer *outbuf,
+ GstMeta *meta, GstBuffer *inbuf);
+
+ void (*before_transform) (GstBaseTransform *trans, GstBuffer *buffer);
+
+ /* transform */
+ GstFlowReturn (*transform) (GstBaseTransform *trans, GstBuffer *inbuf,
+ GstBuffer *outbuf);
+ GstFlowReturn (*transform_ip) (GstBaseTransform *trans, GstBuffer *buf);
+
+ GstFlowReturn (*submit_input_buffer) (GstBaseTransform *trans, gboolean is_discont, GstBuffer *input);
+
+ /**
+ * GstBaseTransformClass::generate_output:
+ * @outbuf: (out):
+ */
+ GstFlowReturn (*generate_output) (GstBaseTransform *trans, GstBuffer **outbuf);
+
+ /*< private >*/
+ gpointer _gst_reserved[GST_PADDING_LARGE - 2];
+};
+
+GST_BASE_API
+GType gst_base_transform_get_type (void);
+
+GST_BASE_API
+void gst_base_transform_set_passthrough (GstBaseTransform *trans,
+ gboolean passthrough);
+GST_BASE_API
+gboolean gst_base_transform_is_passthrough (GstBaseTransform *trans);
+
+GST_BASE_API
+void gst_base_transform_set_in_place (GstBaseTransform *trans,
+ gboolean in_place);
+GST_BASE_API
+gboolean gst_base_transform_is_in_place (GstBaseTransform *trans);
+
+GST_BASE_API
+void gst_base_transform_update_qos (GstBaseTransform *trans,
+ gdouble proportion,
+ GstClockTimeDiff diff,
+ GstClockTime timestamp);
+GST_BASE_API
+void gst_base_transform_set_qos_enabled (GstBaseTransform *trans,
+ gboolean enabled);
+GST_BASE_API
+gboolean gst_base_transform_is_qos_enabled (GstBaseTransform *trans);
+
+GST_BASE_API
+void gst_base_transform_set_gap_aware (GstBaseTransform *trans,
+ gboolean gap_aware);
+GST_BASE_API
+void gst_base_transform_set_prefer_passthrough (GstBaseTransform *trans,
+ gboolean prefer_passthrough);
+GST_BASE_API
+GstBufferPool * gst_base_transform_get_buffer_pool (GstBaseTransform *trans);
+
+GST_BASE_API
+void gst_base_transform_get_allocator (GstBaseTransform *trans,
+ GstAllocator **allocator,
+ GstAllocationParams *params);
+GST_BASE_API
+void gst_base_transform_reconfigure_sink (GstBaseTransform *trans);
+
+GST_BASE_API
+void gst_base_transform_reconfigure_src (GstBaseTransform *trans);
+
+GST_BASE_API
+gboolean gst_base_transform_update_src_caps (GstBaseTransform *trans,
+ GstCaps *updated_caps);
+
+GST_BASE_API
+gboolean gst_base_transform_reconfigure (GstBaseTransform * trans);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstBaseTransform, gst_object_unref)
+
+G_END_DECLS
+
+#endif /* __GST_BASE_TRANSFORM_H__ */
diff --git a/include/gst/base/gstbitreader.h b/include/gst/base/gstbitreader.h
new file mode 100644
index 0000000000..380edd3fe6
--- /dev/null
+++ b/include/gst/base/gstbitreader.h
@@ -0,0 +1,328 @@
+/* GStreamer
+ *
+ * Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_BIT_READER_H__
+#define __GST_BIT_READER_H__
+
+#include <gst/gst.h>
+#include <gst/base/base-prelude.h>
+
+/* FIXME: inline functions */
+
+G_BEGIN_DECLS
+
+#define GST_BIT_READER(reader) ((GstBitReader *) (reader))
+
+/**
+ * GstBitReader:
+ * @data: (array length=size): Data from which the bit reader will
+ * read
+ * @size: Size of @data in bytes
+ * @byte: Current byte position
+ * @bit: Bit position in the current byte
+ *
+ * A bit reader instance.
+ */
+typedef struct {
+ const guint8 *data;
+ guint size;
+
+ guint byte; /* Byte position */
+ guint bit; /* Bit position in the current byte */
+
+ /* < private > */
+ gpointer _gst_reserved[GST_PADDING];
+} GstBitReader;
+
+GST_BASE_API
+GstBitReader * gst_bit_reader_new (const guint8 *data, guint size) G_GNUC_MALLOC;
+
+GST_BASE_API
+void gst_bit_reader_free (GstBitReader *reader);
+
+GST_BASE_API
+void gst_bit_reader_init (GstBitReader *reader, const guint8 *data, guint size);
+
+GST_BASE_API
+gboolean gst_bit_reader_set_pos (GstBitReader *reader, guint pos);
+
+GST_BASE_API
+guint gst_bit_reader_get_pos (const GstBitReader *reader);
+
+GST_BASE_API
+guint gst_bit_reader_get_remaining (const GstBitReader *reader);
+
+GST_BASE_API
+guint gst_bit_reader_get_size (const GstBitReader *reader);
+
+GST_BASE_API
+gboolean gst_bit_reader_skip (GstBitReader *reader, guint nbits);
+
+GST_BASE_API
+gboolean gst_bit_reader_skip_to_byte (GstBitReader *reader);
+
+GST_BASE_API
+gboolean gst_bit_reader_get_bits_uint8 (GstBitReader *reader, guint8 *val, guint nbits);
+
+GST_BASE_API
+gboolean gst_bit_reader_get_bits_uint16 (GstBitReader *reader, guint16 *val, guint nbits);
+
+GST_BASE_API
+gboolean gst_bit_reader_get_bits_uint32 (GstBitReader *reader, guint32 *val, guint nbits);
+
+GST_BASE_API
+gboolean gst_bit_reader_get_bits_uint64 (GstBitReader *reader, guint64 *val, guint nbits);
+
+GST_BASE_API
+gboolean gst_bit_reader_peek_bits_uint8 (const GstBitReader *reader, guint8 *val, guint nbits);
+
+GST_BASE_API
+gboolean gst_bit_reader_peek_bits_uint16 (const GstBitReader *reader, guint16 *val, guint nbits);
+
+GST_BASE_API
+gboolean gst_bit_reader_peek_bits_uint32 (const GstBitReader *reader, guint32 *val, guint nbits);
+
+GST_BASE_API
+gboolean gst_bit_reader_peek_bits_uint64 (const GstBitReader *reader, guint64 *val, guint nbits);
+
+/**
+ * GST_BIT_READER_INIT:
+ * @data: Data from which the #GstBitReader should read
+ * @size: Size of @data in bytes
+ *
+ * A #GstBitReader must be initialized with this macro, before it can be
+ * used. This macro can used be to initialize a variable, but it cannot
+ * be assigned to a variable. In that case you have to use
+ * gst_bit_reader_init().
+ */
+#define GST_BIT_READER_INIT(data, size) {data, size, 0, 0}
+
+/* Unchecked variants */
+
+static inline void
+gst_bit_reader_skip_unchecked (GstBitReader * reader, guint nbits)
+{
+ reader->bit += nbits;
+ reader->byte += reader->bit / 8;
+ reader->bit = reader->bit % 8;
+}
+
+static inline void
+gst_bit_reader_skip_to_byte_unchecked (GstBitReader * reader)
+{
+ if (reader->bit) {
+ reader->bit = 0;
+ reader->byte++;
+ }
+}
+
+#define __GST_BIT_READER_READ_BITS_UNCHECKED(bits) \
+static inline guint##bits \
+gst_bit_reader_peek_bits_uint##bits##_unchecked (const GstBitReader *reader, guint nbits) \
+{ \
+ guint##bits ret = 0; \
+ const guint8 *data; \
+ guint byte, bit; \
+ \
+ data = reader->data; \
+ byte = reader->byte; \
+ bit = reader->bit; \
+ \
+ while (nbits > 0) { \
+ guint toread = MIN (nbits, 8 - bit); \
+ \
+ ret <<= toread; \
+ ret |= (data[byte] & (0xff >> bit)) >> (8 - toread - bit); \
+ \
+ bit += toread; \
+ if (bit >= 8) { \
+ byte++; \
+ bit = 0; \
+ } \
+ nbits -= toread; \
+ } \
+ \
+ return ret; \
+} \
+\
+static inline guint##bits \
+gst_bit_reader_get_bits_uint##bits##_unchecked (GstBitReader *reader, guint nbits) \
+{ \
+ guint##bits ret; \
+ \
+ ret = gst_bit_reader_peek_bits_uint##bits##_unchecked (reader, nbits); \
+ \
+ gst_bit_reader_skip_unchecked (reader, nbits); \
+ \
+ return ret; \
+}
+
+__GST_BIT_READER_READ_BITS_UNCHECKED (8)
+__GST_BIT_READER_READ_BITS_UNCHECKED (16)
+__GST_BIT_READER_READ_BITS_UNCHECKED (32)
+__GST_BIT_READER_READ_BITS_UNCHECKED (64)
+
+#undef __GST_BIT_READER_READ_BITS_UNCHECKED
+
+/* unchecked variants -- do not use */
+
+static inline guint
+_gst_bit_reader_get_size_unchecked (const GstBitReader * reader)
+{
+ return reader->size * 8;
+}
+
+static inline guint
+_gst_bit_reader_get_pos_unchecked (const GstBitReader * reader)
+{
+ return reader->byte * 8 + reader->bit;
+}
+
+static inline guint
+_gst_bit_reader_get_remaining_unchecked (const GstBitReader * reader)
+{
+ return reader->size * 8 - (reader->byte * 8 + reader->bit);
+}
+
+/* inlined variants -- do not use directly */
+static inline guint
+_gst_bit_reader_get_size_inline (const GstBitReader * reader)
+{
+ g_return_val_if_fail (reader != NULL, 0);
+
+ return _gst_bit_reader_get_size_unchecked (reader);
+}
+
+static inline guint
+_gst_bit_reader_get_pos_inline (const GstBitReader * reader)
+{
+ g_return_val_if_fail (reader != NULL, 0);
+
+ return _gst_bit_reader_get_pos_unchecked (reader);
+}
+
+static inline guint
+_gst_bit_reader_get_remaining_inline (const GstBitReader * reader)
+{
+ g_return_val_if_fail (reader != NULL, 0);
+
+ return _gst_bit_reader_get_remaining_unchecked (reader);
+}
+
+static inline gboolean
+_gst_bit_reader_skip_inline (GstBitReader * reader, guint nbits)
+{
+ g_return_val_if_fail (reader != NULL, FALSE);
+
+ if (_gst_bit_reader_get_remaining_unchecked (reader) < nbits)
+ return FALSE;
+
+ gst_bit_reader_skip_unchecked (reader, nbits);
+
+ return TRUE;
+}
+
+static inline gboolean
+_gst_bit_reader_skip_to_byte_inline (GstBitReader * reader)
+{
+ g_return_val_if_fail (reader != NULL, FALSE);
+
+ if (reader->byte > reader->size)
+ return FALSE;
+
+ gst_bit_reader_skip_to_byte_unchecked (reader);
+
+ return TRUE;
+}
+
+#define __GST_BIT_READER_READ_BITS_INLINE(bits) \
+static inline gboolean \
+_gst_bit_reader_get_bits_uint##bits##_inline (GstBitReader *reader, guint##bits *val, guint nbits) \
+{ \
+ g_return_val_if_fail (reader != NULL, FALSE); \
+ g_return_val_if_fail (val != NULL, FALSE); \
+ g_return_val_if_fail (nbits <= bits, FALSE); \
+ \
+ if (_gst_bit_reader_get_remaining_unchecked (reader) < nbits) \
+ return FALSE; \
+\
+ *val = gst_bit_reader_get_bits_uint##bits##_unchecked (reader, nbits); \
+ return TRUE; \
+} \
+\
+static inline gboolean \
+_gst_bit_reader_peek_bits_uint##bits##_inline (const GstBitReader *reader, guint##bits *val, guint nbits) \
+{ \
+ g_return_val_if_fail (reader != NULL, FALSE); \
+ g_return_val_if_fail (val != NULL, FALSE); \
+ g_return_val_if_fail (nbits <= bits, FALSE); \
+ \
+ if (_gst_bit_reader_get_remaining_unchecked (reader) < nbits) \
+ return FALSE; \
+\
+ *val = gst_bit_reader_peek_bits_uint##bits##_unchecked (reader, nbits); \
+ return TRUE; \
+}
+
+__GST_BIT_READER_READ_BITS_INLINE (8)
+__GST_BIT_READER_READ_BITS_INLINE (16)
+__GST_BIT_READER_READ_BITS_INLINE (32)
+__GST_BIT_READER_READ_BITS_INLINE (64)
+
+#undef __GST_BIT_READER_READ_BITS_INLINE
+
+#ifndef GST_BIT_READER_DISABLE_INLINES
+
+#define gst_bit_reader_get_size(reader) \
+ _gst_bit_reader_get_size_inline (reader)
+#define gst_bit_reader_get_pos(reader) \
+ _gst_bit_reader_get_pos_inline (reader)
+#define gst_bit_reader_get_remaining(reader) \
+ _gst_bit_reader_get_remaining_inline (reader)
+
+/* we use defines here so we can add the G_LIKELY() */
+
+#define gst_bit_reader_skip(reader, nbits)\
+ G_LIKELY (_gst_bit_reader_skip_inline(reader, nbits))
+#define gst_bit_reader_skip_to_byte(reader)\
+ G_LIKELY (_gst_bit_reader_skip_to_byte_inline(reader))
+
+#define gst_bit_reader_get_bits_uint8(reader, val, nbits) \
+ G_LIKELY (_gst_bit_reader_get_bits_uint8_inline (reader, val, nbits))
+#define gst_bit_reader_get_bits_uint16(reader, val, nbits) \
+ G_LIKELY (_gst_bit_reader_get_bits_uint16_inline (reader, val, nbits))
+#define gst_bit_reader_get_bits_uint32(reader, val, nbits) \
+ G_LIKELY (_gst_bit_reader_get_bits_uint32_inline (reader, val, nbits))
+#define gst_bit_reader_get_bits_uint64(reader, val, nbits) \
+ G_LIKELY (_gst_bit_reader_get_bits_uint64_inline (reader, val, nbits))
+
+#define gst_bit_reader_peek_bits_uint8(reader, val, nbits) \
+ G_LIKELY (_gst_bit_reader_peek_bits_uint8_inline (reader, val, nbits))
+#define gst_bit_reader_peek_bits_uint16(reader, val, nbits) \
+ G_LIKELY (_gst_bit_reader_peek_bits_uint16_inline (reader, val, nbits))
+#define gst_bit_reader_peek_bits_uint32(reader, val, nbits) \
+ G_LIKELY (_gst_bit_reader_peek_bits_uint32_inline (reader, val, nbits))
+#define gst_bit_reader_peek_bits_uint64(reader, val, nbits) \
+ G_LIKELY (_gst_bit_reader_peek_bits_uint64_inline (reader, val, nbits))
+#endif
+
+G_END_DECLS
+
+#endif /* __GST_BIT_READER_H__ */
diff --git a/include/gst/base/gstbitwriter.h b/include/gst/base/gstbitwriter.h
new file mode 100644
index 0000000000..8a860e8e08
--- /dev/null
+++ b/include/gst/base/gstbitwriter.h
@@ -0,0 +1,384 @@
+/*
+ * gstbitwriter.h - bitstream writer
+ *
+ * Copyright (C) 2013 Intel Corporation
+ * Copyright (C) 2018 Igalia, S. L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifndef GST_BIT_WRITER_H
+#define GST_BIT_WRITER_H
+
+#include <gst/gst.h>
+#include <gst/base/base-prelude.h>
+
+#include <string.h>
+
+G_BEGIN_DECLS
+
+#define GST_BIT_WRITER_DATA(writer) ((writer)->data)
+#define GST_BIT_WRITER_BIT_SIZE(writer) ((writer)->bit_size)
+#define GST_BIT_WRITER(writer) ((GstBitWriter *) (writer))
+
+typedef struct _GstBitWriter GstBitWriter;
+
+/**
+ * GstBitWriter:
+ * @data: Allocated @data for bit writer to write
+ * @bit_size: Size of written @data in bits
+ *
+ * A bit writer instance.
+ *
+ * Since: 1.16
+ */
+struct _GstBitWriter
+{
+ guint8 *data;
+ guint bit_size;
+
+ /*< private >*/
+ guint bit_capacity; /* Capacity of the allocated data */
+ gboolean auto_grow; /* Whether space can auto grow */
+ gboolean owned;
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+GST_BASE_API
+GstBitWriter * gst_bit_writer_new (void) G_GNUC_MALLOC;
+
+GST_BASE_API
+GstBitWriter * gst_bit_writer_new_with_size (guint32 size, gboolean fixed) G_GNUC_MALLOC;
+
+GST_BASE_API
+GstBitWriter * gst_bit_writer_new_with_data (guint8 *data, guint size,
+ gboolean initialized) G_GNUC_MALLOC;
+
+GST_BASE_API
+void gst_bit_writer_free (GstBitWriter *bitwriter);
+
+GST_BASE_API
+guint8 * gst_bit_writer_free_and_get_data (GstBitWriter *bitwriter);
+
+GST_BASE_API
+GstBuffer * gst_bit_writer_free_and_get_buffer (GstBitWriter *bitwriter);
+
+GST_BASE_API
+void gst_bit_writer_init (GstBitWriter *bitwriter);
+
+GST_BASE_API
+void gst_bit_writer_init_with_size (GstBitWriter *bitwriter,
+ guint32 size, gboolean fixed);
+
+GST_BASE_API
+void gst_bit_writer_init_with_data (GstBitWriter *bitwriter, guint8 *data,
+ guint size, gboolean initialized);
+
+GST_BASE_API
+void gst_bit_writer_reset (GstBitWriter *bitwriter);
+
+GST_BASE_API
+guint8 * gst_bit_writer_reset_and_get_data (GstBitWriter *bitwriter);
+
+GST_BASE_API
+GstBuffer * gst_bit_writer_reset_and_get_buffer (GstBitWriter *bitwriter);
+
+GST_BASE_API
+guint gst_bit_writer_get_size (const GstBitWriter *bitwriter);
+
+GST_BASE_API
+guint8 * gst_bit_writer_get_data (const GstBitWriter *bitwriter);
+
+GST_BASE_API
+gboolean gst_bit_writer_set_pos (GstBitWriter *bitwriter, guint pos);
+
+GST_BASE_API
+guint gst_bit_writer_get_remaining (const GstBitWriter *bitwriter);
+
+GST_BASE_API
+gboolean gst_bit_writer_put_bits_uint8 (GstBitWriter *bitwriter, guint8 value,
+ guint nbits);
+
+GST_BASE_API
+gboolean gst_bit_writer_put_bits_uint16 (GstBitWriter *bitwriter, guint16 value,
+ guint nbits);
+
+GST_BASE_API
+gboolean gst_bit_writer_put_bits_uint32 (GstBitWriter *bitwriter, guint32 value,
+ guint nbits);
+
+GST_BASE_API
+gboolean gst_bit_writer_put_bits_uint64 (GstBitWriter *bitwriter, guint64 value,
+ guint nbits);
+
+GST_BASE_API
+gboolean gst_bit_writer_put_bytes (GstBitWriter *bitwriter, const guint8 *data,
+ guint nbytes);
+
+GST_BASE_API
+gboolean gst_bit_writer_align_bytes (GstBitWriter *bitwriter, guint8 trailing_bit);
+
+static const guint8 _gst_bit_writer_bit_filling_mask[9] = {
+ 0x00, 0x01, 0x03, 0x07,
+ 0x0F, 0x1F, 0x3F, 0x7F,
+ 0xFF
+};
+
+/* Aligned to 256 bytes */
+#define __GST_BITS_WRITER_ALIGNMENT_MASK 2047
+#define __GST_BITS_WRITER_ALIGNED(bitsize) \
+ (((bitsize) + __GST_BITS_WRITER_ALIGNMENT_MASK)&(~__GST_BITS_WRITER_ALIGNMENT_MASK))
+
+static inline gboolean
+_gst_bit_writer_check_remaining (GstBitWriter * bitwriter, guint32 bits)
+{
+ guint32 new_bit_size = bits + bitwriter->bit_size;
+ guint32 clear_pos;
+
+ g_assert (bitwriter->bit_size <= bitwriter->bit_capacity);
+ if (new_bit_size <= bitwriter->bit_capacity)
+ return TRUE;
+
+ if (!bitwriter->auto_grow)
+ return FALSE;
+
+ /* auto grow space */
+ new_bit_size = __GST_BITS_WRITER_ALIGNED (new_bit_size);
+ g_assert (new_bit_size
+ && ((new_bit_size & __GST_BITS_WRITER_ALIGNMENT_MASK) == 0));
+ clear_pos = ((bitwriter->bit_size + 7) >> 3);
+ bitwriter->data = (guint8 *) g_realloc (bitwriter->data, (new_bit_size >> 3));
+ memset (bitwriter->data + clear_pos, 0, (new_bit_size >> 3) - clear_pos);
+ bitwriter->bit_capacity = new_bit_size;
+ return TRUE;
+}
+
+#undef __GST_BITS_WRITER_ALIGNMENT_MASK
+#undef __GST_BITS_WRITER_ALIGNED
+
+#define __GST_BIT_WRITER_WRITE_BITS_UNCHECKED(bits) \
+static inline void \
+gst_bit_writer_put_bits_uint##bits##_unchecked( \
+ GstBitWriter *bitwriter, \
+ guint##bits value, \
+ guint nbits \
+) \
+{ \
+ guint byte_pos, bit_offset; \
+ guint8 *cur_byte; \
+ guint fill_bits; \
+ \
+ byte_pos = (bitwriter->bit_size >> 3); \
+ bit_offset = (bitwriter->bit_size & 0x07); \
+ cur_byte = bitwriter->data + byte_pos; \
+ g_assert (nbits <= bits); \
+ g_assert( bit_offset < 8 && \
+ bitwriter->bit_size <= bitwriter->bit_capacity); \
+ \
+ while (nbits) { \
+ fill_bits = ((8 - bit_offset) < nbits ? (8 - bit_offset) : nbits); \
+ nbits -= fill_bits; \
+ bitwriter->bit_size += fill_bits; \
+ \
+ *cur_byte |= (((value >> nbits) & _gst_bit_writer_bit_filling_mask[fill_bits]) \
+ << (8 - bit_offset - fill_bits)); \
+ ++cur_byte; \
+ bit_offset = 0; \
+ } \
+ g_assert(cur_byte <= \
+ (bitwriter->data + (bitwriter->bit_capacity >> 3))); \
+}
+
+__GST_BIT_WRITER_WRITE_BITS_UNCHECKED (8)
+__GST_BIT_WRITER_WRITE_BITS_UNCHECKED (16)
+__GST_BIT_WRITER_WRITE_BITS_UNCHECKED (32)
+__GST_BIT_WRITER_WRITE_BITS_UNCHECKED (64)
+#undef __GST_BIT_WRITER_WRITE_BITS_UNCHECKED
+
+static inline guint
+gst_bit_writer_get_size_unchecked (const GstBitWriter * bitwriter)
+{
+ return GST_BIT_WRITER_BIT_SIZE (bitwriter);
+}
+
+static inline guint8 *
+gst_bit_writer_get_data_unchecked (const GstBitWriter * bitwriter)
+{
+ return GST_BIT_WRITER_DATA (bitwriter);
+}
+
+static inline gboolean
+gst_bit_writer_set_pos_unchecked (GstBitWriter * bitwriter, guint pos)
+{
+ GST_BIT_WRITER_BIT_SIZE (bitwriter) = pos;
+ return TRUE;
+}
+
+static inline guint
+gst_bit_writer_get_remaining_unchecked (const GstBitWriter * bitwriter)
+{
+ return bitwriter->bit_capacity - bitwriter->bit_size;
+}
+
+static inline void
+gst_bit_writer_put_bytes_unchecked (GstBitWriter * bitwriter,
+ const guint8 * data, guint nbytes)
+{
+ if ((bitwriter->bit_size & 0x07) == 0) {
+ memcpy (&bitwriter->data[bitwriter->bit_size >> 3], data, nbytes);
+ bitwriter->bit_size += (nbytes << 3);
+ } else {
+ g_assert (0);
+ while (nbytes) {
+ gst_bit_writer_put_bits_uint8_unchecked (bitwriter, *data, 8);
+ --nbytes;
+ ++data;
+ }
+ }
+}
+
+static inline void
+gst_bit_writer_align_bytes_unchecked (GstBitWriter * bitwriter,
+ guint8 trailing_bit)
+{
+ guint32 bit_offset, bit_left;
+ guint8 value = 0;
+
+ bit_offset = (bitwriter->bit_size & 0x07);
+ if (!bit_offset)
+ return;
+
+ bit_left = 8 - bit_offset;
+ if (trailing_bit)
+ value = _gst_bit_writer_bit_filling_mask[bit_left];
+ gst_bit_writer_put_bits_uint8_unchecked (bitwriter, value, bit_left);
+}
+
+#define __GST_BIT_WRITER_WRITE_BITS_INLINE(bits) \
+static inline gboolean \
+_gst_bit_writer_put_bits_uint##bits##_inline( \
+ GstBitWriter *bitwriter, \
+ guint##bits value, \
+ guint nbits \
+) \
+{ \
+ g_return_val_if_fail(bitwriter != NULL, FALSE); \
+ g_return_val_if_fail(nbits != 0, FALSE); \
+ g_return_val_if_fail(nbits <= bits, FALSE); \
+ \
+ if (!_gst_bit_writer_check_remaining(bitwriter, nbits)) \
+ return FALSE; \
+ gst_bit_writer_put_bits_uint##bits##_unchecked(bitwriter, value, nbits); \
+ return TRUE; \
+}
+
+__GST_BIT_WRITER_WRITE_BITS_INLINE (8)
+__GST_BIT_WRITER_WRITE_BITS_INLINE (16)
+__GST_BIT_WRITER_WRITE_BITS_INLINE (32)
+__GST_BIT_WRITER_WRITE_BITS_INLINE (64)
+#undef __GST_BIT_WRITER_WRITE_BITS_INLINE
+
+static inline guint
+_gst_bit_writer_get_size_inline (const GstBitWriter * bitwriter)
+{
+ g_return_val_if_fail (bitwriter != NULL, 0);
+
+ return gst_bit_writer_get_size_unchecked (bitwriter);
+}
+
+static inline guint8 *
+_gst_bit_writer_get_data_inline (const GstBitWriter * bitwriter)
+{
+ g_return_val_if_fail (bitwriter != NULL, NULL);
+
+ return gst_bit_writer_get_data_unchecked (bitwriter);
+}
+
+static inline gboolean
+_gst_bit_writer_set_pos_inline (GstBitWriter * bitwriter, guint pos)
+{
+ g_return_val_if_fail (bitwriter != NULL, FALSE);
+ g_return_val_if_fail (pos <= bitwriter->bit_capacity, FALSE);
+
+ return gst_bit_writer_set_pos_unchecked (bitwriter, pos);
+}
+
+static inline guint
+_gst_bit_writer_get_remaining_inline (const GstBitWriter * bitwriter)
+{
+ g_return_val_if_fail (bitwriter != NULL, 0);
+ g_return_val_if_fail (bitwriter->bit_size < bitwriter->bit_capacity, 0);
+
+ return gst_bit_writer_get_remaining_unchecked (bitwriter);
+}
+
+static inline gboolean
+_gst_bit_writer_put_bytes_inline (GstBitWriter * bitwriter,
+ const guint8 * data, guint nbytes)
+{
+ g_return_val_if_fail (bitwriter != NULL, FALSE);
+ g_return_val_if_fail (data != NULL, FALSE);
+ g_return_val_if_fail (nbytes, FALSE);
+
+ if (!_gst_bit_writer_check_remaining (bitwriter, nbytes * 8))
+ return FALSE;
+
+ gst_bit_writer_put_bytes_unchecked (bitwriter, data, nbytes);
+ return TRUE;
+}
+
+static inline gboolean
+_gst_bit_writer_align_bytes_inline (GstBitWriter * bitwriter,
+ guint8 trailing_bit)
+{
+ g_return_val_if_fail (bitwriter != NULL, FALSE);
+ g_return_val_if_fail ((trailing_bit == 0 || trailing_bit == 1), FALSE);
+ g_return_val_if_fail (((bitwriter->bit_size + 7) & (~7)) <=
+ bitwriter->bit_capacity, FALSE);
+
+ gst_bit_writer_align_bytes_unchecked (bitwriter, trailing_bit);
+ return TRUE;
+}
+
+#ifndef GST_BIT_WRITER_DISABLE_INLINES
+#define gst_bit_writer_get_size(bitwriter) \
+ _gst_bit_writer_get_size_inline(bitwriter)
+#define gst_bit_writer_get_data(bitwriter) \
+ _gst_bit_writer_get_data_inline(bitwriter)
+#define gst_bit_writer_set_pos(bitwriter, pos) \
+ G_LIKELY (_gst_bit_writer_set_pos_inline (bitwriter, pos))
+#define gst_bit_writer_get_remaining(bitwriter) \
+ _gst_bit_writer_get_remaining_inline(bitwriter)
+
+#define gst_bit_writer_put_bits_uint8(bitwriter, value, nbits) \
+ G_LIKELY (_gst_bit_writer_put_bits_uint8_inline (bitwriter, value, nbits))
+#define gst_bit_writer_put_bits_uint16(bitwriter, value, nbits) \
+ G_LIKELY (_gst_bit_writer_put_bits_uint16_inline (bitwriter, value, nbits))
+#define gst_bit_writer_put_bits_uint32(bitwriter, value, nbits) \
+ G_LIKELY (_gst_bit_writer_put_bits_uint32_inline (bitwriter, value, nbits))
+#define gst_bit_writer_put_bits_uint64(bitwriter, value, nbits) \
+ G_LIKELY (_gst_bit_writer_put_bits_uint64_inline (bitwriter, value, nbits))
+
+#define gst_bit_writer_put_bytes(bitwriter, data, nbytes) \
+ G_LIKELY (_gst_bit_writer_put_bytes_inline (bitwriter, data, nbytes))
+
+#define gst_bit_writer_align_bytes(bitwriter, trailing_bit) \
+ G_LIKELY (_gst_bit_writer_align_bytes_inline(bitwriter, trailing_bit))
+#endif
+
+G_END_DECLS
+
+#endif /* GST_BIT_WRITER_H */
diff --git a/include/gst/base/gstbytereader.h b/include/gst/base/gstbytereader.h
new file mode 100644
index 0000000000..2130a8a008
--- /dev/null
+++ b/include/gst/base/gstbytereader.h
@@ -0,0 +1,684 @@
+/* GStreamer byte reader
+ *
+ * Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>.
+ * Copyright (C) 2009 Tim-Philipp Müller <tim centricular net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_BYTE_READER_H__
+#define __GST_BYTE_READER_H__
+
+#include <gst/gst.h>
+#include <gst/base/base-prelude.h>
+
+G_BEGIN_DECLS
+
+#define GST_BYTE_READER(reader) ((GstByteReader *) (reader))
+
+/**
+ * GstByteReader:
+ * @data: (array length=size): Data from which the bit reader will
+ * read
+ * @size: Size of @data in bytes
+ * @byte: Current byte position
+ *
+ * A byte reader instance.
+ */
+typedef struct {
+ const guint8 *data;
+ guint size;
+
+ guint byte; /* Byte position */
+
+ /* < private > */
+ gpointer _gst_reserved[GST_PADDING];
+} GstByteReader;
+
+GST_BASE_API
+GstByteReader * gst_byte_reader_new (const guint8 *data, guint size) G_GNUC_MALLOC;
+
+GST_BASE_API
+void gst_byte_reader_free (GstByteReader *reader);
+
+GST_BASE_API
+void gst_byte_reader_init (GstByteReader *reader, const guint8 *data, guint size);
+
+GST_BASE_API
+gboolean gst_byte_reader_peek_sub_reader (GstByteReader * reader,
+ GstByteReader * sub_reader,
+ guint size);
+GST_BASE_API
+gboolean gst_byte_reader_get_sub_reader (GstByteReader * reader,
+ GstByteReader * sub_reader,
+ guint size);
+GST_BASE_API
+gboolean gst_byte_reader_set_pos (GstByteReader *reader, guint pos);
+
+GST_BASE_API
+guint gst_byte_reader_get_pos (const GstByteReader *reader);
+
+GST_BASE_API
+guint gst_byte_reader_get_remaining (const GstByteReader *reader);
+
+GST_BASE_API
+guint gst_byte_reader_get_size (const GstByteReader *reader);
+
+GST_BASE_API
+gboolean gst_byte_reader_skip (GstByteReader *reader, guint nbytes);
+
+GST_BASE_API
+gboolean gst_byte_reader_get_uint8 (GstByteReader *reader, guint8 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_get_int8 (GstByteReader *reader, gint8 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_get_uint16_le (GstByteReader *reader, guint16 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_get_int16_le (GstByteReader *reader, gint16 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_get_uint16_be (GstByteReader *reader, guint16 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_get_int16_be (GstByteReader *reader, gint16 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_get_uint24_le (GstByteReader *reader, guint32 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_get_int24_le (GstByteReader *reader, gint32 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_get_uint24_be (GstByteReader *reader, guint32 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_get_int24_be (GstByteReader *reader, gint32 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_get_uint32_le (GstByteReader *reader, guint32 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_get_int32_le (GstByteReader *reader, gint32 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_get_uint32_be (GstByteReader *reader, guint32 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_get_int32_be (GstByteReader *reader, gint32 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_get_uint64_le (GstByteReader *reader, guint64 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_get_int64_le (GstByteReader *reader, gint64 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_get_uint64_be (GstByteReader *reader, guint64 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_get_int64_be (GstByteReader *reader, gint64 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_peek_uint8 (const GstByteReader *reader, guint8 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_peek_int8 (const GstByteReader *reader, gint8 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_peek_uint16_le (const GstByteReader *reader, guint16 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_peek_int16_le (const GstByteReader *reader, gint16 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_peek_uint16_be (const GstByteReader *reader, guint16 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_peek_int16_be (const GstByteReader *reader, gint16 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_peek_uint24_le (const GstByteReader *reader, guint32 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_peek_int24_le (const GstByteReader *reader, gint32 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_peek_uint24_be (const GstByteReader *reader, guint32 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_peek_int24_be (const GstByteReader *reader, gint32 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_peek_uint32_le (const GstByteReader *reader, guint32 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_peek_int32_le (const GstByteReader *reader, gint32 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_peek_uint32_be (const GstByteReader *reader, guint32 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_peek_int32_be (const GstByteReader *reader, gint32 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_peek_uint64_le (const GstByteReader *reader, guint64 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_peek_int64_le (const GstByteReader *reader, gint64 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_peek_uint64_be (const GstByteReader *reader, guint64 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_peek_int64_be (const GstByteReader *reader, gint64 *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_get_float32_le (GstByteReader *reader, gfloat *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_get_float32_be (GstByteReader *reader, gfloat *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_get_float64_le (GstByteReader *reader, gdouble *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_get_float64_be (GstByteReader *reader, gdouble *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_peek_float32_le (const GstByteReader *reader, gfloat *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_peek_float32_be (const GstByteReader *reader, gfloat *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_peek_float64_le (const GstByteReader *reader, gdouble *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_peek_float64_be (const GstByteReader *reader, gdouble *val);
+
+GST_BASE_API
+gboolean gst_byte_reader_dup_data (GstByteReader * reader, guint size, guint8 ** val);
+
+GST_BASE_API
+gboolean gst_byte_reader_get_data (GstByteReader * reader, guint size, const guint8 ** val);
+
+GST_BASE_API
+gboolean gst_byte_reader_peek_data (const GstByteReader * reader, guint size, const guint8 ** val);
+
+#define gst_byte_reader_dup_string(reader,str) \
+ gst_byte_reader_dup_string_utf8(reader,str)
+
+GST_BASE_API
+gboolean gst_byte_reader_dup_string_utf8 (GstByteReader * reader, gchar ** str);
+
+GST_BASE_API
+gboolean gst_byte_reader_dup_string_utf16 (GstByteReader * reader, guint16 ** str);
+
+GST_BASE_API
+gboolean gst_byte_reader_dup_string_utf32 (GstByteReader * reader, guint32 ** str);
+
+#define gst_byte_reader_skip_string(reader) \
+ gst_byte_reader_skip_string_utf8(reader)
+
+GST_BASE_API
+gboolean gst_byte_reader_skip_string_utf8 (GstByteReader * reader);
+
+GST_BASE_API
+gboolean gst_byte_reader_skip_string_utf16 (GstByteReader * reader);
+
+GST_BASE_API
+gboolean gst_byte_reader_skip_string_utf32 (GstByteReader * reader);
+
+#define gst_byte_reader_get_string(reader,str) \
+ gst_byte_reader_get_string_utf8(reader,str)
+
+#define gst_byte_reader_peek_string(reader,str) \
+ gst_byte_reader_peek_string_utf8(reader,str)
+
+GST_BASE_API
+gboolean gst_byte_reader_get_string_utf8 (GstByteReader * reader, const gchar ** str);
+
+GST_BASE_API
+gboolean gst_byte_reader_peek_string_utf8 (const GstByteReader * reader, const gchar ** str);
+
+GST_BASE_API
+guint gst_byte_reader_masked_scan_uint32 (const GstByteReader * reader,
+ guint32 mask,
+ guint32 pattern,
+ guint offset,
+ guint size);
+GST_BASE_API
+guint gst_byte_reader_masked_scan_uint32_peek (const GstByteReader * reader,
+ guint32 mask,
+ guint32 pattern,
+ guint offset,
+ guint size,
+ guint32 * value);
+
+/**
+ * GST_BYTE_READER_INIT:
+ * @data: Data from which the #GstByteReader should read
+ * @size: Size of @data in bytes
+ *
+ * A #GstByteReader must be initialized with this macro, before it can be
+ * used. This macro can used be to initialize a variable, but it cannot
+ * be assigned to a variable. In that case you have to use
+ * gst_byte_reader_init().
+ */
+#define GST_BYTE_READER_INIT(data, size) {data, size, 0}
+
+/* unchecked variants */
+static inline void
+gst_byte_reader_skip_unchecked (GstByteReader * reader, guint nbytes)
+{
+ reader->byte += nbytes;
+}
+
+#define __GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(bits,type,lower,upper,adj) \
+\
+static inline type \
+gst_byte_reader_peek_##lower##_unchecked (const GstByteReader * reader) \
+{ \
+ type val = (type) GST_READ_##upper (reader->data + reader->byte); \
+ adj \
+ return val; \
+} \
+\
+static inline type \
+gst_byte_reader_get_##lower##_unchecked (GstByteReader * reader) \
+{ \
+ type val = gst_byte_reader_peek_##lower##_unchecked (reader); \
+ reader->byte += bits / 8; \
+ return val; \
+}
+
+__GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(8,guint8,uint8,UINT8,/* */)
+__GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(8,gint8,int8,UINT8,/* */)
+
+__GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(16,guint16,uint16_le,UINT16_LE,/* */)
+__GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(16,guint16,uint16_be,UINT16_BE,/* */)
+__GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(16,gint16,int16_le,UINT16_LE,/* */)
+__GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(16,gint16,int16_be,UINT16_BE,/* */)
+
+__GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(32,guint32,uint32_le,UINT32_LE,/* */)
+__GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(32,guint32,uint32_be,UINT32_BE,/* */)
+__GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(32,gint32,int32_le,UINT32_LE,/* */)
+__GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(32,gint32,int32_be,UINT32_BE,/* */)
+
+__GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(24,guint32,uint24_le,UINT24_LE,/* */)
+__GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(24,guint32,uint24_be,UINT24_BE,/* */)
+
+/* fix up the sign for 24-bit signed ints stored in 32-bit signed ints */
+__GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(24,gint32,int24_le,UINT24_LE,
+ if (val & 0x00800000) val |= 0xff000000;)
+__GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(24,gint32,int24_be,UINT24_BE,
+ if (val & 0x00800000) val |= 0xff000000;)
+
+__GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(64,guint64,uint64_le,UINT64_LE,/* */)
+__GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(64,guint64,uint64_be,UINT64_BE,/* */)
+__GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(64,gint64,int64_le,UINT64_LE,/* */)
+__GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(64,gint64,int64_be,UINT64_BE,/* */)
+
+__GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(32,gfloat,float32_le,FLOAT_LE,/* */)
+__GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(32,gfloat,float32_be,FLOAT_BE,/* */)
+__GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(64,gdouble,float64_le,DOUBLE_LE,/* */)
+__GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(64,gdouble,float64_be,DOUBLE_BE,/* */)
+
+#undef __GET_PEEK_BITS_UNCHECKED
+
+static inline const guint8 *
+gst_byte_reader_peek_data_unchecked (const GstByteReader * reader)
+{
+ return (const guint8 *) (reader->data + reader->byte);
+}
+
+static inline const guint8 *
+gst_byte_reader_get_data_unchecked (GstByteReader * reader, guint size)
+{
+ const guint8 *data;
+
+ data = gst_byte_reader_peek_data_unchecked (reader);
+ gst_byte_reader_skip_unchecked (reader, size);
+ return data;
+}
+
+static inline guint8 *
+gst_byte_reader_dup_data_unchecked (GstByteReader * reader, guint size)
+{
+ gconstpointer data = gst_byte_reader_get_data_unchecked (reader, size);
+ guint8 *dup_data = (guint8 *) g_malloc (size);
+
+ memcpy (dup_data, data, size);
+ return dup_data;
+}
+
+/* Unchecked variants that should not be used */
+static inline guint
+_gst_byte_reader_get_pos_unchecked (const GstByteReader * reader)
+{
+ return reader->byte;
+}
+
+static inline guint
+_gst_byte_reader_get_remaining_unchecked (const GstByteReader * reader)
+{
+ return reader->size - reader->byte;
+}
+
+static inline guint
+_gst_byte_reader_get_size_unchecked (const GstByteReader * reader)
+{
+ return reader->size;
+}
+
+/* inlined variants (do not use directly) */
+
+static inline guint
+_gst_byte_reader_get_remaining_inline (const GstByteReader * reader)
+{
+ g_return_val_if_fail (reader != NULL, 0);
+
+ return _gst_byte_reader_get_remaining_unchecked (reader);
+}
+
+static inline guint
+_gst_byte_reader_get_size_inline (const GstByteReader * reader)
+{
+ g_return_val_if_fail (reader != NULL, 0);
+
+ return _gst_byte_reader_get_size_unchecked (reader);
+}
+
+#define __GST_BYTE_READER_GET_PEEK_BITS_INLINE(bits,type,name) \
+\
+static inline gboolean \
+_gst_byte_reader_peek_##name##_inline (const GstByteReader * reader, type * val) \
+{ \
+ g_return_val_if_fail (reader != NULL, FALSE); \
+ g_return_val_if_fail (val != NULL, FALSE); \
+ \
+ if (_gst_byte_reader_get_remaining_unchecked (reader) < (bits / 8)) \
+ return FALSE; \
+\
+ *val = gst_byte_reader_peek_##name##_unchecked (reader); \
+ return TRUE; \
+} \
+\
+static inline gboolean \
+_gst_byte_reader_get_##name##_inline (GstByteReader * reader, type * val) \
+{ \
+ g_return_val_if_fail (reader != NULL, FALSE); \
+ g_return_val_if_fail (val != NULL, FALSE); \
+ \
+ if (_gst_byte_reader_get_remaining_unchecked (reader) < (bits / 8)) \
+ return FALSE; \
+\
+ *val = gst_byte_reader_get_##name##_unchecked (reader); \
+ return TRUE; \
+}
+
+__GST_BYTE_READER_GET_PEEK_BITS_INLINE(8,guint8,uint8)
+__GST_BYTE_READER_GET_PEEK_BITS_INLINE(8,gint8,int8)
+
+__GST_BYTE_READER_GET_PEEK_BITS_INLINE(16,guint16,uint16_le)
+__GST_BYTE_READER_GET_PEEK_BITS_INLINE(16,guint16,uint16_be)
+__GST_BYTE_READER_GET_PEEK_BITS_INLINE(16,gint16,int16_le)
+__GST_BYTE_READER_GET_PEEK_BITS_INLINE(16,gint16,int16_be)
+
+__GST_BYTE_READER_GET_PEEK_BITS_INLINE(32,guint32,uint32_le)
+__GST_BYTE_READER_GET_PEEK_BITS_INLINE(32,guint32,uint32_be)
+__GST_BYTE_READER_GET_PEEK_BITS_INLINE(32,gint32,int32_le)
+__GST_BYTE_READER_GET_PEEK_BITS_INLINE(32,gint32,int32_be)
+
+__GST_BYTE_READER_GET_PEEK_BITS_INLINE(24,guint32,uint24_le)
+__GST_BYTE_READER_GET_PEEK_BITS_INLINE(24,guint32,uint24_be)
+__GST_BYTE_READER_GET_PEEK_BITS_INLINE(24,gint32,int24_le)
+__GST_BYTE_READER_GET_PEEK_BITS_INLINE(24,gint32,int24_be)
+
+__GST_BYTE_READER_GET_PEEK_BITS_INLINE(64,guint64,uint64_le)
+__GST_BYTE_READER_GET_PEEK_BITS_INLINE(64,guint64,uint64_be)
+__GST_BYTE_READER_GET_PEEK_BITS_INLINE(64,gint64,int64_le)
+__GST_BYTE_READER_GET_PEEK_BITS_INLINE(64,gint64,int64_be)
+
+__GST_BYTE_READER_GET_PEEK_BITS_INLINE(32,gfloat,float32_le)
+__GST_BYTE_READER_GET_PEEK_BITS_INLINE(32,gfloat,float32_be)
+__GST_BYTE_READER_GET_PEEK_BITS_INLINE(64,gdouble,float64_le)
+__GST_BYTE_READER_GET_PEEK_BITS_INLINE(64,gdouble,float64_be)
+
+#undef __GST_BYTE_READER_GET_PEEK_BITS_INLINE
+
+#ifndef GST_BYTE_READER_DISABLE_INLINES
+
+#define gst_byte_reader_init(reader,data,size) \
+ _gst_byte_reader_init_inline(reader,data,size)
+
+#define gst_byte_reader_get_remaining(reader) \
+ _gst_byte_reader_get_remaining_inline(reader)
+
+#define gst_byte_reader_get_size(reader) \
+ _gst_byte_reader_get_size_inline(reader)
+
+#define gst_byte_reader_get_pos(reader) \
+ _gst_byte_reader_get_pos_inline(reader)
+
+/* we use defines here so we can add the G_LIKELY() */
+#define gst_byte_reader_get_uint8(reader,val) \
+ G_LIKELY(_gst_byte_reader_get_uint8_inline(reader,val))
+#define gst_byte_reader_get_int8(reader,val) \
+ G_LIKELY(_gst_byte_reader_get_int8_inline(reader,val))
+#define gst_byte_reader_get_uint16_le(reader,val) \
+ G_LIKELY(_gst_byte_reader_get_uint16_le_inline(reader,val))
+#define gst_byte_reader_get_int16_le(reader,val) \
+ G_LIKELY(_gst_byte_reader_get_int16_le_inline(reader,val))
+#define gst_byte_reader_get_uint16_be(reader,val) \
+ G_LIKELY(_gst_byte_reader_get_uint16_be_inline(reader,val))
+#define gst_byte_reader_get_int16_be(reader,val) \
+ G_LIKELY(_gst_byte_reader_get_int16_be_inline(reader,val))
+#define gst_byte_reader_get_uint24_le(reader,val) \
+ G_LIKELY(_gst_byte_reader_get_uint24_le_inline(reader,val))
+#define gst_byte_reader_get_int24_le(reader,val) \
+ G_LIKELY(_gst_byte_reader_get_int24_le_inline(reader,val))
+#define gst_byte_reader_get_uint24_be(reader,val) \
+ G_LIKELY(_gst_byte_reader_get_uint24_be_inline(reader,val))
+#define gst_byte_reader_get_int24_be(reader,val) \
+ G_LIKELY(_gst_byte_reader_get_int24_be_inline(reader,val))
+#define gst_byte_reader_get_uint32_le(reader,val) \
+ G_LIKELY(_gst_byte_reader_get_uint32_le_inline(reader,val))
+#define gst_byte_reader_get_int32_le(reader,val) \
+ G_LIKELY(_gst_byte_reader_get_int32_le_inline(reader,val))
+#define gst_byte_reader_get_uint32_be(reader,val) \
+ G_LIKELY(_gst_byte_reader_get_uint32_be_inline(reader,val))
+#define gst_byte_reader_get_int32_be(reader,val) \
+ G_LIKELY(_gst_byte_reader_get_int32_be_inline(reader,val))
+#define gst_byte_reader_get_uint64_le(reader,val) \
+ G_LIKELY(_gst_byte_reader_get_uint64_le_inline(reader,val))
+#define gst_byte_reader_get_int64_le(reader,val) \
+ G_LIKELY(_gst_byte_reader_get_int64_le_inline(reader,val))
+#define gst_byte_reader_get_uint64_be(reader,val) \
+ G_LIKELY(_gst_byte_reader_get_uint64_be_inline(reader,val))
+#define gst_byte_reader_get_int64_be(reader,val) \
+ G_LIKELY(_gst_byte_reader_get_int64_be_inline(reader,val))
+
+#define gst_byte_reader_peek_uint8(reader,val) \
+ G_LIKELY(_gst_byte_reader_peek_uint8_inline(reader,val))
+#define gst_byte_reader_peek_int8(reader,val) \
+ G_LIKELY(_gst_byte_reader_peek_int8_inline(reader,val))
+#define gst_byte_reader_peek_uint16_le(reader,val) \
+ G_LIKELY(_gst_byte_reader_peek_uint16_le_inline(reader,val))
+#define gst_byte_reader_peek_int16_le(reader,val) \
+ G_LIKELY(_gst_byte_reader_peek_int16_le_inline(reader,val))
+#define gst_byte_reader_peek_uint16_be(reader,val) \
+ G_LIKELY(_gst_byte_reader_peek_uint16_be_inline(reader,val))
+#define gst_byte_reader_peek_int16_be(reader,val) \
+ G_LIKELY(_gst_byte_reader_peek_int16_be_inline(reader,val))
+#define gst_byte_reader_peek_uint24_le(reader,val) \
+ G_LIKELY(_gst_byte_reader_peek_uint24_le_inline(reader,val))
+#define gst_byte_reader_peek_int24_le(reader,val) \
+ G_LIKELY(_gst_byte_reader_peek_int24_le_inline(reader,val))
+#define gst_byte_reader_peek_uint24_be(reader,val) \
+ G_LIKELY(_gst_byte_reader_peek_uint24_be_inline(reader,val))
+#define gst_byte_reader_peek_int24_be(reader,val) \
+ G_LIKELY(_gst_byte_reader_peek_int24_be_inline(reader,val))
+#define gst_byte_reader_peek_uint32_le(reader,val) \
+ G_LIKELY(_gst_byte_reader_peek_uint32_le_inline(reader,val))
+#define gst_byte_reader_peek_int32_le(reader,val) \
+ G_LIKELY(_gst_byte_reader_peek_int32_le_inline(reader,val))
+#define gst_byte_reader_peek_uint32_be(reader,val) \
+ G_LIKELY(_gst_byte_reader_peek_uint32_be_inline(reader,val))
+#define gst_byte_reader_peek_int32_be(reader,val) \
+ G_LIKELY(_gst_byte_reader_peek_int32_be_inline(reader,val))
+#define gst_byte_reader_peek_uint64_le(reader,val) \
+ G_LIKELY(_gst_byte_reader_peek_uint64_le_inline(reader,val))
+#define gst_byte_reader_peek_int64_le(reader,val) \
+ G_LIKELY(_gst_byte_reader_peek_int64_le_inline(reader,val))
+#define gst_byte_reader_peek_uint64_be(reader,val) \
+ G_LIKELY(_gst_byte_reader_peek_uint64_be_inline(reader,val))
+#define gst_byte_reader_peek_int64_be(reader,val) \
+ G_LIKELY(_gst_byte_reader_peek_int64_be_inline(reader,val))
+
+#define gst_byte_reader_get_float32_le(reader,val) \
+ G_LIKELY(_gst_byte_reader_get_float32_le_inline(reader,val))
+#define gst_byte_reader_get_float32_be(reader,val) \
+ G_LIKELY(_gst_byte_reader_get_float32_be_inline(reader,val))
+#define gst_byte_reader_get_float64_le(reader,val) \
+ G_LIKELY(_gst_byte_reader_get_float64_le_inline(reader,val))
+#define gst_byte_reader_get_float64_be(reader,val) \
+ G_LIKELY(_gst_byte_reader_get_float64_be_inline(reader,val))
+#define gst_byte_reader_peek_float32_le(reader,val) \
+ G_LIKELY(_gst_byte_reader_peek_float32_le_inline(reader,val))
+#define gst_byte_reader_peek_float32_be(reader,val) \
+ G_LIKELY(_gst_byte_reader_peek_float32_be_inline(reader,val))
+#define gst_byte_reader_peek_float64_le(reader,val) \
+ G_LIKELY(_gst_byte_reader_peek_float64_le_inline(reader,val))
+#define gst_byte_reader_peek_float64_be(reader,val) \
+ G_LIKELY(_gst_byte_reader_peek_float64_be_inline(reader,val))
+
+#endif /* GST_BYTE_READER_DISABLE_INLINES */
+
+static inline void
+_gst_byte_reader_init_inline (GstByteReader * reader, const guint8 * data, guint size)
+{
+ g_return_if_fail (reader != NULL);
+
+ reader->data = data;
+ reader->size = size;
+ reader->byte = 0;
+}
+
+static inline gboolean
+_gst_byte_reader_peek_sub_reader_inline (GstByteReader * reader,
+ GstByteReader * sub_reader, guint size)
+{
+ g_return_val_if_fail (reader != NULL, FALSE);
+ g_return_val_if_fail (sub_reader != NULL, FALSE);
+
+ if (_gst_byte_reader_get_remaining_unchecked (reader) < size)
+ return FALSE;
+
+ sub_reader->data = reader->data + reader->byte;
+ sub_reader->byte = 0;
+ sub_reader->size = size;
+ return TRUE;
+}
+
+static inline gboolean
+_gst_byte_reader_get_sub_reader_inline (GstByteReader * reader,
+ GstByteReader * sub_reader, guint size)
+{
+ if (!_gst_byte_reader_peek_sub_reader_inline (reader, sub_reader, size))
+ return FALSE;
+ gst_byte_reader_skip_unchecked (reader, size);
+ return TRUE;
+}
+
+static inline gboolean
+_gst_byte_reader_dup_data_inline (GstByteReader * reader, guint size, guint8 ** val)
+{
+ g_return_val_if_fail (reader != NULL, FALSE);
+ g_return_val_if_fail (val != NULL, FALSE);
+
+ if (G_UNLIKELY (size > reader->size || _gst_byte_reader_get_remaining_unchecked (reader) < size))
+ return FALSE;
+
+ *val = gst_byte_reader_dup_data_unchecked (reader, size);
+ return TRUE;
+}
+
+static inline gboolean
+_gst_byte_reader_get_data_inline (GstByteReader * reader, guint size, const guint8 ** val)
+{
+ g_return_val_if_fail (reader != NULL, FALSE);
+ g_return_val_if_fail (val != NULL, FALSE);
+
+ if (G_UNLIKELY (size > reader->size || _gst_byte_reader_get_remaining_unchecked (reader) < size))
+ return FALSE;
+
+ *val = gst_byte_reader_get_data_unchecked (reader, size);
+ return TRUE;
+}
+
+static inline gboolean
+_gst_byte_reader_peek_data_inline (const GstByteReader * reader, guint size, const guint8 ** val)
+{
+ g_return_val_if_fail (reader != NULL, FALSE);
+ g_return_val_if_fail (val != NULL, FALSE);
+
+ if (G_UNLIKELY (size > reader->size || _gst_byte_reader_get_remaining_unchecked (reader) < size))
+ return FALSE;
+
+ *val = gst_byte_reader_peek_data_unchecked (reader);
+ return TRUE;
+}
+
+static inline guint
+_gst_byte_reader_get_pos_inline (const GstByteReader * reader)
+{
+ g_return_val_if_fail (reader != NULL, 0);
+
+ return _gst_byte_reader_get_pos_unchecked (reader);
+}
+
+static inline gboolean
+_gst_byte_reader_skip_inline (GstByteReader * reader, guint nbytes)
+{
+ g_return_val_if_fail (reader != NULL, FALSE);
+
+ if (G_UNLIKELY (_gst_byte_reader_get_remaining_unchecked (reader) < nbytes))
+ return FALSE;
+
+ reader->byte += nbytes;
+ return TRUE;
+}
+
+#ifndef GST_BYTE_READER_DISABLE_INLINES
+
+#define gst_byte_reader_dup_data(reader,size,val) \
+ G_LIKELY(_gst_byte_reader_dup_data_inline(reader,size,val))
+#define gst_byte_reader_get_data(reader,size,val) \
+ G_LIKELY(_gst_byte_reader_get_data_inline(reader,size,val))
+#define gst_byte_reader_peek_data(reader,size,val) \
+ G_LIKELY(_gst_byte_reader_peek_data_inline(reader,size,val))
+#define gst_byte_reader_skip(reader,nbytes) \
+ G_LIKELY(_gst_byte_reader_skip_inline(reader,nbytes))
+
+#endif /* GST_BYTE_READER_DISABLE_INLINES */
+
+G_END_DECLS
+
+#endif /* __GST_BYTE_READER_H__ */
diff --git a/include/gst/base/gstbytewriter.h b/include/gst/base/gstbytewriter.h
new file mode 100644
index 0000000000..365c7742d7
--- /dev/null
+++ b/include/gst/base/gstbytewriter.h
@@ -0,0 +1,468 @@
+/* GStreamer byte writer
+ *
+ * Copyright (C) 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_BYTE_WRITER_H__
+#define __GST_BYTE_WRITER_H__
+
+#include <gst/gst.h>
+#include <gst/base/gstbytereader.h>
+
+#include <string.h>
+
+G_BEGIN_DECLS
+
+#define GST_BYTE_WRITER(writer) ((GstByteWriter *) (writer))
+
+/**
+ * GstByteWriter:
+ * @parent: #GstByteReader parent
+ * @alloc_size: Allocation size of the data
+ * @fixed: If %TRUE no reallocations are allowed
+ * @owned: If %FALSE no reallocations are allowed and copies of data are returned
+ *
+ * A byte writer instance.
+ */
+typedef struct {
+ GstByteReader parent;
+
+ guint alloc_size;
+
+ gboolean fixed;
+ gboolean owned;
+
+ /* < private > */
+ gpointer _gst_reserved[GST_PADDING];
+} GstByteWriter;
+
+GST_BASE_API
+GstByteWriter * gst_byte_writer_new (void) G_GNUC_MALLOC;
+
+GST_BASE_API
+GstByteWriter * gst_byte_writer_new_with_size (guint size, gboolean fixed) G_GNUC_MALLOC;
+
+GST_BASE_API
+GstByteWriter * gst_byte_writer_new_with_data (guint8 *data, guint size, gboolean initialized) G_GNUC_MALLOC;
+
+GST_BASE_API
+void gst_byte_writer_init (GstByteWriter *writer);
+
+GST_BASE_API
+void gst_byte_writer_init_with_size (GstByteWriter *writer, guint size, gboolean fixed);
+
+GST_BASE_API
+void gst_byte_writer_init_with_data (GstByteWriter *writer, guint8 *data,
+ guint size, gboolean initialized);
+GST_BASE_API
+void gst_byte_writer_free (GstByteWriter *writer);
+
+GST_BASE_API
+guint8 * gst_byte_writer_free_and_get_data (GstByteWriter *writer);
+
+GST_BASE_API
+GstBuffer * gst_byte_writer_free_and_get_buffer (GstByteWriter *writer) G_GNUC_MALLOC;
+
+GST_BASE_API
+void gst_byte_writer_reset (GstByteWriter *writer);
+
+GST_BASE_API
+guint8 * gst_byte_writer_reset_and_get_data (GstByteWriter *writer);
+
+GST_BASE_API
+GstBuffer * gst_byte_writer_reset_and_get_buffer (GstByteWriter *writer) G_GNUC_MALLOC;
+
+/**
+ * gst_byte_writer_get_pos:
+ * @writer: #GstByteWriter instance
+ *
+ * Returns: The current position of the read/write cursor
+ */
+/**
+ * gst_byte_writer_set_pos:
+ * @writer: #GstByteWriter instance
+ * @pos: new position
+ *
+ * Sets the current read/write cursor of @writer. The new position
+ * can only be between 0 and the current size.
+ *
+ * Returns: %TRUE if the new position could be set
+ */
+/**
+ * gst_byte_writer_get_size:
+ * @writer: #GstByteWriter instance
+ *
+ * Returns: The current, initialized size of the data
+ */
+static inline guint
+gst_byte_writer_get_pos (const GstByteWriter *writer)
+{
+ return gst_byte_reader_get_pos ((const GstByteReader *) writer);
+}
+
+static inline gboolean
+gst_byte_writer_set_pos (GstByteWriter *writer, guint pos)
+{
+ return gst_byte_reader_set_pos (GST_BYTE_READER (writer), pos);
+}
+
+static inline guint
+gst_byte_writer_get_size (const GstByteWriter *writer)
+{
+ return gst_byte_reader_get_size ((const GstByteReader *) writer);
+}
+
+GST_BASE_API
+guint gst_byte_writer_get_remaining (const GstByteWriter *writer);
+
+GST_BASE_API
+gboolean gst_byte_writer_ensure_free_space (GstByteWriter *writer, guint size);
+
+GST_BASE_API
+gboolean gst_byte_writer_put_uint8 (GstByteWriter *writer, guint8 val);
+
+GST_BASE_API
+gboolean gst_byte_writer_put_int8 (GstByteWriter *writer, gint8 val);
+
+GST_BASE_API
+gboolean gst_byte_writer_put_uint16_be (GstByteWriter *writer, guint16 val);
+
+GST_BASE_API
+gboolean gst_byte_writer_put_uint16_le (GstByteWriter *writer, guint16 val);
+
+GST_BASE_API
+gboolean gst_byte_writer_put_int16_be (GstByteWriter *writer, gint16 val);
+
+GST_BASE_API
+gboolean gst_byte_writer_put_int16_le (GstByteWriter *writer, gint16 val);
+
+GST_BASE_API
+gboolean gst_byte_writer_put_uint24_be (GstByteWriter *writer, guint32 val);
+
+GST_BASE_API
+gboolean gst_byte_writer_put_uint24_le (GstByteWriter *writer, guint32 val);
+
+GST_BASE_API
+gboolean gst_byte_writer_put_int24_be (GstByteWriter *writer, gint32 val);
+
+GST_BASE_API
+gboolean gst_byte_writer_put_int24_le (GstByteWriter *writer, gint32 val);
+
+GST_BASE_API
+gboolean gst_byte_writer_put_uint32_be (GstByteWriter *writer, guint32 val);
+
+GST_BASE_API
+gboolean gst_byte_writer_put_uint32_le (GstByteWriter *writer, guint32 val);
+
+GST_BASE_API
+gboolean gst_byte_writer_put_int32_be (GstByteWriter *writer, gint32 val);
+
+GST_BASE_API
+gboolean gst_byte_writer_put_int32_le (GstByteWriter *writer, gint32 val);
+
+GST_BASE_API
+gboolean gst_byte_writer_put_uint64_be (GstByteWriter *writer, guint64 val);
+
+GST_BASE_API
+gboolean gst_byte_writer_put_uint64_le (GstByteWriter *writer, guint64 val);
+
+GST_BASE_API
+gboolean gst_byte_writer_put_int64_be (GstByteWriter *writer, gint64 val);
+
+GST_BASE_API
+gboolean gst_byte_writer_put_int64_le (GstByteWriter *writer, gint64 val);
+
+GST_BASE_API
+gboolean gst_byte_writer_put_float32_be (GstByteWriter *writer, gfloat val);
+
+GST_BASE_API
+gboolean gst_byte_writer_put_float32_le (GstByteWriter *writer, gfloat val);
+
+GST_BASE_API
+gboolean gst_byte_writer_put_float64_be (GstByteWriter *writer, gdouble val);
+
+GST_BASE_API
+gboolean gst_byte_writer_put_float64_le (GstByteWriter *writer, gdouble val);
+
+GST_BASE_API
+gboolean gst_byte_writer_put_data (GstByteWriter *writer, const guint8 *data, guint size);
+
+GST_BASE_API
+gboolean gst_byte_writer_fill (GstByteWriter *writer, guint8 value, guint size);
+
+GST_BASE_API
+gboolean gst_byte_writer_put_string_utf8 (GstByteWriter *writer, const gchar *data);
+
+GST_BASE_API
+gboolean gst_byte_writer_put_string_utf16 (GstByteWriter *writer, const guint16 *data);
+
+GST_BASE_API
+gboolean gst_byte_writer_put_string_utf32 (GstByteWriter *writer, const guint32 *data);
+gboolean gst_byte_writer_put_buffer (GstByteWriter *writer, GstBuffer * buffer, gsize offset, gssize size);
+
+/**
+ * gst_byte_writer_put_string:
+ * @writer: #GstByteWriter instance
+ * @data: (in) (array zero-terminated=1): Null terminated string
+ *
+ * Write a NUL-terminated string to @writer (including the terminator). The
+ * string is assumed to be in an 8-bit encoding (e.g. ASCII,UTF-8 or
+ * ISO-8859-1).
+ *
+ * Returns: %TRUE if the string could be written
+ */
+#define gst_byte_writer_put_string(writer, data) \
+ gst_byte_writer_put_string_utf8(writer, data)
+
+static inline guint
+_gst_byte_writer_next_pow2 (guint n)
+{
+ guint ret = 16;
+
+ /* We start with 16, smaller allocations make no sense */
+
+ while (ret < n && ret > 0)
+ ret <<= 1;
+
+ return ret ? ret : n;
+}
+
+static inline gboolean
+_gst_byte_writer_ensure_free_space_inline (GstByteWriter * writer, guint size)
+{
+ gpointer data;
+
+ if (G_LIKELY (size <= writer->alloc_size - writer->parent.byte))
+ return TRUE;
+ if (G_UNLIKELY (writer->fixed || !writer->owned))
+ return FALSE;
+ if (G_UNLIKELY (writer->parent.byte > G_MAXUINT - size))
+ return FALSE;
+
+ writer->alloc_size = _gst_byte_writer_next_pow2 (writer->parent.byte + size);
+ data = g_try_realloc ((guint8 *) writer->parent.data, writer->alloc_size);
+ if (G_UNLIKELY (data == NULL))
+ return FALSE;
+
+ writer->parent.data = (guint8 *) data;
+
+ return TRUE;
+}
+
+#define __GST_BYTE_WRITER_CREATE_WRITE_FUNC(bits,type,name,write_func) \
+static inline void \
+gst_byte_writer_put_##name##_unchecked (GstByteWriter *writer, type val) \
+{ \
+ guint8 *write_data; \
+ \
+ write_data = (guint8 *) writer->parent.data + writer->parent.byte; \
+ write_func (write_data, val); \
+ writer->parent.byte += bits/8; \
+ writer->parent.size = MAX (writer->parent.size, writer->parent.byte); \
+} \
+\
+static inline gboolean \
+_gst_byte_writer_put_##name##_inline (GstByteWriter *writer, type val) \
+{ \
+ g_return_val_if_fail (writer != NULL, FALSE); \
+ \
+ if (G_UNLIKELY (!_gst_byte_writer_ensure_free_space_inline(writer, bits/8))) \
+ return FALSE; \
+ \
+ gst_byte_writer_put_##name##_unchecked (writer, val); \
+ \
+ return TRUE; \
+}
+
+__GST_BYTE_WRITER_CREATE_WRITE_FUNC (8, guint8, uint8, GST_WRITE_UINT8)
+__GST_BYTE_WRITER_CREATE_WRITE_FUNC (8, gint8, int8, GST_WRITE_UINT8)
+__GST_BYTE_WRITER_CREATE_WRITE_FUNC (16, guint16, uint16_le, GST_WRITE_UINT16_LE)
+__GST_BYTE_WRITER_CREATE_WRITE_FUNC (16, guint16, uint16_be, GST_WRITE_UINT16_BE)
+__GST_BYTE_WRITER_CREATE_WRITE_FUNC (16, gint16, int16_le, GST_WRITE_UINT16_LE)
+__GST_BYTE_WRITER_CREATE_WRITE_FUNC (16, gint16, int16_be, GST_WRITE_UINT16_BE)
+__GST_BYTE_WRITER_CREATE_WRITE_FUNC (24, guint32, uint24_le, GST_WRITE_UINT24_LE)
+__GST_BYTE_WRITER_CREATE_WRITE_FUNC (24, guint32, uint24_be, GST_WRITE_UINT24_BE)
+__GST_BYTE_WRITER_CREATE_WRITE_FUNC (24, gint32, int24_le, GST_WRITE_UINT24_LE)
+__GST_BYTE_WRITER_CREATE_WRITE_FUNC (24, gint32, int24_be, GST_WRITE_UINT24_BE)
+__GST_BYTE_WRITER_CREATE_WRITE_FUNC (32, guint32, uint32_le, GST_WRITE_UINT32_LE)
+__GST_BYTE_WRITER_CREATE_WRITE_FUNC (32, guint32, uint32_be, GST_WRITE_UINT32_BE)
+__GST_BYTE_WRITER_CREATE_WRITE_FUNC (32, gint32, int32_le, GST_WRITE_UINT32_LE)
+__GST_BYTE_WRITER_CREATE_WRITE_FUNC (32, gint32, int32_be, GST_WRITE_UINT32_BE)
+__GST_BYTE_WRITER_CREATE_WRITE_FUNC (64, guint64, uint64_le, GST_WRITE_UINT64_LE)
+__GST_BYTE_WRITER_CREATE_WRITE_FUNC (64, guint64, uint64_be, GST_WRITE_UINT64_BE)
+__GST_BYTE_WRITER_CREATE_WRITE_FUNC (64, gint64, int64_le, GST_WRITE_UINT64_LE)
+__GST_BYTE_WRITER_CREATE_WRITE_FUNC (64, gint64, int64_be, GST_WRITE_UINT64_BE)
+
+__GST_BYTE_WRITER_CREATE_WRITE_FUNC (32, gfloat, float32_be, GST_WRITE_FLOAT_BE)
+__GST_BYTE_WRITER_CREATE_WRITE_FUNC (32, gfloat, float32_le, GST_WRITE_FLOAT_LE)
+__GST_BYTE_WRITER_CREATE_WRITE_FUNC (64, gdouble, float64_be, GST_WRITE_DOUBLE_BE)
+__GST_BYTE_WRITER_CREATE_WRITE_FUNC (64, gdouble, float64_le, GST_WRITE_DOUBLE_LE)
+
+#undef __GST_BYTE_WRITER_CREATE_WRITE_FUNC
+
+static inline void
+gst_byte_writer_put_data_unchecked (GstByteWriter * writer, const guint8 * data,
+ guint size)
+{
+ memcpy ((guint8 *) & writer->parent.data[writer->parent.byte], data, size);
+ writer->parent.byte += size;
+ writer->parent.size = MAX (writer->parent.size, writer->parent.byte);
+}
+
+static inline gboolean
+_gst_byte_writer_put_data_inline (GstByteWriter * writer, const guint8 * data,
+ guint size)
+{
+ g_return_val_if_fail (writer != NULL, FALSE);
+
+ if (G_UNLIKELY (!_gst_byte_writer_ensure_free_space_inline (writer, size)))
+ return FALSE;
+
+ gst_byte_writer_put_data_unchecked (writer, data, size);
+
+ return TRUE;
+}
+
+static inline void
+gst_byte_writer_fill_unchecked (GstByteWriter * writer, guint8 value, guint size)
+{
+ memset ((guint8 *) & writer->parent.data[writer->parent.byte], value, size);
+ writer->parent.byte += size;
+ writer->parent.size = MAX (writer->parent.size, writer->parent.byte);
+}
+
+static inline gboolean
+_gst_byte_writer_fill_inline (GstByteWriter * writer, guint8 value, guint size)
+{
+ g_return_val_if_fail (writer != NULL, FALSE);
+
+ if (G_UNLIKELY (!_gst_byte_writer_ensure_free_space_inline (writer, size)))
+ return FALSE;
+
+ gst_byte_writer_fill_unchecked (writer, value, size);
+
+ return TRUE;
+}
+
+static inline void
+gst_byte_writer_put_buffer_unchecked (GstByteWriter * writer, GstBuffer * buffer,
+ gsize offset, gssize size)
+{
+ if (size == -1) {
+ size = gst_buffer_get_size (buffer);
+
+ if (offset >= (gsize) size)
+ return;
+
+ size -= offset;
+ }
+
+ gst_buffer_extract (buffer, offset,
+ (guint8 *) & writer->parent.data[writer->parent.byte], size);
+ writer->parent.byte += size;
+ writer->parent.size = MAX (writer->parent.size, writer->parent.byte);
+}
+
+static inline gboolean
+_gst_byte_writer_put_buffer_inline (GstByteWriter * writer, GstBuffer * buffer,
+ gsize offset, gssize size)
+{
+ g_return_val_if_fail (writer != NULL, FALSE);
+ g_return_val_if_fail (size >= -1, FALSE);
+
+ if (size == -1) {
+ size = gst_buffer_get_size (buffer);
+
+ if (offset >= (gsize) size)
+ return TRUE;
+
+ size -= offset;
+ }
+
+ if (G_UNLIKELY (!_gst_byte_writer_ensure_free_space_inline (writer, size)))
+ return FALSE;
+
+ gst_byte_writer_put_buffer_unchecked (writer, buffer, offset, size);
+
+ return TRUE;
+}
+
+#ifndef GST_BYTE_WRITER_DISABLE_INLINES
+
+/* we use defines here so we can add the G_LIKELY() */
+
+#define gst_byte_writer_ensure_free_space(writer, size) \
+ G_LIKELY (_gst_byte_writer_ensure_free_space_inline (writer, size))
+#define gst_byte_writer_put_uint8(writer, val) \
+ G_LIKELY (_gst_byte_writer_put_uint8_inline (writer, val))
+#define gst_byte_writer_put_int8(writer, val) \
+ G_LIKELY (_gst_byte_writer_put_int8_inline (writer, val))
+#define gst_byte_writer_put_uint16_be(writer, val) \
+ G_LIKELY (_gst_byte_writer_put_uint16_be_inline (writer, val))
+#define gst_byte_writer_put_uint16_le(writer, val) \
+ G_LIKELY (_gst_byte_writer_put_uint16_le_inline (writer, val))
+#define gst_byte_writer_put_int16_be(writer, val) \
+ G_LIKELY (_gst_byte_writer_put_int16_be_inline (writer, val))
+#define gst_byte_writer_put_int16_le(writer, val) \
+ G_LIKELY (_gst_byte_writer_put_int16_le_inline (writer, val))
+#define gst_byte_writer_put_uint24_be(writer, val) \
+ G_LIKELY (_gst_byte_writer_put_uint24_be_inline (writer, val))
+#define gst_byte_writer_put_uint24_le(writer, val) \
+ G_LIKELY (_gst_byte_writer_put_uint24_le_inline (writer, val))
+#define gst_byte_writer_put_int24_be(writer, val) \
+ G_LIKELY (_gst_byte_writer_put_int24_be_inline (writer, val))
+#define gst_byte_writer_put_int24_le(writer, val) \
+ G_LIKELY (_gst_byte_writer_put_int24_le_inline (writer, val))
+#define gst_byte_writer_put_uint32_be(writer, val) \
+ G_LIKELY (_gst_byte_writer_put_uint32_be_inline (writer, val))
+#define gst_byte_writer_put_uint32_le(writer, val) \
+ G_LIKELY (_gst_byte_writer_put_uint32_le_inline (writer, val))
+#define gst_byte_writer_put_int32_be(writer, val) \
+ G_LIKELY (_gst_byte_writer_put_int32_be_inline (writer, val))
+#define gst_byte_writer_put_int32_le(writer, val) \
+ G_LIKELY (_gst_byte_writer_put_int32_le_inline (writer, val))
+#define gst_byte_writer_put_uint64_be(writer, val) \
+ G_LIKELY (_gst_byte_writer_put_uint64_be_inline (writer, val))
+#define gst_byte_writer_put_uint64_le(writer, val) \
+ G_LIKELY (_gst_byte_writer_put_uint64_le_inline (writer, val))
+#define gst_byte_writer_put_int64_be(writer, val) \
+ G_LIKELY (_gst_byte_writer_put_int64_be_inline (writer, val))
+#define gst_byte_writer_put_int64_le(writer, val) \
+ G_LIKELY (_gst_byte_writer_put_int64_le_inline (writer, val))
+
+#define gst_byte_writer_put_float32_be(writer, val) \
+ G_LIKELY (_gst_byte_writer_put_float32_be_inline (writer, val))
+#define gst_byte_writer_put_float32_le(writer, val) \
+ G_LIKELY (_gst_byte_writer_put_float32_le_inline (writer, val))
+#define gst_byte_writer_put_float64_be(writer, val) \
+ G_LIKELY (_gst_byte_writer_put_float64_be_inline (writer, val))
+#define gst_byte_writer_put_float64_le(writer, val) \
+ G_LIKELY (_gst_byte_writer_put_float64_le_inline (writer, val))
+
+#define gst_byte_writer_put_data(writer, data, size) \
+ G_LIKELY (_gst_byte_writer_put_data_inline (writer, data, size))
+#define gst_byte_writer_fill(writer, val, size) \
+ G_LIKELY (_gst_byte_writer_fill_inline (writer, val, size))
+#define gst_byte_writer_put_buffer(writer, buffer, offset, size) \
+ G_LIKELY (_gst_byte_writer_put_buffer_inline (writer, buffer, offset, size))
+
+#endif
+
+G_END_DECLS
+
+#endif /* __GST_BYTE_WRITER_H__ */
diff --git a/include/gst/base/gstcollectpads.h b/include/gst/base/gstcollectpads.h
new file mode 100644
index 0000000000..13d60a17d9
--- /dev/null
+++ b/include/gst/base/gstcollectpads.h
@@ -0,0 +1,456 @@
+/* GStreamer
+ * Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
+ * Copyright (C) 2008 Mark Nauwelaerts <mnauw@users.sourceforge.net>
+ *
+ * gstcollectpads.h:
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_COLLECT_PADS_H__
+#define __GST_COLLECT_PADS_H__
+
+#include <gst/gst.h>
+#include <gst/base/base-prelude.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_COLLECT_PADS (gst_collect_pads_get_type())
+#define GST_COLLECT_PADS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_COLLECT_PADS,GstCollectPads))
+#define GST_COLLECT_PADS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_COLLECT_PADS,GstCollectPadsClass))
+#define GST_COLLECT_PADS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),GST_TYPE_COLLECT_PADS,GstCollectPadsClass))
+#define GST_IS_COLLECT_PADS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_COLLECT_PADS))
+#define GST_IS_COLLECT_PADS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_COLLECT_PADS))
+
+typedef struct _GstCollectData GstCollectData;
+typedef struct _GstCollectDataPrivate GstCollectDataPrivate;
+typedef struct _GstCollectPads GstCollectPads;
+typedef struct _GstCollectPadsPrivate GstCollectPadsPrivate;
+typedef struct _GstCollectPadsClass GstCollectPadsClass;
+
+/**
+ * GstCollectDataDestroyNotify:
+ * @data: the #GstCollectData that will be freed
+ *
+ * A function that will be called when the #GstCollectData will be freed.
+ * It is passed the pointer to the structure and should free any custom
+ * memory and resources allocated for it.
+ */
+typedef void (*GstCollectDataDestroyNotify) (GstCollectData *data);
+
+/**
+ * GstCollectPadsStateFlags:
+ * @GST_COLLECT_PADS_STATE_EOS: Set if collectdata's pad is EOS.
+ * @GST_COLLECT_PADS_STATE_FLUSHING: Set if collectdata's pad is flushing.
+ * @GST_COLLECT_PADS_STATE_NEW_SEGMENT: Set if collectdata's pad received a
+ * new_segment event.
+ * @GST_COLLECT_PADS_STATE_WAITING: Set if collectdata's pad must be waited
+ * for when collecting.
+ * @GST_COLLECT_PADS_STATE_LOCKED: Set collectdata's pad WAITING state must
+ * not be changed.
+ * #GstCollectPadsStateFlags indicate private state of a collectdata('s pad).
+ */
+typedef enum {
+ GST_COLLECT_PADS_STATE_EOS = 1 << 0,
+ GST_COLLECT_PADS_STATE_FLUSHING = 1 << 1,
+ GST_COLLECT_PADS_STATE_NEW_SEGMENT = 1 << 2,
+ GST_COLLECT_PADS_STATE_WAITING = 1 << 3,
+ GST_COLLECT_PADS_STATE_LOCKED = 1 << 4
+} GstCollectPadsStateFlags;
+
+/**
+ * GST_COLLECT_PADS_STATE:
+ * @data: a #GstCollectData.
+ *
+ * A flags word containing #GstCollectPadsStateFlags flags set
+ * on this collected pad.
+ */
+#define GST_COLLECT_PADS_STATE(data) (((GstCollectData *) data)->state)
+/**
+ * GST_COLLECT_PADS_STATE_IS_SET:
+ * @data: a #GstCollectData.
+ * @flag: the #GstCollectPadsStateFlags to check.
+ *
+ * Gives the status of a specific flag on a collected pad.
+ */
+#define GST_COLLECT_PADS_STATE_IS_SET(data,flag) !!(GST_COLLECT_PADS_STATE (data) & flag)
+/**
+ * GST_COLLECT_PADS_STATE_SET:
+ * @data: a #GstCollectData.
+ * @flag: the #GstCollectPadsStateFlags to set.
+ *
+ * Sets a state flag on a collected pad.
+ */
+#define GST_COLLECT_PADS_STATE_SET(data,flag) (GST_COLLECT_PADS_STATE (data) |= flag)
+/**
+ * GST_COLLECT_PADS_STATE_UNSET:
+ * @data: a #GstCollectData.
+ * @flag: the #GstCollectPadsStateFlags to clear.
+ *
+ * Clears a state flag on a collected pad.
+ */
+#define GST_COLLECT_PADS_STATE_UNSET(data,flag) (GST_COLLECT_PADS_STATE (data) &= ~(flag))
+
+/**
+ * GST_COLLECT_PADS_DTS:
+ * @data: A #GstCollectData.
+ *
+ * Returns the DTS that has been converted to running time when using
+ * gst_collect_pads_clip_running_time(). Unlike the value saved into
+ * the buffer, this value is of type gint64 and may be negative. This allow
+ * properly handling streams with frame reordering where the first DTS may
+ * be negative. If the initial DTS was not set, this value will be
+ * set to %G_MININT64.
+ *
+ * Since: 1.6
+ */
+#define GST_COLLECT_PADS_DTS(data) (((GstCollectData *) data)->ABI.abi.dts)
+
+/**
+ * GST_COLLECT_PADS_DTS_IS_VALID:
+ * @data: A #GstCollectData.
+ *
+ * Check if running DTS value store is valid.
+ *
+ * Since: 1.6
+ */
+#define GST_COLLECT_PADS_DTS_IS_VALID(data) (GST_CLOCK_STIME_IS_VALID (GST_COLLECT_PADS_DTS (data)))
+
+/**
+ * GstCollectData:
+ * @collect: owner #GstCollectPads
+ * @pad: #GstPad managed by this data
+ * @buffer: currently queued buffer.
+ * @pos: position in the buffer
+ * @segment: last segment received.
+ * @dts: the signed version of the DTS converted to running time. To access
+ * this member, use %GST_COLLECT_PADS_DTS macro. (Since: 1.6)
+ *
+ * Structure used by the collect_pads.
+ */
+struct _GstCollectData
+{
+ /* with STREAM_LOCK of @collect */
+ GstCollectPads *collect;
+ GstPad *pad;
+ GstBuffer *buffer;
+ guint pos;
+ GstSegment segment;
+
+ /*< private >*/
+ /* state: bitfield for easier extension;
+ * eos, flushing, new_segment, waiting */
+ GstCollectPadsStateFlags state;
+
+ GstCollectDataPrivate *priv;
+
+ union {
+ struct {
+ /*< public >*/
+ gint64 dts;
+ /*< private >*/
+ } abi;
+ gpointer _gst_reserved[GST_PADDING];
+ } ABI;
+};
+
+/**
+ * GstCollectPadsFunction:
+ * @pads: the #GstCollectPads that triggered the callback
+ * @user_data: user data passed to gst_collect_pads_set_function()
+ *
+ * A function that will be called when all pads have received data.
+ *
+ * Returns: %GST_FLOW_OK for success
+ */
+typedef GstFlowReturn (*GstCollectPadsFunction) (GstCollectPads *pads, gpointer user_data);
+
+/**
+ * GstCollectPadsBufferFunction:
+ * @pads: the #GstCollectPads that triggered the callback
+ * @data: the #GstCollectData of pad that has received the buffer
+ * @buffer: (transfer full): the #GstBuffer
+ * @user_data: user data passed to gst_collect_pads_set_buffer_function()
+ *
+ * A function that will be called when a (considered oldest) buffer can be muxed.
+ * If all pads have reached EOS, this function is called with %NULL @buffer
+ * and %NULL @data.
+ *
+ * Returns: %GST_FLOW_OK for success
+ */
+typedef GstFlowReturn (*GstCollectPadsBufferFunction) (GstCollectPads *pads, GstCollectData *data,
+ GstBuffer *buffer, gpointer user_data);
+
+/**
+ * GstCollectPadsCompareFunction:
+ * @pads: the #GstCollectPads that is comparing the timestamps
+ * @data1: the first #GstCollectData
+ * @timestamp1: the first timestamp
+ * @data2: the second #GstCollectData
+ * @timestamp2: the second timestamp
+ * @user_data: user data passed to gst_collect_pads_set_compare_function()
+ *
+ * A function for comparing two timestamps of buffers or newsegments collected on one pad.
+ *
+ * Returns: Integer less than zero when first timestamp is deemed older than the second one.
+ * Zero if the timestamps are deemed equally old.
+ * Integer greater than zero when second timestamp is deemed older than the first one.
+ */
+typedef gint (*GstCollectPadsCompareFunction) (GstCollectPads *pads,
+ GstCollectData * data1, GstClockTime timestamp1,
+ GstCollectData * data2, GstClockTime timestamp2,
+ gpointer user_data);
+
+/**
+ * GstCollectPadsEventFunction:
+ * @pads: the #GstCollectPads that triggered the callback
+ * @pad: the #GstPad that received an event
+ * @event: the #GstEvent received
+ * @user_data: user data passed to gst_collect_pads_set_event_function()
+ *
+ * A function that will be called while processing an event. It takes
+ * ownership of the event and is responsible for chaining up (to
+ * gst_collect_pads_event_default()) or dropping events (such typical cases
+ * being handled by the default handler).
+ *
+ * Returns: %TRUE if the pad could handle the event
+ */
+typedef gboolean (*GstCollectPadsEventFunction) (GstCollectPads *pads, GstCollectData * pad,
+ GstEvent * event, gpointer user_data);
+
+
+/**
+ * GstCollectPadsQueryFunction:
+ * @pads: the #GstCollectPads that triggered the callback
+ * @pad: the #GstPad that received an event
+ * @query: the #GstEvent received
+ * @user_data: user data passed to gst_collect_pads_set_query_function()
+ *
+ * A function that will be called while processing a query. It takes
+ * ownership of the query and is responsible for chaining up (to
+ * events downstream (with gst_pad_event_default()).
+ *
+ * Returns: %TRUE if the pad could handle the event
+ */
+typedef gboolean (*GstCollectPadsQueryFunction) (GstCollectPads *pads, GstCollectData * pad,
+ GstQuery * query, gpointer user_data);
+
+/**
+ * GstCollectPadsClipFunction:
+ * @pads: a #GstCollectPads
+ * @data: a #GstCollectData
+ * @inbuffer: (transfer full): the input #GstBuffer
+ * @outbuffer: (out): the output #GstBuffer
+ * @user_data: user data
+ *
+ * A function that will be called when @inbuffer is received on the pad managed
+ * by @data in the collectpad object @pads.
+ *
+ * The function should use the segment of @data and the negotiated media type on
+ * the pad to perform clipping of @inbuffer.
+ *
+ * This function takes ownership of @inbuffer and should output a buffer in
+ * @outbuffer or return %NULL in @outbuffer if the buffer should be dropped.
+ *
+ * Returns: a #GstFlowReturn that corresponds to the result of clipping.
+ */
+typedef GstFlowReturn (*GstCollectPadsClipFunction) (GstCollectPads *pads, GstCollectData *data,
+ GstBuffer *inbuffer, GstBuffer **outbuffer,
+ gpointer user_data);
+
+
+/**
+ * GstCollectPadsFlushFunction:
+ * @pads: a #GstCollectPads
+ * @user_data: user data
+ *
+ * A function that will be called while processing a flushing seek event.
+ *
+ * The function should flush any internal state of the element and the state of
+ * all the pads. It should clear only the state not directly managed by the
+ * @pads object. It is therefore not necessary to call
+ * gst_collect_pads_set_flushing nor gst_collect_pads_clear from this function.
+ *
+ * Since: 1.4
+ */
+typedef void (*GstCollectPadsFlushFunction) (GstCollectPads *pads, gpointer user_data);
+
+/**
+ * GST_COLLECT_PADS_GET_STREAM_LOCK:
+ * @pads: a #GstCollectPads
+ *
+ * Get the stream lock of @pads. The stream lock is used to coordinate and
+ * serialize execution among the various streams being collected, and in
+ * protecting the resources used to accomplish this.
+ */
+#define GST_COLLECT_PADS_GET_STREAM_LOCK(pads) (&((GstCollectPads *)pads)->stream_lock)
+/**
+ * GST_COLLECT_PADS_STREAM_LOCK:
+ * @pads: a #GstCollectPads
+ *
+ * Lock the stream lock of @pads.
+ */
+#define GST_COLLECT_PADS_STREAM_LOCK(pads) g_rec_mutex_lock(GST_COLLECT_PADS_GET_STREAM_LOCK (pads))
+/**
+ * GST_COLLECT_PADS_STREAM_UNLOCK:
+ * @pads: a #GstCollectPads
+ *
+ * Unlock the stream lock of @pads.
+ */
+#define GST_COLLECT_PADS_STREAM_UNLOCK(pads) g_rec_mutex_unlock(GST_COLLECT_PADS_GET_STREAM_LOCK (pads))
+
+/**
+ * GstCollectPads:
+ * @data: (element-type GstBase.CollectData): #GList of #GstCollectData managed
+ * by this #GstCollectPads.
+ *
+ * Collectpads object.
+ */
+struct _GstCollectPads {
+ GstObject object;
+
+ /*< public >*/ /* with LOCK and/or STREAM_LOCK */
+ GSList *data; /* list of CollectData items */
+
+ /*< private >*/
+ GRecMutex stream_lock; /* used to serialize collection among several streams */
+
+ GstCollectPadsPrivate *priv;
+
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+struct _GstCollectPadsClass {
+ GstObjectClass parent_class;
+
+ /*< private >*/
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+GST_BASE_API
+GType gst_collect_pads_get_type (void);
+
+/* creating the object */
+
+GST_BASE_API
+GstCollectPads* gst_collect_pads_new (void);
+
+/* set the callbacks */
+
+GST_BASE_API
+void gst_collect_pads_set_function (GstCollectPads *pads,
+ GstCollectPadsFunction func,
+ gpointer user_data);
+GST_BASE_API
+void gst_collect_pads_set_buffer_function (GstCollectPads *pads,
+ GstCollectPadsBufferFunction func,
+ gpointer user_data);
+GST_BASE_API
+void gst_collect_pads_set_event_function (GstCollectPads *pads,
+ GstCollectPadsEventFunction func,
+ gpointer user_data);
+GST_BASE_API
+void gst_collect_pads_set_query_function (GstCollectPads *pads,
+ GstCollectPadsQueryFunction func,
+ gpointer user_data);
+GST_BASE_API
+void gst_collect_pads_set_compare_function (GstCollectPads *pads,
+ GstCollectPadsCompareFunction func,
+ gpointer user_data);
+GST_BASE_API
+void gst_collect_pads_set_clip_function (GstCollectPads *pads,
+ GstCollectPadsClipFunction clipfunc,
+ gpointer user_data);
+GST_BASE_API
+void gst_collect_pads_set_flush_function (GstCollectPads *pads,
+ GstCollectPadsFlushFunction func,
+ gpointer user_data);
+
+/* pad management */
+
+GST_BASE_API
+GstCollectData* gst_collect_pads_add_pad (GstCollectPads *pads, GstPad *pad, guint size,
+ GstCollectDataDestroyNotify destroy_notify,
+ gboolean lock);
+GST_BASE_API
+gboolean gst_collect_pads_remove_pad (GstCollectPads *pads, GstPad *pad);
+
+/* start/stop collection */
+
+GST_BASE_API
+void gst_collect_pads_start (GstCollectPads *pads);
+
+GST_BASE_API
+void gst_collect_pads_stop (GstCollectPads *pads);
+
+GST_BASE_API
+void gst_collect_pads_set_flushing (GstCollectPads *pads, gboolean flushing);
+
+/* get collected buffers */
+
+GST_BASE_API
+GstBuffer* gst_collect_pads_peek (GstCollectPads *pads, GstCollectData *data);
+
+GST_BASE_API
+GstBuffer* gst_collect_pads_pop (GstCollectPads *pads, GstCollectData *data);
+
+/* get collected bytes */
+
+GST_BASE_API
+guint gst_collect_pads_available (GstCollectPads *pads);
+
+GST_BASE_API
+guint gst_collect_pads_flush (GstCollectPads *pads, GstCollectData *data,
+ guint size);
+GST_BASE_API
+GstBuffer* gst_collect_pads_read_buffer (GstCollectPads * pads, GstCollectData * data,
+ guint size);
+GST_BASE_API
+GstBuffer* gst_collect_pads_take_buffer (GstCollectPads * pads, GstCollectData * data,
+ guint size);
+
+/* setting and unsetting waiting mode */
+
+GST_BASE_API
+void gst_collect_pads_set_waiting (GstCollectPads *pads, GstCollectData *data,
+ gboolean waiting);
+
+/* convenience helper */
+
+GST_BASE_API
+GstFlowReturn gst_collect_pads_clip_running_time (GstCollectPads * pads,
+ GstCollectData * cdata,
+ GstBuffer * buf, GstBuffer ** outbuf,
+ gpointer user_data);
+
+/* default handlers */
+
+GST_BASE_API
+gboolean gst_collect_pads_event_default (GstCollectPads * pads, GstCollectData * data,
+ GstEvent * event, gboolean discard);
+GST_BASE_API
+gboolean gst_collect_pads_src_event_default (GstCollectPads * pads, GstPad * pad,
+ GstEvent * event);
+GST_BASE_API
+gboolean gst_collect_pads_query_default (GstCollectPads * pads, GstCollectData * data,
+ GstQuery * query, gboolean discard);
+
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstCollectPads, gst_object_unref)
+
+G_END_DECLS
+
+#endif /* __GST_COLLECT_PADS_H__ */
diff --git a/include/gst/base/gstdataqueue.h b/include/gst/base/gstdataqueue.h
new file mode 100644
index 0000000000..e814a2b693
--- /dev/null
+++ b/include/gst/base/gstdataqueue.h
@@ -0,0 +1,184 @@
+/* GStreamer
+ * Copyright (C) 2006 Edward Hervey <edward@fluendo.com>
+ *
+ * gstdataqueue.h:
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef __GST_DATA_QUEUE_H__
+#define __GST_DATA_QUEUE_H__
+
+#include <gst/gst.h>
+#include <gst/base/base-prelude.h>
+
+G_BEGIN_DECLS
+#define GST_TYPE_DATA_QUEUE \
+ (gst_data_queue_get_type())
+#define GST_DATA_QUEUE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DATA_QUEUE,GstDataQueue))
+#define GST_DATA_QUEUE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DATA_QUEUE,GstDataQueueClass))
+#define GST_IS_DATA_QUEUE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DATA_QUEUE))
+#define GST_IS_DATA_QUEUE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DATA_QUEUE))
+
+typedef struct _GstDataQueue GstDataQueue;
+typedef struct _GstDataQueueClass GstDataQueueClass;
+typedef struct _GstDataQueueSize GstDataQueueSize;
+typedef struct _GstDataQueueItem GstDataQueueItem;
+typedef struct _GstDataQueuePrivate GstDataQueuePrivate;
+
+/**
+ * GstDataQueueItem: (skip)
+ * @object: the #GstMiniObject to queue.
+ * @size: the size in bytes of the miniobject.
+ * @duration: the duration in #GstClockTime of the miniobject. Can not be
+ * %GST_CLOCK_TIME_NONE.
+ * @visible: %TRUE if @object should be considered as a visible object.
+ * @destroy: The #GDestroyNotify function to use to free the #GstDataQueueItem.
+ * This function should also drop the reference to @object the owner of the
+ * #GstDataQueueItem is assumed to hold.
+ *
+ * Structure used by #GstDataQueue. You can supply a different structure, as
+ * long as the top of the structure is identical to this structure.
+ */
+
+struct _GstDataQueueItem
+{
+ GstMiniObject *object;
+ guint size;
+ guint64 duration;
+ gboolean visible;
+
+ /* user supplied destroy function */
+ GDestroyNotify destroy;
+
+ /* < private > */
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+/**
+ * GstDataQueueSize: (skip)
+ * @visible: number of buffers
+ * @bytes: number of bytes
+ * @time: amount of time
+ *
+ * Structure describing the size of a queue.
+ */
+struct _GstDataQueueSize
+{
+ guint visible;
+ guint bytes;
+ guint64 time;
+};
+
+/**
+ * GstDataQueueCheckFullFunction: (skip)
+ * @queue: a #GstDataQueue.
+ * @visible: The number of visible items currently in the queue.
+ * @bytes: The amount of bytes currently in the queue.
+ * @time: The accumulated duration of the items currently in the queue.
+ * @checkdata: The #gpointer registered when the #GstDataQueue was created.
+ *
+ * The prototype of the function used to inform the queue that it should be
+ * considered as full.
+ *
+ * Returns: %TRUE if the queue should be considered full.
+ */
+typedef gboolean (*GstDataQueueCheckFullFunction) (GstDataQueue * queue,
+ guint visible, guint bytes, guint64 time, gpointer checkdata);
+
+typedef void (*GstDataQueueFullCallback) (GstDataQueue * queue, gpointer checkdata);
+typedef void (*GstDataQueueEmptyCallback) (GstDataQueue * queue, gpointer checkdata);
+
+/**
+ * GstDataQueue:
+ * @object: the parent structure
+ *
+ * Opaque #GstDataQueue structure.
+ */
+struct _GstDataQueue
+{
+ GObject object;
+
+ /*< private >*/
+ GstDataQueuePrivate *priv;
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+/**
+ * GstDataQueueClass:
+ */
+struct _GstDataQueueClass
+{
+ GObjectClass parent_class;
+
+ /* signals */
+ void (*empty) (GstDataQueue * queue);
+ void (*full) (GstDataQueue * queue);
+
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+GST_BASE_API
+GType gst_data_queue_get_type (void);
+
+GST_BASE_API
+GstDataQueue * gst_data_queue_new (GstDataQueueCheckFullFunction checkfull,
+ GstDataQueueFullCallback fullcallback,
+ GstDataQueueEmptyCallback emptycallback,
+ gpointer checkdata) G_GNUC_MALLOC;
+GST_BASE_API
+gboolean gst_data_queue_push (GstDataQueue * queue, GstDataQueueItem * item);
+
+GST_BASE_API
+gboolean gst_data_queue_push_force (GstDataQueue * queue, GstDataQueueItem * item);
+
+GST_BASE_API
+gboolean gst_data_queue_pop (GstDataQueue * queue, GstDataQueueItem ** item);
+
+GST_BASE_API
+gboolean gst_data_queue_peek (GstDataQueue * queue, GstDataQueueItem ** item);
+
+GST_BASE_API
+void gst_data_queue_flush (GstDataQueue * queue);
+
+GST_BASE_API
+void gst_data_queue_set_flushing (GstDataQueue * queue, gboolean flushing);
+
+GST_BASE_API
+gboolean gst_data_queue_drop_head (GstDataQueue * queue, GType type);
+
+GST_BASE_API
+gboolean gst_data_queue_is_full (GstDataQueue * queue);
+
+GST_BASE_API
+gboolean gst_data_queue_is_empty (GstDataQueue * queue);
+
+GST_BASE_API
+void gst_data_queue_get_level (GstDataQueue * queue, GstDataQueueSize *level);
+
+GST_BASE_API
+void gst_data_queue_limits_changed (GstDataQueue * queue);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstDataQueue, gst_object_unref)
+
+G_END_DECLS
+
+#endif /* __GST_DATA_QUEUE_H__ */
diff --git a/include/gst/base/gstflowcombiner.h b/include/gst/base/gstflowcombiner.h
new file mode 100644
index 0000000000..fa905a93fc
--- /dev/null
+++ b/include/gst/base/gstflowcombiner.h
@@ -0,0 +1,82 @@
+/* GStreamer
+ *
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
+ * Author: Thiago Santos <ts.santos@sisa.samsung.com>
+ *
+ * gstflowcombiner.h: utility to combine multiple flow returns into a single one
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef __GST_FLOW_COMBINER_H__
+#define __GST_FLOW_COMBINER_H__
+
+#include <glib.h>
+#include <gst/gst.h>
+#include <gst/base/base-prelude.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_FLOW_COMBINER gst_flow_combiner_get_type()
+
+/**
+ * GstFlowCombiner:
+ *
+ * Opaque helper structure to aggregate flow returns.
+ *
+ * Since: 1.4
+ */
+typedef struct _GstFlowCombiner GstFlowCombiner;
+
+GST_BASE_API
+GstFlowCombiner * gst_flow_combiner_new (void);
+
+GST_BASE_API
+GstFlowCombiner * gst_flow_combiner_ref (GstFlowCombiner * combiner);
+
+GST_BASE_API
+void gst_flow_combiner_unref (GstFlowCombiner * combiner);
+
+GST_BASE_API
+void gst_flow_combiner_free (GstFlowCombiner * combiner);
+
+GST_BASE_API
+GstFlowReturn gst_flow_combiner_update_flow (GstFlowCombiner * combiner, GstFlowReturn fret);
+
+GST_BASE_API
+GstFlowReturn gst_flow_combiner_update_pad_flow (GstFlowCombiner * combiner, GstPad * pad,
+ GstFlowReturn fret);
+GST_BASE_API
+void gst_flow_combiner_add_pad (GstFlowCombiner * combiner, GstPad * pad);
+
+GST_BASE_API
+void gst_flow_combiner_remove_pad (GstFlowCombiner * combiner, GstPad * pad);
+
+GST_BASE_API
+void gst_flow_combiner_clear (GstFlowCombiner * combiner);
+
+GST_BASE_API
+void gst_flow_combiner_reset (GstFlowCombiner * combiner);
+
+GST_BASE_API
+GType gst_flow_combiner_get_type (void);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstFlowCombiner, gst_flow_combiner_free)
+
+G_END_DECLS
+
+#endif /* __GST_FLOW_COMBINER_H__ */
diff --git a/include/gst/base/gstpushsrc.h b/include/gst/base/gstpushsrc.h
new file mode 100644
index 0000000000..d0d8cef9b7
--- /dev/null
+++ b/include/gst/base/gstpushsrc.h
@@ -0,0 +1,102 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ * 2000 Wim Taymans <wtay@chello.be>
+ * 2005 Wim Taymans <wim@fluendo.com>
+ *
+ * gstpushsrc.h:
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_PUSH_SRC_H__
+#define __GST_PUSH_SRC_H__
+
+#include <gst/gst.h>
+#include <gst/base/gstbasesrc.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_PUSH_SRC (gst_push_src_get_type())
+#define GST_PUSH_SRC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PUSH_SRC,GstPushSrc))
+#define GST_PUSH_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PUSH_SRC,GstPushSrcClass))
+#define GST_PUSH_SRC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_PUSH_SRC, GstPushSrcClass))
+#define GST_IS_PUSH_SRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PUSH_SRC))
+#define GST_IS_PUSH_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PUSH_SRC))
+
+typedef struct _GstPushSrc GstPushSrc;
+typedef struct _GstPushSrcClass GstPushSrcClass;
+
+/**
+ * GstPushSrc:
+ *
+ * The opaque #GstPushSrc data structure.
+ */
+struct _GstPushSrc {
+ GstBaseSrc parent;
+
+ /*< private >*/
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+/**
+ * GstPushSrcClass:
+ * @parent_class: Element parent class
+ * @create: Ask the subclass to create a buffer. The subclass decides which
+ * size this buffer should be. Other then that, refer to
+ * #GstBaseSrc<!-- -->.create() for more details. If this method is
+ * not implemented, @alloc followed by @fill will be called.
+ * @alloc: Ask the subclass to allocate a buffer. The subclass decides which
+ * size this buffer should be. The default implementation will create
+ * a new buffer from the negotiated allocator.
+ * @fill: Ask the subclass to fill the buffer with data.
+ *
+ * Subclasses can override any of the available virtual methods or not, as
+ * needed. At the minimum, the @fill method should be overridden to produce
+ * buffers.
+ */
+struct _GstPushSrcClass {
+ GstBaseSrcClass parent_class;
+
+ /**
+ * GstPushSrcClass::create:
+ * @buf: (inout):
+ *
+ * Ask the subclass to create a buffer, the default implementation will call alloc if
+ * no allocated @buf is provided and then call fill.
+ */
+ GstFlowReturn (*create) (GstPushSrc *src, GstBuffer **buf);
+ /**
+ * GstPushSrcClass::alloc:
+ * @buf: (out):
+ *
+ * Allocate memory for a buffer.
+ */
+ GstFlowReturn (*alloc) (GstPushSrc *src, GstBuffer **buf);
+ /* ask the subclass to fill a buffer */
+ GstFlowReturn (*fill) (GstPushSrc *src, GstBuffer *buf);
+
+ /*< private >*/
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+GST_BASE_API
+GType gst_push_src_get_type (void);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstPushSrc, gst_object_unref)
+
+G_END_DECLS
+
+#endif /* __GST_PUSH_SRC_H__ */
diff --git a/include/gst/base/gstqueuearray.h b/include/gst/base/gstqueuearray.h
new file mode 100644
index 0000000000..77edec0990
--- /dev/null
+++ b/include/gst/base/gstqueuearray.h
@@ -0,0 +1,109 @@
+/* GStreamer
+ * Copyright (C) 2009-2010 Edward Hervey <bilboed@bilboed.com>
+ *
+ * gstqueuearray.h:
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <glib.h>
+
+#ifndef __GST_QUEUE_ARRAY_H__
+#define __GST_QUEUE_ARRAY_H__
+
+#include <gst/base/base-prelude.h>
+
+G_BEGIN_DECLS
+
+/**
+ * GstQueueArray: (skip)
+ */
+typedef struct _GstQueueArray GstQueueArray;
+
+GST_BASE_API
+GstQueueArray * gst_queue_array_new (guint initial_size);
+
+GST_BASE_API
+void gst_queue_array_free (GstQueueArray * array);
+
+GST_BASE_API
+void gst_queue_array_set_clear_func (GstQueueArray *array,
+ GDestroyNotify clear_func);
+
+GST_BASE_API
+void gst_queue_array_clear (GstQueueArray * array);
+
+GST_BASE_API
+gpointer gst_queue_array_pop_head (GstQueueArray * array);
+
+GST_BASE_API
+gpointer gst_queue_array_peek_head (GstQueueArray * array);
+
+GST_BASE_API
+gpointer gst_queue_array_peek_nth (GstQueueArray * array, guint idx);
+
+GST_BASE_API
+gpointer gst_queue_array_pop_tail (GstQueueArray * array);
+
+GST_BASE_API
+gpointer gst_queue_array_peek_tail (GstQueueArray * array);
+
+GST_BASE_API
+void gst_queue_array_push_tail (GstQueueArray * array,
+ gpointer data);
+GST_BASE_API
+gboolean gst_queue_array_is_empty (GstQueueArray * array);
+
+GST_BASE_API
+gpointer gst_queue_array_drop_element (GstQueueArray * array,
+ guint idx);
+GST_BASE_API
+guint gst_queue_array_find (GstQueueArray * array,
+ GCompareFunc func,
+ gpointer data);
+GST_BASE_API
+guint gst_queue_array_get_length (GstQueueArray * array);
+
+/* Functions for use with structures */
+
+GST_BASE_API
+GstQueueArray * gst_queue_array_new_for_struct (gsize struct_size,
+ guint initial_size);
+GST_BASE_API
+void gst_queue_array_push_tail_struct (GstQueueArray * array,
+ gpointer p_struct);
+GST_BASE_API
+gpointer gst_queue_array_pop_head_struct (GstQueueArray * array);
+
+GST_BASE_API
+gpointer gst_queue_array_peek_head_struct (GstQueueArray * array);
+
+GST_BASE_API
+gpointer gst_queue_array_peek_nth_struct (GstQueueArray * array, guint idx);
+
+GST_BASE_API
+gboolean gst_queue_array_drop_struct (GstQueueArray * array,
+ guint idx,
+ gpointer p_struct);
+GST_BASE_API
+gpointer gst_queue_array_pop_tail_struct (GstQueueArray * array);
+
+GST_BASE_API
+gpointer gst_queue_array_peek_tail_struct (GstQueueArray * array);
+
+G_END_DECLS
+
+#endif
diff --git a/include/gst/base/gsttypefindhelper.h b/include/gst/base/gsttypefindhelper.h
new file mode 100644
index 0000000000..bda346cac1
--- /dev/null
+++ b/include/gst/base/gsttypefindhelper.h
@@ -0,0 +1,105 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ * Copyright (C) 2000,2005 Wim Taymans <wim@fluendo.com>
+ * Copyright (C) 2006 Tim-Philipp Müller <tim centricular net>
+ *
+ * gsttypefindhelper.h:
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_TYPEFINDHELPER_H__
+#define __GST_TYPEFINDHELPER_H__
+
+#include <gst/gst.h>
+#include <gst/base/base-prelude.h>
+
+G_BEGIN_DECLS
+
+GST_BASE_API
+GstCaps * gst_type_find_helper (GstPad *src, guint64 size);
+
+GST_BASE_API
+GstCaps * gst_type_find_helper_for_data (GstObject *obj,
+ const guint8 *data,
+ gsize size,
+ GstTypeFindProbability *prob);
+
+GST_BASE_API
+GstCaps * gst_type_find_helper_for_data_with_extension (GstObject *obj,
+ const guint8 *data,
+ gsize size,
+ const gchar *extension,
+ GstTypeFindProbability *prob);
+
+GST_BASE_API
+GstCaps * gst_type_find_helper_for_buffer (GstObject *obj,
+ GstBuffer *buf,
+ GstTypeFindProbability *prob);
+
+GST_BASE_API
+GstCaps * gst_type_find_helper_for_buffer_with_extension (GstObject *obj,
+ GstBuffer *buf,
+ const gchar *extension,
+ GstTypeFindProbability *prob);
+
+GST_BASE_API
+GstCaps * gst_type_find_helper_for_extension (GstObject * obj,
+ const gchar * extension);
+
+/**
+ * GstTypeFindHelperGetRangeFunction:
+ * @obj: a #GstObject that will handle the getrange request
+ * @parent: (allow-none): the parent of @obj or %NULL
+ * @offset: the offset of the range
+ * @length: the length of the range
+ * @buffer: (out): a memory location to hold the result buffer
+ *
+ * This function will be called by gst_type_find_helper_get_range() when
+ * typefinding functions request to peek at the data of a stream at certain
+ * offsets. If this function returns GST_FLOW_OK, the result buffer will be
+ * stored in @buffer. The contents of @buffer is invalid for any other
+ * return value.
+ *
+ * This function is supposed to behave exactly like a #GstPadGetRangeFunction.
+ *
+ * Returns: GST_FLOW_OK for success
+ */
+typedef GstFlowReturn (*GstTypeFindHelperGetRangeFunction) (GstObject *obj,
+ GstObject *parent,
+ guint64 offset,
+ guint length,
+ GstBuffer **buffer);
+GST_BASE_API
+GstCaps * gst_type_find_helper_get_range (GstObject *obj,
+ GstObject *parent,
+ GstTypeFindHelperGetRangeFunction func,
+ guint64 size,
+ const gchar *extension,
+ GstTypeFindProbability *prob);
+
+GST_BASE_API
+GstFlowReturn gst_type_find_helper_get_range_full (GstObject *obj,
+ GstObject *parent,
+ GstTypeFindHelperGetRangeFunction func,
+ guint64 size,
+ const gchar *extension,
+ GstCaps **caps,
+ GstTypeFindProbability *prob);
+
+G_END_DECLS
+
+#endif /* __GST_TYPEFINDHELPER_H__ */