无法更改 GstBuffer 中的数据

Can't change data in GstBuffer

我正在尝试为图像处理例程创建一组 gstreamer 插件。我已经成功创建了一个将图像和元数据读取到 GstBuffer 中的源元素,以及一个将缓冲区中的数据(连同随附的元数据)写入磁盘的接收器元素。我已经成功地测试了这些,并获得了所需的输出(与没有过滤器的输入相同)。

我还创建了一个拉伸元素,它利用外部库来填充可用的动态范围(即每个像素仅使用 12 位的 16 位图像可以拉伸以填充整个可用的 16 位).

如果我只是将未更改的缓冲区推出 srcpad 上的 Stretching 元素,我会得到我所期望的(未更改的图像)。但是,如果我尝试对缓冲区中的数据执行任何类型的操作,缓冲区中的数据将设置为 0。

这是我的 Stretching 插件的 chain() 函数的当前实现:

static GstFlowReturn
gst_stretching_chain(GstPad *pad, GstObject *parent, GstBuffer *buf)
{
  GstStretching *filter;
  filter = GST_STRETCHING(parent);

  g_print("Stretching...\n");

  guint num_rows;
  g_object_get(G_OBJECT(parent), "num_rows", &num_rows, NULL);

  guint num_cols;
  g_object_get(G_OBJECT(parent), "num_cols", &num_cols, NULL);

  guint bit_depth;
  g_object_get(G_OBJECT(parent), "bit_depth", &bit_depth, NULL);

  guint sig_bits;
  g_object_get(G_OBJECT(parent), "sig_bits", &sig_bits, NULL);

  gchar *product;
  g_object_get(G_OBJECT(parent), "product", &product, NULL);

  GstMapInfo info_in;
  gst_buffer_map(buf, &info_in, GST_MAP_WRITE);
  guint8 *in = info_in.data;

  GstMemory *mem;
  mem = gst_allocator_alloc(NULL, num_rows*num_cols*bit_depth/8, NULL);

  GstMapInfo info_out;
  gst_memory_map(mem, &info_out, GST_MAP_WRITE);
  guint8 *out = info_out.data;

  float *rad_gain[4] = {NULL, NULL, NULL, NULL};
  float *rad_offset[4] = {NULL, NULL, NULL, NULL};

  StretchingImage((unsigned short int *)in, num_rows, num_cols, sig_bits,
      bit_depth, rad_gain, rad_offset, 0, product, (unsigned short int *)out);

  gst_buffer_unmap(buf, &info_in);

  gst_buffer_replace_all_memory(buf, mem);

  return gst_pad_push(filter->srcpad, buf);
}

当这不起作用时,我还尝试手动更改数据(以查看是否会得到预期的输出):

static GstFlowReturn
gst_stretching_chain(GstPad *pad, GstObject *parent, GstBuffer *buf)
{
  GstStretching *filter;
  filter = GST_STRETCHING(parent);

  g_print("Stretching...\n");

  guint num_rows;
  g_object_get(G_OBJECT(parent), "num_rows", &num_rows, NULL);

  guint num_cols;
  g_object_get(G_OBJECT(parent), "num_cols", &num_cols, NULL);

  guint bit_depth;
  g_object_get(G_OBJECT(parent), "bit_depth", &bit_depth, NULL);

  guint sig_bits;
  g_object_get(G_OBJECT(parent), "sig_bits", &sig_bits, NULL);

  gchar *product;
  g_object_get(G_OBJECT(parent), "product", &product, NULL);

  GstMapInfo info_in;
  gst_buffer_map(buf, &info_in, GST_MAP_WRITE);
  guint8 *in = info_in.data;

  GstMemory *mem;
  mem = gst_allocator_alloc(NULL, num_rows*num_cols*bit_depth/8, NULL);

  GstMapInfo info_out;
  gst_memory_map(mem, &info_out, GST_MAP_WRITE);
  guint8 *out = info_out.data;

  int i;
  for (i=0; i<num_rows*num_cols*bit_depth/8; i++) {
    out[i] = 255;
  }

  float *rad_gain[4] = {NULL, NULL, NULL, NULL};
  float *rad_offset[4] = {NULL, NULL, NULL, NULL};

  StretchingImage((unsigned short int *)in, num_rows, num_cols, sig_bits,
      bit_depth, rad_gain, rad_offset, 0, product, (unsigned short int *)out);

  gst_buffer_unmap(buf, &info_in);

  gst_buffer_replace_all_memory(buf, mem);

  return gst_pad_push(filter->srcpad, buf);
}

即便如此,我在检查输出时仍然得到全 0。我假设我在尝试访问缓冲区中的数据时做错了什么,但还没有弄清楚它可能是什么。有什么想法吗?

gst_buffer_map(buf, &info_in, GST_MAP_WRITE); 应该 gst_buffer_map(buf, &info_in, GST_MAP_READ);

另外,你可以简化代码

guint num_rows, num_cols, ...;

g_object_get(G_OBJECT(parent), 
  "num_rows", &num_rows, 
  "num_cols", &num_cols,
  ...
  NULL);