使用 GStreamer 修改流中的数据
Modify data in a stream using GStreamer
我一直在寻找一种方法来修改 GStreamer 流以显示质量(通过在原始视频和 enc/dec 流之间的减法结果旁边显示原始视频例子)。
我已经学习 GStreamer 一周了,到目前为止我能够按照要求做,但现在我被卡住了。
我查看了似乎混合流的 compositor
元素,但我很确定它不能满足我的需要。
然后我检查了一些代码中的appsrc
和appsink
。我试图建立一个管道:filesrc - appsink - appsrc - filesink
。但由于显而易见的原因,它没有用。我浏览了 github 个项目,但大多数 appsrc/appsink
用途只是以编程方式执行读取文件等任务。
最后我找到了一个和他分享的 problem like me. He "solved" it by creating 2 pipelines (filesrc - appsink
& appsrc - filesink
) but he still got allocation errors. I was not even able to run the code 相同的人。
有没有人知道如何以干净的方式完成它?
合成器可能是您所尝试的最简单的解决方案。您必须使用 tee 才能分叉成 2 sub-pipelines,一个用于直接视频,另一个用于 encoding/decoding(此处使用 jpeg),然后将两者组合:
gst-launch-1.0 videotestsrc ! video/x-raw,width=640,height=480,framerate=30/1 ! tee name=t t. ! queue ! comp.sink_0 t. ! queue ! jpegenc ! jpegdec ! comp.sink_1 compositor name=comp sink_0::xpos=0 sink_1::xpos=640 ! autovideosink
我找到了修改流的方法。
它基本上是创建我自己的插件,因为通过创建一个元素,我可以修改我的元素的源板和接收器板之间的流。
如果有人感兴趣,the documentation 解释了如何创建插件,这是我的链函数,我在其中修改了 pad 之间的数据:
static GstFlowReturn
gst_my_filter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
GstMyFilter *filter;
filter = GST_MYFILTER (parent);
if (filter->silent == FALSE) {
GstMapInfo info;
if(gst_buffer_map(buf, &info, GST_MAP_READWRITE)) {
guint8* offset = info.data;
int i = 0;
while(i < info.maxsize) {
guint8* pos = offset + i;
guint8 c = 100; // Value that will be added to make the color lighter
int cc = (int) (*pos + c); // Adding the value to the color
guint8 color;
if(cc > 255) { // Making sure the color stays valid
color = 255;
}
else {
color = (guint8) cc;
}
memset(pos, color, 1); // Setting the value
i++;
}
}
gst_buffer_unmap(buf, &info);
}
return gst_pad_push (filter->srcpad, buf);
}
它非常简陋,只能使视频的颜色变亮,但我可以修改流,所以完成我想要完成的事情只是时间问题。
只是希望它能帮助某人
我一直在寻找一种方法来修改 GStreamer 流以显示质量(通过在原始视频和 enc/dec 流之间的减法结果旁边显示原始视频例子)。 我已经学习 GStreamer 一周了,到目前为止我能够按照要求做,但现在我被卡住了。
我查看了似乎混合流的 compositor
元素,但我很确定它不能满足我的需要。
然后我检查了一些代码中的appsrc
和appsink
。我试图建立一个管道:filesrc - appsink - appsrc - filesink
。但由于显而易见的原因,它没有用。我浏览了 github 个项目,但大多数 appsrc/appsink
用途只是以编程方式执行读取文件等任务。
最后我找到了一个和他分享的 problem like me. He "solved" it by creating 2 pipelines (filesrc - appsink
& appsrc - filesink
) but he still got allocation errors. I was not even able to run the code 相同的人。
有没有人知道如何以干净的方式完成它?
合成器可能是您所尝试的最简单的解决方案。您必须使用 tee 才能分叉成 2 sub-pipelines,一个用于直接视频,另一个用于 encoding/decoding(此处使用 jpeg),然后将两者组合:
gst-launch-1.0 videotestsrc ! video/x-raw,width=640,height=480,framerate=30/1 ! tee name=t t. ! queue ! comp.sink_0 t. ! queue ! jpegenc ! jpegdec ! comp.sink_1 compositor name=comp sink_0::xpos=0 sink_1::xpos=640 ! autovideosink
我找到了修改流的方法。 它基本上是创建我自己的插件,因为通过创建一个元素,我可以修改我的元素的源板和接收器板之间的流。 如果有人感兴趣,the documentation 解释了如何创建插件,这是我的链函数,我在其中修改了 pad 之间的数据:
static GstFlowReturn
gst_my_filter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
GstMyFilter *filter;
filter = GST_MYFILTER (parent);
if (filter->silent == FALSE) {
GstMapInfo info;
if(gst_buffer_map(buf, &info, GST_MAP_READWRITE)) {
guint8* offset = info.data;
int i = 0;
while(i < info.maxsize) {
guint8* pos = offset + i;
guint8 c = 100; // Value that will be added to make the color lighter
int cc = (int) (*pos + c); // Adding the value to the color
guint8 color;
if(cc > 255) { // Making sure the color stays valid
color = 255;
}
else {
color = (guint8) cc;
}
memset(pos, color, 1); // Setting the value
i++;
}
}
gst_buffer_unmap(buf, &info);
}
return gst_pad_push (filter->srcpad, buf);
}
它非常简陋,只能使视频的颜色变亮,但我可以修改流,所以完成我想要完成的事情只是时间问题。 只是希望它能帮助某人