[GStreamer] 内存管理

  • GstMemory:管理一小块实际的虚拟内存
  • GstBuffer:一个对象,是element、plugin、application互相信息交互的最小数据单位,内部包含GstMemory、时间信息和一些其他信息。
  • GstMeta:附加在GstBuffer上,用来提供一些描述内存的额外信息。
  • GstBufferPool:buffer池,但是只能分配尺寸固定的buffer。

GstMemory:

/**
 * GstMemory:
 * @mini_object: parent structure
 * @allocator: pointer to the #GstAllocator
 * @parent: parent memory block
 * @maxsize: the maximum size allocated
 * @align: the alignment of the memory
 * @offset: the offset where valid data starts
 * @size: the size of valid data
 *
 * Base structure for memory implementations. Custom memory will put this structure
 * as the first member of their structure.
 */
struct _GstMemory {
  GstMiniObject   mini_object;

  GstAllocator   *allocator;

  GstMemory      *parent;
  gsize           maxsize;
  gsize           align;
  gsize           offset;
  gsize           size;
};

GstMemory由GstAllocator创建。

GstAllocator:

/**
 * GstAllocator:
 * @mem_map: the implementation of the GstMemoryMapFunction
 * @mem_unmap: the implementation of the GstMemoryUnmapFunction
 * @mem_copy: the implementation of the GstMemoryCopyFunction
 * @mem_share: the implementation of the GstMemoryShareFunction
 * @mem_is_span: the implementation of the GstMemoryIsSpanFunction
 * @mem_map_full: the implementation of the GstMemoryMapFullFunction.
 *      Will be used instead of @mem_map if present. (Since: 1.6)
 * @mem_unmap_full: the implementation of the GstMemoryUnmapFullFunction.
 *      Will be used instead of @mem_unmap if present. (Since: 1.6)
 *
 * The #GstAllocator is used to create new memory.
 */
struct _GstAllocator
{
  GstObject  object;

  const gchar               *mem_type;

  /*< public >*/
  GstMemoryMapFunction       mem_map;
  GstMemoryUnmapFunction     mem_unmap;

  GstMemoryCopyFunction      mem_copy;
  GstMemoryShareFunction     mem_share;
  GstMemoryIsSpanFunction    mem_is_span;

  GstMemoryMapFullFunction   mem_map_full;
  GstMemoryUnmapFullFunction mem_unmap_full;

  /*< private >*/
  gpointer _gst_reserved[GST_PADDING - 2];

  GstAllocatorPrivate *priv;
};

内存分配器,是一个接口层,如果自行管理内存分配,可以自己实现这个接口。

内存分配和使用:

使用 gst_allocator_alloc 分配内存,此函数返回的是一个 GstMemory 指针,GstMemory内的数据必须通过 gst_memory_map 保护才可以访问,然后通过 gst_memory_unmap 释放保护后别人才可以访问,类似于加锁解锁。

[...]

  GstMemory *mem;
  GstMapInfo info;
  gint i;

  /* allocate 100 bytes */
  mem = gst_allocator_alloc (NULL, 100, NULL);

  /* get access to the memory in write mode */
  gst_memory_map (mem, &info, GST_MAP_WRITE);

  /* fill with pattern */
  for (i = 0; i < info.size; i++)
    info.data[i] = i;

  /* release memory */
  gst_memory_unmap (mem, &info);

[...]

GstBuffer :

  • GstBuffer内部包含了n个GstMemory,同时也包含了一些meta data:
  • dts 、pts:用来进行同步。
  • duration:buffer内数据总时长,不是整个流的总时长。
  • offset :buffer存视频时,表示当前buffer内第一帧数据在整个流中是第多少个帧;buffer存音频时,???
  • offset_end:buffer存视频时,表示当前buffer内最后一帧数据在整个流中是第多少个帧;buffer存音频时,???
/**
 * GstBuffer:
 * @mini_object: the parent structure
 * @pool: pointer to the pool owner of the buffer
 * @pts: presentation timestamp of the buffer, can be #GST_CLOCK_TIME_NONE when the
 *     pts is not known or relevant. The pts contains the timestamp when the
 *     media should be presented to the user.
 * @dts: decoding timestamp of the buffer, can be #GST_CLOCK_TIME_NONE when the
 *     dts is not known or relevant. The dts contains the timestamp when the
 *     media should be processed.
 * @duration: duration in time of the buffer data, can be #GST_CLOCK_TIME_NONE
 *     when the duration is not known or relevant.
 * @offset: a media specific offset for the buffer data.
 *     For video frames, this is the frame number of this buffer.
 *     For audio samples, this is the offset of the first sample in this buffer.
 *     For file data or compressed data this is the byte offset of the first
 *       byte in this buffer.
 * @offset_end: the last offset contained in this buffer. It has the same
 *     format as @offset.
 *
 * The structure of a #GstBuffer. Use the associated macros to access the public
 * variables.
 */
struct _GstBuffer {
  GstMiniObject          mini_object;

