Mailing List Archive

Audio Video Sync on v31 and Alsa Buffer Size
Hello fellow mythtv users.

I have noticed several recurring posts regarding issues with Audio-to-Video
synchronization (or lip sync) that people are experiencing after moving to
mythtv v31. A significant change under the hood in this area is that
mythtv now uses the presentation timestamp information (which nearly all
modern video transports include) to keep these two streams synchronized.

In the synchronization approach in v31, the audio timestamp information
serves as the baseline and the exact moment of presentation of the
accompanying video frame is adjusted a little early or a little late to
always try to drive perfect synchronization. If things get too far out of
sync, the system will either drop frames of video to catch up in a larger
increments or it will rebaseline against the latest audio & video
timestamps and resume synchronizing.

One key element in this process is consistent audiotimestamp data and if
the audio playback alsa buffer is not configured to be large enough, then
quality of synchronization can suffer. If this type of message appears in
your log file:

audio/audiooutputalsa.cpp:236 (IncPreallocBufferSize) ALSA: Try to manually
increase audio buffer with: echo 128 | sudo tee
/proc/asound/card0/pcm3p/sub0/prealloc

then you really should try to increase the value of the alsa buffer as
instructed. Consequently, the amount of alsa buffer required / requested
will differ depending on the number of playback channels in stream (e.g.
stereo source vs 5.1 vs 7.1).

I have noticed this exact msg/error appearing in several logs that have
been posted in trac tickets or forums related to av sync complaints.

As an example, I was experiencing significant sync jitter on a low end
Intel machine (Celeron N3350) using VAAPI when viewing 1080i 29.97fps
source material with deinterlacing. The system would regularly drop frames
and this made video playback not as smooth as I would like. When looking at
verbose playback, timestamp logs, I found this variability was driven by
variation in the audiotimestamp results. At the time, I had the same alsa
buffer message in the mythfrontend log that I never bothered to properly
address thinking it unimportant since i didn't hear any artifacts /
dropouts in audio playback. After fixing the alsa buffer, the timestamp
variability and associated sync jitter essentially disappeared.

See data here collected during LiveTV playback that demonstrates this: The
y-axis scales are the same on these two plots and dip around 1550 frames on
the second plot is a channel change.

Before adjusting prealloc
Audioadjust results with /proc/asound/card0/pcm3p/sub0/prealloc value of 64
<https://imgur.com/DXQ6cQF>

After adjusting prealloc
Audioadjust results with /proc/asound/card0/pcm3p/sub0/prealloc value of 128
<https://imgur.com/1tEgS3s>

Even on my more powerful frontend using NVDEC on a GT1030 card, I found
similar jitter existed if the alsa buffer was not set properly.

Unfortunately, adjustment of the alsa buffer is not persistent and must be
done upon each restart of the system. To work around this, I use a systemd
oneshot service to run a script to set the alsa buffer value upon boot.

To summarize, if experiencing occasional but recurring frame drops, you
might want to confirm you are using the recommended alsa buffer value. For
me personally, v31 playback using VAAPI on a low end intel machine is silky
smooth and better than anything I achieved on prior mythtv versions.
Re: Audio Video Sync on v31 and Alsa Buffer Size [ In reply to ]
On Wed, 3 Jun 2020 11:32:26 -0400, you wrote:

>Hello fellow mythtv users.
>
>I have noticed several recurring posts regarding issues with Audio-to-Video
>synchronization (or lip sync) that people are experiencing after moving to
>mythtv v31. A significant change under the hood in this area is that
>mythtv now uses the presentation timestamp information (which nearly all
>modern video transports include) to keep these two streams synchronized.
>
>In the synchronization approach in v31, the audio timestamp information
>serves as the baseline and the exact moment of presentation of the
>accompanying video frame is adjusted a little early or a little late to
>always try to drive perfect synchronization. If things get too far out of
>sync, the system will either drop frames of video to catch up in a larger
>increments or it will rebaseline against the latest audio & video
>timestamps and resume synchronizing.
>
>One key element in this process is consistent audiotimestamp data and if
>the audio playback alsa buffer is not configured to be large enough, then
>quality of synchronization can suffer. If this type of message appears in
>your log file:
>
>audio/audiooutputalsa.cpp:236 (IncPreallocBufferSize) ALSA: Try to manually
>increase audio buffer with: echo 128 | sudo tee
>/proc/asound/card0/pcm3p/sub0/prealloc
>
>then you really should try to increase the value of the alsa buffer as
>instructed. Consequently, the amount of alsa buffer required / requested
>will differ depending on the number of playback channels in stream (e.g.
>stereo source vs 5.1 vs 7.1).
>
>I have noticed this exact msg/error appearing in several logs that have
>been posted in trac tickets or forums related to av sync complaints.
>
>As an example, I was experiencing significant sync jitter on a low end
>Intel machine (Celeron N3350) using VAAPI when viewing 1080i 29.97fps
>source material with deinterlacing. The system would regularly drop frames
>and this made video playback not as smooth as I would like. When looking at
>verbose playback, timestamp logs, I found this variability was driven by
>variation in the audiotimestamp results. At the time, I had the same alsa
>buffer message in the mythfrontend log that I never bothered to properly
>address thinking it unimportant since i didn't hear any artifacts /
>dropouts in audio playback. After fixing the alsa buffer, the timestamp
>variability and associated sync jitter essentially disappeared.
>
>See data here collected during LiveTV playback that demonstrates this: The
>y-axis scales are the same on these two plots and dip around 1550 frames on
>the second plot is a channel change.
>
>Before adjusting prealloc
>Audioadjust results with /proc/asound/card0/pcm3p/sub0/prealloc value of 64
><https://imgur.com/DXQ6cQF>
>
>After adjusting prealloc
>Audioadjust results with /proc/asound/card0/pcm3p/sub0/prealloc value of 128
><https://imgur.com/1tEgS3s>
>
>Even on my more powerful frontend using NVDEC on a GT1030 card, I found
>similar jitter existed if the alsa buffer was not set properly.
>
>Unfortunately, adjustment of the alsa buffer is not persistent and must be
>done upon each restart of the system. To work around this, I use a systemd
>oneshot service to run a script to set the alsa buffer value upon boot.
>
>To summarize, if experiencing occasional but recurring frame drops, you
>might want to confirm you are using the recommended alsa buffer value. For
>me personally, v31 playback using VAAPI on a low end intel machine is silky
>smooth and better than anything I achieved on prior mythtv versions.

