gstreamer rust 为 x264enc 上设置的比特率获取人类可读的输出

gstreamer rust get human readable output for bitrate set on x264enc

希望在 Rust 绑定中获得 x264enc 比特率和帧率的人类可读输出,以确认值的变化

根据示例,比特率似乎是从

设置的

bitrate : Bitrate in kbit/sec flags: readable, writable, changeable in NULL, READY, PAUSED or PLAYING state

所以首先我们创建元素并将其添加到管道,然后 link 它

 let myEnc = gst::ElementFactory::make("x264enc", None)
            .map_err(|_| MissingElement("x264enc"))?;
 //... do the .link() stuff

现在将速率设置为 gint

//... set the rate
 let setBitrate = 1500;
 let haveSetBr = myEnc.set_property("bitrate",&setBitrate).unwrap();

这会生成一个错误,告诉我们更改为 guint,这似乎是 type guint = c_uint; => type c_uint = u32;,因此请更改类型

  //... set the rate
 let setBitrate:u32 = 1500;
 let haveSetBr = myEnc.set_property("bitrate",&setBitrate).unwrap();

没有报告错误

//... get the rate
 let brNow = myEnc.get_property("bitrate");
            println!("the bit rate is set at {:#?}",brNow );

将输出作为 enum

the bit rate is set at Ok(
    Value(
        GString(
            Foreign(
                0x0000555555aebb00,
                4,
            ),
        ),
    ),
)

那么如何将输出类型更改为 u32 数字?

现在根据 gst-inspect-1.0 x264enc 设置帧率,功能报告为

>  Capabilities:
>       video/x-raw
>               framerate: [ 0/1, 2147483647/1 ]
>                   width: [ 16, 2147483647 ]
>                  height: [ 16, 2147483647 ]
>                  format: { (string)Y444, (string)Y42B, (string)I420, (string)YV12, (string)NV12, (string)Y444_10LE, (string)I422_10LE,
> (string)I420_10LE }
> 
>   SRC template: 'src'
>     Availability: Always
>     Capabilities:
>       video/x-h264
>               framerate: [ 0/1, 2147483647/1 ]
>                   width: [ 1, 2147483647 ]
>                  height: [ 1, 2147483647 ]
>           stream-format: { (string)avc, (string)byte-stream }
>               alignment: au
>                 profile: { (string)high-4:4:4, (string)high-4:2:2, (string)high-10, (string)high, (string)main, (string)baseline,
> (string)constrained-baseline, (string)high-4:4:4-intra,
> (string)high-4:2:2-intra, (string)high-10-intra }

所以按照示例 glupload.rs 我们添加

 let caps = gst::Caps::builder("video/x-raw")
            .field("format", &gst_video::VideoFormat::I420.to_str())
            .field("framerate", &"25/1")
            .build();
 myEnc.set_caps(Some(&caps));

但是这会产生编译错误

error[E0599]: no method named `set_caps` found for struct `gst::Element` in the current scope
       --> examples....
        |
        |         myEnc.set_caps(Some(&caps));
        |              ^^^^^^^^ method not found in `gst::Element`

这里是脚本顶部的导入,我们是否遗漏了任何可以解决上述错误的内容?例如,我们是否需要 link 到示例文件夹或 gstreamer/src/ 文件夹中的另一个脚本?

extern crate gstreamer as gst;
use gst::gst_element_error;
use gst::prelude::*;
use glib::GString;
extern crate gstreamer_video as gst_video;
extern crate gstreamer_app as gst_app;
use std::env;
use anyhow::Error;
use derive_more::{Display, Error};

这里有多个问题:

  1. so how do you change the output type to a u32 number?

您的应用程序的输出已经告诉您这是一个 glib::Value,因此第一步是检查 it's docs:您需要从中获取值,在您的情况下通过 value.get::<u32>()value.get_some::<u32>().

  1. myEnc.set_caps(Some(&caps)); however this generates compile errors

您不能只在元素上设置上限,这在概念上没有任何意义,而且正如编译器告诉您的那样,也没有这样的功能。如果你想在两个元素的垫之间强制执行特定的上限,你需要使用 capsfilter 元素(通过 set_property()) or by using element1.link_pads_filtered(Some("src"), &element2, Some("sink"), Some(&caps)).[=22= 在其 caps 属性 上设置上限]