Repository navigation
feat(libSceVideodec2): implement H.264 picture info in sceVideodec2GetPictureInfo and sceVideodec2GetAvcPictureInfo - #12633
Merged
adriadam10 merged 1 commit intoOct 29, 2026
Conversation
…tPictureInfo and sceVideodec2GetAvcPictureInfo Fill the 120-byte SceVideodec2AvcPictureInfo for a single owned H.264 picture queried with thisSize 0x78: SPS fields, VUI, pic_struct from the picture-timing SEI and per-unit presence flags, parsed per ITU-T H.264 (08/2021) from the access unit that produced the picture. Layout from SharpProspero Videodec2.cs and shadPS4 videodec2.h. Other accepted sizes, two records and unsupported syntax still throw after the validity clears. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
|
Windows run of this head (
AI-assisted: yes (Claude Code). |
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
sceVideodec2GetPictureInfo(NtXRa3dRzU0) andsceVideodec2GetAvcPictureInfo(kjrLbcyhEiw) now fill the 120-byte (0x78)SceVideodec2AvcPictureInfoof an H.264 picture. Since #10959 removed the 56-byte fill, both getters threwNotImplementedfor an H.264 picture with an accepted destination size. The bot listed both under "went back to stubs" on #10959.Getter behaviour
PictureArguments) is unchanged. Argument errors and the early validity clears still come first.pictureCountis 1, an H.264 decoder owns the frame buffer and the destinationthisSizeis 0x78, the getter copies that picture's record under aGuestArena::HostWriteover the 0x78 bytes. It keeps the caller'sthisSizeand returns 0.codecType.pictureCount2, and records marked unsupported.Parsing in
sceVideodec2DecodesceVideodec2Decodeparses every H.264 unit withVideodec2Avc::Parse_nid_no_patchin the newAvcMetadata.cpp. It mirrorsHevcMetadata.cpp: a bit reader, RBSP extraction and onecatchper NAL, so metadata never stops decoding. Only the first 32 bytes after a slice's NAL header are unescaped.decoder.inputs, keyed by packet pts, as for HEVC.Record fields
isValidis 1.ptsData,dtsDataandattachedDatacome from the unit.idrPictureFlagis set when the unit's slices arenal_unit_type5. It does not come from FFmpeg's key flag.profile_idc,level_idc,constraint_set0..5,pic_width_in_mbs_minus1,pic_height_in_map_units_minus1,frame_mbs_only_flag,frame_cropping_flagand the rawframe_crop_*_offsetin SPS units.num_units_in_tick,time_scaleandfixed_frame_rate_flag.bitstream_restriction_flagandmax_dec_frame_buffering.max_dec_frame_bufferingtakes the E.2.1 inferred value:constraint_set3_flag.level_idc9, or 11 withconstraint_set3_flagfor profiles 66, 77 and 88.pic_struct_present_flagcomes from the VUI.pic_structcomes from the unit's picture-timing SEI (D.1.3).cpb_removal_delayanddpb_output_delay, whose lengths come from that SPS's NAL or VCLhrd_parameters(E.1.2).field_pic_flagandbottom_field_flagcome from the first slice header (7.3.3). They are 0 whenframe_mbs_only_flagis 1.Unsupported cases
These mark the record unsupported: the query throws and decoding continues.
pic_struct_present_flagwithout a picture-timing SEI, orpic_structabove 8.first_mb_in_sliceis 0, or when its PPS id,frame_num, field flags, IDR type ornal_ref_idcbeing zero differ from the first slice's.max_dec_frame_bufferingabove 16.forbidden_zero_bitset, an emulation prevention pattern that 7.4.1 forbids, or a value outside its range.ue(v)values are limited to 32 bits. Every count that drives a loop is bounded:num_ref_frames_in_pic_order_cnt_cycleat most 255 andcpb_cnt_minus1at most 31.Layout, tests and debt
SceVideodec2::AvcPictureInfoinApi.hppbecomes the 120-byte layout. It has the size of the in-treeSceVdecsw::AvcPictureInfoand the same named fields up toframeCropBottomOffsetat 0x44. The fields from 0x48 to 0x74, which that struct keeps asvui[44]and the first byte of its tail padding, take their names and order from SharpProspero, shadPS4 and KytyPS5. Offsetstatic_asserts inAvcMetadata.hppcover 0x2c, 0x35, 0x38, 0x48, 0x4a, 0x55, 0x58, 0x60, 0x67, 0x6f, 0x74 and size 0x78.sizeof(AvcPictureInfo)is now 0x78, an accepted size.testDecode's two 0x811D0101 checks, through both getters on every H.264 picture, become the record checks.testClip(HEVC and VP9 pictures) andtestFailureskeep a 0x38 destination for their size-error checks.GuestHevcMetadata.cppstill checks 0x811D0101 through all four getters.sceVideodec2GetPictureInforeports no frame cropping" is removed.References:
Videodec2.csL244-L400, which gives the field order and meaning ("from the SPS"). Its getter docs at L754-L764 say H.264 fills up to two entries, one per field.videodec2.hL117-L182, withstatic_assert0x78.videoDec2Decoder.hL76-L140, withstatic_assert120.videodec2.cpp(L221-L224, L1302-L1311).sceVideodec2GetPictureInfo(&outputInfo, &pictureInfo, 0, 0)on H.264 pictures withthisSize0x78.scaling_list), 7.3.2.2, 7.3.2.3.1, 7.3.3, 7.4.1, 7.4.1.2.3 and 7.4.1.2.4.sceVideodec2GetPictureInfo'ssar_widthandsar_height, and that idc 1 to 16 give the standard table, 255 gives the explicit pair, and 0, 17 to 254 or a picture without aspect information give 0:0.HevcMetadata.cppL202-L264 (Table E-1 SAR, inferred VUI defaults) and L352-L505 (per-unit presence flags, replacement policy, onecatchper NAL).Where the sources disagree:
videoDec2Decoder.cppL432-L468).aspect_ratio_idcis 255 whenever FFmpeg reports a SAR, and 0 otherwise.frame_mbs_only_flagandvideo_signal_type_present_flagare forced to 1.thisSize0x68 and fills its first 0x68 bytes (libVideoDec2.cppL535-L543).HevcMetadata.cppL277-L306), and its debt entry says crop units are not guessed. This PR fills the rawframe_crop_*_offsetvalues in SPS units, which SharpProspero documents as "from the SPS" (L284-L294).PicStructPresentFlagas "Whether picture-timing SEI is present" (L347-L348), next to a separatePictureTimingSeiPresentFlag(L377-L378). This PR fills it from the VUI'spic_struct_present_flag, as its name says. The two readings differ for a stream that carries picture-timing SEIs for its HRD delays whilepic_struct_present_flagis 0.aspect_ratio_idc0 and the reserved 17 to 254 to 1:1 (h264_sps.cppL86-L98). This PR gives 0:0, as BunnyFl's reading does.videodec2.cppL1375-L1380). That fits +0x20 being the caller'sattachedData, as in SharpProspero, KytyPS5 and shadPS4.No console measured the field values. The debt entry lists the choices that are not verified:
max_dec_frame_buffering.pic_struct_present_flagfrom the VUI.attachedData.Overlaps:
tools/pr_overlap.pyreports no overlap with open pull requests. One open PR edits the same files:sceVideodec2Decode(the line after this PR's parse call) and the "AVC parameter-set units" debt entry. It also adds aCodecAvcconstant andtestParameterSetsBoundtoGuestVideodec2.cpp.git merge-treeof this branch and its head cfdff8d is clean in all three files, and no name is defined twice. A build of that merge passesguest_videodec2andguest_hevc_metadata. With both in, this PR also parses a unit that fix(libSceVideodec2): bound cumulative AVC parameter sets before insertion #12197's bound then rejects. A parameter set in that unit can only make later records unsupported, not wrong.Relevance: in prosper's notes on PPSA06367, the title calls
sceVideodec2GetPictureInfowiththisSize0x78 on its H.264 pictures. Since #10959 that call throws onmain. I did not run a title for this PR, so Unblocks is none.Tested
Gentoo Linux, kernel 7.2.8, GCC 16.2.1, AMD Ryzen 7 9800X3D. Release build of this branch on
main319621b, withBUILD_TESTING=ON.ctest --test-dir build -R 'guest_videodec2|guest_hevc_metadata|guest_videodec$|guest_vdecsw|public_headers' --output-on-failure -j8 --timeout 300: 70/70 pass. These areguest_videodec2,guest_videodec2_unimplemented,guest_hevc_metadata,guest_videodec,guest_vdecsw,public_headersand the 64public_headers_compile_*tests.GuestVideodec2.cpp. Records are compared field by field through both getters, with a guard word after the 0x78 record.H264Fixture::Stream, Annex-B and length-prefixed:max_dec_frame_buffering4.attachedDatamatch the unit, in display order.croppedStream()gives crop (0,0,4,4).pic_struct_present_flagand SAR idc 13 (160:99).pic_struct0, 3, 4, 7, 8 and 6.pic_struct_present_flagcalls for, either completes or changes only the validity word and nothing pastthisSize. This is the try-and-canary pattern ofGuestHevcMetadata.cpp.constraint_set0andconstraint_set1.max_dec_frame_bufferingis inferred as 16 (MaxDpbMbs 396 / 12 MBs, capped at 16).aspect_ratio_idc100 gives theStreamrecords with idc 100 and SAR 0:0, and FFmpeg decodes all six pictures with the reference hashes.thisSize0x58 and 0x68 on everyStreampicture use the same try-and-canary check.testClipkeeps 0x811D0101 for a 0x38 destination. That is the error BunnyFl's 13.42 emulator run reports for sizes other than the six accepted ones; 0x38 itself was not among the sizes tried.testFailureskeeps 0x811D010F for a missing picture count ahead of that size error, in the order of the same run.Export.cppreverted tomain's:ctest --test-dir build -R '^guest_videodec2$'fails withsceVideodec2GetAvcPictureInfo_nid_postfix not implemented.-fsanitize=address,undefined -fno-sanitize-recover=all, ran the parser on 39,999 seeds, 479,988 parses in all.Parse_nid_no_patch.python3 tools/check_test_registration.py buildpasses: 1515 test executables, none new.tools/select_tests.py): 491 of 2745 tests selected. All 491 pass, none skipped.python3 tools/check_conventions.py --base 319621ba2passes.x86_64-w64-mingw32-g++16.2.0 with-std=gnu++20 -fsyntax-only -Wall -Wextra -D_WIN32_WINNT=0x0602compilesAvcMetadata.cpp,Export.cppandGuestVideodec2.cppwithout errors.AvcMetadata.cppgives no warnings.-Wmissing-field-initializers, from the partial aggregate initializers both files already use onmain.Export.cppgives 2 against 1 onmain, because thePicture{pts, dts, attached}initializer now also leaves outavc.GuestVideodec2.cppgives 772 against 492.Not tested: no Windows or macOS build or run, no console, and no title.
Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code