Skip to content

Commit

Permalink
#3964 run some basic pipelines for testing
Browse files Browse the repository at this point in the history
  • Loading branch information
totaam committed Oct 11, 2023
1 parent 5f9a3e3 commit fa59906
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 29 deletions.
106 changes: 102 additions & 4 deletions xpra/gtk/configure/gstreamer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,20 @@
# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
# later version. See the file COPYING for details.

import gi
import shlex
from textwrap import wrap
from subprocess import Popen, PIPE

from xpra.util.types import AtomicInteger
from xpra.os_util import is_X11, is_gnome, OSX, WIN32
from xpra.gtk.dialogs.base_gui_window import BaseGUIWindow
from xpra.gtk.widget import label
from xpra.gtk.widget import label, slabel, title_box
from xpra.platform.paths import get_image
from xpra.log import Logger

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import Gtk, GLib

log = Logger("gstreamer", "util")

Expand All @@ -34,7 +38,7 @@ def __init__(self, parent:Gtk.Window|None=None):
self.warning_pixbuf = get_image("warning.png")
size = (800, 554)
if self.warning_pixbuf:
size = self.warning_pixbuf.get_width(), self.warning_pixbuf.get_height()
size = self.warning_pixbuf.get_width()+20, self.warning_pixbuf.get_height()+20
super().__init__(
"Configure Xpra's GStreamer Codecs",
"gstreamer.png",
Expand All @@ -52,11 +56,105 @@ def populate(self):
self.populate_with_warning()
else:
self.add_widget(label("Configure Xpra GStreamer Codecs", font="sans 20"))
grid = Gtk.Grid()
grid.set_row_homogeneous(False)
grid.set_column_homogeneous(True)
hbox = Gtk.HBox()
hbox.add(slabel("Please select the viewing element"))
videosink = "ximagesink"
self.add_widget(hbox)
self.add_widget(grid)
grid.attach(title_box("Mode"), 0, 0, 1, 1)
grid.attach(title_box("GStreamer Elements"), 1, 0, 1, 1)
grid.attach(title_box("Test"), 2, 0, 1, 1)
grid.attach(title_box("Result"), 3, 0, 1, 1)
row = AtomicInteger(1)

WIDTH = 640
HEIGHT = 480
FRAMERATE = 10

def lal(text:str, element:str, test="") -> None:
r = int(row)
grid.attach(title_box(text), 0, r, 1, 1)
lbl = slabel(element)
al = Gtk.Alignment(xalign=0, yalign=0.5, xscale=0.0, yscale=0.0)
al.add(lbl)
grid.attach(al, 1, r, 1, 1)
if test:
btn = Gtk.Button(label="Run")
grid.attach(btn, 2, r, 1, 1)
lbl = slabel()
al = Gtk.Alignment(xalign=0, yalign=0.5, xscale=0.0, yscale=0.0)
al.add(lbl)
grid.attach(al, 3, r, 1, 1)
def run_test(btn, lbl):
log(f"run_test({btn}, {lbl})")
lbl.set_label(f"Testing {element}")
from xpra.util.thread import start_thread
start_thread(self.test_element, f"test {element}", True, (lbl, element, test))
btn.connect("clicked", run_test, lbl)
row.increase()
if is_X11():
lal("X11 Capture", "ximagesrc",
f"ximagesrc use-damage=0 ! video/x-raw,framerate={FRAMERATE}/1 ! videoscale method=0 ! video/x-raw,width={WIDTH},height={HEIGHT} ! {videosink}")
if is_gnome():
lal("pipewire ScreenCast", "pipewiresrc")
lal("pipewire RemoteDesktop", "pipewiresrc")

def testencoder(element, fmt) -> str:
return f"videotestsrc num-buffers=50 ! 'video/x-raw,format=(string)NV12,width={WIDTH},height={HEIGHT},framerate=(fraction){FRAMERATE}/1' ! videoconvert ! {element} ! avdec_{fmt} ! videoconvert ! {videosink}"
def encoder_option(text:str, element:str, fmt:str):
lal(text, element, testencoder(element, fmt))

for sw in ("x264", "vp8", "vp9", "av1"):
fmt = {"x264" : "h264"}.get(sw, sw)
encoder_option(f"software {sw} encoder", f"{sw}enc", fmt)
for fmt in ("h264", "h265", "jpeg", "vp8", "vp9"):
encoder_option(f"vaapi {fmt} encoder", f"vaapi{fmt}enc", fmt)
encoder_option(f"libva {fmt} encoder", f"va{fmt}enc", fmt)
if WIN32:
for fmt in ("h264", "h265"):
encoder_option(f"NVidia D3D11 {fmt}", f"nvd3d11{fmt}enc", fmt)
for fmt in ("h264", "h265"):
encoder_option(f"NVENC {fmt}", f"nv{fmt}enc", fmt)
if not (OSX or WIN32):
for fmt in ("h264", "h265"):
lal(f"AMD AMF {fmt}", f"amf{fmt}enc", fmt)
self.vbox.show_all()

def test_element(self, lbl, element, test):
def set_label(message="OK"):
GLib.timeout_add(1000, lbl.set_label, message)
def run_test_cmd(cmd):
try:
log.info(f"running {cmd!r}")
proc = Popen(cmd, text=True, stdout=PIPE, stderr=PIPE)
out, err = proc.communicate(None)
if proc.returncode==0:
return True
log.error(f"Error: {cmd!r} returned {proc.returncode}")
set_label(f"Error: test pipeline returned {proc.returncode}")
except OSError as e:
log.error(f"Error running {cmd!r}: {e}")
set_label(f"Error: {e}")
return False

#first make sure that the element exists:
if not run_test_cmd(["gst-inspect-1.0", element]):
return
set_label("Element found")
if not run_test_cmd(["gst-launch-1.0"]+shlex.split(test)):
return
set_label("Test pipeline worked")


def populate_with_warning(self):
layout = Gtk.Layout()
layout.set_margin_top(0)
layout.set_margin_bottom(0)
layout.set_margin_start(0)
layout.set_margin_end(0)
self.vbox.add(layout)
if self.warning_pixbuf:
image = Gtk.Image.new_from_pixbuf(self.warning_pixbuf)
Expand Down
16 changes: 15 additions & 1 deletion xpra/gtk/configure/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from xpra.scripts.config import InitExit
from xpra.exit_codes import ExitCode
from xpra.util.parsing import parse_simple_dict
from xpra.gtk.dialogs.base_gui_window import BaseGUIWindow
from xpra.gtk.widget import label
from xpra.log import Logger
Expand Down Expand Up @@ -66,10 +67,23 @@ def run_gui(gui_class=ConfigureGUI) -> int:
return 0


def get_user_config_file():
def get_user_config_file() -> str:
from xpra.platform.paths import get_user_conf_dirs
return os.path.join(get_user_conf_dirs()[0], "99_configure_tool.conf")

def parse_user_config_file() -> dict:
filename = get_user_config_file()
if not os.path.exists(filename):
return {}
with open(filename, "r", encoding="utf8") as f:
return parse_simple_dict(f.read())

def save_user_config_file(options:dict) -> None:
filename = get_user_config_file()
with open(filename, "w", encoding="utf8") as f:
for k,v in options.items():
f.write(f"{k} = {v}")


def main(args) -> ExitCode:
if args:
Expand Down
23 changes: 1 addition & 22 deletions xpra/gtk/dialogs/session_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from xpra.client.base.gobject_client import InfoTimerClient
from xpra.gtk.gtk_util import add_close_accel
from xpra.gtk.graph import make_graph_imagesurface
from xpra.gtk.widget import imagebutton, label, modify_fg, IgnoreWarningsContext
from xpra.gtk.widget import imagebutton, title_box, slabel
from xpra.gtk.pixbuf import get_icon_pixbuf
from xpra.log import Logger

Expand All @@ -47,18 +47,6 @@ def make_datetime(date, time) -> str:
return bytestostr(date or "")
return "%s %s" % (bytestostr(date), bytestostr(time))

def title_box(label_str:str, tooltip="") -> Gtk.EventBox:
eb = Gtk.EventBox()
lbl = slabel(label_str, tooltip=tooltip)
modify_fg(lbl, Gdk.Color(red=48*256, green=0, blue=0))
al = Gtk.Alignment(xalign=0.0, yalign=0.5, xscale=0.0, yscale=0.0)
al.set_margin_start(10)
al.set_margin_end(10)
al.add(lbl)
eb.add(al)
with IgnoreWarningsContext():
eb.modify_bg(Gtk.StateType.NORMAL, Gdk.Color(red=219*256, green=226*256, blue=242*256))
return eb

def bool_icon(image, on_off:bool):
if on_off:
Expand Down Expand Up @@ -134,15 +122,6 @@ def newdictlook(d, parts, fallback=None):
return fallback
return v

def slabel(text:str="", tooltip:str="", font:str="") -> Gtk.Label:
l = label(text, tooltip, font)
l.set_margin_start(5)
l.set_margin_end(5)
l.set_margin_top(2)
l.set_margin_bottom(2)
l.set_selectable(True)
l.set_line_wrap(True)
return l

def image_label_hbox():
hbox = Gtk.HBox(homogeneous=False, spacing=10)
Expand Down
31 changes: 29 additions & 2 deletions xpra/gtk/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
from contextlib import AbstractContextManager

import gi

gi.require_version("Gtk", "3.0") # @UndefinedVariable
gi.require_version("Gdk", "3.0") # @UndefinedVariable
gi.require_version("Pango", "1.0") # @UndefinedVariable
from gi.repository import Gtk, Pango #@UnresolvedImport
from gi.repository import Gtk, Gdk, Pango #@UnresolvedImport

from xpra.log import Logger
log = Logger("gtk", "util")
Expand Down Expand Up @@ -152,4 +154,29 @@ def choose_file(parent_window, title, action=Gtk.FileChooserAction.OPEN, action_

def pack_start(self, child, expand=True, fill=True, padding=0):
orig_pack_start(self, child, expand, fill, padding)
Gtk.Box.pack_start = pack_start
Gtk.Box.pack_start = pack_start


def slabel(text:str="", tooltip:str="", font:str="") -> Gtk.Label:
l = label(text, tooltip, font)
l.set_margin_start(5)
l.set_margin_end(5)
l.set_margin_top(2)
l.set_margin_bottom(2)
l.set_selectable(True)
l.set_line_wrap(True)
return l


def title_box(label_str:str, tooltip="") -> Gtk.EventBox:
eb = Gtk.EventBox()
lbl = slabel(label_str, tooltip=tooltip)
modify_fg(lbl, Gdk.Color(red=48*256, green=0, blue=0))
al = Gtk.Alignment(xalign=0.0, yalign=0.5, xscale=0.0, yscale=0.0)
al.set_margin_start(10)
al.set_margin_end(10)
al.add(lbl)
eb.add(al)
with IgnoreWarningsContext():
eb.modify_bg(Gtk.StateType.NORMAL, Gdk.Color(red=219*256, green=226*256, blue=242*256))
return eb

0 comments on commit fa59906

Please sign in to comment.