You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 13:35:04