如何使用tee插件创建含不同FPS并行分支的GStreamer流水线
问题原因及修复方案
你的代码存在3个核心错误,和命令行的流水线逻辑不匹配,导致出现卡顿:
- 分支元素链接顺序错误
命令行中每个分支的逻辑是queue→videorate→帧率约束→nvvideoconvert→autovideosink,你的C++代码中把nvvideoconvert放在了videorate前面,顺序完全颠倒,会引发格式协商异常。 - 缺少显式的帧率Caps约束
仅设置videorate的rate属性是按比例缩放帧率,无法保证输出帧率固定,你需要新增capsfilter元素显式指定输出帧率,和命令行逻辑对齐。 - 无独立的分支缓冲隔离
你代码中两个分支的queue没有配置合理的缓冲参数,两个分支处理速度不一致时会互相阻塞,引发整体卡顿。
修复代码示例
1. 第一分支修改
//First Branch creation GstPadTemplate *templ; templ = gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (tee), "src_%u"); GstPad *teepad1 = gst_element_request_pad (tee, templ, NULL, NULL); queue1 = gst_element_factory_make ("queue", NULL); videorate1 = gst_element_factory_make("videorate",NULL); // 新增capsfilter用于指定输出帧率 GstElement *caps1 = gst_element_factory_make("capsfilter", NULL); conv1 = gst_element_factory_make ("nvvideoconvert", NULL); sink1 = gst_element_factory_make ("autovideosink", NULL); // 配置1fps的帧率约束 GstCaps *fr_caps1 = gst_caps_from_string("video/x-raw(ANY), framerate=1/1"); g_object_set(G_OBJECT(caps1), "caps", fr_caps1, NULL); gst_caps_unref(fr_caps1); // 配置queue缓存避免阻塞 g_object_set(queue1, "max-size-buffers", 10, "max-size-bytes", 0, "max-size-time", 0, NULL); gst_bin_add_many (GST_BIN (pipeline), queue1, videorate1, caps1, conv1, sink1, NULL); // 调整链接顺序和命令行对齐 if (!gst_element_link_many (queue1, videorate1, caps1, conv1, sink1, NULL)) { g_error ("Failed to link first branch elements"); } GstPad *sinkpad = gst_element_get_static_pad (queue1, "sink"); gst_pad_link (teepad1, sinkpad); gst_object_unref (sinkpad); //First Branch creation ends
2. 第二分支修改
//Second Branch GstPadTemplate *templ2; templ2 = gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (tee), "src_%u"); GstPad *teepad2 = gst_element_request_pad (tee, templ2, NULL, NULL); queue2 = gst_element_factory_make ("queue", NULL); videorate2 = gst_element_factory_make("videorate",NULL); // 新增capsfilter用于指定输出帧率 GstElement *caps2 = gst_element_factory_make("capsfilter", NULL); conv2 = gst_element_factory_make ("nvvideoconvert", NULL); sink2 = gst_element_factory_make ("autovideosink", NULL); // 配置30fps的帧率约束 GstCaps *fr_caps2 = gst_caps_from_string("video/x-raw(ANY), framerate=30/1"); g_object_set(G_OBJECT(caps2), "caps", fr_caps2, NULL); gst_caps_unref(fr_caps2); // 配置queue缓存避免阻塞 g_object_set(queue2, "max-size-buffers", 10, "max-size-bytes", 0, "max-size-time", 0, NULL); gst_bin_add_many (GST_BIN (pipeline), queue2, videorate2, caps2, conv2, sink2, NULL); // 调整链接顺序和命令行对齐 if (!gst_element_link_many (queue2, videorate2, caps2, conv2, sink2, NULL)) { g_error ("Failed to link second branch elements"); } GstPad *sinkpad2 = gst_element_get_static_pad (queue2, "sink"); gst_pad_link (teepad2, sinkpad2); gst_object_unref (sinkpad2); //Second brach creation ends
内容的提问来源于stack exchange,提问作者goldfish
相关产品推荐
相关产品推荐

