Files
AnyPS5/core/libs/tests/H264Fixture.hpp
T
Slick Daddy 51c6b38978 fix(libSceVideodec): take the coded picture size the decoder reports
Videodec2 opens FFmpeg with apply_cropping = 0, so the frame it reports is
the coded picture and its crop fields describe the cropping rectangle. The
coded size was derived from the frame size and the crop, which counted the
crop a second time when it added up to a multiple of 16: a picture cropped
four units at the top and four at the bottom was reported 16 rows taller
than the coded picture, and every picture was then refused for a frame
buffer that was sized for the coded picture. The frame size is the coded
size, so the crop only fills the crop offsets.

The fixture's sequence parameter set is also decoded with a crop of four
units at the top and four at the bottom now, which covers the case in the
guest test.
2026-10-21 01:13:00 +03:00

177 lines
12 KiB
C++

#pragma once
#include <array>
#include <cstddef>
#include <cstdint>
#include <vector>
namespace H264Fixture {
inline constexpr std::uint32_t Width = 64;
inline constexpr std::uint32_t Height = 40;
inline constexpr std::uint32_t CodedHeight = 48;
inline constexpr std::array<std::uint8_t, 1477> Stream{
0x00, 0x00, 0x00, 0x01, 0x09, 0x10, 0x00, 0x00, 0x00, 0x01, 0x67, 0x64, 0x00, 0x0a, 0xac, 0xd9,
0x44, 0x7f, 0x97, 0x01, 0x10, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x03, 0x03, 0xc0, 0xf1,
0x22, 0x59, 0x60, 0x00, 0x00, 0x00, 0x01, 0x68, 0xeb, 0xe3, 0xcb, 0x22, 0xc0, 0x00, 0x00, 0x01,
0x06, 0x05, 0xff, 0xff, 0xa5, 0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7, 0x96, 0x2c, 0xd8,
0x20, 0xd9, 0x23, 0xee, 0xef, 0x78, 0x32, 0x36, 0x34, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x72, 0x65,
0x20, 0x31, 0x36, 0x35, 0x20, 0x72, 0x33, 0x32, 0x32, 0x32, 0x20, 0x62, 0x33, 0x35, 0x36, 0x30,
0x35, 0x61, 0x20, 0x2d, 0x20, 0x48, 0x2e, 0x32, 0x36, 0x34, 0x2f, 0x4d, 0x50, 0x45, 0x47, 0x2d,
0x34, 0x20, 0x41, 0x56, 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x63, 0x20, 0x2d, 0x20, 0x43, 0x6f,
0x70, 0x79, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x32, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x30, 0x32, 0x35,
0x20, 0x2d, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x69,
0x64, 0x65, 0x6f, 0x6c, 0x61, 0x6e, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x78, 0x32, 0x36, 0x34, 0x2e,
0x68, 0x74, 0x6d, 0x6c, 0x20, 0x2d, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x20,
0x63, 0x61, 0x62, 0x61, 0x63, 0x3d, 0x31, 0x20, 0x72, 0x65, 0x66, 0x3d, 0x33, 0x20, 0x64, 0x65,
0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3d, 0x31, 0x3a, 0x30, 0x3a, 0x30, 0x20, 0x61, 0x6e, 0x61, 0x6c,
0x79, 0x73, 0x65, 0x3d, 0x30, 0x78, 0x33, 0x3a, 0x30, 0x78, 0x31, 0x31, 0x33, 0x20, 0x6d, 0x65,
0x3d, 0x68, 0x65, 0x78, 0x20, 0x73, 0x75, 0x62, 0x6d, 0x65, 0x3d, 0x37, 0x20, 0x70, 0x73, 0x79,
0x3d, 0x31, 0x20, 0x70, 0x73, 0x79, 0x5f, 0x72, 0x64, 0x3d, 0x31, 0x2e, 0x30, 0x30, 0x3a, 0x30,
0x2e, 0x30, 0x30, 0x20, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x3d, 0x31, 0x20,
0x6d, 0x65, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3d, 0x31, 0x36, 0x20, 0x63, 0x68, 0x72, 0x6f,
0x6d, 0x61, 0x5f, 0x6d, 0x65, 0x3d, 0x31, 0x20, 0x74, 0x72, 0x65, 0x6c, 0x6c, 0x69, 0x73, 0x3d,
0x31, 0x20, 0x38, 0x78, 0x38, 0x64, 0x63, 0x74, 0x3d, 0x31, 0x20, 0x63, 0x71, 0x6d, 0x3d, 0x30,
0x20, 0x64, 0x65, 0x61, 0x64, 0x7a, 0x6f, 0x6e, 0x65, 0x3d, 0x32, 0x31, 0x2c, 0x31, 0x31, 0x20,
0x66, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x73, 0x6b, 0x69, 0x70, 0x3d, 0x31, 0x20, 0x63, 0x68, 0x72,
0x6f, 0x6d, 0x61, 0x5f, 0x71, 0x70, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x3d, 0x2d, 0x32,
0x20, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x31, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x61,
0x68, 0x65, 0x61, 0x64, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x31, 0x20, 0x73,
0x6c, 0x69, 0x63, 0x65, 0x64, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x30, 0x20,
0x6e, 0x72, 0x3d, 0x30, 0x20, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x3d, 0x31, 0x20,
0x69, 0x6e, 0x74, 0x65, 0x72, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x3d, 0x30, 0x20, 0x62, 0x6c, 0x75,
0x72, 0x61, 0x79, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x3d, 0x30, 0x20, 0x63, 0x6f, 0x6e,
0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x72, 0x61, 0x3d, 0x30,
0x20, 0x62, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x3d, 0x32, 0x20, 0x62, 0x5f, 0x70, 0x79, 0x72,
0x61, 0x6d, 0x69, 0x64, 0x3d, 0x32, 0x20, 0x62, 0x5f, 0x61, 0x64, 0x61, 0x70, 0x74, 0x3d, 0x30,
0x20, 0x62, 0x5f, 0x62, 0x69, 0x61, 0x73, 0x3d, 0x30, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74,
0x3d, 0x31, 0x20, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x62, 0x3d, 0x31, 0x20, 0x6f, 0x70, 0x65,
0x6e, 0x5f, 0x67, 0x6f, 0x70, 0x3d, 0x30, 0x20, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x70, 0x3d,
0x32, 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x3d, 0x36, 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e,
0x74, 0x5f, 0x6d, 0x69, 0x6e, 0x3d, 0x31, 0x20, 0x73, 0x63, 0x65, 0x6e, 0x65, 0x63, 0x75, 0x74,
0x3d, 0x30, 0x20, 0x69, 0x6e, 0x74, 0x72, 0x61, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68,
0x3d, 0x30, 0x20, 0x72, 0x63, 0x5f, 0x6c, 0x6f, 0x6f, 0x6b, 0x61, 0x68, 0x65, 0x61, 0x64, 0x3d,
0x36, 0x20, 0x72, 0x63, 0x3d, 0x63, 0x72, 0x66, 0x20, 0x6d, 0x62, 0x74, 0x72, 0x65, 0x65, 0x3d,
0x31, 0x20, 0x63, 0x72, 0x66, 0x3d, 0x32, 0x33, 0x2e, 0x30, 0x20, 0x71, 0x63, 0x6f, 0x6d, 0x70,
0x3d, 0x30, 0x2e, 0x36, 0x30, 0x20, 0x71, 0x70, 0x6d, 0x69, 0x6e, 0x3d, 0x30, 0x20, 0x71, 0x70,
0x6d, 0x61, 0x78, 0x3d, 0x36, 0x39, 0x20, 0x71, 0x70, 0x73, 0x74, 0x65, 0x70, 0x3d, 0x34, 0x20,
0x69, 0x70, 0x5f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x3d, 0x31, 0x2e, 0x34, 0x30, 0x20, 0x61, 0x71,
0x3d, 0x31, 0x3a, 0x31, 0x2e, 0x30, 0x30, 0x00, 0x80, 0x00, 0x00, 0x01, 0x65, 0x88, 0x84, 0x00,
0x21, 0xff, 0x5b, 0xff, 0x78, 0x50, 0x63, 0x8c, 0x32, 0x61, 0x08, 0xb9, 0xb3, 0xab, 0x26, 0xb5,
0xe1, 0xe9, 0x5b, 0xb7, 0x7b, 0xfd, 0x6b, 0x41, 0x3a, 0x52, 0x12, 0x59, 0x95, 0x0c, 0xa4, 0x3b,
0xc7, 0x28, 0x9a, 0x87, 0xd9, 0x38, 0xc9, 0xcb, 0x8f, 0x05, 0x47, 0xff, 0xd1, 0x1e, 0xd3, 0x68,
0xb5, 0x05, 0x8c, 0xb4, 0xf3, 0x18, 0x74, 0x33, 0x57, 0x68, 0xf6, 0xf0, 0xc7, 0xcb, 0xbf, 0x7b,
0x3d, 0x43, 0x0f, 0xa7, 0x42, 0x5a, 0x78, 0x5b, 0x61, 0x0e, 0xc6, 0x5c, 0xb2, 0xdf, 0xa0, 0xe0,
0x96, 0x11, 0xdd, 0x02, 0xec, 0x17, 0x80, 0x72, 0x4f, 0x35, 0x05, 0x1e, 0x8b, 0xa8, 0xfc, 0x38,
0x28, 0xa8, 0xc7, 0x19, 0x5a, 0xa0, 0x8b, 0x96, 0x47, 0x6c, 0xf3, 0x37, 0x65, 0x02, 0x13, 0x8a,
0x97, 0xbc, 0x86, 0xf8, 0x31, 0xc2, 0xab, 0x7f, 0xe1, 0xa4, 0x68, 0x21, 0xc5, 0xe1, 0x56, 0xca,
0x96, 0xd7, 0xa3, 0x7f, 0x77, 0x7b, 0xed, 0x28, 0x08, 0xd4, 0xe3, 0x98, 0xdc, 0xc1, 0x2f, 0x0f,
0x0c, 0x37, 0x06, 0x36, 0xd4, 0x10, 0xdb, 0x7e, 0x99, 0xd4, 0xb1, 0x67, 0xda, 0xbd, 0x28, 0x58,
0xe6, 0x0e, 0x70, 0x33, 0xe4, 0xb0, 0xb8, 0xd2, 0xb4, 0x60, 0x16, 0x41, 0x1d, 0xda, 0xc5, 0x47,
0xad, 0xd3, 0x55, 0x30, 0xdf, 0xca, 0xab, 0xb9, 0x91, 0xca, 0xca, 0xe6, 0xfe, 0xb4, 0x9e, 0x55,
0x18, 0xeb, 0x74, 0x83, 0x01, 0x95, 0xb3, 0x0c, 0x92, 0x4d, 0xb8, 0xfd, 0xa6, 0x28, 0x77, 0xdb,
0xb9, 0xbc, 0xf2, 0x2c, 0xde, 0xe2, 0x1f, 0x55, 0x39, 0x80, 0x05, 0x67, 0xf1, 0x8c, 0x46, 0xf3,
0xf8, 0x61, 0x00, 0x00, 0x00, 0x01, 0x09, 0x30, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x23, 0x6c, 0x47,
0x7f, 0xd6, 0x70, 0xed, 0x07, 0x2d, 0x6f, 0xf0, 0xd9, 0x1c, 0xc5, 0x57, 0x33, 0x9c, 0x0b, 0xe3,
0x29, 0x4d, 0xc8, 0x18, 0xba, 0x21, 0x49, 0x77, 0xb9, 0xc5, 0x9c, 0xab, 0xcb, 0xca, 0xe9, 0xab,
0xf7, 0xad, 0xfb, 0x45, 0xda, 0x68, 0x98, 0x7e, 0xff, 0xbd, 0x7e, 0x91, 0xb8, 0x93, 0xb5, 0x78,
0x93, 0x98, 0x6e, 0x6e, 0xdf, 0x1f, 0x8f, 0x3c, 0x4e, 0xc9, 0x78, 0x17, 0xbf, 0xf4, 0xfb, 0x47,
0x64, 0x2f, 0xb3, 0xf8, 0xb6, 0xdc, 0x1a, 0xe9, 0xb7, 0x7c, 0xfc, 0x6a, 0x5d, 0xb5, 0x95, 0xb6,
0x47, 0x6b, 0xfe, 0x5d, 0xf6, 0x8e, 0x6e, 0x85, 0x65, 0x2a, 0x2d, 0x05, 0x21, 0x45, 0x13, 0x0d,
0x0c, 0xf3, 0xea, 0x6f, 0x58, 0x28, 0x7a, 0x66, 0x54, 0xfd, 0x7e, 0x27, 0xc6, 0x6a, 0xf0, 0x00,
0x00, 0x00, 0x01, 0x09, 0x50, 0x00, 0x00, 0x01, 0x41, 0x9e, 0x41, 0x78, 0x84, 0x3f, 0xe3, 0x5a,
0x3c, 0x1e, 0x34, 0x44, 0x68, 0x14, 0xb9, 0xbc, 0x32, 0x4a, 0xc3, 0x1b, 0x54, 0xd4, 0x00, 0x3c,
0x17, 0xa1, 0xbd, 0xc0, 0x86, 0xe1, 0xbf, 0x7d, 0xf4, 0x08, 0x3c, 0xa3, 0xeb, 0xe0, 0xfd, 0x44,
0x09, 0x7d, 0x95, 0x20, 0xf4, 0x50, 0x4b, 0x4e, 0xf3, 0x78, 0xa5, 0x9f, 0x14, 0x23, 0x7f, 0xc1,
0x4e, 0x94, 0xf1, 0x1b, 0xa1, 0x94, 0x86, 0x6d, 0x14, 0x53, 0xa8, 0xe6, 0xa4, 0xd4, 0x28, 0xcd,
0x86, 0xb1, 0xcb, 0x9f, 0x67, 0x72, 0xc5, 0xf8, 0x99, 0x9a, 0xf3, 0xba, 0x47, 0xdf, 0x41, 0x00,
0x00, 0x00, 0x01, 0x09, 0x50, 0x00, 0x00, 0x01, 0x01, 0x9e, 0x62, 0x6a, 0x42, 0x5f, 0xdf, 0xac,
0xe9, 0x76, 0x6c, 0x13, 0x5c, 0xa1, 0x08, 0xbf, 0xd4, 0xd8, 0x03, 0xef, 0xd2, 0x0d, 0xc1, 0xde,
0x35, 0x3b, 0x9e, 0x3d, 0xe1, 0xf6, 0xd8, 0xe7, 0xae, 0xdf, 0x9f, 0x20, 0x19, 0xbc, 0x50, 0xa9,
0x69, 0x82, 0x26, 0x04, 0xaf, 0x83, 0x44, 0x79, 0x1b, 0x74, 0x18, 0x2b, 0x00, 0xb8, 0x62, 0xa3,
0xd1, 0x84, 0x8b, 0x61, 0x87, 0x1a, 0x4f, 0x5b, 0xef, 0x16, 0xeb, 0xb3, 0x1a, 0x06, 0xfd, 0x92,
0x87, 0x06, 0xc3, 0xec, 0xda, 0xde, 0xec, 0x3d, 0x7d, 0x8a, 0x06, 0x91, 0xc8, 0xdf, 0x59, 0xa7,
0x58, 0xef, 0x7a, 0x3c, 0x27, 0x1d, 0x00, 0x00, 0x00, 0x01, 0x09, 0x30, 0x00, 0x00, 0x01, 0x41,
0x9a, 0x65, 0x49, 0xa8, 0x41, 0x68, 0x99, 0x4c, 0x14, 0xf0, 0xc7, 0xde, 0x88, 0x44, 0x37, 0xa7,
0x7f, 0x10, 0x1e, 0xf9, 0x41, 0xb5, 0x7c, 0x9b, 0xf7, 0x1d, 0x61, 0x0e, 0xe1, 0xec, 0xbc, 0x75,
0x08, 0x53, 0x8f, 0x68, 0x84, 0x84, 0x93, 0x11, 0x08, 0xf6, 0xb2, 0xe5, 0x6f, 0x30, 0x16, 0xd0,
0x9d, 0xf2, 0x87, 0x44, 0x40, 0x82, 0x85, 0xcf, 0x16, 0x73, 0x64, 0x1f, 0xb0, 0x22, 0x75, 0xc8,
0xd7, 0xd2, 0x61, 0xdc, 0x1e, 0x9c, 0xa0, 0xeb, 0x88, 0x7d, 0x1a, 0x55, 0xe4, 0x66, 0x49, 0x5e,
0xa8, 0xff, 0xc2, 0xb5, 0xb0, 0x46, 0x2a, 0xb5, 0xcd, 0xed, 0x7c, 0xf9, 0xd8, 0xe7, 0x00, 0x00,
0x00, 0x01, 0x09, 0x50, 0x00, 0x00, 0x01, 0x01, 0x9e, 0x84, 0x6a, 0x42, 0x5f, 0xf9, 0x0f, 0xf0,
0x52, 0xca, 0xb7, 0x04, 0x3a, 0xd3, 0x0a, 0xb3, 0xaa, 0x47, 0xf0, 0x8c, 0x9f, 0x4b, 0x6f, 0x0e,
0x38, 0x62, 0x53, 0x04, 0x7d, 0x8f, 0x80, 0xca, 0x62, 0x93, 0xfd, 0xbb, 0x97, 0xef, 0x71, 0xf8,
0xbc, 0x20, 0x23, 0xd1, 0x9d, 0x50, 0xee, 0xd4, 0x9a, 0x13, 0xb6, 0xfb, 0x78, 0x71, 0x43, 0x78,
0x65, 0xd6, 0x24, 0xe4, 0xca, 0x6f, 0xb4, 0x42, 0x4d, 0x64, 0xd5, 0xfc, 0x12, 0x29, 0x20, 0x52,
0xd8, 0x82, 0x78, 0x3d, 0x2f,
};
inline constexpr std::array<std::uint64_t, 6> PictureHashes{
0x51b6aa8b48a59d5full, 0x2d097708ed7c0f66ull, 0xdee989a52806e938ull,
0x4bfd091eacb8679full, 0x290cf60ce8be58bcull, 0x809cb73819503632ull,
};
inline constexpr std::array<std::uint64_t, 6> DisplayOrderUnits{0, 2, 3, 1, 5, 4};
inline constexpr std::size_t SpsOffset = 10;
inline constexpr std::array<std::uint8_t, 25> CroppedSps{
0x67, 0x64, 0x00, 0x0a, 0xac, 0xd9, 0x44, 0x7f, 0x29, 0x70, 0x11, 0x00, 0x00,
0x03, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x3c, 0x0f, 0x12, 0x25, 0x96,
};
inline std::vector<std::uint8_t> croppedStream() {
std::vector<std::uint8_t> stream(Stream.begin(), Stream.end());
for (std::size_t index = 0; index < CroppedSps.size(); ++index) stream[SpsOffset + index] = CroppedSps[index];
return stream;
}
inline std::uint64_t hashNv12(const std::uint8_t* buffer, std::uint32_t pitch, std::uint32_t height) {
std::uint64_t hash = 0xcbf29ce484222325ull;
const auto mix = [&](const std::uint8_t* row) {
for (std::uint32_t column = 0; column < Width; ++column) hash = (hash ^ row[column]) * 0x100000001b3ull;
};
for (std::uint32_t row = 0; row < height; ++row) mix(buffer + static_cast<std::size_t>(row) * pitch);
const auto* chroma = buffer + static_cast<std::size_t>(pitch) * height;
for (std::uint32_t row = 0; row < height / 2; ++row) mix(chroma + static_cast<std::size_t>(row) * pitch);
return hash;
}
inline std::vector<std::vector<std::uint8_t>> accessUnits(const std::uint8_t* data, std::size_t size, bool lengthPrefixed) {
std::vector<std::size_t> starts;
for (std::size_t index = 0; index + 4 < size; ++index) {
if (data[index] == 0 && data[index + 1] == 0 && data[index + 2] == 0 && data[index + 3] == 1 && (data[index + 4] & 0x1fu) == 9) starts.push_back(index);
}
starts.push_back(size);
std::vector<std::vector<std::uint8_t>> units;
for (std::size_t unit = 0; unit + 1 < starts.size(); ++unit) {
if (!lengthPrefixed) {
units.emplace_back(data + starts[unit], data + starts[unit + 1]);
continue;
}
std::vector<std::size_t> nals;
for (std::size_t index = starts[unit]; index + 3 < starts[unit + 1]; ++index) {
if (data[index] == 0 && data[index + 1] == 0 && data[index + 2] == 1) {
nals.push_back(index + 3);
index += 2;
}
}
std::vector<std::uint8_t> converted;
for (std::size_t nal = 0; nal < nals.size(); ++nal) {
auto end = nal + 1 < nals.size() ? nals[nal + 1] - 3 : starts[unit + 1];
while (end > nals[nal] && data[end - 1] == 0) --end;
const auto length = end - nals[nal];
for (int shift = 24; shift >= 0; shift -= 8) converted.push_back(static_cast<std::uint8_t>(length >> shift));
converted.insert(converted.end(), data + nals[nal], data + end);
}
units.push_back(std::move(converted));
}
return units;
}
inline std::vector<std::vector<std::uint8_t>> accessUnits(bool lengthPrefixed) {
return accessUnits(Stream.data(), Stream.size(), lengthPrefixed);
}
}