GStreamer中使用input-selector无法切换摄像头的问题求助
GStreamer 1.16.3 运行时摄像头切换实现
问题背景
我是GStreamer新手,当前使用1.16.3版本。代码中配置了两条摄像头输入管道:
gst_element_link_many(v4l2src1, videoconvert1, capsfilter1, queue1, input_selector, NULL); gst_element_link_many(v4l2src2, videoconvert2, capsfilter2, queue2, input_selector, NULL);
初始状态下v4l2src1对应的摄像头正常推流,但通过控制台按键调用switch_camera函数时,无法切换到另一个摄像头,需要能实现运行时切换的完整switch_camera函数代码。
原代码问题分析
原switch_camera函数存在以下关键问题:
- 未根据按键选择目标Pad:固定指向queue2的src pad,无法实现双向切换
- Pad引用管理不当:获取新Pad后未正确释放引用,可能导致资源泄漏
- 状态处理不严谨:切换时的管道状态操作逻辑存在疏漏,易引发数据流冲突
修正后的完整代码片段
修正的switch_camera函数
void switch_camera(char key) { // 根据按键确定目标Pad GstPad *target_pad = NULL; if (key == '1') { target_pad = gst_element_get_static_pad(queue1, "src"); g_print("切换至摄像头1\n"); } else if (key == '2') { target_pad = gst_element_get_static_pad(queue2, "src"); g_print("切换至摄像头2\n"); } if (!target_pad) { g_printerr("无法获取目标Pad\n"); return; } // 暂停管道避免切换时数据流混乱 gst_element_set_state(pipeline, GST_STATE_PAUSED); // 获取并释放旧激活Pad的引用 GstPad *old_active_pad = NULL; g_object_get(G_OBJECT(input_selector), "active-pad", &old_active_pad, NULL); if (old_active_pad) { gst_object_unref(old_active_pad); } // 设置新的激活Pad g_object_set(G_OBJECT(input_selector), "active-pad", target_pad, NULL); gst_object_unref(target_pad); // 释放目标Pad的引用 // 恢复管道播放状态 gst_element_set_state(pipeline, GST_STATE_PLAYING); }
配套修正的check_keyboard_input函数
gboolean check_keyboard_input(gpointer user_data) { char key; if (read(STDIN_FILENO, &key, 1) == 1) { if (key == '1' || key == '2') { switch_camera(key); } } return TRUE; }
关键注意事项
- 确保两个摄像头的
capsfilter配置完全一致(原代码已满足),否则input-selector切换时会出现格式不兼容错误 - GStreamer 1.16.3版本的
input-selector原生支持动态切换active-pad,无需额外处理Pad激活事件 - 切换时暂停管道是为了避免前后摄像头数据流冲突,保证切换过程平滑稳定
内容的提问来源于stack exchange,提问作者Aman
相关产品推荐
相关产品推荐

