📄 gstadapter.c
字号:
const guint8 *gst_adapter_peek (GstAdapter * adapter, guint size){ GstBuffer *cur; g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL); g_return_val_if_fail (size > 0, NULL); /* we don't have enough data, return NULL. This is unlikely * as one usually does an _available() first instead of peeking a * random size. */ if (G_UNLIKELY (size > adapter->size)) return NULL; /* we have enough assembled data, return it */ if (adapter->assembled_len >= size) return adapter->assembled_data; /* our head buffer has enough data left, return it */ cur = adapter->buflist->data; if (GST_BUFFER_SIZE (cur) >= size + adapter->skip) return GST_BUFFER_DATA (cur) + adapter->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 */ cur = adapter->buflist->data; if (GST_BUFFER_SIZE (cur) >= size + adapter->skip) return GST_BUFFER_DATA (cur) + adapter->skip; } /* Gonna need to copy stuff out */ if (adapter->assembled_size < size) { adapter->assembled_size = (size / DEFAULT_SIZE + 1) * DEFAULT_SIZE; GST_DEBUG_OBJECT (adapter, "setting size of internal buffer to %u", adapter->assembled_size); g_free (adapter->assembled_data); adapter->assembled_data = g_malloc (adapter->assembled_size); } adapter->assembled_len = size; gst_adapter_peek_into (adapter, adapter->assembled_data, size); return adapter->assembled_data;}/** * gst_adapter_copy: * @adapter: a #GstAdapter * @dest: the memory where to copy to * @offset: the bytes offset in the adapter to start from * @size: the number of bytes to copy * * Copies @size bytes of data starting at @offset out of the buffers * contained in @GstAdapter into an array @dest provided by the caller. * * The array @dest should be large enough to contain @size bytes. * The user should check that the adapter has (@offset + @size) bytes * available before calling this function. * * Since: 0.10.12 */voidgst_adapter_copy (GstAdapter * adapter, guint8 * dest, guint offset, guint size){ GSList *g; int skip; g_return_if_fail (GST_IS_ADAPTER (adapter)); g_return_if_fail (size > 0); /* we don't have enough data, return. This is unlikely * as one usually does an _available() first instead of copying a * random size. */ if (G_UNLIKELY (offset + size > adapter->size)) return; skip = adapter->skip; for (g = adapter->buflist; g && size > 0; g = g_slist_next (g)) { GstBuffer *buf; buf = g->data; if (offset < GST_BUFFER_SIZE (buf) - skip) { int n; n = MIN (GST_BUFFER_SIZE (buf) - skip - offset, size); memcpy (dest, GST_BUFFER_DATA (buf) + skip + offset, n); dest += n; offset = 0; size -= n; } else { offset -= GST_BUFFER_SIZE (buf) - skip; } skip = 0; }}/** * gst_adapter_flush: * @adapter: a #GstAdapter * @flush: the number of bytes to flush * * Flushes the first @flush bytes in the @adapter. The caller must ensure that * at least this many bytes are available. * * See also: gst_adapter_peek(). */voidgst_adapter_flush (GstAdapter * adapter, guint flush){ GstBuffer *cur; g_return_if_fail (GST_IS_ADAPTER (adapter)); g_return_if_fail (flush <= adapter->size); GST_LOG_OBJECT (adapter, "flushing %u bytes", flush); adapter->size -= flush; adapter->assembled_len = 0; while (flush > 0) { cur = adapter->buflist->data; if (GST_BUFFER_SIZE (cur) <= flush + adapter->skip) { /* can skip whole buffer */ flush -= GST_BUFFER_SIZE (cur) - adapter->skip; adapter->skip = 0; adapter->buflist = g_slist_delete_link (adapter->buflist, adapter->buflist); if (G_UNLIKELY (adapter->buflist == NULL)) adapter->buflist_end = NULL; gst_buffer_unref (cur); } else { adapter->skip += flush; break; } }}/** * gst_adapter_take: * @adapter: a #GstAdapter * @nbytes: the number of bytes to take * * Returns a freshly allocated buffer containing the first @nbytes bytes of the * @adapter. The returned bytes will be flushed from the adapter. * * Caller owns returned value. g_free after usage. * * Returns: oven-fresh hot data, or #NULL if @nbytes bytes are not available */guint8 *gst_adapter_take (GstAdapter * adapter, guint nbytes){ guint8 *data; g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL); g_return_val_if_fail (nbytes > 0, NULL); /* we don't have enough data, return NULL. This is unlikely * as one usually does an _available() first instead of peeking a * random size. */ if (G_UNLIKELY (nbytes > adapter->size)) return NULL; data = g_malloc (nbytes); /* we have enough assembled data, copy from there */ if (adapter->assembled_len >= nbytes) { GST_LOG_OBJECT (adapter, "taking %u bytes already assembled", nbytes); memcpy (data, adapter->assembled_data, nbytes); } else { GST_LOG_OBJECT (adapter, "taking %u bytes by collection", nbytes); gst_adapter_peek_into (adapter, data, nbytes); } gst_adapter_flush (adapter, nbytes); return data;}/** * gst_adapter_take_buffer: * @adapter: a #GstAdapter * @nbytes: the number of bytes to take * * Returns a #GstBuffer containing the first @nbytes bytes of the * @adapter. The returned bytes will be flushed from the adapter. * This function is potentially more performant than gst_adapter_take() * since it can reuse the memory in pushed buffers by subbuffering * or merging. * * Caller owns returned value. gst_buffer_unref() after usage. * * Since: 0.10.6 * * Returns: a #GstBuffer containing the first @nbytes of the adapter, * or #NULL if @nbytes bytes are not available */GstBuffer *gst_adapter_take_buffer (GstAdapter * adapter, guint nbytes){ GstBuffer *buffer; GstBuffer *cur; g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL); g_return_val_if_fail (nbytes > 0, NULL); GST_LOG_OBJECT (adapter, "taking buffer of %u bytes", nbytes); /* we don't have enough data, return NULL. This is unlikely * as one usually does an _available() first instead of grabbing a * random size. */ if (G_UNLIKELY (nbytes > adapter->size)) return NULL; /* our head buffer has enough data left, return it */ cur = adapter->buflist->data; if (GST_BUFFER_SIZE (cur) >= nbytes + adapter->skip) { GST_LOG_OBJECT (adapter, "providing buffer of %d bytes via sub-buffer", nbytes); buffer = gst_buffer_create_sub (cur, adapter->skip, nbytes); gst_adapter_flush (adapter, nbytes); return buffer; } 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 + adapter->skip) { GST_LOG_OBJECT (adapter, "providing buffer of %d bytes via sub-buffer", nbytes); buffer = gst_buffer_create_sub (cur, adapter->skip, nbytes); gst_adapter_flush (adapter, nbytes); return buffer; } } buffer = gst_buffer_new_and_alloc (nbytes); /* we have enough assembled data, copy from there */ if (adapter->assembled_len >= nbytes) { GST_LOG_OBJECT (adapter, "taking %u bytes already assembled", nbytes); memcpy (GST_BUFFER_DATA (buffer), adapter->assembled_data, nbytes); } else { GST_LOG_OBJECT (adapter, "taking %u bytes by collection", nbytes); gst_adapter_peek_into (adapter, GST_BUFFER_DATA (buffer), nbytes); } gst_adapter_flush (adapter, nbytes); return buffer;}/** * gst_adapter_available: * @adapter: a #GstAdapter * * Gets the maximum amount of bytes available, that is it returns the maximum * value that can be supplied to gst_adapter_peek() without that function * returning NULL. * * Returns: number of bytes available in @adapter */guintgst_adapter_available (GstAdapter * adapter){ g_return_val_if_fail (GST_IS_ADAPTER (adapter), 0); return adapter->size;}/** * gst_adapter_available_fast: * @adapter: a #GstAdapter * * Gets the maximum number of bytes that are immediately available without * requiring any expensive operations (like copying the data into a * temporary buffer). * * Returns: number of bytes that are available in @adapter without expensive * operations */guintgst_adapter_available_fast (GstAdapter * adapter){ g_return_val_if_fail (GST_IS_ADAPTER (adapter), 0); /* no buffers, we have no data */ if (!adapter->buflist) return 0; /* some stuff we already assembled */ if (adapter->assembled_len) return adapter->assembled_len; /* we cannot have skipped more than the first buffer */ g_assert (GST_BUFFER_SIZE (adapter->buflist->data) > adapter->skip); /* we can quickly get the data of the first buffer */ return GST_BUFFER_SIZE (adapter->buflist->data) - adapter->skip;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -