Repository navigation
Conversation
…here VideoToolbox has none Fire Emblem Fortune's Weave's 91 movies are AV1, and VideoToolbox decodes AV1 only on Apple M3 and A17 Pro and later; the supported Macs and iPads go back to M1. dav1d is VideoLAN's AV1 decoder (BSD 2-Clause), with NEON assembly for arm64. This adds release 1.5.4 (upstream 54706fc), unmodified, as the host's other third-party code is shipped, so that nothing is fetched at build time. The next commit builds and uses it. Only what an arm64 build needs is kept: the public headers, the C sources of src/, and src/arm/ with the 64-bit assembly; the other architectures, tools, tests and meson files are left out. config/ holds config.h as meson writes it for an arm64 Apple target, verbatim, the version header of a release archive build and one wrapper per template and bit depth (config/tmpl/), where meson passes -DBITDEPTH per object, so that a project with one set of defines for all its files builds them too. dav1d/README.md lists the files compiled and how to check the configuration against a new release; dm/third_party/README.md has its row. Checked: the 130 files are byte-identical to the 1.5.4 tag (54706fc). config.h is the one meson 1.11.2 writes on this Mac, and an arm64-apple-ios cross build writes the same file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
VideoToolbox decodes AV1 only in hardware, on Apple M3 and A17 Pro and later. On the other Macs and iPads the host gave black pictures with a red line. That was meant to let a game go on past its movies, but Fire Emblem Fortune's Weave's movie module aborts on a decoder that does not initialize (movie::detail::InitializeDecoderByTransferMemory, subsdk2+0xf9b4), so on those chips the game could not get past its movies. hle_movie_av1.c gets dav1d (vendored in the previous commit) as a second backend behind the same interface. It is used on chips with no hardware AV1 decoder, for a stream VideoToolbox refuses (from that temporal unit on), and with DM_AV1_DAV1D=1 on any chip. Its planar pictures are handed over as the NV12 the interface gives. 10- and 12-bit streams are shifted to 8 bits, and a stream with no colour matrix gets BT.601 below 720 lines and BT.709 from there, as VideoToolbox gives its pictures. hle_codec_video.c drops the black-picture path, names the backend in its log line, and keeps a full-range stream's range. dm/host/Makefile builds dav1d into gen/dav1d/libdav1d.a and links it, the host tests link it for t_codec_video, and the NSP script's Mac host build key includes it. The iOS build takes it from the Makefile's compile lines. Checked: - t_codec_video decodes a 64x64 AV1 key frame (SVT-AV1) on VideoToolbox and on dav1d, and reads both back as the same NV12 (AddressSanitizer and UBSan). The rest of the host tests pass. - The host builds, and the iOS compile check passes (258 files, dav1d's among them). - With DM_AV1_DAV1D=1 on an M3 Pro, Fire Emblem Fortune's Weave's opening movie (2560x1440) decodes through dav1d with no red line. Its pictures were not seen on screen, because the game's shader libraries for main's chain version are not built here. - On seedds#957's branch, the two backends gave the same pictures, bit for bit, over the opening's first 600, and a tester's M1 Pro played the first two movies through dav1d (seedds#927). movies.md, the game's note, development.md and env_switches.tsv describe it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seedds
added a commit
that referenced
this pull request
Nov 2, 2026
…here VideoToolbox has none Fire Emblem Fortune's Weave's movies are AV1, and VideoToolbox decodes AV1 only on Apple M3 and A17 Pro and later; the supported Macs and iPads go back to M1. dav1d is VideoLAN's AV1 decoder (BSD 2-Clause), with NEON assembly for arm64. This adds release 1.5.4 (upstream 54706fc), unmodified, as the host's other third-party code is shipped, so that nothing is fetched at build time. The next commit builds and uses it. Only what an arm64 build needs is kept: the public headers, the C sources of src/, and src/arm/ with the 64-bit assembly; the other architectures, tools, tests and meson files are left out. config/ holds config.h as meson writes it for an arm64 Apple target, verbatim, the version header of a release archive build and one wrapper per template and bit depth (config/tmpl/), where meson passes -DBITDEPTH per object, so that a project with one set of defines for all its files builds them too. dav1d/README.md lists the files compiled and how to check the configuration against a new release. Checked: the 130 upstream files are byte-identical to VideoLAN's 1.5.4 archive, compared here against a fresh download. The other 29 are the project's own: README.md, config.h, the version header and 26 wrappers. From PR #976. Co-authored-by: James <12531452+capibawa@users.noreply.github.com>
seedds
added a commit
that referenced
this pull request
Nov 2, 2026
VideoToolbox decodes AV1 only in hardware, on Apple M3 and A17 Pro and later. On M1 and M2 the host gave black pictures with a red line. Here a session with the hardware decoder forbidden opens for H.264 and not for AV1, so VideoToolbox has no software path to fall back on. hle_movie_av1.c gets dav1d (vendored in the previous commit) as a second backend behind the same interface. It is used on chips with no hardware AV1 decoder, for a stream VideoToolbox refuses (from that temporal unit on), and with DM_AV1_DAV1D=1 on any chip. Its planar pictures are handed over as the NV12 the interface gives. 10- and 12-bit streams are shifted to 8 bits, and a stream with no colour matrix gets BT.601 below 720 lines and BT.709 from there, as VideoToolbox gives its pictures. hle_codec_video.c drops the black-picture path, names the backend in its log line, and keeps a full-range stream's range. dm/host/Makefile builds dav1d into gen/dav1d/libdav1d.a and links it, the host tests link it for t_codec_video, and the NSP script's Mac host build key includes it. The iOS build takes the same files from the Makefile's compile lines. Checked: - t_codec_video decodes a 64x64 AV1 key frame (SVT-AV1) on VideoToolbox and on dav1d, and reads both back as the same NV12 (AddressSanitizer and UBSan). - Fire Emblem Fortune's Weave's 82 movies through hle_movie_av1.c, the first 300 pictures of each on an M6: 23,219 pictures with the same size, matrix, range and hashes on both decoders (every 7th row hashed), no stream refused. dav1d ran at about 190 pictures a second with its two task threads. - With DM_AV1_DAV1D=1 and no window on the M6, the game plays the opening's 3,301 pictures, right on screen, and goes on into the prologue with no crash. - An M1 Pro played the first two movies through an earlier version of this code, on #957's branch (#927). This commit has not itself run on a chip without hardware AV1, and iOS has only been compile-checked. Regression, on main plus this work against 54ab7b1: uncertain reach (it includes the clear ordering and the chain change of 0a759de), so 2 games, in quick mode, as each game has at most 5 minutes. Pikmin 4 for its compute shaders, Blasphemous as a small NVN game on another engine, in place of Breath of the Wild, whose translation takes far longer than that. No new red lines, crashes or hangs, and no translated shader changed (Blasphemous's reflections gain only primitive_id 0 and the chain version). Blasphemous's screenshots match, 59.4 to 59.9 fps. Pikmin's quick route has no screenshots or timing window, so only its boot and frame count (2815 to 2817) were compared. Peak memory rose 1.4 % and about 4 % in single runs, not looked into. From PR #976. Co-authored-by: James <12531452+capibawa@users.noreply.github.com>
Owner
|
Thank you. This landed on Changed from your branch:
Checked on an M6, macOS 27.2:
Still unchecked:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What and why
This is split out of #957, as offered in its closing comment. The scope is still open in #927, so this PR is there to show the change concretely: rework or close it according to what's decided there.
VideoToolbox decodes AV1 only in hardware (Apple M3 and A17 Pro and later). On older chips,
maingives black pictures with a red line. But Fire Emblem Fortune's Weave's movie module aborts on a decoder that does not initialize (movie::detail::InitializeDecoderByTransferMemory,subsdk2+0xf9b4), so there is no error path for the game to take.Two commits:
dav1d 1.5.4, vendored unmodified: the arm64 sources and NEON assembly, with meson's
config.hfor an arm64 Apple target and per-bit-depth wrappers.dm/third_party/dav1d/README.mdlists what's compiled. This is about 81,000 lines, all upstream code (BSD 2-Clause), byte-identical to the 1.5.4 tag.dav1d as a second backend in
hle_movie_av1.c, behindmain's interface. It is used:DM_AV1_DAV1D=1, on any chip.Its planar pictures are handed over as NV12. 10- and 12-bit streams are shifted to 8 bits, and a stream with no colour matrix gets BT.601 below 720 lines and BT.709 from there, as VideoToolbox does.
hle_codec_video.cdrops the black-picture path and keeps a full-range stream's range.dm/host/Makefilebuildsgen/dav1d/libdav1d.a, and the iOS build picks it up from the Makefile's compile lines.Checked
make -C dm/host/tests GAME=010015100B514000 run.t_codec_videonow decodes a 64x64 AV1 key frame on VideoToolbox and on dav1d, and reads both back as the same NV12 (AddressSanitizer and UBSan).make -C dm/host GAME=04007EF01F8AE000 dmhostbuilds.dm/ios/tools/compile_check.pypasses (258 files, dav1d's among them).test_docspasses.04007EF01F8AE000, v131072):DM_AV1_DAV1D=1on an M3 Pro, the opening movie (2560x1440) decodes through dav1d with no red line.main's chain version, I took screenshots of the opening movie decoded by dav1d and by VideoToolbox: the same pictures and colours, differing only where smoke moves between frames.regress.py: not run. Only AV1 decoding changes, and no game in the local harness has AV1 movies.Docs
movies.mdentry, the game's note,development.mdandenv_switches.tsv(DM_AV1_DAV1D) describe it;python3 dm/tools/docs_symptoms.pywas run (no change to the index)Related: #927.
🤖 Generated with Claude Code