"""Synthetic X11 input to decoded video; excludes physical USB and scanout.""" import ctypes, ctypes.util, subprocess, os, time, json, statistics os.environ.update(DISPLAY=':0',XAUTHORITY='/home/armbian/.Xauthority') x=ctypes.CDLL(ctypes.util.find_library('X11')) x.XOpenDisplay.argtypes=[ctypes.c_char_p];x.XOpenDisplay.restype=ctypes.c_void_p x.XDefaultRootWindow.argtypes=[ctypes.c_void_p];x.XDefaultRootWindow.restype=ctypes.c_ulong x.XGetImage.argtypes=[ctypes.c_void_p,ctypes.c_ulong,ctypes.c_int,ctypes.c_int,ctypes.c_uint,ctypes.c_uint,ctypes.c_ulong,ctypes.c_int];x.XGetImage.restype=ctypes.c_void_p x.XGetPixel.argtypes=[ctypes.c_void_p,ctypes.c_int,ctypes.c_int];x.XGetPixel.restype=ctypes.c_ulong x.XDestroyImage.argtypes=[ctypes.c_void_p];x.XCloseDisplay.argtypes=[ctypes.c_void_p] prefix='/home/armbian/vdi-build/rkmpp-experiment/build/moonlight/app/moonlight stream 192.168.1.72 ' items=[l.split(None,1) for l in subprocess.check_output(['ps','-eo','pid,args'],text=True).splitlines()[1:] if len(l.split(None,1))==2 and l.split(None,1)[1].startswith(prefix)] assert len(items)==1,items pid=items[0][0] ids=subprocess.check_output(['xdotool','search','--onlyvisible','--pid',pid,'--class','Moonlight'],text=True).split();assert ids subprocess.run(['xdotool','windowactivate','--sync',ids[-1]],check=True) assert subprocess.check_output(['xdotool','getwindowfocus','getwindowpid'],text=True).strip()==pid subprocess.run(['xdotool','key','F8'],check=True) for i in range(24): px,py=((300,850) if i%2==0 else (1800,950)) subprocess.run(['xdotool','mousemove','--sync',str(px),str(py),'click','1'],check=True) time.sleep(.06) d=x.XOpenDisplay(b':0');assert d;root=x.XDefaultRootWindow(d) def pixel(): im=x.XGetImage(d,root,2250,130,1,1,0xffffffff,2);assert im v=x.XGetPixel(im,0,0);x.XDestroyImage(im);return v&0xffffff samples=[];errors=[] for i in range(24): v=pixel();assert v<0x202020 or v>0xe0e0e0,hex(v) assert subprocess.check_output(['xdotool','getwindowfocus','getwindowpid'],text=True).strip()==pid start=time.monotonic_ns() subprocess.run(['xdotool','key','--clearmodifiers','--delay','0','F9'],check=True,stdout=subprocess.DEVNULL) while time.monotonic_ns()-start<2000000000: cur=pixel() if (v<0x202020 and cur>0xe0e0e0) or (v>0xe0e0e0 and cur<0x202020): samples.append((time.monotonic_ns()-start)/1e6);break time.sleep(.002) else:errors.append(i) time.sleep(.12) x.XCloseDisplay(d);vals=sorted(samples) print(json.dumps({'method':'synthetic F9 injection to decoded marker; includes xdotool startup/polling; excludes physical USB and panel scanout','samples_ms':samples,'timeouts':errors,'p50_ms':statistics.median(vals) if vals else None,'p95_ms':vals[min(len(vals)-1,int(len(vals)*.95))] if vals else None}))