Log in

View Full Version : RGB32 converted to YV12 jitter


tin3tin
9th April 2008, 14:15
I've been using FFrend(great software BTW.) to generate freeframe filters to be processed through avisynth in order to make some nice slow endless motion backgrounds for DVD slideshow GUI.

Unfortunately the conversion between RGB(which FreeFrame needs) and YV12 for DVD output results in jitter in the soft moving gradients.

I've tried to fix this through the various matrixes but noting solved the problem.

Here's a zip (http://download.videohelp.com/tin2tin/RGB_YV12_Problem.zip) with the files(run the .avs in Media Player Classic or something like that - its changing endless though MPC loops the timeslider). And here's my script:

# Endless Motion Background - RGB32 -> YV12 color jitter problem
# For use as motion background in DVD slideshow GUI - Tin2tin
LoadPlugin("freeframe.dll")
Imagesource("Californication.jpg",0,0)# A nice color combination from Adobe Kuler
BlackmanResize(720,int(last.height()/40))#Downsize for realtime playback
loop(600)
converttorgb32()
freeframe("BackColorLines.dll",false)
#converttoYV12()#Uncomment this to see the color jitter
LanczosResize(720,576)


How can I solve this?

IanB
9th April 2008, 22:14
Resize the result first then convert it to YV12. i.e....
freeframe("BackColorLines.dll",false)
LanczosResize(720,576)
converttoYV12()
Also you can make a minor speed up by loading you image directly as RGB32 by adding ImageSource(... , PixelType="RGB32")

tin3tin
10th April 2008, 07:47
Thanks IanB. Unfortunately it still jitters here. Though it's a bit crazy(converting back and forth), I think it is possible to see the jitter in top of the lower part, when it fades up from black to light blue, if you exchange this with the last part of the script:
a=last.converttorgb32().LanczosResize(720,200)
b=last.converttoYV12().converttorgb32().LanczosResize(720,200)
stackvertical(a,b)

scharfis_brain
10th April 2008, 07:59
don't know what you mean with jitter here.

but YV12 only has a quarter of the colour resolution compared to RGB.
this means FOUR (2x2) Greyscale pixels are sharing only ONE colour information (hue, saturation).
This either causes colour stairstepping (mostly on red/blue) or blurring.

tin3tin
10th April 2008, 08:29
@ scharfis_brain
I know, but is there anything you would suggest I could do to minimize the jitter/staircase flicker?

AVIL
10th April 2008, 10:47
Hi,

In Soulhunter's site there is a plugin called YV12toRGB24HQ wich claims:

YV12 to RGB24 with dithering!

After that a converttorgb32 is inexpensive.

Get it at:

http://soulhunter.chronocrossdev.com/data/yv12torgb24hq.zip

Good luck

tin3tin
10th April 2008, 11:07
@ AVIL Thanks I didn't know about that one. Unfortunately it's the other way which causes the problem. The RGB32 FreeFrame plugin turns the image into a slow moving abstract video with a lot of soft, changing gradients and it is the conversion from this to YV12(with less colors) which causes the problem.

If only YV12toRGB24 could do RGB24toYV12 :)

IanB
11th April 2008, 07:07
@tin3tin,

Perhaps you had better explain the effect more completely.

Jitter is normally describing temporal anomalies, where smooth motion stutters unexpectadly.

Another term is flicker, where image components rapidly alternate position.

And just a thought is the problem a result of interlacing with a progressive YV12 conversion.

Does your encoder accept YUY2 input?

tin3tin
11th April 2008, 08:37
I'm sorry english isn't my first language and avisynish isn't either. :)
Due to my lacking language abilities I've included the example files in a zip, so people could take a look themselves. You know pictures speaks louder that words. :)

DSG uses HCenc, avs2avi and ffmpeg for export.

J_Darnley
11th April 2008, 11:56
I've looked at the files you have provided and I only notice a bit of stutter in the opening fade of black -> blue. The only way to correct this would be to do a fade yourself, with FadeIn(). Then later I can see some stronger banding than in the RGB version. This can be hidden with gradfun2db.

2Bdecided
11th April 2008, 13:03
You've got two issues: reduced colour resolution, and several stages of re-quantisation.

The reduced colour resolution shouldn't be an issue, unless your player upscales the chroma without softening/filtering it in the process.

The re-quantisation is killing it. Firstly, there's some quantisation within your function itself: what comes out isn't perfectly smooth gradients, even in the RGB version.

Secondly, you convert RGB to YV12 - that scales 0-255 > 16-235, which will cause banding on smooth gradients because at some points on the scale pairs of adjacent values will be quantised to the same value - your smooth gradient get a step in it! Spatially, you see this is a line; temporally (where something is fading in or out) you see this as a jump in brightness; with complex fading effects, you can see flicker. I _think_ the combination of all of this is what you mean by "jitter".

