GStreamer处理RTSP流时tee分支appsink无法触发new-sample信号问题咨询
问题原因分析
- appsink 元素的
emit-signals属性默认值为FALSE,没有主动开启的话不会触发new-sample、new-preroll这类信号,这是你遇到问题的核心原因。 - 另外 appsink 默认开启时钟同步(
sync属性为TRUE),如果流水线两个分支处理速度不一致,可能出现帧阻塞、不触发回调的问题。 - 你当前的流水线配置下,appsink 输出的是 H264 编码后的裸流,如果需要获取解码后的原始视频帧做处理,还需要调整流水线分支结构。
调整方案
1. 开启appsink信号配置
你可以任选以下两种方式之一配置属性:
方式一:直接修改流水线指令
在 appsink 配置段补充属性即可:
rtspsrc location=rtspt://admin:scut123456@192.168.1.64:554/Streaming/Channels/1 ! tee name=t ! queue ! decodebin ! videoconvert ! autovideosink t. ! queue ! rtph264depay ! h264parse ! appsink name=mysink emit-signals=TRUE sync=FALSE
方式二:在C++代码中动态设置
获取到 appsink 对象后,新增属性设置逻辑:
GstElement *appsink = gst_bin_get_by_name(GST_BIN(pipeline), "mysink"); // 新增属性配置 g_object_set(appsink, "emit-signals", TRUE, "sync", FALSE, NULL); printIt(appsink->pads);
2. (可选)调整为获取解码后原始帧
如果需要直接拿到可处理的RGB/YUV格式视频帧,可以把appsink分支调整为解码逻辑:
t. ! queue ! decodebin ! videoconvert ! video/x-raw,format=BGR ! appsink name=mysink emit-signals=TRUE sync=FALSE
回调获取帧数据的补充逻辑
你可以在new_sample_cb回调中添加以下代码拿到实际帧数据:
GstFlowReturn new_sample_cb (GstElement * appsink, gpointer udata) { GstSample *sample = gst_app_sink_pull_sample(GST_APP_SINK(appsink)); GstBuffer *buffer = gst_sample_get_buffer(sample); // 这里可以解析buffer获取帧数据 g_print("new-sample cb, get frame size: %lu\n", gst_buffer_get_size(buffer)); gst_sample_unref(sample); return GST_FLOW_OK; }
内容的提问来源于stack exchange,提问作者majiao
相关产品推荐
相关产品推荐

