Log in

View Full Version : Quality difference/"texture shift" on I-frames (x264)


Zero1
15th February 2009, 11:21
Hey guys
I'm having a slight problem with a video I am trying to encode.

The source is a lossless screen capture of Street Fighter 3 - 3rd Strike. It was captured in RGB and then fed to x264 in YV12 via AVISynth. The original capture is pixel perfect and is at the games native resolution. For those of you not familiar with Street Fighter, it features a more or less static background that pans while the 2 sprites move around.

The problem that I am coming across is that some frames look inconsistant, almost like the texture has shifted or changed, where in the source the images are identical. Here is a little example encoded with the default x264 settings except I specified -q 18. As you can see, all frames are pretty consistant, except for when the I-frame was inserted. You should be able to open these in tabs and see the difference by switching, although it would be easier if you zoom. It is most noticable in the detail on the hut above the characters heads, or on the tree.

http://xs136.xs.to/xs136/09070/1436228.png
http://xs136.xs.to/xs136/09070/1437427.png
http://xs136.xs.to/xs136/09070/1438400.png
http://xs136.xs.to/xs136/09070/1439965.png

The first thing you might notice as well as the change happening on the I-frame, is that the I-frame has a different quantizer, so to try and make it a fair test, I set --ipratio 1.0. As you can see, it didn't help much, and probably made the overall quality lower.

http://xs536.xs.to/xs536/09070/1436ip424.png
http://xs536.xs.to/xs536/09070/1437ip652.png
http://xs536.xs.to/xs536/09070/1438ip528.png
http://xs536.xs.to/xs536/09070/1439ip459.png

After digging a little more, I notice that I get the same problem with an I-frame at frame 1688 and again at 1938, which is of course 250 frames more than the previous. Obviously what is happening is that the scene is not changing enough to warrant a scene change and instead is inserting an I-frame at the maximum GOP size specified in the encoding settings (which 250 is the default). In my tests, I ended up setting the maximum GOP size to a frame count higher than the number of frames in the source and the result was that it was a little more consistant with I-frames being placed at what would be considered real scene changes.

Although setting a huge GOP size seemed to work, I feel as though it may be a suboptimal solution. I'm also concerned about the quality gradually decreasing with the lack of I-frames. Seeing how the P-frame directly after the I-frame was very similar, but the P-frame before the I-frame wasn't as similar, could this be in part due to accumulated errors through motion compensation etc, or is it just the nature of P-frames that they will decrease in quality and an I-frame is needed every so often to "freshen" things up?

So for now, I'm just wondering if anyone can anyone offer any pointers. Would some simpler settings actually work better, or is setting a large GOP the only way round this? Also, if a large GOP is the only way round this, would there be any use for an option in x264 for some kind of intelligent GOP size, or an auto maximum? I'm sure this issue won't affect most people, but it might crop up in other types of capture (eg GUI screen caps or anime/CG).

Thanks for your time guys. If you need any samples uploading or options testing just let me know. Fortunately since it is low res, testing is not too bad :)

Sagittaire
15th February 2009, 14:37
Quality flick with noscene change Iframe in static scene is well know problem for all codec. Solution are:
- improve Pframe ratio before noscene change Iframe
- impose Bframe before noscene change Iframe PbBbIbBbP (open gop)
- Reduce Iframe ratio for noscene change Iframe

Guest
15th February 2009, 15:28
Using two passes improved things a lot for me.

Dark Shikari
15th February 2009, 21:20
except I specified -q 18.Turning off AQ is bad. Use CRF, not "-q".

Also, this is an inherent problem of intra prediction. There are potential solutions, albeit ugly ones.

Zero1
16th February 2009, 09:46
Turning off AQ is bad. Use CRF, not "-q".

Also, this is an inherent problem of intra prediction. There are potential solutions, albeit ugly ones.
Thanks, I'll give it a go.

I was thinking of another way round this. Would it work if you was able to implement some code or metric that compares the quality of the following frames to the last I-frame? I'm thinking if the similarity of the following frames falls below a user specified percentage compared to the last I-frame, that it would then insert a new I-frame to prevent the quality falling even more. This in theory would be inserting new I-frames before the quality of the P/B-frames falls so much that inserting a new I-frame is noticable.

Since the quality of the I-frame and P/B-frames could be set pretty close, it might mean that the effect is reduced.

Does that sound plausible or something that would be worthwhile implementing? I imagine it would be a bit of a slow process for a small gain, so maybe if it was of interest, it could be something like --keyint auto.

Dark Shikari
16th February 2009, 09:56
Thanks, I'll give it a go.

I was thinking of another way round this. Would it work if you was able to implement some code or metric that compares the quality of the following frames to the last I-frame? I'm thinking if the similarity of the following frames falls below a user specified percentage compared to the last I-frame, that it would then insert a new I-frame to prevent the quality falling even more. This in theory would be inserting new I-frames before the quality of the P/B-frames falls so much that inserting a new I-frame is noticable.

Since the quality of the I-frame and P/B-frames could be set pretty close, it might mean that the effect is reduced.

Does that sound plausible or something that would be worthwhile implementing? I imagine it would be a bit of a slow process for a small gain, so maybe if it was of interest, it could be something like --keyint auto.That is a bad idea and would not solve the problem, merely make it occur more often. The correct solution is to encode all non-scenecut I-frames as P-frames and then encode them again as I-frames with respect to the P-frame instead of with respect to the source.

"Inserting an I-frame" is not a valid method of "preventing quality from falling more" anyways; a low-quant P-frame would be much more efficient. Of course that would cause the exact same "quality flash" that an I-frame would.