Help to solve CPU peaks (overheats) while using camera (possibly HW Acceleration I guess)

PC overheats while using camera, I use KDE so an widget showed me that my CPU peaks everytime I use camera for meetings in firefox, google chrome, opening OBS etc etc. I guess the hardware acceleration is not working for camera, how to solve this?

here’s my PC spec(incase u need it):

You’re using an intel CPU with an integrated graphics card. I would recommend using it for hardware acceleration, as NVIDIA do not officially support for hardware acceleration on Linux (there is a third-party hack, but it doesn’t work in Chrome, and is generally less efficient and more limited).

The wiki has a page on doing this, it also has a section on debugging specific applications (including Chrome and Firefox): Accelerated Video Playback - Official NixOS Wiki

OBS is a slightly different story. I would recommend configuring OBS to use NVENC. This is done entirely in the OBS settings, since it means directly calling an NVIDIA API.

2 Likes

Ok I’ll try this. Also while watching YouTube etc though heating, the CPU don’t peak much. Only for camera it’s heating too much. So still what u mentioned remains valid?
@TLATER

Yeah, the non-NVIDIA VAAPI drivers support video encoding as well, which is the most likely culprit here.

1 Like


I am getting this output. is this working as expected?
or should I solved the failed something there?

Yep, that’s broken. I don’t actually own any intel hardware, so I can’t support any further as far as debugging the actual driver goes. Looks like the driver is properly installed and configured, but fails to function in practice.

1 Like

:sob::sob::sob::sob::sob:
Sed lyf
I hope someone else facing this shower some knowledge on this

Sorry about that, I’m running this on a ThinkPad X1 Carbon Gen 13. It does not help, because we have completly diffent harware ( no nvidia on my side ). At least it has nothing todo with intel in my thinking.

$ nix shell nixpkgs#libva-utils
$ vainfo
Trying display: wayland
libva info: VA-API version 1.22.0
libva info: Trying to open /run/opengl-driver/lib/dri/iHD_drv_video.so
libva info: Found init function __vaDriverInit_1_22
libva info: va_openDriver() returns 0
vainfo: VA-API version: 1.22 (libva 2.22.0)
vainfo: Driver version: Intel iHD driver for Intel(R) Gen Graphics - 25.2.6 ()
vainfo: Supported profile and entrypoints
      VAProfileNone                   : VAEntrypointVideoProc
      VAProfileMPEG2Simple            : VAEntrypointVLD
      VAProfileMPEG2Main              : VAEntrypointVLD
      VAProfileH264Main               : VAEntrypointVLD
      VAProfileH264Main               : VAEntrypointEncSlice
      VAProfileH264High               : VAEntrypointVLD
      VAProfileH264High               : VAEntrypointEncSlice
      VAProfileJPEGBaseline           : VAEntrypointVLD
      VAProfileJPEGBaseline           : VAEntrypointEncPicture
      VAProfileH264ConstrainedBaseline: VAEntrypointVLD
      VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
      VAProfileVP8Version0_3          : VAEntrypointVLD
      VAProfileHEVCMain               : VAEntrypointVLD
      VAProfileHEVCMain               : VAEntrypointEncSlice
      VAProfileHEVCMain10             : VAEntrypointVLD
      VAProfileHEVCMain10             : VAEntrypointEncSlice
      VAProfileVP9Profile0            : VAEntrypointVLD
      VAProfileVP9Profile1            : VAEntrypointVLD
      VAProfileVP9Profile2            : VAEntrypointVLD
      VAProfileVP9Profile3            : VAEntrypointVLD
      VAProfileHEVCMain12             : VAEntrypointVLD
      VAProfileHEVCMain422_10         : VAEntrypointVLD
      VAProfileHEVCMain422_10         : VAEntrypointEncSlice
      VAProfileHEVCMain422_12         : VAEntrypointVLD
      VAProfileHEVCMain444            : VAEntrypointVLD
      VAProfileHEVCMain444            : VAEntrypointEncSlice
      VAProfileHEVCMain444_10         : VAEntrypointVLD
      VAProfileHEVCMain444_10         : VAEntrypointEncSlice
      VAProfileHEVCMain444_12         : VAEntrypointVLD
      VAProfileHEVCSccMain            : VAEntrypointVLD
      VAProfileHEVCSccMain            : VAEntrypointEncSlice
      VAProfileHEVCSccMain10          : VAEntrypointVLD
      VAProfileHEVCSccMain10          : VAEntrypointEncSlice
      VAProfileHEVCSccMain444         : VAEntrypointVLD
      VAProfileHEVCSccMain444         : VAEntrypointEncSlice
      VAProfileAV1Profile0            : VAEntrypointVLD
      VAProfileAV1Profile0            : VAEntrypointEncSlice
      VAProfileHEVCSccMain444_10      : VAEntrypointVLD
      VAProfileHEVCSccMain444_10      : VAEntrypointEncSlice
      VAProfileVVCMain10              : VAEntrypointVLD
      VAProfileVVCMultilayerMain10    : VAEntrypointVLD
1 Like

i am still getting the same error even after started using nixpkgs unstable for my system :face_holding_back_tears:

looks like your CPU (i7-4500U) is not supported by intel-media-driver, but by the older libva-intel-driver. see: Hardware video acceleration - ArchWiki

ensure your hardware config looks like this:

{
  hardware.graphics = {
    enable = true;
    extraPackages = with pkgs; [
      intel-vaapi-driver # For older processors. LIBVA_DRIVER_NAME=i965
    ];
  };
  environment.sessionVariables = { LIBVA_DRIVER_NAME = "i965"; };
}

If you have both drivers already in the extraPackages list, you can test it out by running LIBVA_DRIVER_NAME=i965 vainfo

2 Likes

Gah, you’re right! I’m so sorry, I was convinced the i7-4500U was Broadwell. See the support table here: GitHub - intel/media-driver: Intel Graphics Media Driver to support hardware decode, encode and video processing.

My config:

hardware.graphics = {
    enable = true;
    extraPackages = with pkgs-unstable; [
      intel-media-driver # For Broadwell (2014) or newer processors. LIBVA_DRIVER_NAME=iHD
      intel-vaapi-driver # For older processors. LIBVA_DRIVER_NAME=i965
      intel-ocl # took this package name from this option example in nixos option (no other specific reason to add such this)
    ];
  };
  environment.sessionVariables = {
    #LIBVA_DRIVER_NAME = "iHD";
    LIBVA_DRIVER_NAME = "i965";
  };

after nixos rebuild:

So I shouldnt add multiple driver packages? :thinking: or something else is going on here? :cry:

Yes, best case you’re just wasting disk space.

Also yes, from that output it looks like vainfo is picking up the correct driver and still failing.

Maybe don’t use the unstable package?

That’s for compute. If you run stable diffusion or ollama or such it would theoretically be usable for acceleration, but a 10 year old iGPU probably isn’t going to do much for you for that kind of stuff. I’d just remove it, though it’s unlikely to cause issues.

ok makes sense. Also Should I specifically mention my nvidia graphics too? Or it’s drivers are loaded automatically by the system?

my fastfetch output for reference:

This depends. By default I believe only your iGPU will be used. But maybe it isn’t and that’s why playback isn’t working?

Anyway, let’s take a step back and look at what you have and might want. There are multiple things GPUs can be used for:

  • Rendering intensive graphical workfloads, such as video games
  • Accelerating certain types of computation
  • Rendering your desktop
  • Accelerating media playback

Your dGPU is good at the first two, and your iGPU is good at the last two, while using less energy (good for your battery life and/or environment) and being more stable (since the drivers are baked into the kernel). For this reason, the ideal setup is to use your iGPU for rendering your desktop and watching videos, and using your dGPU for rendering games and doing various compute things (e.g. blender and “AI workloads”, as most of those have algorithms that can be accelerated well using GPUs).

That said, you can choose to make either GPU do any of those things. My recommendation is to make your iGPU do most stuff, and only turn on your dGPU for games or compute, but since media acceleration isn’t working on your iGPU maybe you can try the nvidia alternative.

How do you make this work? Well, that also depends. Your hardware is positively ancient, and since nvidia has always had proprietary drivers (it has improved a bit lately, but that doesn’t affect GPUs from 2011), it’s quite possible that using the proprietary driver with your nvidia GPU simply will not work with modern kernels. nouveau is however also notorious for not being very good, both in terms of performance and battery use, since it doesn’t implement power scaling correctly, so using the nvidia GPU at all may simply not be worth it.

You’re also using wayland. Wayland fully supports multi-GPU management, but the specific implementation depends on your compositor. Plasma has some special default logic to choose a suitable GPU for rendering your desktop, but this logic can be quirky; it may well make a weird choice with some hardware. I don’t use Plasma, so I don’t know how to ask it for its default choice.

So, there are a couple of different setups to try. Firstly, you’ll need to figure out which nvidia driver version actually supports your graphics card. From your neofetch output I can’t tell which GPU you actually have; it’s either the 470 or the 390 driver, but who knows. There might be a hardware sticker somewhere telling you the actual name.

Additionally, you’ll need to figure out the bus IDs of both of your GPUs. See the offload option for instructions on how to get the ID, then look for those IDs in /dri/by-path/pci and note down the path for your nvidia and intel GPUs.

From there, we can go and start filling in the options for using your GPUs. Since we’re going to be mucking with what makes your computer show anything at all, remember that you can switch to an old generation if you hold space during boot, just in case stuff breaks.

I’d recommend doing this in a separate file, so create a new file called /etc/nixos/graphics.nix, and import it in /etc/nixos/configuration.nix (and make sure to remove any former graphics configuration from configuration.nix):

# configuration.nix
{ pkgs, lib, ... }: {
  imports = [
    ./graphics.nix
  ];

  # Rest of your configuration here
}

Let’s first try if the nvidia GPU works at all, and try to render the desktop with it:

# graphics.nix
{ config, ... }: let
  # Put your real IDs here; these should not be the same in practice
  gpuBusId = {
    intelBusId = "PCI:0:2:0";
    nvidiaBusId = "PCI:1:0:0";
  };

  gpuPaths = let
    pciPath =
      xorgBusId:
        let
          components = lib.drop 1 (lib.splitString ":" xorgBusId);
          toHex = i: lib.toLower (lib.toHexString (lib.toInt i));

          domain = "0000"; # Apparently the domain is always set to 0000
          bus = lib.fixedWidthString 2 "0" (toHex (builtins.elemAt components 0));
          device = lib.fixedWidthString 2 "0" (toHex (builtins.elemAt components 1));
          function = toHex (builtins.elemAt components 2);
        in
        "dri/by-path/pci-${domain}:${bus}:${device}.${function}-card";
  in {
    intel = pciPath gpuBusId.intelBusId;
    nvidia = pciPath gpuBusId.nvidiaBusId;
  };
in {
  services.xserver.videoDrivers = [ "nvidia" ];

  hardware = {
    nvidia = {
      # Depending on which GPU you actually have
      package = config.boot.kernelPackages.nvidiaPackages.legacy_470;
      # package = config.boot.kernelPackages.nvidiaPackages.legacy_390;
      videoAcceleration = false;
    };

    graphics = {
      enable = true;
      extraPackages = [
        pkgs.intel-vaapi-driver
      ];
    };
  };

  # Note that this is using `.variables` not `.sessionVariables` now;
  # Double check that this is still set correctly when you start your terminal
  environment.variables = {
    LIBVA_DRIVER_NAME = "i965";
    KWIN_DRM_DEVICES = gpuPaths.nvidia;
  };
}

If you build this config (use nixos-rebuild boot and reboot, not nixos-rebuild switch) and reboot, and everything continues to work, congratulations, you can use your nvidia GPU!

If not, well, that’s not surprising, I’ve seen many people try to revive old nvidia GPUs and fail.

