GStreamer & Multimedya
TEKNİK REHBER GSTREAMER DONANIM HIZLANDIRMA 2026

Donanım Hızlandırmalı Video —
VPU & Zero-Copy.

CPU yerine VPU/GPU: i.MX VPU, Rockchip MPP, Jetson NVENC/NVDEC, VA-API ve DMA-BUF zero-copy pipeline — gömülü sistemlerde güç ve termal sınırları aşmadan 1080p encode.

00 Neden donanım codec — CPU vs VPU

Gömülü sistemlerde yazılım encode, CPU'yu tamamen meşgul eder; ısıl kısıtlama (thermal throttling) devreye girerek çalışma süresini kısaltır. VPU, sabit fonksiyon donanımı olduğundan aynı işi çok daha az güçle yapar.

Karşılaştırma tablosu — i.MX8MP örneği

Metrik
x264enc (software)
v4l2h264enc (HW VPU)
1080p@30 CPU kullanımı
~95%
~5%
Güç tüketimi (encode)
~3.5W
~0.5W
Encode latency
~15ms (ultrafast)
~8ms
Maksimum çözünürlük
Sınırsız (CPU'ya bağlı)
Platform limitine kadar
Termal sorun
Uzun süre kritik
Yok

VPU mimarisi

VPU Blok Diyagramı
┌────────────────────────────────────────────────────┐
│                 SoC (örn: i.MX8MP)                  │
│                                                      │
│  ┌──────────┐    DMA-BUF    ┌────────────────────┐  │
│  │   ISP /  │ ──────────→  │   VPU (Video        │  │
│  │  V4L2    │              │   Processing Unit)   │  │
│  │  kamera  │              │   H.264/H.265 HW     │  │
│  └──────────┘              └────────┬───────────┘  │
│                                     │ encoded data  │
│  ┌──────────┐    DDR        ┌────────▼───────────┐  │
│  │   CPU    │ ◄──────────── │   Output buffer    │  │
│  │  (ARM)   │               │   (filesink/net)   │  │
│  └──────────┘               └────────────────────┘  │
└────────────────────────────────────────────────────┘

Zero-copy path: V4L2 DMA-BUF → VPU DMA-BUF input
Kamera frame CPU'ya hiç taşınmaz — doğrudan VPU'ya
UYARI

Donanım encoder kalite/hız parametreleri yazılım encoder'a göre sınırlıdır. x264enc'in tune/preset seçeneklerinin tamamı VPU'da mevcut değildir. Kalite kritikse yazılım encode tercih edin; güç/ısı kritikse donanım zorunludur.

01 i.MX VPU — imxvpuenc ve mxc_vpu driver

NXP i.MX serisi SoC'larda (i.MX6, i.MX8, i.MX8MP) entegre VPU bulunur. Kernel driver mxc_vpu veya imx-vpu, GStreamer plugin'i gstreamer-imx üzerinden erişilir.

Kernel ve driver durumu

bash — i.MX VPU kontrolü
# VPU cihaz düğümlerini kontrol et
ls -la /dev/mxc_vpu* /dev/video* 2>/dev/null
# /dev/mxc_vpu      ← i.MX6 VPU (eski driver)
# /dev/video10       ← i.MX8 VPU encode (V4L2 M2M)
# /dev/video12       ← i.MX8 VPU decode (V4L2 M2M)

# Kernel modülünü kontrol et
lsmod | grep vpu
# imx_vpu_v4l2_dec   ...
# imx_vpu_v4l2_enc   ...

# V4L2 M2M encoder desteklediği formatları listele
v4l2-ctl -d /dev/video10 --list-formats
# Index: 0 (Output)
#   Pixel Format: 'NV12' (Y/UV 4:2:0)
# Index: 0 (Capture)
#   Pixel Format: 'H264' (H.264)

gstreamer-imx pipeline

bash — i.MX8MP hardware encode
# gstreamer-imx plugin'leri kur (Yocto: meta-imx)
# IMAGE_INSTALL += " gstreamer1.0-plugins-imx"

# imxvpuenc_h264 ile hardware encode
gst-launch-1.0 \
  v4l2src device=/dev/video0 ! \
  video/x-raw,format=NV12,width=1920,height=1080,framerate=30/1 ! \
  imxvpuenc_h264 \
    bitrate=4000 \
    intra-refresh=0 \
    idr-interval=30 ! \
  h264parse ! \
  filesink location=imx_hw.mp4

# v4l2h264enc (standard V4L2 M2M — yeni kernel)
gst-launch-1.0 \
  v4l2src device=/dev/video0 io-mode=4 ! \
  video/x-raw,format=NV12,width=1920,height=1080,framerate=30/1 ! \
  v4l2h264enc \
    capture-io-mode=4 \
    extra-controls="controls,h264_profile=4,h264_level=41" ! \
  video/x-h264,level=\(string\)4 ! \
  h264parse ! \
  filesink location=v4l2hw.h264

i.MX G2D hardware scaler

bash — imxvideoconvert_g2d
# G2D (2D GPU) ile zero-copy format dönüşüm ve scale
# CPU yerine 2D GPU kullanır
gst-launch-1.0 \
  v4l2src device=/dev/video0 ! \
  video/x-raw,format=YUYV,width=1920,height=1080 ! \
  imxvideoconvert_g2d ! \
  video/x-raw,format=NV12,width=1280,height=720 ! \
  v4l2h264enc ! \
  filesink location=g2d_scaled.h264

02 Rockchip MPP — mppvideodec ve rkmpp

Rockchip RK3399, RK3568, RK3588 SoC'ları güçlü Media Process Platform (MPP) VPU'ya sahiptir. rkmpp GStreamer plugin'i ve rockchip-mpp kütüphanesi ile H.264/H.265/VP9 donanım encode/decode desteklenir.

MPP kurulum ve yapı

bash — Rockchip MPP kurulum
# Debian/Ubuntu (Armbian/Ubuntu 22.04 for RK3588)
sudo apt install librockchip-mpp1 librockchip-mpp-dev

# gstreamer-rockchip plugin kur
# Genellikle BSP imajında gelir veya kaynak koddan derlenir
# https://github.com/JeffyCN/rockchip_mirrors/gstreamer-rockchip

# VPU cihaz kontrolü
ls -la /dev/mpp_service /dev/rga
# /dev/mpp_service    ← Rockchip MPP
# /dev/rga            ← Rockchip RGA (2D accelerator)

# MPP codec bilgisi
mpi_enc_test -w 1920 -h 1080 -t 7 -f 0 -o /tmp/test.h264
# MPP INFO: mpp_enc encode success, frame cnt 100

rkmpp GStreamer pipeline

bash — RK3588 hardware encode/decode
# H.264 hardware encode (RK3568/RK3588)
gst-launch-1.0 \
  v4l2src device=/dev/video0 ! \
  video/x-raw,format=NV12,width=1920,height=1080,framerate=30/1 ! \
  mpph264enc \
    bps=4000000 \
    bps-target=4000000 \
    rc-mode=vbr \
    profile=high \
    gop=30 ! \
  h264parse ! \
  filesink location=rk_hw.h264

# H.265 hardware encode (RK3588 — 8K capable)
gst-launch-1.0 \
  v4l2src device=/dev/video0 ! \
  video/x-raw,format=NV12,width=3840,height=2160,framerate=30/1 ! \
  mpph265enc bps=8000000 rc-mode=vbr ! \
  h265parse ! \
  filesink location=rk_4k_hevc.h265

# Hardware decode
gst-launch-1.0 \
  filesrc location=video.h264 ! \
  h264parse ! \
  mppvideodec ! \
  videoconvert ! autovideosink

# RGA ile scale + format dönüşüm
gst-launch-1.0 \
  v4l2src device=/dev/video0 ! \
  video/x-raw,format=NV12,width=3840,height=2160 ! \
  rgaconvert ! \
  video/x-raw,format=NV12,width=1920,height=1080 ! \
  mpph264enc bps=4000000 ! filesink location=4k_to_1080p.h264
mpph264enc
Rockchip MPP H.264 encoder. bps, bps-target, rc-mode (cbr/vbr/fixqp), profile, gop parametreleri.
mppvideodec
Rockchip MPP decoder. H.264, H.265, VP9, AV1 destekler (platform bağımlı).
rgaconvert
Rockchip RGA 2D accelerator ile format dönüşüm ve ölçekleme. CPU yok.

03 Jetson NVENC/NVDEC — nvv4l2 pipeline

NVIDIA Jetson serisinde (Nano, NX, AGX Orin) NVENC (encoder) ve NVDEC (decoder) donanımsal video işleme birimi bulunur. DeepStream SDK veya doğrudan nvv4l2 GStreamer plugin'i ile kullanılır.

Jetson ortam kurulumu

bash — Jetson kurulum
# JetPack kurulu Jetson'da nvv4l2 plugin genellikle hazırdır
gst-inspect-1.0 nvv4l2h264enc
# Plugin Details:
#   Name: nvv4l2h264enc
#   Description: NVENC Video H264 Encoder
#   Version: 1.16.5

# CUDA ve codec bilgisi
jetson_clocks --show
nvpmodel -q
# MAXN veya farklı güç modu seç

# Tüm V4L2 M2M cihazları listele
v4l2-ctl --list-devices

Jetson hardware encode pipeline

bash — nvv4l2h264enc
# Jetson hardware H.264 encode
gst-launch-1.0 \
  v4l2src device=/dev/video0 ! \
  video/x-raw,format=NV12,width=1920,height=1080,framerate=30/1 ! \
  nvv4l2h264enc \
    bitrate=4000000 \
    iframeinterval=30 \
    preset-level=1 \
    insert-sps-pps=true \
    bufapi-version=true ! \
  h264parse ! \
  mp4mux ! filesink location=jetson.mp4

# Jetson H.265 4K encode
gst-launch-1.0 \
  v4l2src device=/dev/video0 ! \
  video/x-raw,format=NV12,width=3840,height=2160,framerate=30/1 ! \
  nvv4l2h265enc bitrate=8000000 iframeinterval=30 ! \
  h265parse ! filesink location=jetson_4k.h265

# Jetson hardware decode + display
gst-launch-1.0 \
  filesrc location=video.h264 ! \
  h264parse ! \
  nvv4l2decoder ! \
  nvvideoconvert ! \
  nv3dsink

# CUDA tabanlı ek işlem için nvdsvideotemplate
nvv4l2h264enc
NVENC H.264 encoder. bitrate (bps), iframeinterval, preset-level (1=ultrafast, 4=medium), insert-sps-pps.
nvv4l2decoder
NVDEC hardware decoder. H.264, H.265, VP9, AV1 destekler (AGX Orin için). Çıkış NV12 formatında.
nvvideoconvert
GPU üzerinde renk uzayı dönüşümü. NV12↔RGBA, zero-copy GPU memory.
nv3dsink
Jetson ekran çıkışı (EGLStream/OpenGL). GPU bellek → display, zero-copy.

04 VA-API — Intel ve AMD GPU encode

VA-API (Video Acceleration API), Linux'ta GPU video işleme için standart arayüzdür. Intel iHD/i965, AMD Mesa RadeonSI driver'ları ile çalışır. Masaüstü ve embedded x86 platformlarda yaygındır.

VA-API durumu kontrol

bash — vainfo
# VA-API kurulum
sudo apt install vainfo libva-dev gstreamer1.0-vaapi

# Desteklenen profil ve işlemleri listele
vainfo
# vainfo: VA-API version: 1.16 (libva 2.16.0)
# Driver version: Intel iHD driver for Intel(R) Gen Graphics - 22.5
# Supported profile and entrypoints
# ...
#    VAProfileH264Main               :    VAEntrypointEncSliceLP
#    VAProfileH264High               :    VAEntrypointEncSliceLP
#    VAProfileH264High               :    VAEntrypointVLD (decode)
#    VAProfileHEVCMain               :    VAEntrypointEncSliceLP
# ...

# GPU cihaz kontrolü
ls -la /dev/dri/
# renderD128 ← GPU render node (VA-API buna erişir)

gstreamer-vaapi encode pipeline

bash — VAAPI encode
# VAAPI H.264 encode
gst-launch-1.0 \
  videotestsrc num-buffers=300 ! \
  video/x-raw,format=NV12,width=1920,height=1080,framerate=30/1 ! \
  vaapih264enc \
    bitrate=4000 \
    keyframe-period=30 \
    tune=high-compression \
    rate-control=cbr ! \
  h264parse ! \
  mp4mux ! filesink location=vaapi_h264.mp4

# VAAPI H.265 encode
gst-launch-1.0 \
  videotestsrc num-buffers=300 ! \
  vaapih265enc bitrate=2000 keyframe-period=30 ! \
  h265parse ! \
  mp4mux ! filesink location=vaapi_h265.mp4

# VAAPI decode
gst-launch-1.0 \
  filesrc location=video.h264 ! \
  h264parse ! \
  vaapih264dec ! \
  vaapipostproc ! \
  autovideosink

# VAAPI postprocessing (scale + color)
gst-launch-1.0 \
  filesrc location=video.h264 ! h264parse ! vaapih264dec ! \
  vaapipostproc \
    width=1280 height=720 \
    format=nv12 \
    deinterlace-mode=bob ! \
  vaapih264enc bitrate=2000 ! filesink location=scaled.h264
DRM RENDER NODE

VAAPI /dev/dri/renderD128 cihazına erişim gerektirir. Kullanıcının render grubunda olması veya uygun yetkiye sahip olması gerekir: sudo usermod -aG render $USER

05 DMA-BUF zero-copy pipeline

DMA-BUF (Direct Memory Access Buffer), çeşitli donanım bileşenlerinin (kamera, GPU, codec) aynı fiziksel bellek bloğuna CPU kopyası olmadan erişmesini sağlar. Gömülü sistemlerde bant genişliği ve gecikme kritik avantaj sağlar.

DMA-BUF mekanizması

DMA-BUF Akış Diyagramı
Geleneksel pipeline (KOPYALI):
  Kamera → [DMA → CPU bellek] → [CPU kopyası → encode giriş] → VPU encode
  Bellek kopyası: 2x (1080p NV12 = 3MB × 30fps = 90MB/s kopyalama!)

DMA-BUF zero-copy pipeline:
  Kamera → [DMA-BUF fd] → VPU encode (aynı fiziksel bellek)
  Bellek kopyası: 0

Faydalar:
  - DDR bant genişliği tasarrufu
  - CPU meşguliyeti azalma
  - Gecikme düşüşü (1-5ms)
  - Güç tüketimi azalma

V4L2 → DMA-BUF → encode

bash — zero-copy pipeline
# io-mode=4 (DMABUF) ile kamera → encoder zero-copy
gst-launch-1.0 \
  v4l2src device=/dev/video0 io-mode=dmabuf ! \
  video/x-raw,format=NV12,width=1920,height=1080,framerate=30/1 ! \
  v4l2h264enc \
    capture-io-mode=dmabuf-import \
    extra-controls="controls,h264_profile=4" ! \
  h264parse ! filesink location=zerocopy.h264

# io-mode değerleri
# dmabuf         = v4l2src output DMA-BUF olarak export eder
# dmabuf-import  = encoder input DMA-BUF import eder

DMA-BUF C API ile manuel yönetim

dmabuf_pipeline.c
#include <gst/gst.h>
#include <gst/allocators/gstdmabuf.h>
#include <gst/video/gstvideometa.h>

/* DMA-BUF buffer'ı kontrol etmek için probe */
static GstPadProbeReturn dmabuf_probe(GstPad *pad, GstPadProbeInfo *info,
                                       gpointer data)
{
    GstBuffer *buf = GST_PAD_PROBE_INFO_BUFFER(info);
    GstMemory *mem = gst_buffer_peek_memory(buf, 0);

    if (gst_is_dmabuf_memory(mem)) {
        gint fd = gst_dmabuf_memory_get_fd(mem);
        gsize size = gst_memory_get_sizes(mem, NULL, NULL);
        g_print("DMA-BUF: fd=%d, size=%zu, pts=%" GST_TIME_FORMAT "\n",
                fd, size, GST_TIME_ARGS(GST_BUFFER_PTS(buf)));
    } else {
        g_print("Uyarı: Buffer DMA-BUF değil — kopya gerekecek!\n");
    }
    return GST_PAD_PROBE_OK;
}

int main(int argc, char *argv[])
{
    GstElement *pipeline, *v4l2src, *enc, *sink;
    GstPad     *pad;

    gst_init(&argc, &argv);

    pipeline = gst_pipeline_new("zerocopy");
    v4l2src  = gst_element_factory_make("v4l2src",      "src");
    enc      = gst_element_factory_make("v4l2h264enc",  "enc");
    sink     = gst_element_factory_make("filesink",     "sink");

    g_object_set(v4l2src, "device", "/dev/video0",
                          "io-mode", 4 /* DMABUF */, NULL);
    g_object_set(sink, "location", "out.h264", NULL);

    gst_bin_add_many(GST_BIN(pipeline), v4l2src, enc, sink, NULL);

    /* Caps filter: NV12 formatı encoder için */
    GstCaps *caps = gst_caps_from_string(
        "video/x-raw,format=NV12,width=1920,height=1080,framerate=30/1");
    gst_element_link_filtered(v4l2src, enc, caps);
    gst_caps_unref(caps);
    gst_element_link(enc, sink);

    /* v4l2src src pad'ine probe ekle — DMA-BUF kontrolü */
    pad = gst_element_get_static_pad(v4l2src, "src");
    gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER, dmabuf_probe, NULL, NULL);
    gst_object_unref(pad);

    gst_element_set_state(pipeline, GST_STATE_PLAYING);

    GMainLoop *loop = g_main_loop_new(NULL, FALSE);
    g_main_loop_run(loop);

    gst_element_set_state(pipeline, GST_STATE_NULL);
    gst_object_unref(pipeline);
    return 0;
}

06 GstVideoInfo ve format negotiation

Hardware encoder/decoder'lar belirli piksel formatlarını destekler. GstVideoInfo API ile format detaylarını sorgulamak ve caps negotiation'ı doğru yönlendirmek gerekir.

Donanım formatları

NV12
Y plane tam çözünürlük + interleaved UV plane yarım çözünürlük. Çoğu hardware encoder'ın tercih ettiği format. Her pixel 1.5 byte.
I420 (YUV420P)
Y + U + V ayrı düzlemler, UV yarım çözünürlük. Software encoder'ların tercihi. NV12'ye göre benzer boyut, farklı layout.
P010 (10-bit)
NV12'nin 10-bit versiyonu. Her komponent 10-bit (2 byte). HEVC Main10 ve HDR encode için gerekli.
YUYV (YUY2)
4:2:2 packed format. USB kamera çıkışı. Her pixel 2 byte. Hardware encoder öncesi dönüşüm gerekir.

GstVideoInfo C API

video_info_example.c
#include <gst/video/video.h>

void print_video_info(GstCaps *caps)
{
    GstVideoInfo info;

    if (!gst_video_info_from_caps(&info, caps)) {
        g_print("Caps'ten video info alınamadı.\n");
        return;
    }

    g_print("Format    : %s\n", gst_video_format_to_string(info.finfo->format));
    g_print("Çözünürlük: %dx%d\n", info.width, info.height);
    g_print("FPS       : %d/%d\n", info.fps_n, info.fps_d);
    g_print("Stride[0] : %d byte\n", info.stride[0]);
    g_print("Offset[0] : %zu\n", info.offset[0]);
    g_print("Toplam    : %zu byte/frame\n", info.size);

    /* NV12 için Y ve UV plane ayrıntıları */
    if (info.finfo->format == GST_VIDEO_FORMAT_NV12) {
        g_print("Y  plane stride : %d\n", info.stride[0]);
        g_print("UV plane stride : %d\n", info.stride[1]);
        g_print("UV plane offset : %zu\n", info.offset[1]);
    }
}

/* Caps negotiation için yardımcı */
GstCaps* make_hw_caps(gint w, gint h, gint fps_n, gint fps_d)
{
    return gst_caps_new_simple("video/x-raw",
        "format",    G_TYPE_STRING,  "NV12",
        "width",     G_TYPE_INT,     w,
        "height",    G_TYPE_INT,     h,
        "framerate", GST_TYPE_FRACTION, fps_n, fps_d,
        NULL);
}

07 Benchmark metodolojisi

Donanım ve yazılım encode'u karşılaştırmak için tekrarlanabilir ölçüm yöntemi gerekir. CPU kullanımı, termal performans, gerçek bitrate ve kalite metrikleri kayıt altına alınmalıdır.

CPU kullanımı ölçümü

bash — CPU benchmark
# Yöntem 1: top ile anlık izleme
gst-launch-1.0 -e \
  videotestsrc num-buffers=600 ! \
  video/x-raw,format=I420,width=1920,height=1080,framerate=30/1 ! \
  x264enc speed-preset=ultrafast ! filesink location=/dev/null &
PID=$!
top -b -n 20 -p $PID | grep gst-launch
wait $PID

# Yöntem 2: /usr/bin/time ile toplam CPU
/usr/bin/time -v gst-launch-1.0 \
  videotestsrc num-buffers=300 ! \
  videoconvert ! x264enc ! filesink location=/dev/null 2>&1 | \
  grep "Percent of CPU"

