mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2025-09-02 17:53:48 +00:00
webrtcsink: Don't require encoder element for pre-encoded streams
When webrtcsink takes as an input a stream that is already encoded, it errors out when there is no encoder element available for the codec in question. This change makes it possible to stream an output from a camera that already produces e.g. video/x-h264 without bloating the GStreamer installation with a redundant H.264 encoder element. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2273>
This commit is contained in:
parent
80877c49c3
commit
1e205c842e
2 changed files with 24 additions and 6 deletions
|
@ -464,9 +464,9 @@ impl Codec {
|
||||||
let encoder = Self::get_encoder_for_caps(caps, encoders);
|
let encoder = Self::get_encoder_for_caps(caps, encoders);
|
||||||
let payloader = Self::get_payloader_for_codec(name, payloaders);
|
let payloader = Self::get_payloader_for_codec(name, payloaders);
|
||||||
|
|
||||||
let encoding_info = if let (Some(encoder), Some(payloader)) = (encoder, payloader) {
|
let encoding_info = if let (encoder, Some(payloader)) = (encoder, payloader) {
|
||||||
Some(EncodingInfo {
|
Some(EncodingInfo {
|
||||||
encoder: Some(encoder),
|
encoder,
|
||||||
payloader,
|
payloader,
|
||||||
output_filter: None,
|
output_filter: None,
|
||||||
})
|
})
|
||||||
|
@ -828,6 +828,20 @@ impl Codecs {
|
||||||
Self(codecs.values().cloned().collect())
|
Self(codecs.values().cloned().collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn list_encoders(&self) -> Codecs {
|
||||||
|
Codecs(
|
||||||
|
self.iter()
|
||||||
|
.filter(|codec| {
|
||||||
|
codec
|
||||||
|
.encoding_info
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(|info| info.encoder.is_some())
|
||||||
|
})
|
||||||
|
.cloned()
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn find_for_payloadable_caps(&self, caps: &gst::Caps) -> Option<Codec> {
|
pub fn find_for_payloadable_caps(&self, caps: &gst::Caps) -> Option<Codec> {
|
||||||
self.iter()
|
self.iter()
|
||||||
.find(|codec| codec.caps.can_intersect(caps) && codec.encoding_info.is_some())
|
.find(|codec| codec.caps.can_intersect(caps) && codec.encoding_info.is_some())
|
||||||
|
@ -938,9 +952,12 @@ impl Codecs {
|
||||||
.filter(|codec| codec.stream_type == gst::StreamType::AUDIO)
|
.filter(|codec| codec.stream_type == gst::StreamType::AUDIO)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List all codecs that can be used for encoding the given caps and assign
|
/// List all codecs that can be used for encoding and/or payloading the given
|
||||||
/// a payload type to each of them. This is useful to initiate SDP negotiation.
|
/// caps and assign a payload type to each of them. This is useful to initiate
|
||||||
pub fn list_encoders<'a>(caps: impl IntoIterator<Item = &'a gst::StructureRef>) -> Codecs {
|
/// SDP negotiation.
|
||||||
|
pub fn list_encoders_and_payloaders<'a>(
|
||||||
|
caps: impl IntoIterator<Item = &'a gst::StructureRef>,
|
||||||
|
) -> Codecs {
|
||||||
let mut payload = 96..128;
|
let mut payload = 96..128;
|
||||||
|
|
||||||
Codecs(
|
Codecs(
|
||||||
|
|
|
@ -4080,6 +4080,7 @@ impl BaseWebRTCSink {
|
||||||
codecs: &Codecs,
|
codecs: &Codecs,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let futs = if has_raw_caps(&discovery_info.caps) {
|
let futs = if has_raw_caps(&discovery_info.caps) {
|
||||||
|
let codecs = codecs.list_encoders();
|
||||||
if codecs.is_empty() {
|
if codecs.is_empty() {
|
||||||
return Err(anyhow!(
|
return Err(anyhow!(
|
||||||
"No codec available for encoding stream {}, \
|
"No codec available for encoding stream {}, \
|
||||||
|
@ -4331,7 +4332,7 @@ impl BaseWebRTCSink {
|
||||||
} else {
|
} else {
|
||||||
drop(state);
|
drop(state);
|
||||||
let settings = self.settings.lock().unwrap();
|
let settings = self.settings.lock().unwrap();
|
||||||
let codecs = Codecs::list_encoders(
|
let codecs = Codecs::list_encoders_and_payloaders(
|
||||||
settings.video_caps.iter().chain(settings.audio_caps.iter()),
|
settings.video_caps.iter().chain(settings.audio_caps.iter()),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue