-
Notifications
You must be signed in to change notification settings - Fork 257
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
Allow to choose between old and new speed limiter from ricrpi #115
Conversation
{ | ||
l_MainSpeedLimit = enable ? 1 : 0; | ||
l_MainSpeedLimit = value; |
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.
Is this function really usefull?
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.
Not really, I'll remove it.
I don't really like this because it introduces complexity rather than properly solving the problem. What is the (qualitative/quantitative) performance difference between the Old and New speed limiters in Android? What is it about the new speed limiter mechanism which causes an issue in Android? It would be better to improve the new algorithm so that it performs well in all operating systems, rather than choosing one or the other. |
@richard42 I agree that I took the easy way here. Using the new framelimiter on android causes non linear framerate (eg: framerate beeing to high for a few ms). I was not able to reproduce this issue on PC, so I actually don't know what is causing this issue on Android. |
@Gillou68310 @richard42 One theory I have is that the averaging window is too large. @Gillou68310 could you try changing the following lines in the new (current) framelimiter, and posting back?
|
Thanks @littleguy77 I lowered the array size to 2 and the framerate is now completely stable. @richard42 what is your opinion on how to deal with this issue? |
The framelimiter is a bit screwey, but I guess it's to keep it all in int math. It still has its precision limits because of the array though, but then again I've studied it for minutes instead of hours. Have there been any thoughts about a direct deviance-tracking design, or is the whole floating point part a dealbreaker for certain users? |
Lowering the array size to 2 will almost completely remove the moving average feature of the framelimiter. I think it's helpful for diagnosis but practically speaking I'd say use a larger value like 8, or eliminate the moving-average algorithm altogether. I noticed on my 2012 Nexus 7 in DK64 intro, if I set the value to 8, the video seemed a bit more choppy in some places. The lower the array size the choppier the video gets. Basically it's a balancing act between desyncing the audio/video vs. maintaining visual smoothness. Lower array sizes keep tighter sync but reduce smoothness, and vice versa. |
I just noticed that ThisFrameDelta is calculated with the CurrentFPSTime whose timestamp reading is from https://github.com/mupen64plus/mupen64plus-core/blob/master/src/main/main.c#L764 and the LastFPSTime whose reading is from https://github.com/mupen64plus/mupen64plus-core/blob/master/src/main/main.c#L780. There are branches between the cracks of these timing reads, which can make the OS scheduler take over for a millisecond and say "screw you". Basically, the LastFPSTime is lower than it should be in those cases, because it doesn't count the time that those branches took. |
@wareya |
My bad, I read the code wrong. I was confused by the variables being reused for different things. It should already function correctly. |
Are you using the SDL audio plugin in Android, or have you written your own? I ask because this plugin also has a speed limiter which inserts delays based upon the buffer levels at the time when new audio data is fed in from the running ROM. |
@richard42 I made some new tests with the dummy audio plugin and the problem is even more noticeable, so I don't think this is related to the audio plugin speed limiter. BTW I just wrote a new audio plugin using OpenSLES, but till now we were using the SDL plugin ;-) @littleguy77 could you check if this is the same for you, I based all my tests on ZeldaOOT US |
Ok, I have done a fair amount of thinking about this. I actually quite like the current speed limiter code, but it does have one big flaw which is that it doesn't communicate with the audio plugin. The reason for the history array is to stay in sync with the audio plugin, but it is open loop due to the lack of communication. And the fact that the audio plugin has it's own speed limiter is also a problem, because they can potentially fight each other. A proper fix for this requires higher-level design changes. It would be wasted work to do this if we are going to redesign the system API anyway, remove the audio plugin, and add audio functionality to the front-end. I propose that we fix this after bsmiles32 does the system-level audio refactoring work. I think the way that this ought to work is that when the audio is disabled (or paused for sync) this function should wait if necessary to to consume exactly the amount of time given by the AdjustedLimit. But if the audio is running, then this function should wait as necessary in order to cause the resampled audio buffer level ("secondary" buffer) to converge on its target level. The details are somewhat tricky because this buffer gets fed by callbacks from the running emulator, and drained by callbacks from the audio output (SDL), and these callbacks don't always come at regular intervals. But there's definitely room for improvement here. Another possible approach, which may be better, is to implement this speed limiter without regard to the audio buffer level, but only inserting delays as necessary to maintain the correct output frame rate (AdjustedLimit). And then feeding forward the actual frame rate to the audio system, which would then dynamically slow down audio as necessary to match the output video frame rate and maintain its target buffer fullness. I implemented this type of mechanism (called Varispeed in the movie industry) in a video player about a year ago. It may also be the best option for us here. |
Random thought: If the emulator speed limiter treated the audio's own speed limiter as part of simulation time, would the timing jitter of each limiter fight the other's? That might be where the need for framerate smoothing comes from. |
Yes, I think in some cases there could be conflict between the 2 speed limiters, and really there should only be one. |
@Gillou68310 I definitely see more instability in framerate when using dummy audio, but without audio, I'm not really sure what the correct behavior should be. @richard42 I have no issue with you delaying the proposed changes until after bsmiles32 refactoring is further along. I personally don't notice the jitter with the audio-sdl, but then again I am not very sensitive to it compared to a lot of users. |
@richard42 thanks for taking time to think about this, these are awesome ideas. @bsmiles32 just updated is audio refactoring branch so I'll take a look at his work and see how we can send the current framerate to the audio system. Before closing this PR I'd like to make a reference of it in @bsmiles32's PR so we can keep trace of this discussion. What it the process to make a reference in git? |
Where can I find this updated branch? |
Ah, I missed the console end of it :) |
New speed limiter from ricrpi doesn't perform very well on android.