Enable AMF Decoder, HWContext AMF, vpp_amf filter#6475
Enable AMF Decoder, HWContext AMF, vpp_amf filter#6475Hotactioncop wants to merge 1 commit intoHandBrake:masterfrom
Conversation
|
I have a feeling it would be better to wait until the patches are integrated into FFmpeg, and after #6446 is merged. |
|
Thanks so much for this! I'm running the AMF decoder with SVT-AV1 on my AMD Ryzen 9 9950x. It works great! I just had to update my bios and disable PBO to fix the BSOD problem. |
e8687d0 to
fc8b54d
Compare
|
Asking for patch review. |
fc8b54d to
310f497
Compare
galad87
left a comment
There was a problem hiding this comment.
Added a bunch of random comments, didn't test this yet. But it would be better to replicate what NVenc/NVdec are doing (even if it was an hit and run and no one is keeping it working), instead of QSV.
| job->qsv.decode = !!(title->video_decode_support & | ||
| HB_DECODE_SUPPORT_QSV); | ||
| #endif | ||
| memset(&job->amf, 0, sizeof(job->amf)); |
There was a problem hiding this comment.
hb_job_t is already zeroed on creation, this shouldn't be needed.
There was a problem hiding this comment.
Thanks, this will be applied in the upcoming fix commit.
| hb_dict_set(settings, "format", hb_value_string(av_get_pix_fmt_name(pv->job->input_pix_fmt))); | ||
| hb_avfilter_append_dict(filters, "scale_cuda", settings); | ||
| } | ||
| else if ((pv->frame->hw_frames_ctx && pv->job && pv->job->hw_pix_fmt == AV_PIX_FMT_AMF_SURFACE) && |
There was a problem hiding this comment.
A rotate filter is needed in this function too, if not all those video recorded on phones with a rotation metadata will fail to encode properly
There was a problem hiding this comment.
Currently, AMF Hardware filters do not support rotation.
I will add an extra condition if (pv->title->rotation == HB_ROTATION_0) in the upcoming fix commit.
| // HWAccel falled back to the software decoder | ||
| av_frame_ref(pv->frame, pv->hw_frame); | ||
| av_frame_unref(pv->hw_frame); | ||
| if (ret < 0) |
There was a problem hiding this comment.
Accidentally removed, will be returned in the next fix commit.
| } while (ret >= 0); | ||
| if(send_packet) | ||
| { | ||
| av_usleep(100);// wait 0.1 ms before resubmitting |
There was a problem hiding this comment.
Please don't add random usleep around.
There was a problem hiding this comment.
A sleep is required if the submit input is full, to prevent unnecessary CPU usage.
| if(name != NULL) | ||
| { | ||
| pv->codec = avcodec_find_decoder_by_name(name); | ||
| if(pv->job) // no need to copy output for preview |
There was a problem hiding this comment.
I feel this is not a good way, what if we start to use hw filters for previews in the future?
There was a problem hiding this comment.
A reasonable remark. Will be removed in the next fix commit.
| } | ||
| } | ||
| #endif | ||
| #if HB_PROJECT_FEATURE_VCE |
There was a problem hiding this comment.
The other hardware encoders check if the hwaccel falled back to software decoder, wouldn't that work for amfdec too?
| // AMF-specific settings | ||
| struct | ||
| { | ||
| int num_sw_filters; |
There was a problem hiding this comment.
Do we need to store these numbers?
There was a problem hiding this comment.
We need to store this variable because it is used to check whether software filters are present.
If this variable is not 0, it means that software filters are present, and the pipeline can't be fully hardware-accelerated. However, since HandBrake is designed for maximum compatibility, we use int instead of bool.
| { | ||
| return job->hw_pix_fmt == AV_PIX_FMT_AMF_SURFACE; | ||
| } | ||
| hb_buffer_t * hb_vce_copy_avframe_to_video_buffer(hb_job_t *job, AVFrame *frame, AVRational time_base) |
There was a problem hiding this comment.
Is this function needed? Looks the same as hb_avframe_to_video_buffer
There was a problem hiding this comment.
The hw frame to sw frame conversion happens before, so there shouldn't be any need to check for sw_filters or whatever.
| if(w->hw_device_ctx) | ||
| { | ||
| pv->codec = avcodec_find_decoder_by_name(pv->qsv.codec_name); | ||
| const char* name = hb_vce_decode_get_codec_name(w->codec_param); |
There was a problem hiding this comment.
Would't be better to use the hwaccel framework like nvdec and videotoolboxdec? Don't try to copy the QSV implementation, because it was added before hwaccel, and it's doing custom things that hopefully will go away soon.
There was a problem hiding this comment.
The HWContext and AMF decoder is not hardware accelerated, it is an offload decoder.
Implementation of HWaccel AMF in hw_configs for default codecs was blocked by ffmpeg maintainers:
https://patchwork.ffmpeg.org/project/ffmpeg/patch/20240214015515.1027-2-ovchinnikov.dmitrii@gmail.com/
There was a problem hiding this comment.
The issue with standalone hw decoders is that they are missing features, and are never in sync with the built-in parsers and hwaccel decoders. For example HDR dynamic metadata are ignored, and others metadata too. It's a pain because you never know what works and what doesn't.
There was a problem hiding this comment.
That ultimately leads to a bad user experience when features that should be transparent and just work, don't.
|
There may be a bug that requires fixing before the feature is fully functional. Per the below, the output is sub-optimal and the work speed is slower. Below each image is the respective activity log for the encode. I also noticed that with the I used the |
Thank you for testing this PR! Input video file (or a short sample that reproduces the issue).
With my setup and a prepared video file matching the characteristics in your log file, I haven't encountered any errors. |
|
any update on this merge request? |
|
Thanks for following up! |


Adds hwcontext_amf, enabling a shared AMF context for encoders,
decoders, and AMF-based filters, without copy to the host memory.
Benefits:
Compression Artefact Removal(in future plans)
(like for encoder)
GPU and the accelerator will have the same API
Tested on: