H.265 Processing Benchmarking on M2 Pro

14 October 2023

In this blog post, I'll be demostrating you the benchmarking results on encoding and decoding a HEVC video using both the CPU and Media Engine of a M2 Pro Note that this tests made on a Macbook Pro 2023.

I have used ffmpeg to perform a this operation.

Speed Comparison

libx265 (the CPU) results as 0.134x. It means that the calculation performed $25\text{FPS} \cdot 0.134 = 3.37\text{FPS}$ speed.

hevc_videotoolbox (Media Engine) results as 2.04x. In more sense, it says that $25\text{FPS} \cdot 2.04 = 51\text{FPS}$ speed.

Execution Time Comparison

libx265 (the CPU) averagly performed one conversion operation in 182.643 seconds.

hevc_videotoolbox (Media Engine) averagly performed one conversion operation in 11.971 seconds.

The average retrieved from 5-run test. It should be noted that in CPU testing, the fans started to operate and the temperature of the device gor increased suddenly a lot.


Reports

ffmpeg -hide_banner -y -t 300 \
-filter_complex "[0:v]drawbox=x=10:y=10:w=100:h=100:color=red" \
-i ../videosets/Beauty_3840x2160_120fps_420_8bit_HEVC_RAW.hevc \
-c:v libx265 m2_pro_encoding.hevc


[hevc @ 0x11ff05590] Stream #0: not enough frames to estimate rate; consider increasing probesize
Input #0, hevc, from '../videosets/Beauty_3840x2160_120fps_420_8bit_HEVC_RAW.hevc':
  Duration: N/A, bitrate: N/A
  Stream #0:0: Video: hevc (Main), yuv420p(tv), 3840x2160, 25 fps, 25 tbr, 1200k tbn
Stream mapping:
  Stream #0:0 (hevc) -> drawbox:default
  drawbox:default -> Stream #0:0 (libx265)
Press [q] to stop, [?] for help
x265 [info]: HEVC encoder version 3.4+31-6722fce1f
x265 [info]: build info [Mac OS X][clang 15.0.0][32 bit][noasm] 8bit+10bit+12bit
x265 [info]: using cpu capabilities: none!
x265 [info]: Main profile, Level-5 (Main tier)
x265 [info]: Thread pool created using 10 threads
x265 [info]: Slices                              : 1
x265 [info]: frame threads / pool features       : 3 / wpp(34 rows)
x265 [info]: Coding QT: max CU size, min CU size : 64 / 8
x265 [info]: Residual QT: max TU size, max depth : 32 / 1 inter / 1 intra
x265 [info]: ME / range / subpel / merge         : hex / 57 / 2 / 3
x265 [info]: Keyframe min / max / scenecut / bias  : 25 / 250 / 40 / 5.00 
x265 [info]: Lookahead / bframes / badapt        : 20 / 4 / 2
x265 [info]: b-pyramid / weightp / weightb       : 1 / 1 / 0
x265 [info]: References / ref-limit  cu / depth  : 3 / off / on
x265 [info]: AQ: mode / str / qg-size / cu-tree  : 2 / 1.0 / 32 / 1
x265 [info]: Rate Control / qCompress            : CRF-28.0 / 0.60
x265 [info]: tools: rd=3 psy-rd=2.00 early-skip rskip mode=1 signhide tmvp
x265 [info]: tools: b-intra strong-intra-smoothing lslices=8 deblock sao
Output #0, hevc, to 'm2_pro_encoding.hevc':
  Metadata:
    encoder         : Lavf60.3.100
  Stream #0:0: Video: hevc, yuv420p(tv, progressive), 3840x2160, q=2-31, 25 fps, 25 tbn
    Metadata:
      encoder         : Lavc60.3.100 libx265
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
frame=  600 fps=3.4 q=33.7 Lsize=    8293kB time=00:00:23.88 bitrate=2845.0kbits/s speed=0.134x     
video:8293kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000000%
x265 [info]: frame I:      3, Avg QP:27.87  kb/s: 14695.20
x265 [info]: frame P:    149, Avg QP:28.19  kb/s: 5097.97 
x265 [info]: frame B:    448, Avg QP:32.91  kb/s: 1993.09 
x265 [info]: Weighted P-Frames: Y:0.0% UV:0.0%
x265 [info]: consecutive B-frames: 0.7% 2.0% 2.0% 92.8% 2.6% 

encoded 600 frames in 177.84s (3.37 fps), 2827.65 kb/s, Avg QP:31.71
ffmpeg -hide_banner -y -t 300 \
-filter_complex "[0:v]drawbox=x=10:y=10:w=100:h=100:color=red" \
-i ../videosets/Beauty_3840x2160_120fps_420_8bit_HEVC_RAW.hevc \
-c:v hevc_videotoolbox media_engine.hevc


[hevc @ 0x13c604d10] Stream #0: not enough frames to estimate rate; consider increasing probesize
Input #0, hevc, from '../videosets/Beauty_3840x2160_120fps_420_8bit_HEVC_RAW.hevc':
  Duration: N/A, bitrate: N/A
  Stream #0:0: Video: hevc (Main), yuv420p(tv), 3840x2160, 25 fps, 25 tbr, 1200k tbn
Stream mapping:
  Stream #0:0 (hevc) -> drawbox:default
  drawbox:default -> Stream #0:0 (hevc_videotoolbox)
Press [q] to stop, [?] for help
Output #0, hevc, to 'media_engine.hevc':
  Metadata:
    encoder         : Lavf60.3.100
  Stream #0:0: Video: hevc, yuv420p(tv, progressive), 3840x2160, q=2-31, 200 kb/s, 25 fps, 25 tbn
    Metadata:
      encoder         : Lavc60.3.100 hevc_videotoolbox
frame=  600 fps= 51 q=-0.0 Lsize=    8172kB time=00:00:23.96 bitrate=2793.9kbits/s speed=2.04x     
video:8172kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000000%
# Using Media Engine
❯ hyperfine --runs 5 --show-output ./start_media_engine.sh
Benchmark 1: ./start_media_engine.sh
  Time (mean ± σ):     11.971 s ±  0.018 s    [User: 34.417 s, System: 0.410 s]
  Range (min … max):   11.951 s … 11.998 s    5 runs

# Using M2 Pro CPU
❯ hyperfine --runs 5 --show-output ./start_m2_pro_cpu.sh
Benchmark 1: ./start_m2_pro_cpu.sh
  Time (mean ± σ):     182.643 s ±  4.518 s    [User: 1526.881 s, System: 5.858 s]
  Range (min … max):   178.292 s … 187.795 s    5 runs