Grasshopper2
Posts: 14
Joined: Sat Feb 20, 2016 11:54 am

Create framebuffer with non-square pixels?

Sat Feb 20, 2016 12:22 pm

Hi,

I'm currently experimenting with the Advance MAME emulator on my Raspberry Pi 2.

Advmame has the ability to program the framebuffer driver to create a custom display mode that has exactly the same resolution as the game being played. And for performance reasons, I'd prefer to do this instead of having the emulator do the scaling itself.

On a regular PC running Linux, the custom display generation works extremely well. However, on my RPi the results have been a bit unpredictable.

After a lot of experimentation, it finally dawned on me that the RPi framebuffer driver always forces the pixels to be square, regardless of the resolution you have selected. So, for example, if the native resolution of the display 1920x1080 and I run "fbset -g 640 480 640 480 32", I'll end up with black bars to the left and right of the text area because 640x480 is not a widescreen resolution.

Most of the time this behaviour is OK. However, there are a few games that don't have square pixels, and they end up with an incorrect aspect ratio when run on the RPi. So ideally, for these games, I'd like to be able create a framebuffer display mode that has non-square pixels. Can someone tell me whether this is possible?

Thanks in advance.

User avatar
experix
Posts: 204
Joined: Mon Nov 10, 2014 7:39 pm
Location: Coquille OR
Contact: Website

Re: Create framebuffer with non-square pixels?

Sat Feb 20, 2016 4:44 pm

I don't know whether framebuffer drivers have any built-in knowledge of non-square pixels. But assuming they do not, consider this: if you make a 1920x1080 pixel screen that is 3 inches by 3 feet, your 1920x1080 framebuffer will happily fill that up and you get a really skinny tall picture with everything stretched out. So to get a reasonable aspect ratio you need to take the physical geometry into account when you write to the framebuffer. For example if you want to display a 1000x1000 pixel picture on that screen, and it is supposed to be a square, you would first transform it. You could map 1000 horizontal picture pixels 1920 horizontal screen pixels, and 1000 vertical picture pixels to 1080*3/(3*12) = 90 vertical screen pixels. This would be done by Fourier transform operations on the original picture and the result would have all the objects of the original, i.e. nothing is cropped out, but the vertical resolution would be greatly reduced and the horizontal resolution would be unchanged although more pixels are used there. When you display that picture it will occupy a 3x3 inch square on the screen.

drgeoff
Posts: 8762
Joined: Wed Jan 25, 2012 6:39 pm

Re: Create framebuffer with non-square pixels?

Sat Feb 20, 2016 6:06 pm

experix wrote:This would be done by Fourier transform operations on the original picture...
Maybe you would use Fourier Transforms but the rest of the world, including myself, has been using Finite Impulse Response digital filters for decades.

User avatar
experix
Posts: 204
Joined: Mon Nov 10, 2014 7:39 pm
Location: Coquille OR
Contact: Website

Re: Create framebuffer with non-square pixels?

Mon Feb 22, 2016 8:08 pm

Thanks for the tip, drgeoff. I'll try doing that. Could be quite a bit faster, but maybe not as easy to get a bunch of different results out of one picture. (I can FT the picture, manipulate that various ways and inverse-FT those to get different filters, sizes, etc.) I looked up some articles on FIR and they did not mention image processing, but I can see how it would be done.

drgeoff
Posts: 8762
Joined: Wed Jan 25, 2012 6:39 pm

Re: Create framebuffer with non-square pixels?

Tue Feb 23, 2016 10:48 am

You might find more if you include 'interpolation' and 'TV standards conversion' in the search terms.

When upsampling one is always trying to generate new pixel values at positions between input samples.

When downsampling there should be some attempt at a low pass filter to reflect the lower sampling rate and reduce aliasing. Then, unless the input rate is an integer multiple of the output rate, there will again be a need to produce interpolated values. In practice both operations are performed simultaneously in one FIR filter.

Usually horizontal and vertical resamplings are performed in series with two 1-D filters rather than one 2-D filter.

