I'm pretty sure the lossless part of the compression and the DCT are working fine now, but there is still a problem with the color space transformation. I found the cause of the problem, but I'm not sure how to deal with it. Maybe someone here has a good idea for a solution.
This is what my current test image looks like. It's a different frame, because it's better suited to explain what happens.
View attachment 5752
We can see a lot off-color pixels around the edges of the letters. I will explain how this happens for the vertical yellow strip left of the letter "E". The original (y,cb,cr) values for these pixels are (121,0,0). These values are than encoded with the quantization and DCT. Because this process is lossy our decoded values have errors. The stronger the compression the higher the errors. In this case I used the compression level 10 and the decoded values are (120,-8,-1). On first glance these errors seem reasonable and not particularly high. Since these are signed 8 bit integers an error of 8 equals about to 3%. The game then uses this equation to calculate the RGB values:
g = (y+124)+cb+cr = 235
b = (y+124) - 2*cb = 260
r = (y+124) - 2*cr = 246
Now here comes the problem. While doing this calculation the game doesn't bother to check for under- or overflows. Thus the blue value overflows to 4 and we get a strong yellow tint. This is a simple problem that is not so simple to solve, especially when we keep in mind that the game throws out every second data point of the cb and cr channel during subsampling. I can't really predict the errors that the DCT introduces without actually decoding the video. This means in order to correct overflow situations I would have to effectively do two passes of the encoding. Another solution would be to try to introduce some head and foot room into the calculations by offsetting the luma channel. This would impact the image details in bright and dark spots though and certainly wouldn't fix overflows caused by the subsampling.
So does anyone here know a better solution than two encoding passes?