-
-
Notifications
You must be signed in to change notification settings - Fork 517
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Android: When the hardware/default decoder fails to initialize, fall back to software. #1933
Android: When the hardware/default decoder fails to initialize, fall back to software. #1933
Conversation
Update: Have managed to get a build pair working to test on master and worn it to get an idea of the characteristics (and also, you know, test the PR). On my device, ALVR (with the baseline profile PR)+PhoneVR (master with ALVR swapped for this commit) appears to eagerly predict the head rotation, possibly too far. Alone this results in a "snapback effect" on the desktop VR view, but then some sort of glitchy stutter turns this into a very weird sensation, sort of like as if the last few frames were being repeated. I don't know what causes this effect. My current suspicion is that the client can't keep up and reacts poorly, but I'm not sure; too much involved. Further research required. I'm not strictly sure if the baseline profile PR is or is not necessary. It seems uncertain. In some configurations things definitely weren't working at all (often complete grey blanking of screen) and with other settings they were fine. It might help to reduce the load on the decoder, if nothing else. |
decoder.start().unwrap(); | ||
|
||
let preparing_decoder = if config.force_software_decoder { | ||
decoder_try_software(sw_codec_name, &format, &image_reader).unwrap() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of unwrapping you can pass the error upstream.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code is within a thread. I'm not sure where it'd go. I am cleaning up to reduce the amount of unwrapping, but there still will be "an unwrap". In addition, trying to de-unwrapify the code results in loss of which specific call failed, which could be bad for debugging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could use the function alvr_common::show_err()
to print the error. The error per se might not be interesting, but otherwise the unwrap() will crash the thread silently, which is worse.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done as of 97eff12
"Attempting software fallback due to error in default decoder: {}", | ||
e | ||
); | ||
decoder_try_software(sw_codec_name, &format, &image_reader).unwrap() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
alvr/client_core/src/decoder.rs
Outdated
// TODO: Actually get the real values for these and update accordingly. | ||
// These are inherited from the previous code to avoid breaking anything. | ||
// Would also be nice if force_software_decoder was configurable. | ||
width: 512, | ||
height: 1024, | ||
force_software_decoder: false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you checked it really matters? Video resolution is extracted from SPS/PPS (CSD-0).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know that it, for certain, really matters. In my testing it does not aid my particular case. But given that this whole thing started because of codec breakage, I feel there is merit to setting these properties correctly. If they didn't somehow matter, why even set them in the first place?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current code was translated as faithfully as possible from ancient java code. We are not in touch with the original author. I think this was used to mitigate some decoder implementation edge cases.
Since we are not changing the values at all, I think we should not add the width an height fields in DecoderInitConfig
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done as of 97eff12
alvr/session/src/settings.rs
Outdated
#[schema(strings( | ||
help = "Attempts to use a software decoder on the device. Slow, but may work around broken codecs." | ||
))] | ||
pub force_software_decoder: bool, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this just above mediacodec_extra_options
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done as of d9a8731.
alvr/client_core/src/decoder.rs
Outdated
// TODO: Actually get the real values for these and update accordingly. | ||
// These are inherited from the previous code to avoid breaking anything. | ||
// Would also be nice if force_software_decoder was configurable. | ||
width: 512, | ||
height: 1024, | ||
force_software_decoder: false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current code was translated as faithfully as possible from ancient java code. We are not in touch with the original author. I think this was used to mitigate some decoder implementation edge cases.
Since we are not changing the values at all, I think we should not add the width an height fields in DecoderInitConfig
…hould be more explicit
… Logging: cargo fmt --all
alvr/common/src/logging.rs
Outdated
pub fn show_err<T, E: Display>(res: Result<T, E>) -> Option<T> { | ||
res.map_err(|e| show_e_block(e, false)).ok() | ||
res.map_err(|e| show_e_block(format!("{:#}", e), false)) | ||
.ok() | ||
} | ||
|
||
pub fn show_err_blocking<T, E: Display>(res: Result<T, E>) -> Option<T> { | ||
res.map_err(|e| show_e_block(e, true)).ok() | ||
res.map_err(|e| show_e_block(format!("{:#}", e), true)).ok() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you changing this code? I'm surprised it even compiles. {:#}
is valid for E: Debug
but the type bound is not specified. In practice, try not to depend on Debug, rather depend on Display.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, an explanation of what happened here:
While testing the "no unwrap" changes, I found that I wasn't getting the "inner error" (i.e. the ErrorUnknown
from the media error), just the context. Now, to me, this is very bad (because it makes it harder to debug codec error reports from users/etc).
However, I couldn't get the error details out of it without either duplicating the inner error details in the context or going through this. I'll change things to duplicate the inner error details in the context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remember you can get help from anyhow to format the error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Turns out that wasn't necessary. Not sure what I missed the first time; doesn't matter in any case.
d3645fe undoes this.
decoder.stop().unwrap(); | ||
drop(decoder); | ||
} else { | ||
show_err(preparing_decoder); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't try to print the whole object. Rather, if you handle both Ok and Err cases, prefer using match instead of if-let, then print only the error in the Err branch.
Thanks. There are more styling nits i would point out but I guess it's fine for now. |
Ok, so, things to do? should I squish these all into one commit? Etc. |
I'd like to get some more testers before merging |
I will say, in my testing - and I get this with a hardware decoder on another device also - I seem to have this problem where ALVR-in-PhoneVR flashes between the last two frames a lot. |
Tested this. I just release built with this pr and ran ALVR, works fine. Any specific test methodology/procedure to test this pr ? |
Try force software, make sure it works. If you have a device which you know decoder init fails on reliably, it is good to test with that too; it should work (with high latency). Keep in mind that you can recursive-clone PhoneVR, change directly to this commit (not merge), and get deps setup, or even symlink PhoneVR's ALVR directory to your ALVR repo. EDIT: Visual side-effects due to high latency are out of scope for this PR, but having a way to consistently trigger them should be productive to allow other developers to provide insight. |
Dont have a device that fails, but everything else is working normally. |
I'll merge within a day if noone has more objections :) |
To be clear, this commit was only tested (and I only have the hardware to test it) with PhoneVR.
That version is https://github.com/20kdc/ALVR/tree/changeling-buffet-pt-2-phonevr-edition .
This code first attempts to use the hardware decoder as usual, and failing that, attempts the software decoder. These software decoder names are "well known" names. As far as I'm aware they're not strictly API-defined, but the alternative is API functions which are way too new to be usable to determine software-ness.
Since this functionality only triggers when the previous code would panic, it shouldn't make anything worse.
To be actually effective, this PR might need constrained baseline encoding. See #1932
Possible things of future research: