-
Notifications
You must be signed in to change notification settings - Fork 152
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Question]: bgr0 input, yuv444 10 bit output? #488
Comments
I understand the need and here are few points:
|
Hi @MikhailAMD, Thank you for you helpful and informative answers, as always! That's much appreciated :) Your suggestions are nice and make sense but it's only to get the most quality out of a limited color format. For desktop streaming that's just gonna give you a washed out desktop. Considering that the AMF API does know how to convert many color formats to 4:2:0 it isn't a far flung thought to assume the encoder can handle those too, can it not? Else the VCN hardware literally is a pipeline of Many formats in -> 1 format out. Possible, but it sounds like a waste of resources to not add in the extra bits to at least to a 1:1 format mapping (no conversion), to me that seems technically easier too. I suppose i'm asking "in subtle ways" if AMF, with the current hardware of say VCN 4.0, could technically support higher quality color spaces? |
You need to clarify term "quality". It can mean multiple things:
Also need to clarify "support higher quality color spaces". One thing is input format support. Another thing is encoder output support.
|
Ha :) It doesn't have to output 10 bit as long as it does the encoding based on 10 bit. This is solely to reduce banding hell. In terms of color this is still poor quality as the desktop stream would look washed out. So the YUV compression (it's color/luminosity compression) of 4:2:0 is just too little color data (chrominance signals, the U and V) to have a good looking desktop stream. 4:2:2 would already look much better and perhaps even be sufficient. But ideally 4:4:4 is what's needed here. |
IMHO, 4:2:0 is not related to washed-out color but only to reduced clarity of the text on symbol borders. |
Thank you so much for your hints @MikhailAMD! I'm passing in Another snapshot: Now gradients. Color banding hell... You can easily see banding in the bottom part, that's AMF. Looks the same as 8 bit? Yup, that's right. No change indeed. Below is a full settings output of 8 bit and bgr0, i found these settings to be working quite well.
If we can only fix that banding, that'd be super! Yes, i'm using |
OK, it is more clear now. The gradient bands you have are most likely due to compression, not color conversion. I would recommend several changes in your parameters:
|
Hi @MikhailAMD Thank you for these suggestions! I tried I also tried
A big issue i still have is YUV 4:2:0. Forget what i'm doing there (certainly not playing with flv... but i tried out some ffmpeg container formats for latency reasons). Just having YUV 4:2:2 would already be such an immense improvement here! For completeness sake, here's my full set of settings:
A couple observations:
This is how it would look like with YUV 4:2:2 (tried on libx264) It's still bad but acceptable. But as i want to stay within 20 mbit/sec i'm guessing YUV 4:2:2 + HEVC is the maximum achievable. Before one thinks AV1 here, that really doesn't matter much. HEVC and AV1 have similar bandwidth usages. A practical difference here is that i can have a hardware encode on one pc and hardware decode on the other with HEVC. I can't with AV1 (receiving end doesn't have AV1 hardware decoding). My wishlist for encoding here:
Now here's a fun little detail. While i am using
But ... if i change my input from |
What is the correct AMF surface format for |
I've noticed that with In both cases the format is passed in as ffmpeg It's tricky to find out if there's something wrong with AMF, with the arguments i give it or with the software format conversion. I tried passing in this exact format to libx264 as well but it doesn't recognize this format and automatically switches to To aid debugging, here's the full set of properties passed into AMF with p010le:
|
Hi @DimkaTsv, While it might seem like you're doing an apples-apples comparison, i think it's more like an apples-oranges one in this case :) OBS does a lot. I don't know what but you should remove external factors and limit it to just an ffmpeg command. That's what i'm testing here after all. The eventual intent is live desktop streaming for my own use. There's no OBS in there at all. As you asked, my GPU is an 7900XT. I did do another test with bgr0 and nv12 both at 8 bit (as 10 bit seems to introduce some grey veil annoyance). The AMF properties for BGR0:
And the AMF properties for NV12:
In both cases the output is yuv420p. I tried the same nv12 on libx264 and while it doesn't look exactly like the the above bgr0 image it does match it very closely. It's definitely different. This does lead me to think that there is something wrong with color conversions in AMF. It might be a flag that needs tweaking but perhaps i'm also hitting up against actual driver bugs here? |
I'm also using existing tools. ffmpeg :) Well, i did patch in the 10 bit support but only because a patch already existed and it seemed easy enough for me to add it.
It's more complex.
I get that there is a difference with RGB -> NV12. Now i could be wrong but i think the nv12 -> yuv420 conversion should be lossless. They both represent the exact same data but just in a different memory layout. This does rests on the assumption that i'm correct here which would also mean that AMF does something with nv12 input that libx264 doesn't. The output is different while it shouldn't.
|
For interwebs to think about reasonable bitrate... You have own streaming server hosted somewhere? Twitch limits you to 6mbps unless you popular afaik, and that forces even 1080p users to downscale their streams to 720p, not to say 1440p. Or use capture cards and second dedicated PC with CPU encode just to squeeze more quality. And if you go over limit, then ingest server will transcode source into lower quality stream anyways iirc. One reason i mention this, is that you concidered raw RGB or YUV444 encode, which, despite giving you higher color precision, will also likely require higher bitrate for same movement quality due to more data being encoded. But issue you still is being left atm, is that AMD HW physically doesn't support YUV444, and 10bit stream support is still pretty limited. |
@DimkaTsv Those are all assumptions that are just not relevant. I don't think i ever even hinted at streaming to a webservice. You apparently want to know... My case is simple. I have a local pc/server "in a closet" that is a powerhouse. I have thin/light devices elsewhere (laptop, raspberry pi, etc..). Within this local network environment i want to stream the gorgeous graphics from my high powered "server" to my low powered devices. With that in mind, i don't care if it's 10mbit, 100mbit or even a gigabit! As long as it works and feels fast en fluid. You didn't aks/imply about this yet but i'll answer it in advance 😛 I'm not going for the sunshine/moonlight combination because those are pre-made where it would be much harder for me to try out a tiny change. That's - to me - surprisingly easy to do in ffmpeg. For reference, within a minute i can make an ffmpeg one-liner change, build it and run with it. Now i prefer to also have this high quality desktop stream working over the internet - for my own personal private use, not for youtube/twitch/whatever - and for that reason i try to make something work that i deem acceptable within 20mbit/sec (also because that's my max upload bandwidth..). Does that answer your assumptions/questions? 😉 |
There is a lot of good discussions here, be sure they are noted as well as the wish list. On practical terms: In one of the parameter sets from @markg85 (not the latest one) I see couple of problems:
vbr_latency forces less variations in frame-over-frame bitrate compared to vbr_peak. HEVC 10 bit (main10) - several points:
Pls remind me if I missed something. |
Hi @MikhailAMD, So the 10 bit support for the VDI case isn't much useful i suppose? As that requires HDR on the AMF side to make things work properly. That seems a bit much, i might play with it to see if i can get it to work properly but from what you've said it seems like 8 bit is the way to go instead. Regarding What i'm missing is why the BGR0 vs NV12 as input have a (slight but observable) different output color? I't all 8 bit in this case, no HDR or 10 bit. The output is yuv420p so the conversion inside AMF must be from BGR0 -> -> yuv420p. This should be the same color output as if i were passing in nv12 yet it's not. Do you have a clue about what's going on here? |
It looks like you are using FFmpeg to convert from BGRA to NV12 and FFmpeg color converter is programmed to apply STUDIO range. The STUDIO range keeps color values for luma 16-235 so you don't have true black. For chroma it is 16-240. Full range is 0-255 for both. |
Hi,
I went though a lot of documentation and code and could find this little clue.
Do note that this is for desktop streaming. I want to preserve as much quality as possible so i'd prefer to not even convert from bgr0 to anything else. If i look at the features that HEVC as container format should support in terms of color spaces then RGB is definitely one of them.
That makes me assume the AMF codec can handle bgr0 as format.
The question is: How do i output a format that both AMF and HEVC support that preserves the most quality?
I have ffmpeg with the 10 bit for HEVC with AMF working. If there's a hint for what to add to support this then i can probably hack it in. I just need the hint to know what to do :)
Best regards,
Mark
The text was updated successfully, but these errors were encountered: