this is about saving harddisk space, by reeconding videos (basically zipping videos to take up less space) takes a lot of CPU power… GPUs are way efficienter at this. no one would have guessed that a 14 year old (!!!) macbook pro with HD 4000 can reencode at 3x or 5x the playback speed! while using only 20% CPU 😀 😀 absolutely amazing work all involved!

lack of hardware acceleration makes 8k videos stutter as heck because even the fastest CPU will reach it’s limit with 8k playback (can test it with youtube but also with dwave’s S21 8k videos)

before trying this obviously make sure the OS is up to date

warning! while this script is pretty cool, it sometimes produces files LARGER than the original file.

so in order to make this usefull, it might be wise, to include a check: is the new reencoded file smaller than the original file? good delete the original, otherwise keep the original and delete the reencoded X-D

hostnamectl; # tested on
 Static hostname: macian
       Icon name: computer-laptop
         Chassis: laptop 💻
Operating System: Debian GNU/Linux 13 (trixie)
          Kernel: Linux 6.12.105+deb13-amd64
    Architecture: x86-64
 Hardware Vendor: Apple Inc.
  Hardware Model: MacBookPro9,2
Firmware Version: 429.0.0.0.0
# as non root user that also runs the desktop run
glxinfo -B
name of display: :0
display: :0 screen: 0
direct rendering: Yes
Extended renderer info (GLX_MESA_query_renderer):
Vendor: Intel (0x8086)
Device: Mesa Intel(R) HD Graphics 4000 (IVB GT2) (0x166)
Version: 25.0.7
Accelerated: yes
Video memory: 1536MB
Unified memory: yes
Preferred profile: core (0x1)
Max core profile version: 4.2
Max compat profile version: 4.2
Max GLES1 profile version: 1.1
Max GLES[23] profile version: 3.0
OpenGL vendor string: Intel
OpenGL renderer string: Mesa Intel(R) HD Graphics 4000 (IVB GT2)
OpenGL core profile version string: 4.2 (Core Profile) Mesa 25.0.7-2+deb13u1
OpenGL core profile shading language version string: 4.20
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile

OpenGL version string: 4.2 (Compatibility Profile) Mesa 25.0.7-2+deb13u1
OpenGL shading language version string: 4.20
OpenGL context flags: (none)
OpenGL profile mask: compatibility profile

OpenGL ES profile version string: OpenGL ES 3.0 Mesa 25.0.7-2+deb13u1
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.00

apt install mesa-utils
apt install vainfo i965-va-driver
ffmpeg -hide_banner -encoders | grep -E 'h264|hevc'
V....D libx264 libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (codec h264)
V....D libx264rgb libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 RGB (codec h264)
V....D h264_nvenc NVIDIA NVENC H.264 encoder (codec h264)
V..... h264_qsv H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (Intel Quick Sync Video acceleration) (codec h264)
V..... h264_v4l2m2m V4L2 mem2mem H.264 encoder wrapper (codec h264)
V....D h264_vaapi H.264/AVC (VAAPI) (codec h264)
V....D h264_vulkan H.264/AVC (Vulkan) (codec h264)
V....D libx265 libx265 H.265 / HEVC (codec hevc)
V....D hevc_nvenc NVIDIA NVENC hevc encoder (codec hevc)
V..... hevc_qsv HEVC (Intel Quick Sync Video acceleration) (codec hevc)
V..... hevc_v4l2m2m V4L2 mem2mem HEVC encoder wrapper (codec hevc)
V....D hevc_vaapi H.265/HEVC (VAAPI) (codec hevc)
V....D hevc_vulkan H.265/HEVC (Vulkan) (codec hevc)

# Do not rely on the presence of hevc_vaapi or hevc_qsv: FFmpeg lists compiled encoders even when the GPU cannot support them. HD 4000 should support hardware H.264 encoding, but not hardware H.265/HEVC encoding

vainfo; # as non root user
Trying display: wayland
Trying display: x11
libva info: VA-API version 1.22.0
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so
libva info: Found init function __vaDriverInit_1_22
libva error: /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so init failed
libva info: va_openDriver() returns 1
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/i965_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 i965 driver for Intel(R) Ivybridge Mobile - 2.4.1
vainfo: Supported profile and entrypoints
VAProfileMPEG2Simple : VAEntrypointVLD
VAProfileMPEG2Simple : VAEntrypointEncSlice
VAProfileMPEG2Main : VAEntrypointVLD
VAProfileMPEG2Main : VAEntrypointEncSlice
VAProfileH264ConstrainedBaseline: VAEntrypointVLD
VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
VAProfileH264Main : VAEntrypointVLD
VAProfileH264Main : VAEntrypointEncSlice
VAProfileH264High : VAEntrypointVLD
VAProfileH264High : VAEntrypointEncSlice
VAProfileH264StereoHigh : VAEntrypointVLD
VAProfileVC1Simple : VAEntrypointVLD
VAProfileVC1Main : VAEntrypointVLD
VAProfileVC1Advanced : VAEntrypointVLD
VAProfileNone : VAEntrypointVideoProc
VAProfileJPEGBaseline : VAEntrypointVLD

