Pi4 forced output resolution: tvservice vs. userconfig.txt


Setting the video mode on the Pi4 works a little bit different than on the older Pi’s and as documented.

I usually set a fixed video output mode for all devices that i deploy because i often have to work with broken screens as well as video mixers that don’t send proper EDID information.
In the past i used to do this using the file /config/tvservice.
Unfortunately this does not work on the Pi4. It briefly works during boot but as soon as the setup is loaded it switches back to automatic detection.
I can manually fix this by ssh-ing into the box and running the tvservice binary (i.e. tvservice -e "CEA 33"). After that i also have to restart the infobeamer binary to fix the OpenGL screen size. Of course this workaround is far from being feasible - especially since the video output resolution is reset whenever a new setup gets assigned to the device.
After some tinkering i found out that it is possible to force the resolution on the Pi4 by writing something like this


to /config/userconfig.txt. So everything is basically fine now but i still have some questions:

  • What’s the preferred way to force the output resolution on the Pi4? The documentation tells me to use /config/tvservice and does not mention /config/userconfig.txt.
  • Are there any drawbacks to use /config/userconfig.txt? I did some testing with a Pi3, a PiZero W and a Pi1. All of which used the correct resolution once i added the above settings to the file.
  • Is it problematic if i just use both /config/tvservice and /config/userconfig.txt? Since i’m using ansible to generate the /config/ directory on the SD cards the extra work to do both is not really an issue.


You’re correct: The hdmi_group and hdmi_mode options are the preferred method on the Pi4. If you use the configuration editor, that’s what is being added to /config/screen-settings.txt (included from /config.txt). Adding the values to /config/userconfig.txt will produce the exact same result and as it’s included later in /config.txt it will overwrite any earlier setting. The only downside is that the setting is then made outside of what the configuration editor can present you in a structured way.

For some reason I seem to have some issues on some Pi4s when trying to force 720p: The initial resolution is set correctly by the firmware but switches back to FullHD once the FKMS linux driver is loaded. Still looking into that one.

/config/tvservice should not be needed in that case.

hm Ok thanks. I will update my ansible role to use /config/screen-setttings.txt then.
I’m guessing this will also work on older Pi’s. Does this mean that i can just delete /config/tvservice file for all devices?
I would very much prefer to not need to distinguish between device hardware types when ansible generates the configuration.

You can delete /config/tvservice. Essentially all it does is call tvservice with those arguments late into the boot process. Setting the value in /config/screen-setttings.txt is better as it’s done earlier than that.

If you’re using ansible: Do you open up SSH then? Or how does that work? I assume you’ve seen the API calls for They also allow you to manage the files within /config.

Ok thanks.

My ansible role does not really connect to the device. All it does is to generate a /config/ directory that contains the configuration for the device to boot up using the correct screen resolution as well as working networking and and the device connect key for my account. Since up until now i only used info-beamer in the context of conferences and festivals i do the live video streaming for there is no need to maintain info-beamer devices that are already deployed in the field. Simply generating a new SD card is totally fine in this case.
I use ansible because most of the other infrastructure that i usually set up is bootstraped using it. This means that stuff like the WIFI password are readily available.

In the future i will probably have some more permanent installations and i will definitely look into the API for this.

Ah. I see. Makes sense and sound like a good solution.

For completeness I might also point to the customize download API call: It allows you to prepare an installation zip (and soon .img disk image file) that already includes configuration files you specify in the call.

Yeah i saw that already. But since i sometimes use a branding.mp4 file it felt quite backwards to upload several megabytes to your API service just to re-download it again as part of the complete install ZIP file. Especially since the task at hand is actually not that complicated once everything is in place.

Hi again,

I did some more testing and can report that most things works now using only /config/screen-setttings.txt. However i was not able to use any interlaced resolutions (i.e. CEA 20 aka 1080i50) on the Pi4. Setting this mode on an older Pi works using only /config/screen-setttings.txt though.
Apperently there are some issues with interlaced video on the Pi4 as can be seen here or here.
Interestingly i am able to manually switch to 1080i50 on the Pi4 by ssh-ing into the device and running tvservice -e "CEA 20". Also, in contrast to what is stated in the Github Issue, once i manually switch to this resolution video playback still works without any problems.

Also i just realized that audio via HDMI does not work on the Pi4… i only get distorted noise. Is this a known issue? Hadn’t had the time to look at this in detail. It might be an issue with the HDMI to SDI converter the Pi is currently plugged into.

I’m pretty sure doing that while the info-beamer process is running messes up internal state somewhere: The firmware part of the video output sets(?) interlaced mode, while the Linux/DRM based side thinks nothing has changed. The option of setting resolution/refresh rate/etc will no longer be available at some point in the future once full (instead of fake) KMS is used to drive all video output. So it’s probably better to not depend on interlacing for now. Or just use a Pi3 :}

HDMI audio should definitely work. If you can reproduce the issue, could you share the asset, so I can try to reproduce the issue locally?

Ok thanks. for now i probably doesn’t matter that i can’t use interlaced modes because the video mixer the Pi4 will be used with can convert that.

As for the audio issue i did some more testing. Apparently audio playback does work with some resolutions but not with others. I did all my tests using two different assets (API ID: 16066, and API ID: 358027). No matter which asset is used i always get the same results.

On the Pi4 i get working Audio if the HDMI output is set to 1080p50, 1080p60 or 2160p30. But i get either no sound at all (on a cheapo TV) or distored noise (only on the left channel and silence on the right channel) on my Atem TV Studio 4k when one of the following resolutions is configured: 720p50, 720p60 or 1080p25.
I couldn’t test 2160p60 because the only two screens i have that support HDMI 2.0 and therefore 4k @ 60fps have no speakers and while the Atem has 12G SDI inputs it has no HDMI inputs. I therefore have to use a HDMI to SDI converter and the only ones i have here do only support 6G SDI - so again this is limited to 2160p30.
All these resolutions (besides 1080p25) have been configured using the device page at the hosted service.

If i do the same tests on a Pi3 i couldn’t find a resolution where the audio didn’t work. I tested with 1080p50, 1080p60, 1080p25, 1080i50, 720p50 and 720p60. These are most likely the only ones i will ever be using…

info-beamer - Digital Signage for the Raspberry Pi community forum - Imprint