如何在GStreamer中从RTSP H264流读取Producer Reference Time?
技术建议:GStreamer无法解码带Producer Reference Time的RTSP流数据包
问题背景
通过修改后的ffprobe执行命令:
ffprobe -show_packets -show_frames -of json <rtspstream of ip camera>
获取到数据包包含Producer Reference Time侧数据:
AvPacket: "side_data_list": [ { "side_data_type": "Producer Reference Time" "wallclock": 213414, "flags": 24 } ]
在Ubuntu上编译GStreamer源码并开启日志级别1000,追踪解封装、解复用、解码环节10小时后,仍无法解码该数据并传递给下游GStreamer API。
针对性技术建议
排查PRT侧数据的兼容性支持
检查编译的GStreamer版本及插件是否原生支持Producer Reference Time(PRT):- 执行
gst-inspect-1.0 rtspsrc查看rtspsrc插件是否有处理PRT的相关属性; - 确认gst-plugins-good、gst-plugins-bad等插件集是否开启了RTSP扩展支持,部分PRT处理逻辑可能在特定插件中。
- 执行
拆解Pipeline定位故障环节
避免全链路调试,拆分环节验证:- 先验证解封装解复用是否正常:
将dump出的码流保存为文件,用gst-launch-1.0 rtspsrc location=<你的RTSP流地址> ! rtph264depay ! h264parse ! fakesink dump=trueffplay播放,若能正常播放则说明解封装环节无问题,故障出在解码或下游传递; - 用uridecodebin快速验证完整链路兼容性:
若能正常播放,说明基础流无问题,需聚焦自定义Pipeline的配置细节。gst-launch-1.0 uridecodebin uri=<你的RTSP流地址> ! autovideosink
- 先验证解封装解复用是否正常:
精准过滤GStreamer日志
日志级别1000输出冗余信息过多,聚焦关键环节:- 解封装阶段:
搜索日志中的GST_DEBUG=rtspsrc:7,rtph264depay:7 gst-launch-1.0 <你的Pipeline>side data、Producer Reference Time关键词,确认RTSP包的侧数据是否被正确解析; - 解码阶段:
(若用硬件解码器则替换为GST_DEBUG=avdec_h264:7 gst-launch-1.0 <你的Pipeline>vaapidecode:7等),查找decode error、dropped packet等报错信息,定位解码失败的具体原因。
- 解封装阶段:
手动剥离PRT侧数据的备选方案
若GStreamer原生不支持PRT传递,可通过自定义逻辑剥离侧数据:- 使用GStreamer Python绑定快速实现过滤逻辑:
import gi gi.require_version('Gst', '1.0') from gi.repository import Gst Gst.init(None) def filter_prt_side_data(pad, info): buf = info.get_buffer() buf.remove_side_data(Gst.BufferSideType.PRODUCER_REFERENCE_TIME) return Gst.PadProbeReturn.OK # 构建Pipeline,在解码前加入identity元素作为过滤点 pipeline = Gst.parse_launch("rtspsrc location=<你的RTSP流地址> ! rtph264depay ! h264parse ! identity name=prt_filter ! avdec_h264 ! autovideosink") # 给identity的sink pad添加探针处理buffer filter_pad = pipeline.get_by_name("prt_filter").get_static_pad("sink") filter_pad.add_probe(Gst.PadProbeType.BUFFER, filter_prt_side_data) # 启动Pipeline并等待结束 pipeline.set_state(Gst.State.PLAYING) bus = pipeline.get_bus() msg = bus.timed_pop_filtered(Gst.CLOCK_TIME_NONE, Gst.MessageType.ERROR | Gst.MessageType.EOS) pipeline.set_state(Gst.State.NULL)
- 使用GStreamer Python绑定快速实现过滤逻辑:
检查GStreamer编译配置
确认编译时的关键选项是否开启:- 确保开启FFmpeg支持:
--enable-ffmpeg,多数RTSP流的解码依赖FFmpeg解码器,PRT处理可能需要二者联动; - 开启调试信息:
--enable-debug和--enable-debug-info,否则即使设置高日志级别,也无法输出足够的调试细节。
- 确保开启FFmpeg支持:
内容的提问来源于stack exchange,提问作者Krzysztof Stankiewicz
相关产品推荐
相关产品推荐

