无法更改 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);
我正在尝试为图像处理例程创建一组 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);