-
Notifications
You must be signed in to change notification settings - Fork 1.6k
VAAPI Encoder (2nd branch/attempt) #7467
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
base: master
Are you sure you want to change the base?
Conversation
|
Thank you for this, looks pretty clean. Looking forward to again setting up Linux on my AMD machine to test (not a blocker). |
contrib/ffmpeg/A23-avformat-matroskaenc-tolerate-no-global-header.patch
Outdated
Show resolved
Hide resolved
…al_verbosity_level >= 3
7eaee89 to
1a5379c
Compare
|
I have force pushed this branch, addressed some comments. |
Thanks for keeping at it!
I've got a NAVI22, which supports h264 and h265 encoding. I'll try to test this soon.
FWIW, the current code in mesa looks like this: case VAConfigAttribEncPackedHeaders:
value = VA_ENC_PACKED_HEADER_NONE;
if ((u_reduce_video_profile(ProfileToPipe(profile)) == PIPE_VIDEO_FORMAT_MPEG4_AVC))
value |= ENC_PACKED_HEADERS_H264;
else if ((u_reduce_video_profile(ProfileToPipe(profile)) == PIPE_VIDEO_FORMAT_HEVC))
value |= ENC_PACKED_HEADERS_HEVC;
else if (u_reduce_video_profile(ProfileToPipe(profile)) == PIPE_VIDEO_FORMAT_AV1)
value |= ENC_PACKED_HEADERS_AV1;and the To me, this means mesa doesn't need to be patched anymore, right? |
15ca91a to
646822a
Compare
Yes, looks like! Mesa commit https://gitlab.freedesktop.org/mesa/mesa/-/commit/fc4abbe27d063337a420d147cf8c9fa492789f71, So we may need to unblind vaapi in ffmpeg public API, allowing to query these values? |
ddab085 to
6f6728d
Compare
|
Force pushed w/ added |
|
Hi, I own a Radeon RX 9070 XT so I'm able to test this PR with H.264, HEVC and AV1. First of all, here is what I get with As you can see, VAAPI works on my system and my GPU can encode with H.264, HEVC and AV1, but not with VP9. The command line used for this test is: H.264: HEVC: AV1: As a control test, I have also tried to transcode with ffmpeg, using VAAPI, and it has worked flawlessly for each codec. |
|
Thank you!
Yup!
I could reproduce this here also with ffmpeg transcoding, stuttering/jumping frames from theora, My test script: The last two Notable, I use the same ffmpeg 8.0.1 version (manual build) as our current Handbrake build This is potentially an ffmpeg issue ...
The HEVC + AV1 detection is also fixed, I was using h264 only parameter in Will force push soon after some additional tests. |
|
With the proposed changes above, encode with av1 through VAAPI now works and with good results, though it still complains about missing profile: And a warning: Also, while with CLI every codec works, but in the GUI only |
Not sure about the bug being in ffmpeg. I use the same version, 8.0.1. In my case transcoding directly with ffmpeg was flawless with each codec, it was done with a command line like this, e.g. for H.264: |
6f6728d to
0b77490
Compare
|
@Mastergatto OK pushed revision w/ our noted changes Below my test scripts. Tested w/ below scripts and a proper theora test file (my bad), Couldn't test AV1, due to hardware - but h264 + hevc/h265 works OK w/ vaapi here. If you test w/ HB, please ensure the +++ cat ffmpeg_test.sh cat hb_test.sh |
I revised the |
|
H.264, still not good: For what's worth, I have also tested AV1 - OK: And HEVC - OK: For GUI, now all three VAAPI encoders are available in the menu, and they produce same result as the CLI. Thank you for your hard work! |
Hmm, weird .. as it works for me :| What I see is this in your log So this may need some more elaboration, could be due to +++ Notable, your new Mesa/vaapi produces the packed header (our dire debate above), good.
Great.
Thank you! |
0b77490 to
baac9a8
Compare
|
force pushed changing inline function |
baac9a8 to
f560738
Compare
|
Forced pushed w/o sub-optimal ffmpeg patch:
Edit:
|
galad87
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use the same coding style as the rest of libhb:
blah *foo;
if (foo)
{
printf("hello");
}
supported: h264, hevc, av1, untested: vp8 and vp9
- h264, hevc works on AMD >= NAVI10
- av1 works on AMD > NAVI10(?)
- Bitrate either VBR (variable) or CQP (constant)
- Using Mesa 25 / libva 2.22 (Debian 13),
vaapi supports writing required sequence- and global-packet.
Therefor, no more patch is required to write into a MKV container.
On Debian 12, Mesa 22, these packets are not written
and hence no MKV container can be used.
+++
Test environment:
- GNU/Linux, Debian 13
- vainfo: VA-API version: 1.22 (libva 2.22.0)
- vainfo: Driver version: Mesa Gallium driver 25.0.7-2 for AMD Radeon RX 5700 XT (radeonsi, navi10, LLVM 19.1.7, DRM 3.61, 6.12.57+deb13-amd64)
Codev h264_vaapi, avcodec_open options: rc_mode=CQP,qp=24,b_depth=2,profile=100,level=40 (profile high, level 4.0)
HD1080 source ~45min with 212-330fps
PSNR and SSIM difference to x264 below 1%,
having x264 using profile high, level 4.0, preset fast, rc 23.
Both using constant-quality w/ variable bitrate.
++++
If FEATURE vaapi is enable (autodetected),
the following libraries are linked: X11 va va-drm va-x11.
- hb.c:
- Adding global static 'vaapi_device_ctx0' default device
initialized via hb_avcodec_init() and released via hb_avcodec_free().
The 'vaapi_device_ctx0' is used in vaa_common hb_avcodec_vaapi_set_hwframe_ctx(..).
- hb_avcodec_vaapi_set_hwframe_ctx() attaches the new AVHWFramesContext
to the AVCodecContext at initializing the encoder.
This is the final sink for the vaapi hw-encoder
and Encode(..) performs the frame conversion into it.
- hb_avcodec_test_encoder(..) adds VAAPI branch,
needs refinement
- encavcodec.c
- adding VAAPI branches, enabling available, needs refinement.
Currently profile and level are set to the user preferences,
additionally 'b_depth=2' is being passed.
- added hb_avcodec_test_encoder*(..) functions, currently only
used to check vaapi-*codec*-availability.
We used this codefragment regularly in an earlier HB version.
+++
Discussion:
VAAPI Workflow:
- It uses hardware frames on the target device, which are being transported
from the software device. The frame transport implicitly converts the pix_fmt.
- AVCodecContext's pix_fmt uses AV_PIX_FMT_VAAPI
- AVHWFramesContext: format uses AV_PIX_FMT_VAAPI and sw_format AV_PIX_FMT_NV12,
the latter hinting on the actual hw-frame's target format.
- AV_PIX_FMT_NV12 uses interleaved UV data, where AV_PIX_FMT_YUV420P uses
seperated planes. Both use a separated Y plane upfront.
Therefor both formats are not picture compatible, memory requirements are same.
- Encode(..) allocates a hw_frame and the source frame is being transported
to the hw-frame target using the pic_fmt conversion to NV12.
Finally the hw_frame is being sent 'avcodec_send_frame' and the code-path re-aligns
with non VAAPI.
Further fixes to do:
Validate whether 'b_depth=2' (b-frames) works for all vaapi implementations,
add custom extra-video-encoder field.
f560738 to
e0d003d
Compare
|
Changes:
Selection of vaapi device has not been addressed here yet, |
Please
Setup 1 (mine) Setup 2(*) |
Here is my Regarding Here are the logs running with the original code (where I tried commenting out On the other hand, encoding to AVC and HEVC directly using the |
My bad, yes - comment out, my cold makes me a bit fuzzy :) Thank you for testing. +++ Tricky .. You and the other tester use a more up-to-date GPU than me. As you both wrote, the build in vanilla
|
Get well soon! I actually just recovered from a cold myself, so I know the feeling. I just tried using a static build of FFmpeg 8.0.1 to see if I could reproduce the issue outside of HandBrake. However, I encountered a symbol resolution error: Instead of the visual glitches I saw earlier, this resulted in a 0kb output mp4 file. This might be unrelated to your current investigation (likely just a library version mismatch on my system), but I'm sharing the logs just in case they are useful to you: |
Uh oh, new finding: outputting to |
|
Below is a summary of our above tests, including @HexStan Perhaps we can merge this PR as-is and create a followup Test Machine Setup
Test Results
|
This is the 2nd clean VAAPI branch tackling issue 1083 #1083
and superseding pull-request #3039
supported: h264, hevc, av1, untested: vp8 and vp9
h264, hevc works on AMD >= NAVI10
av1 works on AMD > NAVI10(?)
Bitrate either VBR (variable) or CQP (constant)
Using Mesa 25 / libva 2.22 (Debian 13),
vaapi supports writing required sequence- and global-packet.
Therefor, no more patch is required to write into a MKV container.
On Debian 12, Mesa 22, these packets are not written
and hence no MKV container can be used.
+++
Tested on:
Test environment:
- GNU/Linux, Debian 13
- vainfo: VA-API version: 1.22 (libva 2.22.0)
- vainfo: Driver version: Mesa Gallium driver 25.0.7-2 for AMD Radeon RX 5700 XT (radeonsi, navi10, LLVM 19.1.7, DRM 3.61, 6.12.57+deb13-amd64)