If it does work, we can go a step further and try to use the iGPU as the desktop driver, and only offload intense rendering to the dGPU. How you do that depends on the driver version. If you have a GPU that is supported by the 470 driver, you can use prime offload. For that, we configure the system like so:

# graphics.nix
{ config, ... }: let
  # Put your real IDs here; these should not be the same in practice
  gpuBusId = {
    intelBusId = "PCI:0:2:0";
    nvidiaBusId = "PCI:1:0:0";
  };

  gpuPaths = let
    pciPath =
      xorgBusId:
        let
          components = lib.drop 1 (lib.splitString ":" xorgBusId);
          toHex = i: lib.toLower (lib.toHexString (lib.toInt i));

          domain = "0000"; # Apparently the domain is always set to 0000
          bus = lib.fixedWidthString 2 "0" (toHex (builtins.elemAt components 0));
          device = lib.fixedWidthString 2 "0" (toHex (builtins.elemAt components 1));
          function = toHex (builtins.elemAt components 2);
        in
        "dri/by-path/pci-${domain}:${bus}:${device}.${function}-card";
  in {
    intel = pciPath gpuBusId.intelBusId;
    nvidia = pciPath gpuBusId.nvidiaBusId;
  };
in {
  services.xserver.videoDrivers = [ "nvidia" ];

  hardware = {
    nvidia = {
      package = config.boot.kernelPackages.nvidiaPackages.legacy_470;
      videoAcceleration = false;

      prime = {
        inherit (gpuBusId) intelBusId nvidiaBusId;

        offload = {
          enable = true;
          enableOffloadCommand = true;
        };
      };
    };

    graphics = {
      enable = true;
      extraPackages = [
        pkgs.intel-vaapi-driver
      ];
    };
  };

  environment.variables = {
    LIBVA_DRIVER_NAME = "i965";
    KWIN_DRM_DEVICES = "${gpuPaths.intel}:${gpuPaths.nvidia}";
  };
}

Again, rebuild and reboot, see if your computer still works. If you get to your desktop, you will now be rendering using the intel GPU; to test that the nvidia GPU is still working, you will have to use the offload command to explicitly make something start with nvidia.

Say, for example, your web browser:

$ nvidia-offload firefox

You can then use the nvidia-smi command to confirm that firefox is in fact rendering on your GPU.

If this works, congratulations! We can further dig into the details of media acceleration once you get here. There are also other things you will likely want to configure, such as “finegrained” power management and KMS - these are enabled by default on newer drivers, but not on these old drivers. They may even be required to get wayland to run, so I’m not holding my breath for the first attempt being successful.

If your GPU only supports the 390 driver, well, I have to admit I don’t really know how to do that. I don’t have the hardware to test this scenario. The nvidia docs might help: Chapter 17. Using the NVIDIA Driver with Optimus Laptops

… given the length of this post, and that we’re not even halfway to a fully featured setup, you may realize that using nvidia on Linux is a FREAKING MESS. Good luck!

1 Like

You can also get these IDs (more conveniently in the PCI: format) via

nix --experimental-features "flakes nix-command" run github:eclairevoyant/pcids
2 Likes

:flushed::flushed::flushed: wow wow. Thanks for the big efforts. I’ll try these and will post here. I think it’s 390, anyway I’ll check and try all these and post.

Also my use case is that when using camera for meetings, the CPU peaks and overheats. And also while recording in OBS the CPU heats. Because of this 30 minutes into the meeting and CPU is overheated and device hangs a lot.
I have a KDE widget in my panel, so I know the CPU spikes on using camera.

Same happens while watching youtube in Firefox or Chrome, CPU overheats .

Yep, this is because you’re using the CPU to render video. Given OBS/camera are also involved, I’m not sure the nvidia vaapi driver will do much for you, since it doesn’t support encoding. But let’s see where we get when you’ve tested what actually functions.

Where can I find such cool stuffs like these? :fire::heart:

If you don’t find it, make it. (I wrote that one.)

1 Like