Browse Source

bench: add videoscale GstBin path (mirrors _create_appsink, --noscale flag)

main
Matteo Benedetto 1 week ago
parent
commit
435bd51bbe
  1. 60
      tests/benchmark_nv12_decode.py

60
tests/benchmark_nv12_decode.py

@ -91,15 +91,6 @@ for dev in _HW_VPU_DEVICES:
if not hw_decoders: if not hw_decoders:
print("[SW] No VPU device or no gst-mpp plugin — using software decode") print("[SW] No VPU device or no gst-mpp plugin — using software decode")
# ── Caps: prefer NV12 when HW decode available, same as app ─────────────────
if hw_decoders:
caps_str = "video/x-raw,format=NV12;video/x-raw,format=BGRA"
else:
caps_str = "video/x-raw,format=BGRA"
print(f"[caps] appsink caps: {caps_str}")
# ── Pipeline ──────────────────────────────────────────────────────────────── # ── Pipeline ────────────────────────────────────────────────────────────────
pipeline = Gst.ElementFactory.make("playbin", "player") pipeline = Gst.ElementFactory.make("playbin", "player")
@ -107,14 +98,59 @@ if pipeline is None:
print("[ERR] playbin unavailable — install gst-plugins-base") print("[ERR] playbin unavailable — install gst-plugins-base")
sys.exit(1) sys.exit(1)
# Target display size — same default as the app (R36S screen is 640×480).
SCALE_W, SCALE_H = 640, 480
appsink = Gst.ElementFactory.make("appsink", "vsink") appsink = Gst.ElementFactory.make("appsink", "vsink")
appsink.set_property("emit-signals", True) appsink.set_property("emit-signals", True)
appsink.set_property("sync", True) # keep A/V sync on appsink.set_property("sync", True) # keep A/V sync on
appsink.set_property("max-buffers", 2) appsink.set_property("max-buffers", 2)
appsink.set_property("drop", True) appsink.set_property("drop", True)
appsink.set_property("caps", Gst.Caps.from_string(caps_str))
pipeline.set_property("video-sink", appsink) # video_sink is what we hand to playbin. For HW decode we mirror _create_appsink()
# from the app: wrap videoscale → capsfilter(NV12,640×480) → appsink in a GstBin
# so the Python callback receives 460 KB per frame instead of 3.1 MB (6.7× smaller).
# Pass --noscale to disable this and benchmark the unscaled path.
video_sink = appsink
if hw_decoders and "--noscale" not in sys.argv:
scale_el = Gst.ElementFactory.make("videoscale", "vscale")
cfilt_el = Gst.ElementFactory.make("capsfilter", "vcaps")
if scale_el is not None and cfilt_el is not None:
cfilt_el.set_property(
"caps",
Gst.Caps.from_string(
f"video/x-raw,format=NV12,width={SCALE_W},height={SCALE_H}"
),
)
bin_ = Gst.Bin.new("vscale-bin")
bin_.add(scale_el)
bin_.add(cfilt_el)
bin_.add(appsink)
scale_el.link(cfilt_el)
cfilt_el.link(appsink)
sink_pad = scale_el.get_static_pad("sink")
ghost = Gst.GhostPad.new("sink", sink_pad)
ghost.set_active(True)
bin_.add_pad(ghost)
video_sink = bin_
print(f"[scale] videoscale → {SCALE_W}×{SCALE_H} NV12 (mirrors app _create_appsink)")
else:
print("[scale] videoscale element unavailable — falling back to unscaled NV12")
appsink.set_property(
"caps", Gst.Caps.from_string("video/x-raw,format=NV12;video/x-raw,format=BGRA")
)
elif hw_decoders:
print(f"[scale] --noscale: unscaled NV12 ({SCALE_W}×{SCALE_H} disabled)")
appsink.set_property(
"caps", Gst.Caps.from_string("video/x-raw,format=NV12;video/x-raw,format=BGRA")
)
else:
appsink.set_property("caps", Gst.Caps.from_string("video/x-raw,format=BGRA"))
print(f"[caps] video-sink: {'GstBin(videoscale+capsfilter+appsink)' if video_sink is not appsink else 'appsink'}")
pipeline.set_property("video-sink", video_sink)
pipeline.set_property("uri", url) pipeline.set_property("uri", url)
# Disable subtitles / visualisations, keep audio+video (same flags as app). # Disable subtitles / visualisations, keep audio+video (same flags as app).
@ -302,7 +338,9 @@ with stats.lock:
fmt = stats.fmt fmt = stats.fmt
w, h = stats.width, stats.height w, h = stats.width, stats.height
scale_active = video_sink is not appsink
print(f" URL : {url}") print(f" URL : {url}")
print(f" Scale : {'videoscale → %d×%d NV12' % (SCALE_W, SCALE_H) if scale_active else 'none (--noscale or SW)'}")
print(f" Format : {fmt} {w}x{h}") print(f" Format : {fmt} {w}x{h}")
print(f" Decoder : {'HW (' + ', '.join(hw_decoders) + ')' if hw_decoders else 'SW (avdec_*)'}") print(f" Decoder : {'HW (' + ', '.join(hw_decoders) + ')' if hw_decoders else 'SW (avdec_*)'}")
print(f" Total frames decoded : {total} (excl. {WARMUP_FRAMES} warmup)") print(f" Total frames decoded : {total} (excl. {WARMUP_FRAMES} warmup)")

Loading…
Cancel
Save