I have a script for fixing this that I currently run at boot from
rc.local on Ubuntu 18.04. It parses the correct values for the device
name and the buffer size from mythfrontend.log. It is self modifying
so that it remembers the last settings when the correct values are not
available in mythfrontend.log. I have it available for download from
my web server:

http://www.jsw.gen.nz/mythtv/audio_prealloc.sh

Now that I think about it, the script could just be run on the
PLAY_STARTED event, and have the script delay for a second or two to
allow mythfrontend to log the message with the prealloc value in it,
then do the fix. I would have to convert it to work as an sudoers
helper script, so that it would run as root from the event. If I find
time tomorrow I will have a look at doing that.
_______________________________________________
mythtv-users mailing list
mythtv-users@mythtv.org
http://lists.mythtv.org/mailman/listinfo/mythtv-users
http://wiki.mythtv.org/Mailing_List_etiquette
MythTV Forums: https://forum.mythtv.org
Re: Audio Video Sync on v31 and Alsa Buffer Size [ In reply to ]
On Thu, 04 Jun 2020 05:17:07 +1200, you wrote:

>
>http://www.jsw.gen.nz/mythtv/audio_prealloc.sh
>

I mis-typed the file name. Try this:

http://www.jsw.gen.nz/mythtv/audio-prealloc.sh
_______________________________________________
mythtv-users mailing list
mythtv-users@mythtv.org
http://lists.mythtv.org/mailman/listinfo/mythtv-users
http://wiki.mythtv.org/Mailing_List_etiquette
MythTV Forums: https://forum.mythtv.org
Re: Audio Video Sync on v31 and Alsa Buffer Size [ In reply to ]
On Thu, 04 Jun 2020 05:19:24 +1200, you wrote:

It looks like this problem is a bit more complicated than I thought.
While MythTV is playing a file, even root is unable to change the
prealloc buffer setting. So if you run my audio-prealloc.sh file from
the LiveTVStarted or PlayStarted events, mythfrontend has already got
the audio device open and the setting does not get changed. If you
pause playback, the audio device remains under mythfrontend's control
and the prealloc buffer setting still can not be changed. So the best
fix I can come up with is to run audio-prealloc.sh at boot and then
from the LiveTVStopped and PlayStopped events. That means that if you
get symptoms of the buffer being too small during playback, such as
some sorts of juddering, if you stop and restart playback, the audio
prealloc buffer setting will have been fixed and it should work on the
second try.

During testing this, I have also noticed that the setting that
mythfrontend recommends changes depending on what recording you are
playing. For my main MythTV system, I have seen values from 168 to
32768 (the maximum possible value) recommended. So having the setting
correct for one recording does not necessarily fix it for a subsequent
recording which might want a larger value. So I am now wondering if
it would not be best to just set the audio prealloc to 32768 and leave
it at that. Does anyone know if there are any bad consequences from
setting the prealloc that high?

To further complicate things, if you change the audio device that
MythTV is using (say you plug in a TV with audio over HDMI and you
switch to using that, instead of the motherboard audio device(s)),
then the prealloc will need to be set for the new device.

To run audio-prealloc.sh at boot and from the *Stopped events, the
following commands should work on Ubuntu. If you do not already have
these files installed, the rm commands will cause error messages -
just ignore them. If you already have some of the files, they will be
removed and the new versions installed. The new versions are
compatible with the old versions - they just have support for
audio-prealloc.sh added.

sudo su
cd /etc/sudoers.d
rm mythtv-systemctl-helper
wget http://www.jsw.gen.nz/mythtv/mythtv-systemctl-helper
chown root:root mythtv-systemctl-helper
chmod u,g=r mythtv-systemctl-helper
cd /usr/local/bin
rm mythtv-systemctl-helper.sh
wget http://www.jsw.gen.nz/mythtv/mythtv-systemctl-helper.sh
chown root:mythtv
chmod ug=rx,o= mythtv-systemctl-helper.sh
rm audio-prealloc.sh
wget http://www.jsw.gen.nz/mythtv/audio-prealloc.sh
chown root:root audio-prealloc.sh
chmod ug=rwx,o=r audio-prealloc.sh
cd /etc/systemd/system
rm audio-prealloc.service
wget http://www.jsw.gen.nz/mythtv/audio-prealloc.service
chown root:root audio-prealloc.service
chmod u=rw,go=r audio-prealloc.service
systemctl enable audio-prealloc.service
systemctl start audio-prealloc.service

Then you have to set up the events in mythfrontend:

Setup > System Event Handlers > Live TV ended
Setup > System Event Handlers > Playback stopped

For each of those events, set the command to be:

sudo systemctl start audio-prealloc

If (like me) you are already using those events, you will need to
create a script file run from each event which does the "sudo
systemctl start audio-prealloc" command and also whatever else you
want to happen on that event.

To see what the audio-prealloc service has done, look at its journal:

sudo journalctl -eu audio-prealloc

If there are any error messages they should show up there, and you
will be able to see when the service was run. If you want to manually
run audio-prealloc, start it with systemctl:

sudo systemctl start audio-prealloc
_______________________________________________
mythtv-users mailing list
mythtv-users@mythtv.org
http://lists.mythtv.org/mailman/listinfo/mythtv-users
http://wiki.mythtv.org/Mailing_List_etiquette
MythTV Forums: https://forum.mythtv.org
Re: Audio Video Sync on v31 and Alsa Buffer Size [ In reply to ]
On Sun, 7 Jun 2020 11:55:30 +0100, you wrote:

>On 07/06/2020 11:23, Stephen Worthington wrote:
>> On Thu, 04 Jun 2020 05:19:24 +1200, you wrote:
>>
>(snip)
>>
>> To further complicate things, if you change the audio device that
>> MythTV is using (say you plug in a TV with audio over HDMI and you
>> switch to using that, instead of the motherboard audio device(s)),
>> then the prealloc will need to be set for the new device.
>>
>If this is true then it seems to me that the surest way of doing what is required would be with one
>or more udev rules. That would apply the needed correction as root and at exactly the right times.

Unfortunately that does not work. It was tried many years ago when
this problem first cropped up. It seems (yet to be confirmed) that
when mythfrontend is using the audio device, not even root can change
the prealloc value. Udev rules may be able to give mythfrontend the
ability to write to the prealloc setting, but mythfrontend also may
well not be able to write to the prealloc setting even then if it has
the audio device already open, which seems to be what is happening. So
if someone would like to try altering mythfrontend to close the audio
device and then try setting the prealloc value itself, before
reopening the audio device, that might work with the correct udev
permissions settings. Or with mythfrontend running an external helper
file that has sudo permissions.

There would still be the problem of finding all the audio prealloc
settings devices and writing a udev rule for each one to allow mythtv
group to have access. And, of course, these days there are plug-in
USB audio devices (eg DACs of many sorts) which can be plugged in at
any time. There would also need to be a udev rule created for them if
they were used. I am not sure if it would be possible to create a
generic udev rule that would allow access to any audio prealloc
settings device.
_______________________________________________
mythtv-users mailing list
mythtv-users@mythtv.org
http://lists.mythtv.org/mailman/listinfo/mythtv-users
http://wiki.mythtv.org/Mailing_List_etiquette
MythTV Forums: https://forum.mythtv.org
Re: Audio Video Sync on v31 and Alsa Buffer Size [ In reply to ]
Hi Stephen,

Thank you for working on this and sharing your script. I have also
concluded this is not an easy problem to address in an automated fashion.

7.1 channel TrueHD source material requires 1536 KB alsa buffer to hold 500
ms so I don't think there should be too much need to set it to a higher
value than this. I also question why so many ALSA drivers use such small
default values here if there is no drawback to setting it higher. One
other complicating factor is that not all ALSA drivers allow for values as
high as even 1536 as the prealloc_max value can differ. For example, RPi 3
that I just checked has a prealloc_max value of 128 KB. I suppose any
requested value in a script should probably be sanity checked against the
prealloc_max limit and warn the user if it can't be set to an optimal value.

Searching on this topic seems to suggest prealloc tuning is somewhat unique
to MythTV and most other media software doesn't require this. Speculating
here but it seems as if either the frequency of the loop draining the alsa
buffer in Mythtv is limiting or there is some other way to set the required
DMA buffer within an application. Unfortunately, I don't have the skillset
to efficiently dig into this too far and could very well be totally off
base in why alsa buffer optimization is more critical for MythTV.