Skip to content

Media player: non-16:9 video is vertically stretched on the 3D screen (no aspect handling) #949

Description

@towneh

Describe the bug?

Non-16:9 video (e.g. a 1920×800 / 2.40:1 clip) is stretched vertically to fill the fixed 16:9 media-player screen. There's no letterboxing and no aspect correction, so a cinemascope source looks squashed. This is a rendering/geometry behaviour with a code-level root cause (see Additional Context), not a runtime error, so there's no crash or log output to attach.

Steps to Reproduce

  1. Open the MediaPlayerStreaming (or MediaPlayerMultiChannelStreaming) prefab.
  2. Load any source whose aspect isn't 16:9 — e.g. a 1920×800 clip.
  3. Watch the 3D screen: the image fills the whole quad and is vertically stretched.
  4. Optional: select the screen's BasisVideoMaterialOutput in the Inspector at runtime and switch AspectMode to FitInside — it still doesn't letterbox.

The expected behavior

The video keeps its correct proportions on the screen: either letterboxed with black bars on the fixed 16:9 quad, or the screen resized to the source aspect. A 16:9 source should look exactly as it does today (full screen, no bars).

Screenshots

A screenshot of the stretched 1920×800 output can be attached here if useful.

Build Info

Not environment-specific — reproducible on developer and any current build. Diagnosed against developer HEAD; the relevant code is in com.basis.mediaplayer (paths cited below).

Log Files

None. The stretch is a rendering/geometry behaviour and produces no errors or warnings on the Video log tag.

Additional Context

Root cause. The screen is a fixed 16:9 quad (VideoScreen16x9, ~14.464 × 8.136 = 1.778:1, generated by Editor/BasisVideoScreenMeshGenerator.cs), and the material output maps the video onto it with no shape correction:

  • BasisVideoMaterialOutput has an AspectMode, but it defaults to Original (no correction) and applies its result purely as a texture scale/offset (material.SetTextureScale/SetTextureOffset, i.e. _BaseMap_ST, at Runtime/Rendering/BasisVideoMaterialOutput.cs:259-260).
  • The material is stock URP/Unlit (Materials/MediaPlayer.mat), and the output texture is created with TextureWrapMode.Clamp (Runtime/Native/BasisNativeVideoSource.cs:399,423). A texture scale/offset can only crop or zoom within the source; it can't introduce black bars, and clamp smears anything sampled outside [0,1] rather than rendering it black.
  • The FitInside branch in BasisVideoOutputMath.GetAspectUv (:66-80) also returns a scale ≤ 1, so even when it's selected it crops toward the centre rather than fitting-with-bars. Switching AspectMode to FitInside at runtime therefore doesn't letterbox (confirmed in-editor).

So there's no code path today that makes a non-16:9 source display at correct proportions on the 3D screen.

Suggested fix. Two workable approaches, depending on whether the screen should stay a fixed size.

  • A. Letterbox with black bars (screen stays fixed). Invert the FitInside math so the sampled region scales > 1 (leaving room outside [0,1] for the bars), and make out-of-range render black — either a small custom unlit video shader with a border check (any(uv < 0 || uv > 1) outputs black), or TextureWrapMode.Border with a black border colour. A custom shader is the more reliable route across the D3D external-texture and Vulkan RenderTexture paths, and it would also give somewhere to implement the BASIS_PROJ_* (equirect / VR180 / fisheye) keywords, which are currently set in C# but consumed by no shader.
  • B. Fit the quad to the source aspect (screen resizes). Drive the screen mesh's localScale from the decoded width/height (already surfaced as BasisMediaPlayer.VideoSize) so the quad takes the video's shape. No shader or wrap-mode change, works on every backend, no smearing — the trade-off is that the screen's in-world footprint changes with content.

I'd lean towards A with a small dedicated video shader (a fixed screen is nicer in VR, and it revives the projection keywords), but B is the lighter change if a resizing screen is acceptable. Happy to put up a PR for whichever you'd prefer.

For context, #948 fixes a separate, narrower Windows-only issue (a thin top strip from the coded macroblock pad); this one is the aspect/stretch behaviour and is unrelated.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

Fields

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions