我正在处理一个rtsp流,其中一个通道是视频,其他通道可以是音频或onvif数据。
我需要检测第二个rtspsrc pad(通道)是否是音频,然后设置管道来解码音频流。
首先,我通过添加一个connect_pad_added
来检测rtspsrc中新添加的pad是否是音频。当它是音频时,我创建一个decodebin,然后附加到src_pad
,并添加另一个connect_pad_added
到decodebin,这次是为了接收src_pad
,然后创建管道的其余部分。
不知何故,第一个到rtspsrc的connect_pad_added
被调用,但不是我连接到解码bin的那个。
像这样链接pad_added
连接是不是不好?在这种情况下,有什么更好的方法吗?
下面是我正在做的一个代码片段。
从通过parse_launch
启动的管道中,我得到了rtspsrc元素let rtspsrc=pipeline.by_name("basesrc")
。
rtspsrc.connect_pad_added(|src, src_pad| {
// get the pad struct and detect media type
let media_type = src_pad.current_caps().and_then(|caps| {
let new_pad_struct = caps
.structure(0)
.expect("Failed to get first structure of caps for audio");
for i in 0..new_pad_struct.n_fields() {
match new_pad_struct.nth_field_name(i).unwrap() {
"media" => {
// check if field value starts with audio
audio = true
}
_ => {}
}
}
Some(audio)
});
match media_type {
Some(is_audio) => {
if is_audio {
let audio_decode = gst::ElementFactory::make("decodebin", None)
.expect("unable to create decodebin");
pipeline
.add_many(&[&audio_decode])
.expect("unable to add audio decoder to pipeline bin");
let sink_pad = audio_decode.static_pad("sink").ok_or(/*...*/);
src_pad
.link(&sink_pad)
.expect("unable to link src_pad to audio_decode sinkpad");
audio_decode.connect_pad_added(move |dbin, audio_src_pad| {
// setup the rest of pipeline audiodecoder ! encoder ! tee name=t t.! hlssink2.. t. ! hlssink2
//.....
});
}
}
None => {
log::warn!("failed to get media_type from pad after pad added");
}
}
});
1条答案
按热度按时间nzk0hqpo1#
问题是,一旦流水线处于运行状态,新添加的decodebin与流水线的其余部分不处于相同的状态。
在链接rtspsrc.src-〉decodebin.sink之后调用
decodebin.sync_state_with_parent()
修复了这个问题。