summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/gst/base/Makefile.am11
-rw-r--r--libs/gst/base/gstadapter.c212
-rw-r--r--libs/gst/base/gstadapter.h41
-rw-r--r--libs/gst/base/gstbaseparse.c343
-rw-r--r--libs/gst/base/gstbasesink.c634
-rw-r--r--libs/gst/base/gstbasesink.h69
-rw-r--r--libs/gst/base/gstbasesrc.c598
-rw-r--r--libs/gst/base/gstbasesrc.h121
-rw-r--r--libs/gst/base/gstbasetransform.c1367
-rw-r--r--libs/gst/base/gstbasetransform.h54
-rw-r--r--libs/gst/base/gstbitreader.c44
-rw-r--r--libs/gst/base/gstbitreader.h15
-rw-r--r--libs/gst/base/gstbytereader.c44
-rw-r--r--libs/gst/base/gstbytereader.h16
-rw-r--r--libs/gst/base/gstbytewriter.c63
-rw-r--r--libs/gst/base/gstbytewriter.h2
-rw-r--r--libs/gst/base/gstcollectpads.c90
-rw-r--r--libs/gst/base/gstcollectpads.h2
-rw-r--r--libs/gst/base/gstdataqueue.c20
-rw-r--r--libs/gst/base/gstdataqueue.h10
-rw-r--r--libs/gst/base/gstpushsrc.c69
-rw-r--r--libs/gst/base/gstpushsrc.h3
-rw-r--r--libs/gst/base/gsttypefindhelper.c112
-rw-r--r--libs/gst/base/gsttypefindhelper.h4
-rw-r--r--libs/gst/check/Makefile.am12
-rw-r--r--libs/gst/check/gstbufferstraw.c8
-rw-r--r--libs/gst/check/gstcheck.c70
-rw-r--r--libs/gst/check/gstcheck.h1
-rw-r--r--libs/gst/check/gstconsistencychecker.c26
-rw-r--r--libs/gst/controller/Makefile.am11
-rw-r--r--libs/gst/controller/gstcontroller.c330
-rw-r--r--libs/gst/controller/gstcontroller.h18
-rw-r--r--libs/gst/dataprotocol/Makefile.am11
-rw-r--r--libs/gst/dataprotocol/dataprotocol.c184
-rw-r--r--libs/gst/dataprotocol/dataprotocol.h21
-rw-r--r--libs/gst/net/Makefile.am11
-rw-r--r--libs/gst/net/gstnetclientclock.c17
-rw-r--r--libs/gst/net/gstnettimeprovider.c14
38 files changed, 1813 insertions, 2865 deletions
diff --git a/libs/gst/base/Makefile.am b/libs/gst/base/Makefile.am
index f6fa3efa7f..9a5f50ead5 100644
--- a/libs/gst/base/Makefile.am
+++ b/libs/gst/base/Makefile.am
@@ -74,6 +74,7 @@ GstBase-@GST_MAJORMINOR@.gir: $(INTROSPECTION_SCANNER) libgstbase-@GST_MAJORMINO
$(INTROSPECTION_SCANNER) -v --namespace GstBase \
--nsversion=@GST_MAJORMINOR@ \
--strip-prefix=Gst \
+ -DGST_USE_UNSTABLE_API \
-I$(top_srcdir) \
-I$(top_srcdir)/libs \
-I$(top_builddir) \
@@ -81,12 +82,12 @@ GstBase-@GST_MAJORMINOR@.gir: $(INTROSPECTION_SCANNER) libgstbase-@GST_MAJORMINO
$(gir_cincludes) \
--add-include-path=$(top_builddir)/gst \
--library-path=$(top_builddir)/gst \
- --library=$(top_builddir)/gst/libgstreamer-0.10.la \
- --library=libgstbase-0.10.la \
- --include=Gst-0.10 \
+ --library=$(top_builddir)/gst/libgstreamer-0.11.la \
+ --library=libgstbase-0.11.la \
+ --include=Gst-0.11 \
--libtool="$(top_builddir)/libtool" \
- --pkg gstreamer-0.10 \
- --pkg-export gstreamer-base-0.10 \
+ --pkg gstreamer-@GST_MAJORMINOR@ \
+ --pkg-export gstreamer-base-@GST_MAJORMINOR@ \
--add-init-section="gst_init(NULL,NULL);" \
--output $@ \
$(gir_headers) \
diff --git a/libs/gst/base/gstadapter.c b/libs/gst/base/gstadapter.c
index 75944a902a..94fbabf9cd 100644
--- a/libs/gst/base/gstadapter.c
+++ b/libs/gst/base/gstadapter.c
@@ -33,11 +33,12 @@
*
* The theory of operation is like this: All buffers received are put
* into the adapter using gst_adapter_push() and the data is then read back
- * in chunks of the desired size using gst_adapter_peek(). After the data is
- * processed, it is freed using gst_adapter_flush().
+ * in chunks of the desired size using gst_adapter_map()/gst_adapter_unmap()
+ * and/or gst_adapter_copy(). After the data has been processed, it is freed
+ * using gst_adapter_unmap().
*
* Other methods such as gst_adapter_take() and gst_adapter_take_buffer()
- * combine gst_adapter_peek() and gst_adapter_flush() in one method and are
+ * combine gst_adapter_map() and gst_adapter_unmap() in one method and are
* potentially more convenient for some use cases.
*
* For example, a sink pad's chain function that needs to pass data to a library
@@ -58,9 +59,10 @@
* gst_adapter_push (adapter, buffer);
* // while we can read out 512 bytes, process them
* while (gst_adapter_available (adapter) >= 512 && ret == GST_FLOW_OK) {
+ * const guint8 *data = gst_adapter_map (adapter, 512);
* // use flowreturn as an error value
- * ret = my_library_foo (gst_adapter_peek (adapter, 512));
- * gst_adapter_flush (adapter, 512);
+ * ret = my_library_foo (data);
+ * gst_adapter_unmap (adapter, 512);
* }
*
* gst_object_unref (this);
@@ -116,6 +118,8 @@
/* default size for the assembled data buffer */
#define DEFAULT_SIZE 4096
+static void gst_adapter_flush_unchecked (GstAdapter * adapter, gsize flush);
+
GST_DEBUG_CATEGORY_STATIC (gst_adapter_debug);
#define GST_CAT_DEFAULT gst_adapter_debug
@@ -127,25 +131,22 @@ struct _GstAdapterPrivate
GstClockTime timestamp;
guint64 distance;
- guint scan_offset;
+ gsize scan_offset;
GSList *scan_entry;
+
+ gpointer cdata;
+ gsize csize;
};
-#define _do_init(thing) \
+#define _do_init \
GST_DEBUG_CATEGORY_INIT (gst_adapter_debug, "adapter", 0, "object to splice and merge buffers to desired size")
-GST_BOILERPLATE_FULL (GstAdapter, gst_adapter, GObject, G_TYPE_OBJECT,
- _do_init);
+#define gst_adapter_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstAdapter, gst_adapter, G_TYPE_OBJECT, _do_init);
static void gst_adapter_dispose (GObject * object);
static void gst_adapter_finalize (GObject * object);
static void
-gst_adapter_base_init (gpointer g_class)
-{
- /* nop */
-}
-
-static void
gst_adapter_class_init (GstAdapterClass * klass)
{
GObjectClass *object = G_OBJECT_CLASS (klass);
@@ -157,7 +158,7 @@ gst_adapter_class_init (GstAdapterClass * klass)
}
static void
-gst_adapter_init (GstAdapter * adapter, GstAdapterClass * g_class)
+gst_adapter_init (GstAdapter * adapter)
{
adapter->priv = GST_ADAPTER_GET_PRIVATE (adapter);
adapter->assembled_data = g_malloc (DEFAULT_SIZE);
@@ -239,12 +240,12 @@ update_timestamp (GstAdapter * adapter, GstBuffer * buf)
/* copy data into @dest, skipping @skip bytes from the head buffers */
static void
-copy_into_unchecked (GstAdapter * adapter, guint8 * dest, guint skip,
- guint size)
+copy_into_unchecked (GstAdapter * adapter, guint8 * dest, gsize skip,
+ gsize size)
{
GSList *g;
GstBuffer *buf;
- guint bsize, csize;
+ gsize bsize, csize;
/* first step, do skipping */
/* we might well be copying where we were scanning */
@@ -255,16 +256,17 @@ copy_into_unchecked (GstAdapter * adapter, guint8 * dest, guint skip,
g = adapter->buflist;
}
buf = g->data;
- bsize = GST_BUFFER_SIZE (buf);
+ bsize = gst_buffer_get_size (buf);
while (G_UNLIKELY (skip >= bsize)) {
skip -= bsize;
g = g_slist_next (g);
buf = g->data;
- bsize = GST_BUFFER_SIZE (buf);
+ bsize = gst_buffer_get_size (buf);
}
/* copy partial buffer */
csize = MIN (bsize - skip, size);
- memcpy (dest, GST_BUFFER_DATA (buf) + skip, csize);
+ GST_DEBUG ("%u %u %u", bsize, skip, csize);
+ gst_buffer_extract (buf, skip, dest, csize);
size -= csize;
dest += csize;
@@ -272,10 +274,10 @@ copy_into_unchecked (GstAdapter * adapter, guint8 * dest, guint skip,
while (size > 0) {
g = g_slist_next (g);
buf = g->data;
- bsize = GST_BUFFER_SIZE (buf);
+ bsize = gst_buffer_get_size (buf);
if (G_LIKELY (bsize > 0)) {
csize = MIN (bsize, size);
- memcpy (dest, GST_BUFFER_DATA (buf), csize);
+ gst_buffer_extract (buf, 0, dest, csize);
size -= csize;
dest += csize;
}
@@ -293,12 +295,12 @@ copy_into_unchecked (GstAdapter * adapter, guint8 * dest, guint skip,
void
gst_adapter_push (GstAdapter * adapter, GstBuffer * buf)
{
- guint size;
+ gsize size;
g_return_if_fail (GST_IS_ADAPTER (adapter));
g_return_if_fail (GST_IS_BUFFER (buf));
- size = GST_BUFFER_SIZE (buf);
+ size = gst_buffer_get_size (buf);
adapter->size += size;
/* Note: merging buffers at this point is premature. */
@@ -322,11 +324,12 @@ gst_adapter_push (GstAdapter * adapter, GstBuffer * buf)
* Returns TRUE if it managed to merge anything.
*/
static gboolean
-gst_adapter_try_to_merge_up (GstAdapter * adapter, guint size)
+gst_adapter_try_to_merge_up (GstAdapter * adapter, gsize size)
{
GstBuffer *cur, *head;
GSList *g;
gboolean ret = FALSE;
+ gsize hsize;
g = adapter->buflist;
if (g == NULL)
@@ -338,8 +341,9 @@ gst_adapter_try_to_merge_up (GstAdapter * adapter, guint size)
/* How large do we want our head buffer? The requested size, plus whatever's
* been skipped already */
size += adapter->skip;
+ hsize = gst_buffer_get_size (head);
- while (g != NULL && GST_BUFFER_SIZE (head) < size) {
+ while (g != NULL && hsize < size) {
cur = g->data;
if (!gst_buffer_is_span_fast (head, cur))
return ret;
@@ -347,9 +351,10 @@ gst_adapter_try_to_merge_up (GstAdapter * adapter, guint size)
/* Merge the head buffer and the next in line */
GST_LOG_OBJECT (adapter,
"Merging buffers of size %u & %u in search of target %u",
- GST_BUFFER_SIZE (head), GST_BUFFER_SIZE (cur), size);
+ hsize, gst_buffer_get_size (cur), size);
head = gst_buffer_join (head, cur);
+ hsize = gst_buffer_get_size (head);
ret = TRUE;
/* Delete the front list item, and store our new buffer in the 2nd list
@@ -368,9 +373,9 @@ gst_adapter_try_to_merge_up (GstAdapter * adapter, guint size)
}
/**
- * gst_adapter_peek:
+ * gst_adapter_map:
* @adapter: a #GstAdapter
- * @size: the number of bytes to peek
+ * @size: the number of bytes to map/peek
*
* Gets the first @size bytes stored in the @adapter. The returned pointer is
* valid until the next function is called on the adapter.
@@ -390,11 +395,11 @@ gst_adapter_try_to_merge_up (GstAdapter * adapter, guint size)
* @size bytes of data, or NULL
*/
const guint8 *
-gst_adapter_peek (GstAdapter * adapter, guint size)
+gst_adapter_map (GstAdapter * adapter, gsize size)
{
GstBuffer *cur;
- guint skip;
- guint toreuse, tocopy;
+ gsize skip, csize;
+ gsize toreuse, tocopy;
guint8 *data;
g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL);
@@ -410,20 +415,20 @@ gst_adapter_peek (GstAdapter * adapter, guint size)
if (adapter->assembled_len >= size)
return adapter->assembled_data;
- /* our head buffer has enough data left, return it */
- cur = adapter->buflist->data;
- skip = adapter->skip;
- if (GST_BUFFER_SIZE (cur) >= size + skip)
- return GST_BUFFER_DATA (cur) + skip;
-
- /* We may be able to efficiently merge buffers in our pool to
- * gather a big enough chunk to return it from the head buffer directly */
- if (gst_adapter_try_to_merge_up (adapter, size)) {
- /* Merged something! Check if there's enough avail now */
+ do {
cur = adapter->buflist->data;
- if (GST_BUFFER_SIZE (cur) >= size + skip)
- return GST_BUFFER_DATA (cur) + skip;
- }
+ skip = adapter->skip;
+
+ csize = gst_buffer_get_size (cur);
+ if (csize >= size + skip) {
+ data = gst_buffer_map (cur, &csize, NULL, GST_MAP_READ);
+ adapter->priv->cdata = data;
+ adapter->priv->csize = csize;
+ return data + skip;
+ }
+ /* We may be able to efficiently merge buffers in our pool to
+ * gather a big enough chunk to return it from the head buffer directly */
+ } while (gst_adapter_try_to_merge_up (adapter, size));
/* see how much data we can reuse from the assembled memory and how much
* we need to copy */
@@ -458,6 +463,29 @@ gst_adapter_peek (GstAdapter * adapter, guint size)
}
/**
+ * gst_adapter_unmap:
+ * @adapter: a #GstAdapter
+ * @flush: the amount of bytes to flush
+ *
+ * Releases the memory obtained with the last gst_adapter_map() and flushes
+ * @size bytes from the adapter.
+ */
+void
+gst_adapter_unmap (GstAdapter * adapter, gsize flush)
+{
+ g_return_if_fail (GST_IS_ADAPTER (adapter));
+
+ if (adapter->priv->cdata) {
+ GstBuffer *cur = adapter->buflist->data;
+ gst_buffer_unmap (cur, adapter->priv->cdata, adapter->priv->csize);
+ adapter->priv->cdata = NULL;
+ }
+
+ if (flush)
+ gst_adapter_flush_unchecked (adapter, flush);
+}
+
+/**
* gst_adapter_copy:
* @adapter: a #GstAdapter
* @dest: (out caller-allocates) (array length=size): the memory to copy into
@@ -474,7 +502,7 @@ gst_adapter_peek (GstAdapter * adapter, guint size)
* Since: 0.10.12
*/
void
-gst_adapter_copy (GstAdapter * adapter, guint8 * dest, guint offset, guint size)
+gst_adapter_copy (GstAdapter * adapter, guint8 * dest, gsize offset, gsize size)
{
g_return_if_fail (GST_IS_ADAPTER (adapter));
g_return_if_fail (size > 0);
@@ -491,13 +519,13 @@ gst_adapter_copy (GstAdapter * adapter, guint8 * dest, guint offset, guint size)
* Flushes the first @flush bytes in the @adapter. The caller must ensure that
* at least this many bytes are available.
*
- * See also: gst_adapter_peek().
+ * See also: gst_adapter_map(), gst_adapter_unmap()
*/
static void
-gst_adapter_flush_unchecked (GstAdapter * adapter, guint flush)
+gst_adapter_flush_unchecked (GstAdapter * adapter, gsize flush)
{
GstBuffer *cur;
- guint size;
+ gsize size;
GstAdapterPrivate *priv;
GSList *g;
@@ -516,7 +544,7 @@ gst_adapter_flush_unchecked (GstAdapter * adapter, guint flush)
g = adapter->buflist;
cur = g->data;
- size = GST_BUFFER_SIZE (cur);
+ size = gst_buffer_get_size (cur);
while (flush >= size) {
/* can skip whole buffer */
GST_LOG_OBJECT (adapter, "flushing out head buffer");
@@ -534,7 +562,7 @@ gst_adapter_flush_unchecked (GstAdapter * adapter, guint flush)
/* there is a new head buffer, update the timestamp */
cur = g->data;
update_timestamp (adapter, cur);
- size = GST_BUFFER_SIZE (cur);
+ size = gst_buffer_get_size (cur);
}
adapter->buflist = g;
/* account for the remaining bytes */
@@ -546,7 +574,7 @@ gst_adapter_flush_unchecked (GstAdapter * adapter, guint flush)
}
void
-gst_adapter_flush (GstAdapter * adapter, guint flush)
+gst_adapter_flush (GstAdapter * adapter, gsize flush)
{
g_return_if_fail (GST_IS_ADAPTER (adapter));
g_return_if_fail (flush <= adapter->size);
@@ -560,10 +588,10 @@ gst_adapter_flush (GstAdapter * adapter, guint flush)
/* internal function, nbytes should be flushed after calling this function */
static guint8 *
-gst_adapter_take_internal (GstAdapter * adapter, guint nbytes)
+gst_adapter_take_internal (GstAdapter * adapter, gsize nbytes)
{
guint8 *data;
- guint toreuse, tocopy;
+ gsize toreuse, tocopy;
/* see how much data we can reuse from the assembled memory and how much
* we need to copy */
@@ -592,7 +620,6 @@ gst_adapter_take_internal (GstAdapter * adapter, guint nbytes)
}
if (tocopy) {
/* copy the remaining data */
- GST_LOG_OBJECT (adapter, "copying %u bytes", tocopy);
copy_into_unchecked (adapter, toreuse + data, toreuse + adapter->skip,
tocopy);
}
@@ -615,7 +642,7 @@ gst_adapter_take_internal (GstAdapter * adapter, guint nbytes)
* #NULL if @nbytes bytes are not available
*/
guint8 *
-gst_adapter_take (GstAdapter * adapter, guint nbytes)
+gst_adapter_take (GstAdapter * adapter, gsize nbytes)
{
guint8 *data;
@@ -656,11 +683,11 @@ gst_adapter_take (GstAdapter * adapter, guint nbytes)
* Since: 0.10.6
*/
GstBuffer *
-gst_adapter_take_buffer (GstAdapter * adapter, guint nbytes)
+gst_adapter_take_buffer (GstAdapter * adapter, gsize nbytes)
{
GstBuffer *buffer;
GstBuffer *cur;
- guint hsize, skip;
+ gsize hsize, skip;
guint8 *data;
g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL);
@@ -676,7 +703,7 @@ gst_adapter_take_buffer (GstAdapter * adapter, guint nbytes)
cur = adapter->buflist->data;
skip = adapter->skip;
- hsize = GST_BUFFER_SIZE (cur);
+ hsize = gst_buffer_get_size (cur);
/* our head buffer has enough data left, return it */
if (skip == 0 && hsize == nbytes) {
@@ -685,19 +712,19 @@ gst_adapter_take_buffer (GstAdapter * adapter, guint nbytes)
buffer = gst_buffer_ref (cur);
goto done;
} else if (hsize >= nbytes + skip) {
- GST_LOG_OBJECT (adapter, "providing buffer of %d bytes via sub-buffer",
+ GST_LOG_OBJECT (adapter, "providing buffer of %d bytes via region copy",
nbytes);
- buffer = gst_buffer_create_sub (cur, skip, nbytes);
+ buffer = gst_buffer_copy_region (cur, GST_BUFFER_COPY_ALL, skip, nbytes);
goto done;
}
if (gst_adapter_try_to_merge_up (adapter, nbytes)) {
/* Merged something, let's try again for sub-buffering */
cur = adapter->buflist->data;
- if (GST_BUFFER_SIZE (cur) >= nbytes + skip) {
+ if (gst_buffer_get_size (cur) >= nbytes + skip) {
GST_LOG_OBJECT (adapter, "providing buffer of %d bytes via sub-buffer",
nbytes);
- buffer = gst_buffer_create_sub (cur, skip, nbytes);
+ buffer = gst_buffer_copy_region (cur, GST_BUFFER_COPY_ALL, skip, nbytes);
goto done;
}
}
@@ -705,9 +732,8 @@ gst_adapter_take_buffer (GstAdapter * adapter, guint nbytes)
data = gst_adapter_take_internal (adapter, nbytes);
buffer = gst_buffer_new ();
- GST_BUFFER_SIZE (buffer) = nbytes;
- GST_BUFFER_DATA (buffer) = data;
- GST_BUFFER_MALLOCDATA (buffer) = data;
+ gst_buffer_take_memory (buffer, -1,
+ gst_memory_new_wrapped (0, data, g_free, nbytes, 0, nbytes));
done:
gst_adapter_flush_unchecked (adapter, nbytes);
@@ -735,11 +761,11 @@ done:
* Since: 0.10.31
*/
GList *
-gst_adapter_take_list (GstAdapter * adapter, guint nbytes)
+gst_adapter_take_list (GstAdapter * adapter, gsize nbytes)
{
GList *result = NULL, *tail = NULL;
GstBuffer *cur;
- guint hsize, skip;
+ gsize hsize, skip;
g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL);
g_return_val_if_fail (nbytes <= adapter->size, NULL);
@@ -749,7 +775,7 @@ gst_adapter_take_list (GstAdapter * adapter, guint nbytes)
while (nbytes > 0) {
cur = adapter->buflist->data;
skip = adapter->skip;
- hsize = MIN (nbytes, GST_BUFFER_SIZE (cur) - skip);
+ hsize = MIN (nbytes, gst_buffer_get_size (cur) - skip);
cur = gst_adapter_take_buffer (adapter, hsize);
@@ -769,12 +795,12 @@ gst_adapter_take_list (GstAdapter * adapter, guint nbytes)
* @adapter: a #GstAdapter
*
* Gets the maximum amount of bytes available, that is it returns the maximum
- * value that can be supplied to gst_adapter_peek() without that function
+ * value that can be supplied to gst_adapter_map() without that function
* returning NULL.
*
* Returns: number of bytes available in @adapter
*/
-guint
+gsize
gst_adapter_available (GstAdapter * adapter)
{
g_return_val_if_fail (GST_IS_ADAPTER (adapter), 0);
@@ -793,11 +819,11 @@ gst_adapter_available (GstAdapter * adapter)
* Returns: number of bytes that are available in @adapter without expensive
* operations
*/
-guint
+gsize
gst_adapter_available_fast (GstAdapter * adapter)
{
GstBuffer *cur;
- guint size;
+ gsize size;
GSList *g;
g_return_val_if_fail (GST_IS_ADAPTER (adapter), 0);
@@ -814,7 +840,7 @@ gst_adapter_available_fast (GstAdapter * adapter)
g = adapter->buflist;
while (TRUE) {
cur = g->data;
- size = GST_BUFFER_SIZE (cur);
+ size = gst_buffer_get_size (cur);
if (size != 0)
break;
g = g_slist_next (g);
@@ -878,14 +904,14 @@ gst_adapter_prev_timestamp (GstAdapter * adapter, guint64 * distance)
*
* Since: 0.10.30
*/
-guint
+gsize
gst_adapter_masked_scan_uint32_peek (GstAdapter * adapter, guint32 mask,
- guint32 pattern, guint offset, guint size, guint32 * value)
+ guint32 pattern, gsize offset, gsize size, guint32 * value)
{
GSList *g;
- guint skip, bsize, i;
+ gsize skip, bsize, osize, i;
guint32 state;
- guint8 *bdata;
+ guint8 *bdata, *odata;
GstBuffer *buf;
g_return_val_if_fail (size > 0, -1);
@@ -909,18 +935,20 @@ gst_adapter_masked_scan_uint32_peek (GstAdapter * adapter, guint32 mask,
adapter->priv->scan_entry = NULL;
}
buf = g->data;
- bsize = GST_BUFFER_SIZE (buf);
+ bsize = gst_buffer_get_size (buf);
while (G_UNLIKELY (skip >= bsize)) {
skip -= bsize;
g = g_slist_next (g);
adapter->priv->scan_offset += bsize;
adapter->priv->scan_entry = g;
buf = g->data;
- bsize = GST_BUFFER_SIZE (buf);
+ bsize = gst_buffer_get_size (buf);
}
/* get the data now */
- bsize -= skip;
- bdata = GST_BUFFER_DATA (buf) + skip;
+ odata = gst_buffer_map (buf, &osize, NULL, GST_MAP_READ);
+
+ bdata = odata + skip;
+ bsize = osize - skip;
skip = 0;
/* set the state to something that does not match */
@@ -937,6 +965,7 @@ gst_adapter_masked_scan_uint32_peek (GstAdapter * adapter, guint32 mask,
if (G_LIKELY (skip + i >= 3)) {
if (G_LIKELY (value))
*value = state;
+ gst_buffer_unmap (buf, odata, osize);
return offset + skip + i - 3;
}
}
@@ -948,13 +977,18 @@ gst_adapter_masked_scan_uint32_peek (GstAdapter * adapter, guint32 mask,
/* nothing found yet, go to next buffer */
skip += bsize;
g = g_slist_next (g);
- adapter->priv->scan_offset += GST_BUFFER_SIZE (buf);
+ adapter->priv->scan_offset += osize;
adapter->priv->scan_entry = g;
+ gst_buffer_unmap (buf, odata, osize);
buf = g->data;
- bsize = GST_BUFFER_SIZE (buf);
- bdata = GST_BUFFER_DATA (buf);
+
+ odata = gst_buffer_map (buf, &osize, NULL, GST_MAP_READ);
+ bsize = osize;
+ bdata = odata;
} while (TRUE);
+ gst_buffer_unmap (buf, odata, osize);
+
/* nothing found */
return -1;
}
@@ -1005,9 +1039,9 @@ gst_adapter_masked_scan_uint32_peek (GstAdapter * adapter, guint32 mask,
*
* Since: 0.10.24
*/
-guint
+gsize
gst_adapter_masked_scan_uint32 (GstAdapter * adapter, guint32 mask,
- guint32 pattern, guint offset, guint size)
+ guint32 pattern, gsize offset, gsize size)
{
return gst_adapter_masked_scan_uint32_peek (adapter, mask, pattern, offset,
size, NULL);
diff --git a/libs/gst/base/gstadapter.h b/libs/gst/base/gstadapter.h
index ae8b7813b8..aa6730b6c2 100644
--- a/libs/gst/base/gstadapter.h
+++ b/libs/gst/base/gstadapter.h
@@ -52,22 +52,18 @@ struct _GstAdapter {
/*< private >*/
GSList * buflist;
- guint size;
- guint skip;
+ GSList * buflist_end;
+ gsize size;
+ gsize skip;
/* we keep state of assembled pieces */
guint8 * assembled_data;
- guint assembled_size;
- guint assembled_len;
-
- /* ABI added */
- /* Remember where the end of our buffer list is to
- * speed up the push */
- GSList *buflist_end;
+ gsize assembled_size;
+ gsize assembled_len;
GstAdapterPrivate *priv;
- gpointer _gst_reserved[GST_PADDING - 2];
+ gpointer _gst_reserved[GST_PADDING];
};
struct _GstAdapterClass {
@@ -83,23 +79,24 @@ GstAdapter * gst_adapter_new (void);
void gst_adapter_clear (GstAdapter *adapter);
void gst_adapter_push (GstAdapter *adapter, GstBuffer* buf);
-const guint8 * gst_adapter_peek (GstAdapter *adapter, guint size);
+const guint8 * gst_adapter_map (GstAdapter *adapter, gsize size);
+void gst_adapter_unmap (GstAdapter *adapter, gsize flush);
void gst_adapter_copy (GstAdapter *adapter, guint8 *dest,
- guint offset, guint size);
-void gst_adapter_flush (GstAdapter *adapter, guint flush);
-guint8* gst_adapter_take (GstAdapter *adapter, guint nbytes);
-GstBuffer* gst_adapter_take_buffer (GstAdapter *adapter, guint nbytes);
-GList* gst_adapter_take_list (GstAdapter *adapter, guint nbytes);
-guint gst_adapter_available (GstAdapter *adapter);
-guint gst_adapter_available_fast (GstAdapter *adapter);
+ gsize offset, gsize size);
+void gst_adapter_flush (GstAdapter *adapter, gsize flush);
+guint8* gst_adapter_take (GstAdapter *adapter, gsize nbytes);
+GstBuffer* gst_adapter_take_buffer (GstAdapter *adapter, gsize nbytes);
+GList* gst_adapter_take_list (GstAdapter *adapter, gsize nbytes);
+gsize gst_adapter_available (GstAdapter *adapter);
+gsize gst_adapter_available_fast (GstAdapter *adapter);
GstClockTime gst_adapter_prev_timestamp (GstAdapter *adapter, guint64 *distance);
-guint gst_adapter_masked_scan_uint32 (GstAdapter * adapter, guint32 mask,
- guint32 pattern, guint offset, guint size);
+gsize gst_adapter_masked_scan_uint32 (GstAdapter * adapter, guint32 mask,
+ guint32 pattern, gsize offset, gsize size);
-guint gst_adapter_masked_scan_uint32_peek (GstAdapter * adapter, guint32 mask,
- guint32 pattern, guint offset, guint size, guint32 * value);
+gsize gst_adapter_masked_scan_uint32_peek (GstAdapter * adapter, guint32 mask,
+ guint32 pattern, gsize offset, gsize size, guint32 * value);
G_END_DECLS
diff --git a/libs/gst/base/gstbaseparse.c b/libs/gst/base/gstbaseparse.c
index e0158ce119..6aa1db8084 100644
--- a/libs/gst/base/gstbaseparse.c
+++ b/libs/gst/base/gstbaseparse.c
@@ -377,7 +377,6 @@ static void gst_base_parse_handle_tag (GstBaseParse * parse, GstEvent * event);
static gboolean gst_base_parse_src_event (GstPad * pad, GstEvent * event);
static gboolean gst_base_parse_sink_event (GstPad * pad, GstEvent * event);
static gboolean gst_base_parse_query (GstPad * pad, GstQuery * query);
-static gboolean gst_base_parse_sink_setcaps (GstPad * pad, GstCaps * caps);
static const GstQueryType *gst_base_parse_get_querytypes (GstPad * pad);
static GstFlowReturn gst_base_parse_chain (GstPad * pad, GstBuffer * buffer);
@@ -509,8 +508,6 @@ gst_base_parse_init (GstBaseParse * parse, GstBaseParseClass * bclass)
parse->sinkpad = gst_pad_new_from_template (pad_template, "sink");
gst_pad_set_event_function (parse->sinkpad,
GST_DEBUG_FUNCPTR (gst_base_parse_sink_event));
- gst_pad_set_setcaps_function (parse->sinkpad,
- GST_DEBUG_FUNCPTR (gst_base_parse_sink_setcaps));
gst_pad_set_chain_function (parse->sinkpad,
GST_DEBUG_FUNCPTR (gst_base_parse_chain));
gst_pad_set_activate_function (parse->sinkpad,
@@ -754,7 +751,7 @@ static gboolean
gst_base_parse_check_frame (GstBaseParse * parse,
GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
{
- *framesize = GST_BUFFER_SIZE (frame->buffer);
+ *framesize = gst_buffer_get_size (frame->buffer);
*skipsize = 0;
return TRUE;
}
@@ -858,10 +855,10 @@ gst_base_parse_sink_event (GstPad * pad, GstEvent * event)
GST_DEBUG_OBJECT (parse, "handling event %d, %s", GST_EVENT_TYPE (event),
GST_EVENT_TYPE_NAME (event));
- /* Cache all events except EOS, NEWSEGMENT and FLUSH_STOP if we have a
+ /* Cache all events except EOS, SEGMENT and FLUSH_STOP if we have a
* pending segment */
if (parse->priv->pending_segment && GST_EVENT_TYPE (event) != GST_EVENT_EOS
- && GST_EVENT_TYPE (event) != GST_EVENT_NEWSEGMENT
+ && GST_EVENT_TYPE (event) != GST_EVENT_SEGMENT
&& GST_EVENT_TYPE (event) != GST_EVENT_FLUSH_START
&& GST_EVENT_TYPE (event) != GST_EVENT_FLUSH_STOP) {
@@ -913,36 +910,52 @@ gst_base_parse_sink_eventfunc (GstBaseParse * parse, GstEvent * event)
GstEvent **eventp;
switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_NEWSEGMENT:
+ case GST_EVENT_CAPS:
{
+ GstCaps *caps;
+ GstBaseParseClass *klass;
+
+ klass = GST_BASE_PARSE_GET_CLASS (parse);
+
+ gst_event_parse_caps (event, &caps);
+ GST_DEBUG_OBJECT (parse, "caps: %" GST_PTR_FORMAT, caps);
+
+ if (klass->set_sink_caps)
+ klass->set_sink_caps (parse, caps);
+
+ handled = TRUE;
+ break;
+ }
+ case GST_EVENT_SEGMENT:
+ {
+ const GstSegment *in_segment;
+ GstSegment out_segment;
+ gint64 offset = 0, next_ts;
+
+#if 0
gdouble rate, applied_rate;
GstFormat format;
- gint64 start, stop, pos, next_ts, offset = 0;
+ gint64 start, stop, pos, next_ts;
gboolean update;
+#endif
- gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
- &format, &start, &stop, &pos);
+ gst_event_parse_segment (event, &in_segment);
+ gst_segment_init (&out_segment, GST_FORMAT_TIME);
- GST_DEBUG_OBJECT (parse, "newseg rate %g, applied rate %g, "
- "format %d, start = %" GST_TIME_FORMAT ", stop = %" GST_TIME_FORMAT
- ", pos = %" GST_TIME_FORMAT, rate, applied_rate, format,
- GST_TIME_ARGS (start), GST_TIME_ARGS (stop), GST_TIME_ARGS (pos));
+ GST_DEBUG_OBJECT (parse, "segment %" GST_SEGMENT_FORMAT, in_segment);
- if (format == GST_FORMAT_BYTES) {
- GstClockTime seg_start, seg_stop;
+ if (in_segment->format == GST_FORMAT_BYTES) {
GstBaseParseSeek *seek = NULL;
GSList *node;
/* stop time is allowed to be open-ended, but not start & pos */
- seg_stop = GST_CLOCK_TIME_NONE;
- seg_start = 0;
- offset = pos;
+ offset = in_segment->time;
GST_OBJECT_LOCK (parse);
for (node = parse->priv->pending_seeks; node; node = node->next) {
GstBaseParseSeek *tmp = node->data;
- if (tmp->offset == pos) {
+ if (tmp->offset == offset) {
seek = tmp;
break;
}
@@ -955,8 +968,11 @@ gst_base_parse_sink_eventfunc (GstBaseParse * parse, GstEvent * event)
GST_DEBUG_OBJECT (parse,
"Matched newsegment to%s seek: %" GST_SEGMENT_FORMAT,
seek->accurate ? " accurate" : "", &seek->segment);
- seg_start = seek->segment.start;
- seg_stop = seek->segment.stop;
+
+ out_segment.start = seek->segment.start;
+ out_segment.stop = seek->segment.stop;
+ out_segment.time = seek->segment.start;
+
next_ts = seek->start_ts;
parse->priv->exact_position = seek->accurate;
g_free (seek);
@@ -964,39 +980,48 @@ gst_base_parse_sink_eventfunc (GstBaseParse * parse, GstEvent * event)
/* best attempt convert */
/* as these are only estimates, stop is kept open-ended to avoid
* premature cutting */
- gst_base_parse_convert (parse, GST_FORMAT_BYTES, start,
- GST_FORMAT_TIME, (gint64 *) & seg_start);
- parse->priv->exact_position = (start == 0);
- next_ts = seg_start;
+ gst_base_parse_convert (parse, GST_FORMAT_BYTES, in_segment->start,
+ GST_FORMAT_TIME, (gint64 *) & next_ts);
+
+ out_segment.start = next_ts;
+ out_segment.stop = GST_CLOCK_TIME_NONE;
+ out_segment.time = next_ts;
+
+ parse->priv->exact_position = (in_segment->start == 0);
}
gst_event_unref (event);
- event = gst_event_new_new_segment_full (update, rate, applied_rate,
- GST_FORMAT_TIME, seg_start, seg_stop, seg_start);
- format = GST_FORMAT_TIME;
- start = seg_start;
- stop = seg_stop;
+
+ event = gst_event_new_segment (&out_segment);
+
GST_DEBUG_OBJECT (parse, "Converted incoming segment to TIME. "
- "start = %" GST_TIME_FORMAT ", stop = %" GST_TIME_FORMAT,
- GST_TIME_ARGS (seg_start), GST_TIME_ARGS (seg_stop));
- } else if (format != GST_FORMAT_TIME) {
+ GST_SEGMENT_FORMAT, in_segment);
+
+ } else if (in_segment->format != GST_FORMAT_TIME) {
/* Unknown incoming segment format. Output a default open-ended
* TIME segment */
gst_event_unref (event);
- event = gst_event_new_new_segment_full (update, rate, applied_rate,
- GST_FORMAT_TIME, 0, GST_CLOCK_TIME_NONE, 0);
- format = GST_FORMAT_TIME;
- next_ts = start = 0;
- stop = GST_CLOCK_TIME_NONE;
+
+ out_segment.start = 0;
+ out_segment.stop = GST_CLOCK_TIME_NONE;;
+ out_segment.time = 0;;
+
+ event = gst_event_new_segment (&out_segment);
+
+ next_ts = 0;
} else {
/* not considered BYTE seekable if it is talking to us in TIME,
* whatever else it might claim */
parse->priv->upstream_seekable = FALSE;
- next_ts = start;
+ next_ts = in_segment->start;
}
- gst_segment_set_newsegment_full (&parse->segment, update, rate,
- applied_rate, format, start, stop, start);
+ memcpy (&parse->segment, &out_segment, sizeof (GstSegment));
+
+ /*
+ gst_segment_set_newsegment (&parse->segment, update, rate,
+ applied_rate, format, start, stop, start);
+ */
/* save the segment for later, right before we push a new buffer so that
* the caps are fixed and the next linked element can receive
@@ -1008,11 +1033,12 @@ gst_base_parse_sink_eventfunc (GstBaseParse * parse, GstEvent * event)
/* but finish the current segment */
GST_DEBUG_OBJECT (parse, "draining current segment");
- if (parse->segment.rate > 0.0)
+ if (in_segment->rate > 0.0)
gst_base_parse_drain (parse);
else
gst_base_parse_process_fragment (parse, FALSE);
gst_adapter_clear (parse->priv->adapter);
+
parse->priv->offset = offset;
parse->priv->sync_offset = offset;
parse->priv->next_ts = next_ts;
@@ -1310,7 +1336,7 @@ gst_base_parse_update_bitrates (GstBaseParse * parse, GstBaseParseFrame * frame)
if (overhead == -1)
return;
- data_len = GST_BUFFER_SIZE (buffer) - overhead;
+ data_len = gst_buffer_get_size (buffer) - overhead;
parse->priv->data_bytecount += data_len;
/* duration should be valid by now,
@@ -1551,7 +1577,7 @@ gst_base_parse_check_media (GstBaseParse * parse)
GstCaps *caps;
GstStructure *s;
- caps = GST_PAD_CAPS (parse->srcpad);
+ caps = gst_pad_get_current_caps (parse->srcpad);
if (G_LIKELY (caps) && (s = gst_caps_get_structure (caps, 0))) {
parse->priv->is_video =
g_str_has_prefix (gst_structure_get_name (s), "video");
@@ -1559,6 +1585,8 @@ gst_base_parse_check_media (GstBaseParse * parse)
/* historical default */
parse->priv->is_video = FALSE;
}
+ if (caps)
+ gst_caps_unref (caps);
GST_DEBUG_OBJECT (parse, "media is video == %d", parse->priv->is_video);
}
@@ -1622,7 +1650,7 @@ gst_base_parse_handle_and_push_frame (GstBaseParse * parse,
"parsing frame at offset %" G_GUINT64_FORMAT
" (%#" G_GINT64_MODIFIER "x) of size %d",
GST_BUFFER_OFFSET (buffer), GST_BUFFER_OFFSET (buffer),
- GST_BUFFER_SIZE (buffer));
+ gst_buffer_get_size (buffer));
/* use default handler to provide initial (upstream) metadata */
gst_base_parse_parse_frame (parse, frame);
@@ -1699,10 +1727,6 @@ gst_base_parse_handle_and_push_frame (GstBaseParse * parse,
GstBaseParseFrame *queued_frame;
while ((queued_frame = g_queue_pop_head (&parse->priv->queued_frames))) {
- queued_frame->buffer =
- gst_buffer_make_metadata_writable (queued_frame->buffer);
- gst_buffer_set_caps (queued_frame->buffer,
- GST_PAD_CAPS (GST_BASE_PARSE_SRC_PAD (parse)));
gst_base_parse_push_frame (parse, queued_frame);
gst_base_parse_frame_free (queued_frame);
}
@@ -1735,6 +1759,7 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
GstClockTime last_stop = GST_CLOCK_TIME_NONE;
GstBaseParseClass *klass = GST_BASE_PARSE_GET_CLASS (parse);
GstBuffer *buffer;
+ gsize size;
g_return_val_if_fail (frame != NULL, GST_FLOW_ERROR);
g_return_val_if_fail (frame->buffer != NULL, GST_FLOW_ERROR);
@@ -1745,12 +1770,13 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
GST_LOG_OBJECT (parse,
"processing buffer of size %d with ts %" GST_TIME_FORMAT
- ", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buffer),
+ ", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buffer),
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));
/* update stats */
- parse->priv->bytecount += GST_BUFFER_SIZE (buffer);
+ size = gst_buffer_get_size (buffer);
+ parse->priv->bytecount += size;
if (G_LIKELY (!(frame->flags & GST_BASE_PARSE_FRAME_FLAG_NO_FRAME))) {
parse->priv->framecount++;
if (GST_BUFFER_DURATION_IS_VALID (buffer)) {
@@ -1771,7 +1797,8 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
last_stop = last_start + GST_BUFFER_DURATION (buffer);
/* should have caps by now */
- g_return_val_if_fail (GST_PAD_CAPS (parse->srcpad), GST_FLOW_ERROR);
+ g_return_val_if_fail (gst_pad_has_current_caps (parse->srcpad),
+ GST_FLOW_ERROR);
/* segment adjustment magic; only if we are running the whole show */
if (!parse->priv->passthrough && parse->segment.rate > 0.0 &&
@@ -1785,60 +1812,46 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
gst_event_unref (parse->priv->pending_segment);
parse->segment.start =
MIN ((guint64) last_start, (guint64) parse->segment.stop);
+
GST_DEBUG_OBJECT (parse,
"adjusting pending segment start to %" GST_TIME_FORMAT,
GST_TIME_ARGS (parse->segment.start));
- parse->priv->pending_segment =
- gst_event_new_new_segment (FALSE, parse->segment.rate,
- parse->segment.format, parse->segment.start,
- parse->segment.stop, parse->segment.start);
+
+ parse->priv->pending_segment = gst_event_new_segment (&parse->segment);
}
/* handle gaps, e.g. non-zero start-time, in as much not handled by above */
- if (GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop) &&
+ if (GST_CLOCK_TIME_IS_VALID (parse->segment.position) &&
GST_CLOCK_TIME_IS_VALID (last_start)) {
GstClockTimeDiff diff;
/* only send newsegments with increasing start times,
* otherwise if these go back and forth downstream (sinks) increase
* accumulated time and running_time */
- diff = GST_CLOCK_DIFF (parse->segment.last_stop, last_start);
+ diff = GST_CLOCK_DIFF (parse->segment.position, last_start);
if (G_UNLIKELY (diff > 2 * GST_SECOND
&& last_start > parse->segment.start
&& (!GST_CLOCK_TIME_IS_VALID (parse->segment.stop)
|| last_start < parse->segment.stop))) {
+
GST_DEBUG_OBJECT (parse,
"Gap of %" G_GINT64_FORMAT " ns detected in stream " "(%"
GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
"Sending updated NEWSEGMENT events", diff,
- GST_TIME_ARGS (parse->segment.last_stop),
+ GST_TIME_ARGS (parse->segment.position),
GST_TIME_ARGS (last_start));
+
if (G_UNLIKELY (parse->priv->pending_segment)) {
gst_event_unref (parse->priv->pending_segment);
parse->segment.start = last_start;
+ parse->segment.time = last_start;
parse->priv->pending_segment =
- gst_event_new_new_segment (FALSE, parse->segment.rate,
- parse->segment.format, parse->segment.start,
- parse->segment.stop, parse->segment.start);
+ gst_event_new_segment (&parse->segment);
} else {
- /* send newsegment events such that the gap is not accounted in
- * accum time, hence running_time */
- /* close ahead of gap */
- gst_pad_push_event (parse->srcpad,
- gst_event_new_new_segment (TRUE, parse->segment.rate,
- parse->segment.format, parse->segment.last_stop,
- parse->segment.last_stop, parse->segment.last_stop));
- /* skip gap */
+ /* skip gap FIXME */
gst_pad_push_event (parse->srcpad,
- gst_event_new_new_segment (FALSE, parse->segment.rate,
- parse->segment.format, last_start,
- parse->segment.stop, last_start));
+ gst_event_new_segment (&parse->segment));
}
- /* align segment view with downstream,
- * prevents double-counting accum when closing segment */
- gst_segment_set_newsegment (&parse->segment, FALSE,
- parse->segment.rate, parse->segment.format, last_start,
- parse->segment.stop, last_start);
- parse->segment.last_stop = last_start;
+ parse->segment.position = last_start;
}
}
}
@@ -1887,10 +1900,6 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
/* subclass must play nice */
g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
- /* decorate */
- buffer = gst_buffer_make_metadata_writable (buffer);
- gst_buffer_set_caps (buffer, GST_PAD_CAPS (parse->srcpad));
-
parse->priv->seen_keyframe |= parse->priv->is_video &&
!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
@@ -1919,26 +1928,25 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
}
if (ret == GST_BASE_PARSE_FLOW_DROPPED) {
- GST_LOG_OBJECT (parse, "frame (%d bytes) dropped",
- GST_BUFFER_SIZE (buffer));
+ GST_LOG_OBJECT (parse, "frame (%" G_GSIZE_FORMAT " bytes) dropped", size);
gst_buffer_unref (buffer);
ret = GST_FLOW_OK;
} else if (ret == GST_FLOW_OK) {
if (parse->segment.rate > 0.0) {
ret = gst_pad_push (parse->srcpad, buffer);
- GST_LOG_OBJECT (parse, "frame (%d bytes) pushed: %s",
- GST_BUFFER_SIZE (buffer), gst_flow_get_name (ret));
+ GST_LOG_OBJECT (parse, "frame (%" G_GSIZE_FORMAT " bytes) pushed: %s",
+ size, gst_flow_get_name (ret));
} else {
- GST_LOG_OBJECT (parse, "frame (%d bytes) queued for now",
- GST_BUFFER_SIZE (buffer));
+ GST_LOG_OBJECT (parse, "frame (%" G_GSIZE_FORMAT " bytes) queued for now",
+ size);
parse->priv->buffers_queued =
g_slist_prepend (parse->priv->buffers_queued, buffer);
ret = GST_FLOW_OK;
}
} else {
gst_buffer_unref (buffer);
- GST_LOG_OBJECT (parse, "frame (%d bytes) not pushed: %s",
- GST_BUFFER_SIZE (buffer), gst_flow_get_name (ret));
+ GST_LOG_OBJECT (parse, "frame (%" G_GSIZE_FORMAT " bytes) not pushed: %s",
+ size, gst_flow_get_name (ret));
/* if we are not sufficiently in control, let upstream decide on EOS */
if (ret == GST_FLOW_UNEXPECTED &&
(parse->priv->passthrough ||
@@ -1949,8 +1957,8 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
/* Update current running segment position */
if (ret == GST_FLOW_OK && last_stop != GST_CLOCK_TIME_NONE &&
- parse->segment.last_stop < last_stop)
- gst_segment_set_last_stop (&parse->segment, GST_FORMAT_TIME, last_stop);
+ parse->segment.position < last_stop)
+ parse->segment.position = last_stop;
gst_base_parse_frame_free (frame);
@@ -2056,7 +2064,7 @@ gst_base_parse_process_fragment (GstBaseParse * parse, gboolean push_only)
while (parse->priv->buffers_pending) {
buf = GST_BUFFER_CAST (parse->priv->buffers_pending->data);
GST_LOG_OBJECT (parse, "adding pending buffer (size %d)",
- GST_BUFFER_SIZE (buf));
+ gst_buffer_get_size (buf));
gst_adapter_push (parse->priv->adapter, buf);
parse->priv->buffers_pending =
g_slist_delete_link (parse->priv->buffers_pending,
@@ -2067,7 +2075,7 @@ gst_base_parse_process_fragment (GstBaseParse * parse, gboolean push_only)
* ok if taken from subclass or upstream */
parse->priv->next_ts = GST_CLOCK_TIME_NONE;
/* prevent it hanging around stop all the time */
- parse->segment.last_stop = GST_CLOCK_TIME_NONE;
+ parse->segment.position = GST_CLOCK_TIME_NONE;
/* mark next run */
parse->priv->discont = TRUE;
@@ -2184,10 +2192,10 @@ gst_base_parse_chain (GstPad * pad, GstBuffer * buffer)
if (G_LIKELY (buffer)) {
GST_LOG_OBJECT (parse, "buffer size: %d, offset = %" G_GINT64_FORMAT,
- GST_BUFFER_SIZE (buffer), GST_BUFFER_OFFSET (buffer));
+ gst_buffer_get_size (buffer), GST_BUFFER_OFFSET (buffer));
if (G_UNLIKELY (parse->priv->passthrough)) {
gst_base_parse_frame_init (frame);
- frame->buffer = gst_buffer_make_metadata_writable (buffer);
+ frame->buffer = gst_buffer_make_writable (buffer);
return gst_base_parse_push_frame (parse, frame);
}
/* upstream feeding us in reverse playback;
@@ -2252,11 +2260,11 @@ gst_base_parse_chain (GstPad * pad, GstBuffer * buffer)
}
/* always pass all available data */
- data = gst_adapter_peek (parse->priv->adapter, av);
- GST_BUFFER_DATA (tmpbuf) = (guint8 *) data;
- GST_BUFFER_SIZE (tmpbuf) = av;
+ data = gst_adapter_map (parse->priv->adapter, av);
+ gst_buffer_take_memory (tmpbuf, -1,
+ gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
+ (gpointer) data, NULL, av, 0, av));
GST_BUFFER_OFFSET (tmpbuf) = parse->priv->offset;
- GST_BUFFER_FLAG_SET (tmpbuf, GST_MINI_OBJECT_FLAG_READONLY);
if (parse->priv->discont) {
GST_DEBUG_OBJECT (parse, "marking DISCONT");
@@ -2266,6 +2274,7 @@ gst_base_parse_chain (GstPad * pad, GstBuffer * buffer)
skip = -1;
gst_base_parse_frame_update (parse, frame, tmpbuf);
res = bclass->check_valid_frame (parse, frame, &fsize, &skip);
+ gst_adapter_unmap (parse->priv->adapter, 0);
gst_buffer_replace (&frame->buffer, NULL);
if (res) {
if (gst_adapter_available (parse->priv->adapter) < fsize) {
@@ -2290,7 +2299,7 @@ gst_base_parse_chain (GstPad * pad, GstBuffer * buffer)
* fragment coming later, hopefully subclass skips efficiently ... */
timestamp = gst_adapter_prev_timestamp (parse->priv->adapter, NULL);
outbuf = gst_adapter_take_buffer (parse->priv->adapter, skip);
- outbuf = gst_buffer_make_metadata_writable (outbuf);
+ outbuf = gst_buffer_make_writable (outbuf);
GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
parse->priv->buffers_pending =
g_slist_prepend (parse->priv->buffers_pending, outbuf);
@@ -2342,7 +2351,7 @@ gst_base_parse_chain (GstPad * pad, GstBuffer * buffer)
/* FIXME: Would it be more efficient to make a subbuffer instead? */
outbuf = gst_adapter_take_buffer (parse->priv->adapter, fsize);
- outbuf = gst_buffer_make_metadata_writable (outbuf);
+ outbuf = gst_buffer_make_writable (outbuf);
/* Subclass may want to know the data offset */
GST_BUFFER_OFFSET (outbuf) = parse->priv->offset;
@@ -2388,11 +2397,11 @@ gst_base_parse_pull_range (GstBaseParse * parse, guint size,
* We do it mainly to avoid pulling buffers of 1 byte all the time */
if (parse->priv->cache) {
gint64 cache_offset = GST_BUFFER_OFFSET (parse->priv->cache);
- gint cache_size = GST_BUFFER_SIZE (parse->priv->cache);
+ gint cache_size = gst_buffer_get_size (parse->priv->cache);
if (cache_offset <= parse->priv->offset &&
(parse->priv->offset + size) <= (cache_offset + cache_size)) {
- *buffer = gst_buffer_create_sub (parse->priv->cache,
+ *buffer = gst_buffer_copy_region (parse->priv->cache, GST_BUFFER_COPY_ALL,
parse->priv->offset - cache_offset, size);
GST_BUFFER_OFFSET (*buffer) = parse->priv->offset;
return GST_FLOW_OK;
@@ -2411,8 +2420,10 @@ gst_base_parse_pull_range (GstBaseParse * parse, guint size,
return ret;
}
- if (GST_BUFFER_SIZE (parse->priv->cache) >= size) {
- *buffer = gst_buffer_create_sub (parse->priv->cache, 0, size);
+ if (gst_buffer_get_size (parse->priv->cache) >= size) {
+ *buffer =
+ gst_buffer_copy_region (parse->priv->cache, GST_BUFFER_COPY_ALL, 0,
+ size);
GST_BUFFER_OFFSET (*buffer) = parse->priv->offset;
return GST_FLOW_OK;
}
@@ -2431,10 +2442,10 @@ gst_base_parse_pull_range (GstBaseParse * parse, guint size,
return ret;
}
- if (GST_BUFFER_SIZE (parse->priv->cache) < size) {
+ if (gst_buffer_get_size (parse->priv->cache) < size) {
GST_DEBUG_OBJECT (parse, "Returning short buffer at offset %"
G_GUINT64_FORMAT ": wanted %u bytes, got %u bytes", parse->priv->offset,
- size, GST_BUFFER_SIZE (parse->priv->cache));
+ size, gst_buffer_get_size (parse->priv->cache));
*buffer = parse->priv->cache;
parse->priv->cache = NULL;
@@ -2442,7 +2453,8 @@ gst_base_parse_pull_range (GstBaseParse * parse, guint size,
return GST_FLOW_OK;
}
- *buffer = gst_buffer_create_sub (parse->priv->cache, 0, size);
+ *buffer =
+ gst_buffer_copy_region (parse->priv->cache, GST_BUFFER_COPY_ALL, 0, size);
GST_BUFFER_OFFSET (*buffer) = parse->priv->offset;
return GST_FLOW_OK;
@@ -2553,7 +2565,7 @@ gst_base_parse_scan_frame (GstBaseParse * parse, GstBaseParseClass * klass,
/* if we got a short read, inform subclass we are draining leftover
* and no more is to be expected */
- if (GST_BUFFER_SIZE (buffer) < min_size)
+ if (gst_buffer_get_size (buffer) < min_size)
parse->priv->drain = TRUE;
skip = -1;
@@ -2574,7 +2586,7 @@ gst_base_parse_scan_frame (GstBaseParse * parse, GstBaseParseClass * klass,
/* reverse playback, and no frames found yet, so we are skipping
* the leading part of a fragment, which may form the tail of
* fragment coming later, hopefully subclass skips efficiently ... */
- outbuf = gst_buffer_create_sub (buffer, 0, skip);
+ outbuf = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0, skip);
parse->priv->buffers_pending =
g_slist_prepend (parse->priv->buffers_pending, outbuf);
outbuf = NULL;
@@ -2603,8 +2615,8 @@ gst_base_parse_scan_frame (GstBaseParse * parse, GstBaseParseClass * klass,
else if (skip < 0)
skip = 0;
- if (fsize + skip <= GST_BUFFER_SIZE (buffer)) {
- outbuf = gst_buffer_create_sub (buffer, skip, fsize);
+ if (fsize + skip <= gst_buffer_get_size (buffer)) {
+ outbuf = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, skip, fsize);
GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET (buffer) + skip;
GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE;
gst_buffer_unref (buffer);
@@ -2613,7 +2625,7 @@ gst_base_parse_scan_frame (GstBaseParse * parse, GstBaseParseClass * klass,
ret = gst_base_parse_pull_range (parse, fsize, &outbuf);
if (ret != GST_FLOW_OK)
goto done;
- if (GST_BUFFER_SIZE (outbuf) < fsize) {
+ if (gst_buffer_get_size (outbuf) < fsize) {
gst_buffer_unref (outbuf);
ret = GST_FLOW_UNEXPECTED;
}
@@ -2670,7 +2682,7 @@ gst_base_parse_loop (GstPad * pad)
/* eat expected eos signalling past segment in reverse playback */
if (parse->segment.rate < 0.0 && ret == GST_FLOW_UNEXPECTED &&
- parse->segment.last_stop >= parse->segment.stop) {
+ parse->segment.position >= parse->segment.stop) {
GST_DEBUG_OBJECT (parse, "downstream has reached end of segment");
/* push what was accumulated during loop run */
gst_base_parse_process_fragment (parse, TRUE);
@@ -2750,12 +2762,24 @@ gst_base_parse_sink_activate (GstPad * sinkpad)
{
GstBaseParse *parse;
gboolean result = TRUE;
+ GstQuery *query;
+ gboolean pull_mode;
parse = GST_BASE_PARSE (gst_pad_get_parent (sinkpad));
GST_DEBUG_OBJECT (parse, "sink activate");
- if (gst_pad_check_pull_range (sinkpad)) {
+ query = gst_query_new_scheduling ();
+ result = gst_pad_peer_query (sinkpad, query);
+ if (result) {
+ gst_query_parse_scheduling (query, &pull_mode, NULL, NULL, NULL, NULL,
+ NULL);
+ } else {
+ pull_mode = FALSE;
+ }
+ gst_query_unref (query);
+
+ if (pull_mode) {
GST_DEBUG_OBJECT (parse, "trying to activate in pull mode");
result = gst_pad_activate_pull (sinkpad, TRUE);
} else {
@@ -2831,9 +2855,7 @@ gst_base_parse_sink_activate_pull (GstPad * sinkpad, gboolean active)
if (result) {
if (active) {
- parse->priv->pending_segment = gst_event_new_new_segment (FALSE,
- parse->segment.rate, parse->segment.format,
- parse->segment.start, parse->segment.stop, parse->segment.last_stop);
+ parse->priv->pending_segment = gst_event_new_segment (&parse->segment);
result &=
gst_pad_start_task (sinkpad, (GstTaskFunction) gst_base_parse_loop,
sinkpad);
@@ -3148,8 +3170,8 @@ gst_base_parse_query (GstPad * pad, GstQuery * query)
dest_value = parse->priv->offset;
res = TRUE;
} else if (format == parse->segment.format &&
- GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop)) {
- dest_value = parse->segment.last_stop;
+ GST_CLOCK_TIME_IS_VALID (parse->segment.position)) {
+ dest_value = parse->segment.position;
res = TRUE;
}
GST_OBJECT_UNLOCK (parse);
@@ -3284,9 +3306,9 @@ gst_base_parse_find_frame (GstBaseParse * parse, gint64 * pos,
GstBuffer *buf = NULL;
GstBaseParseFrame frame;
- g_return_val_if_fail (GST_FLOW_ERROR, pos != NULL);
- g_return_val_if_fail (GST_FLOW_ERROR, time != NULL);
- g_return_val_if_fail (GST_FLOW_ERROR, duration != NULL);
+ g_return_val_if_fail (pos != NULL, GST_FLOW_ERROR);
+ g_return_val_if_fail (time != NULL, GST_FLOW_ERROR);
+ g_return_val_if_fail (duration != NULL, GST_FLOW_ERROR);
klass = GST_BASE_PARSE_GET_CLASS (parse);
@@ -3313,7 +3335,8 @@ gst_base_parse_find_frame (GstBaseParse * parse, gint64 * pos,
GST_LOG_OBJECT (parse,
"peek parsing frame at offset %" G_GUINT64_FORMAT
" (%#" G_GINT64_MODIFIER "x) of size %d",
- GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET (buf), GST_BUFFER_SIZE (buf));
+ GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET (buf),
+ gst_buffer_get_size (buf));
/* get offset first, subclass parsing might dump other stuff in there */
*pos = GST_BUFFER_OFFSET (buf);
@@ -3571,10 +3594,10 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
/* copy segment, we need this because we still need the old
* segment when we close the current segment. */
- memcpy (&seeksegment, &parse->segment, sizeof (GstSegment));
+ gst_segment_copy_into (&parse->segment, &seeksegment);
GST_DEBUG_OBJECT (parse, "configuring seek");
- gst_segment_set_seek (&seeksegment, rate, format, flags,
+ gst_segment_do_seek (&seeksegment, rate, format, flags,
cur_type, cur, stop_type, stop, &update);
/* accurate seeking implies seek tables are used to obtain position,
@@ -3582,13 +3605,13 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
accurate = flags & GST_SEEK_FLAG_ACCURATE;
/* maybe we can be accurate for (almost) free */
- gst_base_parse_find_offset (parse, seeksegment.last_stop, TRUE, &start_ts);
- if (seeksegment.last_stop <= start_ts + TARGET_DIFFERENCE) {
+ gst_base_parse_find_offset (parse, seeksegment.position, TRUE, &start_ts);
+ if (seeksegment.position <= start_ts + TARGET_DIFFERENCE) {
GST_DEBUG_OBJECT (parse, "accurate seek possible");
accurate = TRUE;
}
if (accurate) {
- GstClockTime startpos = seeksegment.last_stop;
+ GstClockTime startpos = seeksegment.position;
/* accurate requested, so ... seek a bit before target */
if (startpos < parse->priv->lead_in_ts)
@@ -3599,9 +3622,9 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
seekstop = gst_base_parse_find_offset (parse, seeksegment.stop, FALSE,
NULL);
} else {
- start_ts = seeksegment.last_stop;
+ start_ts = seeksegment.position;
dstformat = GST_FORMAT_BYTES;
- if (!gst_pad_query_convert (parse->srcpad, format, seeksegment.last_stop,
+ if (!gst_pad_query_convert (parse->srcpad, format, seeksegment.position,
&dstformat, &seekpos))
goto convert_failed;
if (!gst_pad_query_convert (parse->srcpad, format, seeksegment.stop,
@@ -3637,7 +3660,7 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
GST_PAD_STREAM_LOCK (parse->sinkpad);
/* save current position */
- last_stop = parse->segment.last_stop;
+ last_stop = parse->segment.position;
GST_DEBUG_OBJECT (parse, "stopped streaming at %" G_GINT64_FORMAT,
last_stop);
@@ -3646,26 +3669,13 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
/* prepare for streaming again */
if (flush) {
GST_DEBUG_OBJECT (parse, "sending flush stop");
- gst_pad_push_event (parse->srcpad, gst_event_new_flush_stop ());
- gst_pad_push_event (parse->sinkpad, gst_event_new_flush_stop ());
+ gst_pad_push_event (parse->srcpad, gst_event_new_flush_stop (TRUE));
+ gst_pad_push_event (parse->sinkpad, gst_event_new_flush_stop (TRUE));
gst_base_parse_clear_queues (parse);
} else {
- if (parse->priv->close_segment)
- gst_event_unref (parse->priv->close_segment);
-
- parse->priv->close_segment = gst_event_new_new_segment (TRUE,
- parse->segment.rate, parse->segment.format,
- parse->segment.accum, parse->segment.last_stop, parse->segment.accum);
-
- /* keep track of our last_stop */
- seeksegment.accum = parse->segment.last_stop;
-
- GST_DEBUG_OBJECT (parse, "Created close seg format %d, "
- "start = %" GST_TIME_FORMAT ", stop = %" GST_TIME_FORMAT
- ", pos = %" GST_TIME_FORMAT, format,
- GST_TIME_ARGS (parse->segment.accum),
- GST_TIME_ARGS (parse->segment.last_stop),
- GST_TIME_ARGS (parse->segment.accum));
+ /* keep track of our position */
+ seeksegment.base = gst_segment_to_running_time (&seeksegment,
+ seeksegment.format, parse->segment.position);
}
memcpy (&parse->segment, &seeksegment, sizeof (GstSegment));
@@ -3675,10 +3685,7 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
gst_event_unref (parse->priv->pending_segment);
/* This will be sent later in _loop() */
- parse->priv->pending_segment =
- gst_event_new_new_segment (FALSE, parse->segment.rate,
- parse->segment.format, parse->segment.start,
- parse->segment.stop, parse->segment.start);
+ parse->priv->pending_segment = gst_event_new_segment (&parse->segment);
GST_DEBUG_OBJECT (parse, "Created newseg format %d, "
"start = %" GST_TIME_FORMAT ", stop = %" GST_TIME_FORMAT
@@ -3691,7 +3698,7 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
* maybe scan and subclass can find where to go */
if (!accurate) {
gint64 scanpos;
- GstClockTime ts = seeksegment.last_stop;
+ GstClockTime ts = seeksegment.position;
gst_base_parse_locate_time (parse, &ts, &scanpos);
if (scanpos >= 0) {
@@ -3735,7 +3742,7 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
seek event (in bytes) to upstream. Segment / flush handling happens
in corresponding src event handlers */
GST_DEBUG_OBJECT (parse, "seek in PUSH mode");
- if (seekstop >= 0 && seekpos <= seekpos)
+ if (seekstop >= 0 && seekstop <= seekpos)
seekstop = seekpos;
new_event = gst_event_new_seek (rate, GST_FORMAT_BYTES, flush,
GST_SEEK_TYPE_SET, seekpos, stop_type, seekstop);
@@ -3818,24 +3825,6 @@ gst_base_parse_handle_tag (GstBaseParse * parse, GstEvent * event)
}
}
-static gboolean
-gst_base_parse_sink_setcaps (GstPad * pad, GstCaps * caps)
-{
- GstBaseParse *parse;
- GstBaseParseClass *klass;
- gboolean res = TRUE;
-
- parse = GST_BASE_PARSE (GST_PAD_PARENT (pad));
- klass = GST_BASE_PARSE_GET_CLASS (parse);
-
- GST_DEBUG_OBJECT (parse, "caps: %" GST_PTR_FORMAT, caps);
-
- if (klass->set_sink_caps)
- res = klass->set_sink_caps (parse, caps);
-
- return res;
-}
-
static void
gst_base_parse_set_index (GstElement * element, GstIndex * index)
{
diff --git a/libs/gst/base/gstbasesink.c b/libs/gst/base/gstbasesink.c
index d60ba6fdfd..d9cf0b0cf3 100644
--- a/libs/gst/base/gstbasesink.c
+++ b/libs/gst/base/gstbasesink.c
@@ -36,12 +36,12 @@
*
* #GstBaseSink provides support for exactly one sink pad, which should be
* named "sink". A sink implementation (subclass of #GstBaseSink) should
- * install a pad template in its base_init function, like so:
+ * install a pad template in its class_init function, like so:
* |[
* static void
- * my_element_base_init (gpointer g_class)
+ * my_element_class_init (GstMyElementClass *klass)
* {
- * GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
+ * GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
*
* // sinktemplate should be a #GstStaticPadTemplate with direction
* // #GST_PAD_SINK and name "sink"
@@ -105,10 +105,6 @@
* very specific elements (such as file sinks) which need to handle the
* newsegment event specially.
*
- * #GstBaseSink provides an overridable #GstBaseSinkClass.buffer_alloc()
- * function that can be used by sinks that want to do reverse negotiation or to
- * provide custom buffers (hardware buffers for example) to upstream elements.
- *
* The #GstBaseSinkClass.unlock() method is called when the elements should
* unblock any blocking operations they perform in the
* #GstBaseSinkClass.render() method. This is mostly useful when the
@@ -266,6 +262,8 @@ struct _GstBaseSinkPrivate
/* for throttling and QoS */
GstClockTime earliest_in_time;
GstClockTime throttle_time;
+
+ gboolean reset_time;
};
#define DO_RUNNING_AVG(avg,val,size) (((val) + ((size)-1) * (avg)) / (size))
@@ -367,10 +365,8 @@ static gboolean gst_base_sink_send_event (GstElement * element,
static gboolean gst_base_sink_query (GstElement * element, GstQuery * query);
static const GstQueryType *gst_base_sink_get_query_types (GstElement * element);
-static GstCaps *gst_base_sink_get_caps (GstBaseSink * sink);
+static GstCaps *gst_base_sink_get_caps (GstBaseSink * sink, GstCaps * caps);
static gboolean gst_base_sink_set_caps (GstBaseSink * sink, GstCaps * caps);
-static GstFlowReturn gst_base_sink_buffer_alloc (GstBaseSink * sink,
- guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
static void gst_base_sink_get_times (GstBaseSink * basesink, GstBuffer * buffer,
GstClockTime * start, GstClockTime * end);
static gboolean gst_base_sink_set_flushing (GstBaseSink * basesink,
@@ -396,12 +392,8 @@ static gboolean gst_base_sink_pad_activate_pull (GstPad * pad, gboolean active);
static gboolean gst_base_sink_event (GstPad * pad, GstEvent * event);
static gboolean gst_base_sink_negotiate_pull (GstBaseSink * basesink);
-static GstCaps *gst_base_sink_pad_getcaps (GstPad * pad);
-static gboolean gst_base_sink_pad_setcaps (GstPad * pad, GstCaps * caps);
+static GstCaps *gst_base_sink_pad_getcaps (GstPad * pad, GstCaps * filter);
static void gst_base_sink_pad_fixate (GstPad * pad, GstCaps * caps);
-static GstFlowReturn gst_base_sink_pad_buffer_alloc (GstPad * pad,
- guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
-
/* check if an object was too late */
static gboolean gst_base_sink_is_too_late (GstBaseSink * basesink,
@@ -505,7 +497,7 @@ gst_base_sink_class_init (GstBaseSinkClass * klass)
* Since: 0.10.15
*/
g_object_class_install_property (gobject_class, PROP_LAST_BUFFER,
- gst_param_spec_mini_object ("last-buffer", "Last Buffer",
+ g_param_spec_boxed ("last-buffer", "Last Buffer",
"The last buffer received in the sink", GST_TYPE_BUFFER,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
/**
@@ -556,16 +548,13 @@ gst_base_sink_class_init (GstBaseSinkClass * klass)
klass->get_caps = GST_DEBUG_FUNCPTR (gst_base_sink_get_caps);
klass->set_caps = GST_DEBUG_FUNCPTR (gst_base_sink_set_caps);
- klass->buffer_alloc = GST_DEBUG_FUNCPTR (gst_base_sink_buffer_alloc);
klass->get_times = GST_DEBUG_FUNCPTR (gst_base_sink_get_times);
klass->activate_pull =
GST_DEBUG_FUNCPTR (gst_base_sink_default_activate_pull);
/* Registering debug symbols for function pointers */
GST_DEBUG_REGISTER_FUNCPTR (gst_base_sink_pad_getcaps);
- GST_DEBUG_REGISTER_FUNCPTR (gst_base_sink_pad_setcaps);
GST_DEBUG_REGISTER_FUNCPTR (gst_base_sink_pad_fixate);
- GST_DEBUG_REGISTER_FUNCPTR (gst_base_sink_pad_buffer_alloc);
GST_DEBUG_REGISTER_FUNCPTR (gst_base_sink_pad_activate);
GST_DEBUG_REGISTER_FUNCPTR (gst_base_sink_pad_activate_push);
GST_DEBUG_REGISTER_FUNCPTR (gst_base_sink_pad_activate_pull);
@@ -575,7 +564,7 @@ gst_base_sink_class_init (GstBaseSinkClass * klass)
}
static GstCaps *
-gst_base_sink_pad_getcaps (GstPad * pad)
+gst_base_sink_pad_getcaps (GstPad * pad, GstCaps * filter)
{
GstBaseSinkClass *bclass;
GstBaseSink *bsink;
@@ -586,14 +575,11 @@ gst_base_sink_pad_getcaps (GstPad * pad)
if (bsink->pad_mode == GST_ACTIVATE_PULL) {
/* if we are operating in pull mode we only accept the negotiated caps */
- GST_OBJECT_LOCK (pad);
- if ((caps = GST_PAD_CAPS (pad)))
- gst_caps_ref (caps);
- GST_OBJECT_UNLOCK (pad);
+ caps = gst_pad_get_current_caps (pad);
}
if (caps == NULL) {
if (bclass->get_caps)
- caps = bclass->get_caps (bsink);
+ caps = bclass->get_caps (bsink, filter);
if (caps == NULL) {
GstPadTemplate *pad_template;
@@ -602,7 +588,16 @@ gst_base_sink_pad_getcaps (GstPad * pad)
gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass),
"sink");
if (pad_template != NULL) {
- caps = gst_caps_ref (gst_pad_template_get_caps (pad_template));
+ caps = gst_pad_template_get_caps (pad_template);
+
+ if (filter) {
+ GstCaps *intersection;
+
+ intersection =
+ gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+ gst_caps_unref (caps);
+ caps = intersection;
+ }
}
}
}
@@ -611,24 +606,6 @@ gst_base_sink_pad_getcaps (GstPad * pad)
return caps;
}
-static gboolean
-gst_base_sink_pad_setcaps (GstPad * pad, GstCaps * caps)
-{
- GstBaseSinkClass *bclass;
- GstBaseSink *bsink;
- gboolean res = TRUE;
-
- bsink = GST_BASE_SINK (gst_pad_get_parent (pad));
- bclass = GST_BASE_SINK_GET_CLASS (bsink);
-
- if (res && bclass->set_caps)
- res = bclass->set_caps (bsink, caps);
-
- gst_object_unref (bsink);
-
- return res;
-}
-
static void
gst_base_sink_pad_fixate (GstPad * pad, GstCaps * caps)
{
@@ -644,29 +621,6 @@ gst_base_sink_pad_fixate (GstPad * pad, GstCaps * caps)
gst_object_unref (bsink);
}
-static GstFlowReturn
-gst_base_sink_pad_buffer_alloc (GstPad * pad, guint64 offset, guint size,
- GstCaps * caps, GstBuffer ** buf)
-{
- GstBaseSinkClass *bclass;
- GstBaseSink *bsink;
- GstFlowReturn result = GST_FLOW_OK;
-
- bsink = GST_BASE_SINK (gst_pad_get_parent (pad));
- if (G_UNLIKELY (bsink == NULL))
- return GST_FLOW_WRONG_STATE;
- bclass = GST_BASE_SINK_GET_CLASS (bsink);
-
- if (bclass->buffer_alloc)
- result = bclass->buffer_alloc (bsink, offset, size, caps, buf);
- else
- *buf = NULL; /* fallback in gstpad.c will allocate generic buffer */
-
- gst_object_unref (bsink);
-
- return result;
-}
-
static void
gst_base_sink_init (GstBaseSink * basesink, gpointer g_class)
{
@@ -682,10 +636,7 @@ gst_base_sink_init (GstBaseSink * basesink, gpointer g_class)
basesink->sinkpad = gst_pad_new_from_template (pad_template, "sink");
gst_pad_set_getcaps_function (basesink->sinkpad, gst_base_sink_pad_getcaps);
- gst_pad_set_setcaps_function (basesink->sinkpad, gst_base_sink_pad_setcaps);
gst_pad_set_fixatecaps_function (basesink->sinkpad, gst_base_sink_pad_fixate);
- gst_pad_set_bufferalloc_function (basesink->sinkpad,
- gst_base_sink_pad_buffer_alloc);
gst_pad_set_activate_function (basesink->sinkpad, gst_base_sink_pad_activate);
gst_pad_set_activatepush_function (basesink->sinkpad,
gst_base_sink_pad_activate_push);
@@ -697,15 +648,16 @@ gst_base_sink_init (GstBaseSink * basesink, gpointer g_class)
gst_element_add_pad (GST_ELEMENT_CAST (basesink), basesink->sinkpad);
basesink->pad_mode = GST_ACTIVATE_NONE;
+ basesink->preroll_lock = g_mutex_new ();
+ basesink->preroll_cond = g_cond_new ();
basesink->preroll_queue = g_queue_new ();
- basesink->abidata.ABI.clip_segment = gst_segment_new ();
priv->have_latency = FALSE;
basesink->can_activate_push = DEFAULT_CAN_ACTIVATE_PUSH;
basesink->can_activate_pull = DEFAULT_CAN_ACTIVATE_PULL;
basesink->sync = DEFAULT_SYNC;
- basesink->abidata.ABI.max_lateness = DEFAULT_MAX_LATENESS;
+ basesink->max_lateness = DEFAULT_MAX_LATENESS;
g_atomic_int_set (&priv->qos_enabled, DEFAULT_QOS);
priv->async_enabled = DEFAULT_ASYNC;
priv->ts_offset = DEFAULT_TS_OFFSET;
@@ -725,8 +677,9 @@ gst_base_sink_finalize (GObject * object)
basesink = GST_BASE_SINK (object);
+ g_mutex_free (basesink->preroll_lock);
+ g_cond_free (basesink->preroll_cond);
g_queue_free (basesink->preroll_queue);
- gst_segment_free (basesink->abidata.ABI.clip_segment);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -797,7 +750,7 @@ gst_base_sink_set_max_lateness (GstBaseSink * sink, gint64 max_lateness)
g_return_if_fail (GST_IS_BASE_SINK (sink));
GST_OBJECT_LOCK (sink);
- sink->abidata.ABI.max_lateness = max_lateness;
+ sink->max_lateness = max_lateness;
GST_OBJECT_UNLOCK (sink);
}
@@ -822,7 +775,7 @@ gst_base_sink_get_max_lateness (GstBaseSink * sink)
g_return_val_if_fail (GST_IS_BASE_SINK (sink), -1);
GST_OBJECT_LOCK (sink);
- res = sink->abidata.ABI.max_lateness;
+ res = sink->max_lateness;
GST_OBJECT_UNLOCK (sink);
return res;
@@ -885,10 +838,10 @@ gst_base_sink_set_async_enabled (GstBaseSink * sink, gboolean enabled)
{
g_return_if_fail (GST_IS_BASE_SINK (sink));
- GST_PAD_PREROLL_LOCK (sink->sinkpad);
+ GST_BASE_SINK_PREROLL_LOCK (sink);
g_atomic_int_set (&sink->priv->async_enabled, enabled);
GST_LOG_OBJECT (sink, "set async enabled to %d", enabled);
- GST_PAD_PREROLL_UNLOCK (sink->sinkpad);
+ GST_BASE_SINK_PREROLL_UNLOCK (sink);
}
/**
@@ -1364,9 +1317,9 @@ gst_base_sink_set_property (GObject * object, guint prop_id,
switch (prop_id) {
case PROP_PREROLL_QUEUE_LEN:
/* preroll lock necessary to serialize with finish_preroll */
- GST_PAD_PREROLL_LOCK (sink->sinkpad);
+ GST_BASE_SINK_PREROLL_LOCK (sink);
g_atomic_int_set (&sink->preroll_queue_max_len, g_value_get_uint (value));
- GST_PAD_PREROLL_UNLOCK (sink->sinkpad);
+ GST_BASE_SINK_PREROLL_UNLOCK (sink);
break;
case PROP_SYNC:
gst_base_sink_set_sync (sink, g_value_get_boolean (value));
@@ -1449,7 +1402,7 @@ gst_base_sink_get_property (GObject * object, guint prop_id, GValue * value,
static GstCaps *
-gst_base_sink_get_caps (GstBaseSink * sink)
+gst_base_sink_get_caps (GstBaseSink * sink, GstCaps * filter)
{
return NULL;
}
@@ -1460,14 +1413,6 @@ gst_base_sink_set_caps (GstBaseSink * sink, GstCaps * caps)
return TRUE;
}
-static GstFlowReturn
-gst_base_sink_buffer_alloc (GstBaseSink * sink, guint64 offset, guint size,
- GstCaps * caps, GstBuffer ** buf)
-{
- *buf = NULL;
- return GST_FLOW_OK;
-}
-
/* with PREROLL_LOCK, STREAM_LOCK */
static void
gst_base_sink_preroll_queue_flush (GstBaseSink * basesink, GstPad * pad)
@@ -1495,7 +1440,7 @@ gst_base_sink_preroll_queue_flush (GstBaseSink * basesink, GstPad * pad)
GST_OBJECT_UNLOCK (basesink);
}
/* and signal any waiters now */
- GST_PAD_PREROLL_SIGNAL (pad);
+ GST_BASE_SINK_PREROLL_SIGNAL (basesink);
}
/* with STREAM_LOCK, configures given segment with the event information. */
@@ -1503,43 +1448,15 @@ static void
gst_base_sink_configure_segment (GstBaseSink * basesink, GstPad * pad,
GstEvent * event, GstSegment * segment)
{
- gboolean update;
- gdouble rate, arate;
- GstFormat format;
- gint64 start;
- gint64 stop;
- gint64 time;
-
- /* the newsegment event is needed to bring the buffer timestamps to the
- * stream time and to drop samples outside of the playback segment. */
- gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
- &start, &stop, &time);
-
/* The segment is protected with both the STREAM_LOCK and the OBJECT_LOCK.
* We protect with the OBJECT_LOCK so that we can use the values to
* safely answer a POSITION query. */
GST_OBJECT_LOCK (basesink);
- gst_segment_set_newsegment_full (segment, update, rate, arate, format, start,
- stop, time);
-
- if (format == GST_FORMAT_TIME) {
- GST_DEBUG_OBJECT (basesink,
- "configured NEWSEGMENT update %d, rate %lf, applied rate %lf, "
- "format GST_FORMAT_TIME, "
- "%" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT
- ", time %" GST_TIME_FORMAT ", accum %" GST_TIME_FORMAT,
- update, rate, arate, GST_TIME_ARGS (segment->start),
- GST_TIME_ARGS (segment->stop), GST_TIME_ARGS (segment->time),
- GST_TIME_ARGS (segment->accum));
- } else {
- GST_DEBUG_OBJECT (basesink,
- "configured NEWSEGMENT update %d, rate %lf, applied rate %lf, "
- "format %d, "
- "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %"
- G_GINT64_FORMAT ", accum %" G_GINT64_FORMAT, update, rate, arate,
- segment->format, segment->start, segment->stop, segment->time,
- segment->accum);
- }
+ /* the newsegment event is needed to bring the buffer timestamps to the
+ * stream time and to drop samples outside of the playback segment. */
+ gst_event_copy_segment (event, segment);
+ GST_DEBUG_OBJECT (basesink, "configured SEGMENT %" GST_SEGMENT_FORMAT,
+ segment);
GST_OBJECT_UNLOCK (basesink);
}
@@ -1552,6 +1469,7 @@ gst_base_sink_commit_state (GstBaseSink * basesink)
gboolean post_paused = FALSE;
gboolean post_async_done = FALSE;
gboolean post_playing = FALSE;
+ gboolean reset_time;
/* we are certainly not playing async anymore now */
basesink->playing_async = FALSE;
@@ -1561,15 +1479,12 @@ gst_base_sink_commit_state (GstBaseSink * basesink)
next = GST_STATE_NEXT (basesink);
pending = GST_STATE_PENDING (basesink);
post_pending = pending;
+ reset_time = basesink->priv->reset_time;
+ basesink->priv->reset_time = FALSE;
switch (pending) {
case GST_STATE_PLAYING:
{
- GstBaseSinkClass *bclass;
- GstStateChangeReturn ret;
-
- bclass = GST_BASE_SINK_GET_CLASS (basesink);
-
GST_DEBUG_OBJECT (basesink, "commiting state to PLAYING");
basesink->need_preroll = FALSE;
@@ -1580,14 +1495,6 @@ gst_base_sink_commit_state (GstBaseSink * basesink)
if (current == GST_STATE_READY) {
post_paused = TRUE;
}
-
- /* make sure we notify the subclass of async playing */
- if (bclass->async_play) {
- GST_WARNING_OBJECT (basesink, "deprecated async_play");
- ret = bclass->async_play (basesink);
- if (ret == GST_STATE_CHANGE_FAILURE)
- goto async_failed;
- }
break;
}
case GST_STATE_PAUSED:
@@ -1624,7 +1531,7 @@ gst_base_sink_commit_state (GstBaseSink * basesink)
if (post_async_done) {
GST_DEBUG_OBJECT (basesink, "posting async-done message");
gst_element_post_message (GST_ELEMENT_CAST (basesink),
- gst_message_new_async_done (GST_OBJECT_CAST (basesink)));
+ gst_message_new_async_done (GST_OBJECT_CAST (basesink), reset_time));
}
if (post_playing) {
GST_DEBUG_OBJECT (basesink, "posting PLAYING state change message");
@@ -1672,13 +1579,6 @@ stopping:
GST_OBJECT_UNLOCK (basesink);
return FALSE;
}
-async_failed:
- {
- GST_DEBUG_OBJECT (basesink, "async commit failed");
- GST_STATE_RETURN (basesink) = GST_STATE_CHANGE_FAILURE;
- GST_OBJECT_UNLOCK (basesink);
- return FALSE;
- }
}
static void
@@ -1709,7 +1609,6 @@ start_stepping (GstBaseSink * sink, GstSegment * segment,
/* set the new rate for the remainder of the segment */
current->start_rate = segment->rate;
segment->rate *= current->rate;
- segment->abs_rate = ABS (segment->rate);
/* save values */
if (segment->rate > 0.0)
@@ -1723,27 +1622,19 @@ start_stepping (GstBaseSink * sink, GstSegment * segment,
/* update the segment clipping regions for non-flushing seeks */
if (segment->rate > 0.0) {
segment->stop = gst_segment_to_position (segment, GST_FORMAT_TIME, end);
- segment->last_stop = segment->stop;
+ segment->position = segment->stop;
} else {
gint64 position;
position = gst_segment_to_position (segment, GST_FORMAT_TIME, end);
segment->time = position;
segment->start = position;
- segment->last_stop = position;
+ segment->position = position;
}
}
}
- GST_DEBUG_OBJECT (sink,
- "segment now rate %lf, applied rate %lf, "
- "format GST_FORMAT_TIME, "
- "%" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT
- ", time %" GST_TIME_FORMAT ", accum %" GST_TIME_FORMAT,
- segment->rate, segment->applied_rate, GST_TIME_ARGS (segment->start),
- GST_TIME_ARGS (segment->stop), GST_TIME_ARGS (segment->time),
- GST_TIME_ARGS (segment->accum));
-
+ GST_DEBUG_OBJECT (sink, "segment now %" GST_SEGMENT_FORMAT, segment);
GST_DEBUG_OBJECT (sink, "step started at running_time %" GST_TIME_FORMAT,
GST_TIME_ARGS (current->start));
@@ -1788,8 +1679,8 @@ stop_stepping (GstBaseSink * sink, GstSegment * segment,
gst_segment_set_running_time (segment, GST_FORMAT_TIME, position);
if (current->flush) {
- /* and remove the accumulated time we flushed, start time did not change */
- segment->accum = current->start;
+ /* and remove the time we flushed, start time did not change */
+ segment->base = current->start;
} else {
/* start time is now the stepped position */
gst_element_set_start_time (GST_ELEMENT_CAST (sink), position);
@@ -1797,7 +1688,6 @@ stop_stepping (GstBaseSink * sink, GstSegment * segment,
/* restore the previous rate */
segment->rate = current->start_rate;
- segment->abs_rate = ABS (segment->rate);
if (segment->rate > 0.0)
segment->stop = current->start_stop;
@@ -1805,7 +1695,7 @@ stop_stepping (GstBaseSink * sink, GstSegment * segment,
segment->start = current->start_start;
/* the clip segment is used for position report in paused... */
- memcpy (sink->abidata.ABI.clip_segment, segment, sizeof (GstSegment));
+ gst_segment_copy_into (segment, &sink->clip_segment);
/* post the step done when we know the stepped duration in TIME */
message =
@@ -1824,8 +1714,8 @@ stop_stepping (GstBaseSink * sink, GstSegment * segment,
static gboolean
handle_stepping (GstBaseSink * sink, GstSegment * segment,
- GstStepInfo * current, gint64 * cstart, gint64 * cstop, gint64 * rstart,
- gint64 * rstop)
+ GstStepInfo * current, guint64 * cstart, guint64 * cstop, guint64 * rstart,
+ guint64 * rstop)
{
gboolean step_end = FALSE;
@@ -1834,7 +1724,8 @@ handle_stepping (GstBaseSink * sink, GstSegment * segment,
case GST_FORMAT_TIME:
{
guint64 end;
- gint64 first, last;
+ guint64 first, last;
+ gdouble abs_rate;
if (segment->rate > 0.0) {
if (segment->stop == *cstop)
@@ -1853,8 +1744,9 @@ handle_stepping (GstBaseSink * sink, GstSegment * segment,
end = current->start + current->amount;
current->position = first - current->start;
- if (G_UNLIKELY (segment->abs_rate != 1.0))
- current->position /= segment->abs_rate;
+ abs_rate = ABS (segment->rate);
+ if (G_UNLIKELY (abs_rate != 1.0))
+ current->position /= abs_rate;
GST_DEBUG_OBJECT (sink,
"buffer: %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT,
@@ -1924,8 +1816,8 @@ gst_base_sink_get_sync_times (GstBaseSink * basesink, GstMiniObject * obj,
GstBaseSinkClass *bclass;
GstBuffer *buffer;
GstClockTime start, stop; /* raw start/stop timestamps */
- gint64 cstart, cstop; /* clipped raw timestamps */
- gint64 rstart, rstop; /* clipped timestamps converted to running time */
+ guint64 cstart, cstop; /* clipped raw timestamps */
+ guint64 rstart, rstop; /* clipped timestamps converted to running time */
GstClockTime sstart, sstop; /* clipped timestamps converted to stream time */
GstFormat format;
GstBaseSinkPrivate *priv;
@@ -1970,11 +1862,6 @@ gst_base_sink_get_sync_times (GstBaseSink * basesink, GstMiniObject * obj,
}
default:
/* other events do not need syncing */
- /* FIXME, maybe NEWSEGMENT might need synchronisation
- * since the POSITION query depends on accumulated times and
- * we cannot accumulate the current segment before the previous
- * one completed.
- */
return FALSE;
}
}
@@ -2008,19 +1895,9 @@ again:
/* collect segment and format for code clarity */
format = segment->format;
- /* no timestamp clipping if we did not get a TIME segment format */
- if (G_UNLIKELY (format != GST_FORMAT_TIME)) {
- cstart = start;
- cstop = stop;
- /* do running and stream time in TIME format */
- format = GST_FORMAT_TIME;
- GST_LOG_OBJECT (basesink, "not time format, don't clip");
- goto do_times;
- }
-
- /* clip, only when we know about time */
- if (G_UNLIKELY (!gst_segment_clip (segment, GST_FORMAT_TIME,
- (gint64) start, (gint64) stop, &cstart, &cstop))) {
+ /* clip */
+ if (G_UNLIKELY (!gst_segment_clip (segment, format,
+ start, stop, &cstart, &cstop))) {
if (step->valid) {
GST_DEBUG_OBJECT (basesink, "step out of segment");
/* when we are stepping, pretend we're at the end of the segment */
@@ -2044,9 +1921,9 @@ again:
/* set last stop position */
if (G_LIKELY (stop != GST_CLOCK_TIME_NONE && cstop != GST_CLOCK_TIME_NONE))
- gst_segment_set_last_stop (segment, GST_FORMAT_TIME, cstop);
+ segment->position = cstop;
else
- gst_segment_set_last_stop (segment, GST_FORMAT_TIME, cstart);
+ segment->position = cstart;
do_times:
rstart = gst_segment_to_running_time (segment, format, cstart);
@@ -2209,11 +2086,11 @@ gst_base_sink_wait_clock (GstBaseSink * sink, GstClockTime time,
* entry. */
sink->clock_id = sink->priv->cached_clock_id;
/* release the preroll lock while waiting */
- GST_PAD_PREROLL_UNLOCK (sink->sinkpad);
+ GST_BASE_SINK_PREROLL_UNLOCK (sink);
ret = gst_clock_id_wait (sink->priv->cached_clock_id, jitter);
- GST_PAD_PREROLL_LOCK (sink->sinkpad);
+ GST_BASE_SINK_PREROLL_LOCK (sink);
sink->clock_id = NULL;
return ret;
@@ -2265,7 +2142,7 @@ gst_base_sink_wait_preroll (GstBaseSink * sink)
sink->have_preroll = TRUE;
GST_DEBUG_OBJECT (sink, "waiting in preroll for flush or PLAYING");
/* block until the state changes, or we get a flush, or something */
- GST_PAD_PREROLL_WAIT (sink->sinkpad);
+ GST_BASE_SINK_PREROLL_WAIT (sink);
sink->have_preroll = FALSE;
if (G_UNLIKELY (sink->flushing))
goto stopping;
@@ -2641,7 +2518,7 @@ gst_base_sink_send_qos (GstBaseSink * basesink, GstQOSType type,
"qos: type %d, proportion: %lf, diff %" G_GINT64_FORMAT ", timestamp %"
GST_TIME_FORMAT, type, proportion, diff, GST_TIME_ARGS (time));
- event = gst_event_new_qos_full (type, proportion, diff, time);
+ event = gst_event_new_qos (type, proportion, diff, time);
/* send upstream */
res = gst_pad_push_event (basesink->sinkpad, event);
@@ -2822,7 +2699,7 @@ gst_base_sink_is_too_late (GstBaseSink * basesink, GstMiniObject * obj,
GstClockReturn status, GstClockTimeDiff jitter)
{
gboolean late;
- gint64 max_lateness;
+ guint64 max_lateness;
GstBaseSinkPrivate *priv;
priv = basesink->priv;
@@ -2833,7 +2710,7 @@ gst_base_sink_is_too_late (GstBaseSink * basesink, GstMiniObject * obj,
if (G_LIKELY (status != GST_CLOCK_EARLY))
goto in_time;
- max_lateness = basesink->abidata.ABI.max_lateness;
+ max_lateness = basesink->max_lateness;
/* check if frame dropping is enabled */
if (max_lateness == -1)
@@ -2961,7 +2838,7 @@ gst_base_sink_render_object (GstBaseSink * basesink, GstPad * pad,
* If buffer list, use the first group buffer within the list
* for syncing
*/
- sync_obj = gst_buffer_list_get (GST_BUFFER_LIST_CAST (obj), 0, 0);
+ sync_obj = gst_buffer_list_get (GST_BUFFER_LIST_CAST (obj), 0);
g_assert (NULL != sync_obj);
} else {
sync_obj = obj;
@@ -3076,12 +2953,24 @@ again:
gst_element_post_message (GST_ELEMENT_CAST (basesink), message);
break;
}
- case GST_EVENT_NEWSEGMENT:
+ case GST_EVENT_SEGMENT:
/* configure the segment */
gst_base_sink_configure_segment (basesink, pad, event,
&basesink->segment);
break;
- case GST_EVENT_SINK_MESSAGE:{
+ case GST_EVENT_TAG:
+ {
+ GstTagList *taglist;
+
+ gst_event_parse_tag (event, &taglist);
+
+ gst_element_post_message (GST_ELEMENT_CAST (basesink),
+ gst_message_new_tag (GST_OBJECT_CAST (basesink),
+ gst_tag_list_copy (taglist)));
+ break;
+ }
+ case GST_EVENT_SINK_MESSAGE:
+ {
GstMessage *msg = NULL;
gst_event_parse_sink_message (event, &msg);
@@ -3182,7 +3071,7 @@ gst_base_sink_preroll_object (GstBaseSink * basesink, guint8 obj_type,
GstClockTime timestamp;
if (OBJ_IS_BUFFERLIST (obj_type)) {
- buf = gst_buffer_list_get (GST_BUFFER_LIST_CAST (obj), 0, 0);
+ buf = gst_buffer_list_get (GST_BUFFER_LIST_CAST (obj), 0);
g_assert (NULL != buf);
} else {
buf = GST_BUFFER_CAST (obj);
@@ -3335,7 +3224,7 @@ gst_base_sink_queue_object (GstBaseSink * basesink, GstPad * pad,
{
GstFlowReturn ret;
- GST_PAD_PREROLL_LOCK (pad);
+ GST_BASE_SINK_PREROLL_LOCK (basesink);
if (G_UNLIKELY (basesink->flushing))
goto flushing;
@@ -3345,7 +3234,7 @@ gst_base_sink_queue_object (GstBaseSink * basesink, GstPad * pad,
ret =
gst_base_sink_queue_object_unlocked (basesink, pad, _PR_IS_EVENT, obj,
prerollable);
- GST_PAD_PREROLL_UNLOCK (pad);
+ GST_BASE_SINK_PREROLL_UNLOCK (basesink);
return ret;
@@ -3353,7 +3242,7 @@ gst_base_sink_queue_object (GstBaseSink * basesink, GstPad * pad,
flushing:
{
GST_DEBUG_OBJECT (basesink, "sink is flushing");
- GST_PAD_PREROLL_UNLOCK (pad);
+ GST_BASE_SINK_PREROLL_UNLOCK (basesink);
gst_mini_object_unref (obj);
return GST_FLOW_WRONG_STATE;
}
@@ -3361,7 +3250,7 @@ was_eos:
{
GST_DEBUG_OBJECT (basesink,
"we are EOS, dropping object, return UNEXPECTED");
- GST_PAD_PREROLL_UNLOCK (pad);
+ GST_BASE_SINK_PREROLL_UNLOCK (basesink);
gst_mini_object_unref (obj);
return GST_FLOW_UNEXPECTED;
}
@@ -3392,7 +3281,8 @@ gst_base_sink_flush_start (GstBaseSink * basesink, GstPad * pad)
}
static void
-gst_base_sink_flush_stop (GstBaseSink * basesink, GstPad * pad)
+gst_base_sink_flush_stop (GstBaseSink * basesink, GstPad * pad,
+ gboolean reset_time)
{
/* unset flushing so we can accept new data, this also flushes out any EOS
* event. */
@@ -3409,9 +3299,12 @@ gst_base_sink_flush_stop (GstBaseSink * basesink, GstPad * pad)
if (basesink->pad_mode == GST_ACTIVATE_PUSH) {
/* we need new segment info after the flush. */
basesink->have_newsegment = FALSE;
- gst_segment_init (&basesink->segment, GST_FORMAT_UNDEFINED);
- gst_segment_init (basesink->abidata.ABI.clip_segment, GST_FORMAT_UNDEFINED);
+ if (reset_time) {
+ gst_segment_init (&basesink->segment, GST_FORMAT_UNDEFINED);
+ gst_segment_init (&basesink->clip_segment, GST_FORMAT_UNDEFINED);
+ }
}
+ basesink->priv->reset_time = reset_time;
GST_OBJECT_UNLOCK (basesink);
}
@@ -3438,66 +3331,70 @@ gst_base_sink_event (GstPad * pad, GstEvent * event)
{
GstFlowReturn ret;
- GST_PAD_PREROLL_LOCK (pad);
+ GST_BASE_SINK_PREROLL_LOCK (basesink);
if (G_UNLIKELY (basesink->flushing))
goto flushing;
- if (G_UNLIKELY (basesink->priv->received_eos)) {
- /* we can't accept anything when we are EOS */
+ if (G_UNLIKELY (basesink->priv->received_eos))
+ goto after_eos;
+
+ /* we set the received EOS flag here so that we can use it when testing if
+ * we are prerolled and to refuse more buffers. */
+ basesink->priv->received_eos = TRUE;
+
+ /* EOS is a prerollable object, we call the unlocked version because it
+ * does not check the received_eos flag. */
+ ret = gst_base_sink_queue_object_unlocked (basesink, pad,
+ _PR_IS_EVENT, GST_MINI_OBJECT_CAST (event), TRUE);
+ if (G_UNLIKELY (ret != GST_FLOW_OK))
result = FALSE;
- gst_event_unref (event);
- } else {
- /* we set the received EOS flag here so that we can use it when testing if
- * we are prerolled and to refuse more buffers. */
- basesink->priv->received_eos = TRUE;
-
- /* EOS is a prerollable object, we call the unlocked version because it
- * does not check the received_eos flag. */
- ret = gst_base_sink_queue_object_unlocked (basesink, pad,
- _PR_IS_EVENT, GST_MINI_OBJECT_CAST (event), TRUE);
- if (G_UNLIKELY (ret != GST_FLOW_OK))
- result = FALSE;
- }
- GST_PAD_PREROLL_UNLOCK (pad);
+
+ GST_BASE_SINK_PREROLL_UNLOCK (basesink);
+ break;
+ }
+ case GST_EVENT_CAPS:
+ {
+ GstCaps *caps;
+
+ GST_DEBUG_OBJECT (basesink, "caps %p", event);
+
+ gst_event_parse_caps (event, &caps);
+ if (bclass->set_caps)
+ result = bclass->set_caps (basesink, caps);
+
+ gst_event_unref (event);
break;
}
- case GST_EVENT_NEWSEGMENT:
+ case GST_EVENT_SEGMENT:
{
GstFlowReturn ret;
- gboolean update;
- GST_DEBUG_OBJECT (basesink, "newsegment %p", event);
+ GST_DEBUG_OBJECT (basesink, "segment %p", event);
- GST_PAD_PREROLL_LOCK (pad);
+ GST_BASE_SINK_PREROLL_LOCK (basesink);
if (G_UNLIKELY (basesink->flushing))
goto flushing;
- gst_event_parse_new_segment_full (event, &update, NULL, NULL, NULL, NULL,
- NULL, NULL);
+ if (G_UNLIKELY (basesink->priv->received_eos))
+ goto after_eos;
- if (G_UNLIKELY (basesink->priv->received_eos && !update)) {
- /* we can't accept anything when we are EOS */
+ /* the new segment is a non prerollable item and does not block anything,
+ * we need to configure the current clipping segment and insert the event
+ * in the queue to serialize it with the buffers for rendering. */
+ gst_base_sink_configure_segment (basesink, pad, event,
+ &basesink->clip_segment);
+
+ ret =
+ gst_base_sink_queue_object_unlocked (basesink, pad,
+ _PR_IS_EVENT, GST_MINI_OBJECT_CAST (event), FALSE);
+ if (G_UNLIKELY (ret != GST_FLOW_OK))
result = FALSE;
- gst_event_unref (event);
- } else {
- /* the new segment is a non prerollable item and does not block anything,
- * we need to configure the current clipping segment and insert the event
- * in the queue to serialize it with the buffers for rendering. */
- gst_base_sink_configure_segment (basesink, pad, event,
- basesink->abidata.ABI.clip_segment);
-
- ret =
- gst_base_sink_queue_object_unlocked (basesink, pad,
- _PR_IS_EVENT, GST_MINI_OBJECT_CAST (event), FALSE);
- if (G_UNLIKELY (ret != GST_FLOW_OK))
- result = FALSE;
- else {
- GST_OBJECT_LOCK (basesink);
- basesink->have_newsegment = TRUE;
- GST_OBJECT_UNLOCK (basesink);
- }
+ else {
+ GST_OBJECT_LOCK (basesink);
+ basesink->have_newsegment = TRUE;
+ GST_OBJECT_UNLOCK (basesink);
}
- GST_PAD_PREROLL_UNLOCK (pad);
+ GST_BASE_SINK_PREROLL_UNLOCK (basesink);
break;
}
case GST_EVENT_FLUSH_START:
@@ -3511,15 +3408,21 @@ gst_base_sink_event (GstPad * pad, GstEvent * event)
gst_event_unref (event);
break;
case GST_EVENT_FLUSH_STOP:
+ {
+ gboolean reset_time;
+
if (bclass->event)
bclass->event (basesink, event);
- GST_DEBUG_OBJECT (basesink, "flush-stop %p", event);
+ gst_event_parse_flush_stop (event, &reset_time);
+ GST_DEBUG_OBJECT (basesink, "flush-stop %p, reset_time: %d", event,
+ reset_time);
- gst_base_sink_flush_stop (basesink, pad);
+ gst_base_sink_flush_stop (basesink, pad, reset_time);
gst_event_unref (event);
break;
+ }
default:
/* other events are sent to queue or subclass depending on if they
* are serialized. */
@@ -3542,7 +3445,16 @@ done:
flushing:
{
GST_DEBUG_OBJECT (basesink, "we are flushing");
- GST_PAD_PREROLL_UNLOCK (pad);
+ GST_BASE_SINK_PREROLL_UNLOCK (basesink);
+ result = FALSE;
+ gst_event_unref (event);
+ goto done;
+ }
+
+after_eos:
+ {
+ GST_DEBUG_OBJECT (basesink, "Event received after EOS, dropping");
+ GST_BASE_SINK_PREROLL_UNLOCK (basesink);
result = FALSE;
gst_event_unref (event);
goto done;
@@ -3614,14 +3526,14 @@ gst_base_sink_chain_unlocked (GstBaseSink * basesink, GstPad * pad,
goto was_eos;
if (OBJ_IS_BUFFERLIST (obj_type)) {
- time_buf = gst_buffer_list_get (GST_BUFFER_LIST_CAST (obj), 0, 0);
+ time_buf = gst_buffer_list_get (GST_BUFFER_LIST_CAST (obj), 0);
g_assert (NULL != time_buf);
} else {
time_buf = GST_BUFFER_CAST (obj);
}
/* for code clarity */
- clip_segment = basesink->abidata.ABI.clip_segment;
+ clip_segment = &basesink->clip_segment;
if (G_UNLIKELY (!basesink->have_newsegment)) {
gboolean sync;
@@ -3663,7 +3575,7 @@ gst_base_sink_chain_unlocked (GstBaseSink * basesink, GstPad * pad,
if (GST_CLOCK_TIME_IS_VALID (start) &&
(clip_segment->format == GST_FORMAT_TIME)) {
if (G_UNLIKELY (!gst_segment_clip (clip_segment,
- GST_FORMAT_TIME, (gint64) start, (gint64) end, NULL, NULL)))
+ GST_FORMAT_TIME, start, end, NULL, NULL)))
goto out_of_segment;
}
@@ -3706,9 +3618,9 @@ gst_base_sink_chain_main (GstBaseSink * basesink, GstPad * pad,
if (G_UNLIKELY (basesink->pad_mode != GST_ACTIVATE_PUSH))
goto wrong_mode;
- GST_PAD_PREROLL_LOCK (pad);
+ GST_BASE_SINK_PREROLL_LOCK (basesink);
result = gst_base_sink_chain_unlocked (basesink, pad, obj_type, obj);
- GST_PAD_PREROLL_UNLOCK (pad);
+ GST_BASE_SINK_PREROLL_UNLOCK (basesink);
done:
return result;
@@ -3752,32 +3664,21 @@ gst_base_sink_chain_list (GstPad * pad, GstBufferList * list)
if (G_LIKELY (bclass->render_list)) {
result = gst_base_sink_chain_main (basesink, pad, _PR_IS_BUFFERLIST, list);
} else {
- GstBufferListIterator *it;
- GstBuffer *group;
+ guint i, len;
+ GstBuffer *buffer;
GST_INFO_OBJECT (pad, "chaining each group in list as a merged buffer");
- it = gst_buffer_list_iterate (list);
+ len = gst_buffer_list_len (list);
- if (gst_buffer_list_iterator_next_group (it)) {
- do {
- group = gst_buffer_list_iterator_merge_group (it);
- if (group == NULL) {
- group = gst_buffer_new ();
- GST_CAT_INFO_OBJECT (GST_CAT_SCHEDULING, pad, "chaining empty group");
- } else {
- GST_CAT_INFO_OBJECT (GST_CAT_SCHEDULING, pad, "chaining group");
- }
- result = gst_base_sink_chain_main (basesink, pad, _PR_IS_BUFFER, group);
- } while (result == GST_FLOW_OK
- && gst_buffer_list_iterator_next_group (it));
- } else {
- GST_CAT_INFO_OBJECT (GST_CAT_SCHEDULING, pad, "chaining empty group");
- result =
- gst_base_sink_chain_main (basesink, pad, _PR_IS_BUFFER,
- gst_buffer_new ());
+ result = GST_FLOW_OK;
+ for (i = 0; i < len; i++) {
+ buffer = gst_buffer_list_get (list, 0);
+ result = gst_base_sink_chain_main (basesink, pad, _PR_IS_BUFFER,
+ gst_buffer_ref (buffer));
+ if (result != GST_FLOW_OK)
+ break;
}
- gst_buffer_list_iterator_free (it);
gst_buffer_list_unref (list);
}
return result;
@@ -3829,7 +3730,7 @@ gst_base_sink_default_prepare_seek_segment (GstBaseSink * sink,
dest_format = segment->format;
if (seek_format == dest_format) {
- gst_segment_set_seek (segment, rate, seek_format, flags,
+ gst_segment_do_seek (segment, rate, seek_format, flags,
cur_type, cur, stop_type, stop, &update);
return TRUE;
}
@@ -3851,7 +3752,7 @@ gst_base_sink_default_prepare_seek_segment (GstBaseSink * sink,
}
/* And finally, configure our output segment in the desired format */
- gst_segment_set_seek (segment, rate, dest_format, flags, cur_type, cur,
+ gst_segment_do_seek (segment, rate, dest_format, flags, cur_type, cur,
stop_type, stop, &update);
if (!res)
@@ -3924,7 +3825,7 @@ gst_base_sink_perform_seek (GstBaseSink * sink, GstPad * pad, GstEvent * event)
} else {
/* The seek format matches our processing format, no need to ask the
* the subclass to configure the segment. */
- gst_segment_set_seek (&seeksegment, rate, seek_format, flags,
+ gst_segment_do_seek (&seeksegment, rate, seek_format, flags,
cur_type, cur, stop_type, stop, &update);
}
}
@@ -3935,22 +3836,22 @@ gst_base_sink_perform_seek (GstBaseSink * sink, GstPad * pad, GstEvent * event)
if (res) {
GST_DEBUG_OBJECT (sink, "segment configured from %" G_GINT64_FORMAT
" to %" G_GINT64_FORMAT ", position %" G_GINT64_FORMAT,
- seeksegment.start, seeksegment.stop, seeksegment.last_stop);
+ seeksegment.start, seeksegment.stop, seeksegment.position);
- /* do the seek, segment.last_stop contains the new position. */
+ /* do the seek, segment.position contains the new position. */
res = gst_base_sink_default_do_seek (sink, &seeksegment);
}
if (flush) {
GST_DEBUG_OBJECT (sink, "stop flushing upstream");
- gst_pad_push_event (pad, gst_event_new_flush_stop ());
- gst_base_sink_flush_stop (sink, pad);
- } else if (res && sink->abidata.ABI.running) {
+ gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
+ gst_base_sink_flush_stop (sink, pad, TRUE);
+ } else if (res && sink->running) {
/* we are running the current segment and doing a non-flushing seek,
- * close the segment first based on the last_stop. */
+ * close the segment first based on the position. */
GST_DEBUG_OBJECT (sink, "closing running segment %" G_GINT64_FORMAT
- " to %" G_GINT64_FORMAT, sink->segment.start, sink->segment.last_stop);
+ " to %" G_GINT64_FORMAT, sink->segment.start, sink->segment.position);
}
/* The subclass must have converted the segment to the processing format
@@ -3964,17 +3865,17 @@ gst_base_sink_perform_seek (GstBaseSink * sink, GstPad * pad, GstEvent * event)
/* if successfull seek, we update our real segment and push
* out the new segment. */
if (res) {
- memcpy (&sink->segment, &seeksegment, sizeof (GstSegment));
+ gst_segment_copy_into (&seeksegment, &sink->segment);
if (sink->segment.flags & GST_SEEK_FLAG_SEGMENT) {
gst_element_post_message (GST_ELEMENT (sink),
gst_message_new_segment_start (GST_OBJECT (sink),
- sink->segment.format, sink->segment.last_stop));
+ sink->segment.format, sink->segment.position));
}
}
sink->priv->discont = TRUE;
- sink->abidata.ABI.running = TRUE;
+ sink->running = TRUE;
GST_PAD_STREAM_UNLOCK (pad);
@@ -4037,7 +3938,7 @@ gst_base_sink_perform_step (GstBaseSink * sink, GstPad * pad, GstEvent * event)
if (bclass->unlock)
bclass->unlock (sink);
- GST_PAD_PREROLL_LOCK (sink->sinkpad);
+ GST_BASE_SINK_PREROLL_LOCK (sink);
/* now that we have the PREROLL lock, clear our unlock request */
if (bclass->unlock_stop)
bclass->unlock_stop (sink);
@@ -4052,7 +3953,7 @@ gst_base_sink_perform_step (GstBaseSink * sink, GstPad * pad, GstEvent * event)
sink->playing_async = TRUE;
priv->pending_step.need_preroll = TRUE;
sink->need_preroll = FALSE;
- gst_element_lost_state_full (GST_ELEMENT_CAST (sink), FALSE);
+ gst_element_lost_state (GST_ELEMENT_CAST (sink));
} else {
sink->priv->have_latency = TRUE;
sink->need_preroll = FALSE;
@@ -4071,9 +3972,9 @@ gst_base_sink_perform_step (GstBaseSink * sink, GstPad * pad, GstEvent * event)
if (sink->have_preroll) {
GST_DEBUG_OBJECT (sink, "signal waiter");
priv->step_unlock = TRUE;
- GST_PAD_PREROLL_SIGNAL (sink->sinkpad);
+ GST_BASE_SINK_PREROLL_SIGNAL (sink);
}
- GST_PAD_PREROLL_UNLOCK (sink->sinkpad);
+ GST_BASE_SINK_PREROLL_UNLOCK (sink);
} else {
/* update the stepinfo and make it valid */
set_step_info (sink, current, pending, seqnum, format, amount, rate, flush,
@@ -4101,7 +4002,7 @@ gst_base_sink_loop (GstPad * pad)
if ((blocksize = basesink->priv->blocksize) == 0)
blocksize = -1;
- offset = basesink->segment.last_stop;
+ offset = basesink->segment.position;
GST_DEBUG_OBJECT (basesink, "pulling %" G_GUINT64_FORMAT ", %u",
offset, blocksize);
@@ -4113,13 +4014,13 @@ gst_base_sink_loop (GstPad * pad)
if (G_UNLIKELY (buf == NULL))
goto no_buffer;
- offset += GST_BUFFER_SIZE (buf);
+ offset += gst_buffer_get_size (buf);
- gst_segment_set_last_stop (&basesink->segment, GST_FORMAT_BYTES, offset);
+ basesink->segment.position = offset;
- GST_PAD_PREROLL_LOCK (pad);
+ GST_BASE_SINK_PREROLL_LOCK (basesink);
result = gst_base_sink_chain_unlocked (basesink, pad, _PR_IS_BUFFER, buf);
- GST_PAD_PREROLL_UNLOCK (pad);
+ GST_BASE_SINK_PREROLL_UNLOCK (basesink);
if (G_UNLIKELY (result != GST_FLOW_OK))
goto paused;
@@ -4136,7 +4037,7 @@ paused:
if (basesink->segment.flags & GST_SEEK_FLAG_SEGMENT) {
gst_element_post_message (GST_ELEMENT_CAST (basesink),
gst_message_new_segment_done (GST_OBJECT_CAST (basesink),
- basesink->segment.format, basesink->segment.last_stop));
+ basesink->segment.format, basesink->segment.position));
} else {
gst_base_sink_event (pad, gst_event_new_eos ());
}
@@ -4179,7 +4080,7 @@ gst_base_sink_set_flushing (GstBaseSink * basesink, GstPad * pad,
bclass->unlock (basesink);
}
- GST_PAD_PREROLL_LOCK (pad);
+ GST_BASE_SINK_PREROLL_LOCK (basesink);
basesink->flushing = flushing;
if (flushing) {
/* step 1, now that we have the PREROLL lock, clear our unlock request */
@@ -4201,7 +4102,7 @@ gst_base_sink_set_flushing (GstBaseSink * basesink, GstPad * pad,
"flushing out data thread, need preroll to TRUE");
gst_base_sink_preroll_queue_flush (basesink, pad);
}
- GST_PAD_PREROLL_UNLOCK (pad);
+ GST_BASE_SINK_PREROLL_UNLOCK (basesink);
return TRUE;
}
@@ -4228,6 +4129,8 @@ gst_base_sink_pad_activate (GstPad * pad)
{
gboolean result = FALSE;
GstBaseSink *basesink;
+ GstQuery *query;
+ gboolean pull_mode;
basesink = GST_BASE_SINK (gst_pad_get_parent (pad));
@@ -4242,7 +4145,19 @@ gst_base_sink_pad_activate (GstPad * pad)
}
/* check if downstreams supports pull mode at all */
- if (!gst_pad_check_pull_range (pad)) {
+ query = gst_query_new_scheduling ();
+
+ if (!gst_pad_peer_query (pad, query)) {
+ gst_query_unref (query);
+ GST_DEBUG_OBJECT (basesink, "peer query faild, no pull mode");
+ goto fallback;
+ }
+
+ /* parse result of the query */
+ gst_query_parse_scheduling (query, &pull_mode, NULL, NULL, NULL, NULL, NULL);
+ gst_query_unref (query);
+
+ if (!pull_mode) {
GST_DEBUG_OBJECT (basesink, "pull mode not supported");
goto fallback;
}
@@ -4343,10 +4258,8 @@ gst_base_sink_negotiate_pull (GstBaseSink * basesink)
caps = gst_caps_make_writable (caps);
/* get the first (prefered) format */
gst_caps_truncate (caps);
- /* try to fixate */
- gst_pad_fixate_caps (GST_BASE_SINK_PAD (basesink), caps);
- GST_DEBUG_OBJECT (basesink, "fixated to: %" GST_PTR_FORMAT, caps);
+ GST_DEBUG_OBJECT (basesink, "have caps: %" GST_PTR_FORMAT, caps);
if (gst_caps_is_any (caps)) {
GST_DEBUG_OBJECT (basesink, "caps were ANY after fixating, "
@@ -4354,15 +4267,22 @@ gst_base_sink_negotiate_pull (GstBaseSink * basesink)
/* neither side has template caps in this case, so they are prepared for
pull() without setcaps() */
result = TRUE;
- } else if (gst_caps_is_fixed (caps)) {
- if (!gst_pad_set_caps (GST_BASE_SINK_PAD (basesink), caps))
- goto could_not_set_caps;
+ } else {
+ /* try to fixate */
+ gst_pad_fixate_caps (GST_BASE_SINK_PAD (basesink), caps);
+ GST_DEBUG_OBJECT (basesink, "fixated to: %" GST_PTR_FORMAT, caps);
- GST_OBJECT_LOCK (basesink);
- gst_caps_replace (&basesink->priv->pull_caps, caps);
- GST_OBJECT_UNLOCK (basesink);
+ if (gst_caps_is_fixed (caps)) {
+ if (!gst_pad_send_event (GST_BASE_SINK_PAD (basesink),
+ gst_event_new_caps (caps)))
+ goto could_not_set_caps;
- result = TRUE;
+ GST_OBJECT_LOCK (basesink);
+ gst_caps_replace (&basesink->priv->pull_caps, caps);
+ GST_OBJECT_UNLOCK (basesink);
+
+ result = TRUE;
+ }
}
gst_caps_unref (caps);
@@ -4406,7 +4326,7 @@ gst_base_sink_pad_activate_pull (GstPad * pad, gboolean active)
format = GST_FORMAT_BYTES;
gst_segment_init (&basesink->segment, format);
- gst_segment_init (basesink->abidata.ABI.clip_segment, format);
+ gst_segment_init (&basesink->clip_segment, format);
GST_OBJECT_LOCK (basesink);
basesink->have_newsegment = TRUE;
GST_OBJECT_UNLOCK (basesink);
@@ -4416,9 +4336,8 @@ gst_base_sink_pad_activate_pull (GstPad * pad, gboolean active)
if (result) {
GST_DEBUG_OBJECT (basesink,
"setting duration in bytes to %" G_GINT64_FORMAT, duration);
- gst_segment_set_duration (basesink->abidata.ABI.clip_segment, format,
- duration);
- gst_segment_set_duration (&basesink->segment, format, duration);
+ basesink->clip_segment.duration = duration;
+ basesink->segment.duration = duration;
} else {
GST_DEBUG_OBJECT (basesink, "unknown duration");
}
@@ -4537,8 +4456,8 @@ gst_base_sink_get_position (GstBaseSink * basesink, GstFormat format,
GstFormat oformat, tformat;
GstSegment *segment;
GstClockTime now, latency;
- GstClockTimeDiff base;
- gint64 time, accum, duration;
+ GstClockTimeDiff base_time;
+ gint64 time, base, duration;
gdouble rate;
gint64 last;
gboolean last_seen, with_clock, in_paused;
@@ -4561,7 +4480,7 @@ gst_base_sink_get_position (GstBaseSink * basesink, GstFormat format,
* main segment directly with the new segment values without it having to be
* activated by the rendering after preroll */
if (basesink->pad_mode == GST_ACTIVATE_PUSH)
- segment = basesink->abidata.ABI.clip_segment;
+ segment = &basesink->clip_segment;
else
segment = &basesink->segment;
@@ -4595,7 +4514,7 @@ gst_base_sink_get_position (GstBaseSink * basesink, GstFormat format,
else
duration = 0;
- accum = segment->accum;
+ base = segment->base;
rate = segment->rate * segment->applied_rate;
latency = basesink->priv->latency;
@@ -4620,28 +4539,28 @@ gst_base_sink_get_position (GstBaseSink * basesink, GstFormat format,
}
} else {
/* convert last stop to stream time */
- last = gst_segment_to_stream_time (segment, oformat, segment->last_stop);
+ last = gst_segment_to_stream_time (segment, oformat, segment->position);
}
if (in_paused) {
/* in paused, use start_time */
- base = GST_ELEMENT_START_TIME (basesink);
+ base_time = GST_ELEMENT_START_TIME (basesink);
GST_DEBUG_OBJECT (basesink, "in paused, using start time %" GST_TIME_FORMAT,
- GST_TIME_ARGS (base));
+ GST_TIME_ARGS (base_time));
} else if (with_clock) {
/* else use clock when needed */
- base = GST_ELEMENT_CAST (basesink)->base_time;
+ base_time = GST_ELEMENT_CAST (basesink)->base_time;
GST_DEBUG_OBJECT (basesink, "using clock and base time %" GST_TIME_FORMAT,
- GST_TIME_ARGS (base));
+ GST_TIME_ARGS (base_time));
} else {
/* else, no sync or clock -> no base time */
GST_DEBUG_OBJECT (basesink, "no sync or no clock");
- base = -1;
+ base_time = -1;
}
- /* no base, we can't calculate running_time, use last seem timestamp to report
+ /* no base_time, we can't calculate running_time, use last seem timestamp to report
* time */
- if (base == -1)
+ if (base_time == -1)
last_seen = TRUE;
/* need to release the object lock before we can get the time,
@@ -4664,9 +4583,9 @@ gst_base_sink_get_position (GstBaseSink * basesink, GstFormat format,
*cur = last;
} else {
if (oformat != tformat) {
- /* convert accum, time and duration to time */
- if (!gst_pad_query_convert (basesink->sinkpad, oformat, accum, &tformat,
- &accum))
+ /* convert base, time and duration to time */
+ if (!gst_pad_query_convert (basesink->sinkpad, oformat, base, &tformat,
+ &base))
goto convert_failed;
if (!gst_pad_query_convert (basesink->sinkpad, oformat, duration,
&tformat, &duration))
@@ -4685,25 +4604,25 @@ gst_base_sink_get_position (GstBaseSink * basesink, GstFormat format,
if (!in_paused && with_clock) {
now = gst_clock_get_time (clock);
} else {
- now = base;
- base = 0;
+ now = base_time;
+ base_time = 0;
}
- /* subtract base time and accumulated time from the clock time.
+ /* subtract base time and base time from the clock time.
* Make sure we don't go negative. This is the current time in
* the segment which we need to scale with the combined
* rate and applied rate. */
- base += accum;
- base += latency;
- if (GST_CLOCK_DIFF (base, now) < 0)
- base = now;
+ base_time += base;
+ base_time += latency;
+ if (GST_CLOCK_DIFF (base_time, now) < 0)
+ base_time = now;
/* for negative rates we need to count back from the segment
* duration. */
if (rate < 0.0)
time += duration;
- *cur = time + gst_guint64_to_gdouble (now - base) * rate;
+ *cur = time + gst_guint64_to_gdouble (now - base_time) * rate;
if (in_paused) {
/* never report less than segment values in paused */
@@ -4716,9 +4635,9 @@ gst_base_sink_get_position (GstBaseSink * basesink, GstFormat format,
}
GST_DEBUG_OBJECT (basesink,
- "now %" GST_TIME_FORMAT " - base %" GST_TIME_FORMAT " - accum %"
+ "now %" GST_TIME_FORMAT " - base_time %" GST_TIME_FORMAT " - base %"
GST_TIME_FORMAT " + time %" GST_TIME_FORMAT " last %" GST_TIME_FORMAT,
- GST_TIME_ARGS (now), GST_TIME_ARGS (base), GST_TIME_ARGS (accum),
+ GST_TIME_ARGS (now), GST_TIME_ARGS (base_time), GST_TIME_ARGS (base),
GST_TIME_ARGS (time), GST_TIME_ARGS (last));
}
@@ -4774,7 +4693,7 @@ gst_base_sink_get_duration (GstBaseSink * basesink, GstFormat format,
* should be done at a higher level. */
res = gst_pad_query_peer_duration (basesink->sinkpad, &uformat, &uduration);
if (res) {
- gst_segment_set_duration (&basesink->segment, uformat, uduration);
+ basesink->segment.duration = uduration;
if (format != uformat) {
/* convert to the requested format */
res = gst_pad_query_convert (basesink->sinkpad, uformat, uduration,
@@ -4952,17 +4871,17 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
case GST_STATE_CHANGE_READY_TO_PAUSED:
/* need to complete preroll before this state change completes, there
* is no data flow in READY so we can safely assume we need to preroll. */
- GST_PAD_PREROLL_LOCK (basesink->sinkpad);
+ GST_BASE_SINK_PREROLL_LOCK (basesink);
GST_DEBUG_OBJECT (basesink, "READY to PAUSED");
basesink->have_newsegment = FALSE;
gst_segment_init (&basesink->segment, GST_FORMAT_UNDEFINED);
- gst_segment_init (basesink->abidata.ABI.clip_segment,
- GST_FORMAT_UNDEFINED);
+ gst_segment_init (&basesink->clip_segment, GST_FORMAT_UNDEFINED);
basesink->offset = 0;
basesink->have_preroll = FALSE;
priv->step_unlock = FALSE;
basesink->need_preroll = TRUE;
basesink->playing_async = TRUE;
+ basesink->priv->reset_time = FALSE;
priv->current_sstart = GST_CLOCK_TIME_NONE;
priv->current_sstop = GST_CLOCK_TIME_NONE;
priv->eos_rtime = GST_CLOCK_TIME_NONE;
@@ -4980,14 +4899,14 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
* the state change function */
ret = GST_STATE_CHANGE_ASYNC;
gst_element_post_message (GST_ELEMENT_CAST (basesink),
- gst_message_new_async_start (GST_OBJECT_CAST (basesink), FALSE));
+ gst_message_new_async_start (GST_OBJECT_CAST (basesink)));
} else {
priv->have_latency = TRUE;
}
- GST_PAD_PREROLL_UNLOCK (basesink->sinkpad);
+ GST_BASE_SINK_PREROLL_UNLOCK (basesink);
break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
- GST_PAD_PREROLL_LOCK (basesink->sinkpad);
+ GST_BASE_SINK_PREROLL_LOCK (basesink);
if (!gst_base_sink_needs_preroll (basesink)) {
GST_DEBUG_OBJECT (basesink, "PAUSED to PLAYING, don't need preroll");
/* no preroll needed anymore now. */
@@ -5003,7 +4922,7 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
gst_element_post_message (GST_ELEMENT_CAST (basesink), message);
} else {
GST_DEBUG_OBJECT (basesink, "signal preroll");
- GST_PAD_PREROLL_SIGNAL (basesink->sinkpad);
+ GST_BASE_SINK_PREROLL_SIGNAL (basesink);
}
} else {
GST_DEBUG_OBJECT (basesink, "PAUSED to PLAYING, we are not prerolled");
@@ -5015,10 +4934,10 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
GST_DEBUG_OBJECT (basesink, "doing async state change");
ret = GST_STATE_CHANGE_ASYNC;
gst_element_post_message (GST_ELEMENT_CAST (basesink),
- gst_message_new_async_start (GST_OBJECT_CAST (basesink), FALSE));
+ gst_message_new_async_start (GST_OBJECT_CAST (basesink)));
}
}
- GST_PAD_PREROLL_UNLOCK (basesink->sinkpad);
+ GST_BASE_SINK_PREROLL_UNLOCK (basesink);
break;
default:
break;
@@ -5042,7 +4961,7 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
if (bclass->unlock)
bclass->unlock (basesink);
- GST_PAD_PREROLL_LOCK (basesink->sinkpad);
+ GST_BASE_SINK_PREROLL_LOCK (basesink);
GST_DEBUG_OBJECT (basesink, "got preroll lock");
/* now that we have the PREROLL lock, clear our unlock request */
if (bclass->unlock_stop)
@@ -5077,8 +4996,7 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
GST_DEBUG_OBJECT (basesink, "doing async state change");
ret = GST_STATE_CHANGE_ASYNC;
gst_element_post_message (GST_ELEMENT_CAST (basesink),
- gst_message_new_async_start (GST_OBJECT_CAST (basesink),
- FALSE));
+ gst_message_new_async_start (GST_OBJECT_CAST (basesink)));
}
}
}
@@ -5086,10 +5004,10 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
", dropped: %" G_GUINT64_FORMAT, priv->rendered, priv->dropped);
gst_base_sink_reset_qos (basesink);
- GST_PAD_PREROLL_UNLOCK (basesink->sinkpad);
+ GST_BASE_SINK_PREROLL_UNLOCK (basesink);
break;
case GST_STATE_CHANGE_PAUSED_TO_READY:
- GST_PAD_PREROLL_LOCK (basesink->sinkpad);
+ GST_BASE_SINK_PREROLL_LOCK (basesink);
/* start by reseting our position state with the object lock so that the
* position query gets the right idea. We do this before we post the
* messages so that the message handlers pick this up. */
@@ -5116,13 +5034,13 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
GST_STATE_PLAYING, GST_STATE_PAUSED, GST_STATE_READY));
gst_element_post_message (GST_ELEMENT_CAST (basesink),
- gst_message_new_async_done (GST_OBJECT_CAST (basesink)));
+ gst_message_new_async_done (GST_OBJECT_CAST (basesink), FALSE));
}
priv->commited = TRUE;
} else {
GST_DEBUG_OBJECT (basesink, "PAUSED to READY, don't need_preroll");
}
- GST_PAD_PREROLL_UNLOCK (basesink->sinkpad);
+ GST_BASE_SINK_PREROLL_UNLOCK (basesink);
break;
case GST_STATE_CHANGE_READY_TO_NULL:
if (bclass->stop) {
diff --git a/libs/gst/base/gstbasesink.h b/libs/gst/base/gstbasesink.h
index a4215b8de4..c651a44bac 100644
--- a/libs/gst/base/gstbasesink.h
+++ b/libs/gst/base/gstbasesink.h
@@ -44,6 +44,19 @@ G_BEGIN_DECLS
*/
#define GST_BASE_SINK_PAD(obj) (GST_BASE_SINK_CAST (obj)->sinkpad)
+#define GST_BASE_SINK_GET_PREROLL_LOCK(pad) (GST_BASE_SINK_CAST(pad)->preroll_lock)
+#define GST_BASE_SINK_PREROLL_LOCK(pad) (g_mutex_lock(GST_BASE_SINK_GET_PREROLL_LOCK(pad)))
+#define GST_BASE_SINK_PREROLL_TRYLOCK(pad) (g_mutex_trylock(GST_BASE_SINK_GET_PREROLL_LOCK(pad)))
+#define GST_BASE_SINK_PREROLL_UNLOCK(pad) (g_mutex_unlock(GST_BASE_SINK_GET_PREROLL_LOCK(pad)))
+
+#define GST_BASE_SINK_GET_PREROLL_COND(pad) (GST_BASE_SINK_CAST(pad)->preroll_cond)
+#define GST_BASE_SINK_PREROLL_WAIT(pad) \
+ g_cond_wait (GST_BASE_SINK_GET_PREROLL_COND (pad), GST_BASE_SINK_GET_PREROLL_LOCK (pad))
+#define GST_BASE_SINK_PREROLL_TIMED_WAIT(pad, timeval) \
+ g_cond_timed_wait (GST_BASE_SINK_GET_PREROLL_COND (pad), GST_BASE_SINK_GET_PREROLL_LOCK (pad), timeval)
+#define GST_BASE_SINK_PREROLL_SIGNAL(pad) g_cond_signal (GST_BASE_SINK_GET_PREROLL_COND (pad));
+#define GST_BASE_SINK_PREROLL_BROADCAST(pad) g_cond_broadcast (GST_BASE_SINK_GET_PREROLL_COND (pad));
+
typedef struct _GstBaseSink GstBaseSink;
typedef struct _GstBaseSinkClass GstBaseSinkClass;
typedef struct _GstBaseSinkPrivate GstBaseSinkPrivate;
@@ -66,6 +79,8 @@ struct _GstBaseSink {
gboolean can_activate_push;
/*< protected >*/ /* with PREROLL_LOCK */
+ GMutex *preroll_lock;
+ GCond *preroll_cond;
GQueue *preroll_queue;
gint preroll_queue_max_len; /* FIXME-0.11: the property is guint */
gint preroll_queued;
@@ -80,26 +95,21 @@ struct _GstBaseSink {
/*< protected >*/ /* with STREAM_LOCK */
gboolean have_newsegment;
GstSegment segment;
+ GstSegment clip_segment;
/*< private >*/ /* with LOCK */
GstClockID clock_id;
GstClockTime end_time;
gboolean sync;
gboolean flushing;
+ gboolean running;
- /*< private >*/
- union {
- struct {
- /* segment used for clipping incoming buffers */
- GstSegment *clip_segment;
- /* max amount of time a buffer can be late, -1 no limit. */
- gint64 max_lateness;
- gboolean running;
- } ABI;
- gpointer _gst_reserved[GST_PADDING_LARGE - 1];
- } abidata;
+ gint64 max_lateness;
+ /*< private >*/
GstBaseSinkPrivate *priv;
+
+ gpointer _gst_reserved[GST_PADDING_LARGE];
};
/**
@@ -107,7 +117,6 @@ struct _GstBaseSink {
* @parent_class: Element parent class
* @get_caps: Called to get sink pad caps from the subclass
* @set_caps: Notify subclass of changed caps
- * @buffer_alloc: Subclasses can override to perform custom buffer allocations
* @get_times: Called to get the start and end times for synchronising
* the passed buffer to the clock
* @start: Start processing. Ideal for opening resources in the subclass
@@ -122,9 +131,6 @@ struct _GstBaseSink {
* correct moment if the #GstBaseSink has been set to sync to the clock.
* @render_list: Same as @render but used whith buffer lists instead of
* buffers. Since: 0.10.24
- * @async_play: Subclasses should override this when they need to perform
- * special processing when changing to the PLAYING state asynchronously.
- * Called with the OBJECT_LOCK held.
* @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
@@ -142,13 +148,14 @@ struct _GstBaseSinkClass {
GstElementClass parent_class;
/* get caps from subclass */
- GstCaps* (*get_caps) (GstBaseSink *sink);
+ GstCaps* (*get_caps) (GstBaseSink *sink, GstCaps *filter);
/* notify subclass of new caps */
gboolean (*set_caps) (GstBaseSink *sink, GstCaps *caps);
- /* allocate a new buffer with given caps */
- GstFlowReturn (*buffer_alloc) (GstBaseSink *sink, guint64 offset, guint size,
- GstCaps *caps, GstBuffer **buf);
+ /* fixate sink caps during pull-mode negotiation */
+ void (*fixate) (GstBaseSink *sink, GstCaps *caps);
+ /* start or stop a pulling thread */
+ gboolean (*activate_pull)(GstBaseSink *sink, gboolean active);
/* get the start and end times for syncing on this buffer */
void (*get_times) (GstBaseSink *sink, GstBuffer *buffer,
@@ -161,33 +168,21 @@ struct _GstBaseSinkClass {
/* unlock any pending access to the resource. subclasses should unlock
* any function ASAP. */
gboolean (*unlock) (GstBaseSink *sink);
-
- /* notify subclass of event, preroll buffer or real buffer */
- gboolean (*event) (GstBaseSink *sink, GstEvent *event);
- GstFlowReturn (*preroll) (GstBaseSink *sink, GstBuffer *buffer);
- GstFlowReturn (*render) (GstBaseSink *sink, GstBuffer *buffer);
-
- /* ABI additions */
-
- /* when an ASYNC state change to PLAYING happens */ /* with LOCK */
- GstStateChangeReturn (*async_play) (GstBaseSink *sink);
-
- /* start or stop a pulling thread */
- gboolean (*activate_pull)(GstBaseSink *sink, gboolean active);
-
- /* fixate sink caps during pull-mode negotiation */
- void (*fixate) (GstBaseSink *sink, GstCaps *caps);
-
/* 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 event, preroll buffer or real buffer */
+ gboolean (*event) (GstBaseSink *sink, GstEvent *event);
+
+ 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-5];
+ gpointer _gst_reserved[GST_PADDING_LARGE];
};
GType gst_base_sink_get_type(void);
diff --git a/libs/gst/base/gstbasesrc.c b/libs/gst/base/gstbasesrc.c
index e2efcaa7bd..c40ae940dc 100644
--- a/libs/gst/base/gstbasesrc.c
+++ b/libs/gst/base/gstbasesrc.c
@@ -47,9 +47,6 @@
* </listitem>
* </itemizedlist>
*
- * Since 0.10.9, any #GstBaseSrc can enable pull based scheduling at any time
- * by overriding #GstBaseSrcClass.check_get_range() so that it returns %TRUE.
- *
* If all the conditions are met for operating in pull mode, #GstBaseSrc is
* automatically seekable in push mode as well. The following conditions must
* be met to make the element seekable in push mode when the format is not
@@ -150,9 +147,6 @@
* an EOS message to be posted on the pipeline's bus. Once this EOS message is
* received, it may safely shut down the entire pipeline.
*
- * The old behaviour for controlled shutdown introduced since GStreamer 0.10.3
- * is still available but deprecated as it is dangerous and less flexible.
- *
* Last reviewed on 2007-12-19 (0.10.16)
* </para>
* </refsect2>
@@ -212,15 +206,11 @@ enum
struct _GstBaseSrcPrivate
{
- gboolean last_sent_eos; /* last thing we did was send an EOS (we set this
- * to avoid the sending of two EOS in some cases) */
gboolean discont;
gboolean flushing;
- /* two segments to be sent in the streaming thread with STREAM_LOCK */
- GstEvent *close_segment;
- GstEvent *start_segment;
- gboolean newsegment_pending;
+ /* if segment should be sent */
+ gboolean segment_pending;
/* if EOS is pending (atomic) */
gint pending_eos;
@@ -248,11 +238,15 @@ struct _GstBaseSrcPrivate
gboolean qos_enabled;
gdouble proportion;
GstClockTime earliest_time;
+
+ GstBufferPool *pool;
+ const GstAllocator *allocator;
+ guint prefix;
+ guint alignment;
};
static GstElementClass *parent_class = NULL;
-static void gst_base_src_base_init (gpointer g_class);
static void gst_base_src_class_init (GstBaseSrcClass * klass);
static void gst_base_src_init (GstBaseSrc * src, gpointer g_class);
static void gst_base_src_finalize (GObject * object);
@@ -267,7 +261,7 @@ gst_base_src_get_type (void)
GType _type;
static const GTypeInfo base_src_info = {
sizeof (GstBaseSrcClass),
- (GBaseInitFunc) gst_base_src_base_init,
+ NULL,
NULL,
(GClassInitFunc) gst_base_src_class_init,
NULL,
@@ -284,10 +278,10 @@ gst_base_src_get_type (void)
return base_src_type;
}
-static GstCaps *gst_base_src_getcaps (GstPad * pad);
-static gboolean gst_base_src_setcaps (GstPad * pad, GstCaps * caps);
+static GstCaps *gst_base_src_getcaps (GstPad * pad, GstCaps * filter);
static void gst_base_src_fixate (GstPad * pad, GstCaps * caps);
+static gboolean gst_base_src_is_random_access (GstBaseSrc * src);
static gboolean gst_base_src_activate_push (GstPad * pad, gboolean active);
static gboolean gst_base_src_activate_pull (GstPad * pad, gboolean active);
static void gst_base_src_set_property (GObject * object, guint prop_id,
@@ -301,12 +295,16 @@ static const GstQueryType *gst_base_src_get_query_types (GstElement * element);
static gboolean gst_base_src_query (GstPad * pad, GstQuery * query);
+static gboolean gst_base_src_activate_pool (GstBaseSrc * basesrc,
+ gboolean active);
static gboolean gst_base_src_default_negotiate (GstBaseSrc * basesrc);
static gboolean gst_base_src_default_do_seek (GstBaseSrc * src,
GstSegment * segment);
static gboolean gst_base_src_default_query (GstBaseSrc * src, GstQuery * query);
static gboolean gst_base_src_default_prepare_seek_segment (GstBaseSrc * src,
GstEvent * event, GstSegment * segment);
+static GstFlowReturn gst_base_src_default_create (GstBaseSrc * basesrc,
+ guint64 offset, guint size, GstBuffer ** buf);
static gboolean gst_base_src_set_flushing (GstBaseSrc * basesrc,
gboolean flushing, gboolean live_play, gboolean unlock, gboolean * playing);
@@ -317,23 +315,16 @@ static GstStateChangeReturn gst_base_src_change_state (GstElement * element,
GstStateChange transition);
static void gst_base_src_loop (GstPad * pad);
-static gboolean gst_base_src_pad_check_get_range (GstPad * pad);
-static gboolean gst_base_src_default_check_get_range (GstBaseSrc * bsrc);
static GstFlowReturn gst_base_src_pad_get_range (GstPad * pad, guint64 offset,
guint length, GstBuffer ** buf);
static GstFlowReturn gst_base_src_get_range (GstBaseSrc * src, guint64 offset,
guint length, GstBuffer ** buf);
static gboolean gst_base_src_seekable (GstBaseSrc * src);
+static gboolean gst_base_src_negotiate (GstBaseSrc * basesrc);
static gboolean gst_base_src_update_length (GstBaseSrc * src, guint64 offset,
guint * length);
static void
-gst_base_src_base_init (gpointer g_class)
-{
- GST_DEBUG_CATEGORY_INIT (gst_base_src_debug, "basesrc", 0, "basesrc element");
-}
-
-static void
gst_base_src_class_init (GstBaseSrcClass * klass)
{
GObjectClass *gobject_class;
@@ -342,6 +333,8 @@ gst_base_src_class_init (GstBaseSrcClass * klass)
gobject_class = G_OBJECT_CLASS (klass);
gstelement_class = GST_ELEMENT_CLASS (klass);
+ GST_DEBUG_CATEGORY_INIT (gst_base_src_debug, "basesrc", 0, "basesrc element");
+
g_type_class_add_private (klass, sizeof (GstBaseSrcPrivate));
parent_class = g_type_class_peek_parent (klass);
@@ -350,10 +343,9 @@ gst_base_src_class_init (GstBaseSrcClass * klass)
gobject_class->set_property = gst_base_src_set_property;
gobject_class->get_property = gst_base_src_get_property;
-/* FIXME 0.11: blocksize property should be int, not ulong (min is >max here) */
g_object_class_install_property (gobject_class, PROP_BLOCKSIZE,
- g_param_spec_ulong ("blocksize", "Block size",
- "Size in bytes to read per buffer (-1 = default)", 0, G_MAXULONG,
+ g_param_spec_uint ("blocksize", "Block size",
+ "Size in bytes to read per buffer (-1 = default)", 0, G_MAXUINT,
DEFAULT_BLOCKSIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_NUM_BUFFERS,
g_param_spec_int ("num-buffers", "num-buffers",
@@ -379,10 +371,9 @@ gst_base_src_class_init (GstBaseSrcClass * klass)
klass->event = GST_DEBUG_FUNCPTR (gst_base_src_default_event);
klass->do_seek = GST_DEBUG_FUNCPTR (gst_base_src_default_do_seek);
klass->query = GST_DEBUG_FUNCPTR (gst_base_src_default_query);
- klass->check_get_range =
- GST_DEBUG_FUNCPTR (gst_base_src_default_check_get_range);
klass->prepare_seek_segment =
GST_DEBUG_FUNCPTR (gst_base_src_default_prepare_seek_segment);
+ klass->create = GST_DEBUG_FUNCPTR (gst_base_src_default_create);
/* Registering debug symbols for function pointers */
GST_DEBUG_REGISTER_FUNCPTR (gst_base_src_activate_push);
@@ -390,9 +381,7 @@ gst_base_src_class_init (GstBaseSrcClass * klass)
GST_DEBUG_REGISTER_FUNCPTR (gst_base_src_event_handler);
GST_DEBUG_REGISTER_FUNCPTR (gst_base_src_query);
GST_DEBUG_REGISTER_FUNCPTR (gst_base_src_pad_get_range);
- GST_DEBUG_REGISTER_FUNCPTR (gst_base_src_pad_check_get_range);
GST_DEBUG_REGISTER_FUNCPTR (gst_base_src_getcaps);
- GST_DEBUG_REGISTER_FUNCPTR (gst_base_src_setcaps);
GST_DEBUG_REGISTER_FUNCPTR (gst_base_src_fixate);
}
@@ -411,7 +400,6 @@ gst_base_src_init (GstBaseSrc * basesrc, gpointer g_class)
basesrc->num_buffers_left = -1;
basesrc->can_activate_push = TRUE;
- basesrc->pad_mode = GST_ACTIVATE_NONE;
pad_template =
gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src");
@@ -425,10 +413,8 @@ gst_base_src_init (GstBaseSrc * basesrc, gpointer g_class)
gst_pad_set_activatepull_function (pad, gst_base_src_activate_pull);
gst_pad_set_event_function (pad, gst_base_src_event_handler);
gst_pad_set_query_function (pad, gst_base_src_query);
- gst_pad_set_checkgetrange_function (pad, gst_base_src_pad_check_get_range);
gst_pad_set_getrange_function (pad, gst_base_src_pad_get_range);
gst_pad_set_getcaps_function (pad, gst_base_src_getcaps);
- gst_pad_set_setcaps_function (pad, gst_base_src_setcaps);
gst_pad_set_fixatecaps_function (pad, gst_base_src_fixate);
/* hold pointer to pad */
@@ -440,7 +426,7 @@ gst_base_src_init (GstBaseSrc * basesrc, gpointer g_class)
basesrc->clock_id = NULL;
/* we operate in BYTES by default */
gst_base_src_set_format (basesrc, GST_FORMAT_BYTES);
- basesrc->data.ABI.typefind = DEFAULT_TYPEFIND;
+ basesrc->typefind = DEFAULT_TYPEFIND;
basesrc->priv->do_timestamp = DEFAULT_DO_TIMESTAMP;
g_atomic_int_set (&basesrc->priv->have_events, FALSE);
@@ -461,7 +447,7 @@ gst_base_src_finalize (GObject * object)
g_mutex_free (basesrc->live_lock);
g_cond_free (basesrc->live_cond);
- event_p = &basesrc->data.ABI.pending_seek;
+ event_p = &basesrc->pending_seek;
gst_event_replace (event_p, NULL);
if (basesrc->priv->pending_events) {
@@ -667,9 +653,8 @@ gst_base_src_query_latency (GstBaseSrc * src, gboolean * live,
*
* Since: 0.10.22
*/
-/* FIXME 0.11: blocksize property should be int, not ulong */
void
-gst_base_src_set_blocksize (GstBaseSrc * src, gulong blocksize)
+gst_base_src_set_blocksize (GstBaseSrc * src, guint blocksize)
{
g_return_if_fail (GST_IS_BASE_SRC (src));
@@ -688,11 +673,10 @@ gst_base_src_set_blocksize (GstBaseSrc * src, gulong blocksize)
*
* Since: 0.10.22
*/
-/* FIXME 0.11: blocksize property should be int, not ulong */
-gulong
+guint
gst_base_src_get_blocksize (GstBaseSrc * src)
{
- gulong res;
+ gint res;
g_return_val_if_fail (GST_IS_BASE_SRC (src), 0);
@@ -779,51 +763,33 @@ gst_base_src_new_seamless_segment (GstBaseSrc * src, gint64 start, gint64 stop,
GST_TIME_ARGS (stop), GST_TIME_ARGS (position));
GST_OBJECT_LOCK (src);
- if (src->data.ABI.running && !src->priv->newsegment_pending) {
- if (src->priv->close_segment)
- gst_event_unref (src->priv->close_segment);
- src->priv->close_segment =
- gst_event_new_new_segment_full (TRUE,
- src->segment.rate, src->segment.applied_rate, src->segment.format,
- src->segment.start, src->segment.last_stop, src->segment.time);
- }
-
- gst_segment_set_newsegment_full (&src->segment, FALSE, src->segment.rate,
- src->segment.applied_rate, src->segment.format, start, stop, position);
-
- if (src->priv->start_segment)
- gst_event_unref (src->priv->start_segment);
- if (src->segment.rate >= 0.0) {
- /* forward, we send data from last_stop to stop */
- src->priv->start_segment =
- gst_event_new_new_segment_full (FALSE,
- src->segment.rate, src->segment.applied_rate, src->segment.format,
- src->segment.last_stop, stop, src->segment.time);
- } else {
- /* reverse, we send data from last_stop to start */
- src->priv->start_segment =
- gst_event_new_new_segment_full (FALSE,
- src->segment.rate, src->segment.applied_rate, src->segment.format,
- src->segment.start, src->segment.last_stop, src->segment.time);
- }
+
+ src->segment.base = gst_segment_to_running_time (&src->segment,
+ src->segment.format, src->segment.position);
+ src->segment.start = start;
+ src->segment.stop = stop;
+ src->segment.position = position;
+
+ /* forward, we send data from position to stop */
+ src->priv->segment_pending = TRUE;
GST_OBJECT_UNLOCK (src);
src->priv->discont = TRUE;
- src->data.ABI.running = TRUE;
+ src->running = TRUE;
return res;
}
static gboolean
-gst_base_src_setcaps (GstPad * pad, GstCaps * caps)
+gst_base_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps)
{
GstBaseSrcClass *bclass;
- GstBaseSrc *bsrc;
gboolean res = TRUE;
- bsrc = GST_BASE_SRC (GST_PAD_PARENT (pad));
bclass = GST_BASE_SRC_GET_CLASS (bsrc);
+ gst_pad_push_event (bsrc->srcpad, gst_event_new_caps (caps));
+
if (bclass->set_caps)
res = bclass->set_caps (bsrc, caps);
@@ -831,7 +797,7 @@ gst_base_src_setcaps (GstPad * pad, GstCaps * caps)
}
static GstCaps *
-gst_base_src_getcaps (GstPad * pad)
+gst_base_src_getcaps (GstPad * pad, GstCaps * filter)
{
GstBaseSrcClass *bclass;
GstBaseSrc *bsrc;
@@ -840,7 +806,7 @@ gst_base_src_getcaps (GstPad * pad)
bsrc = GST_BASE_SRC (GST_PAD_PARENT (pad));
bclass = GST_BASE_SRC_GET_CLASS (bsrc);
if (bclass->get_caps)
- caps = bclass->get_caps (bsrc);
+ caps = bclass->get_caps (bsrc, filter);
if (caps == NULL) {
GstPadTemplate *pad_template;
@@ -848,7 +814,16 @@ gst_base_src_getcaps (GstPad * pad)
pad_template =
gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass), "src");
if (pad_template != NULL) {
- caps = gst_caps_ref (gst_pad_template_get_caps (pad_template));
+ caps = gst_pad_template_get_caps (pad_template);
+
+ if (filter) {
+ GstCaps *intersection;
+
+ intersection =
+ gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+ gst_caps_unref (caps);
+ caps = intersection;
+ }
}
}
return caps;
@@ -892,7 +867,7 @@ gst_base_src_default_query (GstBaseSrc * src, GstQuery * query)
gint64 duration;
GST_OBJECT_LOCK (src);
- position = src->segment.last_stop;
+ position = src->segment.position;
duration = src->segment.duration;
GST_OBJECT_UNLOCK (src);
@@ -917,7 +892,7 @@ gst_base_src_default_query (GstBaseSrc * src, GstQuery * query)
GST_OBJECT_LOCK (src);
position =
gst_segment_to_stream_time (&src->segment, src->segment.format,
- src->segment.last_stop);
+ src->segment.position);
seg_format = src->segment.format;
GST_OBJECT_UNLOCK (src);
@@ -1122,6 +1097,20 @@ gst_base_src_default_query (GstBaseSrc * src, GstQuery * query)
gst_query_set_buffering_range (query, format, start, stop, estimated);
break;
}
+ case GST_QUERY_SCHEDULING:
+ {
+ gboolean random_access;
+
+ random_access = gst_base_src_is_random_access (src);
+
+ /* we can operate in getrange mode if the native format is bytes
+ * and we are seekable, this condition is set in the random_access
+ * flag and is set in the _start() method. */
+ gst_query_set_scheduling (query, random_access, TRUE, FALSE, 1, -1, 1);
+
+ res = TRUE;
+ break;
+ }
default:
res = FALSE;
break;
@@ -1213,7 +1202,7 @@ gst_base_src_default_prepare_seek_segment (GstBaseSrc * src, GstEvent * event,
dest_format = segment->format;
if (seek_format == dest_format) {
- gst_segment_set_seek (segment, rate, seek_format, flags,
+ gst_segment_do_seek (segment, rate, seek_format, flags,
cur_type, cur, stop_type, stop, &update);
return TRUE;
}
@@ -1235,7 +1224,7 @@ gst_base_src_default_prepare_seek_segment (GstBaseSrc * src, GstEvent * event,
}
/* And finally, configure our output segment in the desired format */
- gst_segment_set_seek (segment, rate, dest_format, flags, cur_type, cur,
+ gst_segment_do_seek (segment, rate, dest_format, flags, cur_type, cur,
stop_type, stop, &update);
if (!res)
@@ -1265,6 +1254,77 @@ gst_base_src_prepare_seek_segment (GstBaseSrc * src, GstEvent * event,
return result;
}
+static GstFlowReturn
+gst_base_src_alloc_buffer (GstBaseSrc * src, guint64 offset,
+ guint size, GstBuffer ** buffer)
+{
+ GstFlowReturn ret;
+ GstBaseSrcPrivate *priv = src->priv;
+
+ if (priv->pool) {
+ ret = gst_buffer_pool_acquire_buffer (priv->pool, buffer, NULL);
+ } else {
+ *buffer = gst_buffer_new_allocate (priv->allocator, size, priv->alignment);
+ if (G_UNLIKELY (*buffer == NULL))
+ goto alloc_failed;
+
+ ret = GST_FLOW_OK;
+ }
+ return ret;
+
+ /* ERRORS */
+alloc_failed:
+ {
+ GST_ERROR_OBJECT (src, "Failed to allocate %u bytes", size);
+ return GST_FLOW_ERROR;
+ }
+}
+
+static GstFlowReturn
+gst_base_src_default_create (GstBaseSrc * src, guint64 offset,
+ guint size, GstBuffer ** buffer)
+{
+ GstBaseSrcClass *bclass;
+ GstFlowReturn ret;
+
+ bclass = GST_BASE_SRC_GET_CLASS (src);
+
+ if (G_UNLIKELY (!bclass->fill))
+ goto no_function;
+
+ ret = gst_base_src_alloc_buffer (src, offset, size, buffer);
+ if (G_UNLIKELY (ret != GST_FLOW_OK))
+ goto alloc_failed;
+
+ if (G_LIKELY (size > 0)) {
+ /* only call fill when there is a size */
+ ret = bclass->fill (src, offset, size, *buffer);
+ if (G_UNLIKELY (ret != GST_FLOW_OK))
+ goto not_ok;
+ }
+
+ return GST_FLOW_OK;
+
+ /* ERRORS */
+no_function:
+ {
+ GST_DEBUG_OBJECT (src, "no fill function");
+ return GST_FLOW_NOT_SUPPORTED;
+ }
+alloc_failed:
+ {
+ GST_ERROR_OBJECT (src, "Failed to allocate %u bytes", size);
+ return ret;
+ }
+not_ok:
+ {
+ GST_DEBUG_OBJECT (src, "fill returned %d (%s)", ret,
+ gst_flow_get_name (ret));
+ gst_buffer_unref (*buffer);
+ return ret;
+ }
+}
+
/* this code implements the seeking. It is a good example
* handling all cases.
*
@@ -1416,7 +1476,7 @@ gst_base_src_perform_seek (GstBaseSrc * src, GstEvent * event, gboolean unlock)
} else {
/* The seek format matches our processing format, no need to ask the
* the subclass to configure the segment. */
- gst_segment_set_seek (&seeksegment, rate, seek_format, flags,
+ gst_segment_do_seek (&seeksegment, rate, seek_format, flags,
cur_type, cur, stop_type, stop, &update);
}
}
@@ -1427,33 +1487,19 @@ gst_base_src_perform_seek (GstBaseSrc * src, GstEvent * event, gboolean unlock)
if (res) {
GST_DEBUG_OBJECT (src, "segment configured from %" G_GINT64_FORMAT
" to %" G_GINT64_FORMAT ", position %" G_GINT64_FORMAT,
- seeksegment.start, seeksegment.stop, seeksegment.last_stop);
+ seeksegment.start, seeksegment.stop, seeksegment.position);
- /* do the seek, segment.last_stop contains the new position. */
+ /* do the seek, segment.position contains the new position. */
res = gst_base_src_do_seek (src, &seeksegment);
}
/* and prepare to continue streaming */
if (flush) {
- tevent = gst_event_new_flush_stop ();
+ tevent = gst_event_new_flush_stop (TRUE);
gst_event_set_seqnum (tevent, seqnum);
/* send flush stop, peer will accept data and events again. We
* are not yet providing data as we still have the STREAM_LOCK. */
gst_pad_push_event (src->srcpad, tevent);
- } else if (res && src->data.ABI.running) {
- /* we are running the current segment and doing a non-flushing seek,
- * close the segment first based on the last_stop. */
- GST_DEBUG_OBJECT (src, "closing running segment %" G_GINT64_FORMAT
- " to %" G_GINT64_FORMAT, src->segment.start, src->segment.last_stop);
-
- /* queue the segment for sending in the stream thread */
- if (src->priv->close_segment)
- gst_event_unref (src->priv->close_segment);
- src->priv->close_segment =
- gst_event_new_new_segment_full (TRUE,
- src->segment.rate, src->segment.applied_rate, src->segment.format,
- src->segment.start, src->segment.last_stop, src->segment.time);
- gst_event_set_seqnum (src->priv->close_segment, seqnum);
}
/* The subclass must have converted the segment to the processing format
@@ -1475,7 +1521,7 @@ gst_base_src_perform_seek (GstBaseSrc * src, GstEvent * event, gboolean unlock)
GstMessage *message;
message = gst_message_new_segment_start (GST_OBJECT (src),
- seeksegment.format, seeksegment.last_stop);
+ seeksegment.format, seeksegment.position);
gst_message_set_seqnum (message, seqnum);
gst_element_post_message (GST_ELEMENT (src), message);
@@ -1486,32 +1532,11 @@ gst_base_src_perform_seek (GstBaseSrc * src, GstEvent * event, gboolean unlock)
if ((stop = seeksegment.stop) == -1)
stop = seeksegment.duration;
- GST_DEBUG_OBJECT (src, "Sending newsegment from %" G_GINT64_FORMAT
- " to %" G_GINT64_FORMAT, seeksegment.start, stop);
-
- /* now replace the old segment so that we send it in the stream thread the
- * next time it is scheduled. */
- if (src->priv->start_segment)
- gst_event_unref (src->priv->start_segment);
- if (seeksegment.rate >= 0.0) {
- /* forward, we send data from last_stop to stop */
- src->priv->start_segment =
- gst_event_new_new_segment_full (FALSE,
- seeksegment.rate, seeksegment.applied_rate, seeksegment.format,
- seeksegment.last_stop, stop, seeksegment.time);
- } else {
- /* reverse, we send data from last_stop to start */
- src->priv->start_segment =
- gst_event_new_new_segment_full (FALSE,
- seeksegment.rate, seeksegment.applied_rate, seeksegment.format,
- seeksegment.start, seeksegment.last_stop, seeksegment.time);
- }
- gst_event_set_seqnum (src->priv->start_segment, seqnum);
- src->priv->newsegment_pending = TRUE;
+ src->priv->segment_pending = TRUE;
}
src->priv->discont = TRUE;
- src->data.ABI.running = TRUE;
+ src->running = TRUE;
/* and restart the task in case it got paused explicitly or by
* the FLUSH_START event we pushed out. */
tres = gst_pad_start_task (src->srcpad, (GstTaskFunction) gst_base_src_loop,
@@ -1593,10 +1618,12 @@ gst_base_src_send_event (GstElement * element, GstEvent * event)
g_atomic_int_set (&src->priv->pending_eos, TRUE);
GST_DEBUG_OBJECT (src, "EOS marked, calling unlock");
+
/* unlock the _create function so that we can check the pending_eos flag
* and we can do EOS. This will eventually release the LIVE_LOCK again so
* that we can grab it and stop the unlock again. We don't take the stream
* lock so that this operation is guaranteed to never block. */
+ gst_base_src_activate_pool (src, FALSE);
if (bclass->unlock)
bclass->unlock (src);
@@ -1608,13 +1635,14 @@ gst_base_src_send_event (GstElement * element, GstEvent * event)
* lock is enough because that protects the create function. */
if (bclass->unlock_stop)
bclass->unlock_stop (src);
+ gst_base_src_activate_pool (src, TRUE);
GST_LIVE_UNLOCK (src);
result = TRUE;
break;
}
- case GST_EVENT_NEWSEGMENT:
- /* sending random NEWSEGMENT downstream can break sync. */
+ case GST_EVENT_SEGMENT:
+ /* sending random SEGMENT downstream can break sync. */
break;
case GST_EVENT_TAG:
case GST_EVENT_CUSTOM_DOWNSTREAM:
@@ -1658,7 +1686,7 @@ gst_base_src_send_event (GstElement * element, GstEvent * event)
* get activated */
GST_OBJECT_LOCK (src);
GST_DEBUG_OBJECT (src, "queueing seek");
- event_p = &src->data.ABI.pending_seek;
+ event_p = &src->pending_seek;
gst_event_replace ((GstEvent **) event_p, event);
GST_OBJECT_UNLOCK (src);
/* assume the seek will work */
@@ -1761,7 +1789,7 @@ gst_base_src_default_event (GstBaseSrc * src, GstEvent * event)
GstClockTimeDiff diff;
GstClockTime timestamp;
- gst_event_parse_qos (event, &proportion, &diff, &timestamp);
+ gst_event_parse_qos (event, NULL, &proportion, &diff, &timestamp);
gst_base_src_update_qos (src, proportion, diff, timestamp);
result = TRUE;
break;
@@ -1824,13 +1852,13 @@ gst_base_src_set_property (GObject * object, guint prop_id,
switch (prop_id) {
case PROP_BLOCKSIZE:
- gst_base_src_set_blocksize (src, g_value_get_ulong (value));
+ gst_base_src_set_blocksize (src, g_value_get_uint (value));
break;
case PROP_NUM_BUFFERS:
src->num_buffers = g_value_get_int (value);
break;
case PROP_TYPEFIND:
- src->data.ABI.typefind = g_value_get_boolean (value);
+ src->typefind = g_value_get_boolean (value);
break;
case PROP_DO_TIMESTAMP:
gst_base_src_set_do_timestamp (src, g_value_get_boolean (value));
@@ -1851,13 +1879,13 @@ gst_base_src_get_property (GObject * object, guint prop_id, GValue * value,
switch (prop_id) {
case PROP_BLOCKSIZE:
- g_value_set_ulong (value, gst_base_src_get_blocksize (src));
+ g_value_set_uint (value, gst_base_src_get_blocksize (src));
break;
case PROP_NUM_BUFFERS:
g_value_set_int (value, src->num_buffers);
break;
case PROP_TYPEFIND:
- g_value_set_boolean (value, src->data.ABI.typefind);
+ g_value_set_boolean (value, src->typefind);
break;
case PROP_DO_TIMESTAMP:
g_value_set_boolean (value, gst_base_src_get_do_timestamp (src));
@@ -2062,7 +2090,7 @@ gst_base_src_update_length (GstBaseSrc * src, guint64 offset, guint * length)
format = src->segment.format;
stop = src->segment.stop;
/* get total file size */
- size = (guint64) src->segment.duration;
+ size = src->segment.duration;
/* only operate if we are working with bytes */
if (format != GST_FORMAT_BYTES)
@@ -2111,10 +2139,10 @@ gst_base_src_update_length (GstBaseSrc * src, guint64 offset, guint * length)
}
}
- /* keep track of current position and update duration.
+ /* keep track of current duration.
* segment is in bytes, we checked that above. */
GST_OBJECT_LOCK (src);
- gst_segment_set_duration (&src->segment, GST_FORMAT_BYTES, size);
+ src->segment.duration = size;
GST_OBJECT_UNLOCK (src);
return TRUE;
@@ -2197,16 +2225,10 @@ again:
/* no timestamp set and we are at offset 0, we can timestamp with 0 */
if (offset == 0 && src->segment.time == 0
&& GST_BUFFER_TIMESTAMP (*buf) == -1 && !src->is_live) {
- *buf = gst_buffer_make_metadata_writable (*buf);
+ *buf = gst_buffer_make_writable (*buf);
GST_BUFFER_TIMESTAMP (*buf) = 0;
}
- /* set pad caps on the buffer if the buffer had no caps */
- if (GST_BUFFER_CAPS (*buf) == NULL) {
- *buf = gst_buffer_make_metadata_writable (*buf);
- gst_buffer_set_caps (*buf, GST_PAD_CAPS (src->srcpad));
- }
-
/* now sync before pushing the buffer */
status = gst_base_src_do_sync (src, *buf);
@@ -2276,7 +2298,7 @@ not_started:
no_function:
{
GST_DEBUG_OBJECT (src, "no create function");
- return GST_FLOW_ERROR;
+ return GST_FLOW_NOT_SUPPORTED;
}
unexpected_length:
{
@@ -2335,60 +2357,16 @@ flushing:
}
static gboolean
-gst_base_src_default_check_get_range (GstBaseSrc * src)
+gst_base_src_is_random_access (GstBaseSrc * src)
{
- gboolean res;
-
+ /* we need to start the basesrc to check random access */
if (!GST_OBJECT_FLAG_IS_SET (src, GST_BASE_SRC_STARTED)) {
GST_LOG_OBJECT (src, "doing start/stop to check get_range support");
if (G_LIKELY (gst_base_src_start (src)))
gst_base_src_stop (src);
}
- /* we can operate in getrange mode if the native format is bytes
- * and we are seekable, this condition is set in the random_access
- * flag and is set in the _start() method. */
- res = src->random_access;
-
- return res;
-}
-
-static gboolean
-gst_base_src_check_get_range (GstBaseSrc * src)
-{
- GstBaseSrcClass *bclass;
- gboolean res;
-
- bclass = GST_BASE_SRC_GET_CLASS (src);
-
- if (bclass->check_get_range == NULL)
- goto no_function;
-
- res = bclass->check_get_range (src);
- GST_LOG_OBJECT (src, "%s() returned %d",
- GST_DEBUG_FUNCPTR_NAME (bclass->check_get_range), (gint) res);
-
- return res;
-
- /* ERRORS */
-no_function:
- {
- GST_WARNING_OBJECT (src, "no check_get_range function set");
- return FALSE;
- }
-}
-
-static gboolean
-gst_base_src_pad_check_get_range (GstPad * pad)
-{
- GstBaseSrc *src;
- gboolean res;
-
- src = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
-
- res = gst_base_src_check_get_range (src);
-
- return res;
+ return src->random_access;
}
static void
@@ -2399,25 +2377,29 @@ gst_base_src_loop (GstPad * pad)
GstFlowReturn ret;
gint64 position;
gboolean eos;
- gulong blocksize;
+ guint blocksize;
GList *pending_events = NULL, *tmp;
eos = FALSE;
src = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
+ /* check if we need to renegotiate */
+ if (gst_pad_check_reconfigure (pad)) {
+ if (!gst_base_src_negotiate (src))
+ GST_DEBUG_OBJECT (src, "Failed to renegotiate");
+ }
+
GST_LIVE_LOCK (src);
if (G_UNLIKELY (src->priv->flushing))
goto flushing;
- src->priv->last_sent_eos = FALSE;
-
blocksize = src->blocksize;
/* if we operate in bytes, we can calculate an offset */
if (src->segment.format == GST_FORMAT_BYTES) {
- position = src->segment.last_stop;
+ position = src->segment.position;
/* for negative rates, start with subtracting the blocksize */
if (src->segment.rate < 0.0) {
/* we cannot go below segment.start */
@@ -2432,7 +2414,7 @@ gst_base_src_loop (GstPad * pad)
} else
position = -1;
- GST_LOG_OBJECT (src, "next_ts %" GST_TIME_FORMAT " size %lu",
+ GST_LOG_OBJECT (src, "next_ts %" GST_TIME_FORMAT " size %u",
GST_TIME_ARGS (position), blocksize);
ret = gst_base_src_get_range (src, position, blocksize, &buf);
@@ -2447,15 +2429,10 @@ gst_base_src_loop (GstPad * pad)
goto null_buffer;
/* push events to close/start our segment before we push the buffer. */
- if (G_UNLIKELY (src->priv->close_segment)) {
- gst_pad_push_event (pad, src->priv->close_segment);
- src->priv->close_segment = NULL;
- }
- if (G_UNLIKELY (src->priv->start_segment)) {
- gst_pad_push_event (pad, src->priv->start_segment);
- src->priv->start_segment = NULL;
+ if (G_UNLIKELY (src->priv->segment_pending)) {
+ gst_pad_push_event (pad, gst_event_new_segment (&src->segment));
+ src->priv->segment_pending = FALSE;
}
- src->priv->newsegment_pending = FALSE;
if (g_atomic_int_get (&src->priv->have_events)) {
GST_OBJECT_LOCK (src);
@@ -2479,7 +2456,7 @@ gst_base_src_loop (GstPad * pad)
switch (src->segment.format) {
case GST_FORMAT_BYTES:
{
- guint bufsize = GST_BUFFER_SIZE (buf);
+ guint bufsize = gst_buffer_get_size (buf);
/* we subtracted above for negative rates */
if (src->segment.rate >= 0.0)
@@ -2496,7 +2473,7 @@ gst_base_src_loop (GstPad * pad)
if (GST_CLOCK_TIME_IS_VALID (start))
position = start;
else
- position = src->segment.last_stop;
+ position = src->segment.position;
if (GST_CLOCK_TIME_IS_VALID (duration)) {
if (src->segment.rate >= 0.0)
@@ -2538,12 +2515,12 @@ gst_base_src_loop (GstPad * pad)
src->priv->discont = TRUE;
}
GST_OBJECT_LOCK (src);
- gst_segment_set_last_stop (&src->segment, src->segment.format, position);
+ src->segment.position = position;
GST_OBJECT_UNLOCK (src);
}
if (G_UNLIKELY (src->priv->discont)) {
- buf = gst_buffer_make_metadata_writable (buf);
+ buf = gst_buffer_make_writable (buf);
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
src->priv->discont = FALSE;
}
@@ -2579,30 +2556,29 @@ pause:
GstEvent *event;
GST_DEBUG_OBJECT (src, "pausing task, reason %s", reason);
- src->data.ABI.running = FALSE;
+ src->running = FALSE;
gst_pad_pause_task (pad);
if (ret == GST_FLOW_UNEXPECTED) {
gboolean flag_segment;
GstFormat format;
- gint64 last_stop;
+ gint64 position;
/* perform EOS logic */
flag_segment = (src->segment.flags & GST_SEEK_FLAG_SEGMENT) != 0;
format = src->segment.format;
- last_stop = src->segment.last_stop;
+ position = src->segment.position;
if (flag_segment) {
GstMessage *message;
message = gst_message_new_segment_done (GST_OBJECT_CAST (src),
- format, last_stop);
+ format, position);
gst_message_set_seqnum (message, src->priv->seqnum);
gst_element_post_message (GST_ELEMENT_CAST (src), message);
} else {
event = gst_event_new_eos ();
gst_event_set_seqnum (event, src->priv->seqnum);
gst_pad_push_event (pad, event);
- src->priv->last_sent_eos = TRUE;
}
} else if (ret == GST_FLOW_NOT_LINKED || ret <= GST_FLOW_UNEXPECTED) {
event = gst_event_new_eos ();
@@ -2617,7 +2593,6 @@ pause:
(_("Internal data flow error.")),
("streaming task paused, reason %s (%d)", reason, ret));
gst_pad_push_event (pad, event);
- src->priv->last_sent_eos = TRUE;
}
goto done;
}
@@ -2630,6 +2605,119 @@ null_buffer:
}
}
+static gboolean
+gst_base_src_set_allocation (GstBaseSrc * basesrc, GstBufferPool * pool,
+ const GstAllocator * allocator, guint prefix, guint alignment)
+{
+ GstBufferPool *oldpool;
+ GstBaseSrcPrivate *priv = basesrc->priv;
+
+ if (pool) {
+ if (!gst_buffer_pool_set_active (pool, TRUE))
+ goto activate_failed;
+ }
+
+ GST_OBJECT_LOCK (basesrc);
+ oldpool = priv->pool;
+ priv->pool = pool;
+
+ priv->allocator = allocator;
+
+ priv->prefix = prefix;
+ priv->alignment = alignment;
+ GST_OBJECT_UNLOCK (basesrc);
+
+ if (oldpool) {
+ gst_buffer_pool_set_active (oldpool, FALSE);
+ gst_object_unref (oldpool);
+ }
+ return TRUE;
+
+ /* ERRORS */
+activate_failed:
+ {
+ GST_ERROR_OBJECT (basesrc, "failed to activate bufferpool.");
+ return FALSE;
+ }
+}
+
+static gboolean
+gst_base_src_activate_pool (GstBaseSrc * basesrc, gboolean active)
+{
+ GstBaseSrcPrivate *priv = basesrc->priv;
+ GstBufferPool *pool;
+ gboolean res = TRUE;
+
+ GST_OBJECT_LOCK (basesrc);
+ if ((pool = priv->pool))
+ pool = gst_object_ref (pool);
+ GST_OBJECT_UNLOCK (basesrc);
+
+ if (pool) {
+ res = gst_buffer_pool_set_active (pool, active);
+ gst_object_unref (pool);
+ }
+ return res;
+}
+
+static gboolean
+gst_base_src_prepare_allocation (GstBaseSrc * basesrc, GstCaps * caps)
+{
+ GstBaseSrcClass *bclass;
+ gboolean result = TRUE;
+ GstQuery *query;
+ GstBufferPool *pool = NULL;
+ const GstAllocator *allocator = NULL;
+ guint size, min, max, prefix, alignment;
+
+ bclass = GST_BASE_SRC_GET_CLASS (basesrc);
+
+ /* make query and let peer pad answer, we don't really care if it worked or
+ * not, if it failed, the allocation query would contain defaults and the
+ * subclass would then set better values if needed */
+ query = gst_query_new_allocation (caps, TRUE);
+ if (!gst_pad_peer_query (basesrc->srcpad, query)) {
+ /* not a problem, just debug a little */
+ GST_DEBUG_OBJECT (basesrc, "peer ALLOCATION query failed");
+ }
+
+ if (G_LIKELY (bclass->setup_allocation))
+ result = bclass->setup_allocation (basesrc, query);
+
+ GST_DEBUG_OBJECT (basesrc, "ALLOCATION params: %" GST_PTR_FORMAT, query);
+ gst_query_parse_allocation_params (query, &size, &min, &max, &prefix,
+ &alignment, &pool);
+
+ if (size == 0) {
+ const gchar *mem = NULL;
+
+ /* no size, we have variable size buffers */
+ if (gst_query_get_n_allocation_memories (query) > 0) {
+ mem = gst_query_parse_nth_allocation_memory (query, 0);
+ }
+ allocator = gst_allocator_find (mem);
+ } else if (pool == NULL) {
+ /* fixed size, we can use a bufferpool */
+ GstStructure *config;
+
+ /* we did not get a pool, make one ourselves then */
+ pool = gst_buffer_pool_new ();
+
+ config = gst_buffer_pool_get_config (pool);
+ gst_buffer_pool_config_set (config, caps, size, min, max, prefix,
+ alignment);
+ gst_buffer_pool_set_config (pool, config);
+ }
+
+ gst_query_unref (query);
+
+ result =
+ gst_base_src_set_allocation (basesrc, pool, allocator, prefix, alignment);
+
+ return result;
+
+}
+
/* default negotiation code.
*
* Take intersection between src and sink pads, take first
@@ -2644,7 +2732,7 @@ gst_base_src_default_negotiate (GstBaseSrc * basesrc)
gboolean result = FALSE;
/* first see what is possible on our source pad */
- thiscaps = gst_pad_get_caps_reffed (GST_BASE_SRC_PAD (basesrc));
+ thiscaps = gst_pad_get_caps (GST_BASE_SRC_PAD (basesrc), NULL);
GST_DEBUG_OBJECT (basesrc, "caps of src: %" GST_PTR_FORMAT, thiscaps);
/* nothing or anything is allowed, we're done */
if (thiscaps == NULL || gst_caps_is_any (thiscaps))
@@ -2654,36 +2742,35 @@ gst_base_src_default_negotiate (GstBaseSrc * basesrc)
goto no_caps;
/* get the peer caps */
- peercaps = gst_pad_peer_get_caps_reffed (GST_BASE_SRC_PAD (basesrc));
+ peercaps = gst_pad_peer_get_caps (GST_BASE_SRC_PAD (basesrc), thiscaps);
GST_DEBUG_OBJECT (basesrc, "caps of peer: %" GST_PTR_FORMAT, peercaps);
if (peercaps) {
- /* get intersection */
- caps =
- gst_caps_intersect_full (peercaps, thiscaps, GST_CAPS_INTERSECT_FIRST);
- GST_DEBUG_OBJECT (basesrc, "intersect: %" GST_PTR_FORMAT, caps);
- gst_caps_unref (peercaps);
+ /* The result is already a subset of our caps */
+ caps = peercaps;
+ gst_caps_unref (thiscaps);
} else {
/* no peer, work with our own caps then */
- caps = gst_caps_copy (thiscaps);
+ caps = thiscaps;
}
- gst_caps_unref (thiscaps);
- if (caps) {
+ if (caps && !gst_caps_is_empty (caps)) {
+ caps = gst_caps_make_writable (caps);
+
/* take first (and best, since they are sorted) possibility */
gst_caps_truncate (caps);
/* now fixate */
- if (!gst_caps_is_empty (caps)) {
+ GST_DEBUG_OBJECT (basesrc, "have caps: %" GST_PTR_FORMAT, caps);
+ if (gst_caps_is_any (caps)) {
+ /* hmm, still anything, so element can do anything and
+ * nego is not needed */
+ result = TRUE;
+ } else {
gst_pad_fixate_caps (GST_BASE_SRC_PAD (basesrc), caps);
GST_DEBUG_OBJECT (basesrc, "fixated to: %" GST_PTR_FORMAT, caps);
-
- if (gst_caps_is_any (caps)) {
- /* hmm, still anything, so element can do anything and
- * nego is not needed */
- result = TRUE;
- } else if (gst_caps_is_fixed (caps)) {
+ if (gst_caps_is_fixed (caps)) {
/* yay, fixed caps, use those then, it's possible that the subclass does
* not accept this caps after all and we have to fail. */
- result = gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), caps);
+ result = gst_base_src_setcaps (basesrc, caps);
}
}
gst_caps_unref (caps);
@@ -2718,9 +2805,16 @@ gst_base_src_negotiate (GstBaseSrc * basesrc)
bclass = GST_BASE_SRC_GET_CLASS (basesrc);
- if (bclass->negotiate)
+ if (G_LIKELY (bclass->negotiate))
result = bclass->negotiate (basesrc);
+ if (G_LIKELY (result)) {
+ GstCaps *caps;
+
+ caps = gst_pad_get_current_caps (basesrc->srcpad);
+
+ result = gst_base_src_prepare_allocation (basesrc, caps);
+ }
return result;
}
@@ -2744,8 +2838,8 @@ gst_base_src_start (GstBaseSrc * basesrc)
gst_segment_init (&basesrc->segment, basesrc->segment.format);
GST_OBJECT_UNLOCK (basesrc);
- basesrc->data.ABI.running = FALSE;
- basesrc->priv->newsegment_pending = FALSE;
+ basesrc->running = FALSE;
+ basesrc->priv->segment_pending = FALSE;
bclass = GST_BASE_SRC_GET_CLASS (basesrc);
if (bclass->start)
@@ -2773,7 +2867,7 @@ gst_base_src_start (GstBaseSrc * basesrc)
/* only update the size when operating in bytes, subclass is supposed
* to set duration in the start method for other formats */
GST_OBJECT_LOCK (basesrc);
- gst_segment_set_duration (&basesrc->segment, GST_FORMAT_BYTES, size);
+ basesrc->segment.duration = size;
GST_OBJECT_UNLOCK (basesrc);
} else {
size = -1;
@@ -2793,13 +2887,13 @@ gst_base_src_start (GstBaseSrc * basesrc)
GST_DEBUG_OBJECT (basesrc, "is random_access: %d", basesrc->random_access);
/* run typefind if we are random_access and the typefinding is enabled. */
- if (basesrc->random_access && basesrc->data.ABI.typefind && size != -1) {
+ if (basesrc->random_access && basesrc->typefind && size != -1) {
GstCaps *caps;
if (!(caps = gst_type_find_helper (basesrc->srcpad, size)))
goto typefind_failed;
- result = gst_pad_set_caps (basesrc->srcpad, caps);
+ result = gst_base_src_setcaps (basesrc, caps);
gst_caps_unref (caps);
} else {
/* use class or default negotiate function */
@@ -2850,6 +2944,8 @@ gst_base_src_stop (GstBaseSrc * basesrc)
if (bclass->stop)
result = bclass->stop (basesrc);
+ gst_base_src_set_allocation (basesrc, NULL, NULL, 0, 0);
+
if (result)
GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_STARTED);
@@ -2867,6 +2963,7 @@ gst_base_src_set_flushing (GstBaseSrc * basesrc,
bclass = GST_BASE_SRC_GET_CLASS (basesrc);
if (flushing && unlock) {
+ gst_base_src_activate_pool (basesrc, FALSE);
/* unlock any subclasses, we need to do this before grabbing the
* LIVE_LOCK since we hold this lock before going into ::create. We pass an
* unlock to the params because of backwards compat (see seek handler)*/
@@ -2898,6 +2995,8 @@ gst_base_src_set_flushing (GstBaseSrc * basesrc,
/* signal the live source that it can start playing */
basesrc->live_running = live_play;
+ gst_base_src_activate_pool (basesrc, TRUE);
+
/* When unlocking drop all delayed events */
if (unlock) {
GST_OBJECT_LOCK (basesrc);
@@ -2929,6 +3028,7 @@ gst_base_src_set_playing (GstBaseSrc * basesrc, gboolean live_play)
/* unlock subclasses locked in ::create, we only do this when we stop playing. */
if (!live_play) {
GST_DEBUG_OBJECT (basesrc, "unlock");
+ gst_base_src_activate_pool (basesrc, FALSE);
if (bclass->unlock)
bclass->unlock (basesrc);
}
@@ -2952,6 +3052,7 @@ gst_base_src_set_playing (GstBaseSrc * basesrc, gboolean live_play)
/* clear our unlock request when going to PLAYING */
GST_DEBUG_OBJECT (basesrc, "unlock stop");
+ gst_base_src_activate_pool (basesrc, TRUE);
if (bclass->unlock_stop)
bclass->unlock_stop (basesrc);
@@ -2991,14 +3092,13 @@ gst_base_src_activate_push (GstPad * pad, gboolean active)
if (G_UNLIKELY (!gst_base_src_start (basesrc)))
goto error_start;
- basesrc->priv->last_sent_eos = FALSE;
basesrc->priv->discont = TRUE;
gst_base_src_set_flushing (basesrc, FALSE, FALSE, FALSE, NULL);
/* do initial seek, which will start the task */
GST_OBJECT_LOCK (basesrc);
- event = basesrc->data.ABI.pending_seek;
- basesrc->data.ABI.pending_seek = NULL;
+ event = basesrc->pending_seek;
+ basesrc->pending_seek = NULL;
GST_OBJECT_UNLOCK (basesrc);
/* no need to unlock anything, the task is certainly
@@ -3066,7 +3166,7 @@ gst_base_src_activate_pull (GstPad * pad, gboolean active)
goto error_start;
/* if not random_access, we cannot operate in pull mode for now */
- if (G_UNLIKELY (!gst_base_src_check_get_range (basesrc)))
+ if (G_UNLIKELY (!gst_base_src_is_random_access (basesrc)))
goto no_get_range;
/* stop flushing now but for live sources, still block in the LIVE lock when
@@ -3077,9 +3177,6 @@ gst_base_src_activate_pull (GstPad * pad, gboolean active)
/* flush all, there is no task to stop */
gst_base_src_set_flushing (basesrc, TRUE, FALSE, TRUE, NULL);
- /* don't send EOS when going from PAUSED => READY when in pull mode */
- basesrc->priv->last_sent_eos = TRUE;
-
if (G_UNLIKELY (!gst_base_src_stop (basesrc)))
goto error_stop;
}
@@ -3146,27 +3243,12 @@ gst_base_src_change_state (GstElement * element, GstStateChange transition)
break;
case GST_STATE_CHANGE_PAUSED_TO_READY:
{
- GstEvent **event_p, *event;
+ GstEvent **event_p;
/* we don't need to unblock anything here, the pad deactivation code
* already did this */
-
- /* FIXME, deprecate this behaviour, it is very dangerous.
- * the prefered way of sending EOS downstream is by sending
- * the EOS event to the element */
- if (!basesrc->priv->last_sent_eos) {
- GST_DEBUG_OBJECT (basesrc, "Sending EOS event");
- event = gst_event_new_eos ();
- gst_event_set_seqnum (event, basesrc->priv->seqnum);
- gst_pad_push_event (basesrc->srcpad, event);
- basesrc->priv->last_sent_eos = TRUE;
- }
g_atomic_int_set (&basesrc->priv->pending_eos, FALSE);
- event_p = &basesrc->data.ABI.pending_seek;
- gst_event_replace (event_p, NULL);
- event_p = &basesrc->priv->close_segment;
- gst_event_replace (event_p, NULL);
- event_p = &basesrc->priv->start_segment;
+ event_p = &basesrc->pending_seek;
gst_event_replace (event_p, NULL);
break;
}
diff --git a/libs/gst/base/gstbasesrc.h b/libs/gst/base/gstbasesrc.h
index 87e1c06f41..529c79712f 100644
--- a/libs/gst/base/gstbasesrc.h
+++ b/libs/gst/base/gstbasesrc.h
@@ -81,47 +81,38 @@ struct _GstBaseSrc {
gboolean live_running;
/* MT-protected (with LOCK) */
- gint blocksize; /* size of buffers when operating push based */
+ guint blocksize; /* size of buffers when operating push based */
gboolean can_activate_push; /* some scheduling properties */
- GstActivateMode pad_mode;
- gboolean seekable; /* not used anymore */
gboolean random_access;
GstClockID clock_id; /* for syncing */
- GstClockTime end_time;
/* MT-protected (with STREAM_LOCK *and* OBJECT_LOCK) */
GstSegment segment;
/* MT-protected (with STREAM_LOCK) */
gboolean need_newsegment;
- guint64 offset; /* current offset in the resource, unused */
- guint64 size; /* total size of the resource, unused */
-
gint num_buffers;
gint num_buffers_left;
- /*< private >*/
- union {
- struct {
- /* FIXME: those fields should be moved into the private struct */
- gboolean typefind;
- gboolean running;
- GstEvent *pending_seek;
- } ABI;
- gpointer _gst_reserved[GST_PADDING_LARGE-1];
- } data;
+ gboolean typefind;
+ 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
- * @set_caps: Notify subclass of changed output caps
* @negotiate: Negotiated the caps with the peer.
- * @newsegment: Generate and send a new_segment event (UNUSED)
+ * @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
* @start: Start processing. Subclasses should open resources and prepare
* to produce data.
* @stop: Stop processing. Subclasses should use this to close resources.
@@ -130,6 +121,13 @@ struct _GstBaseSrc {
* these times.
* @get_size: Return the total size of the resource, in the configured format.
* @is_seekable: Check if the source can seek
+ * @prepare_seek_segment: Prepare the GstSegment that will be passed to the
+ * 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.
+ * Since: 0.10.13
+ * @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_WRONG_STATE. Any
@@ -137,29 +135,17 @@ struct _GstBaseSrc {
* until the @unlock_stop<!-- -->() function has been called.
* @unlock_stop: Clear the previous unlock request. Subclasses should clear
* any state they set during 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_UNEXPECTED signifies that the
- * end of stream is reached.
- * @do_seek: Perform seeking on the resource to the indicated segment.
- * @prepare_seek_segment: Prepare the GstSegment that will be passed to the
- * 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.
- * Since: 0.10.13
- * @query: Handle a requested query.
- * @check_get_range: Check whether the source would support pull-based
- * operation if it were to be opened now. This vfunc is optional, but
- * should be implemented if possible to avoid unnecessary start/stop
- * cycles. The default implementation will open and close the resource
- * to find out whether get_range is supported, and that is usually
- * undesirable.
- * @fixate: Called during negotiation if caps need fixating. Implement instead of
- * setting a fixate function on the source pad.
+ * end of stream is reached. The default implementation will create a new
+ * buffer from the negotiated allocator and will call @fill.
+ * @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
@@ -172,15 +158,16 @@ struct _GstBaseSrcClass {
/* virtual methods for subclasses */
/* get caps from subclass */
- GstCaps* (*get_caps) (GstBaseSrc *src);
- /* notify the subclass of new caps */
- gboolean (*set_caps) (GstBaseSrc *src, GstCaps *caps);
-
+ GstCaps* (*get_caps) (GstBaseSrc *src, GstCaps *filter);
/* decide on caps */
gboolean (*negotiate) (GstBaseSrc *src);
+ /* called if, in negotiation, caps need fixating */
+ void (*fixate) (GstBaseSrc *src, GstCaps *caps);
+ /* notify the subclass of new caps */
+ gboolean (*set_caps) (GstBaseSrc *src, GstCaps *caps);
- /* generate and send a newsegment (UNUSED) */
- gboolean (*newsegment) (GstBaseSrc *src);
+ /* setup allocation query */
+ gboolean (*setup_allocation) (GstBaseSrc *src, GstQuery *query);
/* start and stop processing, ideal for opening/closing the resource */
gboolean (*start) (GstBaseSrc *src);
@@ -196,44 +183,36 @@ struct _GstBaseSrcClass {
/* 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);
- /* ask the subclass to create a buffer with offset and size */
+ /* ask the subclass to create a buffer with offset and size, the default
+ * implementation will use the negotiated allocator and call fill. */
GstFlowReturn (*create) (GstBaseSrc *src, guint64 offset, guint size,
GstBuffer **buf);
-
- /* additions that change padding... */
- /* notify subclasses of a seek */
- gboolean (*do_seek) (GstBaseSrc *src, GstSegment *segment);
- /* notify subclasses of a query */
- gboolean (*query) (GstBaseSrc *src, GstQuery *query);
-
- /* check whether the source would support pull-based operation if
- * it were to be opened now. This vfunc is optional, but should be
- * implemented if possible to avoid unnecessary start/stop cycles.
- * The default implementation will open and close the resource to
- * find out whether get_range is supported and that is usually
- * undesirable. */
- gboolean (*check_get_range) (GstBaseSrc *src);
-
- /* called if, in negotiation, caps need fixating */
- void (*fixate) (GstBaseSrc *src, GstCaps *caps);
-
- /* Clear any pending unlock request, as we succeeded in unlocking */
- gboolean (*unlock_stop) (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);
+ /* 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 - 6];
+ gpointer _gst_reserved[GST_PADDING_LARGE];
};
GType gst_base_src_get_type (void);
@@ -251,8 +230,8 @@ gboolean gst_base_src_query_latency (GstBaseSrc *src, gboolean * live,
GstClockTime * min_latency,
GstClockTime * max_latency);
-void gst_base_src_set_blocksize (GstBaseSrc *src, gulong blocksize);
-gulong gst_base_src_get_blocksize (GstBaseSrc *src);
+void gst_base_src_set_blocksize (GstBaseSrc *src, guint blocksize);
+guint gst_base_src_get_blocksize (GstBaseSrc *src);
void gst_base_src_set_do_timestamp (GstBaseSrc *src, gboolean timestamp);
gboolean gst_base_src_get_do_timestamp (GstBaseSrc *src);
diff --git a/libs/gst/base/gstbasetransform.c b/libs/gst/base/gstbasetransform.c
index a46642ea24..9575603eb8 100644
--- a/libs/gst/base/gstbasetransform.c
+++ b/libs/gst/base/gstbasetransform.c
@@ -244,43 +244,18 @@ struct _GstBaseTransformPrivate
gboolean gap_aware;
- /* caps used for allocating buffers */
- gboolean proxy_alloc;
- GstCaps *sink_alloc;
- GstCaps *src_alloc;
-
- /*
- * This flag controls if basetransform should explicitly
- * do a pad alloc when it receives a buffer even if it operates on
- * passthrough, this is needed to check for downstream caps suggestions
- * and this newly alloc'ed buffer is discarded.
- *
- * Without this flag basetransform would try a pad alloc whenever it
- * gets a new buffer and pipelines like:
- * "src ! basetrans1 ! basetrans2 ! basetrans3 ! sink"
- * Would have a 3 pad allocs for each buffer pushed downstream from the src.
- *
- * This flag is set to TRUE on start up, on setcaps and when a buffer is
- * pushed downstream. It is set to FALSE after a pad alloc has been requested
- * downstream.
- * The rationale is that when a pad alloc flows through the pipeline, all
- * basetransform elements on passthrough will avoid pad alloc'ing when they
- * get the buffer.
- */
- gboolean force_alloc;
-
- /* upstream caps and size suggestions */
- GstCaps *sink_suggest;
- guint size_suggest;
- gboolean suggest_pending;
-
gboolean reconfigure;
/* QoS stats */
guint64 processed;
guint64 dropped;
- GstClockTime last_stop_out;
+ GstClockTime position_out;
+
+ GstBufferPool *pool;
+ const GstAllocator *allocator;
+ guint prefix;
+ guint alignment;
};
static GstElementClass *parent_class = NULL;
@@ -329,7 +304,7 @@ static gboolean gst_base_transform_sink_activate_push (GstPad * pad,
static gboolean gst_base_transform_activate (GstBaseTransform * trans,
gboolean active);
static gboolean gst_base_transform_get_unit_size (GstBaseTransform * trans,
- GstCaps * caps, guint * size);
+ GstCaps * caps, gsize * size);
static gboolean gst_base_transform_src_event (GstPad * pad, GstEvent * event);
static gboolean gst_base_transform_src_eventfunc (GstBaseTransform * trans,
@@ -337,18 +312,16 @@ static gboolean gst_base_transform_src_eventfunc (GstBaseTransform * trans,
static gboolean gst_base_transform_sink_event (GstPad * pad, GstEvent * event);
static gboolean gst_base_transform_sink_eventfunc (GstBaseTransform * trans,
GstEvent * event);
-static gboolean gst_base_transform_check_get_range (GstPad * pad);
static GstFlowReturn gst_base_transform_getrange (GstPad * pad, guint64 offset,
guint length, GstBuffer ** buffer);
static GstFlowReturn gst_base_transform_chain (GstPad * pad,
GstBuffer * buffer);
-static GstCaps *gst_base_transform_getcaps (GstPad * pad);
+static GstCaps *gst_base_transform_getcaps (GstPad * pad, GstCaps * filter);
static gboolean gst_base_transform_acceptcaps (GstPad * pad, GstCaps * caps);
static gboolean gst_base_transform_acceptcaps_default (GstBaseTransform * trans,
GstPadDirection direction, GstCaps * caps);
-static gboolean gst_base_transform_setcaps (GstPad * pad, GstCaps * caps);
-static GstFlowReturn gst_base_transform_buffer_alloc (GstPad * pad,
- guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
+static gboolean gst_base_transform_setcaps (GstBaseTransform * trans,
+ GstPad * pad, GstCaps * caps);
static gboolean gst_base_transform_query (GstPad * pad, GstQuery * query);
static const GstQueryType *gst_base_transform_query_type (GstPad * pad);
@@ -361,7 +334,6 @@ gst_base_transform_finalize (GObject * object)
trans = GST_BASE_TRANSFORM (object);
- gst_caps_replace (&trans->priv->sink_suggest, NULL);
g_mutex_free (trans->transform_lock);
G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -417,16 +389,12 @@ gst_base_transform_init (GstBaseTransform * trans,
GST_DEBUG_FUNCPTR (gst_base_transform_getcaps));
gst_pad_set_acceptcaps_function (trans->sinkpad,
GST_DEBUG_FUNCPTR (gst_base_transform_acceptcaps));
- gst_pad_set_setcaps_function (trans->sinkpad,
- GST_DEBUG_FUNCPTR (gst_base_transform_setcaps));
gst_pad_set_event_function (trans->sinkpad,
GST_DEBUG_FUNCPTR (gst_base_transform_sink_event));
gst_pad_set_chain_function (trans->sinkpad,
GST_DEBUG_FUNCPTR (gst_base_transform_chain));
gst_pad_set_activatepush_function (trans->sinkpad,
GST_DEBUG_FUNCPTR (gst_base_transform_sink_activate_push));
- gst_pad_set_bufferalloc_function (trans->sinkpad,
- GST_DEBUG_FUNCPTR (gst_base_transform_buffer_alloc));
gst_pad_set_query_function (trans->sinkpad,
GST_DEBUG_FUNCPTR (gst_base_transform_query));
gst_pad_set_query_type_function (trans->sinkpad,
@@ -443,8 +411,6 @@ gst_base_transform_init (GstBaseTransform * trans,
GST_DEBUG_FUNCPTR (gst_base_transform_acceptcaps));
gst_pad_set_event_function (trans->srcpad,
GST_DEBUG_FUNCPTR (gst_base_transform_src_event));
- gst_pad_set_checkgetrange_function (trans->srcpad,
- GST_DEBUG_FUNCPTR (gst_base_transform_check_get_range));
gst_pad_set_getrange_function (trans->srcpad,
GST_DEBUG_FUNCPTR (gst_base_transform_getrange));
gst_pad_set_activatepull_function (trans->srcpad,
@@ -477,7 +443,6 @@ gst_base_transform_init (GstBaseTransform * trans,
trans->priv->processed = 0;
trans->priv->dropped = 0;
- trans->priv->force_alloc = TRUE;
}
/* given @caps on the src or sink pad (given by @direction)
@@ -487,7 +452,7 @@ gst_base_transform_init (GstBaseTransform * trans,
*/
static GstCaps *
gst_base_transform_transform_caps (GstBaseTransform * trans,
- GstPadDirection direction, GstCaps * caps)
+ GstPadDirection direction, GstCaps * caps, GstCaps * filter)
{
GstCaps *ret;
GstBaseTransformClass *klass;
@@ -499,53 +464,40 @@ gst_base_transform_transform_caps (GstBaseTransform * trans,
/* if there is a custom transform function, use this */
if (klass->transform_caps) {
- GstCaps *temp;
- gint i;
- /* start with empty caps */
- ret = gst_caps_new_empty ();
GST_DEBUG_OBJECT (trans, "transform caps (direction = %d)", direction);
- if (gst_caps_is_any (caps)) {
- /* for any caps we still have to call the transform function */
- GST_DEBUG_OBJECT (trans, "from: ANY");
- temp = klass->transform_caps (trans, direction, caps);
- GST_DEBUG_OBJECT (trans, " to: %" GST_PTR_FORMAT, temp);
-
- temp = gst_caps_make_writable (temp);
- gst_caps_append (ret, temp);
- } else {
- gint n = gst_caps_get_size (caps);
- /* we send caps with just one structure to the transform
- * function as this is easier for the element */
- for (i = 0; i < n; i++) {
- GstCaps *nth;
-
- nth = gst_caps_copy_nth (caps, i);
- GST_LOG_OBJECT (trans, "from[%d]: %" GST_PTR_FORMAT, i, nth);
- temp = klass->transform_caps (trans, direction, nth);
- gst_caps_unref (nth);
- GST_LOG_OBJECT (trans, " to[%d]: %" GST_PTR_FORMAT, i, temp);
-
- temp = gst_caps_make_writable (temp);
-
- /* here we need to only append those structures, that are not yet
- * in there, we use the merge function for this */
- gst_caps_merge (ret, temp);
-
- GST_LOG_OBJECT (trans, " merged[%d]: %" GST_PTR_FORMAT, i, ret);
+ GST_LOG_OBJECT (trans, "from: %" GST_PTR_FORMAT, caps);
+ ret = klass->transform_caps (trans, direction, caps, filter);
+ GST_LOG_OBJECT (trans, " to: %" GST_PTR_FORMAT, ret);
+
+#ifndef G_DISABLE_ASSERT
+ if (filter) {
+ if (!gst_caps_is_subset (ret, filter)) {
+ GstCaps *intersection;
+
+ GST_ERROR_OBJECT (trans,
+ "transform_caps returned caps %" GST_PTR_FORMAT
+ " which are not a real subset of the filter caps %"
+ GST_PTR_FORMAT, ret, filter);
+ g_warning ("%s: transform_caps returned caps which are not a real "
+ "subset of the filter caps", GST_ELEMENT_NAME (trans));
+
+ intersection =
+ gst_caps_intersect_full (filter, ret, GST_CAPS_INTERSECT_FIRST);
+ gst_caps_unref (intersection);
+ ret = intersection;
}
- GST_LOG_OBJECT (trans, "merged: (%d)", gst_caps_get_size (ret));
- /* FIXME: we can't do much simplification here because we don't really want to
- * change the caps order
- gst_caps_do_simplify (ret);
- GST_DEBUG_OBJECT (trans, "simplified: (%d)", gst_caps_get_size (ret));
- */
}
+#endif
} else {
GST_DEBUG_OBJECT (trans, "identity from: %" GST_PTR_FORMAT, caps);
/* no transform function, use the identity transform */
- ret = gst_caps_ref (caps);
+ if (filter) {
+ ret = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+ } else {
+ ret = gst_caps_ref (caps);
+ }
}
GST_DEBUG_OBJECT (trans, "to: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (ret),
@@ -566,9 +518,9 @@ gst_base_transform_transform_caps (GstBaseTransform * trans,
static gboolean
gst_base_transform_transform_size (GstBaseTransform * trans,
GstPadDirection direction, GstCaps * caps,
- guint size, GstCaps * othercaps, guint * othersize)
+ gsize size, GstCaps * othercaps, gsize * othersize)
{
- guint inunitsize, outunitsize, units;
+ gsize inunitsize, outunitsize, units;
GstBaseTransformClass *klass;
gboolean ret;
@@ -628,8 +580,8 @@ no_multiple:
{
GST_DEBUG_OBJECT (trans, "Size %u is not a multiple of unit size %u", size,
inunitsize);
- g_warning ("%s: size %u is not a multiple of unit size %u",
- GST_ELEMENT_NAME (trans), size, inunitsize);
+ g_warning ("%s: size %" G_GSIZE_FORMAT " is not a multiple of unit size %"
+ G_GSIZE_FORMAT, GST_ELEMENT_NAME (trans), size, inunitsize);
return FALSE;
}
no_out_size:
@@ -650,21 +602,54 @@ no_out_size:
* If there is no peer, we simply return the caps of the padtemplate of pad.
*/
static GstCaps *
-gst_base_transform_getcaps (GstPad * pad)
+gst_base_transform_getcaps (GstPad * pad, GstCaps * filter)
{
GstBaseTransform *trans;
GstPad *otherpad;
- GstCaps *peercaps, *caps;
+ GstCaps *peercaps, *caps, *peerfilter = NULL;
trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
otherpad = (pad == trans->srcpad) ? trans->sinkpad : trans->srcpad;
/* we can do what the peer can */
- peercaps = gst_pad_peer_get_caps_reffed (otherpad);
+ if (filter) {
+ GstCaps *temp, *templ;
+
+ GST_DEBUG_OBJECT (pad, "filter caps %" GST_PTR_FORMAT, filter);
+
+ /* filtered against our padtemplate on the other side */
+ templ = gst_pad_get_pad_template_caps (pad);
+ GST_DEBUG_OBJECT (pad, "our template %" GST_PTR_FORMAT, templ);
+ temp = gst_caps_intersect_full (filter, templ, GST_CAPS_INTERSECT_FIRST);
+ GST_DEBUG_OBJECT (pad, "intersected %" GST_PTR_FORMAT, temp);
+ gst_caps_unref (templ);
+
+ /* then see what we can transform this to */
+ peerfilter = gst_base_transform_transform_caps (trans,
+ GST_PAD_DIRECTION (pad), temp, NULL);
+ GST_DEBUG_OBJECT (pad, "transformed %" GST_PTR_FORMAT, peerfilter);
+ gst_caps_unref (temp);
+
+ /* and filter against the template of this pad */
+ templ = gst_pad_get_pad_template_caps (otherpad);
+ GST_DEBUG_OBJECT (pad, "our template %" GST_PTR_FORMAT, templ);
+ /* We keep the caps sorted like the returned caps */
+ temp =
+ gst_caps_intersect_full (peerfilter, templ, GST_CAPS_INTERSECT_FIRST);
+ GST_DEBUG_OBJECT (pad, "intersected %" GST_PTR_FORMAT, temp);
+ gst_caps_unref (peerfilter);
+ gst_caps_unref (templ);
+ peerfilter = temp;
+ }
+
+ peercaps = gst_pad_peer_get_caps (otherpad, peerfilter);
+
+ if (peerfilter)
+ gst_caps_unref (peerfilter);
+
if (peercaps) {
- GstCaps *temp;
- const GstCaps *templ;
+ GstCaps *temp, *templ;
GST_DEBUG_OBJECT (pad, "peer caps %" GST_PTR_FORMAT, peercaps);
@@ -673,10 +658,11 @@ gst_base_transform_getcaps (GstPad * pad)
GST_DEBUG_OBJECT (pad, "our template %" GST_PTR_FORMAT, templ);
temp = gst_caps_intersect_full (peercaps, templ, GST_CAPS_INTERSECT_FIRST);
GST_DEBUG_OBJECT (pad, "intersected %" GST_PTR_FORMAT, temp);
+ gst_caps_unref (templ);
/* then see what we can transform this to */
caps = gst_base_transform_transform_caps (trans,
- GST_PAD_DIRECTION (otherpad), temp);
+ GST_PAD_DIRECTION (otherpad), temp, filter);
GST_DEBUG_OBJECT (pad, "transformed %" GST_PTR_FORMAT, caps);
gst_caps_unref (temp);
if (caps == NULL)
@@ -689,6 +675,7 @@ gst_base_transform_getcaps (GstPad * pad)
temp = gst_caps_intersect_full (caps, templ, GST_CAPS_INTERSECT_FIRST);
GST_DEBUG_OBJECT (pad, "intersected %" GST_PTR_FORMAT, temp);
gst_caps_unref (caps);
+ gst_caps_unref (templ);
caps = temp;
/* Now try if we can put the untransformed downstream caps first */
@@ -701,7 +688,15 @@ gst_base_transform_getcaps (GstPad * pad)
}
} else {
/* no peer or the peer can do anything, our padtemplate is enough then */
- caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
+ caps = gst_pad_get_pad_template_caps (pad);
+
+ if (filter) {
+ GstCaps *temp;
+
+ temp = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+ gst_caps_unref (caps);
+ caps = temp;
+ }
}
done:
@@ -715,6 +710,121 @@ done:
return caps;
}
+static gboolean
+gst_base_transform_set_allocation (GstBaseTransform * trans,
+ GstBufferPool * pool, const GstAllocator * allocator, guint prefix,
+ guint alignment)
+{
+ GstBufferPool *oldpool;
+ GstBaseTransformPrivate *priv = trans->priv;
+
+ /* activate */
+ if (pool) {
+ if (!gst_buffer_pool_set_active (pool, TRUE))
+ goto activate_failed;
+ }
+
+ GST_OBJECT_LOCK (trans);
+ oldpool = priv->pool;
+ priv->pool = pool;
+ priv->allocator = allocator;
+ priv->prefix = prefix;
+ priv->alignment = alignment;
+ GST_OBJECT_UNLOCK (trans);
+
+ if (oldpool) {
+ gst_buffer_pool_set_active (oldpool, FALSE);
+ gst_object_unref (oldpool);
+ }
+ return FALSE;
+
+ /* ERRORS */
+activate_failed:
+ {
+ GST_ERROR_OBJECT (trans, "failed to activate bufferpool.");
+ return FALSE;
+ }
+}
+
+static gboolean
+gst_base_transform_do_bufferpool (GstBaseTransform * trans, GstCaps * outcaps)
+{
+ GstQuery *query;
+ gboolean result = TRUE;
+ GstBufferPool *pool = NULL, *oldpool;
+ guint size, min, max, prefix, alignment;
+ GstBaseTransformClass *klass;
+ const GstAllocator *allocator = NULL;
+
+ /* there are these possibilities:
+ *
+ * 1) we negotiated passthrough, we can proxy the bufferpool directly.
+ * 2)
+ */
+
+ /* clear old pool */
+ oldpool = trans->priv->pool;
+ if (oldpool) {
+ gst_buffer_pool_set_active (oldpool, FALSE);
+ gst_object_unref (oldpool);
+ trans->priv->pool = oldpool = NULL;
+ }
+
+ if (trans->passthrough) {
+ /* we are in passthrough, the input buffer is never copied and always passed
+ * along. We never allocate an output buffer on the srcpad. What we do is
+ * let the upstream element decide if it wants to use a bufferpool and
+ * then we will proxy the downstream pool */
+ GST_DEBUG_OBJECT (trans, "we're passthough, delay bufferpool");
+ return TRUE;
+ }
+
+ /* not passthrough, we need to allocate */
+ /* find a pool for the negotiated caps now */
+ query = gst_query_new_allocation (outcaps, TRUE);
+ if (!gst_pad_peer_query (trans->srcpad, query)) {
+ /* not a problem, just debug a little */
+ GST_DEBUG_OBJECT (trans, "peer ALLOCATION query failed");
+ }
+
+ klass = GST_BASE_TRANSFORM_GET_CLASS (trans);
+
+ if (G_LIKELY (klass->setup_allocation))
+ result = klass->setup_allocation (trans, query);
+
+ /* we got configuration from our peer, parse them */
+ gst_query_parse_allocation_params (query, &size, &min, &max, &prefix,
+ &alignment, &pool);
+ gst_query_unref (query);
+
+ if (size == 0) {
+ const gchar *mem = NULL;
+
+ /* no size, we have variable size buffers */
+ if (gst_query_get_n_allocation_memories (query) > 0) {
+ mem = gst_query_parse_nth_allocation_memory (query, 0);
+ }
+ allocator = gst_allocator_find (mem);
+ } else if (pool == NULL) {
+ GstStructure *config;
+
+ /* we did not get a pool, make one ourselves then */
+ pool = gst_buffer_pool_new ();
+
+ config = gst_buffer_pool_get_config (pool);
+ gst_buffer_pool_config_set (config, outcaps, size, min, max, prefix,
+ alignment);
+ gst_buffer_pool_set_config (pool, config);
+ }
+
+ /* and store */
+ result =
+ gst_base_transform_set_allocation (trans, pool, allocator, prefix,
+ alignment);
+
+ return result;
+}
+
/* function triggered when the in and out caps are negotiated and need
* to be configured in the subclass. */
static gboolean
@@ -754,65 +864,11 @@ gst_base_transform_configure_caps (GstBaseTransform * trans, GstCaps * in,
ret = klass->set_caps (trans, in, out);
}
- GST_OBJECT_LOCK (trans);
- /* make sure we reevaluate how the buffer_alloc works wrt to proxy allocating
- * the buffer. FIXME, this triggers some quite heavy codepaths that don't need
- * to be taken.. */
- trans->priv->suggest_pending = TRUE;
- GST_OBJECT_UNLOCK (trans);
trans->negotiated = ret;
return ret;
}
-/* check if caps @in on @pad can be transformed to @out on the other pad.
- * We don't have a vmethod to test this yet so we have to do a somewhat less
- * efficient check for this.
- */
-static gboolean
-gst_base_transform_can_transform (GstBaseTransform * trans, GstPad * pad,
- GstCaps * in, GstCaps * out)
-{
- GstCaps *othercaps;
-
- /* convert the in caps to all possible out caps */
- othercaps =
- gst_base_transform_transform_caps (trans, GST_PAD_DIRECTION (pad), in);
-
- /* check if transform is empty */
- if (!othercaps || gst_caps_is_empty (othercaps))
- goto no_transform;
-
- /* check if the out caps is a subset of the othercaps */
- if (!gst_caps_can_intersect (out, othercaps))
- goto no_subset;
-
- if (othercaps)
- gst_caps_unref (othercaps);
-
- GST_DEBUG_OBJECT (trans, "from %" GST_PTR_FORMAT, in);
- GST_DEBUG_OBJECT (trans, "to %" GST_PTR_FORMAT, out);
-
- return TRUE;
-
- /* ERRORS */
-no_transform:
- {
- GST_DEBUG_OBJECT (trans,
- "transform returned useless %" GST_PTR_FORMAT, othercaps);
- if (othercaps)
- gst_caps_unref (othercaps);
- return FALSE;
- }
-no_subset:
- {
- GST_DEBUG_OBJECT (trans, "no subset");
- if (othercaps)
- gst_caps_unref (othercaps);
- return FALSE;
- }
-}
-
/* given a fixed @caps on @pad, create the best possible caps for the
* other pad.
* @caps must be fixed when calling this function.
@@ -851,13 +907,12 @@ gst_base_transform_find_transform (GstBaseTransform * trans, GstPad * pad,
* passthrough because it might be possible that this element cannot support
* passthrough at all. */
othercaps = gst_base_transform_transform_caps (trans,
- GST_PAD_DIRECTION (pad), caps);
+ GST_PAD_DIRECTION (pad), caps, NULL);
/* The caps we can actually output is the intersection of the transformed
* caps with the pad template for the pad */
if (othercaps) {
- GstCaps *intersect;
- const GstCaps *templ_caps;
+ GstCaps *intersect, *templ_caps;
templ_caps = gst_pad_get_pad_template_caps (otherpad);
GST_DEBUG_OBJECT (trans,
@@ -868,6 +923,7 @@ gst_base_transform_find_transform (GstBaseTransform * trans, GstPad * pad,
GST_CAPS_INTERSECT_FIRST);
gst_caps_unref (othercaps);
+ gst_caps_unref (templ_caps);
othercaps = intersect;
}
@@ -884,62 +940,51 @@ gst_base_transform_find_transform (GstBaseTransform * trans, GstPad * pad,
GST_DEBUG_OBJECT (trans,
"transform returned non fixed %" GST_PTR_FORMAT, othercaps);
- /* see if the target caps are a superset of the source caps, in this
- * case we can try to perform passthrough */
- if (gst_caps_can_intersect (othercaps, caps)) {
- GST_DEBUG_OBJECT (trans, "try passthrough with %" GST_PTR_FORMAT, caps);
- if (otherpeer) {
- /* try passthrough. we know it's fixed, because caps is fixed */
- if (gst_pad_accept_caps (otherpeer, caps)) {
- GST_DEBUG_OBJECT (trans, "peer accepted %" GST_PTR_FORMAT, caps);
- /* peer accepted unmodified caps, we free the original non-fixed
- * caps and work with the passthrough caps */
- gst_caps_unref (othercaps);
- othercaps = gst_caps_ref (caps);
- is_fixed = TRUE;
- /* mark that we checked othercaps with the peer, this
- * makes sure we don't call accept_caps again with these same
- * caps */
- peer_checked = TRUE;
- } else {
- GST_DEBUG_OBJECT (trans,
- "peer did not accept %" GST_PTR_FORMAT, caps);
- }
- } else {
- GST_DEBUG_OBJECT (trans, "no peer, doing passthrough");
- gst_caps_unref (othercaps);
- othercaps = gst_caps_ref (caps);
- is_fixed = TRUE;
- }
- }
- }
+ /* Now let's see what the peer suggests based on our transformed caps */
+ if (otherpeer) {
+ GstCaps *peercaps, *intersection, *templ_caps;
- /* second attempt at fixation is done by intersecting with
- * the peer caps */
- if (!is_fixed && otherpeer) {
- /* intersect against what the peer can do */
- GstCaps *peercaps;
- GstCaps *intersect;
+ GST_DEBUG_OBJECT (trans,
+ "Checking peer caps with filter %" GST_PTR_FORMAT, othercaps);
- GST_DEBUG_OBJECT (trans, "othercaps now %" GST_PTR_FORMAT, othercaps);
+ peercaps = gst_pad_get_caps (otherpeer, othercaps);
+ GST_DEBUG_OBJECT (trans, "Resulted in %" GST_PTR_FORMAT, peercaps);
- peercaps = gst_pad_get_caps_reffed (otherpeer);
- intersect = gst_caps_intersect (peercaps, othercaps);
- gst_caps_unref (peercaps);
- gst_caps_unref (othercaps);
- othercaps = intersect;
- peer_checked = FALSE;
+ templ_caps = gst_pad_get_pad_template_caps (otherpad);
- is_fixed = gst_caps_is_fixed (othercaps);
+ GST_DEBUG_OBJECT (trans,
+ "Intersecting with template caps %" GST_PTR_FORMAT, templ_caps);
- GST_DEBUG_OBJECT (trans,
- "filtering against peer yields %" GST_PTR_FORMAT, othercaps);
- }
+ intersection =
+ gst_caps_intersect_full (peercaps, templ_caps,
+ GST_CAPS_INTERSECT_FIRST);
+ GST_DEBUG_OBJECT (trans, "Intersection: %" GST_PTR_FORMAT, intersection);
+ gst_caps_unref (peercaps);
+ gst_caps_unref (templ_caps);
+ peercaps = intersection;
+ GST_DEBUG_OBJECT (trans,
+ "Intersecting with transformed caps %" GST_PTR_FORMAT, othercaps);
+ intersection =
+ gst_caps_intersect_full (peercaps, othercaps,
+ GST_CAPS_INTERSECT_FIRST);
+ GST_DEBUG_OBJECT (trans, "Intersection: %" GST_PTR_FORMAT, intersection);
+ gst_caps_unref (peercaps);
+ gst_caps_unref (othercaps);
+ othercaps = intersection;
+ is_fixed = gst_caps_is_fixed (othercaps);
+ peer_checked = TRUE;
+ } else {
+ GST_DEBUG_OBJECT (trans, "no peer, doing passthrough");
+ gst_caps_unref (othercaps);
+ othercaps = gst_caps_ref (caps);
+ is_fixed = TRUE;
+ }
+ }
if (gst_caps_is_empty (othercaps))
goto no_transform_possible;
- /* third attempt at fixation, call the fixate vmethod and
+ /* second attempt at fixation, call the fixate vmethod and
* ultimately call the pad fixate function. */
if (!is_fixed) {
GST_DEBUG_OBJECT (trans,
@@ -1064,9 +1109,9 @@ gst_base_transform_acceptcaps_default (GstBaseTransform * trans,
/* get all the formats we can handle on this pad */
if (direction == GST_PAD_SRC)
- allowed = gst_pad_get_caps_reffed (trans->srcpad);
+ allowed = gst_pad_get_caps (trans->srcpad, NULL);
else
- allowed = gst_pad_get_caps_reffed (trans->sinkpad);
+ allowed = gst_pad_get_caps (trans->sinkpad, NULL);
if (!allowed) {
GST_DEBUG_OBJECT (trans, "gst_pad_get_caps() failed");
@@ -1088,7 +1133,7 @@ gst_base_transform_acceptcaps_default (GstBaseTransform * trans,
/* find best possible caps for the other pad as a way to see if we can
* transform this caps. */
- othercaps = gst_base_transform_find_transform (trans, pad, caps);
+ othercaps = gst_base_transform_find_transform (trans, pad, caps, FALSE);
if (!othercaps || gst_caps_is_empty (othercaps))
goto no_transform_possible;
@@ -1143,24 +1188,17 @@ gst_base_transform_acceptcaps (GstPad * pad, GstCaps * caps)
* because we never set caps starting from the srcpad.
*/
static gboolean
-gst_base_transform_setcaps (GstPad * pad, GstCaps * caps)
+gst_base_transform_setcaps (GstBaseTransform * trans, GstPad * pad,
+ GstCaps * caps)
{
- GstBaseTransform *trans;
GstPad *otherpad, *otherpeer;
GstCaps *othercaps = NULL;
gboolean ret = TRUE;
GstCaps *incaps, *outcaps;
- trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
-
otherpad = (pad == trans->srcpad) ? trans->sinkpad : trans->srcpad;
otherpeer = gst_pad_get_peer (otherpad);
- /* if we get called recursively, we bail out now to avoid an
- * infinite loop. */
- if (GST_PAD_IS_IN_SETCAPS (otherpad))
- goto done;
-
GST_DEBUG_OBJECT (pad, "have new caps %p %" GST_PTR_FORMAT, caps, caps);
/* find best possible caps for the other pad */
@@ -1189,21 +1227,29 @@ gst_base_transform_setcaps (GstPad * pad, GstCaps * caps)
if (!(ret = gst_base_transform_configure_caps (trans, incaps, outcaps)))
goto failed_configure;
+ GST_OBJECT_LOCK (trans->sinkpad);
+ GST_OBJECT_FLAG_UNSET (trans->srcpad, GST_PAD_NEED_RECONFIGURE);
+ trans->priv->reconfigure = FALSE;
+ GST_OBJECT_UNLOCK (trans->sinkpad);
+
/* we know this will work, we implement the setcaps */
- gst_pad_set_caps (otherpad, othercaps);
+ gst_pad_push_event (otherpad, gst_event_new_caps (othercaps));
if (pad == trans->srcpad && trans->priv->pad_mode == GST_ACTIVATE_PULL) {
/* FIXME hm? */
- ret &= gst_pad_set_caps (otherpeer, othercaps);
+ ret &= gst_pad_push_event (otherpeer, gst_event_new_caps (othercaps));
if (!ret) {
GST_INFO_OBJECT (trans, "otherpeer setcaps(%" GST_PTR_FORMAT ") failed",
othercaps);
}
}
+ if (ret) {
+ /* try to get a pool when needed */
+ gst_base_transform_do_bufferpool (trans, othercaps);
+ }
+
done:
- /* new caps, force alloc on next buffer on the chain */
- trans->priv->force_alloc = TRUE;
if (otherpeer)
gst_object_unref (otherpeer);
if (othercaps)
@@ -1211,8 +1257,6 @@ done:
trans->negotiated = ret;
- gst_object_unref (trans);
-
return ret;
/* ERRORS */
@@ -1246,7 +1290,28 @@ gst_base_transform_query (GstPad * pad, GstQuery * query)
otherpad = (pad == trans->srcpad) ? trans->sinkpad : trans->srcpad;
switch (GST_QUERY_TYPE (query)) {
- case GST_QUERY_POSITION:{
+ case GST_QUERY_ALLOCATION:
+ {
+ gboolean passthrough;
+
+ /* can only be done on the sinkpad */
+ if (!GST_PAD_IS_SINK (pad))
+ goto done;
+
+ GST_BASE_TRANSFORM_LOCK (trans);
+ passthrough = trans->passthrough || trans->always_in_place;
+ GST_BASE_TRANSFORM_UNLOCK (trans);
+
+ GST_DEBUG_OBJECT (trans, "passthrough %d", passthrough);
+
+ if (passthrough)
+ ret = gst_pad_peer_query (otherpad, query);
+ else
+ ret = FALSE;
+ break;
+ }
+ case GST_QUERY_POSITION:
+ {
GstFormat format;
gst_query_parse_position (query, &format, NULL);
@@ -1255,13 +1320,13 @@ gst_base_transform_query (GstPad * pad, GstQuery * query)
ret = TRUE;
if ((pad == trans->sinkpad)
- || (trans->priv->last_stop_out == GST_CLOCK_TIME_NONE)) {
+ || (trans->priv->position_out == GST_CLOCK_TIME_NONE)) {
pos =
gst_segment_to_stream_time (&trans->segment, GST_FORMAT_TIME,
- trans->segment.last_stop);
+ trans->segment.position);
} else {
pos = gst_segment_to_stream_time (&trans->segment, GST_FORMAT_TIME,
- trans->priv->last_stop_out);
+ trans->priv->position_out);
}
gst_query_set_position (query, format, pos);
} else {
@@ -1274,6 +1339,7 @@ gst_base_transform_query (GstPad * pad, GstQuery * query)
break;
}
+done:
gst_object_unref (trans);
return ret;
}
@@ -1289,57 +1355,12 @@ gst_base_transform_query_type (GstPad * pad)
return types;
}
-static void
-compute_upstream_suggestion (GstBaseTransform * trans, guint expsize,
- GstCaps * caps)
-{
- GstCaps *othercaps;
- GstBaseTransformPrivate *priv = trans->priv;
-
- GST_DEBUG_OBJECT (trans, "trying to find upstream suggestion");
-
- /* we cannot convert the current buffer but we might be able to suggest a
- * new format upstream, try to find what the best format is. */
- othercaps = gst_base_transform_find_transform (trans, trans->srcpad, caps);
-
- if (!othercaps) {
- GST_DEBUG_OBJECT (trans, "incompatible caps, ignoring");
- /* we received caps that we cannot transform. Upstream is behaving badly
- * because it should have checked if we could handle these caps. We can
- * simply ignore these caps and produce a buffer with our original caps. */
- } else {
- guint size_suggest;
-
- GST_DEBUG_OBJECT (trans, "getting size of suggestion");
-
- /* not a subset, we have a new upstream suggestion, remember it and
- * allocate a default buffer. First we try to convert the size */
- if (gst_base_transform_transform_size (trans,
- GST_PAD_SRC, caps, expsize, othercaps, &size_suggest)) {
-
- /* ok, remember the suggestions now */
- GST_DEBUG_OBJECT (trans,
- "storing new caps and size suggestion of %u and %" GST_PTR_FORMAT,
- size_suggest, othercaps);
-
- GST_OBJECT_LOCK (trans->sinkpad);
- if (priv->sink_suggest)
- gst_caps_unref (priv->sink_suggest);
- priv->sink_suggest = gst_caps_ref (othercaps);
- priv->size_suggest = size_suggest;
- trans->priv->suggest_pending = TRUE;
- GST_OBJECT_UNLOCK (trans->sinkpad);
- }
- gst_caps_unref (othercaps);
- }
-}
-
/* Allocate a buffer using gst_pad_alloc_buffer
*
* This function can do renegotiation on the source pad
*
* The output buffer is always writable. outbuf can be equal to
- * inbuf, the caller should be prepared for this and perform
+ * inbuf, the caller should be prepared for this and perform
* appropriate refcounting.
*/
static GstFlowReturn
@@ -1349,9 +1370,9 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
GstBaseTransformClass *bclass;
GstBaseTransformPrivate *priv;
GstFlowReturn ret = GST_FLOW_OK;
- guint outsize, newsize, expsize;
- gboolean discard, setcaps, copymeta;
- GstCaps *incaps, *oldcaps, *newcaps, *outcaps;
+ gboolean copymeta;
+ gsize insize, outsize;
+ GstCaps *incaps = NULL, *outcaps = NULL;
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
@@ -1359,15 +1380,13 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
*out_buf = NULL;
+ insize = gst_buffer_get_size (in_buf);
+
/* figure out how to allocate a buffer based on the current configuration */
if (trans->passthrough) {
GST_DEBUG_OBJECT (trans, "doing passthrough alloc");
- /* passthrough, we don't really need to call pad alloc but we still need to
- * in order to get upstream negotiation. The output size is the same as the
- * input size. */
- outsize = GST_BUFFER_SIZE (in_buf);
- /* we always alloc and discard here */
- discard = TRUE;
+ /* passthrough, the output size is the same as the input size. */
+ outsize = insize;
} else {
gboolean want_in_place = (bclass->transform_ip != NULL)
&& trans->always_in_place;
@@ -1375,38 +1394,36 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
if (want_in_place) {
GST_DEBUG_OBJECT (trans, "doing inplace alloc");
/* we alloc a buffer of the same size as the input */
- outsize = GST_BUFFER_SIZE (in_buf);
- /* only discard it when the input was not writable, otherwise, we reuse
- * the input buffer. */
- discard = gst_buffer_is_writable (in_buf);
- GST_DEBUG_OBJECT (trans, "discard: %d", discard);
+ outsize = insize;
} else {
+ incaps = gst_pad_get_current_caps (trans->sinkpad);
+ outcaps = gst_pad_get_current_caps (trans->srcpad);
+
GST_DEBUG_OBJECT (trans, "getting output size for copy transform");
/* copy transform, figure out the output size */
if (!gst_base_transform_transform_size (trans,
- GST_PAD_SINK, GST_PAD_CAPS (trans->sinkpad),
- GST_BUFFER_SIZE (in_buf), GST_PAD_CAPS (trans->srcpad),
- &outsize)) {
+ GST_PAD_SINK, incaps, insize, outcaps, &outsize)) {
goto unknown_size;
}
- /* never discard this buffer, we need it for storing the output */
- discard = FALSE;
}
}
- oldcaps = GST_PAD_CAPS (trans->srcpad);
-
if (bclass->prepare_output_buffer) {
+ if (outcaps == NULL)
+ outcaps = gst_pad_get_current_caps (trans->srcpad);
+
GST_DEBUG_OBJECT (trans,
- "calling prepare buffer with caps %p %" GST_PTR_FORMAT, oldcaps,
- oldcaps);
+ "calling prepare buffer with caps %p %" GST_PTR_FORMAT, outcaps,
+ outcaps);
ret =
- bclass->prepare_output_buffer (trans, in_buf, outsize, oldcaps,
+ bclass->prepare_output_buffer (trans, in_buf, outsize, outcaps,
out_buf);
/* get a new ref to the srcpad caps, the prepare_output_buffer function can
* update the pad caps if it wants */
- oldcaps = GST_PAD_CAPS (trans->srcpad);
+ if (outcaps)
+ gst_caps_unref (outcaps);
+ outcaps = gst_pad_get_current_caps (trans->srcpad);
/* FIXME 0.11:
* decrease refcount again if vmethod returned refcounted in_buf. This
@@ -1415,245 +1432,112 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
* a reffed inbuf, which is exactly what we don't want :), oh well.. */
if (in_buf == *out_buf)
gst_buffer_unref (in_buf);
-
- /* never discard the buffer from the prepare_buffer method */
- if (*out_buf != NULL)
- discard = FALSE;
}
if (ret != GST_FLOW_OK)
goto alloc_failed;
if (*out_buf == NULL) {
- if (trans->passthrough && !trans->priv->force_alloc) {
- GST_DEBUG_OBJECT (trans, "Avoiding pad alloc");
- *out_buf = gst_buffer_ref (in_buf);
+ if (trans->passthrough) {
+ GST_DEBUG_OBJECT (trans, "Reusing input buffer");
+ *out_buf = in_buf;
+ } else if (priv->pool) {
+ GST_DEBUG_OBJECT (trans, "using pool alloc");
+ ret = gst_buffer_pool_acquire_buffer (priv->pool, out_buf, NULL);
} else {
- GST_DEBUG_OBJECT (trans, "doing alloc with caps %" GST_PTR_FORMAT,
- oldcaps);
-
- ret = gst_pad_alloc_buffer (trans->srcpad,
- GST_BUFFER_OFFSET (in_buf), outsize, oldcaps, out_buf);
- if (ret != GST_FLOW_OK)
- goto alloc_failed;
+ GST_DEBUG_OBJECT (trans, "doing alloc of size %u", outsize);
+ *out_buf =
+ gst_buffer_new_allocate (priv->allocator, outsize, priv->alignment);
}
}
+ if (ret != GST_FLOW_OK)
+ goto alloc_failed;
+
/* must always have a buffer by now */
if (*out_buf == NULL)
goto no_buffer;
- /* check if we got different caps on this new output buffer */
- newcaps = GST_BUFFER_CAPS (*out_buf);
- newsize = GST_BUFFER_SIZE (*out_buf);
-
- if (newcaps && !gst_caps_is_equal (newcaps, oldcaps)) {
- GstCaps *othercaps;
- gboolean can_convert;
-
- GST_DEBUG_OBJECT (trans, "received new caps %" GST_PTR_FORMAT, newcaps);
-
- incaps = GST_PAD_CAPS (trans->sinkpad);
-
- /* check if we can convert the current incaps to the new target caps */
- can_convert =
- gst_base_transform_can_transform (trans, trans->sinkpad, incaps,
- newcaps);
-
- if (!can_convert) {
- GST_DEBUG_OBJECT (trans, "cannot perform transform on current buffer");
-
- gst_base_transform_transform_size (trans,
- GST_PAD_SINK, incaps, GST_BUFFER_SIZE (in_buf), newcaps, &expsize);
-
- compute_upstream_suggestion (trans, expsize, newcaps);
-
- /* we got a suggested caps but we can't transform to it. See if there is
- * another downstream format that we can transform to */
- othercaps =
- gst_base_transform_find_transform (trans, trans->sinkpad, incaps);
-
- if (othercaps && !gst_caps_is_empty (othercaps)) {
- GST_DEBUG_OBJECT (trans, "we found target caps %" GST_PTR_FORMAT,
- othercaps);
- *out_buf = gst_buffer_make_metadata_writable (*out_buf);
- gst_buffer_set_caps (*out_buf, othercaps);
- gst_caps_unref (othercaps);
- newcaps = GST_BUFFER_CAPS (*out_buf);
- can_convert = TRUE;
- } else if (othercaps)
- gst_caps_unref (othercaps);
- }
-
- /* it's possible that the buffer we got is of the wrong size, get the
- * expected size here, we will check the size if we are going to use the
- * buffer later on. */
- gst_base_transform_transform_size (trans,
- GST_PAD_SINK, incaps, GST_BUFFER_SIZE (in_buf), newcaps, &expsize);
-
- if (can_convert) {
- GST_DEBUG_OBJECT (trans, "reconfigure transform for current buffer");
-
- /* subclass might want to add fields to the caps */
- if (bclass->fixate_caps != NULL) {
- newcaps = gst_caps_copy (newcaps);
-
- GST_DEBUG_OBJECT (trans, "doing fixate %" GST_PTR_FORMAT
- " using caps %" GST_PTR_FORMAT
- " on pad %s:%s using fixate_caps vmethod", newcaps, incaps,
- GST_DEBUG_PAD_NAME (trans->srcpad));
- bclass->fixate_caps (trans, GST_PAD_SINK, incaps, newcaps);
-
- *out_buf = gst_buffer_make_metadata_writable (*out_buf);
- gst_buffer_set_caps (*out_buf, newcaps);
- gst_caps_unref (newcaps);
- newcaps = GST_BUFFER_CAPS (*out_buf);
- }
-
- /* caps not empty, try to renegotiate to the new format */
- if (!gst_base_transform_configure_caps (trans, incaps, newcaps)) {
- /* not sure we need to fail hard here, we can simply continue our
- * conversion with what we negotiated before */
- goto failed_configure;
- }
- /* new format configure, and use the new output buffer */
- gst_pad_set_caps (trans->srcpad, newcaps);
- discard = FALSE;
- /* clear previous cached sink-pad caps, so buffer_alloc knows that
- * it needs to revisit the decision about whether to proxy or not: */
- gst_caps_replace (&priv->sink_alloc, NULL);
- /* if we got a buffer of the wrong size, discard it now and make sure we
- * allocate a propertly sized buffer later. */
- if (newsize != expsize) {
- if (in_buf != *out_buf)
- gst_buffer_unref (*out_buf);
- *out_buf = NULL;
- }
- outsize = expsize;
- } else {
- compute_upstream_suggestion (trans, expsize, newcaps);
-
- if (in_buf != *out_buf)
- gst_buffer_unref (*out_buf);
- *out_buf = NULL;
- }
- } else if (outsize != newsize) {
- GST_WARNING_OBJECT (trans, "Caps did not change but allocated size does "
- "not match expected size (%d != %d)", newsize, outsize);
- if (in_buf != *out_buf)
- gst_buffer_unref (*out_buf);
- *out_buf = NULL;
+ if (trans->passthrough && in_buf != *out_buf) {
+ /* we are asked to perform a passthrough transform but the input and
+ * output buffers are different. We have to discard the output buffer and
+ * reuse the input buffer. */
+ GST_DEBUG_OBJECT (trans, "passthrough but different buffers");
+ gst_buffer_unref (*out_buf);
+ *out_buf = in_buf;
}
+ GST_DEBUG_OBJECT (trans, "using allocated buffer in %p, out %p", in_buf,
+ *out_buf);
- /* these are the final output caps */
- outcaps = GST_PAD_CAPS (trans->srcpad);
-
+ /* if we have different buffers, check if the metadata is ok */
copymeta = FALSE;
- if (*out_buf == NULL) {
- if (!discard) {
- GST_DEBUG_OBJECT (trans, "make default output buffer of size %d",
- outsize);
- /* no valid buffer yet, make one, metadata is writable */
- *out_buf = gst_buffer_new_and_alloc (outsize);
- gst_buffer_copy_metadata (*out_buf, in_buf,
- GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS);
- } else {
- GST_DEBUG_OBJECT (trans, "reuse input buffer");
- *out_buf = in_buf;
- }
- } else {
- if (trans->passthrough && in_buf != *out_buf) {
- /* we are asked to perform a passthrough transform but the input and
- * output buffers are different. We have to discard the output buffer and
- * reuse the input buffer. */
- GST_DEBUG_OBJECT (trans, "passthrough but different buffers");
- discard = TRUE;
- }
- if (discard) {
- GST_DEBUG_OBJECT (trans, "discard buffer, reuse input buffer");
- gst_buffer_unref (*out_buf);
- *out_buf = in_buf;
- } else {
- GST_DEBUG_OBJECT (trans, "using allocated buffer in %p, out %p", in_buf,
- *out_buf);
- /* if we have different buffers, check if the metadata is ok */
- if (*out_buf != in_buf) {
- guint mask;
-
- mask = GST_BUFFER_FLAG_PREROLL | GST_BUFFER_FLAG_IN_CAPS |
- GST_BUFFER_FLAG_DELTA_UNIT | GST_BUFFER_FLAG_DISCONT |
- GST_BUFFER_FLAG_GAP | GST_BUFFER_FLAG_MEDIA1 |
- GST_BUFFER_FLAG_MEDIA2 | GST_BUFFER_FLAG_MEDIA3;
- /* see if the flags and timestamps match */
- copymeta =
- (GST_MINI_OBJECT_FLAGS (*out_buf) & mask) ==
- (GST_MINI_OBJECT_FLAGS (in_buf) & mask);
- copymeta |=
- GST_BUFFER_TIMESTAMP (*out_buf) != GST_BUFFER_TIMESTAMP (in_buf) ||
- GST_BUFFER_DURATION (*out_buf) != GST_BUFFER_DURATION (in_buf) ||
- GST_BUFFER_OFFSET (*out_buf) != GST_BUFFER_OFFSET (in_buf) ||
- GST_BUFFER_OFFSET_END (*out_buf) != GST_BUFFER_OFFSET_END (in_buf);
- }
- }
+ if (*out_buf != in_buf) {
+ guint mask;
+
+ mask = GST_BUFFER_FLAG_PREROLL | GST_BUFFER_FLAG_IN_CAPS |
+ GST_BUFFER_FLAG_DELTA_UNIT | GST_BUFFER_FLAG_DISCONT |
+ GST_BUFFER_FLAG_GAP | GST_BUFFER_FLAG_MEDIA1 |
+ GST_BUFFER_FLAG_MEDIA2 | GST_BUFFER_FLAG_MEDIA3;
+ /* see if the flags and timestamps match */
+ copymeta =
+ (GST_MINI_OBJECT_FLAGS (*out_buf) & mask) ==
+ (GST_MINI_OBJECT_FLAGS (in_buf) & mask);
+ copymeta |=
+ GST_BUFFER_TIMESTAMP (*out_buf) != GST_BUFFER_TIMESTAMP (in_buf) ||
+ GST_BUFFER_DURATION (*out_buf) != GST_BUFFER_DURATION (in_buf) ||
+ GST_BUFFER_OFFSET (*out_buf) != GST_BUFFER_OFFSET (in_buf) ||
+ GST_BUFFER_OFFSET_END (*out_buf) != GST_BUFFER_OFFSET_END (in_buf);
}
- /* check if we need to make things writable. We need this when we need to
- * update the caps or the metadata on the output buffer. */
- newcaps = GST_BUFFER_CAPS (*out_buf);
- /* we check the pointers as a quick check and then go to the more involved
- * check. This is needed when we receive different pointers on the sinkpad
- * that mean the same caps. What we then want to do is prefer those caps over
- * the ones on the srcpad and set the srcpad caps to the buffer caps */
- setcaps = !newcaps || ((newcaps != outcaps)
- && (!gst_caps_is_equal (newcaps, outcaps)));
/* we need to modify the metadata when the element is not gap aware,
* passthrough is not used and the gap flag is set */
- copymeta |= !trans->priv->gap_aware && !trans->passthrough
+ copymeta |= !priv->gap_aware && !trans->passthrough
&& (GST_MINI_OBJECT_FLAGS (*out_buf) & GST_BUFFER_FLAG_GAP);
- if (setcaps || copymeta) {
- GST_DEBUG_OBJECT (trans, "setcaps %d, copymeta %d", setcaps, copymeta);
- if (!gst_buffer_is_metadata_writable (*out_buf)) {
- GST_DEBUG_OBJECT (trans, "buffer metadata %p not writable", *out_buf);
+ if (copymeta) {
+ GST_DEBUG_OBJECT (trans, "copymeta %d", copymeta);
+ if (!gst_buffer_is_writable (*out_buf)) {
+ GST_DEBUG_OBJECT (trans, "buffer %p not writable", *out_buf);
if (in_buf == *out_buf)
- *out_buf = gst_buffer_create_sub (in_buf, 0, GST_BUFFER_SIZE (in_buf));
+ *out_buf = gst_buffer_copy (in_buf);
else
- *out_buf = gst_buffer_make_metadata_writable (*out_buf);
+ *out_buf = gst_buffer_make_writable (*out_buf);
}
/* when we get here, the metadata should be writable */
- if (setcaps)
- gst_buffer_set_caps (*out_buf, outcaps);
if (copymeta)
- gst_buffer_copy_metadata (*out_buf, in_buf,
- GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS);
+ gst_buffer_copy_into (*out_buf, in_buf,
+ GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
/* clear the GAP flag when the subclass does not understand it */
- if (!trans->priv->gap_aware)
+ if (!priv->gap_aware)
GST_BUFFER_FLAG_UNSET (*out_buf, GST_BUFFER_FLAG_GAP);
}
+done:
+ if (incaps)
+ gst_caps_unref (incaps);
+ if (outcaps)
+ gst_caps_unref (outcaps);
+
return ret;
/* ERRORS */
alloc_failed:
{
GST_WARNING_OBJECT (trans, "pad-alloc failed: %s", gst_flow_get_name (ret));
- return ret;
+ goto done;
}
no_buffer:
{
GST_ELEMENT_ERROR (trans, STREAM, NOT_IMPLEMENTED,
("Sub-class failed to provide an output buffer"), (NULL));
- return GST_FLOW_ERROR;
+ ret = GST_FLOW_ERROR;
+ goto done;
}
unknown_size:
{
GST_ERROR_OBJECT (trans, "unknown output size");
- return GST_FLOW_ERROR;
- }
-failed_configure:
- {
- GST_WARNING_OBJECT (trans, "failed to configure caps");
- return GST_FLOW_NOT_NEGOTIATED;
+ ret = GST_FLOW_ERROR;
+ goto done;
}
}
@@ -1672,7 +1556,7 @@ failed_configure:
*/
static gboolean
gst_base_transform_get_unit_size (GstBaseTransform * trans, GstCaps * caps,
- guint * size)
+ gsize * size)
{
gboolean res = FALSE;
GstBaseTransformClass *bclass;
@@ -1715,304 +1599,6 @@ gst_base_transform_get_unit_size (GstBaseTransform * trans, GstCaps * caps,
return res;
}
-/* your upstream peer wants to send you a buffer
- * that buffer has the given offset, size and caps
- * you're requested to allocate a buffer
- */
-static GstFlowReturn
-gst_base_transform_buffer_alloc (GstPad * pad, guint64 offset, guint size,
- GstCaps * caps, GstBuffer ** buf)
-{
- GstBaseTransform *trans;
- GstBaseTransformClass *klass;
- GstBaseTransformPrivate *priv;
- GstFlowReturn res;
- gboolean alloced = FALSE;
- gboolean proxy, suggest, same_caps;
- GstCaps *sink_suggest = NULL;
- guint size_suggest;
-
- trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
- if (G_UNLIKELY (trans == NULL))
- return GST_FLOW_WRONG_STATE;
- klass = GST_BASE_TRANSFORM_GET_CLASS (trans);
- priv = trans->priv;
-
- GST_DEBUG_OBJECT (pad, "alloc with caps %p %" GST_PTR_FORMAT ", size %u",
- caps, caps, size);
-
- /* if the code below does not come up with a better buffer, we will return _OK
- * and an empty buffer. This will trigger the core to allocate a buffer with
- * given input size and caps. */
- *buf = NULL;
- res = GST_FLOW_OK;
-
- /* we remember our previous alloc request to quickly see if we can proxy or
- * not. We skip this check if we have a pending suggestion. */
- GST_OBJECT_LOCK (pad);
- same_caps = !priv->suggest_pending && caps &&
- gst_caps_is_equal (priv->sink_alloc, caps);
- GST_OBJECT_UNLOCK (pad);
-
- if (same_caps) {
- /* we have seen this before, see below if we need to proxy */
- GST_DEBUG_OBJECT (trans, "have old caps %p, size %u", caps, size);
- gst_caps_replace (&sink_suggest, caps);
- size_suggest = size;
- suggest = FALSE;
- } else {
- GST_DEBUG_OBJECT (trans, "new format %p %" GST_PTR_FORMAT, caps, caps);
-
- /* if we have a suggestion, pretend we got these as input */
- GST_OBJECT_LOCK (pad);
- if ((priv->sink_suggest && !gst_caps_is_equal (caps, priv->sink_suggest))) {
- sink_suggest = gst_caps_ref (priv->sink_suggest);
- size_suggest = priv->size_suggest;
- GST_DEBUG_OBJECT (trans, "have suggestion %p %" GST_PTR_FORMAT " size %u",
- sink_suggest, sink_suggest, priv->size_suggest);
- /* suggest is TRUE when we have a custom suggestion pending that we need
- * to unref later. */
- suggest = TRUE;
- } else {
- GST_DEBUG_OBJECT (trans, "using caps %p %" GST_PTR_FORMAT " size %u",
- caps, caps, size);
- gst_caps_replace (&sink_suggest, caps);
- size_suggest = size;
- suggest = FALSE;
- }
- priv->suggest_pending = FALSE;
- GST_OBJECT_UNLOCK (pad);
-
- /* check if we actually handle this format on the sinkpad */
- if (sink_suggest) {
- const GstCaps *templ;
-
- if (!gst_caps_is_fixed (sink_suggest)) {
- GstCaps *peercaps;
-
- GST_DEBUG_OBJECT (trans, "Suggested caps is not fixed: %"
- GST_PTR_FORMAT, sink_suggest);
-
- peercaps =
- gst_pad_peer_get_caps_reffed (GST_BASE_TRANSFORM_SINK_PAD (trans));
- /* try fixating by intersecting with peer caps */
- if (peercaps) {
- GstCaps *intersect;
-
- intersect =
- gst_caps_intersect_full (sink_suggest, peercaps,
- GST_CAPS_INTERSECT_FIRST);
- gst_caps_unref (peercaps);
- gst_caps_unref (sink_suggest);
- sink_suggest = intersect;
- }
-
- if (gst_caps_is_empty (sink_suggest))
- goto not_supported;
-
- /* try the alloc caps if it is still not fixed */
- if (!gst_caps_is_fixed (sink_suggest)) {
- GstCaps *intersect;
-
- GST_DEBUG_OBJECT (trans, "Checking if the input caps is compatible "
- "with the non-fixed caps suggestion");
- intersect =
- gst_caps_intersect_full (sink_suggest, caps,
- GST_CAPS_INTERSECT_FIRST);
- if (!gst_caps_is_empty (intersect)) {
- GST_DEBUG_OBJECT (trans, "It is, using it");
- gst_caps_replace (&sink_suggest, caps);
- }
- gst_caps_unref (intersect);
- }
-
- /* be safe and call default fixate */
- sink_suggest = gst_caps_make_writable (sink_suggest);
- gst_pad_fixate_caps (GST_BASE_TRANSFORM_SINK_PAD (trans), sink_suggest);
-
- if (!gst_caps_is_fixed (sink_suggest)) {
- gst_caps_unref (sink_suggest);
- sink_suggest = NULL;
- }
-
- GST_DEBUG_OBJECT (trans, "Caps fixed to: %" GST_PTR_FORMAT,
- sink_suggest);
- }
-
- if (sink_suggest) {
- templ = gst_pad_get_pad_template_caps (pad);
-
- if (!gst_caps_can_intersect (sink_suggest, templ)) {
- GstCaps *allowed;
- GstCaps *peercaps;
-
- GST_DEBUG_OBJECT (trans,
- "Requested pad alloc caps are not supported: %" GST_PTR_FORMAT,
- sink_suggest);
- /* the requested pad alloc caps are not supported, so let's try
- * picking something allowed between the pads (they are linked,
- * there must be something) */
- allowed = gst_pad_get_allowed_caps (pad);
- if (allowed && !gst_caps_is_empty (allowed)) {
- GST_DEBUG_OBJECT (trans,
- "pads could agree on one of the following caps: " "%"
- GST_PTR_FORMAT, allowed);
- allowed = gst_caps_make_writable (allowed);
-
- if (klass->fixate_caps) {
- peercaps =
- gst_pad_get_allowed_caps (GST_BASE_TRANSFORM_SRC_PAD (trans));
- klass->fixate_caps (trans, GST_PAD_SRC, peercaps, allowed);
- gst_caps_unref (peercaps);
- }
-
- /* Fixate them to be safe if the subclass didn't do it */
- gst_caps_truncate (allowed);
- gst_pad_fixate_caps (pad, allowed);
- gst_caps_replace (&sink_suggest, allowed);
- gst_caps_unref (allowed);
-
- suggest = TRUE;
-
- GST_DEBUG_OBJECT (trans, "Fixated suggestion caps to %"
- GST_PTR_FORMAT, sink_suggest);
- } else {
- if (allowed)
- gst_caps_unref (allowed);
- goto not_supported;
- }
- }
- }
- }
-
- /* find the best format for the other side here we decide if we will proxy
- * the caps or not. */
- if (sink_suggest == NULL) {
- /* always proxy when the caps are NULL. When this is a new format, see if
- * we can proxy it downstream */
- GST_DEBUG_OBJECT (trans, "null caps, marking for proxy");
- priv->proxy_alloc = TRUE;
- } else {
- GstCaps *othercaps;
-
- /* we have a new format, see what we need to proxy to */
- othercaps = gst_base_transform_find_transform (trans, pad, sink_suggest);
- if (!othercaps || gst_caps_is_empty (othercaps)) {
- /* no transform possible, we certainly can't proxy */
- GST_DEBUG_OBJECT (trans, "can't find transform, disable proxy");
- priv->proxy_alloc = FALSE;
- } else {
- /* we transformed into something */
- if (gst_caps_is_equal (sink_suggest, othercaps)) {
- GST_DEBUG_OBJECT (trans,
- "best caps same as input, marking for proxy");
- priv->proxy_alloc = TRUE;
- } else {
- GST_DEBUG_OBJECT (trans,
- "best caps different from input, disable proxy");
- priv->proxy_alloc = FALSE;
- }
- }
- if (othercaps)
- gst_caps_unref (othercaps);
- }
- }
- /* remember the new caps */
- GST_OBJECT_LOCK (pad);
- gst_caps_replace (&priv->sink_alloc, sink_suggest);
- GST_OBJECT_UNLOCK (pad);
-
- proxy = priv->proxy_alloc;
- GST_DEBUG_OBJECT (trans, "doing default alloc, proxy %d, suggest %d", proxy,
- suggest);
-
- /* we only want to proxy if we have no suggestion pending, FIXME */
- if (proxy && !suggest) {
- GstCaps *newcaps;
-
- GST_DEBUG_OBJECT (trans, "proxy buffer-alloc with caps %p %" GST_PTR_FORMAT
- ", size %u", caps, caps, size);
-
- /* we always proxy the input caps, never the suggestion. The reason is that
- * We don't yet handle the caps of renegotiation in here. FIXME */
- res = gst_pad_alloc_buffer (trans->srcpad, offset, size, caps, buf);
- if (res != GST_FLOW_OK)
- goto alloc_failed;
- alloced = TRUE;
-
- /* check if the caps changed */
- newcaps = GST_BUFFER_CAPS (*buf);
-
- GST_DEBUG_OBJECT (trans, "got caps %" GST_PTR_FORMAT, newcaps);
-
- if (!gst_caps_is_equal (newcaps, caps)) {
- GST_DEBUG_OBJECT (trans, "caps are new");
- /* we have new caps, see if we can proxy downstream */
- if (gst_pad_peer_accept_caps (pad, newcaps)) {
- /* peer accepts the caps, return a buffer in this format */
- GST_DEBUG_OBJECT (trans, "peer accepted new caps");
- /* remember the format */
- GST_OBJECT_LOCK (pad);
- gst_caps_replace (&priv->sink_alloc, newcaps);
- GST_OBJECT_UNLOCK (pad);
- } else {
- GST_DEBUG_OBJECT (trans, "peer did not accept new caps");
- /* peer does not accept the caps, disable proxy_alloc, free the
- * buffer we received and create a buffer of the requested format
- * by the default handler. */
- GST_DEBUG_OBJECT (trans, "disabling proxy");
- priv->proxy_alloc = FALSE;
- gst_buffer_unref (*buf);
- *buf = NULL;
- }
- } else {
- GST_DEBUG_OBJECT (trans, "received required caps from peer");
- }
- }
-
- if (suggest) {
- /* there was a custom suggestion, create a buffer of this format and return
- * it. Note that this format */
- *buf = gst_buffer_new_and_alloc (size_suggest);
- GST_DEBUG_OBJECT (trans,
- "doing suggestion of size %u, caps %p %" GST_PTR_FORMAT, size_suggest,
- sink_suggest, sink_suggest);
- GST_BUFFER_CAPS (*buf) = sink_suggest;
- sink_suggest = NULL;
- }
-
- if (sink_suggest)
- gst_caps_unref (sink_suggest);
-
- if (res == GST_FLOW_OK && alloced) {
- /* just alloc'ed a buffer, so we only want to do this again if we
- * received a buffer */
- GST_DEBUG_OBJECT (trans, "Cleaning force alloc");
- trans->priv->force_alloc = FALSE;
- }
-
- gst_object_unref (trans);
- return res;
-
- /* ERRORS */
-alloc_failed:
- {
- GST_DEBUG_OBJECT (trans, "pad alloc failed: %s", gst_flow_get_name (res));
- if (sink_suggest)
- gst_caps_unref (sink_suggest);
- gst_object_unref (trans);
- return res;
- }
-not_supported:
- {
- GST_DEBUG_OBJECT (trans, "pad alloc with unsupported caps");
- if (sink_suggest)
- gst_caps_unref (sink_suggest);
- gst_object_unref (trans);
- return GST_FLOW_NOT_NEGOTIATED;
- }
-}
-
static gboolean
gst_base_transform_sink_event (GstPad * pad, GstEvent * event)
{
@@ -2046,6 +1632,8 @@ gst_base_transform_sink_event (GstPad * pad, GstEvent * event)
static gboolean
gst_base_transform_sink_eventfunc (GstBaseTransform * trans, GstEvent * event)
{
+ gboolean forward = TRUE;
+
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_FLUSH_START:
break;
@@ -2059,51 +1647,38 @@ gst_base_transform_sink_eventfunc (GstBaseTransform * trans, GstEvent * event)
trans->priv->dropped = 0;
GST_OBJECT_UNLOCK (trans);
/* we need new segment info after the flush. */
- trans->have_newsegment = FALSE;
+ trans->have_segment = FALSE;
gst_segment_init (&trans->segment, GST_FORMAT_UNDEFINED);
- trans->priv->last_stop_out = GST_CLOCK_TIME_NONE;
+ trans->priv->position_out = GST_CLOCK_TIME_NONE;
break;
case GST_EVENT_EOS:
break;
case GST_EVENT_TAG:
break;
- case GST_EVENT_NEWSEGMENT:
+ case GST_EVENT_CAPS:
{
- GstFormat format;
- gdouble rate, arate;
- gint64 start, stop, time;
- gboolean update;
-
- gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
- &start, &stop, &time);
-
- trans->have_newsegment = TRUE;
-
- gst_segment_set_newsegment_full (&trans->segment, update, rate, arate,
- format, start, stop, time);
-
- if (format == GST_FORMAT_TIME) {
- GST_DEBUG_OBJECT (trans, "received TIME NEW_SEGMENT %" GST_TIME_FORMAT
- " -- %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT
- ", accum %" GST_TIME_FORMAT,
- GST_TIME_ARGS (trans->segment.start),
- GST_TIME_ARGS (trans->segment.stop),
- GST_TIME_ARGS (trans->segment.time),
- GST_TIME_ARGS (trans->segment.accum));
- } else {
- GST_DEBUG_OBJECT (trans, "received NEW_SEGMENT %" G_GINT64_FORMAT
- " -- %" G_GINT64_FORMAT ", time %" G_GINT64_FORMAT
- ", accum %" G_GINT64_FORMAT,
- trans->segment.start, trans->segment.stop,
- trans->segment.time, trans->segment.accum);
- }
+ GstCaps *caps;
+
+ gst_event_parse_caps (event, &caps);
+ gst_base_transform_setcaps (trans, trans->sinkpad, caps);
+
+ forward = FALSE;
+ break;
+ }
+ case GST_EVENT_SEGMENT:
+ {
+ gst_event_copy_segment (event, &trans->segment);
+ trans->have_segment = TRUE;
+
+ GST_DEBUG_OBJECT (trans, "received SEGMENT %" GST_SEGMENT_FORMAT,
+ &trans->segment);
break;
}
default:
break;
}
- return TRUE;
+ return forward;
}
static gboolean
@@ -2149,7 +1724,7 @@ gst_base_transform_src_eventfunc (GstBaseTransform * trans, GstEvent * event)
GstClockTimeDiff diff;
GstClockTime timestamp;
- gst_event_parse_qos (event, &proportion, &diff, &timestamp);
+ gst_event_parse_qos (event, NULL, &proportion, &diff, &timestamp);
gst_base_transform_update_qos (trans, proportion, diff, timestamp);
break;
}
@@ -2173,36 +1748,51 @@ gst_base_transform_handle_buffer (GstBaseTransform * trans, GstBuffer * inbuf,
{
GstBaseTransformClass *bclass;
GstFlowReturn ret = GST_FLOW_OK;
- gboolean want_in_place, reconfigure;
+ gboolean want_in_place;
GstClockTime running_time;
GstClockTime timestamp;
- GstCaps *incaps;
+ gsize insize;
+ gboolean reconfigure;
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
- if (G_LIKELY ((incaps = GST_BUFFER_CAPS (inbuf)))) {
- GST_OBJECT_LOCK (trans);
- reconfigure = trans->priv->reconfigure;
- trans->priv->reconfigure = FALSE;
- GST_OBJECT_UNLOCK (trans);
+ GST_OBJECT_LOCK (trans->sinkpad);
+ reconfigure = GST_PAD_NEEDS_RECONFIGURE (trans->srcpad)
+ || trans->priv->reconfigure;
+ GST_OBJECT_FLAG_UNSET (trans->srcpad, GST_PAD_NEED_RECONFIGURE);
+ trans->priv->reconfigure = FALSE;
+ GST_OBJECT_UNLOCK (trans->sinkpad);
+
+ if (G_UNLIKELY (reconfigure)) {
+ GstCaps *incaps;
+
+ GST_DEBUG_OBJECT (trans, "we had a pending reconfigure");
+
+ incaps = gst_pad_get_current_caps (trans->sinkpad);
+ if (incaps == NULL)
+ goto no_reconfigure;
- if (G_UNLIKELY (reconfigure)) {
- GST_DEBUG_OBJECT (trans, "we had a pending reconfigure");
- /* if we need to reconfigure we pretend a buffer with new caps arrived. This
- * will reconfigure the transform with the new output format. We can only
- * do this if the buffer actually has caps. */
- if (!gst_base_transform_setcaps (trans->sinkpad, incaps))
- goto not_negotiated;
+ /* if we need to reconfigure we pretend a buffer with new caps arrived. This
+ * will reconfigure the transform with the new output format. We can only
+ * do this if the buffer actually has caps. */
+ if (!gst_base_transform_setcaps (trans, trans->sinkpad, incaps)) {
+ gst_caps_unref (incaps);
+ goto not_negotiated;
}
+ gst_caps_unref (incaps);
}
+no_reconfigure:
+ insize = gst_buffer_get_size (inbuf);
+
if (GST_BUFFER_OFFSET_IS_VALID (inbuf))
- GST_DEBUG_OBJECT (trans, "handling buffer %p of size %d and offset %"
- G_GUINT64_FORMAT, inbuf, GST_BUFFER_SIZE (inbuf),
- GST_BUFFER_OFFSET (inbuf));
+ GST_DEBUG_OBJECT (trans,
+ "handling buffer %p of size %" G_GSIZE_FORMAT " and offset %"
+ G_GUINT64_FORMAT, inbuf, insize, GST_BUFFER_OFFSET (inbuf));
else
- GST_DEBUG_OBJECT (trans, "handling buffer %p of size %d and offset NONE",
- inbuf, GST_BUFFER_SIZE (inbuf));
+ GST_DEBUG_OBJECT (trans,
+ "handling buffer %p of size %" G_GSIZE_FORMAT " and offset NONE", inbuf,
+ insize);
/* Don't allow buffer handling before negotiation, except in passthrough mode
* or if the class doesn't implement a set_caps function (in which case it doesn't
@@ -2277,9 +1867,7 @@ gst_base_transform_handle_buffer (GstBaseTransform * trans, GstBuffer * inbuf,
no_qos:
/* first try to allocate an output buffer based on the currently negotiated
- * format. While we call pad-alloc we could renegotiate the srcpad format or
- * have a new suggestion for upstream buffer-alloc.
- * In any case, outbuf will contain a buffer suitable for doing the configured
+ * format. outbuf will contain a buffer suitable for doing the configured
* transform after this function. */
ret = gst_base_transform_prepare_output_buffer (trans, inbuf, outbuf);
if (G_UNLIKELY (ret != GST_FLOW_OK))
@@ -2304,16 +1892,20 @@ no_qos:
if (inbuf != *outbuf) {
guint8 *indata, *outdata;
+ gsize insize, outsize;
/* Different buffer. The data can still be the same when we are dealing
* with subbuffers of the same buffer. Note that because of the FIXME in
* prepare_output_buffer() we have decreased the refcounts of inbuf and
* outbuf to keep them writable */
- indata = GST_BUFFER_DATA (inbuf);
- outdata = GST_BUFFER_DATA (*outbuf);
+ indata = gst_buffer_map (inbuf, &insize, NULL, GST_MAP_READ);
+ outdata = gst_buffer_map (*outbuf, &outsize, NULL, GST_MAP_WRITE);
if (indata != outdata)
- memcpy (outdata, indata, GST_BUFFER_SIZE (inbuf));
+ memcpy (outdata, indata, insize);
+
+ gst_buffer_unmap (inbuf, indata, insize);
+ gst_buffer_unmap (*outbuf, outdata, outsize);
}
ret = bclass->transform_ip (trans, *outbuf);
} else {
@@ -2331,9 +1923,6 @@ skip:
if (*outbuf != inbuf)
gst_buffer_unref (inbuf);
- /* pushed a buffer, we can now try an alloc */
- GST_DEBUG_OBJECT (trans, "Pushed a buffer, setting force alloc to true");
- trans->priv->force_alloc = TRUE;
return ret;
/* ERRORS */
@@ -2347,27 +1936,13 @@ not_negotiated:
no_buffer:
{
gst_buffer_unref (inbuf);
+ *outbuf = NULL;
GST_WARNING_OBJECT (trans, "could not get buffer from pool: %s",
gst_flow_get_name (ret));
return ret;
}
}
-static gboolean
-gst_base_transform_check_get_range (GstPad * pad)
-{
- GstBaseTransform *trans;
- gboolean ret;
-
- trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
-
- ret = gst_pad_check_pull_range (trans->sinkpad);
-
- gst_object_unref (trans);
-
- return ret;
-}
-
/* FIXME, getrange is broken, need to pull range from the other
* end based on the transform_size result.
*/
@@ -2414,7 +1989,7 @@ gst_base_transform_chain (GstPad * pad, GstBuffer * buffer)
GstBaseTransform *trans;
GstBaseTransformClass *klass;
GstFlowReturn ret;
- GstClockTime last_stop = GST_CLOCK_TIME_NONE;
+ GstClockTime position = GST_CLOCK_TIME_NONE;
GstClockTime timestamp, duration;
GstBuffer *outbuf = NULL;
@@ -2426,9 +2001,9 @@ gst_base_transform_chain (GstPad * pad, GstBuffer * buffer)
/* calculate end position of the incoming buffer */
if (timestamp != GST_CLOCK_TIME_NONE) {
if (duration != GST_CLOCK_TIME_NONE)
- last_stop = timestamp + duration;
+ position = timestamp + duration;
else
- last_stop = timestamp;
+ position = timestamp;
}
klass = GST_BASE_TRANSFORM_GET_CLASS (trans);
@@ -2443,29 +2018,29 @@ gst_base_transform_chain (GstPad * pad, GstBuffer * buffer)
/* outbuf can be NULL, this means a dropped buffer, if we have a buffer but
* GST_BASE_TRANSFORM_FLOW_DROPPED we will not push either. */
if (outbuf != NULL) {
- if ((ret == GST_FLOW_OK)) {
- GstClockTime last_stop_out = GST_CLOCK_TIME_NONE;
+ if (ret == GST_FLOW_OK) {
+ GstClockTime position_out = GST_CLOCK_TIME_NONE;
/* Remember last stop position */
- if (last_stop != GST_CLOCK_TIME_NONE &&
+ if (position != GST_CLOCK_TIME_NONE &&
trans->segment.format == GST_FORMAT_TIME)
- gst_segment_set_last_stop (&trans->segment, GST_FORMAT_TIME, last_stop);
+ trans->segment.position = position;
if (GST_BUFFER_TIMESTAMP_IS_VALID (outbuf)) {
- last_stop_out = GST_BUFFER_TIMESTAMP (outbuf);
+ position_out = GST_BUFFER_TIMESTAMP (outbuf);
if (GST_BUFFER_DURATION_IS_VALID (outbuf))
- last_stop_out += GST_BUFFER_DURATION (outbuf);
- } else if (last_stop != GST_CLOCK_TIME_NONE) {
- last_stop_out = last_stop;
+ position_out += GST_BUFFER_DURATION (outbuf);
+ } else if (position != GST_CLOCK_TIME_NONE) {
+ position_out = position;
}
- if (last_stop_out != GST_CLOCK_TIME_NONE
+ if (position_out != GST_CLOCK_TIME_NONE
&& trans->segment.format == GST_FORMAT_TIME)
- trans->priv->last_stop_out = last_stop_out;
+ trans->priv->position_out = position_out;
/* apply DISCONT flag if the buffer is not yet marked as such */
if (trans->priv->discont) {
if (!GST_BUFFER_IS_DISCONT (outbuf)) {
- outbuf = gst_buffer_make_metadata_writable (outbuf);
+ outbuf = gst_buffer_make_writable (outbuf);
GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
}
trans->priv->discont = FALSE;
@@ -2532,31 +2107,36 @@ gst_base_transform_activate (GstBaseTransform * trans, gboolean active)
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
if (active) {
+ GstCaps *incaps, *outcaps;
+
if (trans->priv->pad_mode == GST_ACTIVATE_NONE && bclass->start)
result &= bclass->start (trans);
- GST_OBJECT_LOCK (trans);
+ incaps = gst_pad_get_current_caps (trans->sinkpad);
+ outcaps = gst_pad_get_current_caps (trans->srcpad);
- if (GST_PAD_CAPS (trans->sinkpad) && GST_PAD_CAPS (trans->srcpad))
+ GST_OBJECT_LOCK (trans);
+ if (incaps && outcaps)
trans->have_same_caps =
- gst_caps_is_equal (GST_PAD_CAPS (trans->sinkpad),
- GST_PAD_CAPS (trans->srcpad)) || trans->passthrough;
+ gst_caps_is_equal (incaps, outcaps) || trans->passthrough;
else
trans->have_same_caps = trans->passthrough;
GST_DEBUG_OBJECT (trans, "have_same_caps %d", trans->have_same_caps);
trans->negotiated = FALSE;
- trans->have_newsegment = FALSE;
+ trans->have_segment = FALSE;
gst_segment_init (&trans->segment, GST_FORMAT_UNDEFINED);
- trans->priv->last_stop_out = GST_CLOCK_TIME_NONE;
+ trans->priv->position_out = GST_CLOCK_TIME_NONE;
trans->priv->proportion = 1.0;
trans->priv->earliest_time = -1;
trans->priv->discont = FALSE;
- gst_caps_replace (&trans->priv->sink_suggest, NULL);
trans->priv->processed = 0;
trans->priv->dropped = 0;
- trans->priv->force_alloc = TRUE;
-
GST_OBJECT_UNLOCK (trans);
+
+ if (incaps)
+ gst_caps_unref (incaps);
+ if (outcaps)
+ gst_caps_unref (outcaps);
} else {
/* We must make sure streaming has finished before resetting things
* and calling the ::stop vfunc */
@@ -2571,11 +2151,11 @@ gst_base_transform_activate (GstBaseTransform * trans, gboolean active)
}
gst_caps_replace (&trans->cache_caps1, NULL);
gst_caps_replace (&trans->cache_caps2, NULL);
- gst_caps_replace (&trans->priv->sink_alloc, NULL);
- gst_caps_replace (&trans->priv->sink_suggest, NULL);
if (trans->priv->pad_mode != GST_ACTIVATE_NONE && bclass->stop)
result &= bclass->stop (trans);
+
+ gst_base_transform_set_allocation (trans, NULL, NULL, 0, 0);
}
return result;
@@ -2866,20 +2446,14 @@ gst_base_transform_set_gap_aware (GstBaseTransform * trans, gboolean gap_aware)
*/
void
gst_base_transform_suggest (GstBaseTransform * trans, GstCaps * caps,
- guint size)
+ gsize size)
{
g_return_if_fail (GST_IS_BASE_TRANSFORM (trans));
- GST_OBJECT_LOCK (trans->sinkpad);
- if (trans->priv->sink_suggest)
- gst_caps_unref (trans->priv->sink_suggest);
- if (caps)
- caps = gst_caps_copy (caps);
- trans->priv->sink_suggest = caps;
- trans->priv->size_suggest = size;
- trans->priv->suggest_pending = TRUE;
- GST_DEBUG_OBJECT (trans, "new suggest %" GST_PTR_FORMAT, caps);
- GST_OBJECT_UNLOCK (trans->sinkpad);
+ /* push the renegotiate event */
+ if (!gst_pad_push_event (GST_BASE_TRANSFORM_SINK_PAD (trans),
+ gst_event_new_reconfigure ()))
+ GST_DEBUG_OBJECT (trans, "Renegotiate event wasn't handled");
}
/**
@@ -2900,6 +2474,5 @@ gst_base_transform_reconfigure (GstBaseTransform * trans)
GST_OBJECT_LOCK (trans);
GST_DEBUG_OBJECT (trans, "marking reconfigure");
trans->priv->reconfigure = TRUE;
- gst_caps_replace (&trans->priv->sink_alloc, NULL);
GST_OBJECT_UNLOCK (trans);
}
diff --git a/libs/gst/base/gstbasetransform.h b/libs/gst/base/gstbasetransform.h
index 72c2b2a9de..d81b0055c5 100644
--- a/libs/gst/base/gstbasetransform.h
+++ b/libs/gst/base/gstbasetransform.h
@@ -119,16 +119,16 @@ struct _GstBaseTransform {
gboolean always_in_place;
GstCaps *cache_caps1;
- guint cache_caps1_size;
+ gsize cache_caps1_size;
GstCaps *cache_caps2;
- guint cache_caps2_size;
+ gsize cache_caps2_size;
gboolean have_same_caps;
gboolean delay_configure;
gboolean pending_configure;
gboolean negotiated;
- gboolean have_newsegment;
+ gboolean have_segment;
/* MT-protected (with STREAM_LOCK) */
GstSegment segment;
@@ -138,7 +138,7 @@ struct _GstBaseTransform {
/*< private >*/
GstBaseTransformPrivate *priv;
- gpointer _gst_reserved[GST_PADDING_LARGE - 1];
+ gpointer _gst_reserved[GST_PADDING_LARGE];
};
/**
@@ -200,52 +200,52 @@ struct _GstBaseTransformClass {
GstElementClass parent_class;
/*< public >*/
- /* virtual methods for subclasses */
+ gboolean passthrough_on_same_caps;
+ /* virtual methods for subclasses */
GstCaps* (*transform_caps) (GstBaseTransform *trans,
GstPadDirection direction,
- GstCaps *caps);
-
+ GstCaps *caps, GstCaps *filter);
void (*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);
+
+ /* setup allocation query */
+ gboolean (*setup_allocation) (GstBaseTransform *trans, GstQuery *query);
+ /* transform size */
gboolean (*transform_size) (GstBaseTransform *trans,
GstPadDirection direction,
- GstCaps *caps, guint size,
- GstCaps *othercaps, guint *othersize);
+ GstCaps *caps, gsize size,
+ GstCaps *othercaps, gsize *othersize);
gboolean (*get_unit_size) (GstBaseTransform *trans, GstCaps *caps,
- guint *size);
-
- gboolean (*set_caps) (GstBaseTransform *trans, GstCaps *incaps,
- GstCaps *outcaps);
+ gsize *size);
+ /* states */
gboolean (*start) (GstBaseTransform *trans);
gboolean (*stop) (GstBaseTransform *trans);
gboolean (*event) (GstBaseTransform *trans, GstEvent *event);
-
- GstFlowReturn (*transform) (GstBaseTransform *trans, GstBuffer *inbuf,
- GstBuffer *outbuf);
- GstFlowReturn (*transform_ip) (GstBaseTransform *trans, GstBuffer *buf);
-
- /* FIXME: When adjusting the padding, move these to nicer places in the class */
- gboolean passthrough_on_same_caps;
+ /* src event */
+ gboolean (*src_event) (GstBaseTransform *trans, GstEvent *event);
GstFlowReturn (*prepare_output_buffer) (GstBaseTransform * trans,
GstBuffer *input, gint size, GstCaps *caps, GstBuffer **buf);
- /* src event */
- gboolean (*src_event) (GstBaseTransform *trans, GstEvent *event);
-
void (*before_transform) (GstBaseTransform *trans, GstBuffer *buffer);
- gboolean (*accept_caps) (GstBaseTransform *trans, GstPadDirection direction,
- GstCaps *caps);
+ /* transform */
+ GstFlowReturn (*transform) (GstBaseTransform *trans, GstBuffer *inbuf,
+ GstBuffer *outbuf);
+ GstFlowReturn (*transform_ip) (GstBaseTransform *trans, GstBuffer *buf);
/*< private >*/
- gpointer _gst_reserved[GST_PADDING_LARGE - 3];
+ gpointer _gst_reserved[GST_PADDING_LARGE];
};
GType gst_base_transform_get_type (void);
@@ -270,7 +270,7 @@ void gst_base_transform_set_gap_aware (GstBaseTransform *trans,
gboolean gap_aware);
void gst_base_transform_suggest (GstBaseTransform *trans,
- GstCaps *caps, guint size);
+ GstCaps *caps, gsize size);
void gst_base_transform_reconfigure (GstBaseTransform *trans);
G_END_DECLS
diff --git a/libs/gst/base/gstbitreader.c b/libs/gst/base/gstbitreader.c
index a4393992cb..ee369cb509 100644
--- a/libs/gst/base/gstbitreader.c
+++ b/libs/gst/base/gstbitreader.c
@@ -61,33 +61,11 @@ gst_bit_reader_new (const guint8 * data, guint size)
}
/**
- * gst_bit_reader_new_from_buffer:
- * @buffer: Buffer from which the #GstBitReader should read
- *
- * Create a new #GstBitReader instance, which will read from the
- * #GstBuffer @buffer.
- *
- * Free-function: gst_bit_reader_free
- *
- * Returns: (transfer full): a new #GstBitReader instance
- *
- * Since: 0.10.22
- */
-GstBitReader *
-gst_bit_reader_new_from_buffer (const GstBuffer * buffer)
-{
- g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
-
- return gst_bit_reader_new (GST_BUFFER_DATA (buffer),
- GST_BUFFER_SIZE (buffer));
-}
-
-/**
* gst_bit_reader_free:
* @reader: (in) (transfer full): a #GstBitReader instance
*
* Frees a #GstBitReader instance, which was previously allocated by
- * gst_bit_reader_new() or gst_bit_reader_new_from_buffer().
+ * gst_bit_reader_new().
*
* Since: 0.10.22
*/
@@ -121,26 +99,6 @@ gst_bit_reader_init (GstBitReader * reader, const guint8 * data, guint size)
}
/**
- * gst_bit_reader_init_from_buffer:
- * @reader: a #GstBitReader instance
- * @buffer: (transfer none): Buffer from which the #GstBitReader should read
- *
- * Initializes a #GstBitReader instance to read from @buffer. This function
- * can be called on already initialized instances.
- *
- * Since: 0.10.22
- */
-void
-gst_bit_reader_init_from_buffer (GstBitReader * reader,
- const GstBuffer * buffer)
-{
- g_return_if_fail (GST_IS_BUFFER (buffer));
-
- gst_bit_reader_init (reader, GST_BUFFER_DATA (buffer),
- GST_BUFFER_SIZE (buffer));
-}
-
-/**
* gst_bit_reader_set_pos:
* @reader: a #GstBitReader instance
* @pos: The new position in bits
diff --git a/libs/gst/base/gstbitreader.h b/libs/gst/base/gstbitreader.h
index b5c3935e7e..e42e3bfd9e 100644
--- a/libs/gst/base/gstbitreader.h
+++ b/libs/gst/base/gstbitreader.h
@@ -47,11 +47,9 @@ typedef struct {
} GstBitReader;
GstBitReader * gst_bit_reader_new (const guint8 *data, guint size);
-GstBitReader * gst_bit_reader_new_from_buffer (const GstBuffer *buffer);
void gst_bit_reader_free (GstBitReader *reader);
void gst_bit_reader_init (GstBitReader *reader, const guint8 *data, guint size);
-void gst_bit_reader_init_from_buffer (GstBitReader *reader, const GstBuffer *buffer);
gboolean gst_bit_reader_set_pos (GstBitReader *reader, guint pos);
@@ -87,19 +85,6 @@ gboolean gst_bit_reader_peek_bits_uint64 (const GstBitReader *reader, guint64 *v
*/
#define GST_BIT_READER_INIT(data, size) {data, size, 0, 0}
-/**
- * GST_BIT_READER_INIT_FROM_BUFFER:
- * @buffer: Buffer from which the #GstBitReader should read
- *
- * 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().
- *
- * Since: 0.10.22
- */
-#define GST_BIT_READER_INIT_FROM_BUFFER(buffer) {GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), 0, 0}
-
/* Unchecked variants */
static inline void
diff --git a/libs/gst/base/gstbytereader.c b/libs/gst/base/gstbytereader.c
index e0cc7237f1..97da6ec4b4 100644
--- a/libs/gst/base/gstbytereader.c
+++ b/libs/gst/base/gstbytereader.c
@@ -67,33 +67,11 @@ gst_byte_reader_new (const guint8 * data, guint size)
}
/**
- * gst_byte_reader_new_from_buffer:
- * @buffer: (transfer none): Buffer from which the #GstByteReader should read
- *
- * Create a new #GstByteReader instance, which will read from the
- * #GstBuffer @buffer.
- *
- * Free-function: gst_byte_reader_free
- *
- * Returns: (transfer full): a new #GstByteReader instance
- *
- * Since: 0.10.22
- */
-GstByteReader *
-gst_byte_reader_new_from_buffer (const GstBuffer * buffer)
-{
- g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
-
- return gst_byte_reader_new (GST_BUFFER_DATA (buffer),
- GST_BUFFER_SIZE (buffer));
-}
-
-/**
* gst_byte_reader_free:
* @reader: (in) (transfer full): a #GstByteReader instance
*
* Frees a #GstByteReader instance, which was previously allocated by
- * gst_byte_reader_new() or gst_byte_reader_new_from_buffer().
+ * gst_byte_reader_new().
*
* Since: 0.10.22
*/
@@ -128,26 +106,6 @@ gst_byte_reader_init (GstByteReader * reader, const guint8 * data, guint size)
}
/**
- * gst_byte_reader_init_from_buffer:
- * @reader: a #GstByteReader instance
- * @buffer: (transfer none): Buffer from which the #GstByteReader should read
- *
- * Initializes a #GstByteReader instance to read from @buffer. This function
- * can be called on already initialized instances.
- *
- * Since: 0.10.22
- */
-void
-gst_byte_reader_init_from_buffer (GstByteReader * reader,
- const GstBuffer * buffer)
-{
- g_return_if_fail (GST_IS_BUFFER (buffer));
-
- gst_byte_reader_init (reader, GST_BUFFER_DATA (buffer),
- GST_BUFFER_SIZE (buffer));
-}
-
-/**
* gst_byte_reader_set_pos:
* @reader: a #GstByteReader instance
* @pos: The new position in bytes
diff --git a/libs/gst/base/gstbytereader.h b/libs/gst/base/gstbytereader.h
index 8ce76df334..9c3c4f46a6 100644
--- a/libs/gst/base/gstbytereader.h
+++ b/libs/gst/base/gstbytereader.h
@@ -44,11 +44,9 @@ typedef struct {
} GstByteReader;
GstByteReader * gst_byte_reader_new (const guint8 *data, guint size);
-GstByteReader * gst_byte_reader_new_from_buffer (const GstBuffer *buffer);
void gst_byte_reader_free (GstByteReader *reader);
void gst_byte_reader_init (GstByteReader *reader, const guint8 *data, guint size);
-void gst_byte_reader_init_from_buffer (GstByteReader *reader, const GstBuffer *buffer);
gboolean gst_byte_reader_set_pos (GstByteReader *reader, guint pos);
@@ -154,20 +152,6 @@ guint gst_byte_reader_masked_scan_uint32 (const GstByteReader * reader,
*/
#define GST_BYTE_READER_INIT(data, size) {data, size, 0}
-/**
- * GST_BYTE_READER_INIT_FROM_BUFFER:
- * @buffer: Buffer from which the #GstByteReader should read
- *
- * 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().
- *
- * Since: 0.10.22
- */
-#define GST_BYTE_READER_INIT_FROM_BUFFER(buffer) {GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), 0}
-
-
/* unchecked variants */
static inline void
gst_byte_reader_skip_unchecked (GstByteReader * reader, guint nbytes)
diff --git a/libs/gst/base/gstbytewriter.c b/libs/gst/base/gstbytewriter.c
index 25564f7d97..969b705143 100644
--- a/libs/gst/base/gstbytewriter.c
+++ b/libs/gst/base/gstbytewriter.c
@@ -116,33 +116,6 @@ gst_byte_writer_new_with_data (guint8 * data, guint size, gboolean initialized)
}
/**
- * gst_byte_writer_new_with_buffer:
- * @buffer: Buffer used for writing
- * @initialized: If %TRUE the complete data can be read from the beginning
- *
- * Creates a new #GstByteWriter instance with the given
- * buffer. If @initialized is %TRUE it is possible to
- * read the complete buffer from the #GstByteWriter from the beginning.
- *
- * <note>@buffer must be writable</note>
- *
- * Free-function: gst_byte_writer_free
- *
- * Returns: (transfer full): a new #GstByteWriter instance
- *
- * Since: 0.10.26
- */
-GstByteWriter *
-gst_byte_writer_new_with_buffer (GstBuffer * buffer, gboolean initialized)
-{
- g_return_val_if_fail (GST_IS_BUFFER (buffer)
- && gst_buffer_is_writable (buffer), NULL);
-
- return gst_byte_writer_new_with_data (GST_BUFFER_DATA (buffer),
- GST_BUFFER_SIZE (buffer), initialized);
-}
-
-/**
* gst_byte_writer_init:
* @writer: #GstByteWriter instance
*
@@ -214,30 +187,6 @@ gst_byte_writer_init_with_data (GstByteWriter * writer, guint8 * data,
}
/**
- * gst_byte_writer_init_with_buffer:
- * @writer: #GstByteWriter instance
- * @buffer: (transfer none): Buffer used for writing
- * @initialized: If %TRUE the complete data can be read from the beginning
- *
- * Initializes @writer with the given
- * buffer. If @initialized is %TRUE it is possible to
- * read the complete buffer from the #GstByteWriter from the beginning.
- *
- * <note>@buffer must be writable</note>
- *
- * Since: 0.10.26
- */
-void
-gst_byte_writer_init_with_buffer (GstByteWriter * writer, GstBuffer * buffer,
- gboolean initialized)
-{
- g_return_if_fail (GST_IS_BUFFER (buffer) && gst_buffer_is_writable (buffer));
-
- gst_byte_writer_init_with_data (writer, GST_BUFFER_DATA (buffer),
- GST_BUFFER_SIZE (buffer), initialized);
-}
-
-/**
* gst_byte_writer_reset:
* @writer: #GstByteWriter instance
*
@@ -301,13 +250,19 @@ GstBuffer *
gst_byte_writer_reset_and_get_buffer (GstByteWriter * writer)
{
GstBuffer *buffer;
+ gpointer data;
+ gsize size;
g_return_val_if_fail (writer != NULL, NULL);
+ size = writer->parent.size;
+ data = gst_byte_writer_reset_and_get_data (writer);
+
buffer = gst_buffer_new ();
- GST_BUFFER_SIZE (buffer) = writer->parent.size;
- GST_BUFFER_MALLOCDATA (buffer) = gst_byte_writer_reset_and_get_data (writer);
- GST_BUFFER_DATA (buffer) = GST_BUFFER_MALLOCDATA (buffer);
+ if (data != NULL) {
+ gst_buffer_take_memory (buffer, -1,
+ gst_memory_new_wrapped (0, data, g_free, size, 0, size));
+ }
return buffer;
}
diff --git a/libs/gst/base/gstbytewriter.h b/libs/gst/base/gstbytewriter.h
index 8fcd53da6f..7cc68d25e3 100644
--- a/libs/gst/base/gstbytewriter.h
+++ b/libs/gst/base/gstbytewriter.h
@@ -51,12 +51,10 @@ typedef struct {
GstByteWriter * gst_byte_writer_new (void);
GstByteWriter * gst_byte_writer_new_with_size (guint size, gboolean fixed);
GstByteWriter * gst_byte_writer_new_with_data (guint8 *data, guint size, gboolean initialized);
-GstByteWriter * gst_byte_writer_new_with_buffer (GstBuffer *buffer, gboolean initialized);
void gst_byte_writer_init (GstByteWriter *writer);
void gst_byte_writer_init_with_size (GstByteWriter *writer, guint size, gboolean fixed);
void gst_byte_writer_init_with_data (GstByteWriter *writer, guint8 *data, guint size, gboolean initialized);
-void gst_byte_writer_init_with_buffer (GstByteWriter *writer, GstBuffer *buffer, gboolean initialized);
void gst_byte_writer_free (GstByteWriter *writer);
guint8 * gst_byte_writer_free_and_get_data (GstByteWriter *writer);
diff --git a/libs/gst/base/gstcollectpads.c b/libs/gst/base/gstcollectpads.c
index 004508d321..fccb52c9f2 100644
--- a/libs/gst/base/gstcollectpads.c
+++ b/libs/gst/base/gstcollectpads.c
@@ -86,7 +86,8 @@ struct _GstCollectPadsPrivate
gpointer clipfunc_user_data;
};
-GST_BOILERPLATE (GstCollectPads, gst_collect_pads, GstObject, GST_TYPE_OBJECT);
+#define gst_collect_pads_parent_class parent_class
+G_DEFINE_TYPE (GstCollectPads, gst_collect_pads, GST_TYPE_OBJECT);
static void gst_collect_pads_clear (GstCollectPads * pads,
GstCollectData * data);
@@ -98,12 +99,6 @@ static void unref_data (GstCollectData * data);
static void gst_collect_pads_check_pads_unlocked (GstCollectPads * pads);
static void
-gst_collect_pads_base_init (gpointer g_class)
-{
- /* Do nothing here */
-}
-
-static void
gst_collect_pads_class_init (GstCollectPadsClass * klass)
{
GObjectClass *gobject_class = (GObjectClass *) klass;
@@ -117,7 +112,7 @@ gst_collect_pads_class_init (GstCollectPadsClass * klass)
}
static void
-gst_collect_pads_init (GstCollectPads * pads, GstCollectPadsClass * g_class)
+gst_collect_pads_init (GstCollectPads * pads)
{
pads->abidata.ABI.priv = GST_COLLECT_PADS_GET_PRIVATE (pads);
@@ -861,7 +856,7 @@ gst_collect_pads_available (GstCollectPads * pads)
}
/* this is the size left of the buffer */
- size = GST_BUFFER_SIZE (buffer) - pdata->pos;
+ size = gst_buffer_get_size (buffer) - pdata->pos;
GST_DEBUG ("pad %s:%s has %d bytes left",
GST_DEBUG_PAD_NAME (pdata->pad), size);
@@ -882,48 +877,6 @@ not_filled:
}
/**
- * gst_collect_pads_read:
- * @pads: the collectspads to query
- * @data: the data to use
- * @bytes: (out) (transfer none) (array length=size): a pointer to a byte array
- * @size: the number of bytes to read
- *
- * Get a pointer in @bytes where @size bytes can be read from the
- * given pad @data.
- *
- * This function should be called with @pads LOCK held, such as
- * in the callback.
- *
- * MT safe.
- *
- * Returns: The number of bytes available for consumption in the
- * memory pointed to by @bytes. This can be less than @size and
- * is 0 if the pad is end-of-stream.
- */
-guint
-gst_collect_pads_read (GstCollectPads * pads, GstCollectData * data,
- guint8 ** bytes, guint size)
-{
- guint readsize;
- GstBuffer *buffer;
-
- g_return_val_if_fail (pads != NULL, 0);
- g_return_val_if_fail (GST_IS_COLLECT_PADS (pads), 0);
- g_return_val_if_fail (data != NULL, 0);
- g_return_val_if_fail (bytes != NULL, 0);
-
- /* no buffer, must be EOS */
- if ((buffer = data->buffer) == NULL)
- return 0;
-
- readsize = MIN (size, GST_BUFFER_SIZE (buffer) - data->pos);
-
- *bytes = GST_BUFFER_DATA (buffer) + data->pos;
-
- return readsize;
-}
-
-/**
* gst_collect_pads_read_buffer:
* @pads: the collectspads to query
* @data: the data to use
@@ -958,14 +911,15 @@ gst_collect_pads_read_buffer (GstCollectPads * pads, GstCollectData * data,
if ((buffer = data->buffer) == NULL)
return NULL;
- bufsize = GST_BUFFER_SIZE (buffer);
+ bufsize = gst_buffer_get_size (buffer);
readsize = MIN (size, bufsize - data->pos);
if (data->pos == 0 && readsize == bufsize)
return gst_buffer_ref (buffer);
else
- return gst_buffer_create_sub (buffer, data->pos, readsize);
+ return gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, data->pos,
+ readsize);
}
/**
@@ -996,7 +950,7 @@ gst_collect_pads_take_buffer (GstCollectPads * pads, GstCollectData * data,
GstBuffer *buffer = gst_collect_pads_read_buffer (pads, data, size);
if (buffer) {
- gst_collect_pads_flush (pads, data, GST_BUFFER_SIZE (buffer));
+ gst_collect_pads_flush (pads, data, gst_buffer_get_size (buffer));
}
return buffer;
}
@@ -1023,6 +977,7 @@ gst_collect_pads_flush (GstCollectPads * pads, GstCollectData * data,
{
guint flushsize;
GstBuffer *buffer;
+ gsize bsize;
g_return_val_if_fail (pads != NULL, 0);
g_return_val_if_fail (GST_IS_COLLECT_PADS (pads), 0);
@@ -1032,14 +987,16 @@ gst_collect_pads_flush (GstCollectPads * pads, GstCollectData * data,
if ((buffer = data->buffer) == NULL)
return 0;
+ bsize = gst_buffer_get_size (buffer);
+
/* this is what we can flush at max */
- flushsize = MIN (size, GST_BUFFER_SIZE (buffer) - data->pos);
+ flushsize = MIN (size, bsize - data->pos);
data->pos += size;
GST_LOG_OBJECT (pads, "Flushing %d bytes, requested %u", flushsize, size);
- if (data->pos >= GST_BUFFER_SIZE (buffer))
+ if (data->pos >= bsize)
/* _clear will also reset data->pos to 0 */
gst_collect_pads_clear (pads, data);
@@ -1241,23 +1198,12 @@ gst_collect_pads_event (GstPad * pad, GstEvent * event)
gst_event_unref (event);
goto done;
}
- case GST_EVENT_NEWSEGMENT:
+ case GST_EVENT_SEGMENT:
{
- gint64 start, stop, time;
- gdouble rate, arate;
- GstFormat format;
- gboolean update;
-
- gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
- &start, &stop, &time);
-
- GST_DEBUG_OBJECT (data->pad, "got newsegment, start %" GST_TIME_FORMAT
- ", stop %" GST_TIME_FORMAT, GST_TIME_ARGS (start),
- GST_TIME_ARGS (stop));
-
- gst_segment_set_newsegment_full (&data->segment, update, rate, arate,
- format, start, stop, time);
+ gst_event_copy_segment (event, &data->segment);
+ GST_DEBUG_OBJECT (data->pad, "got newsegment %" GST_SEGMENT_FORMAT,
+ &data->segment);
data->abidata.ABI.new_segment = TRUE;
/* we must not forward this event since multiple segments will be
@@ -1360,7 +1306,7 @@ gst_collect_pads_chain (GstPad * pad, GstBuffer * buffer)
GstClockTime timestamp = GST_BUFFER_TIMESTAMP (data->buffer);
if (GST_CLOCK_TIME_IS_VALID (timestamp))
- gst_segment_set_last_stop (&data->segment, GST_FORMAT_TIME, timestamp);
+ data->segment.position = timestamp;
}
/* While we have data queued on this pad try to collect stuff */
diff --git a/libs/gst/base/gstcollectpads.h b/libs/gst/base/gstcollectpads.h
index 939c2f63a3..ba6761eebe 100644
--- a/libs/gst/base/gstcollectpads.h
+++ b/libs/gst/base/gstcollectpads.h
@@ -209,8 +209,6 @@ GstBuffer* gst_collect_pads_pop (GstCollectPads *pads, GstCollec
/* get collected bytes */
guint gst_collect_pads_available (GstCollectPads *pads);
-guint gst_collect_pads_read (GstCollectPads *pads, GstCollectData *data,
- guint8 **bytes, guint size);
GstBuffer * gst_collect_pads_read_buffer (GstCollectPads * pads, GstCollectData * data,
guint size);
GstBuffer * gst_collect_pads_take_buffer (GstCollectPads * pads, GstCollectData * data,
diff --git a/libs/gst/base/gstdataqueue.c b/libs/gst/base/gstdataqueue.c
index f6b11177cb..69dadb4c0a 100644
--- a/libs/gst/base/gstdataqueue.c
+++ b/libs/gst/base/gstdataqueue.c
@@ -277,7 +277,7 @@ gst_data_queue_locked_flush (GstDataQueue * queue)
gst_data_queue_cleanup (queue);
STATUS (queue, "after flushing");
/* we deleted something... */
- if (queue->abidata.ABI.waiting_del)
+ if (queue->waiting_del)
g_cond_signal (queue->item_del);
}
@@ -384,9 +384,9 @@ gst_data_queue_set_flushing (GstDataQueue * queue, gboolean flushing)
queue->flushing = flushing;
if (flushing) {
/* release push/pop functions */
- if (queue->abidata.ABI.waiting_add)
+ if (queue->waiting_add)
g_cond_signal (queue->item_add);
- if (queue->abidata.ABI.waiting_del)
+ if (queue->waiting_del)
g_cond_signal (queue->item_del);
}
GST_DATA_QUEUE_MUTEX_UNLOCK (queue);
@@ -432,9 +432,9 @@ gst_data_queue_push (GstDataQueue * queue, GstDataQueueItem * item)
/* signal might have removed some items */
while (gst_data_queue_locked_is_full (queue)) {
- queue->abidata.ABI.waiting_del = TRUE;
+ queue->waiting_del = TRUE;
g_cond_wait (queue->item_del, queue->qlock);
- queue->abidata.ABI.waiting_del = FALSE;
+ queue->waiting_del = FALSE;
if (queue->flushing)
goto flushing;
}
@@ -448,7 +448,7 @@ gst_data_queue_push (GstDataQueue * queue, GstDataQueueItem * item)
queue->cur_level.time += item->duration;
STATUS (queue, "after pushing");
- if (queue->abidata.ABI.waiting_add)
+ if (queue->waiting_add)
g_cond_signal (queue->item_add);
GST_DATA_QUEUE_MUTEX_UNLOCK (queue);
@@ -497,9 +497,9 @@ gst_data_queue_pop (GstDataQueue * queue, GstDataQueueItem ** item)
GST_DATA_QUEUE_MUTEX_LOCK_CHECK (queue, flushing);
while (gst_data_queue_locked_is_empty (queue)) {
- queue->abidata.ABI.waiting_add = TRUE;
+ queue->waiting_add = TRUE;
g_cond_wait (queue->item_add, queue->qlock);
- queue->abidata.ABI.waiting_add = FALSE;
+ queue->waiting_add = FALSE;
if (queue->flushing)
goto flushing;
}
@@ -515,7 +515,7 @@ gst_data_queue_pop (GstDataQueue * queue, GstDataQueueItem ** item)
queue->cur_level.time -= (*item)->duration;
STATUS (queue, "after popping");
- if (queue->abidata.ABI.waiting_del)
+ if (queue->waiting_del)
g_cond_signal (queue->item_del);
GST_DATA_QUEUE_MUTEX_UNLOCK (queue);
@@ -600,7 +600,7 @@ gst_data_queue_limits_changed (GstDataQueue * queue)
g_return_if_fail (GST_IS_DATA_QUEUE (queue));
GST_DATA_QUEUE_MUTEX_LOCK (queue);
- if (queue->abidata.ABI.waiting_del) {
+ if (queue->waiting_del) {
GST_DEBUG ("signal del");
g_cond_signal (queue->item_del);
}
diff --git a/libs/gst/base/gstdataqueue.h b/libs/gst/base/gstdataqueue.h
index d38230b527..4ab42ff932 100644
--- a/libs/gst/base/gstdataqueue.h
+++ b/libs/gst/base/gstdataqueue.h
@@ -128,20 +128,16 @@ struct _GstDataQueue
gpointer *checkdata;
GMutex *qlock; /* lock for queue (vs object lock) */
+ gboolean waiting_add;
GCond *item_add; /* signals buffers now available for reading */
+ gboolean waiting_del;
GCond *item_del; /* signals space now available for writing */
gboolean flushing; /* indicates whether conditions where signalled because
* of external flushing */
GstDataQueueFullCallback fullcallback;
GstDataQueueEmptyCallback emptycallback;
- union {
- struct {
- gboolean waiting_add;
- gboolean waiting_del;
- } ABI;
- gpointer _gst_reserved[GST_PADDING - 2];
- } abidata;
+ gpointer _gst_reserved[GST_PADDING];
};
struct _GstDataQueueClass
diff --git a/libs/gst/base/gstpushsrc.c b/libs/gst/base/gstpushsrc.c
index 4201e3ae22..6faec866e8 100644
--- a/libs/gst/base/gstpushsrc.c
+++ b/libs/gst/base/gstpushsrc.c
@@ -36,8 +36,8 @@
* in a push based mode. If the peer accepts to operate without
* offsets and within the limits of the allowed block size, this
* class can operate in getrange based mode automatically. To make
- * this possible, the subclass should override the ::check_get_range
- * method.
+ * this possible, the subclass should implement and override the
+ * SCHEDULING query.
*
* The subclass should extend the methods from the baseclass in
* addition to the ::create method.
@@ -62,22 +62,18 @@
GST_DEBUG_CATEGORY_STATIC (gst_push_src_debug);
#define GST_CAT_DEFAULT gst_push_src_debug
-#define _do_init(type) \
+#define _do_init \
GST_DEBUG_CATEGORY_INIT (gst_push_src_debug, "pushsrc", 0, \
"pushsrc element");
-GST_BOILERPLATE_FULL (GstPushSrc, gst_push_src, GstBaseSrc, GST_TYPE_BASE_SRC,
- _do_init);
+#define gst_push_src_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstPushSrc, gst_push_src, GST_TYPE_BASE_SRC, _do_init);
-static gboolean gst_push_src_check_get_range (GstBaseSrc * src);
+static gboolean gst_push_src_query (GstBaseSrc * src, GstQuery * query);
static GstFlowReturn gst_push_src_create (GstBaseSrc * bsrc, guint64 offset,
guint length, GstBuffer ** ret);
-
-static void
-gst_push_src_base_init (gpointer g_class)
-{
- /* nop */
-}
+static GstFlowReturn gst_push_src_fill (GstBaseSrc * bsrc, guint64 offset,
+ guint length, GstBuffer * ret);
static void
gst_push_src_class_init (GstPushSrcClass * klass)
@@ -85,24 +81,38 @@ gst_push_src_class_init (GstPushSrcClass * klass)
GstBaseSrcClass *gstbasesrc_class = (GstBaseSrcClass *) klass;
gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_push_src_create);
- gstbasesrc_class->check_get_range =
- GST_DEBUG_FUNCPTR (gst_push_src_check_get_range);
+ gstbasesrc_class->fill = GST_DEBUG_FUNCPTR (gst_push_src_fill);
+ gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_push_src_query);
}
static void
-gst_push_src_init (GstPushSrc * pushsrc, GstPushSrcClass * klass)
+gst_push_src_init (GstPushSrc * pushsrc)
{
/* nop */
}
static gboolean
-gst_push_src_check_get_range (GstBaseSrc * src)
+gst_push_src_query (GstBaseSrc * src, GstQuery * query)
{
- /* a pushsrc can by default never operate in pull mode override
- * if you want something different. */
- return FALSE;
+ gboolean ret;
+
+ switch (GST_QUERY_TYPE (query)) {
+ case GST_QUERY_SCHEDULING:
+ {
+ /* a pushsrc can by default never operate in pull mode override
+ * if you want something different. */
+ gst_query_set_scheduling (query, FALSE, FALSE, TRUE, 1, -1, 1);
+ ret = TRUE;
+ break;
+ }
+ default:
+ ret = GST_BASE_SRC_CLASS (parent_class)->query (src, query);
+ break;
+ }
+ return ret;
}
+
static GstFlowReturn
gst_push_src_create (GstBaseSrc * bsrc, guint64 offset, guint length,
GstBuffer ** ret)
@@ -116,7 +126,26 @@ gst_push_src_create (GstBaseSrc * bsrc, guint64 offset, guint length,
if (pclass->create)
fret = pclass->create (src, ret);
else
- fret = GST_FLOW_ERROR;
+ fret =
+ GST_BASE_SRC_CLASS (parent_class)->create (bsrc, offset, length, ret);
+
+ return fret;
+}
+
+static GstFlowReturn
+gst_push_src_fill (GstBaseSrc * bsrc, guint64 offset, guint length,
+ GstBuffer * ret)
+{
+ GstFlowReturn fret;
+ GstPushSrc *src;
+ GstPushSrcClass *pclass;
+
+ src = GST_PUSH_SRC (bsrc);
+ pclass = GST_PUSH_SRC_GET_CLASS (src);
+ if (pclass->fill)
+ fret = pclass->fill (src, ret);
+ else
+ fret = GST_BASE_SRC_CLASS (parent_class)->fill (bsrc, offset, length, ret);
return fret;
}
diff --git a/libs/gst/base/gstpushsrc.h b/libs/gst/base/gstpushsrc.h
index 49786d57e0..e48ffb1107 100644
--- a/libs/gst/base/gstpushsrc.h
+++ b/libs/gst/base/gstpushsrc.h
@@ -57,6 +57,9 @@ struct _GstPushSrcClass {
/* ask the subclass to create a buffer */
GstFlowReturn (*create) (GstPushSrc *src, GstBuffer **buf);
+ /* ask the subclass to fill a buffer */
+ GstFlowReturn (*fill) (GstPushSrc *src, GstBuffer *buf);
+
/*< private >*/
gpointer _gst_reserved[GST_PADDING];
};
diff --git a/libs/gst/base/gsttypefindhelper.c b/libs/gst/base/gsttypefindhelper.c
index 8695b92917..1f2c01ae92 100644
--- a/libs/gst/base/gsttypefindhelper.c
+++ b/libs/gst/base/gsttypefindhelper.c
@@ -70,21 +70,23 @@ typedef struct
* Returns: address of the data or %NULL if buffer does not cover the
* requested range.
*/
-static guint8 *
+static const guint8 *
helper_find_peek (gpointer data, gint64 offset, guint size)
{
GstTypeFindHelper *helper;
GstBuffer *buffer;
GstFlowReturn ret;
GSList *insert_pos = NULL;
- guint buf_size;
+ gsize buf_size;
guint64 buf_offset;
+#if 0
GstCaps *caps;
+#endif
helper = (GstTypeFindHelper *) data;
GST_LOG_OBJECT (helper->obj, "'%s' called peek (%" G_GINT64_FORMAT
- ", %u)", GST_PLUGIN_FEATURE_NAME (helper->factory), offset, size);
+ ", %u)", GST_OBJECT_NAME (helper->factory), offset, size);
if (size == 0)
return NULL;
@@ -103,14 +105,19 @@ helper_find_peek (gpointer data, gint64 offset, guint size)
for (walk = helper->buffers; walk; walk = walk->next) {
GstBuffer *buf = GST_BUFFER_CAST (walk->data);
guint64 buf_offset = GST_BUFFER_OFFSET (buf);
- guint buf_size = GST_BUFFER_SIZE (buf);
+ guint buf_size = gst_buffer_get_size (buf);
/* buffers are kept sorted by end offset (highest first) in the list, so
* at this point we save the current position and stop searching if
* we're after the searched end offset */
if (buf_offset <= offset) {
if ((offset + size) < (buf_offset + buf_size)) {
- return GST_BUFFER_DATA (buf) + (offset - buf_offset);
+ guint8 *data;
+
+ /* FIXME, unmap after usage */
+ data = gst_buffer_map (buf, NULL, NULL, GST_MAP_READ);
+
+ return data + (offset - buf_offset);
}
} else if (offset + size >= buf_offset + buf_size) {
insert_pos = walk;
@@ -131,6 +138,7 @@ helper_find_peek (gpointer data, gint64 offset, guint size)
if (ret != GST_FLOW_OK)
goto error;
+#if 0
caps = GST_BUFFER_CAPS (buffer);
if (caps && !gst_caps_is_empty (caps) && !gst_caps_is_any (caps)) {
@@ -143,11 +151,12 @@ helper_find_peek (gpointer data, gint64 offset, guint size)
gst_buffer_unref (buffer);
return NULL;
}
+#endif
/* getrange might silently return shortened buffers at the end of a file,
* we must, however, always return either the full requested data or NULL */
buf_offset = GST_BUFFER_OFFSET (buffer);
- buf_size = GST_BUFFER_SIZE (buffer);
+ buf_size = gst_buffer_get_size (buffer);
if ((buf_offset != -1 && buf_offset != offset) || buf_size < size) {
GST_DEBUG ("droping short buffer: %" G_GUINT64_FORMAT "-%" G_GUINT64_FORMAT
@@ -164,10 +173,12 @@ helper_find_peek (gpointer data, gint64 offset, guint size)
/* if insert_pos is not set, our offset is bigger than the largest offset
* we have so far; since we keep the list sorted with highest offsets
* first, we need to prepend the buffer to the list */
- helper->last_offset = GST_BUFFER_OFFSET (buffer) + GST_BUFFER_SIZE (buffer);
+ helper->last_offset = GST_BUFFER_OFFSET (buffer) + buf_size;
helper->buffers = g_slist_prepend (helper->buffers, buffer);
}
- return GST_BUFFER_DATA (buffer);
+
+ /* FIXME, unmap */
+ return gst_buffer_map (buffer, NULL, NULL, GST_MAP_READ);
error:
{
@@ -191,7 +202,7 @@ helper_find_suggest (gpointer data, guint probability, const GstCaps * caps)
GST_LOG_OBJECT (helper->obj,
"'%s' called called suggest (%u, %" GST_PTR_FORMAT ")",
- GST_PLUGIN_FEATURE_NAME (helper->factory), probability, caps);
+ GST_OBJECT_NAME (helper->factory), probability, caps);
if (probability > helper->best_probability) {
GstCaps *copy = gst_caps_copy (caps);
@@ -208,8 +219,7 @@ helper_find_get_length (gpointer data)
GstTypeFindHelper *helper = (GstTypeFindHelper *) data;
GST_LOG_OBJECT (helper->obj, "'%s' called called get_length, returning %"
- G_GUINT64_FORMAT, GST_PLUGIN_FEATURE_NAME (helper->factory),
- helper->size);
+ G_GUINT64_FORMAT, GST_OBJECT_NAME (helper->factory), helper->size);
return helper->size;
}
@@ -302,7 +312,7 @@ gst_type_find_helper_get_range_ext (GstObject * obj,
continue;
GST_LOG_OBJECT (obj, "testing factory %s for extension %s",
- GST_PLUGIN_FEATURE_NAME (factory), extension);
+ GST_OBJECT_NAME (factory), extension);
for (i = 0; ext[i]; i++) {
if (strcmp (ext[i], extension) == 0) {
@@ -406,8 +416,8 @@ gst_type_find_helper (GstPad * src, guint64 size)
typedef struct
{
- guint8 *data; /* buffer data */
- guint size;
+ const guint8 *data; /* buffer data */
+ gsize size;
guint best_probability;
GstCaps *caps;
GstTypeFindFactory *factory; /* for logging */
@@ -425,21 +435,21 @@ typedef struct
* Returns: address inside the buffer or %NULL if buffer does not cover the
* requested range.
*/
-static guint8 *
+static const guint8 *
buf_helper_find_peek (gpointer data, gint64 off, guint size)
{
GstTypeFindBufHelper *helper;
helper = (GstTypeFindBufHelper *) data;
GST_LOG_OBJECT (helper->obj, "'%s' called peek (%" G_GINT64_FORMAT ", %u)",
- GST_PLUGIN_FEATURE_NAME (helper->factory), off, size);
+ GST_OBJECT_NAME (helper->factory), off, size);
if (size == 0)
return NULL;
if (off < 0) {
GST_LOG_OBJECT (helper->obj, "'%s' wanted to peek at end; not supported",
- GST_PLUGIN_FEATURE_NAME (helper->factory));
+ GST_OBJECT_NAME (helper->factory));
return NULL;
}
@@ -464,7 +474,7 @@ buf_helper_find_suggest (gpointer data, guint probability, const GstCaps * caps)
GST_LOG_OBJECT (helper->obj,
"'%s' called called suggest (%u, %" GST_PTR_FORMAT ")",
- GST_PLUGIN_FEATURE_NAME (helper->factory), probability, caps);
+ GST_OBJECT_NAME (helper->factory), probability, caps);
/* Note: not >= as we call typefinders in order of rank, highest first */
if (probability > helper->best_probability) {
@@ -477,14 +487,15 @@ buf_helper_find_suggest (gpointer data, guint probability, const GstCaps * caps)
}
/**
- * gst_type_find_helper_for_buffer:
+ * gst_type_find_helper_for_data:
* @obj: object doing the typefinding, or NULL (used for logging)
- * @buf: (in) (transfer none): a #GstBuffer with data to typefind
+ * @data: (in) (transfer none): a pointer with data to typefind
+ * @size: (in) (transfer none): the size of @data
* @prob: (out) (allow-none): location to store the probability of the found
* caps, or #NULL
*
- * Tries to find what type of data is contained in the given #GstBuffer, the
- * assumption being that the buffer represents the beginning of the stream or
+ * Tries to find what type of data is contained in the given @data, the
+ * assumption being that the data represents the beginning of the stream or
* file.
*
* All available typefinders will be called on the data in order of rank. If
@@ -492,7 +503,7 @@ buf_helper_find_suggest (gpointer data, guint probability, const GstCaps * caps)
* typefinding is stopped immediately and the found caps will be returned
* right away. Otherwise, all available typefind functions will the tried,
* and the caps with the highest probability will be returned, or #NULL if
- * the content of the buffer could not be identified.
+ * the content of @data could not be identified.
*
* Free-function: gst_caps_unref
*
@@ -501,7 +512,7 @@ buf_helper_find_suggest (gpointer data, guint probability, const GstCaps * caps)
* with gst_caps_unref().
*/
GstCaps *
-gst_type_find_helper_for_buffer (GstObject * obj, GstBuffer * buf,
+gst_type_find_helper_for_data (GstObject * obj, const guint8 * data, gsize size,
GstTypeFindProbability * prob)
{
GstTypeFindBufHelper helper;
@@ -509,13 +520,10 @@ gst_type_find_helper_for_buffer (GstObject * obj, GstBuffer * buf,
GList *l, *type_list;
GstCaps *result = NULL;
- g_return_val_if_fail (buf != NULL, NULL);
- g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
- g_return_val_if_fail (GST_BUFFER_OFFSET (buf) == 0 ||
- GST_BUFFER_OFFSET (buf) == GST_BUFFER_OFFSET_NONE, NULL);
+ g_return_val_if_fail (data != NULL, NULL);
- helper.data = GST_BUFFER_DATA (buf);
- helper.size = GST_BUFFER_SIZE (buf);
+ helper.data = data;
+ helper.size = size;
helper.best_probability = 0;
helper.caps = NULL;
helper.obj = obj;
@@ -551,6 +559,50 @@ gst_type_find_helper_for_buffer (GstObject * obj, GstBuffer * buf,
}
/**
+ * gst_type_find_helper_for_buffer:
+ * @obj: object doing the typefinding, or NULL (used for logging)
+ * @buf: (in) (transfer none): a #GstBuffer with data to typefind
+ * @prob: (out) (allow-none): location to store the probability of the found
+ * caps, or #NULL
+ *
+ * Tries to find what type of data is contained in the given #GstBuffer, the
+ * assumption being that the buffer represents the beginning of the stream or
+ * file.
+ *
+ * All available typefinders will be called on the data in order of rank. If
+ * a typefinding function returns a probability of #GST_TYPE_FIND_MAXIMUM,
+ * typefinding is stopped immediately and the found caps will be returned
+ * right away. Otherwise, all available typefind functions will the tried,
+ * and the caps with the highest probability will be returned, or #NULL if
+ * the content of the buffer could not be identified.
+ *
+ * Free-function: gst_caps_unref
+ *
+ * Returns: (transfer full): the #GstCaps corresponding to the data, or #NULL
+ * if no type could be found. The caller should free the caps returned
+ * with gst_caps_unref().
+ */
+GstCaps *
+gst_type_find_helper_for_buffer (GstObject * obj, GstBuffer * buf,
+ GstTypeFindProbability * prob)
+{
+ GstCaps *result;
+ guint8 *data;
+ gsize size;
+
+ g_return_val_if_fail (buf != NULL, NULL);
+ g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
+ g_return_val_if_fail (GST_BUFFER_OFFSET (buf) == 0 ||
+ GST_BUFFER_OFFSET (buf) == GST_BUFFER_OFFSET_NONE, NULL);
+
+ data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+ result = gst_type_find_helper_for_data (obj, data, size, prob);
+ gst_buffer_unmap (buf, data, size);
+
+ return result;
+}
+
+/**
* gst_type_find_helper_for_extension:
* @obj: (allow-none): object doing the typefinding, or NULL (used for logging)
* @extension: an extension
diff --git a/libs/gst/base/gsttypefindhelper.h b/libs/gst/base/gsttypefindhelper.h
index b6ad5173dd..052bc198b4 100644
--- a/libs/gst/base/gsttypefindhelper.h
+++ b/libs/gst/base/gsttypefindhelper.h
@@ -30,6 +30,10 @@ G_BEGIN_DECLS
GstCaps * gst_type_find_helper (GstPad *src, guint64 size);
+GstCaps * gst_type_find_helper_for_data (GstObject *obj,
+ const guint8 *data,
+ gsize size,
+ GstTypeFindProbability *prob);
GstCaps * gst_type_find_helper_for_buffer (GstObject *obj,
GstBuffer *buf,
GstTypeFindProbability *prob);
diff --git a/libs/gst/check/Makefile.am b/libs/gst/check/Makefile.am
index 8dcf66d727..7d3082ab39 100644
--- a/libs/gst/check/Makefile.am
+++ b/libs/gst/check/Makefile.am
@@ -67,6 +67,7 @@ LIBGSTCHECK_EXPORTED_FUNCS = \
gst_buffer_straw_stop_pipeline \
gst_check_abi_list \
gst_check_caps_equal \
+ gst_check_buffer_data \
gst_check_chain_func \
gst_check_drop_buffers \
gst_check_element_push_buffer \
@@ -120,6 +121,7 @@ GstCheck-@GST_MAJORMINOR@.gir: $(INTROSPECTION_SCANNER) libgstcheck-@GST_MAJORMI
$(INTROSPECTION_SCANNER) -v --namespace GstCheck \
--nsversion=@GST_MAJORMINOR@ \
--strip-prefix=Gst \
+ -DGST_USE_UNSTABLE_API \
-I$(top_srcdir) \
-I$(top_srcdir)/libs \
-I$(top_builddir) \
@@ -127,12 +129,12 @@ GstCheck-@GST_MAJORMINOR@.gir: $(INTROSPECTION_SCANNER) libgstcheck-@GST_MAJORMI
$(gir_cincludes) \
--add-include-path=$(top_builddir)/gst \
--library-path=$(top_builddir)/gst \
- --library=$(top_builddir)/gst/libgstreamer-0.10.la \
- --library=libgstcheck-0.10.la \
- --include=Gst-0.10 \
+ --library=$(top_builddir)/gst/libgstreamer-0.11.la \
+ --library=libgstcheck-0.11.la \
+ --include=Gst-0.11 \
--libtool="$(top_builddir)/libtool" \
- --pkg gstreamer-0.10 \
- --pkg-export gstreamer-check-0.10 \
+ --pkg gstreamer-@GST_MAJORMINOR@ \
+ --pkg-export gstreamer-check-@GST_MAJORMINOR@ \
--add-init-section="gst_init(NULL,NULL);" \
--output $@ \
$(gir_headers) \
diff --git a/libs/gst/check/gstbufferstraw.c b/libs/gst/check/gstbufferstraw.c
index 1089ed9011..71504ff64f 100644
--- a/libs/gst/check/gstbufferstraw.c
+++ b/libs/gst/check/gstbufferstraw.c
@@ -38,7 +38,8 @@ static gulong id;
/* called for every buffer. Waits until the global "buf" variable is unset,
* then sets it to the buffer received, and signals. */
static gboolean
-buffer_probe (GstPad * pad, GstBuffer * buffer, gpointer unused)
+buffer_probe (GstPad * pad, GstProbeType type, GstBuffer * buffer,
+ gpointer unused)
{
g_mutex_lock (lock);
@@ -81,7 +82,8 @@ gst_buffer_straw_start_pipeline (GstElement * bin, GstPad * pad)
{
GstStateChangeReturn ret;
- id = gst_pad_add_buffer_probe (pad, G_CALLBACK (buffer_probe), NULL);
+ id = gst_pad_add_probe (pad, GST_PROBE_TYPE_BUFFER,
+ (GstPadProbeCallback) buffer_probe, NULL, NULL);
cond = g_cond_new ();
lock = g_mutex_new ();
@@ -149,7 +151,7 @@ gst_buffer_straw_stop_pipeline (GstElement * bin, GstPad * pad)
if (buf)
gst_buffer_unref (buf);
buf = NULL;
- gst_pad_remove_buffer_probe (pad, (guint) id);
+ gst_pad_remove_probe (pad, (guint) id);
id = 0;
g_cond_signal (cond);
g_mutex_unlock (lock);
diff --git a/libs/gst/check/gstcheck.c b/libs/gst/check/gstcheck.c
index c4370a3ae9..1a95f8f7b0 100644
--- a/libs/gst/check/gstcheck.c
+++ b/libs/gst/check/gstcheck.c
@@ -207,7 +207,8 @@ gst_check_setup_src_pad (GstElement * element,
srcpad = gst_check_setup_src_pad_by_name (element, tmpl, "sink");
if (caps)
- fail_unless (gst_pad_set_caps (srcpad, caps), "could not set caps on pad");
+ fail_unless (gst_pad_push_event (srcpad, gst_event_new_caps (caps)),
+ "could not set caps on pad");
return srcpad;
}
@@ -255,9 +256,6 @@ gst_check_teardown_pad_by_name (GstElement * element, const gchar * name)
gst_pad_unlink (pad_peer, pad_element);
else
gst_pad_unlink (pad_element, pad_peer);
-
- /* caps could have been set, make sure they get unset */
- gst_pad_set_caps (pad_peer, NULL);
}
/* pad refs held by both creator and this function (through _get) */
@@ -289,7 +287,8 @@ gst_check_setup_sink_pad (GstElement * element, GstStaticPadTemplate * tmpl,
sinkpad = gst_check_setup_sink_pad_by_name (element, tmpl, "src");
if (caps)
- fail_unless (gst_pad_set_caps (sinkpad, caps), "Could not set pad caps");
+ fail_unless (gst_pad_send_event (sinkpad, gst_event_new_caps (caps)),
+ "Could not set pad caps");
return sinkpad;
}
@@ -366,6 +365,26 @@ gst_check_caps_equal (GstCaps * caps1, GstCaps * caps2)
g_free (name2);
}
+
+/**
+ * gst_check_buffer_data:
+ * @buffer: buffer to compare
+ * @data: data to compare to
+ * @size: size of data to compare
+ *
+ * Compare the buffer contents with @data and @size.
+ */
+void
+gst_check_buffer_data (GstBuffer * buffer, gconstpointer data, gsize size)
+{
+ guint8 *bdata;
+ gsize bsize;
+
+ bdata = gst_buffer_map (buffer, &bsize, NULL, GST_MAP_READ);
+ fail_unless (memcmp (bdata, data, size) == 0, "buffer contents not equal");
+ gst_buffer_unmap (buffer, bdata, bsize);
+}
+
/**
* gst_check_element_push_buffer_list:
* @element_name: name of the element that needs to be created
@@ -389,8 +408,10 @@ void
gst_check_element_push_buffer_list (const gchar * element_name,
GList * buffer_in, GList * buffer_out, GstFlowReturn last_flow_return)
{
+#if 0
GstCaps *sink_caps;
GstCaps *src_caps = NULL;
+#endif
GstElement *element;
GstPad *pad_peer;
GstPad *sink_pad = NULL;
@@ -407,9 +428,13 @@ gst_check_element_push_buffer_list (const gchar * element_name,
buffer = GST_BUFFER (buffer_in->data);
fail_unless (GST_IS_BUFFER (buffer), "There should be a buffer in buffer_in");
+#if 0
src_caps = GST_BUFFER_CAPS (buffer);
+#endif
src_pad = gst_pad_new (NULL, GST_PAD_SRC);
+#if 0
gst_pad_set_caps (src_pad, src_caps);
+#endif
pad_peer = gst_element_get_static_pad (element, "sink");
fail_if (pad_peer == NULL);
fail_unless (gst_pad_link (src_pad, pad_peer) == GST_PAD_LINK_OK,
@@ -420,10 +445,13 @@ gst_check_element_push_buffer_list (const gchar * element_name,
GST_DEBUG ("src pad activated");
/* don't create the sink_pad if there is no buffer_out list */
if (buffer_out != NULL) {
+#if 0
gchar *temp;
+#endif
GST_DEBUG ("buffer out detected, creating the sink pad");
/* get the sink caps */
+#if 0
sink_caps = GST_BUFFER_CAPS (GST_BUFFER (buffer_out->data));
fail_unless (GST_IS_CAPS (sink_caps), "buffer out don't have caps");
temp = gst_caps_to_string (sink_caps);
@@ -431,10 +459,13 @@ gst_check_element_push_buffer_list (const gchar * element_name,
GST_DEBUG ("sink caps requested by buffer out: '%s'", temp);
g_free (temp);
fail_unless (gst_caps_is_fixed (sink_caps), "we need fixed caps");
+#endif
/* get the sink pad */
sink_pad = gst_pad_new (NULL, GST_PAD_SINK);
fail_unless (GST_IS_PAD (sink_pad));
+#if 0
gst_pad_set_caps (sink_pad, sink_caps);
+#endif
/* get the peer pad */
pad_peer = gst_element_get_static_pad (element, "src");
fail_unless (gst_pad_link (pad_peer, sink_pad) == GST_PAD_LINK_OK,
@@ -471,22 +502,31 @@ gst_check_element_push_buffer_list (const gchar * element_name,
while (buffers != NULL) {
GstBuffer *new = GST_BUFFER (buffers->data);
GstBuffer *orig = GST_BUFFER (buffer_out->data);
+ gsize newsize, origsize;
+ guint8 *newdata, *origdata;
+
+ newdata = gst_buffer_map (new, &newsize, NULL, GST_MAP_READ);
+ origdata = gst_buffer_map (orig, &origsize, NULL, GST_MAP_READ);
- GST_LOG ("orig buffer: size %u, caps %" GST_PTR_FORMAT,
- GST_BUFFER_SIZE (orig), GST_BUFFER_CAPS (orig));
- GST_LOG ("new buffer: size %u, caps %" GST_PTR_FORMAT,
- GST_BUFFER_SIZE (new), GST_BUFFER_CAPS (new));
- GST_MEMDUMP ("orig buffer", GST_BUFFER_DATA (orig), GST_BUFFER_SIZE (orig));
- GST_MEMDUMP ("new buffer", GST_BUFFER_DATA (new), GST_BUFFER_SIZE (new));
+ GST_LOG ("orig buffer: size %u", origsize);
+ GST_LOG ("new buffer: size %u", newsize);
+ GST_MEMDUMP ("orig buffer", origdata, origsize);
+ GST_MEMDUMP ("new buffer", newdata, newsize);
/* remove the buffers */
buffers = g_list_remove (buffers, new);
buffer_out = g_list_remove (buffer_out, orig);
- fail_unless (GST_BUFFER_SIZE (orig) == GST_BUFFER_SIZE (new),
- "size of the buffers are not the same");
- fail_unless (memcmp (GST_BUFFER_DATA (orig), GST_BUFFER_DATA (new),
- GST_BUFFER_SIZE (new)) == 0, "data is not the same");
+
+ fail_unless (origsize == newsize, "size of the buffers are not the same");
+ fail_unless (memcmp (origdata, newdata, newsize) == 0,
+ "data is not the same");
+#if 0
gst_check_caps_equal (GST_BUFFER_CAPS (orig), GST_BUFFER_CAPS (new));
+#endif
+
+ gst_buffer_unmap (orig, origdata, origsize);
+ gst_buffer_unmap (new, newdata, newsize);
+
gst_buffer_unref (new);
gst_buffer_unref (orig);
}
diff --git a/libs/gst/check/gstcheck.h b/libs/gst/check/gstcheck.h
index 004eb7457d..6d4a9356f3 100644
--- a/libs/gst/check/gstcheck.h
+++ b/libs/gst/check/gstcheck.h
@@ -81,6 +81,7 @@ void gst_check_teardown_pad_by_name (GstElement * element, const gchar *name);
void gst_check_teardown_src_pad (GstElement * element);
void gst_check_drop_buffers (void);
void gst_check_caps_equal (GstCaps * caps1, GstCaps * caps2);
+void gst_check_buffer_data (GstBuffer * buffer, gconstpointer data, gsize size);
void gst_check_element_push_buffer_list (const gchar * element_name,
GList * buffer_in, GList * buffer_out, GstFlowReturn last_flow_return);
void gst_check_element_push_buffer (const gchar * element_name,
diff --git a/libs/gst/check/gstconsistencychecker.c b/libs/gst/check/gstconsistencychecker.c
index ded047e1db..731fc5a60a 100644
--- a/libs/gst/check/gstconsistencychecker.c
+++ b/libs/gst/check/gstconsistencychecker.c
@@ -35,14 +35,14 @@
struct _GstStreamConsistency
{
gboolean flushing;
- gboolean newsegment;
+ gboolean segment;
gboolean eos;
gulong probeid;
GstPad *pad;
};
static gboolean
-source_pad_data_cb (GstPad * pad, GstMiniObject * data,
+source_pad_data_cb (GstPad * pad, GstProbeType type, GstMiniObject * data,
GstStreamConsistency * consist)
{
if (GST_IS_BUFFER (data)) {
@@ -50,8 +50,8 @@ source_pad_data_cb (GstPad * pad, GstMiniObject * data,
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (GST_BUFFER (data))));
/* If an EOS went through, a buffer would be invalid */
fail_if (consist->eos, "Buffer received after EOS");
- /* Buffers need to be preceded by a newsegment event */
- fail_unless (consist->newsegment, "Buffer received without newsegment");
+ /* Buffers need to be preceded by a segment event */
+ fail_unless (consist->segment, "Buffer received without segment");
} else if (GST_IS_EVENT (data)) {
GstEvent *event = (GstEvent *) data;
@@ -67,23 +67,24 @@ source_pad_data_cb (GstPad * pad, GstMiniObject * data,
fail_if (consist->eos, "Received a FLUSH_STOP after an EOS");
consist->flushing = FALSE;
break;
- case GST_EVENT_NEWSEGMENT:
- consist->newsegment = TRUE;
+ case GST_EVENT_SEGMENT:
+ consist->segment = TRUE;
consist->eos = FALSE;
break;
case GST_EVENT_EOS:
/* FIXME : not 100% sure about whether two eos in a row is valid */
fail_if (consist->eos, "Received EOS just after another EOS");
consist->eos = TRUE;
- consist->newsegment = FALSE;
+ consist->segment = FALSE;
break;
case GST_EVENT_TAG:
- GST_DEBUG_OBJECT (pad, "tag %" GST_PTR_FORMAT, event->structure);
+ GST_DEBUG_OBJECT (pad, "tag %" GST_PTR_FORMAT,
+ gst_event_get_structure (event));
/* fall through */
default:
if (GST_EVENT_IS_SERIALIZED (event) && GST_EVENT_IS_DOWNSTREAM (event)) {
fail_if (consist->eos, "Event received after EOS");
- fail_unless (consist->newsegment, "Event received before newsegment");
+ fail_unless (consist->segment, "Event received before segment");
}
/* FIXME : Figure out what to do for other events */
break;
@@ -117,7 +118,8 @@ gst_consistency_checker_new (GstPad * pad)
consist = g_new0 (GstStreamConsistency, 1);
consist->pad = g_object_ref (pad);
consist->probeid =
- gst_pad_add_data_probe (pad, (GCallback) source_pad_data_cb, consist);
+ gst_pad_add_probe (pad, GST_PROBE_TYPE_DATA,
+ (GstPadProbeCallback) source_pad_data_cb, consist, NULL);
return consist;
}
@@ -136,7 +138,7 @@ gst_consistency_checker_reset (GstStreamConsistency * consist)
{
consist->eos = FALSE;
consist->flushing = FALSE;
- consist->newsegment = FALSE;
+ consist->segment = FALSE;
}
/**
@@ -152,7 +154,7 @@ void
gst_consistency_checker_free (GstStreamConsistency * consist)
{
/* Remove the data probe */
- gst_pad_remove_data_probe (consist->pad, consist->probeid);
+ gst_pad_remove_probe (consist->pad, consist->probeid);
g_object_unref (consist->pad);
g_free (consist);
}
diff --git a/libs/gst/controller/Makefile.am b/libs/gst/controller/Makefile.am
index bf99b4ec17..7a28ee74cf 100644
--- a/libs/gst/controller/Makefile.am
+++ b/libs/gst/controller/Makefile.am
@@ -57,6 +57,7 @@ GstController-@GST_MAJORMINOR@.gir: $(INTROSPECTION_SCANNER) libgstcontroller-@G
$(INTROSPECTION_SCANNER) -v --namespace GstController \
--nsversion=@GST_MAJORMINOR@ \
--strip-prefix=Gst \
+ -DGST_USE_UNSTABLE_API \
-I$(top_srcdir) \
-I$(top_srcdir)/libs \
-I$(top_builddir) \
@@ -64,12 +65,12 @@ GstController-@GST_MAJORMINOR@.gir: $(INTROSPECTION_SCANNER) libgstcontroller-@G
$(gir_cincludes) \
--add-include-path=$(top_builddir)/gst \
--library-path=$(top_builddir)/gst \
- --library=$(top_builddir)/gst/libgstreamer-0.10.la \
- --library=libgstcontroller-0.10.la \
- --include=Gst-0.10 \
+ --library=$(top_builddir)/gst/libgstreamer-0.11.la \
+ --library=libgstcontroller-0.11.la \
+ --include=Gst-0.11 \
--libtool="$(top_builddir)/libtool" \
- --pkg gstreamer-0.10 \
- --pkg-export gstreamer-controller-0.10 \
+ --pkg gstreamer-@GST_MAJORMINOR@ \
+ --pkg-export gstreamer-controller-@GST_MAJORMINOR@ \
--add-init-section="gst_init(NULL,NULL);" \
--output $@ \
$(gir_headers) \
diff --git a/libs/gst/controller/gstcontroller.c b/libs/gst/controller/gstcontroller.c
index 9bb1d6d66b..1675278a81 100644
--- a/libs/gst/controller/gstcontroller.c
+++ b/libs/gst/controller/gstcontroller.c
@@ -97,21 +97,6 @@ struct _GstControllerPrivate
};
/* helper */
-#ifndef GST_REMOVE_DEPRECATED
-static void
-gst_controlled_property_add_interpolation_control_source (GstControlledProperty
- * self)
-{
- GstControlSource *csource =
- GST_CONTROL_SOURCE (gst_interpolation_control_source_new ());
-
- GST_INFO
- ("Adding a GstInterpolationControlSource because of backward compatibility");
- g_return_if_fail (!self->csource);
- gst_control_source_bind (GST_CONTROL_SOURCE (csource), self->pspec);
- self->csource = csource;
-}
-#endif
/*
* gst_controlled_property_new:
@@ -972,318 +957,3 @@ gst_controller_get_type (void)
}
return type;
}
-
-/* FIXME: backward compatibility functions */
-
-/*
- * gst_controlled_property_set_interpolation_mode:
- * @self: the controlled property object to change
- * @mode: the new interpolation mode
- *
- * Sets the given Interpolation mode for the controlled property and activates
- * the respective interpolation hooks.
- *
- * Deprecated: Use #GstControlSource, for example #GstInterpolationControlSource
- * directly.
- *
- * Returns: %TRUE for success
- */
-#ifndef GST_REMOVE_DEPRECATED
-static gboolean
-gst_controlled_property_set_interpolation_mode (GstControlledProperty * self,
- GstInterpolateMode mode)
-{
- GstInterpolationControlSource *icsource;
-
- /* FIXME: backward compat, add GstInterpolationControlSource */
- if (!self->csource)
- gst_controlled_property_add_interpolation_control_source (self);
-
- g_return_val_if_fail (GST_IS_INTERPOLATION_CONTROL_SOURCE (self->csource),
- FALSE);
-
- icsource = GST_INTERPOLATION_CONTROL_SOURCE (self->csource);
-
- return gst_interpolation_control_source_set_interpolation_mode (icsource,
- mode);
-}
-#endif
-
-/**
- * gst_controller_set:
- * @self: the controller object which handles the properties
- * @property_name: the name of the property to set
- * @timestamp: the time the control-change is schedules for
- * @value: the control-value
- *
- * Set the value of given controller-handled property at a certain time.
- *
- * Deprecated: Use #GstControlSource, for example #GstInterpolationControlSource
- * directly.
- *
- * Returns: FALSE if the values couldn't be set (ex : properties not handled by controller), TRUE otherwise
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-gboolean
-gst_controller_set (GstController * self, const gchar * property_name,
- GstClockTime timestamp, GValue * value);
-#endif
-gboolean
-gst_controller_set (GstController * self, const gchar * property_name,
- GstClockTime timestamp, GValue * value)
-{
- gboolean res = FALSE;
- GstControlledProperty *prop;
-
- g_return_val_if_fail (GST_IS_CONTROLLER (self), FALSE);
- g_return_val_if_fail (property_name, FALSE);
-
- g_mutex_lock (self->lock);
- if ((prop = gst_controller_find_controlled_property (self, property_name))) {
- /* FIXME: backward compat, add GstInterpolationControlSource */
- if (!prop->csource)
- gst_controlled_property_add_interpolation_control_source (prop);
-
- if (!GST_IS_INTERPOLATION_CONTROL_SOURCE (prop->csource))
- goto out;
- res =
- gst_interpolation_control_source_set (GST_INTERPOLATION_CONTROL_SOURCE
- (prop->csource), timestamp, value);
- }
-
-out:
- g_mutex_unlock (self->lock);
-
- return res;
-}
-#endif
-
-/**
- * gst_controller_set_from_list:
- * @self: the controller object which handles the properties
- * @property_name: the name of the property to set
- * @timedvalues: a list with #GstTimedValue items
- *
- * Sets multiple timed values at once.
- *
- * Deprecated: Use #GstControlSource, for example #GstInterpolationControlSource
- * directly.
- *
- * Returns: %FALSE if the values couldn't be set (ex : properties not handled by controller), %TRUE otherwise
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-gboolean
-gst_controller_set_from_list (GstController * self, const gchar * property_name,
- GSList * timedvalues);
-#endif
-gboolean
-gst_controller_set_from_list (GstController * self, const gchar * property_name,
- GSList * timedvalues)
-{
- gboolean res = FALSE;
- GstControlledProperty *prop;
-
- g_return_val_if_fail (GST_IS_CONTROLLER (self), FALSE);
- g_return_val_if_fail (property_name, FALSE);
-
- g_mutex_lock (self->lock);
- if ((prop = gst_controller_find_controlled_property (self, property_name))) {
- /* FIXME: backward compat, add GstInterpolationControlSource */
- if (!prop->csource)
- gst_controlled_property_add_interpolation_control_source (prop);
-
- if (!GST_IS_INTERPOLATION_CONTROL_SOURCE (prop->csource))
- goto out;
-
- res =
- gst_interpolation_control_source_set_from_list
- (GST_INTERPOLATION_CONTROL_SOURCE (prop->csource), timedvalues);
- }
-
-out:
- g_mutex_unlock (self->lock);
-
- return res;
-}
-#endif
-
-/**
- * gst_controller_unset:
- * @self: the controller object which handles the properties
- * @property_name: the name of the property to unset
- * @timestamp: the time the control-change should be removed from
- *
- * Used to remove the value of given controller-handled property at a certain
- * time.
- *
- * Deprecated: Use #GstControlSource, for example #GstInterpolationControlSource
- * directly.
- *
- * Returns: %FALSE if the values couldn't be unset (ex : properties not handled by controller), %TRUE otherwise
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-gboolean
-gst_controller_unset (GstController * self, const gchar * property_name,
- GstClockTime timestamp);
-#endif
-gboolean
-gst_controller_unset (GstController * self, const gchar * property_name,
- GstClockTime timestamp)
-{
- gboolean res = FALSE;
- GstControlledProperty *prop;
-
- g_return_val_if_fail (GST_IS_CONTROLLER (self), FALSE);
- g_return_val_if_fail (property_name, FALSE);
- g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
-
- g_mutex_lock (self->lock);
- if ((prop = gst_controller_find_controlled_property (self, property_name))) {
- if (!prop->csource || !GST_IS_INTERPOLATION_CONTROL_SOURCE (prop->csource))
- goto out;
-
- res =
- gst_interpolation_control_source_unset (GST_INTERPOLATION_CONTROL_SOURCE
- (prop->csource), timestamp);
- }
-
-out:
- g_mutex_unlock (self->lock);
-
- return res;
-}
-#endif
-
-/**
- * gst_controller_unset_all:
- * @self: the controller object which handles the properties
- * @property_name: the name of the property to unset
- *
- * Used to remove all time-stamped values of given controller-handled property
- *
- * Deprecated: Use #GstControlSource, for example #GstInterpolationControlSource
- * directly.
- *
- * Returns: %FALSE if the values couldn't be unset (ex : properties not handled
- * by controller), %TRUE otherwise
- * Since: 0.10.5
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-gboolean gst_controller_unset_all (GstController * self,
- const gchar * property_name);
-#endif
-gboolean
-gst_controller_unset_all (GstController * self, const gchar * property_name)
-{
- GstControlledProperty *prop;
-
- g_return_val_if_fail (GST_IS_CONTROLLER (self), FALSE);
- g_return_val_if_fail (property_name, FALSE);
-
- g_mutex_lock (self->lock);
- if ((prop = gst_controller_find_controlled_property (self, property_name))) {
- if (!prop->csource || !GST_IS_INTERPOLATION_CONTROL_SOURCE (prop->csource))
- goto out;
-
- gst_interpolation_control_source_unset_all (GST_INTERPOLATION_CONTROL_SOURCE
- (prop->csource));
- }
-
-out:
- g_mutex_unlock (self->lock);
-
- return TRUE;
-}
-#endif
-
-/**
- * gst_controller_get_all:
- * @self: the controller to get the list from
- * @property_name: the name of the property to get the list for
- *
- * Returns a read-only copy of the list of #GstTimedValue for the given property.
- * Free the list after done with it.
- *
- * <note><para>This doesn't modify the controlled GObject property!</para></note>
- *
- * Deprecated: Use #GstControlSource, for example #GstInterpolationControlSource
- * directly.
- *
- * Returns: a copy of the list, or %NULL if the property isn't handled by the controller
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-const GList *gst_controller_get_all (GstController * self,
- const gchar * property_name);
-#endif
-const GList *
-gst_controller_get_all (GstController * self, const gchar * property_name)
-{
- const GList *res = NULL;
- GstControlledProperty *prop;
-
- g_return_val_if_fail (GST_IS_CONTROLLER (self), NULL);
- g_return_val_if_fail (property_name, NULL);
-
- g_mutex_lock (self->lock);
- if ((prop = gst_controller_find_controlled_property (self, property_name))) {
- if (!prop->csource || !GST_IS_INTERPOLATION_CONTROL_SOURCE (prop->csource))
- goto out;
-
- res =
- gst_interpolation_control_source_get_all
- (GST_INTERPOLATION_CONTROL_SOURCE (prop->csource));
- }
-
-out:
- g_mutex_unlock (self->lock);
-
- return res;
-}
-#endif
-
-/**
- * gst_controller_set_interpolation_mode:
- * @self: the controller object
- * @property_name: the name of the property for which to change the interpolation
- * @mode: interpolation mode
- *
- * Sets the given interpolation mode on the given property.
- *
- * <note><para>User interpolation is not yet available and quadratic interpolation
- * is deprecated and maps to cubic interpolation.</para></note>
- *
- * Deprecated: Use #GstControlSource, for example #GstInterpolationControlSource
- * directly.
- *
- * Returns: %TRUE if the property is handled by the controller, %FALSE otherwise
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-gboolean
-gst_controller_set_interpolation_mode (GstController * self,
- const gchar * property_name, GstInterpolateMode mode);
-#endif
-gboolean
-gst_controller_set_interpolation_mode (GstController * self,
- const gchar * property_name, GstInterpolateMode mode)
-{
- gboolean res = FALSE;
- GstControlledProperty *prop;
-
- g_return_val_if_fail (GST_IS_CONTROLLER (self), FALSE);
- g_return_val_if_fail (property_name, FALSE);
-
- g_mutex_lock (self->lock);
- if ((prop = gst_controller_find_controlled_property (self, property_name))) {
- res = gst_controlled_property_set_interpolation_mode (prop, mode);
- }
- g_mutex_unlock (self->lock);
-
- return res;
-}
-#endif
diff --git a/libs/gst/controller/gstcontroller.h b/libs/gst/controller/gstcontroller.h
index 0b0379f0ff..ce666a5440 100644
--- a/libs/gst/controller/gstcontroller.h
+++ b/libs/gst/controller/gstcontroller.h
@@ -132,24 +132,6 @@ void gst_object_set_control_rate (GObject * object, GstClockTime control_rate);
gboolean gst_controller_init (int * argc, char ***argv);
-/* FIXME: deprecated functions */
-#ifndef GST_DISABLE_DEPRECATED
-gboolean gst_controller_set (GstController * self, const gchar * property_name,
- GstClockTime timestamp, GValue * value);
-gboolean gst_controller_set_from_list (GstController * self,
- const gchar * property_name, GSList * timedvalues);
-
-gboolean gst_controller_unset (GstController * self, const gchar * property_name,
- GstClockTime timestamp);
-gboolean gst_controller_unset_all (GstController * self, const gchar * property_name);
-
-const GList *gst_controller_get_all (GstController * self,
- const gchar * property_name);
-
-gboolean gst_controller_set_interpolation_mode (GstController * self,
- const gchar * property_name, GstInterpolateMode mode);
-#endif /* GST_DISABLE_DEPRECATED */
-
G_END_DECLS
#endif /* __GST_CONTROLLER_H__ */
diff --git a/libs/gst/dataprotocol/Makefile.am b/libs/gst/dataprotocol/Makefile.am
index cde4a5306c..59bd3878be 100644
--- a/libs/gst/dataprotocol/Makefile.am
+++ b/libs/gst/dataprotocol/Makefile.am
@@ -47,17 +47,18 @@ GstDataprotocol-@GST_MAJORMINOR@.gir: $(INTROSPECTION_SCANNER) libgstdataprotoco
$(INTROSPECTION_SCANNER) -v --namespace GstDataprotocol \
--strip-prefix=Gst \
--nsversion=@GST_MAJORMINOR@ \
+ -DGST_USE_UNSTABLE_API \
-I$(top_srcdir) \
-I$(top_builddir) \
$(gir_cincludes) \
--add-include-path=$(top_builddir)/gst \
--library-path=$(top_builddir)/gst \
- --library=$(top_builddir)/gst/libgstreamer-0.10.la \
- --library=libgstdataprotocol-0.10.la \
- --include=Gst-0.10 \
+ --library=$(top_builddir)/gst/libgstreamer-@GST_MAJORMINOR@.la \
+ --library=libgstdataprotocol-@GST_MAJORMINOR@.la \
+ --include=Gst-@GST_MAJORMINOR@ \
--libtool="$(top_builddir)/libtool" \
- --pkg gstreamer-0.10 \
- --pkg-export=gstreamer-dataprotocol-0.10 \
+ --pkg gstreamer-@GST_MAJORMINOR@ \
+ --pkg-export=gstreamer-dataprotocol-@GST_MAJORMINOR@ \
--add-init-section="gst_init(NULL,NULL);" \
--output $@ \
$(gir_headers) \
diff --git a/libs/gst/dataprotocol/dataprotocol.c b/libs/gst/dataprotocol/dataprotocol.c
index b57d377d69..e924ea5ed9 100644
--- a/libs/gst/dataprotocol/dataprotocol.c
+++ b/libs/gst/dataprotocol/dataprotocol.c
@@ -131,6 +131,8 @@ gst_dp_header_from_buffer_any (const GstBuffer * buffer, GstDPHeaderFlag flags,
{
guint8 *h;
guint16 flags_mask;
+ guint8 *data;
+ gsize size;
g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
g_return_val_if_fail (length, FALSE);
@@ -142,8 +144,10 @@ gst_dp_header_from_buffer_any (const GstBuffer * buffer, GstDPHeaderFlag flags,
/* version, flags, type */
GST_DP_INIT_HEADER (h, version, flags, GST_DP_PAYLOAD_BUFFER);
+ data = gst_buffer_map ((GstBuffer *) buffer, &size, NULL, GST_MAP_READ);
+
/* buffer properties */
- GST_WRITE_UINT32_BE (h + 6, GST_BUFFER_SIZE (buffer));
+ GST_WRITE_UINT32_BE (h + 6, size);
GST_WRITE_UINT64_BE (h + 10, GST_BUFFER_TIMESTAMP (buffer));
GST_WRITE_UINT64_BE (h + 18, GST_BUFFER_DURATION (buffer));
GST_WRITE_UINT64_BE (h + 26, GST_BUFFER_OFFSET (buffer));
@@ -157,7 +161,9 @@ gst_dp_header_from_buffer_any (const GstBuffer * buffer, GstDPHeaderFlag flags,
GST_WRITE_UINT16_BE (h + 42, GST_BUFFER_FLAGS (buffer) & flags_mask);
- GST_DP_SET_CRC (h, flags, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer));
+ GST_DP_SET_CRC (h, flags, data, size);
+
+ gst_buffer_unmap ((GstBuffer *) buffer, data, size);
GST_LOG ("created header from buffer:");
gst_dp_dump_byte_array (h, GST_DP_HEADER_LENGTH);
@@ -365,34 +371,6 @@ gst_dp_header_payload_type (const guint8 * header)
/*** PACKETIZER FUNCTIONS ***/
-/**
- * gst_dp_header_from_buffer:
- * @buffer: a #GstBuffer to create a header for
- * @flags: the #GstDPHeaderFlag to create the header with
- * @length: a guint pointer to store the header length in
- * @header: a guint8 * pointer to store a newly allocated header byte array in
- *
- * Creates a GDP header from the given buffer.
- *
- * Deprecated: use a #GstDPPacketizer
- *
- * Returns: %TRUE if the header was successfully created.
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-gboolean
-gst_dp_header_from_buffer (const GstBuffer * buffer, GstDPHeaderFlag flags,
- guint * length, guint8 ** header);
-#endif
-gboolean
-gst_dp_header_from_buffer (const GstBuffer * buffer, GstDPHeaderFlag flags,
- guint * length, guint8 ** header)
-{
- return gst_dp_header_from_buffer_any (buffer, flags, length, header,
- GST_DP_VERSION_0_2);
-}
-#endif
-
static gboolean
gst_dp_header_from_buffer_1_0 (const GstBuffer * buffer, GstDPHeaderFlag flags,
guint * length, guint8 ** header)
@@ -401,35 +379,6 @@ gst_dp_header_from_buffer_1_0 (const GstBuffer * buffer, GstDPHeaderFlag flags,
GST_DP_VERSION_1_0);
}
-/**
- * gst_dp_packet_from_caps:
- * @caps: a #GstCaps to create a packet for
- * @flags: the #GstDPHeaderFlag to create the header with
- * @length: a guint pointer to store the header length in
- * @header: a guint8 pointer to store a newly allocated header byte array in
- * @payload: a guint8 pointer to store a newly allocated payload byte array in
- *
- * Creates a GDP packet from the given caps.
- *
- * Deprecated: use a #GstDPPacketizer
- *
- * Returns: %TRUE if the packet was successfully created.
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-gboolean
-gst_dp_packet_from_caps (const GstCaps * caps, GstDPHeaderFlag flags,
- guint * length, guint8 ** header, guint8 ** payload);
-#endif
-gboolean
-gst_dp_packet_from_caps (const GstCaps * caps, GstDPHeaderFlag flags,
- guint * length, guint8 ** header, guint8 ** payload)
-{
- return gst_dp_packet_from_caps_any (caps, flags, length, header, payload,
- GST_DP_VERSION_0_2);
-}
-#endif
-
static gboolean
gst_dp_packet_from_caps_1_0 (const GstCaps * caps, GstDPHeaderFlag flags,
guint * length, guint8 ** header, guint8 ** payload)
@@ -438,105 +387,6 @@ gst_dp_packet_from_caps_1_0 (const GstCaps * caps, GstDPHeaderFlag flags,
GST_DP_VERSION_1_0);
}
-/**
- * gst_dp_packet_from_event:
- * @event: a #GstEvent to create a packet for
- * @flags: the #GstDPHeaderFlag to create the header with
- * @length: a guint pointer to store the header length in
- * @header: a guint8 pointer to store a newly allocated header byte array in
- * @payload: a guint8 pointer to store a newly allocated payload byte array in
- *
- * Creates a GDP packet from the given event.
- *
- * Deprecated: use a #GstDPPacketizer
- *
- * Returns: %TRUE if the packet was successfully created.
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-gboolean
-gst_dp_packet_from_event (const GstEvent * event, GstDPHeaderFlag flags,
- guint * length, guint8 ** header, guint8 ** payload);
-#endif
-gboolean
-gst_dp_packet_from_event (const GstEvent * event, GstDPHeaderFlag flags,
- guint * length, guint8 ** header, guint8 ** payload)
-{
- guint8 *h;
- guint pl_length; /* length of payload */
-
- g_return_val_if_fail (GST_IS_EVENT (event), FALSE);
- g_return_val_if_fail (length, FALSE);
- g_return_val_if_fail (header, FALSE);
- g_return_val_if_fail (payload, FALSE);
-
- /* first construct payload, since we need the length */
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_UNKNOWN:
- GST_WARNING ("Unknown event, ignoring");
- return FALSE;
- case GST_EVENT_EOS:
- case GST_EVENT_FLUSH_START:
- case GST_EVENT_FLUSH_STOP:
- case GST_EVENT_NEWSEGMENT:
- pl_length = 0;
- *payload = NULL;
- break;
- case GST_EVENT_SEEK:
- {
- gdouble rate;
- GstFormat format;
- GstSeekFlags flags;
- GstSeekType cur_type, stop_type;
- gint64 cur, stop;
-
- gst_event_parse_seek ((GstEvent *) event, &rate, &format, &flags,
- &cur_type, &cur, &stop_type, &stop);
-
- pl_length = 4 + 4 + 4 + 8 + 4 + 8;
- *payload = g_malloc0 (pl_length);
- /* FIXME write rate */
- GST_WRITE_UINT32_BE (*payload, (guint32) format);
- GST_WRITE_UINT32_BE (*payload + 4, (guint32) flags);
- GST_WRITE_UINT32_BE (*payload + 8, (guint32) cur_type);
- GST_WRITE_UINT64_BE (*payload + 12, (guint64) cur);
- GST_WRITE_UINT32_BE (*payload + 20, (guint32) stop_type);
- GST_WRITE_UINT64_BE (*payload + 24, (guint64) stop);
- break;
- }
- case GST_EVENT_QOS:
- case GST_EVENT_NAVIGATION:
- case GST_EVENT_TAG:
- GST_WARNING ("Unhandled event type %d, ignoring", GST_EVENT_TYPE (event));
- return FALSE;
- default:
- GST_WARNING ("Unknown event type %d, ignoring", GST_EVENT_TYPE (event));
- return FALSE;
- }
-
- /* now we can create and fill the header */
- h = g_malloc0 (GST_DP_HEADER_LENGTH);
- *length = GST_DP_HEADER_LENGTH;
-
- /* version, flags, type */
- GST_DP_INIT_HEADER (h, GST_DP_VERSION_0_2, flags,
- GST_DP_PAYLOAD_EVENT_NONE + GST_EVENT_TYPE (event));
-
- /* length */
- GST_WRITE_UINT32_BE (h + 6, (guint32) pl_length);
- /* timestamp */
- GST_WRITE_UINT64_BE (h + 10, GST_EVENT_TIMESTAMP (event));
-
- GST_DP_SET_CRC (h, flags, *payload, pl_length);
-
- GST_LOG ("created header from event:");
- gst_dp_dump_byte_array (h, GST_DP_HEADER_LENGTH);
-
- *header = h;
- return TRUE;
-}
-#endif
-
static gboolean
gst_dp_packet_from_event_1_0 (const GstEvent * event, GstDPHeaderFlag flags,
guint * length, guint8 ** header, guint8 ** payload)
@@ -544,6 +394,7 @@ gst_dp_packet_from_event_1_0 (const GstEvent * event, GstDPHeaderFlag flags,
guint8 *h;
guint32 pl_length; /* length of payload */
guchar *string = NULL;
+ const GstStructure *structure;
g_return_val_if_fail (GST_IS_EVENT (event), FALSE);
g_return_val_if_fail (length, FALSE);
@@ -553,8 +404,9 @@ gst_dp_packet_from_event_1_0 (const GstEvent * event, GstDPHeaderFlag flags,
*length = GST_DP_HEADER_LENGTH;
h = g_malloc0 (GST_DP_HEADER_LENGTH);
- if (event->structure) {
- string = (guchar *) gst_structure_to_string (event->structure);
+ structure = gst_event_get_structure ((GstEvent *) event);
+ if (structure) {
+ string = (guchar *) gst_structure_to_string (structure);
GST_LOG ("event %p has structure, string %s", event, string);
pl_length = strlen ((gchar *) string) + 1; /* include trailing 0 */
} else {
@@ -609,7 +461,8 @@ gst_dp_buffer_from_header (guint header_length, const guint8 * header)
GST_DP_PAYLOAD_BUFFER, NULL);
buffer =
- gst_buffer_new_and_alloc ((guint) GST_DP_HEADER_PAYLOAD_LENGTH (header));
+ gst_buffer_new_allocate (NULL,
+ (guint) GST_DP_HEADER_PAYLOAD_LENGTH (header), 0);
GST_BUFFER_TIMESTAMP (buffer) = GST_DP_HEADER_TIMESTAMP (header);
GST_BUFFER_DURATION (buffer) = GST_DP_HEADER_DURATION (header);
@@ -671,7 +524,7 @@ gst_dp_event_from_packet_0_2 (guint header_length, const guint8 * header,
case GST_EVENT_EOS:
case GST_EVENT_FLUSH_START:
case GST_EVENT_FLUSH_STOP:
- case GST_EVENT_NEWSEGMENT:
+ case GST_EVENT_SEGMENT:
event = gst_event_new_custom (type, NULL);
GST_EVENT_TIMESTAMP (event) = GST_DP_HEADER_TIMESTAMP (header);
break;
@@ -888,13 +741,6 @@ gst_dp_packetizer_new (GstDPVersion version)
ret->version = version;
switch (version) {
-#ifndef GST_REMOVE_DEPRECATED
- case GST_DP_VERSION_0_2:
- ret->header_from_buffer = gst_dp_header_from_buffer;
- ret->packet_from_caps = gst_dp_packet_from_caps;
- ret->packet_from_event = gst_dp_packet_from_event;
- break;
-#endif
case GST_DP_VERSION_1_0:
ret->header_from_buffer = gst_dp_header_from_buffer_1_0;
ret->packet_from_caps = gst_dp_packet_from_caps_1_0;
diff --git a/libs/gst/dataprotocol/dataprotocol.h b/libs/gst/dataprotocol/dataprotocol.h
index 150b5cca41..efd524af7b 100644
--- a/libs/gst/dataprotocol/dataprotocol.h
+++ b/libs/gst/dataprotocol/dataprotocol.h
@@ -149,27 +149,6 @@ guint32 gst_dp_header_payload_length (const guint8 * header);
GstDPPayloadType
gst_dp_header_payload_type (const guint8 * header);
-/* converting from GstBuffer/GstEvent/GstCaps */
-#ifndef GST_DISABLE_DEPRECATED
-gboolean gst_dp_header_from_buffer (const GstBuffer * buffer,
- GstDPHeaderFlag flags,
- guint * length,
- guint8 ** header);
-#endif
-#ifndef GST_DISABLE_DEPRECATED
-gboolean gst_dp_packet_from_caps (const GstCaps * caps,
- GstDPHeaderFlag flags,
- guint * length,
- guint8 ** header,
- guint8 ** payload);
-#endif
-#ifndef GST_DISABLE_DEPRECATED
-gboolean gst_dp_packet_from_event (const GstEvent * event,
- GstDPHeaderFlag flags,
- guint * length,
- guint8 ** header,
- guint8 ** payload);
-#endif
/* converting to GstBuffer/GstEvent/GstCaps */
GstBuffer * gst_dp_buffer_from_header (guint header_length,
const guint8 * header);
diff --git a/libs/gst/net/Makefile.am b/libs/gst/net/Makefile.am
index 93b522e54f..67afa65540 100644
--- a/libs/gst/net/Makefile.am
+++ b/libs/gst/net/Makefile.am
@@ -49,6 +49,7 @@ GstNet-@GST_MAJORMINOR@.gir: $(INTROSPECTION_SCANNER) libgstnet-@GST_MAJORMINOR@
$(INTROSPECTION_SCANNER) -v --namespace GstNet \
--strip-prefix=Gst \
--nsversion=@GST_MAJORMINOR@ \
+ -DGST_USE_UNSTABLE_API \
-I$(top_srcdir) \
-I$(top_srcdir)/libs \
-I$(top_builddir) \
@@ -56,12 +57,12 @@ GstNet-@GST_MAJORMINOR@.gir: $(INTROSPECTION_SCANNER) libgstnet-@GST_MAJORMINOR@
$(gir_cincludes) \
--add-include-path=$(top_builddir)/gst \
--library-path=$(top_builddir)/gst \
- --library=$(top_builddir)/gst/libgstreamer-0.10.la \
- --library=libgstnet-0.10.la \
- --include=Gst-0.10 \
+ --library=$(top_builddir)/gst/libgstreamer-@GST_MAJORMINOR@.la \
+ --library=libgstnet-@GST_MAJORMINOR@.la \
+ --include=Gst-@GST_MAJORMINOR@ \
--libtool="$(top_builddir)/libtool" \
- --pkg gstreamer-0.10 \
- --pkg-export="gstreamer-net-0.10" \
+ --pkg gstreamer-@GST_MAJORMINOR@ \
+ --pkg-export="gstreamer-net-@GST_MAJORMINOR@" \
--add-init-section="gst_init(NULL,NULL);" \
--output $@ \
$(gir_headers) \
diff --git a/libs/gst/net/gstnetclientclock.c b/libs/gst/net/gstnetclientclock.c
index dcaa975891..8130e3ec8c 100644
--- a/libs/gst/net/gstnetclientclock.c
+++ b/libs/gst/net/gstnetclientclock.c
@@ -88,11 +88,11 @@ struct _GstNetClientClockPrivate
GstPoll *fdset;
};
-#define _do_init(type) \
+#define _do_init \
GST_DEBUG_CATEGORY_INIT (ncc_debug, "netclock", 0, "Network client clock");
-
-GST_BOILERPLATE_FULL (GstNetClientClock, gst_net_client_clock,
- GstSystemClock, GST_TYPE_SYSTEM_CLOCK, _do_init);
+#define gst_net_client_clock_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstNetClientClock, gst_net_client_clock,
+ GST_TYPE_SYSTEM_CLOCK, _do_init);
static void gst_net_client_clock_finalize (GObject * object);
static void gst_net_client_clock_set_property (GObject * object, guint prop_id,
@@ -118,12 +118,6 @@ inet_aton (const char *c, struct in_addr *paddr)
#endif
static void
-gst_net_client_clock_base_init (gpointer g_class)
-{
- /* nop */
-}
-
-static void
gst_net_client_clock_class_init (GstNetClientClockClass * klass)
{
GObjectClass *gobject_class;
@@ -148,8 +142,7 @@ gst_net_client_clock_class_init (GstNetClientClockClass * klass)
}
static void
-gst_net_client_clock_init (GstNetClientClock * self,
- GstNetClientClockClass * g_class)
+gst_net_client_clock_init (GstNetClientClock * self)
{
GstClock *clock = GST_CLOCK_CAST (self);
diff --git a/libs/gst/net/gstnettimeprovider.c b/libs/gst/net/gstnettimeprovider.c
index b04d28243e..c1b4cac1cb 100644
--- a/libs/gst/net/gstnettimeprovider.c
+++ b/libs/gst/net/gstnettimeprovider.c
@@ -105,10 +105,11 @@ static void gst_net_time_provider_set_property (GObject * object, guint prop_id,
static void gst_net_time_provider_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
-#define _do_init(type) \
+#define _do_init \
GST_DEBUG_CATEGORY_INIT (ntp_debug, "nettime", 0, "Network time provider");
-GST_BOILERPLATE_FULL (GstNetTimeProvider, gst_net_time_provider, GstObject,
+#define gst_net_time_provider_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstNetTimeProvider, gst_net_time_provider,
GST_TYPE_OBJECT, _do_init);
#ifdef G_OS_WIN32
@@ -124,12 +125,6 @@ inet_aton (const char *c, struct in_addr *paddr)
#endif
static void
-gst_net_time_provider_base_init (gpointer g_class)
-{
- /* Do nothing here */
-}
-
-static void
gst_net_time_provider_class_init (GstNetTimeProviderClass * klass)
{
GObjectClass *gobject_class;
@@ -163,8 +158,7 @@ gst_net_time_provider_class_init (GstNetTimeProviderClass * klass)
}
static void
-gst_net_time_provider_init (GstNetTimeProvider * self,
- GstNetTimeProviderClass * g_class)
+gst_net_time_provider_init (GstNetTimeProvider * self)
{
#ifdef G_OS_WIN32
WSADATA w;