Skip to content

feat(libSceVideodec2): decode HEVC and VP9 - #1931

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
johnmaia:feat/videodec2-hevc-vp9
Oct 9, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
johnmaia:feat/videodec2-hevc-vp9

Conversation

@johnmaia

@johnmaia johnmaia commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

What

sceVideodec2CreateDecoder accepted only H.264 (codecType == 1). EVO-PLAYER PPSA99039 v0.11.0 creates resident decoders at start-up for AVC, HEVC and VP9, and with its default build for HEVC Main10 and VP9 Profile 2 too. With #1916 and the PRs for its earlier stops, it stopped at the HEVC one:

EVO boot: INFO  EVO vdec native: HEVC config codec_type=974921 profile=1 max_level=123 max=1920x1088 dpb=auto depth=4
  what():  Videodec2: unsupported codec
  • Codec types: 974921 (HEVC) and 2382845 (VP9) open FFmpeg's HEVC and VP9 decoders. Both are already in the bundled FFmpeg build. The tags are SharpProspero's Videodec2CodecType (Interop/Video/Videodec2.cs: Avc = 1, Hevc = 974921, Vp9 = 2382845). EVO-PLAYER's media/include/sce/sce_videodec2.h gives the same values and records sceVideodec2CreateDecoder accepting them on hardware. Any other value still throws unsupported codec.
  • Input: HEVC access units go through the existing length-prefixed to Annex B conversion, as H.264 does. VP9 frames are passed through unchanged.
  • Output: 8-bit NV12, as for H.264.
    • A decoder for HEVC Main10 or VP9 Profile 2 is created, since EVO creates both at start-up.
    • A decoded frame deeper than 8 bits throws instead of being converted silently, because the console's 10-bit output layout is unknown.
    • QueryDecoderMemoryInfo reports the 8-bit frame size for those decoders.
  • Picture info: sceVideodec2GetPictureInfo and sceVideodec2GetAvcPictureInfo throw for HEVC and VP9 pictures instead of writing the AVC layout; SharpProspero gives them separate SceVideodec2HevcPictureInfo and SceVideodec2Vp9PictureInfo layouts. GetHevcPictureInfo and GetVp9PictureInfo are not exported. EVO calls none of these.
  • All of the above is recorded in TechnicalDebt.

Tested

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • AI-assisted: yes

🤖 Generated with Claude Code

https://claude.ai/code/session_01DwFnKjMxmwGDWiuYYf1v4D

EVO-PLAYER (PPSA99039) creates resident AVC, HEVC and VP9 decoders at
start-up, and stopped at "Videodec2: unsupported codec" on the HEVC one.
Codec types 974921 (HEVC) and 2382845 (VP9) now open FFmpeg's HEVC and
VP9 decoders. HEVC input goes through the same Annex B conversion as
H.264 and VP9 frames are passed through; output stays 8-bit NV12, and a
frame deeper than 8 bits throws. Picture info throws for HEVC and VP9,
whose layouts differ from the AVC one.

Assisted by Claude Code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DwFnKjMxmwGDWiuYYf1v4D

@klosixgaming-arch klosixgaming-arch left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed against the repo's bar. This is a clean, well-scoped extension and I can approve it.

What holds up:

  • CodecId centralises the codec dispatch and throws on any unknown tag, so no silent fallback. The create path calls CodecId(config->codecType) before allocating, which rejects bad tags early rather than after OpenCodec.
  • 10-bit guard is the right call: av_pix_fmt_desc_get(...)->comp[0].depth > 8 throwing instead of silently converting is exactly what the repo wants for unknown console output layouts, and it's debt-documented.
  • GetPictureInfo throws for HEVC/VP9 pictures rather than writing the AVC layout — correct, and the debt entry names the real separate layouts.
  • Test coverage is real, not symbol-checks: 6-frame HEVC clip with B-frame display/decode ordering, an independent FFmpeg 9.0.2 reference hash comparison of every NV12 frame (12 distinct hashes), length-prefixed vs Annex-B for HEVC, Main10/Profile-2 create-plus-throw, and a negative control (main fails at unsupported codec). Good.

Notes (non-blocking):

  1. The VP9 branch writes into decoder.annexB then points unit at it, whereas H.264/HEVC go through ToAnnexB. Confirm annexB isn't also holding an H.264 stream for a decoder that is both (it isn't — one codec per decoder) so the reuse is safe; just flagging the shared member.
  2. QueryDecoderMemoryInfo reports the 8-bit size even for Main10/VP9-P2 decoders that then throw on decode. That's debt-documented and acceptable, but a title probing memory for a 10-bit buffer will get an undersized value — worth a sentence in the debt entry that the query also lies in that case (it currently only says the frame throws).

Written with AI assistance.

@johnmaia

johnmaia commented Oct 9, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @klosixgaming-arch. On note 2: the debt entry already covers the query. It ends with "a decoder for HEVC Main10 or VP9 Profile 2 is created, but a frame deeper than 8 bits throws, since the console's 10-bit output layout is unknown, and QueryDecoderMemoryInfo reports the 8-bit frame size for it". On note 1: right, each decoder has one codec, so the shared annexB buffer only ever holds that codec's data.

@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.

Pull request Conflicting files (lines on main) Same exports Same new files
#1819 docs/dev/TechnicalDebt.md L355
#1831 docs/dev/TechnicalDebt.md L355
#1969 docs/dev/TechnicalDebt.md L355
#2052 docs/dev/TechnicalDebt.md L355
#2053 docs/dev/TechnicalDebt.md L355
#2054 docs/dev/TechnicalDebt.md L355

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants