<div dir="ltr"><div>First, I want to caveat this with the declaration that I am not a programmer however I do deal with process control as part of my day job as an engineer.</div><div><br></div>I have been running the render branch (now master) for a while and using AVSync2 for audio/video synchronization mostly with LiveTV. In evaluating, I have found the sync algorithm would only provides acceptably stable video performance if I use an AVSync2 timing setting of 1ms. Anything more than this results in jerky video performance along with frequent frame drops on my systems. <div><br></div><div>Investigating by spending some time studying the AVSync2 code and looking in more detail at playback,timestamp logs, I have come to the conclusion that there might be some potential for refinement of the AVSync2 algorithm. </div><div><br></div><div>The current algorithm is much like a proportional control approach with fixed controller gain of 1 (with each adjustment, try to adjust the time sync exactly back to equilibrium) with clamping of the maximum fix_amount limited to the user defined setting of avsync2adjustms. I think the problem with this approach is that a controller gain of 1 seems to be too high and there is also occasionally some noise in the calculated sync measurement. Both of these issues destabilize the AV sync control. With a larger
avsync2adjustms setting, the system never achieves stable control under many conditions with the sync oscillating over / under target. In turn, the calculated "lateness" value tends to also swing around causing more frequent frame drops further upsetting the control.</div><div><br></div><div>In an attempt to improve, I manually modified the AVSync2 algorithm as follows: </div><div>1. A control gain value is declared and included in the fix_amount calculation to allow for a code configured gain value less than 1. In my case, I am currently using a value of 0.4.</div><div>2. A first order exponential smoothing filter is applied to dampen any noise in the sync measurement. A code configured filter coefficient is set to a value between 0 and 1. In my case, I am using 0.9.</div><div><br></div><div>Note that the 0.4 and 0.9 are the result of some limited eyeball tuning and are probably not optimum values.</div><div><br></div><div>After implementing these changes, my frontends seem to behave MUCH better in both achieving sync quickly and achieving more stable long term control of the av sync along with visually improved video smoothness. The modified approach allows the applied fix_amount to be larger initially when there is a big sync offset but avoids excessive overshoot / instability / overcontrol as the sync approaches equilibrium. </div><div><br></div><div>I throw this out there to share and to see if others that have looked at the AVSynce2 code have any thoughts on the approach at least. </div><div><br></div><div>In this scenario, the avsync2adjustms is no longer needed. However, if wanting to have user configurable/tuneable settings, the gain value ( range: 0-1) and the filter coefficient (range: 0-1) could be exposed in the frontend setup menu under AVSync2 rather than hard-coded.</div><div><br></div><div>Excerpted code with modifications shown in mythplayer.cpp AVSync2 function:</div><div>.....</div><div> auto playspeed1000 = static_cast<int64_t>(1000.0F / play_speed);<br> bool reset = false;</div><div> // controller gain<br> float av_control_gain = 0.4;</div><div> // variable to carry forward prior adjustment for smoothing filter calculation<br> float last_fix = 0;</div><div> // filter coefficient for the smoothing filter.<br> float sync_fc = 0.9;<br></div><div>.......</div><div> int sign = audio_adjustment < 0 ? -1 : 1;<br> // Use proportional control with configured gain & add an exponential smoothing filter.<br> float fix_amount = (last_fix * sync_fc + (1 - sync_fc) * audio_adjustment) * sign * av_control_gain;<br> last_fix = fix_amount;<br> </div><div> //disable clamping of adjustment outputs<br> //if (fix_amount > avsync2adjustms)<br> // fix_amount = avsync2adjustms;<br> // Faster catch-up when off by more than 200 ms<br> //if (audio_adjustment * sign > 200)<br> // fix the sync within 15 - 20 frames<br> //fix_amount = audio_adjustment * sign / 15;<br> auto speedup1000 = static_cast<int64_t>(1000 * play_speed);<br> rtcbase -= static_cast<int64_t>(1000000 * fix_amount * sign / speedup1000);<br>......</div><div><br></div><div>-Tim</div></div>