# the script WARNING! will also reduce resolution by 50% to save disk space (degrading quality)
vim /scripts/reencode_half_size_x264_mp3_64Bit_hard_hd4000_v2.sh

#!/usr/bin/env bash
#
# vaapi_recompress.sh
#
# Iterates over movie files in the current directory, and for any filename
# containing "recompress" (case-sensitive), asks whether to reencode it via
# VAAPI hardware H.264 encoding at half resolution with 64kbit MP3 audio.
# Files not containing "recompress" are skipped automatically.
#
# If the reencoded file ends up larger than the original, the reencode is
# discarded and the original is kept.

set -uo pipefail

VAAPI_DEVICE="/dev/dri/renderD128"

# --- Sanity checks -----------------------------------------------------

if ! command -v ffmpeg >/dev/null 2>&1; then
    echo "Error: ffmpeg not found in PATH." >&2
    exit 1
fi

if [[ ! -e "$VAAPI_DEVICE" ]]; then
    echo "Error: VAAPI device $VAAPI_DEVICE not found." >&2
    exit 1
fi

# --- Glob setup ----------------------------------------------------------
# nullglob: unmatched patterns expand to nothing instead of themselves
# nocaseglob: match extensions regardless of case
shopt -s nullglob nocaseglob

extensions=(mp4 webm avi mkv mpg mpeg wmv mov)

files=()
for ext in "${extensions[@]}"; do
    for f in *."$ext"; do
        [[ -f "$f" ]] && files+=("$f")
    done
done

if [[ ${#files[@]} -eq 0 ]]; then
    echo "No movie files found in current directory."
    exit 0
fi

# --- Main loop -------------------------------------------------------------

for f in "${files[@]}"; do

    if [[ "$f" == *recompress* ]]; then
        read -rp "Filename '$f' contains 'recompress'. Process it? [y/n] " ans
        case "$ans" in
            [Yy]|[Yy][Ee][Ss])
                ;;
            [Nn]|[Nn][Oo])
                echo "Skipped by user: $f"
                continue
                ;;
            *)
                echo "Unrecognized answer, treating as 'no'. Skipped: $f"
                continue
                ;;
        esac
    else
        echo "Processing (no 'recompress' in filename, auto-processing): $f"
    fi

    base="${f%.*}"
    tmpout="${base}.__reencode_tmp__.mp4"

    # Clean up any leftover temp file from a previous aborted run
    rm -f "$tmpout"

    echo "Reencoding: $f -> $tmpout"

    ffmpeg -y \
        -vaapi_device "$VAAPI_DEVICE" \
        -i "$f" \
        -vf "format=nv12,hwupload,scale_vaapi=w=trunc(iw/4)*2:h=trunc(ih/4)*2" \
        -c:v h264_vaapi \
        -c:a libmp3lame -b:a 64k \
        "$tmpout"

    rc=$?

    if [[ $rc -ne 0 || ! -s "$tmpout" ]]; then
        echo "ffmpeg failed (or produced empty output) for: $f -- keeping original, removing temp file."
        rm -f "$tmpout"
        continue
    fi

    orig_size=$(stat -c%s -- "$f")
    new_size=$(stat -c%s -- "$tmpout")

    echo "Original size: $orig_size bytes | New size: $new_size bytes"

    if (( new_size >= orig_size )); then
        echo "Reencoded file is not smaller. Keeping original, discarding reencode: $f"
        rm -f "$tmpout"
    else
        finalout="${base}_x264_64Bit_mp3_recompressed.mp4"

        # If the original wasn't itself .mp4, we're changing container/extension.
        # Remove the original first, then move the temp file into place.
        rm -f -- "$f"

        # Avoid clobbering if finalout somehow already exists (e.g. same base name,
        # different original extension already processed this run).
        if [[ -e "$finalout" && "$finalout" != "$f" ]]; then
            echo "Warning: target '$finalout' already exists, keeping temp name '$tmpout'."
        else
            mv -- "$tmpout" "$finalout"
            echo "Replaced original with reencoded file: $finalout"
        fi
    fi

done

echo "Done."

liked this article?

  • only together we can create a truly free world
  • plz support dwaves to keep it up & running!
  • (yes the info on the internet is (mostly) free but beer is still not free (still have to work on that))
  • really really hate advertisement
  • contribute: whenever a solution was found, blog about it for others to find!
  • talk about, recommend & link to this blog and articles
  • thanks to all who contribute!
admin