  /*< public >*/ /* with COW */
  GstBufferPool         *pool;

  /* timestamp */
  GstClockTime           pts;
  GstClockTime           dts;
  GstClockTime           duration;

  /* media specific offset */
  guint64                offset;
  guint64                offset_end;
};

默认情况下GstBuffer是不可写的,需要先通过gst_buffer_make_writable函数处理,然后才可以修改里面的内容,比如dts、pts、duration、offset等等。

三种创建GstBuffer的方法:

  1. gst_buffer_new 创建GstBuffer 对象,但是创建的对象不包含 GstMemory,需要手动创建GstMemory再进行绑定;
  2. gst_buffer_new_allocate 同时创建GstBuffer 和 指定数量的GstMemory,然后还会自动完成绑定动作;
  3. gst_buffer_new_wrapped_full 为现有GstMemory创建一个GstBuffer。
[...]
  GstBuffer *buffer;
  GstMemory *mem;
  GstMapInfo info;

  /* make empty buffer */
  buffer = gst_buffer_new ();

  /* make memory holding 100 bytes */
  mem = gst_allocator_alloc (NULL, 100, NULL);

  /* add the buffer */
  gst_buffer_append_memory (buffer, mem);

[...]

  /* get WRITE access to the memory and fill with 0xff */
  gst_buffer_map (buffer, &info, GST_MAP_WRITE);
  memset (info.data, 0xff, info.size);
  gst_buffer_unmap (buffer, &info);

[...]

  /* free the buffer */
  gst_buffer_unref (buffer);

[...]

GstMeta:

/**
 * GstMeta:
 * @flags: extra flags for the metadata
 * @info: pointer to the #GstMetaInfo
 *
 * Base structure for metadata. Custom metadata will put this structure
 * as the first member of their structure.
 */
struct _GstMeta {
  GstMetaFlags       flags;
  const GstMetaInfo *info;
};

GstMeta可以随意地附加到一个GstBuffer中。

#include <gst/video/gstvideometa.h>

[...]
  GstVideoCropMeta *meta;    //GstMeta的一个子类

  /* buffer points to a video frame, add some cropping metadata */
  meta = gst_buffer_add_video_crop_meta (buffer);

  /* configure the cropping metadata */
  meta->x = 8;
  meta->y = 8;
  meta->width = 120;
  meta->height = 80;
[...]
#include <gst/video/gstvideometa.h>

[...]
  GstVideoCropMeta *meta;

  /* buffer points to a video frame, get the cropping metadata */
  meta = gst_buffer_get_video_crop_meta (buffer);

  if (meta) {
    /* render frame with cropping */
    _render_frame_cropped (buffer, meta->x, meta->y, meta->width, meta->height);
  } else {
    /* render frame */
    _render_frame (buffer);
  }
[...]

 如何实现自定义的 GstMeta  :Memory allocation

GstBufferPool:

由内存池分配的 GstBuffer 具备完全相同的 meta data,唯一不一样的就是指向的内存区域。

GstBufferPool 以 GstBuffer 为管理单位,当且仅当 GstBufferPool 为 inactive 状态时,可以配置 GstBuffer 的meta data;当且仅当 GstBufferPool 为 active 状态时,可以分配和销毁GstBuffer。

  GstStructure *config;

[...]

  /* get config structure */
  config = gst_buffer_pool_get_config (pool);

  /* set caps, size, minimum and maximum buffers in the pool */
  gst_buffer_pool_config_set_params (config, caps, size, min, max);

  /* configure allocator and parameters */
  gst_buffer_pool_config_set_allocator (config, allocator, &params);

  /* store the updated configuration again */
  gst_buffer_pool_set_config (pool, config);

[...]

The following options can be configured on a GstBufferPool:

  • The caps of the buffers to allocate.

  • The size of the buffers. This is the suggested size of the buffers in the pool. The pool might decide to allocate larger buffers to add padding.

  • The minimum and maximum amount of buffers in the pool. When minimum is set to \> 0, the bufferpool will pre-allocate this amount of buffers. When maximum is not 0, the bufferpool will allocate up to maximum amount of buffers.

  • The allocator and parameters to use. Some bufferpools might ignore the allocator and use its internal one.

  • Other arbitrary bufferpool options identified with a string. a bufferpool lists the supported options with gst_buffer_pool_get_options() and you can ask if an option is supported with gst_buffer_pool_has_option(). The option can be enabled by adding it to the configuration structure with gst_buffer_pool_config_add_option (). These options are used to enable things like letting the pool set metadata on the buffers or to add extra configuration options for padding, for example.

gst_buffer_pool_set_active(pool, TRUE)用来激活内存池,之后用gst_buffer_pool_acquire_buffer ()来获取内存池对象。

  [...]

  GstFlowReturn ret;
  GstBuffer *buffer;

  ret = gst_buffer_pool_acquire_buffer (pool, &buffer, NULL);
  if (G_UNLIKELY (ret != GST_FLOW_OK))
    goto pool_failed;

  [...]

GST_QUERY_ALLOCATION:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值