# Yöntem 3: pidstat (sysstat)
pidstat -u 1 -G gst-launch &
PIDSTAT=$!
gst-launch-1.0 videotestsrc num-buffers=300 ! \
  videoconvert ! x264enc speed-preset=ultrafast ! filesink location=/dev/null
kill $PIDSTAT

Termal izleme

bash — thermal monitoring
# Tüm thermal zone sıcaklıkları
watch -n 0.5 'for f in /sys/class/thermal/thermal_zone*/temp; do
  zone=$(basename $(dirname $f))
  type=$(cat $(dirname $f)/type)
  temp=$(cat $f)
  printf "%-20s: %d.%d°C\n" "$type" "$((temp/1000))" "$((temp%1000/100))"
done'

# Frekans kısıtlaması izle (i.MX8)
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq

# Encode sırasında sıcaklık logu al
(while true; do
  date +%s
  cat /sys/class/thermal/thermal_zone0/temp
  sleep 1
done) > /tmp/temp_log.txt &
TEMP_PID=$!
gst-launch-1.0 -e videotestsrc num-buffers=1800 ! \
  videoconvert ! x264enc ! filesink location=/dev/null
kill $TEMP_PID

PSNR/SSIM kalite ölçümü

bash — kalite metrikleri
# Orijinal ve encode edilmiş video PSNR karşılaştırması
ffmpeg -i original.yuv -i encoded.h264 \
  -lavfi psnr=psnr.log -f null /dev/null 2>&1 | grep PSNR

