使用 GStreamer 修改流中的数据

Modify data in a stream using GStreamer

我一直在寻找一种方法来修改 GStreamer 流以显示质量(通过在原始视频和 enc/dec 流之间的减法结果旁边显示原始视频例子)。 我已经学习 GStreamer 一周了,到目前为止我能够按照要求做,但现在我被卡住了。

我查看了似乎混合流的 compositor 元素,但我很确定它不能满足我的需要。

然后我检查了一些代码中的appsrcappsink。我试图建立一个管道: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);
}

它非常简陋,只能使视频的颜色变亮,但我可以修改流,所以完成我想要完成的事情只是时间问题。 只是希望它能帮助某人