FDH2 / UxPlay

AirPlay Unix mirroring server
GNU General Public License v3.0
1.35k stars 72 forks source link

Fullscreen mode #46

Closed Harvie closed 2 years ago

Harvie commented 2 years ago

I have uxplay 1.44f (on archlinux/AUR) and it seems to work perfectly! I would like to be able specify mode in which uxplay will open in fullscreen mode once device is connected.

My use case is: I have running LXDE on raspberry4 with Kodi in fullscreen window. Once the device gets connected to uxplay i want it to overtake the kodi focus and show mirrored video instead. once phone is disconnected i want to automaticaly return back to kodi fullscreen window.

Is it possible to have such mode? Idealy with optional possibility to specify which monitor should display uxplay window on fullscreen in case i have multiple monitors.

fduncanh commented 2 years ago

Unfortunately, there is no full-screen mode in uxplay. It has basic GStreamer use that works with lots of different video systems using "autovideosink" . My understanding is that one can do a lot more fancy things with GStreamer, but then one needs to specialize to a particular choice of video output. It needs a GStreamer expert to make further improvements to UxPlay

Uxplay is essentially RPiPlay plus some added features/improvements RPiPlay has alternative video and audio options (not GStreamer) adapted to older RPi that might have fullscreen options.

I would think that UxPlay with GStreamer will run fine on a raspberry4, but not on less powerful older versions. Its mainly aimed at desktop systems.

Harvie commented 2 years ago

Perhaps you can add option to configure "connect/disconnect hooks" so when device gets connected, the window gets open and my custom shell command gets invoked, which will then position the uxplay window for me. once device is disconnected, the gstreamer window will be closed again. then the custom disconnect hook shell command gets invoked to make kodi fullscreen again.

Somethinkg like

--hook-connect="/usr/local/bin/myscript connect something something"
--hook-diconnect="/usr/local/bin/myscript disconnect something something"
fduncanh commented 2 years ago

@Harvie

What I can easily offer is a patch that changes the uxplay behavior to close the video window when the client sends the "stop mirroring" message, but keeps the server running so a new connection from a client can be then be made when needed.

uxplay_patch.txt

apply it to uxplay.cpp

If this is a useful behavior, I can add a startup option for it. Let me know.

Maybe you can build on this to do the more complicated thing you want.

fduncanh commented 2 years ago

the server callbacks conn_init and conn_destroy in uxplay.cpp update the number of open connections (audio and video are separate) you could put your hook calls there

Harvie commented 2 years ago

What I can easily offer is a patch that changes the uxplay behavior to close the video window when the client sends the "stop mirroring" message, but keeps the server running so a new connection from a client can be then be made when needed.

That would be perfect! Please add such option.

Will this timeout after while. So when client becomes unavailable, eg. battery in phone dies or wifi signal is lost before client sends "stop mirroring" it does not leave the window open indefinitely?

fduncanh commented 2 years ago

@Harvie I already gave you the patch uxplay_patch.txt (see above). Did you try it? its a clickable link. You did not say that you had tried it.

(click on it to download, put it in the UxPlay directory, then (from in that directory ) "patch < uxplay_patch.txt", and rebuild) This will modify uxplay.cpp Maybe do "cp uxplay.cpp uxplay.cpp.saved" before modifying uxplay.cpp, but if you are using git, "git stash" will also restore the original version.

I see that the patch I give you doesn't shut down the audio connection, so it needs a bit more work, but you should have tested it it reported back the results of the test, which would have showed up this problem... I'll work on a new patch, but please try the first one

fduncanh commented 2 years ago

EDIT the wrong patch was given

here is a corrected patch that also shuts down the audio connection as well as video when you click "stop mirroring" please test carefully, to see if there are any other unanticipated problems with this patch.

(It might be that this should become the default behavior of uxplay when the client signals "stop mirroring")

fduncanh commented 2 years ago

@Harvie

here is the correct patch

uxplay_patchv2.txt

download it and move it to the UxPlay directory, cd to that directory, and apply the patch with

patch <  uxplay_patchv2.txt

then rebuild and test uxplay

fduncanh commented 2 years ago

Q Will this timeout after while. So when client becomes unavailable, eg. battery in phone dies or wifi signal is lost before client sends "stop mirroring" it does not leave the window open indefinitely?

