frontends (tools/webrtc): Fix pipeline for desktop sharing:
Fix desktop sharing, and improve error handling.
This commit is contained in:
parent
9a2830c7e2
commit
a5e1280af8
1 changed files with 72 additions and 13 deletions
|
|
@ -1502,27 +1502,87 @@ class WebRTC:
|
|||
log.debug(f"setting {source_elt} property: {key!r}={value!r}")
|
||||
desktop_src.set_property(key, value)
|
||||
video_convert = Gst.ElementFactory.make("videoconvert", "desktop_videoconvert")
|
||||
video_rate = Gst.ElementFactory.make("videorate", "desktop_videorate")
|
||||
video_scale = Gst.ElementFactory.make("videoscale", "desktop_videoscale")
|
||||
|
||||
# Add capsfilter to ensure proper format matching with video_selector
|
||||
capsfilter = Gst.ElementFactory.make("capsfilter", "desktop_capsfilter")
|
||||
caps = Gst.Caps.from_string("video/x-raw,framerate=30/1")
|
||||
capsfilter.set_property("caps", caps)
|
||||
|
||||
queue = Gst.ElementFactory.make("queue", "desktop_queue")
|
||||
queue.set_property("leaky", "downstream")
|
||||
queue.set_property("max-size-buffers", 3)
|
||||
|
||||
self.pipeline.add(desktop_src)
|
||||
self.pipeline.add(video_convert)
|
||||
self.pipeline.add(video_rate)
|
||||
self.pipeline.add(video_scale)
|
||||
self.pipeline.add(capsfilter)
|
||||
self.pipeline.add(queue)
|
||||
|
||||
desktop_src.link(video_convert)
|
||||
video_convert.link(queue)
|
||||
# Link the elements: src → convert → rate → scale → capsfilter → queue
|
||||
if not desktop_src.link(video_convert):
|
||||
log.error("Failed to link desktop_src to videoconvert")
|
||||
self._cleanup_desktop_elements([desktop_src, video_convert, video_rate,
|
||||
video_scale, capsfilter, queue])
|
||||
return
|
||||
|
||||
if not video_convert.link(video_rate):
|
||||
log.error("Failed to link videoconvert to videorate")
|
||||
self._cleanup_desktop_elements([desktop_src, video_convert, video_rate,
|
||||
video_scale, capsfilter, queue])
|
||||
return
|
||||
|
||||
if not video_rate.link(video_scale):
|
||||
log.error("Failed to link videorate to videoscale")
|
||||
self._cleanup_desktop_elements([desktop_src, video_convert, video_rate,
|
||||
video_scale, capsfilter, queue])
|
||||
return
|
||||
|
||||
if not video_scale.link(capsfilter):
|
||||
log.error("Failed to link videoscale to capsfilter")
|
||||
self._cleanup_desktop_elements([desktop_src, video_convert, video_rate,
|
||||
video_scale, capsfilter, queue])
|
||||
return
|
||||
|
||||
if not capsfilter.link(queue):
|
||||
log.error("Failed to link capsfilter to queue")
|
||||
self._cleanup_desktop_elements([desktop_src, video_convert, video_rate,
|
||||
video_scale, capsfilter, queue])
|
||||
return
|
||||
|
||||
sink_pad_template = self.video_selector.get_pad_template("sink_%u")
|
||||
self.desktop_sink_pad = self.video_selector.request_pad(
|
||||
sink_pad_template, None, None
|
||||
)
|
||||
queue_src_pad = queue.get_static_pad("src")
|
||||
queue_src_pad.link(self.desktop_sink_pad)
|
||||
link_ret = queue_src_pad.link(self.desktop_sink_pad)
|
||||
if link_ret != Gst.PadLinkReturn.OK:
|
||||
log.error(f"Failed to link queue to video_selector: {link_ret}")
|
||||
self._cleanup_desktop_elements([desktop_src, video_convert, video_rate,
|
||||
video_scale, capsfilter, queue])
|
||||
return
|
||||
|
||||
desktop_src.sync_state_with_parent()
|
||||
video_convert.sync_state_with_parent()
|
||||
video_rate.sync_state_with_parent()
|
||||
video_scale.sync_state_with_parent()
|
||||
capsfilter.sync_state_with_parent()
|
||||
queue.sync_state_with_parent()
|
||||
|
||||
log.info("Desktop source pipeline successfully created and linked")
|
||||
|
||||
def _cleanup_desktop_elements(self, elements: list[Gst.Element]) -> None:
|
||||
"""Helper to cleanup elements on error.
|
||||
|
||||
@param elements: List of elements to remove from pipeline
|
||||
"""
|
||||
for element in elements:
|
||||
if element:
|
||||
element.set_state(Gst.State.NULL)
|
||||
self.pipeline.remove(element)
|
||||
|
||||
def _remove_desktop_source(self, desktop_src: Gst.Element) -> None:
|
||||
"""Remove the desktop source from the pipeline.
|
||||
|
||||
|
|
@ -1530,19 +1590,18 @@ class WebRTC:
|
|||
"""
|
||||
# Remove elements for the desktop source
|
||||
video_convert = self.pipeline.get_by_name("desktop_videoconvert")
|
||||
video_rate = self.pipeline.get_by_name("desktop_videorate")
|
||||
video_scale = self.pipeline.get_by_name("desktop_videoscale")
|
||||
capsfilter = self.pipeline.get_by_name("desktop_capsfilter")
|
||||
queue = self.pipeline.get_by_name("desktop_queue")
|
||||
|
||||
if video_convert:
|
||||
video_convert.set_state(Gst.State.NULL)
|
||||
desktop_src.unlink(video_convert)
|
||||
self.pipeline.remove(video_convert)
|
||||
# Unlink and remove in reverse order
|
||||
elements = [queue, capsfilter, video_scale, video_rate, video_convert, desktop_src]
|
||||
|
||||
if queue:
|
||||
queue.set_state(Gst.State.NULL)
|
||||
self.pipeline.remove(queue)
|
||||
|
||||
desktop_src.set_state(Gst.State.NULL)
|
||||
self.pipeline.remove(desktop_src)
|
||||
for element in elements:
|
||||
if element:
|
||||
element.set_state(Gst.State.NULL)
|
||||
self.pipeline.remove(element)
|
||||
|
||||
# Release the pad associated with the desktop source
|
||||
if self.desktop_sink_pad:
|
||||
|
|
|
|||
Loading…
Reference in a new issue