diff options
Diffstat (limited to 'libs/gst/base')
-rw-r--r-- | libs/gst/base/Makefile.am | 10 | ||||
-rw-r--r-- | libs/gst/base/gstadapter.c | 192 | ||||
-rw-r--r-- | libs/gst/base/gstadapter.h | 41 | ||||
-rw-r--r-- | libs/gst/base/gstbaseparse.c | 93 | ||||
-rw-r--r-- | libs/gst/base/gstbasesink.c | 239 | ||||
-rw-r--r-- | libs/gst/base/gstbasesink.h | 64 | ||||
-rw-r--r-- | libs/gst/base/gstbasesrc.c | 75 | ||||
-rw-r--r-- | libs/gst/base/gstbasesrc.h | 64 | ||||
-rw-r--r-- | libs/gst/base/gstbasetransform.c | 513 | ||||
-rw-r--r-- | libs/gst/base/gstbasetransform.h | 45 | ||||
-rw-r--r-- | libs/gst/base/gstbitreader.c | 44 | ||||
-rw-r--r-- | libs/gst/base/gstbitreader.h | 15 | ||||
-rw-r--r-- | libs/gst/base/gstbytereader.c | 44 | ||||
-rw-r--r-- | libs/gst/base/gstbytereader.h | 16 | ||||
-rw-r--r-- | libs/gst/base/gstbytewriter.c | 63 | ||||
-rw-r--r-- | libs/gst/base/gstbytewriter.h | 2 | ||||
-rw-r--r-- | libs/gst/base/gstcollectpads.c | 69 | ||||
-rw-r--r-- | libs/gst/base/gstcollectpads.h | 2 | ||||
-rw-r--r-- | libs/gst/base/gstdataqueue.c | 20 | ||||
-rw-r--r-- | libs/gst/base/gstdataqueue.h | 10 | ||||
-rw-r--r-- | libs/gst/base/gstpushsrc.c | 14 | ||||
-rw-r--r-- | libs/gst/base/gsttypefindhelper.c | 95 | ||||
-rw-r--r-- | libs/gst/base/gsttypefindhelper.h | 4 |
23 files changed, 561 insertions, 1173 deletions
diff --git a/libs/gst/base/Makefile.am b/libs/gst/base/Makefile.am index f6fa3efa7..60c886d0f 100644 --- a/libs/gst/base/Makefile.am +++ b/libs/gst/base/Makefile.am @@ -81,12 +81,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 75944a902..6b4c661b4 100644 --- a/libs/gst/base/gstadapter.c +++ b/libs/gst/base/gstadapter.c @@ -116,6 +116,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 +129,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 +156,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 +238,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 +254,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 +272,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 +293,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 +322,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 +339,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 +349,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 @@ -390,11 +393,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 +413,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 +461,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 +500,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); @@ -494,10 +520,10 @@ gst_adapter_copy (GstAdapter * adapter, guint8 * dest, guint offset, guint size) * See also: gst_adapter_peek(). */ 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 +542,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 +560,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 +572,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 +586,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 +618,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 +640,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 +681,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 +701,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 +710,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 +730,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, + gst_memory_new_wrapped (0, data, g_free, nbytes, 0, nbytes)); done: gst_adapter_flush_unchecked (adapter, nbytes); @@ -735,11 +759,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 +773,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); @@ -774,7 +798,7 @@ gst_adapter_take_list (GstAdapter * adapter, guint nbytes) * * 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 +817,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 +838,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 +902,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 +933,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 +963,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 +975,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 +1037,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 ae8b7813b..aa6730b6c 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 41f84682c..0c5232eaa 100644 --- a/libs/gst/base/gstbaseparse.c +++ b/libs/gst/base/gstbaseparse.c @@ -738,7 +738,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; } @@ -1278,7 +1278,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, @@ -1590,7 +1590,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); @@ -1667,10 +1667,9 @@ 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))); + queued_frame->buffer = gst_buffer_make_writable (queued_frame->buffer); + gst_buffer_set_context (queued_frame->buffer, + GST_PAD_CONTEXT (GST_BASE_PARSE_SRC_PAD (parse))); gst_base_parse_push_frame (parse, queued_frame); gst_base_parse_frame_free (queued_frame); } @@ -1703,6 +1702,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); @@ -1713,12 +1713,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)) { @@ -1856,8 +1857,8 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame) 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)); + buffer = gst_buffer_make_writable (buffer); + gst_buffer_set_context (buffer, GST_PAD_CONTEXT (parse->srcpad)); parse->priv->seen_keyframe |= parse->priv->is_video && !GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT); @@ -1887,26 +1888,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 || @@ -2024,7 +2024,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, @@ -2155,9 +2155,9 @@ 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)) { - 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; @@ -2209,11 +2209,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) = min_size; + data = gst_adapter_map (parse->priv->adapter, av); + gst_buffer_take_memory (tmpbuf, + gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY, + (gpointer) data, NULL, min_size, 0, min_size)); 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"); @@ -2223,6 +2223,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) { @@ -2247,7 +2248,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); @@ -2299,7 +2300,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; @@ -2345,11 +2346,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; @@ -2368,8 +2369,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; } @@ -2388,10 +2391,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; @@ -2399,7 +2402,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; @@ -2504,7 +2508,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; @@ -2525,7 +2529,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; @@ -2552,8 +2556,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); @@ -2562,7 +2566,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; } @@ -3185,9 +3189,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); @@ -3214,7 +3218,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); diff --git a/libs/gst/base/gstbasesink.c b/libs/gst/base/gstbasesink.c index 7740a77e9..c2adb6767 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 @@ -369,8 +365,6 @@ static const GstQueryType *gst_base_sink_get_query_types (GstElement * element); static GstCaps *gst_base_sink_get_caps (GstBaseSink * sink); 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, @@ -399,9 +393,6 @@ 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 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 +496,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,7 +547,6 @@ 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); @@ -565,7 +555,6 @@ gst_base_sink_class_init (GstBaseSinkClass * klass) 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); @@ -644,29 +633,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) { @@ -684,8 +650,6 @@ gst_base_sink_init (GstBaseSink * basesink, gpointer g_class) 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 +661,17 @@ 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 (); + basesink->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 +691,10 @@ 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); + gst_segment_free (basesink->clip_segment); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -797,7 +765,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 +790,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 +853,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 +1332,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)); @@ -1460,14 +1428,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 +1455,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. */ @@ -1566,7 +1526,6 @@ gst_base_sink_commit_state (GstBaseSink * basesink) case GST_STATE_PLAYING: { GstBaseSinkClass *bclass; - GstStateChangeReturn ret; bclass = GST_BASE_SINK_GET_CLASS (basesink); @@ -1580,14 +1539,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: @@ -1672,13 +1623,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 @@ -1805,7 +1749,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)); + memcpy (sink->clip_segment, segment, sizeof (GstSegment)); /* post the step done when we know the stepped duration in TIME */ message = @@ -2202,11 +2146,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; @@ -2258,7 +2202,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; @@ -2826,7 +2770,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) @@ -2954,7 +2898,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; @@ -3175,7 +3119,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); @@ -3328,7 +3272,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; @@ -3338,7 +3282,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; @@ -3346,7 +3290,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; } @@ -3354,7 +3298,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; } @@ -3403,7 +3347,7 @@ gst_base_sink_flush_stop (GstBaseSink * basesink, GstPad * pad) /* 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); + gst_segment_init (basesink->clip_segment, GST_FORMAT_UNDEFINED); } GST_OBJECT_UNLOCK (basesink); } @@ -3431,7 +3375,7 @@ 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; @@ -3451,7 +3395,7 @@ gst_base_sink_event (GstPad * pad, GstEvent * event) if (G_UNLIKELY (ret != GST_FLOW_OK)) result = FALSE; } - GST_PAD_PREROLL_UNLOCK (pad); + GST_BASE_SINK_PREROLL_UNLOCK (basesink); break; } case GST_EVENT_NEWSEGMENT: @@ -3461,7 +3405,7 @@ gst_base_sink_event (GstPad * pad, GstEvent * event) GST_DEBUG_OBJECT (basesink, "newsegment %p", event); - GST_PAD_PREROLL_LOCK (pad); + GST_BASE_SINK_PREROLL_LOCK (basesink); if (G_UNLIKELY (basesink->flushing)) goto flushing; @@ -3477,7 +3421,7 @@ gst_base_sink_event (GstPad * pad, GstEvent * event) * 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); + basesink->clip_segment); ret = gst_base_sink_queue_object_unlocked (basesink, pad, @@ -3490,7 +3434,7 @@ gst_base_sink_event (GstPad * pad, GstEvent * event) GST_OBJECT_UNLOCK (basesink); } } - GST_PAD_PREROLL_UNLOCK (pad); + GST_BASE_SINK_PREROLL_UNLOCK (basesink); break; } case GST_EVENT_FLUSH_START: @@ -3535,7 +3479,7 @@ 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; @@ -3607,14 +3551,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; @@ -3699,9 +3643,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; @@ -3745,32 +3689,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; @@ -3939,7 +3872,7 @@ gst_base_sink_perform_seek (GstBaseSink * sink, GstPad * pad, GstEvent * event) 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) { + } 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. */ GST_DEBUG_OBJECT (sink, "closing running segment %" G_GINT64_FORMAT @@ -3967,7 +3900,7 @@ gst_base_sink_perform_seek (GstBaseSink * sink, GstPad * pad, GstEvent * event) } sink->priv->discont = TRUE; - sink->abidata.ABI.running = TRUE; + sink->running = TRUE; GST_PAD_STREAM_UNLOCK (pad); @@ -4030,7 +3963,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); @@ -4064,9 +3997,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, @@ -4106,13 +4039,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); - 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; @@ -4172,7 +4105,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 */ @@ -4194,7 +4127,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; } @@ -4336,10 +4269,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, " @@ -4347,15 +4278,21 @@ 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_set_caps (GST_BASE_SINK_PAD (basesink), 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); @@ -4399,7 +4336,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); @@ -4409,8 +4346,7 @@ 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->clip_segment, format, duration); gst_segment_set_duration (&basesink->segment, format, duration); } else { GST_DEBUG_OBJECT (basesink, "unknown duration"); @@ -4554,7 +4490,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; @@ -4945,12 +4881,11 @@ 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; @@ -4977,10 +4912,10 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition) } 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. */ @@ -4996,7 +4931,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"); @@ -5011,7 +4946,7 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition) gst_message_new_async_start (GST_OBJECT_CAST (basesink), FALSE)); } } - GST_PAD_PREROLL_UNLOCK (basesink->sinkpad); + GST_BASE_SINK_PREROLL_UNLOCK (basesink); break; default: break; @@ -5035,7 +4970,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) @@ -5079,10 +5014,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. */ @@ -5115,7 +5050,7 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition) } 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 a4215b8de..5b8ab90bb 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 @@ -146,9 +155,10 @@ struct _GstBaseSinkClass { /* 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 +171,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 2b59d48bc..34b9bab35 100644 --- a/libs/gst/base/gstbasesrc.c +++ b/libs/gst/base/gstbasesrc.c @@ -251,7 +251,6 @@ struct _GstBaseSrcPrivate 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); @@ -266,7 +265,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, @@ -325,12 +324,6 @@ static GstFlowReturn gst_base_src_get_range (GstBaseSrc * src, guint64 offset, static gboolean gst_base_src_seekable (GstBaseSrc * src); 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; @@ -339,6 +332,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); @@ -437,7 +432,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); @@ -458,7 +453,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) { @@ -757,7 +752,7 @@ 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->running && !src->priv->newsegment_pending) { if (src->priv->close_segment) gst_event_unref (src->priv->close_segment); src->priv->close_segment = @@ -787,7 +782,7 @@ gst_base_src_new_seamless_segment (GstBaseSrc * src, gint64 start, gint64 stop, GST_OBJECT_UNLOCK (src); src->priv->discont = TRUE; - src->data.ABI.running = TRUE; + src->running = TRUE; return res; } @@ -1413,7 +1408,7 @@ gst_base_src_perform_seek (GstBaseSrc * src, GstEvent * event, gboolean unlock) /* 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) { + } else if (res && src->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 @@ -1484,7 +1479,7 @@ gst_base_src_perform_seek (GstBaseSrc * src, GstEvent * event, gboolean unlock) } 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, @@ -1631,7 +1626,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 */ @@ -1803,7 +1798,7 @@ gst_base_src_set_property (GObject * object, guint prop_id, 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)); @@ -1830,7 +1825,7 @@ gst_base_src_get_property (GObject * object, guint prop_id, GValue * value, 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)); @@ -2161,14 +2156,14 @@ 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) { - *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)); + /* set pad context on the buffer if the buffer had no caps */ + if (GST_BUFFER_CONTEXT (*buf) == NULL) { + *buf = gst_buffer_make_writable (*buf); + gst_buffer_set_context (*buf, GST_PAD_CONTEXT (src->srcpad)); } /* now sync before pushing the buffer */ @@ -2443,7 +2438,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) @@ -2507,7 +2502,7 @@ gst_base_src_loop (GstPad * pad) } 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; } @@ -2543,7 +2538,7 @@ 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; @@ -2608,7 +2603,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)); 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)) @@ -2618,7 +2613,7 @@ 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)); GST_DEBUG_OBJECT (basesrc, "caps of peer: %" GST_PTR_FORMAT, peercaps); if (peercaps) { /* get intersection */ @@ -2637,17 +2632,19 @@ gst_base_src_default_negotiate (GstBaseSrc * basesrc) /* now fixate */ if (!gst_caps_is_empty (caps)) { - gst_pad_fixate_caps (GST_BASE_SRC_PAD (basesrc), caps); - GST_DEBUG_OBJECT (basesrc, "fixated to: %" GST_PTR_FORMAT, 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 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); + } 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_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); + } } } gst_caps_unref (caps); @@ -2708,7 +2705,7 @@ gst_base_src_start (GstBaseSrc * basesrc) gst_segment_init (&basesrc->segment, basesrc->segment.format); GST_OBJECT_UNLOCK (basesrc); - basesrc->data.ABI.running = FALSE; + basesrc->running = FALSE; basesrc->priv->newsegment_pending = FALSE; bclass = GST_BASE_SRC_GET_CLASS (basesrc); @@ -2757,7 +2754,7 @@ 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))) @@ -2961,8 +2958,8 @@ gst_base_src_activate_push (GstPad * pad, gboolean active) /* 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 @@ -3126,7 +3123,7 @@ gst_base_src_change_state (GstElement * element, GstStateChange transition) basesrc->priv->last_sent_eos = TRUE; } g_atomic_int_set (&basesrc->priv->pending_eos, FALSE); - event_p = &basesrc->data.ABI.pending_seek; + event_p = &basesrc->pending_seek; gst_event_replace (event_p, NULL); event_p = &basesrc->priv->close_segment; gst_event_replace (event_p, NULL); diff --git a/libs/gst/base/gstbasesrc.h b/libs/gst/base/gstbasesrc.h index 2a3caecdb..a492d105b 100644 --- a/libs/gst/base/gstbasesrc.h +++ b/libs/gst/base/gstbasesrc.h @@ -101,18 +101,14 @@ struct _GstBaseSrc { 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]; }; /** @@ -178,9 +174,8 @@ struct _GstBaseSrcClass { /* decide on caps */ gboolean (*negotiate) (GstBaseSrc *src); - - /* generate and send a newsegment (UNUSED) */ - gboolean (*newsegment) (GstBaseSrc *src); + /* called if, in negotiation, caps need fixating */ + void (*fixate) (GstBaseSrc *src, GstCaps *caps); /* start and stop processing, ideal for opening/closing the resource */ gboolean (*start) (GstBaseSrc *src); @@ -196,23 +191,6 @@ struct _GstBaseSrcClass { /* check if the resource is seekable */ gboolean (*is_seekable) (GstBaseSrc *src); - /* unlock any pending access to the resource. subclasses should unlock - * any function ASAP. */ - gboolean (*unlock) (GstBaseSrc *src); - - /* notify subclasses of an event */ - gboolean (*event) (GstBaseSrc *src, GstEvent *event); - - /* ask the subclass to create a buffer with offset and size */ - 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. @@ -221,19 +199,31 @@ struct _GstBaseSrcClass { * 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); + /* 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 */ + GstFlowReturn (*create) (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); diff --git a/libs/gst/base/gstbasetransform.c b/libs/gst/base/gstbasetransform.c index ccf0802c2..c72714b4c 100644 --- a/libs/gst/base/gstbasetransform.c +++ b/libs/gst/base/gstbasetransform.c @@ -271,7 +271,7 @@ struct _GstBaseTransformPrivate /* upstream caps and size suggestions */ GstCaps *sink_suggest; - guint size_suggest; + gsize size_suggest; gboolean suggest_pending; gboolean reconfigure; @@ -329,7 +329,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, @@ -347,8 +347,6 @@ 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_query (GstPad * pad, GstQuery * query); static const GstQueryType *gst_base_transform_query_type (GstPad * pad); @@ -425,8 +423,6 @@ gst_base_transform_init (GstBaseTransform * trans, 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, @@ -566,9 +562,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 +624,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: @@ -661,7 +657,7 @@ gst_base_transform_getcaps (GstPad * pad) otherpad = (pad == trans->srcpad) ? trans->sinkpad : trans->srcpad; /* we can do what the peer can */ - caps = gst_pad_peer_get_caps_reffed (otherpad); + caps = gst_pad_peer_get_caps (otherpad); if (caps) { GstCaps *temp; const GstCaps *templ; @@ -755,6 +751,7 @@ gst_base_transform_configure_caps (GstBaseTransform * trans, GstCaps * in, return ret; } +#if 0 /* 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. @@ -802,6 +799,7 @@ no_subset: return FALSE; } } +#endif /* given a fixed @caps on @pad, create the best possible caps for the * other pad. @@ -911,7 +909,7 @@ gst_base_transform_find_transform (GstBaseTransform * trans, GstPad * pad, GST_DEBUG_OBJECT (trans, "othercaps now %" GST_PTR_FORMAT, othercaps); - peercaps = gst_pad_get_caps_reffed (otherpeer); + peercaps = gst_pad_get_caps (otherpeer); intersect = gst_caps_intersect (peercaps, othercaps); gst_caps_unref (peercaps); gst_caps_unref (othercaps); @@ -1052,9 +1050,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); else - allowed = gst_pad_get_caps_reffed (trans->sinkpad); + allowed = gst_pad_get_caps (trans->sinkpad); if (!allowed) { GST_DEBUG_OBJECT (trans, "gst_pad_get_caps() failed"); @@ -1277,8 +1275,9 @@ gst_base_transform_query_type (GstPad * pad) return types; } +#if 0 static void -compute_upstream_suggestion (GstBaseTransform * trans, guint expsize, +compute_upstream_suggestion (GstBaseTransform * trans, gsize expsize, GstCaps * caps) { GstCaps *othercaps; @@ -1296,7 +1295,7 @@ compute_upstream_suggestion (GstBaseTransform * trans, guint expsize, * 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; + gsize size_suggest; GST_DEBUG_OBJECT (trans, "getting size of suggestion"); @@ -1321,6 +1320,7 @@ compute_upstream_suggestion (GstBaseTransform * trans, guint expsize, gst_caps_unref (othercaps); } } +#endif /* Allocate a buffer using gst_pad_alloc_buffer * @@ -1337,9 +1337,9 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans, GstBaseTransformClass *bclass; GstBaseTransformPrivate *priv; GstFlowReturn ret = GST_FLOW_OK; - guint outsize, newsize, expsize; + gsize insize, outsize; gboolean discard, setcaps, copymeta; - GstCaps *incaps, *oldcaps, *newcaps, *outcaps; + GstCaps *oldcaps, *outcaps; bclass = GST_BASE_TRANSFORM_GET_CLASS (trans); @@ -1347,13 +1347,15 @@ 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); + outsize = insize; /* we always alloc and discard here */ discard = TRUE; } else { @@ -1363,7 +1365,7 @@ 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); + outsize = insize; /* only discard it when the input was not writable, otherwise, we reuse * the input buffer. */ discard = gst_buffer_is_writable (in_buf); @@ -1373,8 +1375,7 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans, /* 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)) { + insize, GST_PAD_CAPS (trans->srcpad), &outsize)) { goto unknown_size; } /* never discard this buffer, we need it for storing the output */ @@ -1420,10 +1421,13 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans, GST_DEBUG_OBJECT (trans, "doing alloc with caps %" GST_PTR_FORMAT, oldcaps); + *out_buf = gst_buffer_new_and_alloc (outsize); +#if 0 ret = gst_pad_alloc_buffer (trans->srcpad, GST_BUFFER_OFFSET (in_buf), outsize, oldcaps, out_buf); if (ret != GST_FLOW_OK) goto alloc_failed; +#endif } } @@ -1431,108 +1435,6 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans, 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; - } - /* these are the final output caps */ outcaps = GST_PAD_CAPS (trans->srcpad); @@ -1543,8 +1445,8 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans, 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); + gst_buffer_copy_into (*out_buf, in_buf, + GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1); } else { GST_DEBUG_OBJECT (trans, "reuse input buffer"); *out_buf = in_buf; @@ -1585,35 +1487,24 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans, } } - /* 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 && (GST_MINI_OBJECT_FLAGS (*out_buf) & GST_BUFFER_FLAG_GAP); - if (setcaps || copymeta) { + if (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 (!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) GST_BUFFER_FLAG_UNSET (*out_buf, GST_BUFFER_FLAG_GAP); @@ -1638,11 +1529,6 @@ 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; - } } /* Given @caps calcultate the size of one unit. @@ -1660,7 +1546,7 @@ failed_configure: */ static gboolean gst_base_transform_get_unit_size (GstBaseTransform * trans, GstCaps * caps, - guint * size) + gsize * size) { gboolean res = FALSE; GstBaseTransformClass *bclass; @@ -1703,300 +1589,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 (peercaps, sink_suggest); - 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 (sink_suggest, caps); - 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) { @@ -2157,13 +1749,14 @@ 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; bclass = GST_BASE_TRANSFORM_GET_CLASS (trans); +#if 0 if (G_LIKELY ((incaps = GST_BUFFER_CAPS (inbuf)))) { GST_OBJECT_LOCK (trans); reconfigure = trans->priv->reconfigure; @@ -2179,14 +1772,18 @@ gst_base_transform_handle_buffer (GstBaseTransform * trans, GstBuffer * inbuf, goto not_negotiated; } } +#endif + + 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 @@ -2288,16 +1885,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 { @@ -2449,7 +2050,7 @@ gst_base_transform_chain (GstPad * pad, GstBuffer * buffer) /* 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; @@ -2850,7 +2451,7 @@ 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)); diff --git a/libs/gst/base/gstbasetransform.h b/libs/gst/base/gstbasetransform.h index 72c2b2a9d..cdab57042 100644 --- a/libs/gst/base/gstbasetransform.h +++ b/libs/gst/base/gstbasetransform.h @@ -119,9 +119,9 @@ 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; @@ -138,7 +138,7 @@ struct _GstBaseTransform { /*< private >*/ GstBaseTransformPrivate *priv; - gpointer _gst_reserved[GST_PADDING_LARGE - 1]; + gpointer _gst_reserved[GST_PADDING_LARGE]; }; /** @@ -200,8 +200,9 @@ 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); @@ -209,43 +210,39 @@ struct _GstBaseTransformClass { 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); + 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); 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); + 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 +267,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 a4393992c..ee369cb50 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 b5c3935e7..e42e3bfd9 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 e0cc7237f..97da6ec4b 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 8ce76df33..9c3c4f46a 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 25564f7d9..fa5468821 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, + 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 8fcd53da6..7cc68d25e 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 004508d32..f39a1fbc8 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); diff --git a/libs/gst/base/gstcollectpads.h b/libs/gst/base/gstcollectpads.h index 939c2f63a..ba6761eeb 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 f6b11177c..69dadb4c0 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 d38230b52..4ab42ff93 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 4201e3ae2..19eb37f90 100644 --- a/libs/gst/base/gstpushsrc.c +++ b/libs/gst/base/gstpushsrc.c @@ -62,24 +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 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 void gst_push_src_class_init (GstPushSrcClass * klass) { GstBaseSrcClass *gstbasesrc_class = (GstBaseSrcClass *) klass; @@ -90,7 +84,7 @@ gst_push_src_class_init (GstPushSrcClass * klass) } static void -gst_push_src_init (GstPushSrc * pushsrc, GstPushSrcClass * klass) +gst_push_src_init (GstPushSrc * pushsrc) { /* nop */ } diff --git a/libs/gst/base/gsttypefindhelper.c b/libs/gst/base/gsttypefindhelper.c index 8695b9291..5b533425e 100644 --- a/libs/gst/base/gsttypefindhelper.c +++ b/libs/gst/base/gsttypefindhelper.c @@ -70,14 +70,14 @@ 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; GstCaps *caps; @@ -103,14 +103,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,7 +136,7 @@ helper_find_peek (gpointer data, gint64 offset, guint size) if (ret != GST_FLOW_OK) goto error; - caps = GST_BUFFER_CAPS (buffer); + caps = gst_buffer_caps (buffer); if (caps && !gst_caps_is_empty (caps) && !gst_caps_is_any (caps)) { GST_DEBUG ("buffer has caps %" GST_PTR_FORMAT ", suggest max probability", @@ -147,7 +152,7 @@ helper_find_peek (gpointer data, gint64 offset, guint size) /* 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 +169,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: { @@ -406,8 +413,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,7 +432,7 @@ 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; @@ -477,14 +484,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 +500,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 +509,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 +517,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 +556,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 b6ad5173d..052bc198b 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); |