Thirdly, your player / graphics card must convert YV12 back to RGB for display, expanding the 16-235 range back to 0-255, now leaving "holes" in the luma range - values which no pixel has - which again cause steps in smooth gradients, with all the above effects.

I've used the appropriate AVIsynth commands to avoid all of this (I went RGB > YV12 > RGB within AVIsynth using matrix="PC.601" all the way), and it still doesn't look right to me. I must have made a mistake somewhere.

However, if the output must be YV12, then unless you can stop your playing scaling during the conversation back to RGB32 (look for a 16-235/0-255 option), you can't avoid the last step, so can't avoid the problem!

Hope this helps.

Cheers,
David.

foxyshadis
12th April 2008, 01:25
2B, you have part of the problem identified, the other part of the problem is that YUV and RGB are not losslessly convertible: In the darkest and lightest regions, YUV has much lower color resolution (many RGB values map to the same YUV) ranging to medium brightness where YUV actually has higher chroma resolution. PC conversion will give you only a little extra boost, you might lose a band.

Dithering (debanding) or a dithered RGB->YUV conversion is the only way to hide this. 8-bit YUV and RGB both just suck for smooth gradients (especially on 6- and 7-bit monitors!).

IanB
12th April 2008, 08:06
@tin3tin,

Your principle problem is your freeframe/BackColorLines plugin is not frame number stable, i.e. it does not return an identical frame each time a given frame number is requested. It seems to return the next image in its internal sequence no matter what frame number you request. The mpeg encoder does not ask for frames in strict linear order, so the visual effect gets upset. You can abuse ChangeFPS as a linear access filter, with a big Cache to try an ride over this issue.SetMemoryMax=256 # Biggish Cache
...
ChangeFPS(Last, True) # Abuse as a force linear access filter
2nd problem is the effect output is not Nyquist compliant, and the visual effect exploits this. If you look very carefully there is a stutter present in both the RGB and YV12, it is just no where near as obvious in RGB. A simple Blur mitigates this effect quite markedly.

tin3tin
12th April 2008, 12:20
@ IanB Using the "abuse" lets the converttoYV12(matrix="PC.601") have an effect. I think this is a positive effect on the stutter however I need to add something like: tweak(sat=0.9,bright=9,cont=0.9) to get color resemblance. There are still some horisontal blocks, but with a blur it seem to get better.

:thanks:

IanB
12th April 2008, 14:18
@tin3tin,

You really need to get your plugin fixed, the linear access trick is not guarranteed to work, it is just an aid to demonstrate this fault. All Avisynth filters must return exactly the same frame data for a given frame number every time it is called.

There is no point in using a PC.601 matrix together with Tweak values that effectivly change it back to Rec601, you will still get the banding due to range crushing.

The Blur is a rough approximation to a low pass filter, if you want a truely smooth result you will need to accurately filter the RGB data to ensure there is no aliasing when converting to a YUV420 format like YV12.

tin3tin
12th April 2008, 15:04
The plugin is made as a meta-Freeframe plugin with http://ffrend.sourceforge.net/. I don't know anything about whats happening "inside" the plugin or how to change the non-frame-specific behaviour. It seems like all FF filters loaded with the avisynth FreeFrame loader plugin has this behaviour.

I've made several meta-filters (flash video here (http://download.videohelp.com/tin2tin/AllBack.html) and here (http://download.videohelp.com/tin2tin/After.html) with Ffrend and used them as backgrounds, I guess the vertical lines and the effect of this meta-plugin provoked a more visible stutter in the resulting video. So this specific idear for making diffent backgrounds with of vertical lines just seem like a bad idear then... :)

I don't know anything about the actual coding of the plugins, just how to use them. :rolleyes:

tin3tin
12th April 2008, 15:05
The plugin is made as a meta-Freeframe plugin with http://ffrend.sourceforge.net/. I don't know anything about whats happening "inside" the plugin or how to change the non-frame-specific behaviour. It seems like all FF filters loaded with the avisynth FreeFrame loader plugin has this behaviour.

I've made several meta-filters (flash video here (http://download.videohelp.com/tin2tin/AllBack.html) and here (http://download.videohelp.com/tin2tin/After.html)) with Ffrend and used them as backgrounds, I guess the vertical lines and the effect of this meta-plugin provoked a more visible stutter in the resulting video. So this specific idear for making diffent backgrounds with of vertical lines just seem like a bad idear then... :)

I don't know anything about the actual coding of the plugins, just how to use them. :rolleyes:

IanB
13th April 2008, 05:41
If you cannot get the plugin fixed and the linear access trick is not reliable then you may have to prerender the effect to a intermediate format for which the encoder does request the frames in strictly linear order, i.e. VirtualDub using Huffyuv.