The number of taps in the filter is a tradeoff. When I was doing this in real-time video hardware in the 1980s I never had more than 5 taps and the tap weights were quantised to 1/16 steps. Current hardware/software implementations can probably permit much greater filter accuracy.

The theory is exactly the same for audio resampling but much better filters are required to get an acceptable level of audible artifacts. However audio sample rates being so much lower than video ones helps.

Grasshopper2
Posts: 14
Joined: Sat Feb 20, 2016 11:54 am

Re: Create framebuffer with non-square pixels?

Sat Feb 27, 2016 4:00 pm

Thanks for the replies.

However, I think you guys might be misunderstanding what I'm trying to achieve. Advance MAME is a program that emulates old arcade games, mostly from the eighties and nineties. Most arcade games from that era had a much lower resolution than modern TVs and computer monitors. Therefore, the games generally have to be scaled up to fit on a modern display. This can either by done by Advance MAME itself (i.e. in software), or Advance MAME can program the framebuffer to create a custom display mode that exactly matches the resolution of the original game. The latter is generally considered to be the preferred option as it means that more processor power is freed up for other aspects of the emulation. It's a bit crazy to use the CPU for scaling when there's a perfectly good GPU available to do the same thing.

A traditional framebuffer driver on a PC version of Linux can create custom display modes by setting the pixel clock, vertical sync, horizonal sync timings, etc. However, it appears that on the Raspberry Pi, those parameters are set in config.txt and cannot easily be changed after the RPi has been booted. Instead, custom display modes are created purely by using GPU scaling. That would be OK except that the GPU driver always forces pixels to be square, and some games don't have square pixels.

This is probably best illustrated by an example. One game that causes problems is Ghouls 'n Ghosts. This game was originally played on an arcade monitor with a 4:3 aspect ratio. However, its resolution is 384x224. This means that each individual pixel has a 7:9 aspect ratio (i.e. (4*224)/(384*3)).

I'm using a wide screen 16:9 aspect ratio monitor with a resolution of 1920*1080. So, to determine what display resolution I need to use, I perform the following calculation:

Yres = 224

Xres = 384*(3*16)/(4*9) = 512

That should, in theory, give me a resolution that's big enough to display the game, and with each individual pixel having a 7:9 aspect ratio. My calculation assumes that the usable display area completely fills the screen. The trouble is, it doesn't. The display driver realises that the pixels won't be square, and compensates by creating big margins at the top and bottom of the screen.

This is very frustrating. There must surely be a simple setting somewhere to change this behaviour. However, despite a lot of googling, I'm not finding it.

User avatar
antiriad
Posts: 129
Joined: Sun Nov 17, 2013 7:38 pm
Location: Italy
Contact: Twitter

Re: Create framebuffer with non-square pixels?

Fri Nov 04, 2016 6:20 am

Hi, did you find a solution?
Thanks

Grasshopper2
Posts: 14
Joined: Sat Feb 20, 2016 11:54 am

Re: Create framebuffer with non-square pixels?

Sun Nov 06, 2016 5:56 pm

antiriad wrote:Hi, did you find a solution?
Thanks
Hi,

I've been too busy to do anything with my RPi for several months so my information might not be up to date.

But to answer your question, yes, there is indeed a solution. However, it's a bit of a hack.

All you need to do is add the following line to your config.txt file:

sdtv_aspect=1

I can confirm that it works. However, according to one of the developers, this behaviour is technically regarded as a bug. So, in theory, it could be 'fixed' in a future update of the RPi's firmware. I've asked the developer whether this option can be put on a more permanent footing.

Further details can be found at the following link:

https://github.com/raspberrypi/firmware/issues/638

User avatar
antiriad
Posts: 129
Joined: Sun Nov 17, 2013 7:38 pm
Location: Italy
Contact: Twitter

Re: Create framebuffer with non-square pixels?

Sun Nov 06, 2016 8:17 pm

Thank you very much for you kind feedback.
May I ask if you are using a CRT monitor?

Return to “Advanced users”