Project

General

Profile

Feature #6224

enable Intel VAAPI low power encoding (for iGPU 9+)

Added by Alin Gherghescu almost 2 years ago. Updated over 1 year ago.

Status:
New
Priority:
Normal
Category:
Transcoding
Target version:
-
Start date:
2022-11-29
Due date:
% Done:

0%

Estimated time:

Description

Hi,

I am trying to add low power encoding (H264) to a J4125 (iGPU 9.5) in order to save power.
I have two option (that I know):
1. use ffmpeg spawn with "-low_power 1"

/home/hts/bin/ffmpeg -hide_banner -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi -i pipe:0 -map 0:v -vf 'deinterlace_vaapi' -low_power 1 -c:v h264_vaapi -preset veryslow -profile:v high -qp:v 28 -map 0:a? -c:a aac -b:a 64k -map 0:s? -c:s copy -fflags +nobuffer+discardcorrupt+genpts+flush_packets -avoid_negative_ts disabled -f mpegts pipe:1

ffmpeg is compiled from: https://github.com/FFmpeg/FFmpeg and copied to /home/hts/bin/

This works very well (with some significant delay when I switch channel) ... I can see with intel_gpu_top that is using less resources (not using Render / 3D / 0).
Downside --> I am forced to use http transport

2. use tvheadend with built in ffmpeg with low_power mode enabled (for H264 encoding).
advantage: I can use htsp transport
For that I did the following:
https://github.com/tvheadend/tvheadend/blob/master/src/transcoding/transcode/hwaccels/vaapi.c --> line 586 -- 589 changed:

if (!(hwaccel_context =
tvhva_context_create("encode", avctx, VAEntrypointEncSlice))) {
return -1;
}

with:

if (avctx->codec->id == AV_CODEC_ID_H264){
if (!(hwaccel_context =
tvhva_context_create("encode", avctx, VAEntrypointEncSliceLP))) {
return -1;
}
}
else{
if (!(hwaccel_context =
tvhva_context_create("encode", avctx, VAEntrypointEncSlice))) {
return -1;
}
}

The goal is to return VAEntrypointEncSliceLP for H264 encoding and VAEntrypointEncSlice for other codecs.

Everything compiled and worked but when I checked the gpu top I did not see the same results as with ffmpeg with low_power 1 ... meaning the Render / 3D / 0 was > 0 for tvheadend build ; also the CLK was higher.
I see that tvheadend is using an old ffmpeg build (4.4.1) --> is this the reason why my change was not working? meaning ffmpeg is too old to recognize "VAEntrypointEncSliceLP"?
If anyone sees and other reason please let me know.
Also, can I update the scipt to download a new version of ffmpeg (in Makefile.ffmpeg)? Does anyone has a stable version to recommend?

To clarify:
I have GUC enabled and vaapi is showing the LP codec.

alin@alin-gk41:~$ dmesg | grep guc
[ 1.771782] Setting dangerous option enable_guc - tainting kernel
[ 1.807689] i915 0000:00:02.0: [drm] GuC firmware i915/glk_guc_62.0.0.bin version 62.0 submission:disabled

alin@alin-gk41:~$ vainfo
error: can't connect to X server!
libva info: VA-API version 1.15.0
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so
libva info: Found init function __vaDriverInit_1_15
libva info: va_openDriver() returns 0
vainfo: VA-API version: 1.15 (libva 2.15.0)
vainfo: Driver version: Intel iHD driver for Intel(R) Gen Graphics - 22.5.0 (7e9cc59)
vainfo: Supported profile and entrypoints
VAProfileNone : VAEntrypointVideoProc
VAProfileNone : VAEntrypointStats
VAProfileMPEG2Simple : VAEntrypointVLD
VAProfileMPEG2Main : VAEntrypointVLD
VAProfileH264Main : VAEntrypointVLD
VAProfileH264Main : VAEntrypointEncSlice
VAProfileH264Main : VAEntrypointFEI
VAProfileH264Main : VAEntrypointEncSliceLP
VAProfileH264High : VAEntrypointVLD
VAProfileH264High : VAEntrypointEncSlice
VAProfileH264High : VAEntrypointFEI
VAProfileH264High : VAEntrypointEncSliceLP
VAProfileVC1Simple : VAEntrypointVLD
VAProfileVC1Main : VAEntrypointVLD
VAProfileVC1Advanced : VAEntrypointVLD
VAProfileJPEGBaseline : VAEntrypointVLD
VAProfileJPEGBaseline : VAEntrypointEncPicture
VAProfileH264ConstrainedBaseline: VAEntrypointVLD
VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
VAProfileH264ConstrainedBaseline: VAEntrypointFEI
VAProfileH264ConstrainedBaseline: VAEntrypointEncSliceLP
VAProfileVP8Version0_3 : VAEntrypointVLD
VAProfileVP8Version0_3 : VAEntrypointEncSlice
VAProfileHEVCMain : VAEntrypointVLD
VAProfileHEVCMain : VAEntrypointEncSlice
VAProfileHEVCMain : VAEntrypointFEI
VAProfileHEVCMain10 : VAEntrypointVLD
VAProfileHEVCMain10 : VAEntrypointEncSlice
VAProfileVP9Profile0 : VAEntrypointVLD
VAProfileVP9Profile2 : VAEntrypointVLD


Files

variable.png (12.7 KB) variable.png Alin Gherghescu, 2022-12-11 02:15
UI_code.png (31.9 KB) UI_code.png Alin Gherghescu, 2022-12-11 02:18
UI.png (6.15 KB) UI.png Alin Gherghescu, 2022-12-11 02:19
avlib.png (10.9 KB) avlib.png Alin Gherghescu, 2022-12-11 02:21
tvh_low_power_1.zip (565 KB) tvh_low_power_1.zip logs with low power = 1 Alin Gherghescu, 2022-12-11 02:27
tvh_low_power_0.zip (344 KB) tvh_low_power_0.zip logs with low power = 0 Alin Gherghescu, 2022-12-11 02:27
variable.png (6.61 KB) variable.png Alin Gherghescu, 2022-12-13 03:31
UI_code.png (22.2 KB) UI_code.png Alin Gherghescu, 2022-12-13 03:32
UI.png (6.26 KB) UI.png Alin Gherghescu, 2022-12-13 03:32
avlib.png (22.6 KB) avlib.png Alin Gherghescu, 2022-12-13 03:33
UI_full.png (91.3 KB) UI_full.png Alin Gherghescu, 2022-12-14 07:14
h264_docs.zip (376 KB) h264_docs.zip Alin Gherghescu, 2023-01-07 08:03

History

#1

Updated by Flole Systems almost 2 years ago

  • Assignee set to Alin Gherghescu

Please implement it and submit a PR for it.

#2

Updated by Alin Gherghescu almost 2 years ago

Changes above were dropped for now ... is not clear if are required or not.

I started: https://github.com/alingherghescu/tvheadend

All changes are in file: /src/transcoding/codec/codecs/libs/vaapi.c:
1. added low power to tvh_codec_profile_vaapi_t

2. added setting in UI

with results:

3. send data to AVLIB:

4. logs are showing that parameter is sent:
2022-12-10 16:07:04.675 [ DEBUG]:transcode: 0002: 01:H264: [mpeg2video => h264_vaapi]: opts: qp=27,quality=1,low_power=1,pix_fmt=46,tvh_filter_deint=1,width=1920,height=1080,bf=3,tvh_require_meta=1,profile=100

5. is even selecting the proper entry:
2022-12-10 16:07:04.676 [ DEBUG]:libav: AVCodecContext: Using VAAPI entrypoint VAEntrypointEncSliceLP (8).

6. when I check the GPU loading (sudo intel_gpu_top) I don't see any difference between 0/1. Also if I use ffmpeg (from ubuntu repository ... older) is showing less resources with the command (including 0 load on Render/3D):
/usr/bin/ffmpeg -hide_banner -err_detect ignore_err -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi -i pipe:0 -map 0:v -vf 'deinterlace_vaapi' -low_power 1 -c:v h264_vaapi -profile:v high -qp:v 28 -map 0:a? -c:a aac -b:a 64k -map 0:s? -c:s copy -fflags +nobuffer+discardcorrupt+genpts+flush_packets -avoid_negative_ts disabled -f mpegts pipe:1

I know is a big difference between the parameters used with ffmpeg and the ones used by tvh ... but I was hopping that parameters are equivalent.
Attached are logs with low power set to 0 and 1.

