AMF
AMF copied to clipboard
[Bug]: Full / Limited RGB range issues on 9070XT with HW AMF HEVC encoder in OBS
I'm having recording issues with my new 9070XT. I know the AMF hw encoder / decoder has been upgraded on the new GPUs, so this could very well be an issue with the drivers, although I'm not entirely sure. I already made an issue in the OBS repo, but thought I would also make one here, just to get as much input as possible. (https://github.com/obsproject/obs-studio/issues/11945) This issue will mostly be a copy of that issue.
I'm using Windows 11, latest drivers 25.3.1, and latest OBS 31.0.2.
The Limited RGB range option is darker on 9070XT than on an NVIDIA GPU. The color range does say Limited in MediaInfo, but you can still see that video is darker than what it should be.
9070XT on the left, RTX3070 on the right with the same advanced settings (BT709, Limited, NV12, the source window was set to sRGB). My monitor was set to Full range in both scenarios. The videos play correctly in MPC-HC, but in an editing software like Premiere Pro, the difference is there.
The NVENC encoder has much more params exposed, so I tried setting AMF parameters such as profile, color depth, color profile etc:
AMF_VIDEO_ENCODER_HEVC_PROFILE=AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN
AMF_VIDEO_ENCODER_HEVC_PROFILE_LEVEL=AMF_LEVEL_6_2
AMF_VIDEO_ENCODER_HEVC_COLOR_BIT_DEPTH=AMF_COLOR_BIT_DEPTH_8
AMF_VIDEO_ENCODER_HEVC_OUTPUT_COLOR_PROFILE=AMF_VIDEO_CONVERTER_COLOR_PROFILE_709
AMF_VIDEO_ENCODER_HEVC_NOMINAL_RANGE=AMF_VIDEO_ENCODER_HEVC_NOMINAL_RANGE_STUDIO
but it did not help.
Just to see if the OBS RGB Range setting has any effect on the encode, I set it to Full -- the video gets even darker.
Full Range setting
Limited Range setting
Limited Range on RTX3070
OBS log: https://obsproject.com/logs/RE2ssWnP9ZrtmLW8
Thanks in advance.
To save some time could you please share clips from RX 9070 and RTX: full and nominal range?
To save some time could you please share clips from RX 9070 and RTX: full and nominal range?
Yes, I can't upload them here though.
9070XT: https://drive.google.com/drive/folders/1-aJNtijuGzatfWgPsXjQyL-oSot72I38?usp=sharing 3070 Limited: https://drive.google.com/file/d/1nrNNl2SAaWx20FC-OVF1X0lMjiugOfL5/view?usp=sharing (sorry this one is a bit longer.)
The 9070XT videos have been recorded with the Simple mode in OBS. No additional encoder params have been set. The 3070 was with NVENC HEVC, main profile.
Unfortunately I dont have access to my RTX anymore.
Several thoughts:
- In OBS range parameter is processed by OBS color converter. It does not depend on encoder.
- All AMF parameters you mentioned (except range) are used only if color conversion is done inside AMF and this is not the case.
- The encoder gets the same surface of NV12 format from the converter. And range in video stream is just a bool flag in SPS->VUI header. We see that the flag is written correctly.
- Looking into videos you provided I cannot tell much difference. I tried to compare them in a tool, but the content is not identical.
- I see that in video with full range, bright areas are closer to white and dark areas are closer to black. This is expected.
- Comparing ranges with Nvidia is not reliable because you use DLSS and FSR that may give different results.
- If you want test range objectively, you will need the same YUV source file transcoded using FFmpeg or AMF TranscodeHW sample with full and limited ranges.
- Comparing ranges with Nvidia is not reliable because you use DLSS and FSR that may give different results.
Uploaded 2 more videos on the first link, please check. TAA versions of both.
9070XT
3070
EDIT: whoops the end of the 9070XT file is broken. But you can compare them in the beginning so it's fine.
Also, I was in the middle of making a TAA vs DLSS vs FSR4 video when I noticed just how much darker the recordings are from my 9070XT.
OK, I assume that 2025-03-09 19-28-51_TAA.mp4 is RTX 3070 and 2025-03-11 21-43-17_TAA_9070XT.mp4 is AMD's. We kind of deviated from the question of correct range support to comparison of GPU encoders. Different HW encoders have different algorithms and features and cannot produce identical results. I see the differences in the latest pair of video files but they are related to bit distribution by encoders. For example, NV file bitrate is 350Mbits. and AMD's 100Mbit. But even if you reach the same bitrate, the result will not be identical.
Yep, thats right, the earlier file is the RTX card. And that is interesting, so is this like, "expected" behaviour? But you do also see that it's darker, right? This reminds me of the PS3 vs X360 days -- in most scenarios, the X360 always looked more contrasty and darker.
The Limited RGB range option is darker on 9070XT than on an NVIDIA GPU. The color range does say Limited in MediaInfo, but you can still see that video is darker than what it should be.
And how is it in actual gameplay? Limited option means that video uses 16-235 range, not 0-255 But it doesn't mean that source was like this.
So if you encode 0-255 into 16-235, there may be two different behaviours.
- Eliminating 0-16 and 235-255 ranges, distorting colors that used these ranges.
- Converting 0-255 into 16-235 to preserve as much of a color as possible.
So... Maybe Nvidia and AMD process these situations in different way? Or maybe even something else is processing this conversion? I believe to do similar thing in player you need intermediate shader.
Correct me if i am wrong.
Playing the game I'm not noticing anything different in color on my monitor. I also don't have any of those Radeon driver features enabled that alter the color on the monitor, like dynamic contrast or vivid color.
The only difference is in my recordings, as seen above. In Windows I have HDR disabled, as well as auto-HDR. The monitor uses 10bit color with full range, the exact same settings I had on my RTX GPU.
Playing the video produces normal colors, not overdarkened like when opening them in Premiere Pro. The RTX recording looks as is in both scenarios.
But yes, maybe it's somehow related to the conversion from full -> limited, and 10bit -> 8bit. That's why I had that idea to pass some more AMF parameters. When I get home I'll put my monitor into Limited mode and 8bit, and try recording that way.
The only difference is in my recordings, as seen above. In Windows I have HDR disabled, as well as auto-HDR. The monitor uses 10bit color with full range, the exact same settings I had on my RTX GPU.
Well, that may be something...
HDR compatibility is nasty deep rabbit hole.
So it may be related to HDR.
I don't really know how well native 10 bit --> 8 bit conversion works. But i know that you shouldn't do 8 bit -> 10 bit and 10 bit -> 8 bit on reencodes if possible for the time being. Unless you use external color conversion or something.
Again, correct me if i am wrong.
I'm not, I intend to record in 8bit. Which again, why I wanted to force the encoder to use main instead of main10, but it made no difference. (It probably already defaults to 8bit)
Also... Why did you use BT.709 profile with HDR? Shouldn't you have tried BT.2020?
I'm not in HDR. Please read my previous comments again, HDR is off, Auto-HDR also off.
Ah, sorry, misread your message. Hmm...
AMD support for 10 bit is weaker than for 8-bit (For example preanalysis, which we all waiting with passion). General encode should be fine, though, and you will hardly need such features for that... And your monitor uses 10-bit as well. So there should not be such conversion happening. But... As your monitor is 10-bit, maybe something specific to 10-bit sources is happening?
Had you tried to encode with ReLive (aka recorder built-in Adrenalin, same as Shadowplay)? Just for raw comparison? . . .
And i just understood that it is dumb, because it will encode as 8-bit...
But, that gives a thought... Does same behaviour happens if you encode as 10-bit? Or only for 8-bit? (edited order)
Anyways, i don't think i will be much more helpful there. Just wanted to ask few more questions for additional information.
...
Edit: Dang, could not read properly for some reason. You clearly stated it before:
AMF_VIDEO_ENCODER_HEVC_COLOR_BIT_DEPTH=AMF_COLOR_BIT_DEPTH_8
Well, 10->8 bit conversion can be factor that impacts result. Then, instead, correcting my question. How 10 bit encode will behave?
I think I am encoding as 8bit though -- actually I will try to encode it with main10 (so 10bit HEVC) Once I get home I'll post the results.
Yep, thats right, the earlier file is the RTX card. And that is interesting, so is this like, "expected" behaviour? But you do also see that it's darker, right? This reminds me of the PS3 vs X360 days -- in most scenarios, the X360 always looked more contrasty and darker.
Yes, I see it darker. But cannot say that this is a bug.
So I tried setting the params, but it doesnt seem to recognise them:
17:44:40.262: [texture-amf-h265: 'advanced_video_recording'] Failed to set property 'AMF_VIDEO_ENCODER_HEVC_PROFILE': AMF_INVALID_ARG
17:44:40.262: [texture-amf-h265: 'advanced_video_recording'] settings:
17:44:40.262: rate_control: CBR
17:44:40.262: bitrate: 100000
17:44:40.262: cqp: 20
17:44:40.262: keyint: 120
17:44:40.262: preset: quality
17:44:40.262: profile: high
17:44:40.262: width: 3440
17:44:40.262: height: 1440
17:44:40.262: params: AMF_VIDEO_ENCODER_HEVC_PROFILE=AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN_10
17:44:40.262: AMF_VIDEO_ENCODER_HEVC_PROFILE_LEVEL=AMF_LEVEL_6_2
17:44:40.262: AMF_VIDEO_ENCODER_HEVC_COLOR_BIT_DEPTH=AMF_COLOR_BIT_DEPTH_10
What am I doing wrong?
AMF_VIDEO_ENCODER_HEVC_PROFILE=AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN_10
AMF_VIDEO_ENCODER_HEVC_PROFILE_LEVEL=AMF_LEVEL_6_2
AMF_VIDEO_ENCODER_HEVC_COLOR_BIT_DEPTH=AMF_COLOR_BIT_DEPTH_10
My video is still 8bit.
EDIT: Im dumb. I also need to set it to 10bit in Advanced OBS setting duh. But I still dont understand why arent my params recognized? Aaaand yep video is just as dark as before. But it is still using HEVC main and not main10 profile. I need to figure out why my params are not being applied.
Does OBS even accept AMD options in AMF ENUM format? I thought it uses FFmpeg formatting...
Aka, it should be like this:
-profile main10 -level 6.2
Aaand i think you either will need to add pix_fmt p010le, or set Advanced>Video>Color Format>P010
Unless it actually understands direct AMF enums? And i finally fell into rabbit hole.
What arguments does it even take? I saw a lot of people using arguments this way profile=main10 level=6.2 with many of them not actually being something that ffmpeg shows in helper, so how do you need to format them in the end? Where is that sweet OBS documentation?
...
I know for a fact that this: set Advanced>Video>Color Format>P010 works, i just tried this method and it indeed sets profile to Main10
But why this -profile main10 -level 6.2 does not work?
It throws this error:
19:58:18.569: [texture-amf-h265: 'advanced_video_recording'] Invalid value for profile: main10
19:58:18.569: [texture-amf-h265: 'advanced_video_recording'] Failed to set property 'HevcProfileLevel': AMF_INVALID_ARG
Maybe something with ffmpeg version OBS uses?
Inside AMF string values for enums are case-sensitive similar to parameter strings themselves. Use "Main10". FFmpeg converts strings to integers before passing to AMF.
Inside AMF string values for enums are case-sensitive similar to parameter strings themselves. Use "Main10". FFmpeg converts strings to integers before passing to AMF.
Thanks, now it indeed does not error out on this argument -profile Main10 -level 6.2. Will keep in mind for the future.
But it still ignored Main10 in spectacular way. Aka it still encoded in Main profile.
Maybe it is because of forced NV12 pixel format in Advanced settings? But then... Iirc ffmpeg can be broken to encode NV12 on Main10 profile (even if it is wrong).
But it is still using HEVC main and not main10 profile. I need to figure out why my params are not being applied.
@kotn3l Go to Settings>Advanced>Video>Color Format and set it to P010 This should enforce 10 bit and Main10 as result.
Yes, in OBS input is YUV so you need to configure it to 10-bit for 10-bit stream.
@kotn3l Go to Settings>Advanced>Video>Color Format and set it to P010 This should enforce 10 bit and Main10 as result.
I did that and my video was still main only and not main10... but anyway, lets see the params.
Thanks, now it indeed does not error out on this argument
-profile Main10 -level 6.2. Will keep in mind for the future.
This works, video is now Main10. Video is still dark however...
I went back to NV12, and tried some more params like -color_range tv -colorspace bt709 -color_primaries bt709 -color_trc bt709, didnt make a difference. (Before this I was under the impression you had to use AMF params directly instead of ffmpeg ones)
Upon some googling I found this param: -vf scale=in_range=full:out_range=limited but I can't seem to input it in a way so that it recognises it.
I went back to NV12, and tried some more params like -color_range tv -colorspace bt709 -color_primaries bt709 -color_trc bt709, didnt make a difference. (Before this I was under the impression you had to use AMF params directly instead of ffmpeg ones)
By default not really, unless you do 10-bit encode, as it defaults to BT.2020.
Upon some googling I found this param: -vf scale=in_range=full:out_range=limited but I can't seem to input it in a way so that it recognises it.
I believe it is not AMF parameter... It is definitely ffmpeg, though. It supposed to be short for -filter:v
And probably you won't be able to make this work, because of this... https://obsproject.com/forum/threads/how-to-use-the-ffmpeg-video-filter.146702/
OBS Studio doesn't include ffmpeg filters. It uses its output module for encoding only.
Unless they changed something in last 3+ years?
Also... May there be some weird plugin? They seem to sometimes emulate filters?
Hmm. I have another silly idea. I'm gonna render out my comparison video, just to see if it's still darker in the end after reencoding (along with the 3070 footage). If there's no difference tbh I can live with the footage being darker in the editor lol. BUT still weird.
EDIT: welp it's visible reencoded :(
8bit vs 10bit is unlikely to cause such a noticeable difference visually, it will only cause color banding.
It is recommended that you add a comparison item, that is, a software encoder (x264 or x265) as a reference. Whichever hardware encoder outputs colors more similar to the software encoder output, it is correct.
@kotn3l Open this color.html file in your web browser and fullscreen it with F11. Make a video of it with each, NVenc and AMF and upload it somewhere for us to look at. Use CQP 20 for both. The patterns will show us which of the two encoders is incorrect
One of two possible outcomes should occur:
- crushing blacks/whites
- washout into grey
One of two possible outcomes should occur: May occur. There are also color conversion distortions and direct color distortions, (like W/B balance) aren't they?
I am not him, but here is RDNA4 capture. ReLive and OBS.
See that ReLive has slightly greenish tint compared to OBS. Example of color distortion.
[But unlike OBS, ReLive is much sharper, UPD: OBS was set to 3840x2160 plane and my monitor is 1920x1080, oops. Hence sharpness difference]
But other than that, even with VBR (You cannot capture CQP with ReLive) they do not crush color range.
(but oh well, it is more like difference in white point balancing than anything else. On different monitors actual image may look closer to either one of those. Even though greenish tint definitely not something i anticipated)
Now... Only NVENC encode is expected for comparison purposes?
That looks fine, yeah. Was that with "Limited"? I assume so since I don't think ReLive has an option for "Full" iirc.
And that green tint is probably due to ReLive not supporting CQP, since specified bitrate modes will use VBAQ.
That looks fine, yeah. Was that with "Limited"? I assume so since I don't think ReLive has an option for "Full" iirc.
Yup. ReLive encoded as "Limited". OBS encoded as "Full".
Probably shader based conversion in work?
@DimkaTsv Do one more with Limited in OBS. (to rule out OBS messing something up here)
But yes, your posted images look correct. And although we still need to see NVenc results I expect them to be the same.
So the culprit is most-likely some misconfiguration @kotn3l and not a bug
Nah, even with "Limited" it does conversion/compression.
And ReLive banding is very similar to banding i can notice on OBS Limited capture. Even though bands are slightly shifted. So these are probably artifacts of Full -> Limited conversion algorithm.
Oh, wait, he mentioned that MPC-HC shows them as expected? One sec, then.
UPD: No issues. DaVinci Resolve preview may look slightly brighter or sharper, but color picker shows that it presents same colors as MPC-HC playback of captures.