# GStreamer ile PSNR (ssim element)
gst-launch-1.0 \
  filesrc location=original.y4m ! y4mdec ! tee name=t \
  t. ! queue ! identity name=ref ! fakesink \
  t. ! queue ! x264enc bitrate=2000 ! avdec_h264 ! \
     videomixer name=mix ! \
     fakesink \
  ref. ! mix.

08 Pratik: i.MX8MP üzerinde 1080p@30 H.264 encode CPU karşılaştırma

NXP i.MX8M Plus üzerinde yazılım (x264enc) ve donanım (v4l2h264enc VPU) encode'u karşılaştıran kapsamlı benchmark senaryosu.

Test ortamı

Parametre
Değer
Platform
NXP i.MX8M Plus EVK
CPU
Cortex-A53 @ 1.8GHz (4 core)
VPU
Hantro G1/H1 (H.264/H.265)
OS
Yocto kirkstone, kernel 5.15
Test sinyal
videotestsrc 1920x1080@30fps NV12
Süre
60 saniye (1800 frame)

Benchmark script'i

bench_encode.sh
#!/bin/bash
# i.MX8MP encode benchmark

LOG=/tmp/bench_result.txt
echo "i.MX8MP Encode Benchmark $(date)" > $LOG

run_bench() {
    local name="$1"
    local pipeline="$2"
    local frames=1800

    echo "--- $name ---" | tee -a $LOG

    # CPU sıcaklığı başlangıç
    TEMP_START=$(cat /sys/class/thermal/thermal_zone0/temp)

    # Encode + zaman + CPU ölçümü
    START_TIME=$(date +%s%N)
    /usr/bin/time -f "CPU: %P, MaxRSS: %M kB" \
        gst-launch-1.0 -q \
          videotestsrc num-buffers=$frames is-live=false ! \
          "video/x-raw,format=NV12,width=1920,height=1080,framerate=30/1" ! \
          $pipeline filesink location=/dev/null 2>> $LOG
    END_TIME=$(date +%s%N)

    # Süre hesapla
    DURATION=$(( (END_TIME - START_TIME) / 1000000 ))
    FPS=$(echo "scale=1; $frames * 1000 / $DURATION" | bc)

    TEMP_END=$(cat /sys/class/thermal/thermal_zone0/temp)

    echo "  Süre   : ${DURATION}ms" | tee -a $LOG
    echo "  FPS    : ${FPS}" | tee -a $LOG
    echo "  Temp   : $((TEMP_START/1000))°C → $((TEMP_END/1000))°C" | tee -a $LOG
    echo "" | tee -a $LOG
}

