如何从Deepstream的uridecodebin源获取视频码率
获取DeepStream源视频码率并设置给输出编码器
针对你基于uridecodebin的Source Bin,以下是三种获取源视频码率并传递给输出编码器的可行方案:
方案1:通过streams-selected信号提取码率
在uridecodebin选择好流之后,直接从流信息中提取视频码率,这是最直接的方式。修改create_source_bin函数,添加信号监听:
def create_source_bin(index, uri): print("Creating source bin") bin_name = "source-bin-%02d" % index print(bin_name) nbin = Gst.Bin.new(bin_name) if not nbin: sys.stderr.write(" Unable to create source bin \n") uri_decode_bin = Gst.ElementFactory.make("uridecodebin", "uri-decode-bin") if not uri_decode_bin: sys.stderr.write(" Unable to create uri decode bin \n") uri_decode_bin.set_property("uri", uri) # 新增:监听流选择完成信号,提取视频码率 def on_streams_selected(decodebin, streams): for stream in streams: if stream.get_stream_type() == Gst.StreamType.VIDEO: caps = stream.get_caps() if caps and caps.get_structure(0).has_field("bitrate"): bitrate = caps.get_structure(0).get_int("bitrate").value print(f"源视频码率:{bitrate} bps({bitrate//1000} kbps)") # 将码率绑定到source bin实例,方便后续调用 nbin.source_bitrate = bitrate uri_decode_bin.connect("streams-selected", on_streams_selected) uri_decode_bin.connect("pad-added", cb_newpad, nbin) uri_decode_bin.connect("child-added", decodebin_child_added, nbin) Gst.Bin.add(nbin, uri_decode_bin) bin_pad = nbin.add_pad(Gst.GhostPad.new_no_target("src", Gst.PadDirection.SRC)) if not bin_pad: sys.stderr.write(" Failed to add ghost pad in source bin \n") return None return nbin
方案2:在解码Pad回调中查询码率
在cb_newpad函数中,通过Gst的BITRATE查询接口获取码率:
def cb_newpad(decodebin, decoder_src_pad, data): print("In cb_newpad\n") caps = decoder_src_pad.get_current_caps() if not caps: caps = decoder_src_pad.query_caps() gststruct = caps.get_structure(0) gstname = gststruct.get_name() source_bin = data features = caps.get_features(0) # 新增:查询视频流码率 if gstname.find("video") != -1: bitrate_query = Gst.Query.new_bitrate() if decoder_src_pad.query(bitrate_query): _, _, _, avg_bitrate = bitrate_query.parse_bitrate() if avg_bitrate > 0: print(f"源视频平均码率:{avg_bitrate} bps") source_bin.source_bitrate = avg_bitrate # 原有链接逻辑保持不变 if(gstname.find("video")!=-1): if features.contains("memory:NVMM"): bin_ghost_pad = source_bin.get_static_pad("src") if not bin_ghost_pad.set_target(decoder_src_pad): sys.stderr.write("Failed to link decoder src pad to source bin ghost pad\n") else: sys.stderr.write(" Error: Decodebin did not pick nvidia decoder plugin.\n")
方案3:从Demuxer子元素提取码率
在decodebin_child_added函数中,监听Demuxer的Pad创建事件,从流Caps中提取码率:
def decodebin_child_added(child_proxy, Object, name, user_data): print("Decodebin child added:", name, "\n") if(name.find("decodebin") != -1): Object.connect("child-added", decodebin_child_added, user_data) if "source" in name: source_element = child_proxy.get_by_name("source") if source_element.find_property('drop-on-latency') != None: Object.set_property("drop-on-latency", True) # 新增:处理Demuxer元素,提取视频流码率 if "demux" in name or name in ["qtdemux"]: def on_demux_pad_added(demux, pad): if pad.get_direction() == Gst.PadDirection.SRC: pad_caps = pad.get_current_caps() if pad_caps: struct = pad_caps.get_structure(0) if struct.get_name().startswith("video/") and struct.has_field("bitrate"): bitrate = struct.get_int("bitrate").value print(f"源视频码率:{bitrate} bps") user_data["source_bitrate"] = bitrate Object.connect("pad-added", on_demux_pad_added)
将码率设置给输出编码器
假设你使用的是NVIDIA硬件编码器nvv4l2h264enc,可以在创建编码器后直接绑定获取到的码率:
# 假设已经创建好source_bin并获取到码率 encoder = Gst.ElementFactory.make("nvv4l2h264enc", "video-encoder") if encoder and hasattr(source_bin, 'source_bitrate'): # 编码器bitrate参数单位为bps,直接传入即可 encoder.set_property("bitrate", source_bin.source_bitrate) # 如果使用x264enc等软件编码器,部分参数单位为kbps,需要转换:source_bin.source_bitrate // 1000
注意事项
- 不同容器格式的码率字段存在情况不同,建议结合多种方案确保获取成功;
- 可变码率流获取到的是平均码率,可直接作为编码器的目标码率使用。
内容的提问来源于stack exchange,提问作者Nawin K Sharma
相关产品推荐
相关产品推荐

