使用gstreamer的appsrc和appsink修改视频

时间:2017-11-18 10:45:34

标签: c++ gstreamer

我正在使用GStreamer构建我的第一个应用程序,我的任务是从互联网获取流,使用CUDA修改它(更改像素)以并行计算帧,并输出修改后的流。

为简单起见,我现在使用MP4视频在磁盘上读写,不使用CUDA。

我在这个网站上找到了一个例子:

https://fossies.org/linux/gst-plugins-base/tests/examples/app/appsink-src.c

布置结构。源和宿流水线作为gst_parse_launch()的参数:

"filesrc location=\"%s\" ! appsink name=testsink", input_filename
"appsrc name=testsource ! filesink location=\"%s\"", output_filename

当没有对帧进行任何更改时,程序可以正常工作。但是当我尝试在GstMapInfo.data中设置值时,我无法再打开视频:

  

Windows Media Player无法播放该文件。播放器可能不支持该文件类型,或者可能不支持用于压缩文件的编解码器。

我有一个使用解码的提示,我发现了一个decodebin元素,并将其添加到源管道而不修改接收器:

"filesrc location=\"%s\" ! decodebin ! appsink name=testsink", input_filename

该程序运行了很长时间后崩溃并出现错误:

  

(CudaGStreamer.exe:8428):GLib-ERROR **:gmem.c:100:无法分配3110507字节

我已经在google上搜索了这个问题,但还没有找到解决方案,所以我想知道你可以告诉我我做错了什么。

版本:

代码:https://pastebin.com/GTSiaFXd

2 个答案:

答案 0 :(得分:1)

  1. 在不使用解码器的情况下修改数据时,它不起作用,因为您损坏了压缩的二进制数据。媒体播放器无法播放该流,因为您已损坏它。
  2. 你得到gst mem错误主要是因为你没有在你的应用程序中使用一个缓冲区的unref()导致内存泄漏

答案 1 :(得分:0)

经过多次挖掘,我解决了它。

首先,我取消注释以下行,看看会发生什么,并且"神奇地"它会阻止我的程序从分配错误中退出:

/* uncomment the next line to block when appsrc has buffered enough */
g_object_set (testsource, "block", TRUE, NULL);

然后我注意到输出视频仍然无法播放,并决定第二个管道上的流需要编码(因为在第一个管道解码完成时)才能写入实际的MP4视频。

我接受了以下命令:

How to convert I420 frames to BGRA format with gst-launch-1.0?

Gstreamer-1.0: mux raw video in a mp4 container

获取接收器管道:

"appsrc name=testsource ! "
"videoparse width=560 height=320 format=i420 framerate=24/1 ! "
"autovideoconvert ! x264enc ! h264parse ! mp4mux ! "
"filesink location=\"%s\"",
output_filename

剩下的就是从源视频中获取宽度和高度。

以下是一个工作示例(仍需要调整):https://pastebin.com/J6pPcTjN

编辑:

我更多地处理代码,获得30 MB视频并再次出现分配错误。内存泄漏?每当我试图释放或取消未释放或未解除的指针时,我会收到各种错误,也许应该以另一种方式完成?我很困惑。