diff --git a/src/r36s_dlna_browser/player/gstreamer_backend.py b/src/r36s_dlna_browser/player/gstreamer_backend.py index 110ca5d..ff2aef9 100644 --- a/src/r36s_dlna_browser/player/gstreamer_backend.py +++ b/src/r36s_dlna_browser/player/gstreamer_backend.py @@ -461,13 +461,18 @@ class GStreamerBackend(PlayerBackend): # nearest-neighbour: accesses only the source pixels needed for each # output sample (strided reads), skipping ~56% of source rows entirely. - # Height is unconstrained (range 2–2160) so GStreamer picks whatever - # height preserves the source aspect ratio for the chosen width. + # Height is intentionally OMITTED from the caps so GStreamer computes it + # from the source's display aspect ratio (DAR). Specifying a height + # range like (int)[2,2160] is wrong — GStreamer's caps fixation picks the + # nearest compatible value (the source height itself), bypassing scaling. + # Without any height cap, videoscale scales width to scale_w and derives + # the height that preserves the DAR; NV12's even-dimension requirement is + # satisfied automatically by GStreamer's caps fixation rounding. scale.set_property("method", 0) capsfilter.set_property( "caps", self._gst.Caps.from_string( - f"video/x-raw,format=NV12,width={scale_w},height=(int)[2,2160]" + f"video/x-raw,format=NV12,width={scale_w}" ), )