I am working with a rtsp stream where the one of the channels is video and other could be either audio or onvif data.
I need to detect if the second rtspsrc pad(channel) is audio and then setup the pipeline to decode the audio stream.
First I detect if the newly added pad in rtspsrc is audio by adding a connect_pad_added
. When it is audio then I create a decodebin and then attached to the src_pad
and add another connect_pad_added
to the decodebin this time to receive the src_pad
and then create the rest of the pipeline.
Somehow the first connect_pad_added
to the rtspsrc gets called but not the one I connect to the decode bin.
Is it not okay to chain the pad_added
connections like that? What is a better way to do it in such a scenario?
Here is a code snippet of what I am doing.
From the pipeline launched through parse_launch
I get the rtspsrc element 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");
}
}
});
The issue was that once the pipeline is in running state, the newly added decodebin is not in same state as the rest of the pipeline.
calling decodebin.sync_state_with_parent()
after linking the rtspsrc.src->decodebin.sink fixed the problem.