what to expect?
(click here for two html embedded test video files, if the user’s browser can playback 264x and 265x)
while x264 and x265 are surely great codecs, the re-encoding of x264 to x265 is very CPU and thus time and energy intense and on preset -crf 28 + mp3 audio (for material of high importance aac would be prefered) should yield at least reduction by -30% in file size.
SOMETIMES even Google’s webp format (VP9 codec) might have a BIGGER FILESIZE than the x264 mp4 version of the same content.
example: AMD Ryzen 5 5900G using all 6 cores manages to re-encode 1920×1080 (Full HD) with only 18fps, which depending on the source material (30fps) is half the speed of playback, so the user can imagine how slow things become with 4k and 8k re-encoding 😀
So in order to judge if it’s worth re-encoding a lot of material, really depends on:
- the available CPU power and efficiency
- here x265 “in-hardware” encoding/decoding would really be a win 😀
- Samsung S21 Ultra Snapdragon 888 has full hardware decoding for H.265 (HEVC)
- it can x265 re-encode 45min of Startrek in aprox 6h
- Samsung S21 Ultra Snapdragon 888 has full hardware decoding for H.265 (HEVC)
- “On PC-like platforms, video hardware is typically integrated into a GPU (from AMD, Intel or NVIDIA), while on mobile SoC-type platforms it is generally an independent IP core (many different vendors)” (src)
- tried to use the hardware acceleratio of the Ryzen 5 via amd:/dev/dri/renderD128 and yes it works but… see further down
- here x265 “in-hardware” encoding/decoding would really be a win 😀
- how much energy/1kWh costs
- if harddisk space is available or expensive
setup:
cat /etc/os-release; # tested on PRETTY_NAME="Debian GNU/Linux 11 (bullseye)" apt install ffmpeg ffmpeg --version ffmpeg version 4.3.5-0+deb11u1 Copyright (c) 2000-2022 the FFmpeg developers built with gcc 10 (Debian 10.2.1-6)
howto:
# keep the resolution, simply reencode with x265 (2x smaller) ffmpeg -i "input.mp4" -vcodec libx265 -crf 28 output.mp4 # reencode with x265 and reduce the resolution by 50% (file size 4.4x smaller) ffmpeg -i "input.mp4" -vcodec libx265 -crf 28 -vf "scale=trunc(iw/4)*2:trunc(ih/4)*2" output.mp4 # more examples # maximum compression (warning! very cpu intensive!) f=filename.mp4;nice -n 19 ffmpeg -threads 2 -i "$f" -vcodec libx265 -crf 28 -preset slow -c:a mp3 "$f".soft.x265.mp4 # high compression + better aac sound (still pretty cpu intensive!) f=filename.mp4;nice -n 19 ffmpeg -threads 2 -i "$f" -vcodec libx265 -crf 28 -preset medium -c:a aac "$f".soft.x265..mp4
hardware encoding?
according to src it should be possible 😀
test if hardware accelerated encoding/decoding is available/possible:
hostnamectl ; # tested with Operating System: Debian GNU/Linux 11 (bullseye) Kernel: Linux 5.10.0-21-amd64 Architecture: x86-64 cat /proc/cpuinfo |head processor : 0 vendor_id : AuthenticAMD cpu family : 25 model : 80 model name : AMD Ryzen 5 5600G with Radeon Graphics stepping : 0 microcode : 0xa50000d cpu MHz : 4116.583 cache size : 512 KB su - root; # install apt update apt install vainfo vainfo; # run it libva info: VA-API version 1.10.0 libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/radeonsi_drv_video.so libva info: Found init function __vaDriverInit_1_10 libva info: va_openDriver() returns 0 vainfo: VA-API version: 1.10 (libva 2.10.0) vainfo: Driver version: Mesa Gallium driver 20.3.5 for AMD RENOIR (DRM 3.40.0, 5.10.0-21-amd64, LLVM 11.0.1) vainfo: Supported profile and entrypoints VAProfileMPEG2Simple : VAEntrypointVLD VAProfileMPEG2Main : VAEntrypointVLD VAProfileVC1Simple : VAEntrypointVLD VAProfileVC1Main : VAEntrypointVLD VAProfileVC1Advanced : VAEntrypointVLD VAProfileH264ConstrainedBaseline: VAEntrypointVLD VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice VAProfileH264Main : VAEntrypointVLD VAProfileH264Main : VAEntrypointEncSlice VAProfileH264High : VAEntrypointVLD VAProfileH264High : VAEntrypointEncSlice VAProfileHEVCMain : VAEntrypointVLD VAProfileHEVCMain : VAEntrypointEncSlice VAProfileHEVCMain10 : VAEntrypointVLD VAProfileHEVCMain10 : VAEntrypointEncSlice VAProfileJPEGBaseline : VAEntrypointVLD VAProfileVP9Profile0 : VAEntrypointVLD VAProfileVP9Profile2 : VAEntrypointVLD VAProfileNone : VAEntrypointVideoProc # what hwacc is supported? ffmpeg -hide_banner -hwaccels Hardware acceleration methods: vdpau vaapi qsv drm opencl ffmpeg -h encoder=hevc_vaapi -hide_banner Encoder hevc_vaapi [H.265/HEVC (VAAPI)]: General capabilities: delay hardware Threading capabilities: none Supported hardware devices: vaapi Supported pixel formats: vaapi_vld h265_vaapi AVOptions: -low_power E..V...... Use low-power encoding mode (only available on some platforms; may not support all encoding features) (default false) -idr_interval E..V...... Distance (in I-frames) between IDR frames (from 0 to INT_MAX) (default 0) -b_depth E..V...... Maximum B-frame reference depth (from 1 to INT_MAX) (default 1) -rc_mode E..V...... Set rate control mode (from 0 to 6) (default auto) auto 0 E..V...... Choose mode automatically based on other parameters CQP 1 E..V...... Constant-quality CBR 2 E..V...... Constant-bitrate VBR 3 E..V...... Variable-bitrate ICQ 4 E..V...... Intelligent constant-quality QVBR 5 E..V...... Quality-defined variable-bitrate AVBR 6 E..V...... Average variable-bitrate -qp E..V...... Constant QP (for P-frames; scaled by qfactor/qoffset for I/B) (from 0 to 52) (default 0) -aud E..V...... Include AUD (default false) -profile E..V...... Set profile (general_profile_idc) (from -99 to 255) (default -99) main 1 E..V...... main10 2 E..V...... rext 4 E..V...... -tier E..V...... Set tier (general_tier_flag) (from 0 to 1) (default main) main 0 E..V...... high 1 E..V...... -level E..V...... Set level (general_level_idc) (from -99 to 255) (default -99) 1 30 E..V...... 2 60 E..V...... 2.1 63 E..V...... 3 90 E..V...... 3.1 93 E..V...... 4 120 E..V...... 4.1 123 E..V...... 5 150 E..V...... 5.1 153 E..V...... 5.2 156 E..V...... 6 180 E..V...... 6.1 183 E..V...... 6.2 186 E..V...... -sei E..V...... Set SEI to include (default hdr) hdr E..V...... Include HDR metadata for mastering display colour volume and content light level information # hardware encoding works! :D # + CPU around ~10% (power usage down 90%) # + encoding performance is up to 6x playback or 162 fps, which is great :D # o reduction in filesize depends on the bitrate # a -50% reduction for a 1920x1080 with 25fps was acchieved with 1220k bitrate # without losing too much details and getting too much compression artifacts (pixely squares) # - problem: user MUST SET bitrate MANUALLY (-b:v 2M = 2MBit/s, -b:v 1220k/s ...) f=input.mp4; # NOW COMES THE MAGIC SUPER COMPLICATED ONE-LINER THAT DOES IT ALL (if the bitrate is right X-D) ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi -i "$f" -c:v hevc_vaapi -rc_mode 3 -b:v 1220k "$f.hard.x265.mp4" # update: if that does not work (anymore) try this to reencode all mp4 in the current dir as x265 # use hardware accelerated encoding (way faster if available check with vainfo) for f in *.mp4 ; do ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128 -i "$f" -vf 'format=nv12,hwupload' -c:v hevc_vaapi "$f"_x265.mp4 done
script it:
- this will re-encode all *.mp4 in the current directory
- video encoding/decoding it a very CPU & energy intense process (if not hardware accelerated)
- example: depending on resolution of video:
- AMD-Ryzen-5600G re-encodes x264 to x265 at 1.5x the speed of playback (or ~40fps) while using 125W!
- example: depending on resolution of video:
vim /scripts/reencode_x265.sh #!/bin/bash echo "=== re encoding all video.mp4 files in the current directory via ffmpeg and x265 ===" for f in *.mp4 ; do time ffmpeg -i "$f" -vcodec libx265 -crf 28 "$f".x265.recompressed.mp4 done
To scale to half size:
vim /scripts/reencode_x265_half_size.sh #!/bin/bash echo "=== re encoding all video.mp4 in the current directory via ffmpeg and x265 plus reducing resolution by HALF! ===" # for $FILENAME in ./*.mp4; do for f in *.mp4 ; do time ffmpeg -i "$f" -vcodec libx265 -crf 28 "$f".x265.recompressed.mp4 time ffmpeg -i "$f" -vf "scale=trunc(iw/4)*2:trunc(ih/4)*2" -c:v libx265 -crf 28 "$f".half-size.x265.mp4 done
more examples:
ffmpeg -i input.mkv -vf "scale=trunc(iw/4)*2:trunc(ih/4)*2" -c:v libx265 -crf 28 half_the_frame_size.mkv
One third size:
ffmpeg -i input.mkv -vf "scale=trunc(iw/6)*2:trunc(ih/6)*2" -c:v libx265 -crf 28 a_third_the_frame_size.mkv
One quarter size:
ffmpeg -i input.mkv -vf "scale=trunc(iw/8)*2:trunc(ih/8)*2" -c:v libx265 -crf 28 a_fourth_the_frame_size.mkv
One fifth size:
ffmpeg -i input.mkv -vf "scale=trunc(iw/10)*2:trunc(ih/10)*2" -c:v libx265 -crf 28 a_fifth_the_frame_size.mkv
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!
