player,bench: add queue+nearest-neighbour before videoscale to prevent pipeline stalls

This commit is contained in:
Matteo Benedetto
2026-03-24 10:49:14 +01:00
parent 435bd51bbe
commit 65665f4cff
2 changed files with 49 additions and 19 deletions
+14 -4
View File
@@ -114,9 +114,17 @@ appsink.set_property("drop", True)
video_sink = appsink
if hw_decoders and "--noscale" not in sys.argv:
queue_el = Gst.ElementFactory.make("queue", "vqueue")
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:
if scale_el is not None and cfilt_el is not None and queue_el is not None:
# nearest-neighbour: reads ~1/7 of source pixels (strided), far cheaper
# than bilinear which reads all adjacent pixels for each output sample.
scale_el.set_property("method", 0)
# queue decouples mppvideodec from the scale thread so the decoder is
# never stalled waiting for software scaling to finish.
queue_el.set_property("max-size-buffers", 4)
queue_el.set_property("leaky", 2) # drop oldest when full → keep latest
cfilt_el.set_property(
"caps",
Gst.Caps.from_string(
@@ -124,19 +132,21 @@ if hw_decoders and "--noscale" not in sys.argv:
),
)
bin_ = Gst.Bin.new("vscale-bin")
bin_.add(queue_el)
bin_.add(scale_el)
bin_.add(cfilt_el)
bin_.add(appsink)
queue_el.link(scale_el)
scale_el.link(cfilt_el)
cfilt_el.link(appsink)
sink_pad = scale_el.get_static_pad("sink")
sink_pad = queue_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)")
print(f"[scale] queue → videoscale(nearest){SCALE_W}×{SCALE_H} NV12")
else:
print("[scale] videoscale element unavailable — falling back to unscaled NV12")
print("[scale] queue/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")
)