基于C++的GStreamer RTSP服务器延迟问题求助
解决GStreamer RTSP推流10秒延迟问题
1. 修正Appsrc时间戳逻辑
你当前同时开启了do-timestamp=true和手动设置PTS,这会导致时间戳逻辑冲突;且初始PTS从0累加会让播放器因时间戳滞后缓存大量帧。
- 将appsrc的
do-timestamp改为false,确保时间戳完全由手动控制 - 绑定PTS到系统时钟实际时间,避免累积延迟,同时修复时钟引用泄漏:
void VideoStreamer::need_data(GstElement* appsrc, guint /* unused */, gpointer user_data) { VideoStreamer* self = static_cast<VideoStreamer*>(user_data); GstFlowReturn ret; std::lock_guard<std::mutex> lock(self->queue_mutex); if (!self->frame_queue.empty()) { cv::Mat frame = self->frame_queue.front(); self->frame_queue.pop(); GstBuffer* buffer; int size = frame.total() * frame.elemSize(); buffer = gst_buffer_new_allocate(nullptr, size, nullptr); GstMapInfo map; gst_buffer_map(buffer, &map, GST_MAP_WRITE); memcpy(map.data, frame.data, size); gst_buffer_unmap(buffer, &map); GstClock* clock = gst_element_get_clock(appsrc); GstClockTime now = gst_clock_get_time(clock); // 初始化或更新PTS,确保不落后于当前时间 if (self->last_pts == 0) { self->last_pts = now; } else { self->last_pts = MAX(now, self->last_pts + gst_util_uint64_scale_int(1, GST_SECOND, 30)); } GST_BUFFER_PTS(buffer) = self->last_pts; GST_BUFFER_DURATION(buffer) = gst_util_uint64_scale_int(1, GST_SECOND, 30); g_signal_emit_by_name(appsrc, "push-buffer", buffer, &ret); gst_buffer_unref(buffer); gst_object_unref(clock); // 释放时钟引用,修复内存泄漏 } else { g_signal_emit_by_name(appsrc, "end-of-stream", &ret); } }
2. 限制帧队列大小,避免后端堆积
如果OpenCV处理速度远快于推流速度,frame_queue会持续累积帧,直接导致延迟。限制队列最大长度(比如3-5帧),丢弃旧帧只保留最新的:
// 在向队列添加帧的代码中修改 std::lock_guard<std::mutex> lock(queue_mutex); const int MAX_QUEUE_SIZE = 5; if (frame_queue.size() >= MAX_QUEUE_SIZE) { frame_queue.pop(); // 丢弃最早的帧 } frame_queue.push(new_frame);
3. 优化管线缓存与编码器参数
默认的queue和编码器会缓存大量数据,是延迟的核心来源。修改管线配置:
gst_rtsp_media_factory_set_launch(factory, "( appsrc name=mysource is-live=true format=GST_FORMAT_TIME do-timestamp=false ! " "video/x-raw,format=BGR,width=1920,height=1080,framerate=30/1 ! " "videoconvert ! queue max-size-buffers=2 max-size-bytes=0 max-size-time=0 ! " "video/x-raw,format=NV12 ! " "vaapih264enc low-latency=true rate-control=vbr bitrate=4096 keyframe-period=15 ! " "rtph264pay name=pay0 pt=96 config-interval=1 )");
关键调整:
queue设置max-size-buffers=2,仅缓存2帧vaapih264enc添加low-latency=true,启用编码器低延迟模式rtph264pay添加config-interval=1,每1秒发送一次SPS/PPS,帮助客户端快速初始化- 确认appsrc的
do-timestamp=false
4. 客户端播放优化
确保客户端启用低延迟模式:
- 使用GStreamer客户端测试:
gst-launch-1.0 rtspsrc location=rtsp://your-url latency=0 ! rtph264depay ! h264parse ! vaapih264dec ! videoconvert ! autovideosink sync=false - VLC播放器可将「网络缓存(ms)」设置为100-200ms(路径:工具->偏好设置->输入/编解码器)
内容的提问来源于stack exchange,提问作者Gökhan
相关产品推荐
相关产品推荐

