View Full Version : Making FRAPS video from FFMS2 match AviSource?


AlekseiV
17th November 2010, 22:09
FRAPS video is usually YV12. Their VFW codec stores it as YV12, but decodes it to RGB.
FFVideoSource decodes it to fullrange YV12. The problem is that it doesn't look the same as what AVISource (FRAPS) decodes.

Example:
FRAPS clip, AVISource (http://img525.imageshack.us/img525/849/frapsavisource.jpg)
FRAPS clip, FFVideoSource (http://img576.imageshack.us/img576/2891/frapsffvideosource.jpg)
I also included histograms of the levels.

How do I round/shrink FFMS' levels so that they match the levels of AVISource?

poisondeathray
17th November 2010, 22:18
you can try:

smoothlevels(preset="pc2tv")


you may have to adjust the settings a bit to make it match, and maybe colormatrix as well (I can't tell , because it's RGB screenshot and it's not clear what you did to take the screenshot (how you converted to RGB))

smoothlevels(preset="pc2tv", chroma=100)
colormatrix(mode="rec.709->rec.601" , clamp=0)


FRAPS has a RGB mode as well, RGB Lossless , so it depends what version you are using

Dark Shikari
17th November 2010, 22:28
AVIsource is wrong, FFMS is correct. AVIsource is converting the PC-level FRAPS source to TV-level.

AlekseiV
17th November 2010, 22:28
It is closer but unfortunately still noticeably different:
FRAPS, FFVideoSource.smoothlevels(preset="pc2tv") (http://img155.imageshack.us/img155/959/frapsffmssmoothlevels.jpg)

edit: hold on, testing something

poisondeathray
17th November 2010, 22:34
Note: It depends HOW you are taking screenshots , because the YUV data is converted to RGB for the screenshot (or display)

ie. If you converted to RGB using pc vs. tv levels, what matrix (BT 709 vs. 601 etc..)

If you use Lossless FRAPS, there is no confusion, because RGB is decoded as RGB, no levels issues

AlekseiV
17th November 2010, 22:45
Using Lossless RGB mode in FRAPS makes FRAPS even slower due to the higher bitrate, and the quality difference is not noticeable.

AVISource is not wrong. Example:
Screenshot (taken using built-in screenshot utility; a SS from FRAPS looks identical) (http://img812.imageshack.us/img812/8666/screenshot7n.jpg)
AVISource, still image from video clip recorded at same approx time (http://img293.imageshack.us/img293/892/avisource.jpg)
FFVideoSource, same as above (http://img228.imageshack.us/img228/6902/ffvideosource.jpg)

The screenshot and AVISource are nearly identical; FFVideoSource looks utterly different. Unless the game's screenshot utility is converting PC levels to TV levels, AVISource is correct.

I am taking screenshots from the videos using AvsPmod's "Save Image". They are PNG which I then convert to JPG with 4:4:4 chroma.

Dark Shikari
17th November 2010, 22:47
Stop willy-nilly converting your screenshots around without considering luma levels! Converting to JPEG can change the levels! Converting to RGB also can change the levels! Going through a video renderer and saving a screenshot (e.g. using AvsPmod's Save Image) can change the levels!

My original statement was just based on your original graphs. Those graphs demonstrate that the data being used to create the graphs shows that AVIsource must be wrong. It's quite possible, of course, that the image is being mangled on the way to creating the graphs, and that AVISource is in fact correct.

For example, here's what might be happening:

AVISource: Original -> (PC->TV conversion) -> Create Graph -> (PC->TV conversion)
FFMS2: Original -> Create Graph -> (PC->TV conversion)

poisondeathray
17th November 2010, 22:48
I am taking screenshots from the videos using AvsPmod's "Save Image".

But when you save image , it uses rec.601 conversion (ie. you are converting the yuv data to rgb using rec.601 - you're not VIEWING the YUV data as YUV)

Try this:

ffvideosource()
converttorgb(matrix="pc.709")

and then examine the screenshot

AlekseiV
17th November 2010, 22:55
The images I am using are correct.
Seriously, I was just in the game comparing how the game looks while I'm playing it to how FFVideoSource looks, and FFVideoSource looks wrong. But see below.

But when you save image , it uses rec.601 conversion (ie. you are converting the yuv data to rgb using rec.601 - you're not VIEWING the YUV data as YUV)

Try this:

ffvideosource()
converttorgb(matrix="pc.709")

and then examine the screenshot


Perfect, this solves the thread title.
FFVideoSource(file)
ConvertToRGB(matrix="pc.709")
ConvertToYV12()
Also it turns out using x264 --fullrange on will make the video decode properly in MPC-HC, but I don't know whether it works properly on the various video site backends. Also, this is easier to recommend than setting fullrange on.

poisondeathray
17th November 2010, 22:58
LOL, don't just convert to RGB then back to YV12 - each conversion is LOSSY . Look at the red borders, they will get blurrier from each colorspace conversion. That example was just to show the proper RGB conversion for taking screenshots (AVSP assumes REC.601 for the RGB conversion otherwise)

You should use the suggestion above, this way you have 1 less colorspace conversion

smoothlevels(preset="pc2tv", chroma=100)
colormatrix(mode="rec.709->rec.601", clamp=0)

Essentially what you are doing is scaling 0-255 to 16-235 Y' then converting to REC.601 - this is not ideal, but a workaround for decoders that expect a TV range video (In avisynth, when you use ConvertToYV12() it means ConvertToYV12(matrix="rec.601") )

FRAPS is supposed to be full range, and decoded full range (converted to RGB full range) - When you compress Y' from 0-255 to 16-235 you get induce quantization (banding) ie. lower quality because there is fewer "steps" to express values

Dark Shikari
17th November 2010, 23:02
Also it turns out using x264 --fullrange on will make the video decode properly in MPC-HC, but I don't know whether it works properly on the various video site backends. Also, this is easier to recommend than setting fullrange on.Then this makes it obvious what's going on.

What you WERE doing:

AVIsource: Input -> PC->TV Conversion -> Encode -> Decode -> TV->PC conversion -> Display (Correct, but wasteful and hurts quality)

FFMS2: Input -> Encode -> Decode -> TV->PC conversion -> Display (WROOOOOOOONG)

What you are now doing:

FFMS2: Input -> Encode -> Decode -> Display (Optimal!)

Now, what we probably should do is make x264 automatically trigger --fullrange if it knows that the input is fullrange. I'll yell at TheFluff to do this. Thanks for the bug report.

AlekseiV
17th November 2010, 23:21
LOL, don't just convert to RGB then back to YV12 - each conversion is LOSSY . Look at the red borders, they will get blurrier from each colorspace conversion. That example was just to show the proper RGB conversion for taking screenshots (AVSP assumes REC.601 for the RGB conversion otherwise)

You should use the suggestion above, this way you have 1 less colorspace conversion

smoothlevels(preset="pc2tv", chroma=100)
colormatrix(mode="rec.709->rec.601", clamp=0)I cannot see a difference in quality between the YV12->RGB->YV12 method and the proper SmoothLevels.ColorMatrix method. I know it exists (and Subtract can show it), but I can't see it, even flipping back and forth between them in comparison. But I can notice a difference in speed; SmoothLevels.ColorMatrix halves my playback speed. Encode speed is only ~15% slower, but it still hurts.



Autosetting of fullrange would be really useful, thanks!

poisondeathray
17th November 2010, 23:21
^ yes ideally that's what you would do (do everything fullrange) . The problem is decoders and displays might not expect fullrange video or accept VUI information in the h.264 stream, and it will end up looking like the 1st ffvideosource screenshot .

That screenshot is 0-255 YUV data improperly converted to RGB 16-235 using Rec.601 (because he used AVSP to take screenshots without ConvertToRGB(matrix="PC.709") . Using ConvertToRGB(matrix="PC.709") emulates what the YUV data should look like when a decoder/display correctly decodes the fullrange video

Scaling it to "TV" levels is the (dumb) workaround for now, but it ensures consistency on every device and display

poisondeathray
17th November 2010, 23:28
I cannot see a difference in quality between the YV12->RGB->YV12 method and the proper SmoothLevels.ColorMatrix method. I know it exists (and Subtract can show it), but I can't see it, even flipping back and forth between them in comparison. But I can notice a difference in speed; SmoothLevels.ColorMatrix halves my playback speed. Encode speed is only ~15% slower, but it still hurts.



It's up to you, but colorspace conversion are lossy

You can use levels or coloryuv, instead of smoothlevels and it should be faster

coloryuv(levels="PC->TV")

But smoothlevels does more than just change the levels, it dithers (have a look at the encoded YV12 video in a dark gradient area like shadows, you should see more banding in the video adjusted by levels or coloryuv, but it may or may not be noticable )

dansrfe
17th November 2010, 23:28
Then this makes it obvious what's going on.

What you WERE doing:

AVIsource: Input -> PC->TV Conversion -> Encode -> Decode -> TV->PC conversion -> Display (Correct, but wasteful and hurts quality)

FFMS2: Input -> Encode -> Decode -> TV->PC conversion -> Display (WROOOOOOOONG)

What you are now doing:

FFMS2: Input -> Encode -> Decode -> Display (Optimal!)

Now, what we probably should do is make x264 automatically trigger --fullrange if it knows that the input is fullrange. I'll yell at TheFluff to do this. Thanks for the bug report.

bingo :)

poisondeathray
17th November 2010, 23:34
I cannot see a difference in quality between the YV12->RGB->YV12 method and the proper SmoothLevels.ColorMatrix method.

Have a look more closely, it's most noticable around red colors

You don't see the blurring ?

http://www.mediafire.com/?t279cf2oa6akg5o

AlekseiV
18th November 2010, 00:04
I can see the blurring in your sample, yes. I couldn't see it in mine (even looking at an area Subtract marked out).
I don't know if the quality difference is particularly noticeable after the video has gone through YouTube's encode process.

poisondeathray
18th November 2010, 00:16
Again, it's up to you , and (more) blurry might be better for compression since Youtube brutalizes everything

Youtube converts to RGB for display using Rec.709 (even SD video which should be Rec.601) regardless of flags or format uploaded, so you have to scale to TV levels anyways if it's for Youtube - fullrange isn't an option here