mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2025-09-02 01:33:47 +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 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 {
|
||||
encoder: Some(encoder),
|
||||
encoder,
|
||||
payloader,
|
||||
output_filter: None,
|
||||
})
|
||||
|
@ -828,6 +828,20 @@ impl Codecs {
|
|||
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> {
|
||||
self.iter()
|
||||
.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)
|
||||
}
|
||||
|
||||
/// List all codecs that can be used for encoding the given caps and assign
|
||||
/// a payload type to each of them. This is useful to initiate SDP negotiation.
|
||||
pub fn list_encoders<'a>(caps: impl IntoIterator<Item = &'a gst::StructureRef>) -> Codecs {
|
||||
/// List all codecs that can be used for encoding and/or payloading the given
|
||||
/// caps and assign a payload type to each of them. This is useful to initiate
|
||||
/// SDP negotiation.
|
||||
pub fn list_encoders_and_payloaders<'a>(
|
||||
caps: impl IntoIterator<Item = &'a gst::StructureRef>,
|
||||
) -> Codecs {
|
||||
let mut payload = 96..128;
|
||||
|
||||
Codecs(
|
||||
|
|
|
@ -4080,6 +4080,7 @@ impl BaseWebRTCSink {
|
|||
codecs: &Codecs,
|
||||
) -> Result<(), Error> {
|
||||
let futs = if has_raw_caps(&discovery_info.caps) {
|
||||
let codecs = codecs.list_encoders();
|
||||
if codecs.is_empty() {
|
||||
return Err(anyhow!(
|
||||
"No codec available for encoding stream {}, \
|
||||
|
@ -4331,7 +4332,7 @@ impl BaseWebRTCSink {
|
|||
} else {
|
||||
drop(state);
|
||||
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()),
|
||||
);
|
||||
|
||||
|
|
Loading…
Reference in a new issue