feat: AV1 encoder support, codec discovery improvements#1
feat: AV1 encoder support, codec discovery improvements#1porkloin wants to merge 4 commits intohgaiser:mainfrom
Conversation
There was a problem hiding this comment.
First of all thanks for your contribution! Happy to see others are picking up on this.
I can't really judge the Vulkan / AV1 parts properly since I'm no expert either.. but could you update the example(s) and add a encode_av1.rs example? Specifically the verify_all.rs example helps me to quickly check the results are as expected. Also, please run cargo fmt :).
Regarding B frames: they are needed if you want to use both older and newer frames for better compression. This means if a frame comes in and is intended to be a B frame, it needs to be buffered because it needs to know the next frame (or even multiple frames) before it can be encoded. This is obviously not what you want for low latency streaming, so I opted not to implement this yet.
|
@hgaiser if you have a min to review this again 🙏 |
|
Thanks for the ping, this flew under my radar :) Does the In the I have a RTX 5080 and used AV1 in the past. Not through Vulkan though, but I thought AV1 was already supported for NVidia GPUs. |
9215969 to
76fd20f
Compare
|
@hgaiser just pushed some more work, I had missed adding av1 in the image.rs match and a few other things still needed sprucing up like implementing the re: nvidia, I'm not 100% sure since I don't have any nvidia hardware on hand to test with, so I don't know what the support level for av1 vulkan encode headers is beyond some cursory googling. It looks like you should expect to see at least av1 8bit and 10bit 4:2:0 pass, but 4:4:4 is unsupported? I'm on an AMD 9070XT and the current state of the mesa RADV driver I'm on (version 25.3.5) doesn't have any 4:4:4 support across h264, hevc or av1, and on top of that doesn't have h264 10 bit support at all. My understanding from the mesa source code is that those limitations are truly stuff that the RADV vulkan encoders aren't able to do atm. Anyway, with all that context, here's my output from We might need to figure out what your hardware is capable of with regard to vulkan av1 encoding and make sure the results are lining up, but you should see at least more passes now. Overall what I've learned is that both AMD and nvidia seem to have pretty poor support for 4:4:4 in vulkan across all h264/hevc/av1. I wasn't sure initially how much of that was just poor support for RDNA4 cards like mine, but it looks like it's not great on nvidia. If you let me know what graphics driver you're on for your 5080 I can do some spelunking on the driver code to see what seems reasonable. |
fa3e9c1 to
76fd20f
Compare
76fd20f to
cc07e72
Compare
|
I don't have time to dive into this deeper at the moment, but your branch gives me these results: While main gives: The PSNR for YUV444 dropped to < 10 dB in both H264 and H265. Any idea why that is? I didn't check why the command buffer for AV1 failed, that's a separate issue. For what it's worth, I'm using version 590.48.01-9 of the nvidia-open driver. |
|
That's very helpful output, I'll look into it more later today. |
|
OK, I finally had some time to poke at this a bit more. For the db drop stuff: the original Anyway, if you re-run I also looked into the av1 encoder status for the nvidia drivers, and I really can't find anything definitive. 550.40.xx included support for VK_KHR_video_encode_av1, that was in late 2024. It's possible that the driver support for it isn't really there, or something in ash's implementation is working fine with RADV but not with nvidia driver. If you have time to test it out more with your hardware and trace down exactly where the command buffer thing originates from, that would be great. |
|
Indeed the H264/H265 issue was because of the resolution. I'm still looking into why the AV1 encoding fails on my device.. I'll let you know :). |
|
I've had some time to try and figure this out. It appears that, at least on Nvidia, if you use a P frame as reference to create another P frame, it will mess up. The vk_video_samples repository does work, but they seem to work around the "issue" by only referencing I frames. That means if you generate IPPPP.. sequences that the P frames become increasingly bigger. On H264/H265 you can successfully reference a P frame to create a P frame.. so it feels like a bug in the Nvidia driver or in the configuration of vk_video_samples. I'm not yet sure how to proceed. I want to try some more things and probably make an issue on the vk_video_samples to discuss it further. TLDR: I didn't forget this, but it's not yet in a state where I feel comfortable merging this :) |
All good! I saw you have some recent work merged into main so I'll rebase on that to at least keep things up to date. In the meantime if there's anything I can do to help feel free to shout! I don't have any nvidia hardware at the moment but I am actually considering getting an nvidia card for another system I have that has been running exclusively on iGPU, so if I get hands on that I'll let you know. |
Ah no need! I've got an uncommitted branch that's rebased and contains some fixes to at least make it run on my GPU. If you want I can push those commits to this branch, but I think you have that option disabled :) |
|
Thanks again for the PR! I made some fixes and merged this in #3 , though I couldn't yet get proper IPPPP.. sequences to work without letting the I frame be the reference frame.. I can't recommend using AV1 yet, as I made clear in the documentation too. I'm not sure if this is an nvidia driver issue or something else, I'll need to spend some more time on it. I wanted to get it merged to have at least some form of AV1 encoding functioning, even if it's far from ideal. |
👋 I reached out on the moonlight discord about this work - here's the cleaned up version.
This adds AV1 support for pixelforge - the work was done in conjunction with some partner moonshine PRs which I will link here as soon as they're open:
ash has begun adding av1 encode support in the update branch - so this is mostly work implementing that. Note that this does involve changing the source for ash from the previously pinned main branch commit to a feature branch commit hash from the
updatebranch.A lot of this was put together using ffmpeg's av1 vulkan encoding as a reference implementation, and with a good bit of help from an LLM for questions that I had along the way. I'm hardly a graphics programmer, so this is definitely outside of my are of expertise. I also to a lesser extent consulted Khronos Group Vulkan-Headers repo and nvpro-samples vk_video_samples repo.
It should align with all the rate control and zero copy DMA-BUF, and color profile stuff other encoders in pixelforge currently support.
There's a bunch of av1 stuff here that isn't really working (bframe, tiling) which I barely understand the usecase for but seem not relevant for streaming video like moonshine is doing, and don't seem implemented in the other encoders.
I've tested using moonshine as a client on a 9070XT GPU on a fedora 43 (atomic) system with mesa 25.3.3. Additional testing on more hardware would be great, but is probably easier to do through Moonshine when the AV1 PR on that repo is posted, probably tomorrow night.