bench: add videoscale GstBin path (mirrors _create_appsink, --noscale flag)
This commit is contained in:
@@ -91,15 +91,6 @@ for dev in _HW_VPU_DEVICES:
|
||||
if not hw_decoders:
|
||||
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 = Gst.ElementFactory.make("playbin", "player")
|
||||
@@ -107,14 +98,59 @@ if pipeline is None:
|
||||
print("[ERR] playbin unavailable — install gst-plugins-base")
|
||||
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.set_property("emit-signals", True)
|
||||
appsink.set_property("sync", True) # keep A/V sync on
|
||||
appsink.set_property("max-buffers", 2)
|
||||
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)
|
||||
|
||||
# Disable subtitles / visualisations, keep audio+video (same flags as app).
|
||||
@@ -302,7 +338,9 @@ with stats.lock:
|
||||
fmt = stats.fmt
|
||||
w, h = stats.width, stats.height
|
||||
|
||||
scale_active = video_sink is not appsink
|
||||
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" Decoder : {'HW (' + ', '.join(hw_decoders) + ')' if hw_decoders else 'SW (avdec_*)'}")
|
||||
print(f" Total frames decoded : {total} (excl. {WARMUP_FRAMES} warmup)")
|
||||
|
||||
Reference in New Issue
Block a user