无法更改GstBuffer中的数据

时间:2015-10-06 16:14:37

标签: c gstreamer

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

我还创建了一个拉伸元素,它利用外部库来填充可用的动态范围(即,每个像素只使用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。我假设我在尝试访问缓冲区中的数据时做错了什么,但还没有弄清楚它可能是什么。有什么想法吗?

1 个答案:

答案 0 :(得分:2)

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

另外fyi,你可以简化代码

guint num_rows, num_cols, ...;

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