# Test 1: Yazılım encode (x264enc ultrafast)
run_bench "Software x264enc (ultrafast)" \
    "x264enc speed-preset=ultrafast tune=zerolatency bitrate=4000 ! h264parse !"

# Test 2: Yazılım encode (x264enc fast)
run_bench "Software x264enc (fast)" \
    "x264enc speed-preset=fast bitrate=4000 ! h264parse !"

# Test 3: Donanım encode (v4l2h264enc)
run_bench "Hardware v4l2h264enc" \
    "v4l2h264enc extra-controls=controls,h264_profile=4 ! h264parse !"

echo "Benchmark tamamlandı. Sonuçlar: $LOG"

Beklenen sonuçlar

Encoder
FPS
CPU Kullanımı
Sıcaklık Artışı
x264enc ultrafast
28-32
~92%
+25°C
x264enc fast
15-20
~98%
+35°C
v4l2h264enc (VPU)
30+ (gerçek zamanlı)
~4-6%
+3°C
SONUÇ

i.MX8MP VPU, 1080p@30 encode'u CPU'nun sadece %5'ini kullanarak gerçek zamanlı gerçekleştirir. Yazılım encode ise sınırı zorlar ve termal kısıtlamayla gerçek zamanlılık kaybedilir. Üretim sistemlerinde donanım encoder zorunlu, yazılım encoder sadece yedek veya kalite test amaçlı kullanılmalıdır.