diff options
Diffstat (limited to 'include/gst/base')
-rw-r--r-- | include/gst/base/base-prelude.h | 35 | ||||
-rw-r--r-- | include/gst/base/base.h | 44 | ||||
-rw-r--r-- | include/gst/base/gstadapter.h | 149 | ||||
-rw-r--r-- | include/gst/base/gstaggregator.h | 462 | ||||
-rw-r--r-- | include/gst/base/gstbaseparse.h | 385 | ||||
-rw-r--r-- | include/gst/base/gstbasesink.h | 345 | ||||
-rw-r--r-- | include/gst/base/gstbasesrc.h | 346 | ||||
-rw-r--r-- | include/gst/base/gstbasetransform.h | 372 | ||||
-rw-r--r-- | include/gst/base/gstbitreader.h | 328 | ||||
-rw-r--r-- | include/gst/base/gstbitwriter.h | 384 | ||||
-rw-r--r-- | include/gst/base/gstbytereader.h | 684 | ||||
-rw-r--r-- | include/gst/base/gstbytewriter.h | 468 | ||||
-rw-r--r-- | include/gst/base/gstcollectpads.h | 456 | ||||
-rw-r--r-- | include/gst/base/gstdataqueue.h | 184 | ||||
-rw-r--r-- | include/gst/base/gstflowcombiner.h | 82 | ||||
-rw-r--r-- | include/gst/base/gstpushsrc.h | 102 | ||||
-rw-r--r-- | include/gst/base/gstqueuearray.h | 109 | ||||
-rw-r--r-- | include/gst/base/gsttypefindhelper.h | 105 |
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__ */ |