Skip to content

Signal frame-packed 3D in H.264 transcodes, and correct the 2011-2012 Bravia profiles - #6330

Merged
SubJunk merged 1 commit into
UniversalMediaServer:mainfrom
danielcamposramos:3d-frame-packing-sei-and-bravia-profiles
Sep 19, 2026
Merged

SubJunk merged 1 commit into
UniversalMediaServer:mainfrom
danielcamposramos:3d-frame-packing-sei-and-bravia-profiles

Conversation

@danielcamposramos

Copy link
Copy Markdown
Contributor

Closes #6329.

Two changes, both from measurements on real hardware: a KDL-46EX725 (2011) and a KDL-46HX855 (2012).

1. Frame-packed 3D is never signalled in the elementary stream

3D TVs of the frame-compatible era auto-engage 3D from the H.264 frame_packing_arrangement SEI (Annex D, payload type 45) carried in the elementary stream. x264 writes it only when asked (frame-packing=N). The container-level stereoscopic tag is a separate signal: it does not survive a remux to MPEG-TS, and in the DVB frame-compatible 3DTV spec (ETSI TS 101 547-2) the in-stream SEI takes precedence over it.

So a 3D transcode currently arrives at those renderers as perfectly correct frame-packed video that they have no way to recognise, and it plays flat.

FFMpegVideo.getVideoTranscodeOptions() now adds -x264-params frame-packing=N on libx264 transcodes whose output is frame-packed:

Output layout frame-packing
sbsl / sbsr / sbs2l / sbs2r 3 (side by side)
abl / abr / ab2l / ab2r 4 (top bottom)
irl / irr 2 (row alternation)
ml / mr (2D output), anaglyph not signalled

The value follows Output3DFormat when the renderer sets one, since that is the layout actually leaving the encoder, and otherwise the source layout. It is skipped when CustomFFmpegOptions already contains -x264-params, and it only applies on the libx264 path (GPU encoders do not take x264 parameters).

This mirrors the equivalent change in HandBrake, PR #8100, merged 16 September 2026.

2. The Bravia profiles transcode things these sets play natively

Measured with a pass-through DLNA server, files byte-exact on the wire, tracks copied without re-encoding:

  • MP4 is played directly. Sony-BraviaEX725.conf had no f:mp4 line at all, so every MP4 was transcoded on a set that advertises http-get:*:video/mp4:* as a wildcard and plays H.264 in MP4 without help.
  • E-AC3 is decoded from MP4, including 7.1, and the set reports it on screen as "Dolby Digital Plus". Transcoding it to AC-3 is a real loss. Worth noting because it is counter-intuitive: the sets' HDMI input does not accept E-AC3 as a bitstream at all, so decoding a file and accepting a bitstream are genuinely different capabilities here.
  • DTS is silent in MP4 while the video plays, which the existing "DTS is not supported" note now states precisely.
  • Matroska is not advertised at all, so an MKV is filtered out of the browse listing rather than merely failing to play. Recorded as a comment so the next person does not try to add it.

Changed: Sony-BraviaEX725.conf, Sony-BraviaHX.conf, Sony-BraviaHX75.conf.

Scope, stated honestly

The two sets above are what I measured. The profile changes are applied to the configs whose UpnpDetailsSearch matches those same chassis generations, because Sony shipped one software platform per chassis generation rather than per model — one application catalog and one firmware line served every set in a generation, which is documented here. If you would rather keep the changes to the exact models measured, say so and I will narrow them.

I have not extended this to Sony-BraviaEX.conf, Sony-BraviaNX70x.conf or Sony-BraviaNX800.conf: those cover older models I have no hardware for, and adding MP4 support to a set I cannot test seemed the wrong side of the line.

Testing

The 3D signalling half is verified end to end on both sets, through two independent servers (Serviio and Kodi's UPnP, which never transcodes): an MP4 carrying the SEI switches the TV into 3D automatically, the identical file with the SEI stripped — a difference of 791 bytes, picture data untouched — plays flat, and a Matroska carrying only the container StereoMode tag is not listed at all. Method and files: https://github.com/danielcamposramos/sony-bravia-linux/blob/main/docs/3d-signalling-ecosystem.md

I could not run the UMS test suite locally (no Maven, and Java 25 here against the project's 17), so the Java change has had a syntax check only and needs CI. It is a small, isolated addition to one options block, but please treat it as untested by me.

Renderers that auto-detect 3D read the frame_packing_arrangement SEI in
the H.264 elementary stream (Annex D, payload type 45). x264 writes it
only when asked, and container-level stereoscopic tags are a separate
signal that does not survive a remux to MPEG-TS, so a 3D transcode
currently reaches those renderers as correct frame-packed video they
have no way to recognise, and plays flat.

FFMpegVideo now passes -x264-params frame-packing=N on libx264
transcodes whose output is frame-packed, mapping the output layout
(Output3DFormat when the renderer sets one, otherwise the source
layout) to the H.264 arrangement: side-by-side 3, top-bottom 4,
row-interleaved 2. Anaglyph and 2D output are left alone, and an
existing -x264-params in CustomFFmpegOptions is not overridden.

The Bravia EX725/HX profiles are corrected from measurements on a
KDL-46EX725 and a KDL-46HX855: MP4 is played directly (the EX725
profile had no MP4 line at all, so every MP4 was transcoded), and
E-AC3 is decoded from MP4 up to 7.1 and reported on screen as Dolby
Digital Plus, so transcoding it is a needless loss. The notes also
record that DTS is silent in MP4 and that Matroska is not advertised
by these sets at all, which filters MKVs out of the browse listing
rather than merely failing to play them.
@danielcamposramos

Copy link
Copy Markdown
Contributor Author

For triage, I searched this repo for anything else either half of the PR would close, so you do not have to.

Closed by this PR: #6329 only. That is the honest answer — I searched open issues for 3D, stereoscopic, frame packing, SBS, side by side, Output3DFormat, anaglyph, Bravia, Sony, E-AC3 and Dolby Digital Plus, and nothing else open is about either the in-stream 3D signal or these sets' audio handling.

Not closed by this PR, listed so they are not conflated with it:

Wider context, if it is useful. This is a signalling gap that runs across the whole chain rather than a UMS quirk, and the same finding has been taken to the other projects in it. HandBrake merged the equivalent encoder change (PR #8100, 16 September 2026, closing their #5826). Reports are open at FFmpeg (#24530, #24531), mpv (#18489 with PR #18490), MKVToolNix (#6309, for the container side), Jellyfin (PR #18060 comment), Gerbera (#3937) and Kodi (#29337).

Each project owns a different link: the encoder writes the SEI, the muxer keeps or drops the container tag, the server decides whether to remux, and the TV reads only the SEI. UMS sits at the point where a correct file can still lose the signal, which is why it is worth having here.

@danielcamposramos

Copy link
Copy Markdown
Contributor Author

Following up on the triage above with a deeper sweep, since the first pass only covered 3D wording. I also searched the open issues for Dolby, AC3, E-AC3, passthrough, 5.1, transcode audio, Bravia and KDL.

Still only #6329 is closed by this PR. Nothing else open turns on the frame-packing SEI or on these sets' audio handling.

Same family, different mechanism — not closed by this PR, but worth reading alongside it:

  • UMS trancode instead muxe codec with ffmpeg. #1775 — UMS transcodes video and audio when only the audio is unsupported (reported against Chromecast). Same underlying waste as the E-AC3 half of this PR, where the fix here is simply to stop declaring a codec unsupported when the device decodes it. That issue needs audio-only transcoding logic, which this PR does not touch.
  • Level parameter in supported formats #5974 — no way to express per-resolution level limits in a profile. Adjacent in spirit: both are about a profile describing a device accurately enough that UMS stops guessing. The MP4 line I added leans on H.264 level support that today can only be stated coarsely.

Ruled out, so they are not conflated:

One observation you may want, offered as a hypothesis rather than a measurement. The E-AC3 finding is probably not specific to these two sets: a TV of that era can decode Dolby Digital Plus from a file while its HDMI input refuses the same codec as a bitstream, and those are separate capabilities that a single profile line tends to blur. If other profiles in the repo were written from HDMI specs rather than from playback tests, they may under-declare in the same way. I have only measured the two Sony sets I own, so I am not going to touch anyone else's profile on a guess — but if you want the same method applied to a specific renderer and someone can run the files, I am happy to write up the test set.

@SubJunk

SubJunk commented Sep 19, 2026

Copy link
Copy Markdown
Member

If other profiles in the repo were written from HDMI specs rather than from playback tests, they may under-declare in the same way

Unfortunately this is the reality of our project - we make a first pass at renderer configs based on their manuals, and then it is up to individual people to test and optimize if they want the best experience for their renderer, as you have.

Thanks for the contribution, I will merge it now

@SubJunk
SubJunk merged commit bd032ab into UniversalMediaServer:main Sep 19, 2026
9 checks passed
SubJunk added a commit that referenced this pull request Sep 27, 2026
…salMediaServer into v16

* 'main' of https://github.com/UniversalMediaServer/UniversalMediaServer:
  Vite 7.3.6 (#6353)
  Bump react-router from 7.18.0 to 7.18.2 in /react-client (#6352)
  Audit (#6351)
  Bump the twelvemonkeys group with 16 updates (#6338)
  Bump com.google.guava:guava from 33.6.0-jre to 33.7.1-jre (#6340)
  Fix transcode folder (#6336)
  Fixed endless retries when server is not connected to the internet (#6335)
  Signal frame-packed 3D, and correct the 2011-2012 Bravia profiles (#6330)

# Conflicts:
#	react-client/.yarn/install-state.gz
#	react-client/.yarnrc.yml
#	react-client/package.json
#	react-client/yarn.lock
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Preserve/inject the H.264 frame_packing SEI so frame-packed 3D auto-engages over DLNA

2 participants