Browse Source

fix: omit height from NV12 capsfilter so GStreamer preserves source DAR

A height range like (int)[2,2160] includes the source height (1080),
so GStreamer's caps fixation picked identity for height (no scale) and
only scaled width 1920->720, giving a distorted 720x1080 frame.

Fix: omit height entirely from the capsfilter caps string.
GStreamer then derives the output height from the source's display
aspect ratio for the given width target.  NV12's even-dimension
requirement is satisfied automatically by caps fixation rounding.
main
Matteo Benedetto 1 week ago
parent
commit
0c080bc994
  1. 11
      src/r36s_dlna_browser/player/gstreamer_backend.py

11
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 # nearest-neighbour: accesses only the source pixels needed for each
# output sample (strided reads), skipping ~56% of source rows entirely. # output sample (strided reads), skipping ~56% of source rows entirely.
# Height is unconstrained (range 2–2160) so GStreamer picks whatever # Height is intentionally OMITTED from the caps so GStreamer computes it
# height preserves the source aspect ratio for the chosen width. # 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) scale.set_property("method", 0)
capsfilter.set_property( capsfilter.set_property(
"caps", "caps",
self._gst.Caps.from_string( 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}"
), ),
) )

Loading…
Cancel
Save