Any help is appreciated ... for now I am stuck.

#3

Updated by Alin Gherghescu almost 2 years ago

Finally I understood the problem: quality > 0 will overwrite the low_power with 0=disable.

Let me clarify the changes:
https://github.com/tvheadend/tvheadend/pull/1483

All changes are in file: /src/transcoding/codec/codecs/libs/vaapi.c:
1. added low power to tvh_codec_profile_vaapi_t

2. added setting in UI

with results:

3. send data to AVLIB:

Note:
the low power is above quality because when low power = 1 will override quality value with 0.

GPU load is comparable with ffmpeg:
/usr/bin/ffmpeg -hide_banner -err_detect ignore_err -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi -i pipe:0 -map 0:v -vf 'deinterlace_vaapi' -low_power 1 -c:v h264_vaapi -profile:v high -qp:v 28 -map 0:a? -c:a aac -b:a 64k -map 0:s? -c:s copy -fflags +nobuffer+discardcorrupt+genpts+flush_packets -avoid_negative_ts disabled -f mpegts pipe:1

Let me know if you have any questions.

#4

Updated by Alin Gherghescu almost 2 years ago

Note:
If GPU doesn't have support for low power and low power checkbox is checked the following error will be printed:
libav: AVCodecContext: No usable encoding entrypoint found for profile VAProfileH264High (7).

In the end we updated the UI to checkbox:

#5

Updated by Alin Gherghescu almost 2 years ago

during my development I realized that UI has a lot of limitations.
https://github.com/alingherghescu/tvheadend
Before I invest too much time I want to make sure we are aligned on the new changes.
Please check h264_vaapi interface and let me know if something doesn't seem right.
I finalized h264_vaapi update ... still have to update the rest (hevc_vaapi, bp8_vaapi and vp9_vaapi).
Identified problems/limitations:
1. many rc_mode combinations were not possible (like QVBR, AVBR, VBR) because target bitrate was missing and qp/bitrate can't be set in the same time
2. parameters missing (I consider important parameters): async_depth, low_power
3. bitrate is fixed for any resolution: meaning SD, HD and UHD will be encoded with the same value (very unpractical)
4. interface is not interactive ... to help user to select parameters.
What I added:
1. platform --> will select different constrains. Generic will allow any combination (valid or invalid), iGPU8 and iGPU9 are with the appropriate constrains. AMD has only bf workaround.
2. async_depth --> with increasing number of EUs it make sense to increase also the number of parallel process
3. bit_rate_scale_factor --> this is how much the bitrate will change with resolution (relative to 480). This number is the Slope in a chart X=resolution, Y=bitrate. 0=constant; 1=increase with proportional value.
4. low power.
The parameters are ordered in such a way for parameter to influence only the parameters below.
After confirmation I will continue with other codecs from vaapi.

#6

Updated by Flole Systems almost 2 years ago

Yeah the UI is old and limited, it would require a complete rewrite. It's not possible to migrate to newer extjs versions.

Your approach sounds good so far, I'm not using the VAAPI stuff so I'm not familiar with all options, I'll leave pretty much all decisions on how things are implemented best up to you. Maybe others who use it can give their opinion.

#7

Updated by Alin Gherghescu almost 2 years ago

Flole,
Please update MD file for CodecProfile/VAAPI in the https://github.com/tvheadend/tvheadend/tree/master/docs/class in order for me to document the VAAPI updated interface (after will be merged to Master).
I would prefer you do the split (VAAPI / NVEC / ... SW) from https://github.com/tvheadend/tvheadend/blob/master/docs/class/codec_profile.md ... I plan to document only the VAAPI branch-s (h264_vaapi, hevc_vaapi, vp8_vaapi, vp9_vaapi).
Thank you,
Alin

#8

Updated by Flole Systems almost 2 years ago

I've never really edited the docs but maybe Mark Clarkstone can help here. I'll message him, if he finds some time he can look into this.

Thanks for all the work!

#9

Updated by Alin Gherghescu almost 2 years ago

attached are the md + png files for h264_vaapi. Probably the text must be adjusted ... but the information should be there.
let me know if you need more info.

#10

Updated by Flole Systems over 1 year ago

I think this is implemented by now?

Also available in: Atom PDF