good question. A simple test of shutting down an ipad while it is connected leaves a black screen showing on the server, since the client does not send "stop mirroring". However, another client is not prevented from connecting and if it does, it takes over the screen.

Uxplay does not assign a unique session id to different clients. (The apple tv does, but this is not implemented in uxplay)

Harvie commented 2 years ago

Thank you, i will try the patch later today.

fduncanh commented 2 years ago

on comparing with what an apple tv does, I think closing the screen (as the patch does) is the correct behavior that uxplay ought to have.

Harvie commented 2 years ago

I think closing the screen (as the patch does) is the correct behavior

Perhaps choice should be left to the user. I can imagine use cases for both.

patch < uxplay_patchv2.txt

So far i can confirm it patches, builds and runs. But i don't own any apple device, which is obviously needed to test this, but in the evening i will be able to borrow it to do some more testing.

Harvie commented 2 years ago

I am looking at doccumentation for video sinks:

https://gstreamer.freedesktop.org/documentation/vaapi/vaapisink.html?gi-language=c

They seem to provide options for "fullscreen", "display-name" and few others. I am not really experienced with gstreamer, but i beleive it can build some "pipeline" based on plaintext string which describes modules, their options and how they are connected together.

So if you can provide way to inject these sink options into that pipeline description string, this would likely allow user to activate fullscreen mode on any display just as originaly requested. eg.:

-vs vaapisink -vsopt "fullscreen=true display-name=VGA1"

or

-vs "vaapisink fullscreen=true display-name=VGA1"

This one might actualy work without modifications, i havent tried yet. that would solve the issue.

Harvie commented 2 years ago

Ok, so i've just tested and it does not allow gstreamer module options to be passed into the pipeline:

$ ./uxplay -vs "vaapisink fullscreen=true display-name=VGA1"
Failed to initialize GStreamer video renderer
using system MAC address f1:ge:f1:31:97:fa
Initialized server socket(s)
GStreamer error: GStreamer error: state change failed and some element failed to post a proper error message with the reason for the failure.
Re-launching server...
Harvie commented 2 years ago

On the other hand, this seems to run ok:

$ ./uxplay -vs "vaapisink fullscreen=true rotation=90"
using system MAC address f1:ge:f1:31:97:fa
Initialized server socket(s)

So perhaps the display-name=VGA1 was the culprit. didn't yet tested with actual phone tho...

Harvie commented 2 years ago

Ok, so i've tried your patch. It does succesfully close window on disconnect. So i can confirm it works nicely.

Also ./uxplay -vs "vaapisink fullscreen=true rotation=90" causes fullscreen and rotation to work as expected. However i still struggle with display-name=VGA1, even tried escaping display-name=\"VGA1\" and display-name='VGA1' without luck. Perhaps we can figure this out.

fduncanh commented 2 years ago

@Harvie

do you actually want rotation=90 (there is a uxplay option -r R for this)

I cant test vaapi without removing an nvidia video card (and messing my local system, which I am reluctant to do). but its great you can get vaapi full screen working.

xvimagesink and ximagesink dont do full screen. The others that work for me are gtksink and glimagesink, or waylandsink. I'll have to see if any of those take a fullscreen parameter.

I'll document your success with vaapisink fullscreen to the README. The changed stop mirroring behavior (with an option -nc for "not close" old behavior will be in v1.45)

fduncanh commented 2 years ago

The changes are now in the github master for the eventual 1.45 release. Please see the entry about fullscreen vaapisink in README Usage for -vs option.

(the macOS build needed the new option -nc for keeping the former no-close behavior because of a gstreamer problem with closing the window.)

Harvie commented 2 years ago

I don't really care about rotation, i was just using it to test if i can specify multiple parameters at once :)

fduncanh commented 2 years ago

@Harvie I verified fullscreen with -vs "waylandsink fullscreen=true" as waylandsink also supports fullscreen mode. Thanks for your discovery of this!

tommiv commented 2 years ago

Just my 5 cents: on some systems (which happens to be my case, Ubuntu 20.04, intel HD video) Gstreamer can blacklist VAAPI features, vaapisink included. You can see this by running

gst-inspect-1.0 vaapi

you'll see 0 features: message in the end.

Also uxplay won't start with -vs "vaapisink" arg.

If this is the case for you too, you have to export this env:

GST_VAAPI_ALL_DRIVERS=1

UPD: however, when I do this, I get a black screen or black video window (if I don't do fullscreen=true). Nothing suspicious in uxplay stdout. Not sure what's going on, I've tried to run a test video from gstreamer with GST_VAAPI_ALL_DRIVERS=1 gst-launch-1.0 videotestsrc ! vaapisink and it works just fine.

fduncanh commented 2 years ago

@tommiv

  1. export GST_DEBUG=2 (and repeat with = 4)

  2. see if restoring "decodebin" in the gstreamer pipeline in renderers/video_renderer_gstreamer.c make a difference, someone got me to change it because of a problem they reported that I could not verify, which they reported was solved by the change, and (with a non-vaapi NVIDIA setup) it didnt break anything for me

Right now the pipeline is

GString *launch = g_string_new("appsrc name=video_source stream-type=0 format=GST_FORMAT_TIME is-live=true !"
                     "queue ! h264parse ! avdec_h264 ! videoconvert ! ")
    append_videoflip(launch, &videoflip[0], &videoflip[1]);
    g_string_append(launch, videosink);
    g_string_append(launch, " name=video_sink sync=false");

the line beginning queue used to be

  "queue ! decodebin ! videoconvert ! ");
tommiv commented 2 years ago

@fduncanh

  1. I did it, 2 doesn't actually show anything, 3/4 overwhelms me with logs but I see nothing criminal there. Probably it's too much to comprehend.
  2. I can confirm restoring the old pipeline with "decodebin" did the trick. I can even see some hardware acceleration happening in intel_gpu_top!
  3. (bonus). I actually switched to wayland session and tried waylandsink. It works well and have fullscreen flag too. I can leave it "as is" if the problem is for me only, so you don't have to resolve pipeline disrepancies between different GPUs.

Thanks for a quick answer!

fduncanh commented 2 years ago

@tommiv Thanks for this! I will restore decodebin and provide an option for the avdec_h264
I should not have accepted a users suggestion for the change at face value without some testing. (I can in fact get intel HD if I remove an nvidia card, but its a bit of a pain to do it)

fduncanh commented 2 years ago

@tommiv

now fixed in master. (uxplay v1.46) default is again decodebin replacing it by h264parse ! avdec_h264 forces software h264 decoding so autovideosink will not select vaapi sink.

The users advocating avdec_h264 as a fix for their problems presumably had non-blacklisted non-working vaapisink installed

I added your remarks on blacklisting of vaapi to the Troubleshooting README.

shungo27 commented 2 years ago

I'm using devilspie2 to maximize automatically.

~/.config/devilspie2/config.lua

if (get_window_name() == "<UxPlay Window Name>") then
    maximize();
end
fduncanh commented 2 years ago

@shungo27

  1. does this work with all the videosink windows (including glimagesink, gtksink, vaapisink) or is it just X11 windows like ximagesink and xvimagesink ? (use uxplay -vs videosink )

2, do you get true fullscreen (or is it the same as clicking the maximize button on the window)?

shungo27 commented 2 years ago
  1. The -vs videosink option failed to start uxplay with an error.
  2. i'm sorry, it is not fullscreen. its just maxmize.
fduncanh commented 2 years ago

I mean -vs \<videosink> where \<videosink> is replaced by one of names of the allowed videosinks listed by man uxplay possible values of \<videosink> are xvimagesink ximagesink glimagesink gtksink vaapisink ....

shungo27 commented 2 years ago

I did the following tests.

$ uxplay -vs "xvimagesink" it's working

$ uxplay -vs "ximagesink" uxplay run ok, but get an error when connect airplay. *** ERROR decryption of video packet failed

$ uxplay -vs "glimagesink" get an error on the ios side and cannot connect.

$ uxplay -vs "gtksink" video_renderer_init: Assertion 'renderer ->sink' failed.

$ uxplay -vs "vaapisink" video_renderer_init: Assertion 'renderer ->sink' failed.

However nothing to do with this issue(Fullscreen mode).

fduncanh commented 2 years ago

Thanks I dont fully understand your results, bu t at least its working for you.