Tee at the end of a link chain makes it impossible to link an element to the front of it
Hey,
I apologize in advance for possibly posting this in the wrong place, but I can't find a forum to post problems here. I assume this isn't strictly speaking a bug, but I have tried quite a lot and stuck closely to the tutorials and still it's not working. My problem is this:
gst::Element::link_many(&[&depayloader, &decodebin]).expect("Depayloader/Decodebin elements could not be linked.");
gst::Element::link_many(&[&convert, &flipper, &queue, &clock, &rate, &rate_filter, &textoverlay, &tee]).expect("Source elements could not be linked.");
gst::Element::link_many(&[&tee_queue2, &convert2, &filter, &convert3, &sink]).expect("HLS branch elements could not be linked.");
gst::Element::link_many(&[&tee_queue, &png_enc, &filesink]).expect("Image capture elements could not be linked.");
I have a rather long pipeline starting with an rtspsrc, which is dynamically linked to an rtph264depay (due to the sometimes pad that needs to be created first), which is then statically linked (with link_many) to a decodebin. This is the first part.
The second part consists of a videoconvert element, a videoflip, a queue, a clock, a videorate with a filter element behind it (set to 5FPS), and a textoverlay, all statically linked (with link_many).
The third part is another videoconvert, another capsfilter to enforce h264, an h264parse and an hlssink2, also statically linked.
Now I used to have the second part linked to the third part directly as well (all in one link_many) and it worked perfectly, but I now put a tee at the end of the second part to duplicate the stream to a (again statically linked behind each other) queue, pngenc, and filesink to make snapshots.
But this last part isn't really relevant, because what happens now is this:
I put the first part of the pipeline together, it links statically, then dynamically. I put the second part together, again with link_many. Now I have another dynamic add function to get the sometimes pad from the decodebin and link it to the videoconvert at the beginning of the second part:
decodebin.connect_pad_added(move |src, src_pad| {
println!(
"Received new pad {} from {}",
src_pad.get_name(),
src.get_name()
);
let sink_pad = convert
.get_static_pad("sink")
.expect("Failed to get static sink pad from convert");
if sink_pad.is_linked() {
println!("We are already linked. Ignoring.");
return;
}
let new_pad_caps = src_pad
.get_current_caps()
.expect("Failed to get caps of new pad.");
let new_pad_struct = new_pad_caps
.get_structure(0)
.expect("Failed to get first structure of caps.");
let new_pad_type = new_pad_struct.get_name();
let is_video = new_pad_type.starts_with("video/x-raw");
if !is_video {
println!(
"It has type {} which is not video. Ignoring.",
new_pad_type
);
return;
}
let res = src_pad.link(&sink_pad);
if res.is_err() {
println!("Type is {} but link failed.", new_pad_type);
} else {
println!("Link succeeded (type {}).", new_pad_type);
}
});
It receives the new pad, sees that it is video/x-raw, but then fails to add it with a NoFormat error. This only happens when the tee is at the end of the second pipeline part; when I remove it, it links perfectly fine. Now I would assume that it shouldn't matter at all, because the videoconvert should accept a raw video stream. But it only does that if the tee is not at the end of the pipeline - although it should not have any impact at all. I even tried setting the "allow-not-linked" property of the tee to true, but it didn't help. The only factor that changes anything is removing the tee.
My gstreamer version is now 1.16. Any ideas?