mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-22 08:33:12 -05:00
Replace the decoder-less AvPlayer with a player that demuxes MP4 sources with FFmpeg (opened by path or through the title's file replacement), decodes H.264 and AAC on their own threads, and hands out NV12 frames and interleaved 16-bit PCM in buffers from the title's allocators, presented on a media clock that audio drives when it is enabled. Both libSceAvPlayer and libSceAvPlayer.native are built from the same sources and link the shared ffmpeg target. The struct size checks stay, next to the types in SceTypes.hpp. ChangeStream and GetStreamInfoEx are implemented; Init without allocators, StartEx, SetAvailableBandwidth, SetLogCallback and negative trick speeds succeed as before and are listed in TechnicalDebt. HLS sources throw. guest_avplayer plays an embedded 6 KB MP4 (H.264 plus two AAC tracks).
963 lines
65 KiB
C++
963 lines
65 KiB
C++
#include <algorithm>
|
|
#include <array>
|
|
#include <chrono>
|
|
#include <cmath>
|
|
#include <cstdint>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <deque>
|
|
#include <filesystem>
|
|
#include <fstream>
|
|
#include <functional>
|
|
#include <map>
|
|
#include <mutex>
|
|
#include <new>
|
|
#include <stdexcept>
|
|
#include <string>
|
|
#include <thread>
|
|
#include <vector>
|
|
#include "SceTypes.hpp"
|
|
#include "prx/libc/include/general/VabiMacros.hpp"
|
|
|
|
extern "C" {
|
|
AvPlayerInternal* APS5_VABI sceAvPlayerInit(AvPlayerInitData*);
|
|
int APS5_VABI sceAvPlayerInitEx(const AvPlayerInitDataEx*, AvPlayerInternal**);
|
|
int APS5_VABI sceAvPlayerPostInit(AvPlayerInternal*, const AvPlayerPostInitData*);
|
|
int APS5_VABI sceAvPlayerSetLogCallback(void*, void*);
|
|
int APS5_VABI sceAvPlayerAddSource(AvPlayerInternal*, const char*);
|
|
int APS5_VABI sceAvPlayerStreamCount(AvPlayerInternal*);
|
|
int APS5_VABI sceAvPlayerGetStreamInfo(AvPlayerInternal*, std::uint32_t, AvPlayerStreamInfo*);
|
|
int APS5_VABI sceAvPlayerGetStreamInfoEx(AvPlayerInternal*, std::uint32_t, AvPlayerStreamInfoEx*);
|
|
int APS5_VABI sceAvPlayerEnableStream(AvPlayerInternal*, std::uint32_t);
|
|
int APS5_VABI sceAvPlayerChangeStream(AvPlayerInternal*, std::uint32_t, std::uint32_t);
|
|
int APS5_VABI sceAvPlayerSetAvailableBandwidth(AvPlayerInternal*, std::uint32_t, std::uint32_t, std::uint32_t);
|
|
int APS5_VABI sceAvPlayerStart(AvPlayerInternal*);
|
|
int APS5_VABI sceAvPlayerStartEx(AvPlayerInternal*, const void*);
|
|
int APS5_VABI sceAvPlayerStop(AvPlayerInternal*);
|
|
int APS5_VABI sceAvPlayerPause(AvPlayerInternal*);
|
|
int APS5_VABI sceAvPlayerResume(AvPlayerInternal*);
|
|
int APS5_VABI sceAvPlayerJumpToTime(AvPlayerInternal*, std::uint64_t);
|
|
int APS5_VABI sceAvPlayerSetLooping(AvPlayerInternal*, Bool);
|
|
int APS5_VABI sceAvPlayerSetAvSyncMode(AvPlayerInternal*, std::uint32_t);
|
|
int APS5_VABI sceAvPlayerSetTrickSpeed(AvPlayerInternal*, std::int32_t);
|
|
Bool APS5_VABI sceAvPlayerGetVideoDataEx(AvPlayerInternal*, AvPlayerFrameInfoEx*);
|
|
Bool APS5_VABI sceAvPlayerGetVideoData(AvPlayerInternal*, AvPlayerFrameInfo*);
|
|
Bool APS5_VABI sceAvPlayerGetAudioData(AvPlayerInternal*, AvPlayerFrameInfo*);
|
|
Bool APS5_VABI sceAvPlayerIsActive(AvPlayerInternal*);
|
|
std::uint64_t APS5_VABI sceAvPlayerCurrentTime(AvPlayerInternal*);
|
|
int APS5_VABI sceAvPlayerClose(AvPlayerInternal*);
|
|
}
|
|
|
|
namespace {
|
|
|
|
constexpr int Width = 100;
|
|
constexpr int Height = 60;
|
|
constexpr int Pitch = 256;
|
|
constexpr int FrameRate = 30;
|
|
constexpr int FrameCount = 30;
|
|
constexpr int SampleRate = 48000;
|
|
constexpr std::uint32_t VideoStream = 0;
|
|
constexpr std::uint32_t EnglishAudioStream = 1;
|
|
constexpr std::uint32_t FrenchAudioStream = 2;
|
|
constexpr int InvalidParams = static_cast<int>(0x806A0001u);
|
|
constexpr int OperationFailed = static_cast<int>(0x806A0002u);
|
|
constexpr std::int32_t LoopingBack = static_cast<std::int32_t>(0x806A00A1u);
|
|
constexpr std::int32_t JumpComplete = static_cast<std::int32_t>(0x806A00A3u);
|
|
constexpr std::int32_t EventStop = 1;
|
|
constexpr std::int32_t EventReady = 2;
|
|
constexpr std::int32_t EventPlay = 3;
|
|
constexpr std::int32_t EventPause = 4;
|
|
constexpr std::int32_t EventWarning = 0x20;
|
|
const char* const MoviePath = "app0/avplayer.mp4";
|
|
|
|
constexpr std::array<std::uint8_t, 5986> Movie{
|
|
0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, 0x69, 0x73, 0x6f, 0x6d, 0x00, 0x00, 0x02, 0x00,
|
|
0x69, 0x73, 0x6f, 0x6d, 0x69, 0x73, 0x6f, 0x32, 0x61, 0x76, 0x63, 0x31, 0x6d, 0x70, 0x34, 0x31,
|
|
0x00, 0x00, 0x0b, 0x56, 0x6d, 0x6f, 0x6f, 0x76, 0x00, 0x00, 0x00, 0x6c, 0x6d, 0x76, 0x68, 0x64,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0x80,
|
|
0x00, 0x00, 0xbb, 0x80, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0xfb, 0x74, 0x72, 0x61, 0x6b, 0x00, 0x00, 0x00, 0x5c,
|
|
0x74, 0x6b, 0x68, 0x64, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0x80, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
|
|
0x00, 0x64, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x65, 0x64, 0x74, 0x73,
|
|
0x00, 0x00, 0x00, 0x1c, 0x65, 0x6c, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
|
0x00, 0x00, 0xbb, 0x80, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x73,
|
|
0x6d, 0x64, 0x69, 0x61, 0x00, 0x00, 0x00, 0x20, 0x6d, 0x64, 0x68, 0x64, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x3c, 0x00,
|
|
0x15, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x68, 0x64, 0x6c, 0x72, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x76, 0x69, 0x64, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72,
|
|
0x00, 0x00, 0x00, 0x03, 0x1e, 0x6d, 0x69, 0x6e, 0x66, 0x00, 0x00, 0x00, 0x14, 0x76, 0x6d, 0x68,
|
|
0x64, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x24, 0x64, 0x69, 0x6e, 0x66, 0x00, 0x00, 0x00, 0x1c, 0x64, 0x72, 0x65, 0x66, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x75, 0x72, 0x6c, 0x20, 0x00, 0x00, 0x00,
|
|
0x01, 0x00, 0x00, 0x02, 0xde, 0x73, 0x74, 0x62, 0x6c, 0x00, 0x00, 0x00, 0xb2, 0x73, 0x74, 0x73,
|
|
0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x61, 0x76, 0x63,
|
|
0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x3c, 0x00, 0x48, 0x00,
|
|
0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x4c, 0x61, 0x76, 0x63,
|
|
0x20, 0x6c, 0x69, 0x62, 0x78, 0x32, 0x36, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xff, 0xff, 0x00,
|
|
0x00, 0x00, 0x38, 0x61, 0x76, 0x63, 0x43, 0x01, 0x64, 0x00, 0x0b, 0xff, 0xe1, 0x00, 0x1a, 0x67,
|
|
0x64, 0x00, 0x0b, 0xac, 0x76, 0x11, 0x1c, 0x9e, 0x7b, 0x84, 0x00, 0x00, 0x03, 0x00, 0x04, 0x00,
|
|
0x00, 0x03, 0x00, 0xf0, 0x3c, 0x50, 0xa6, 0x11, 0x80, 0x01, 0x00, 0x07, 0x68, 0xe8, 0x43, 0x81,
|
|
0x0c, 0xb2, 0x2c, 0xfd, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x14, 0x62, 0x74, 0x72, 0x74, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x73,
|
|
0x74, 0x74, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1e, 0x00,
|
|
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x73, 0x74, 0x73, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x15, 0x00,
|
|
0x00, 0x00, 0xb8, 0x63, 0x74, 0x74, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00,
|
|
0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00,
|
|
0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00,
|
|
0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00,
|
|
0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00,
|
|
0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00,
|
|
0x00, 0x00, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00,
|
|
0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00,
|
|
0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00,
|
|
0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00,
|
|
0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00,
|
|
0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x28, 0x73, 0x74, 0x73, 0x63, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00,
|
|
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
|
|
0x00, 0x00, 0x8c, 0x73, 0x74, 0x73, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0d, 0x00,
|
|
0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0e, 0x00,
|
|
0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x30, 0x00,
|
|
0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x1f, 0x00,
|
|
0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x0e, 0x00,
|
|
0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x0d, 0x00,
|
|
0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0e, 0x00,
|
|
0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x84, 0x73,
|
|
0x74, 0x63, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x0b, 0x86, 0x00,
|
|
0x00, 0x0b, 0xfc, 0x00, 0x00, 0x0c, 0x87, 0x00, 0x00, 0x0c, 0xf0, 0x00, 0x00, 0x0d, 0x3e, 0x00,
|
|
0x00, 0x0d, 0xaf, 0x00, 0x00, 0x0d, 0xea, 0x00, 0x00, 0x0e, 0x67, 0x00, 0x00, 0x0e, 0xad, 0x00,
|
|
0x00, 0x0f, 0x21, 0x00, 0x00, 0x0f, 0xad, 0x00, 0x00, 0x0f, 0xf8, 0x00, 0x00, 0x10, 0x5f, 0x00,
|
|
0x00, 0x10, 0x9f, 0x00, 0x00, 0x11, 0x1a, 0x00, 0x00, 0x11, 0x5f, 0x00, 0x00, 0x11, 0xf9, 0x00,
|
|
0x00, 0x12, 0x40, 0x00, 0x00, 0x12, 0xaa, 0x00, 0x00, 0x13, 0x25, 0x00, 0x00, 0x13, 0x83, 0x00,
|
|
0x00, 0x13, 0xfe, 0x00, 0x00, 0x14, 0x3a, 0x00, 0x00, 0x14, 0xa8, 0x00, 0x00, 0x14, 0xfb, 0x00,
|
|
0x00, 0x15, 0x64, 0x00, 0x00, 0x15, 0xd1, 0x00, 0x00, 0x16, 0x28, 0x00, 0x00, 0x16, 0x95, 0x00,
|
|
0x00, 0x02, 0xf5, 0x74, 0x72, 0x61, 0x6b, 0x00, 0x00, 0x00, 0x5c, 0x74, 0x6b, 0x68, 0x64, 0x00,
|
|
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x65, 0x64, 0x74, 0x73, 0x00, 0x00, 0x00, 0x1c, 0x65,
|
|
0x6c, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xbb, 0x80, 0x00,
|
|
0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x6d, 0x6d, 0x64, 0x69, 0x61, 0x00,
|
|
0x00, 0x00, 0x20, 0x6d, 0x64, 0x68, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0x80, 0x00, 0x00, 0xbf, 0x80, 0x15, 0xc7, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x2d, 0x68, 0x64, 0x6c, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73,
|
|
0x6f, 0x75, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53,
|
|
0x6f, 0x75, 0x6e, 0x64, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x00, 0x00, 0x00, 0x02, 0x18,
|
|
0x6d, 0x69, 0x6e, 0x66, 0x00, 0x00, 0x00, 0x10, 0x73, 0x6d, 0x68, 0x64, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x64, 0x69, 0x6e, 0x66, 0x00, 0x00, 0x00, 0x1c,
|
|
0x64, 0x72, 0x65, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c,
|
|
0x75, 0x72, 0x6c, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0xdc, 0x73, 0x74, 0x62, 0x6c,
|
|
0x00, 0x00, 0x00, 0x7e, 0x73, 0x74, 0x73, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
|
0x00, 0x00, 0x00, 0x6e, 0x6d, 0x70, 0x34, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
|
|
0xbb, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x65, 0x73, 0x64, 0x73, 0x00, 0x00, 0x00, 0x00,
|
|
0x03, 0x80, 0x80, 0x80, 0x25, 0x00, 0x02, 0x00, 0x04, 0x80, 0x80, 0x80, 0x17, 0x40, 0x15, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x1f, 0x40, 0x00, 0x00, 0x08, 0xcf, 0x05, 0x80, 0x80, 0x80, 0x05, 0x11,
|
|
0x90, 0x56, 0xe5, 0x00, 0x06, 0x80, 0x80, 0x80, 0x01, 0x02, 0x00, 0x00, 0x00, 0x14, 0x62, 0x74,
|
|
0x72, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x40, 0x00, 0x00, 0x08, 0xcf, 0x00, 0x00,
|
|
0x00, 0x20, 0x73, 0x74, 0x74, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
|
|
0x00, 0x2f, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00,
|
|
0x00, 0x1c, 0x73, 0x74, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
|
|
0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x73, 0x74,
|
|
0x73, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,
|
|
0x00, 0xd0, 0x73, 0x74, 0x63, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,
|
|
0x0b, 0xcb, 0x00, 0x00, 0x0c, 0x09, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x00, 0x0c, 0x94, 0x00, 0x00,
|
|
0x0c, 0xc3, 0x00, 0x00, 0x0d, 0x0f, 0x00, 0x00, 0x0d, 0x4c, 0x00, 0x00, 0x0d, 0x7a, 0x00, 0x00,
|
|
0x0d, 0xbd, 0x00, 0x00, 0x0e, 0x0b, 0x00, 0x00, 0x0e, 0x39, 0x00, 0x00, 0x0e, 0x75, 0x00, 0x00,
|
|
0x0e, 0xbb, 0x00, 0x00, 0x0e, 0xf1, 0x00, 0x00, 0x0f, 0x51, 0x00, 0x00, 0x0f, 0x7e, 0x00, 0x00,
|
|
0x0f, 0xc1, 0x00, 0x00, 0x10, 0x05, 0x00, 0x00, 0x10, 0x31, 0x00, 0x00, 0x10, 0x6c, 0x00, 0x00,
|
|
0x10, 0xbe, 0x00, 0x00, 0x10, 0xec, 0x00, 0x00, 0x11, 0x27, 0x00, 0x00, 0x11, 0x9e, 0x00, 0x00,
|
|
0x11, 0xcc, 0x00, 0x00, 0x12, 0x0b, 0x00, 0x00, 0x12, 0x4e, 0x00, 0x00, 0x12, 0x7b, 0x00, 0x00,
|
|
0x12, 0xca, 0x00, 0x00, 0x12, 0xf8, 0x00, 0x00, 0x13, 0x55, 0x00, 0x00, 0x13, 0x98, 0x00, 0x00,
|
|
0x13, 0xc7, 0x00, 0x00, 0x14, 0x0b, 0x00, 0x00, 0x14, 0x47, 0x00, 0x00, 0x14, 0x7b, 0x00, 0x00,
|
|
0x14, 0xc7, 0x00, 0x00, 0x15, 0x09, 0x00, 0x00, 0x15, 0x38, 0x00, 0x00, 0x15, 0x72, 0x00, 0x00,
|
|
0x15, 0xa2, 0x00, 0x00, 0x15, 0xf1, 0x00, 0x00, 0x16, 0x36, 0x00, 0x00, 0x16, 0x68, 0x00, 0x00,
|
|
0x16, 0xa3, 0x00, 0x00, 0x16, 0xd2, 0x00, 0x00, 0x17, 0x06, 0x00, 0x00, 0x17, 0x35, 0x00, 0x00,
|
|
0x00, 0x1a, 0x73, 0x67, 0x70, 0x64, 0x01, 0x00, 0x00, 0x00, 0x72, 0x6f, 0x6c, 0x6c, 0x00, 0x00,
|
|
0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1c, 0x73, 0x62, 0x67, 0x70,
|
|
0x00, 0x00, 0x00, 0x00, 0x72, 0x6f, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30,
|
|
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0xb5, 0x74, 0x72, 0x61, 0x6b, 0x00, 0x00, 0x00, 0x5c,
|
|
0x74, 0x6b, 0x68, 0x64, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0x80, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x65, 0x64, 0x74, 0x73,
|
|
0x00, 0x00, 0x00, 0x1c, 0x65, 0x6c, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
|
0x00, 0x00, 0xbb, 0x80, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x2d,
|
|
0x6d, 0x64, 0x69, 0x61, 0x00, 0x00, 0x00, 0x20, 0x6d, 0x64, 0x68, 0x64, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0x80, 0x00, 0x00, 0xbf, 0x80,
|
|
0x1a, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x68, 0x64, 0x6c, 0x72, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x73, 0x6f, 0x75, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x53, 0x6f, 0x75, 0x6e, 0x64, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72,
|
|
0x00, 0x00, 0x00, 0x02, 0xd8, 0x6d, 0x69, 0x6e, 0x66, 0x00, 0x00, 0x00, 0x10, 0x73, 0x6d, 0x68,
|
|
0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x64, 0x69, 0x6e,
|
|
0x66, 0x00, 0x00, 0x00, 0x1c, 0x64, 0x72, 0x65, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x01, 0x00, 0x00, 0x00, 0x0c, 0x75, 0x72, 0x6c, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02,
|
|
0x9c, 0x73, 0x74, 0x62, 0x6c, 0x00, 0x00, 0x00, 0x7e, 0x73, 0x74, 0x73, 0x64, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x6e, 0x6d, 0x70, 0x34, 0x61, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
|
0x10, 0x00, 0x00, 0x00, 0x00, 0xbb, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x65, 0x73, 0x64,
|
|
0x73, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x80, 0x80, 0x25, 0x00, 0x03, 0x00, 0x04, 0x80, 0x80,
|
|
0x80, 0x17, 0x40, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0xd8, 0x00, 0x00, 0x3e, 0xd8, 0x05,
|
|
0x80, 0x80, 0x80, 0x05, 0x11, 0x88, 0x56, 0xe5, 0x00, 0x06, 0x80, 0x80, 0x80, 0x01, 0x02, 0x00,
|
|
0x00, 0x00, 0x14, 0x62, 0x74, 0x72, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0xd8, 0x00,
|
|
0x00, 0x3e, 0xd8, 0x00, 0x00, 0x00, 0x20, 0x73, 0x74, 0x74, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
|
0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x1c, 0x73, 0x74, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
|
|
0x00, 0x00, 0xd4, 0x73, 0x74, 0x73, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x29, 0x00,
|
|
0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x28, 0x00,
|
|
0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x28, 0x00,
|
|
0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x27, 0x00,
|
|
0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x28, 0x00,
|
|
0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x32, 0x00,
|
|
0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x27, 0x00,
|
|
0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x28, 0x00,
|
|
0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x2e, 0x00,
|
|
0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x26, 0x00,
|
|
0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x2c, 0x00,
|
|
0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x29, 0x00,
|
|
0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0xd0, 0x73, 0x74, 0x63, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x30, 0x00, 0x00, 0x0b, 0xd1, 0x00, 0x00, 0x0c, 0x0f, 0x00, 0x00, 0x0c, 0x5e, 0x00,
|
|
0x00, 0x0c, 0x9a, 0x00, 0x00, 0x0c, 0xc9, 0x00, 0x00, 0x0d, 0x15, 0x00, 0x00, 0x0d, 0x52, 0x00,
|
|
0x00, 0x0d, 0x80, 0x00, 0x00, 0x0d, 0xc3, 0x00, 0x00, 0x0e, 0x11, 0x00, 0x00, 0x0e, 0x3f, 0x00,
|
|
0x00, 0x0e, 0x7b, 0x00, 0x00, 0x0e, 0xc1, 0x00, 0x00, 0x0e, 0xf7, 0x00, 0x00, 0x0f, 0x57, 0x00,
|
|
0x00, 0x0f, 0x84, 0x00, 0x00, 0x0f, 0xc7, 0x00, 0x00, 0x10, 0x0b, 0x00, 0x00, 0x10, 0x37, 0x00,
|
|
0x00, 0x10, 0x72, 0x00, 0x00, 0x10, 0xc4, 0x00, 0x00, 0x10, 0xf2, 0x00, 0x00, 0x11, 0x2d, 0x00,
|
|
0x00, 0x11, 0xa4, 0x00, 0x00, 0x11, 0xd2, 0x00, 0x00, 0x12, 0x11, 0x00, 0x00, 0x12, 0x54, 0x00,
|
|
0x00, 0x12, 0x81, 0x00, 0x00, 0x12, 0xd0, 0x00, 0x00, 0x12, 0xfe, 0x00, 0x00, 0x13, 0x5b, 0x00,
|
|
0x00, 0x13, 0x9e, 0x00, 0x00, 0x13, 0xcd, 0x00, 0x00, 0x14, 0x11, 0x00, 0x00, 0x14, 0x4d, 0x00,
|
|
0x00, 0x14, 0x81, 0x00, 0x00, 0x14, 0xcd, 0x00, 0x00, 0x15, 0x0f, 0x00, 0x00, 0x15, 0x3e, 0x00,
|
|
0x00, 0x15, 0x78, 0x00, 0x00, 0x15, 0xa8, 0x00, 0x00, 0x15, 0xf7, 0x00, 0x00, 0x16, 0x3c, 0x00,
|
|
0x00, 0x16, 0x6e, 0x00, 0x00, 0x16, 0xa9, 0x00, 0x00, 0x16, 0xd8, 0x00, 0x00, 0x17, 0x0c, 0x00,
|
|
0x00, 0x17, 0x3b, 0x00, 0x00, 0x00, 0x1a, 0x73, 0x67, 0x70, 0x64, 0x01, 0x00, 0x00, 0x00, 0x72,
|
|
0x6f, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0x00, 0x00, 0x00,
|
|
0x1c, 0x73, 0x62, 0x67, 0x70, 0x00, 0x00, 0x00, 0x00, 0x72, 0x6f, 0x6c, 0x6c, 0x00, 0x00, 0x00,
|
|
0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3d, 0x75, 0x64, 0x74,
|
|
0x61, 0x00, 0x00, 0x00, 0x35, 0x6d, 0x65, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x21, 0x68, 0x64, 0x6c, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x64, 0x69,
|
|
0x72, 0x61, 0x70, 0x70, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x08, 0x69, 0x6c, 0x73, 0x74, 0x00, 0x00, 0x00, 0x08, 0x66, 0x72, 0x65, 0x65, 0x00, 0x00,
|
|
0x0b, 0xe4, 0x6d, 0x64, 0x61, 0x74, 0x00, 0x00, 0x00, 0x2d, 0x65, 0x88, 0x81, 0x00, 0x0a, 0xff,
|
|
0xfe, 0xf7, 0xd4, 0xb7, 0xcc, 0xb2, 0xed, 0x78, 0x7e, 0xb6, 0x0b, 0xa8, 0xf7, 0xa0, 0xe3, 0x03,
|
|
0xf2, 0x84, 0x24, 0x3b, 0x57, 0xd1, 0x76, 0x6b, 0xa8, 0xfa, 0xfc, 0x01, 0x87, 0xd1, 0x55, 0x97,
|
|
0xbb, 0x94, 0x2d, 0x98, 0xbc, 0x9d, 0x1d, 0x00, 0x00, 0x00, 0x10, 0x41, 0x9a, 0x08, 0xd8, 0x46,
|
|
0x03, 0x38, 0x19, 0x10, 0xaf, 0xfe, 0xda, 0xa6, 0x58, 0xce, 0x80, 0x21, 0x10, 0x04, 0x60, 0x8c,
|
|
0x1c, 0x01, 0x50, 0x4a, 0x0a, 0x8a, 0xae, 0xfe, 0x78, 0xf6, 0xe3, 0x5a, 0xb6, 0xa5, 0xdc, 0x97,
|
|
0x63, 0xe9, 0xf4, 0xfa, 0x27, 0x02, 0x9a, 0x69, 0xb2, 0xf1, 0xaa, 0xa1, 0x34, 0xd3, 0x14, 0x55,
|
|
0x55, 0x56, 0x59, 0xa6, 0x8a, 0x2e, 0x3c, 0x78, 0xfc, 0xb2, 0xe5, 0xe0, 0x00, 0x00, 0x00, 0x09,
|
|
0x41, 0x9e, 0x10, 0x4e, 0x21, 0x5f, 0x00, 0x05, 0x3d, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01,
|
|
0x3c, 0x88, 0xda, 0x65, 0x91, 0x76, 0x49, 0xc1, 0x46, 0x9f, 0x8f, 0x3f, 0xd7, 0xc7, 0xef, 0xe7,
|
|
0xf4, 0xf5, 0xfb, 0xf9, 0xff, 0x5b, 0xfc, 0x79, 0x58, 0xf5, 0x63, 0xc0, 0x06, 0x3d, 0x58, 0xf2,
|
|
0x00, 0x78, 0x8f, 0x8e, 0xe0, 0xa5, 0x35, 0x96, 0xcb, 0x3d, 0xc2, 0x8b, 0xdf, 0xec, 0xa4, 0x58,
|
|
0x76, 0x3f, 0x96, 0xcb, 0xeb, 0x9e, 0xb4, 0x58, 0xb5, 0x49, 0xfc, 0xdb, 0x74, 0x88, 0x43, 0x13,
|
|
0x3e, 0x51, 0x32, 0xcb, 0x9e, 0xb3, 0x81, 0x3c, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x3a,
|
|
0xea, 0x0a, 0x8c, 0x9f, 0xb7, 0xf5, 0xfd, 0x7a, 0xbe, 0x3c, 0xea, 0xfa, 0x9a, 0x9a, 0x6a, 0xc1,
|
|
0xfe, 0x0c, 0x97, 0xdc, 0xf8, 0x6d, 0xb3, 0x0f, 0x7d, 0x00, 0x7c, 0x66, 0x03, 0x3e, 0x80, 0x32,
|
|
0x7c, 0x01, 0x9f, 0xdc, 0x0f, 0x8c, 0xdc, 0x00, 0x00, 0x00, 0x09, 0x01, 0x9e, 0x18, 0x9a, 0x90,
|
|
0x9f, 0x00, 0x0b, 0x28, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x08, 0x2a, 0x06, 0x8e, 0xf9,
|
|
0xff, 0x5f, 0xfe, 0xbf, 0xf9, 0x7f, 0xa7, 0xfc, 0xca, 0xb9, 0xaa, 0xad, 0x6f, 0xdb, 0x90, 0xad,
|
|
0x6b, 0x6b, 0x78, 0xa3, 0x1d, 0x5a, 0xb5, 0x43, 0x54, 0x35, 0x15, 0x42, 0x15, 0xad, 0x5a, 0xb1,
|
|
0x56, 0xa4, 0x1c, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x0a, 0x2a, 0x06, 0x8d, 0xf7, 0xfd,
|
|
0xff, 0xfa, 0xff, 0xb7, 0xfd, 0x7f, 0xe6, 0x54, 0xba, 0xb7, 0x14, 0xaa, 0x1f, 0xcb, 0x2d, 0xab,
|
|
0x5b, 0xc2, 0x1b, 0x2d, 0xb3, 0x64, 0xf6, 0x46, 0x36, 0x23, 0x6f, 0x5a, 0x64, 0x6d, 0x61, 0x4e,
|
|
0x00, 0x00, 0x00, 0x1b, 0x41, 0x9a, 0x19, 0x92, 0xea, 0x04, 0x08, 0x10, 0x16, 0x88, 0x23, 0x01,
|
|
0x84, 0x0f, 0x90, 0x18, 0x40, 0xf0, 0x02, 0x15, 0xff, 0xfe, 0xda, 0xa6, 0x58, 0xce, 0x81, 0x21,
|
|
0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x0c, 0x2a, 0x06, 0x8e, 0x79, 0xfe, 0x9f, 0xfd, 0x7f, 0x9f,
|
|
0xfe, 0xdf, 0xe9, 0x95, 0x77, 0x5c, 0x15, 0xd7, 0x76, 0x37, 0xd2, 0x92, 0xa4, 0xf0, 0xd3, 0x7e,
|
|
0xfd, 0xfb, 0xe9, 0x7a, 0x2f, 0xed, 0xbd, 0x29, 0x4d, 0xea, 0x5e, 0xeb, 0x11, 0xaf, 0x00, 0x00,
|
|
0x00, 0x0a, 0x41, 0x9e, 0x21, 0x0b, 0x88, 0x57, 0xff, 0x00, 0x05, 0x3d, 0x21, 0x10, 0x04, 0x60,
|
|
0x8c, 0x1c, 0x01, 0x0a, 0x2a, 0x06, 0x8e, 0x7b, 0xfe, 0xdf, 0xfe, 0xdf, 0xcf, 0xff, 0x7f, 0xf3,
|
|
0x8b, 0x92, 0xcc, 0xeb, 0x9a, 0x12, 0x94, 0xa9, 0x2b, 0xc7, 0xa6, 0xbd, 0x7a, 0xf5, 0xca, 0x53,
|
|
0x9f, 0xa7, 0xd3, 0x32, 0x49, 0xcb, 0x5c, 0x93, 0x99, 0x2e, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c,
|
|
0x01, 0x06, 0x2a, 0x06, 0x8e, 0xfb, 0xfe, 0xff, 0xfd, 0x7f, 0xdf, 0xfe, 0x7f, 0xde, 0xea, 0x4e,
|
|
0x29, 0x2e, 0xaf, 0x6d, 0x08, 0xc8, 0xd8, 0xfe, 0x11, 0xb1, 0xf0, 0x21, 0x6b, 0x5a, 0xb5, 0x9c,
|
|
0x21, 0x6d, 0x9b, 0x36, 0x5d, 0xb5, 0x64, 0x63, 0x14, 0x7d, 0x47, 0x68, 0xbd, 0x46, 0xde, 0x00,
|
|
0x00, 0x00, 0x0a, 0x01, 0x9e, 0x29, 0x59, 0x24, 0x27, 0xff, 0x00, 0x0b, 0x29, 0x21, 0x10, 0x04,
|
|
0x60, 0x8c, 0x1c, 0x01, 0x0a, 0x2a, 0x06, 0x8e, 0x79, 0xff, 0x5f, 0xfe, 0xbf, 0xf9, 0x7f, 0x9f,
|
|
0xf6, 0xba, 0x92, 0x47, 0x5e, 0x3c, 0xf7, 0xc0, 0xd5, 0x5a, 0xda, 0xdf, 0x78, 0xc7, 0x56, 0xad,
|
|
0x4d, 0x48, 0x41, 0x54, 0x2b, 0xaa, 0xa2, 0xaa, 0x8c, 0x5c, 0x00, 0x00, 0x00, 0x1d, 0x41, 0x9a,
|
|
0x2a, 0x53, 0xea, 0x04, 0x08, 0x10, 0x16, 0xd6, 0x88, 0x23, 0x01, 0x5c, 0x05, 0x24, 0x05, 0x70,
|
|
0x14, 0x00, 0x02, 0x15, 0xff, 0xfe, 0xda, 0xa6, 0x58, 0xce, 0x81, 0x21, 0x10, 0x04, 0x60, 0x8c,
|
|
0x1c, 0x01, 0x0c, 0x2a, 0x06, 0x8d, 0xf3, 0xfd, 0xff, 0xfa, 0x7f, 0x3f, 0xf9, 0xff, 0xce, 0x2f,
|
|
0x2f, 0x85, 0xe4, 0x72, 0x3c, 0x72, 0x96, 0x2c, 0xf7, 0x84, 0x25, 0xaf, 0xf9, 0x78, 0xe6, 0x93,
|
|
0x5c, 0xe7, 0xd3, 0x59, 0xc1, 0x29, 0x49, 0x62, 0x5c, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01,
|
|
0x0c, 0x2a, 0x06, 0x8e, 0x79, 0xfe, 0xdf, 0xfe, 0xdf, 0xbf, 0xff, 0x8f, 0xfa, 0x65, 0x5b, 0x4e,
|
|
0x2b, 0x7d, 0x6e, 0x0a, 0x52, 0x92, 0xa4, 0xe7, 0x4d, 0xfb, 0xf7, 0xaf, 0x7b, 0xdf, 0x7b, 0x7d,
|
|
0x28, 0xb2, 0x97, 0x53, 0x25, 0xd0, 0xb7, 0x00, 0x00, 0x00, 0x0a, 0x41, 0x9e, 0x31, 0xc9, 0x62,
|
|
0x15, 0xff, 0x00, 0x05, 0x3c, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x02, 0x2a, 0x0a, 0x8f,
|
|
0x1d, 0xff, 0x7f, 0xfe, 0xbf, 0xe3, 0xff, 0x6f, 0xf9, 0x84, 0xb6, 0xab, 0x38, 0xca, 0x68, 0x46,
|
|
0x47, 0xc3, 0xe0, 0x8d, 0x92, 0x00, 0x04, 0xc9, 0x26, 0x0e, 0xa8, 0xc6, 0xfd, 0xf7, 0xf2, 0x64,
|
|
0x4c, 0x79, 0x01, 0x08, 0xc4, 0x83, 0xc1, 0x89, 0x24, 0xad, 0x40, 0x1f, 0x80, 0x00, 0x00, 0x00,
|
|
0x0a, 0x01, 0x9e, 0x3a, 0x19, 0xa4, 0x27, 0xff, 0x00, 0x0b, 0x28, 0x21, 0x10, 0x04, 0x60, 0x8c,
|
|
0x1c, 0x01, 0x0a, 0x2a, 0x06, 0x8e, 0x7b, 0xfe, 0xff, 0xfd, 0x7f, 0xf2, 0xff, 0x4f, 0xf9, 0x27,
|
|
0x15, 0x75, 0xd7, 0x3a, 0x72, 0xd0, 0x8c, 0x8e, 0x40, 0xe1, 0x1b, 0x00, 0xde, 0x16, 0xb5, 0xab,
|
|
0x5e, 0x50, 0x85, 0xb6, 0x6c, 0x6c, 0xd9, 0x68, 0xec, 0x23, 0x68, 0xad, 0x72, 0x9c, 0x2e, 0x8b,
|
|
0x80, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x0c, 0x2a, 0x0a, 0x8c, 0xe7, 0xfd, 0x7f, 0xfa,
|
|
0xff, 0x9f, 0xfc, 0xbf, 0xe4, 0x9a, 0xc8, 0xe3, 0x9e, 0x39, 0xe0, 0x7c, 0xb6, 0x3e, 0xea, 0xd8,
|
|
0x63, 0x65, 0xcb, 0x14, 0x59, 0x62, 0x98, 0xe8, 0x40, 0x28, 0xa6, 0x42, 0x88, 0x10, 0x40, 0x04,
|
|
0x9e, 0x00, 0x00, 0x00, 0x2c, 0x65, 0x88, 0x80, 0x80, 0x02, 0xbf, 0xfe, 0xf7, 0xd4, 0xb7, 0xcc,
|
|
0xb2, 0xcd, 0xa7, 0xeb, 0x60, 0xba, 0x8f, 0x7a, 0x0e, 0x30, 0x3d, 0xb0, 0x24, 0x3b, 0x57, 0xd1,
|
|
0x76, 0x6b, 0xa8, 0xfa, 0xfc, 0x01, 0x87, 0xd1, 0x55, 0x97, 0xbb, 0x94, 0x2d, 0x98, 0xbc, 0x9d,
|
|
0x1d, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x0c, 0x2a, 0x06, 0x8e, 0x79, 0xfe, 0x9f, 0xfd,
|
|
0x7f, 0x9f, 0xff, 0x1f, 0xf1, 0x95, 0x35, 0x1a, 0xaa, 0xbc, 0xb1, 0x29, 0x4a, 0x92, 0xbd, 0xe5,
|
|
0xaf, 0x5c, 0xe7, 0x29, 0xcf, 0x5a, 0x7a, 0xe3, 0x29, 0x58, 0x49, 0x59, 0xa1, 0x4e, 0x21, 0x10,
|
|
0x04, 0x60, 0x8c, 0x1c, 0x01, 0x08, 0x2a, 0x06, 0x8e, 0xf9, 0xff, 0x5f, 0xff, 0x0f, 0xdf, 0xff,
|
|
0x9f, 0xf3, 0x51, 0x5d, 0x5a, 0x77, 0xc6, 0x41, 0x4a, 0x52, 0x58, 0xa7, 0x08, 0x53, 0x7e, 0xf5,
|
|
0xdb, 0xfc, 0xbe, 0x5a, 0x5e, 0x9f, 0x87, 0x96, 0xd7, 0xba, 0x8b, 0x91, 0x70, 0x00, 0x00, 0x00,
|
|
0x10, 0x41, 0x9a, 0x08, 0xd8, 0xb8, 0xe0, 0x12, 0x04, 0x2b, 0xff, 0xfe, 0xda, 0xa6, 0x58, 0xce,
|
|
0x80, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x06, 0x2a, 0x0a, 0x8e, 0xfb, 0xff, 0x8f, 0xff,
|
|
0x6f, 0xfa, 0xff, 0xbf, 0xfb, 0x5d, 0x5a, 0xe6, 0xaa, 0xad, 0xcb, 0x42, 0x32, 0x31, 0x27, 0x04,
|
|
0x6c, 0x02, 0x40, 0x21, 0x08, 0x5a, 0xe1, 0x31, 0xa2, 0x8a, 0x28, 0xa2, 0x08, 0x8a, 0x24, 0x45,
|
|
0x10, 0x42, 0x10, 0xc0, 0x48, 0x5b, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x09, 0x41, 0x9e, 0x10, 0x4e,
|
|
0x21, 0x3f, 0x00, 0x0b, 0x28, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x0a, 0x2a, 0x06, 0x8e,
|
|
0x79, 0xff, 0x5f, 0xfe, 0xbf, 0xf7, 0xff, 0x6f, 0xf7, 0x89, 0x25, 0xa4, 0x6e, 0xc7, 0xf2, 0xb5,
|
|
0xab, 0x5d, 0x10, 0x85, 0xb6, 0x46, 0x3e, 0xa8, 0xf4, 0xb4, 0x51, 0x8c, 0x6d, 0xc9, 0x11, 0x61,
|
|
0x6e, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x0c, 0x2a, 0x06, 0x8d, 0xf7, 0xfd, 0x3f, 0xfd,
|
|
0xbf, 0x7f, 0xfe, 0x7f, 0xdb, 0x11, 0x7a, 0x6b, 0x9d, 0x66, 0x0d, 0xf4, 0xa6, 0x5d, 0xb3, 0x8f,
|
|
0x6d, 0xfb, 0xf7, 0xae, 0x53, 0x7d, 0x6f, 0x83, 0x7e, 0x9d, 0xf5, 0x85, 0x05, 0xca, 0x70, 0x00,
|
|
0x00, 0x00, 0x09, 0x01, 0x9e, 0x18, 0x9a, 0x90, 0x9f, 0x00, 0x0b, 0x29, 0x21, 0x10, 0x04, 0x60,
|
|
0x8c, 0x1c, 0x01, 0x0a, 0x2a, 0x06, 0x8e, 0xf9, 0xfe, 0xdf, 0xfe, 0xdf, 0xcf, 0xff, 0x8f, 0xf8,
|
|
0xdc, 0x69, 0x2e, 0x61, 0x4d, 0x08, 0xc8, 0xe8, 0x0e, 0x11, 0xb0, 0x4f, 0xc1, 0x29, 0x4a, 0x92,
|
|
0xbd, 0xe5, 0x2d, 0x7a, 0xd2, 0x94, 0xe5, 0xae, 0x73, 0x96, 0xb5, 0xa7, 0x31, 0x51, 0x2e, 0x00,
|
|
0x00, 0x00, 0x1b, 0x41, 0x9a, 0x19, 0x52, 0xea, 0x04, 0x08, 0x10, 0x16, 0x88, 0x23, 0x04, 0xc0,
|
|
0x36, 0x90, 0x4c, 0x03, 0x60, 0x02, 0x15, 0xff, 0xfe, 0xda, 0xa6, 0x58, 0xce, 0x81, 0x21, 0x10,
|
|
0x04, 0x60, 0x8c, 0x1c, 0x01, 0x02, 0x2a, 0x09, 0xa2, 0x77, 0x8e, 0xff, 0xbf, 0xff, 0xc5, 0xfe,
|
|
0x7f, 0xf2, 0xff, 0x7b, 0xa9, 0xaa, 0xb9, 0x26, 0xc0, 0xbc, 0x30, 0x91, 0x0c, 0x22, 0xa2, 0x83,
|
|
0x1a, 0xbe, 0x9c, 0x3a, 0x62, 0xd8, 0xb4, 0x6c, 0xba, 0x85, 0xcb, 0x70, 0x21, 0x10, 0x04, 0x60,
|
|
0x8c, 0x1c, 0x01, 0x0a, 0x2a, 0x09, 0xe2, 0x57, 0x3d, 0xff, 0x7f, 0xfe, 0xbf, 0xf9, 0x7f, 0xa7,
|
|
0xfc, 0xc3, 0x4b, 0x95, 0xbe, 0xab, 0x02, 0x10, 0x85, 0xae, 0x53, 0x1a, 0x28, 0x8a, 0x28, 0xa2,
|
|
0x8a, 0x28, 0xa2, 0x88, 0xa0, 0xab, 0x52, 0xa5, 0x4a, 0x70, 0x00, 0x00, 0x00, 0x09, 0x01, 0x9e,
|
|
0x21, 0x0b, 0x90, 0x9f, 0x00, 0x0b, 0x29, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x0c, 0x2a,
|
|
0x11, 0x62, 0x96, 0x73, 0xfe, 0xbf, 0xfe, 0xdf, 0xe3, 0xff, 0x6f, 0xfa, 0xd2, 0x24, 0xbe, 0x3c,
|
|
0x6b, 0x9b, 0x68, 0x46, 0x46, 0x24, 0x60, 0x8d, 0xf3, 0xf0, 0xe0, 0x98, 0x61, 0x8a, 0x3c, 0xd4,
|
|
0xa1, 0x25, 0x42, 0x57, 0xb1, 0x1b, 0x5a, 0x6c, 0x3c, 0x30, 0xa7, 0x17, 0x45, 0x88, 0xb8, 0x00,
|
|
0x00, 0x00, 0x3b, 0x41, 0x9a, 0x22, 0x12, 0xf8, 0x10, 0x29, 0x68, 0x99, 0x4c, 0x02, 0x15, 0xff,
|
|
0xe3, 0x43, 0xff, 0x9f, 0xd8, 0xff, 0xc0, 0xf8, 0xb6, 0xdf, 0xc2, 0x52, 0x94, 0x69, 0x14, 0xc9,
|
|
0x47, 0x2f, 0x8e, 0x9b, 0x7e, 0x4d, 0x5f, 0x02, 0xd9, 0x86, 0xa1, 0x7a, 0x02, 0x92, 0x01, 0xc9,
|
|
0x0c, 0x46, 0x22, 0xe8, 0xf7, 0x55, 0xf6, 0xfe, 0x47, 0xfd, 0xed, 0x00, 0x0c, 0x98, 0x21, 0x10,
|
|
0x04, 0x60, 0x8c, 0x1c, 0x01, 0x0c, 0x2a, 0x06, 0x8e, 0x79, 0xfe, 0xdf, 0xfe, 0xdf, 0xbf, 0xff,
|
|
0x8f, 0xfa, 0x60, 0xe2, 0xd7, 0xba, 0xd5, 0x0a, 0x52, 0x92, 0xa4, 0xe7, 0x4d, 0xfb, 0xf7, 0xde,
|
|
0xeb, 0xef, 0xdf, 0x4a, 0x7b, 0xb7, 0xdf, 0xca, 0xb9, 0x4b, 0x09, 0x70, 0x21, 0x10, 0x04, 0x60,
|
|
0x8c, 0x1c, 0x01, 0x06, 0x2a, 0x06, 0x8e, 0xfb, 0xfe, 0xff, 0xfd, 0x3f, 0x9f, 0xfc, 0xff, 0xda,
|
|
0x49, 0x97, 0x3a, 0xac, 0x50, 0x4a, 0x52, 0xdb, 0x96, 0xf1, 0x8e, 0xbf, 0x4f, 0xe5, 0x29, 0xa5,
|
|
0x24, 0xfd, 0x29, 0x57, 0x5c, 0xe6, 0x27, 0x34, 0x1c, 0x00, 0x00, 0x00, 0x0e, 0x41, 0x9e, 0x29,
|
|
0x89, 0x22, 0x15, 0xff, 0x1e, 0xa6, 0xf6, 0x3e, 0xe2, 0xb7, 0xf8, 0x21, 0x10, 0x04, 0x60, 0x8c,
|
|
0x1c, 0x01, 0x08, 0x2a, 0x06, 0x8e, 0x7b, 0xff, 0x5f, 0xfe, 0xbf, 0xf9, 0x7f, 0x9f, 0xf6, 0xba,
|
|
0xb6, 0x9a, 0xac, 0xb4, 0x68, 0x46, 0x47, 0xe0, 0x60, 0x8d, 0xf3, 0xc1, 0x0b, 0x5a, 0xd5, 0xaf,
|
|
0x86, 0x10, 0xb4, 0x76, 0x6c, 0xd8, 0xb4, 0x6c, 0xd9, 0x68, 0xd9, 0x68, 0xa2, 0xad, 0x91, 0xa7,
|
|
0x00, 0x00, 0x00, 0x0a, 0x01, 0x9e, 0x31, 0xd9, 0x64, 0x27, 0xff, 0x00, 0x0b, 0x29, 0x21, 0x10,
|
|
0x04, 0x60, 0x8c, 0x1c, 0x01, 0x0a, 0x2a, 0x06, 0x8d, 0xf7, 0xfd, 0xff, 0xfa, 0xff, 0xbf, 0xfc,
|
|
0xff, 0xbc, 0x8b, 0xae, 0x23, 0x9e, 0x2a, 0x87, 0xf3, 0xad, 0x6d, 0x69, 0xc6, 0x3a, 0xb5, 0x6a,
|
|
0x85, 0xd0, 0x42, 0x1a, 0xbc, 0xea, 0xd5, 0x80, 0x69, 0x12, 0xe0, 0x21, 0x10, 0x04, 0x60, 0x8c,
|
|
0x1c, 0x01, 0x0c, 0x2a, 0x06, 0x8e, 0x79, 0xfe, 0x9f, 0xfd, 0x7f, 0x9f, 0xfe, 0xff, 0xed, 0x95,
|
|
0x72, 0xea, 0xd3, 0x38, 0xc1, 0xae, 0x52, 0xa4, 0xaf, 0x09, 0x6b, 0xd7, 0xae, 0x52, 0x9c, 0xf0,
|
|
0xce, 0x72, 0xf8, 0x25, 0x6b, 0x4c, 0x5a, 0xe8, 0x5b, 0x80, 0x00, 0x00, 0x00, 0x1c, 0x41, 0x9a,
|
|
0x32, 0x51, 0x1a, 0x81, 0x02, 0x04, 0x05, 0xaa, 0x5a, 0x21, 0x30, 0xb0, 0x18, 0x50, 0xb0, 0x18,
|
|
0xc0, 0x00, 0x85, 0x7f, 0xfe, 0xda, 0xa6, 0x58, 0xce, 0x80, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c,
|
|
0x01, 0x0a, 0x2a, 0x06, 0x8e, 0xf9, 0xfe, 0xdf, 0xfe, 0xdf, 0xcf, 0xff, 0x6f, 0xf3, 0xcc, 0x97,
|
|
0x57, 0xaa, 0xde, 0xb2, 0x85, 0x29, 0x49, 0x52, 0x79, 0xa9, 0x4b, 0xdf, 0x7d, 0x37, 0xd1, 0xbd,
|
|
0xbe, 0xea, 0x5a, 0xf7, 0x51, 0x6b, 0x94, 0xe0, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x04,
|
|
0x2a, 0x06, 0x8e, 0xfb, 0xff, 0xa7, 0xff, 0x4f, 0xf6, 0xff, 0xaf, 0xfc, 0xca, 0x97, 0x2e, 0x2a,
|
|
0x02, 0xb5, 0xad, 0xad, 0x78, 0xc6, 0xba, 0xb5, 0x27, 0x0a, 0xc2, 0x19, 0xb5, 0x21, 0xd7, 0x5a,
|
|
0x05, 0x67, 0x54, 0x73, 0xf0, 0x00, 0x00, 0x00, 0x2c, 0x65, 0x88, 0x81, 0x00, 0x0a, 0xff, 0xfe,
|
|
0xf7, 0xd4, 0xb7, 0xcc, 0xb2, 0xc0, 0x26, 0xfb, 0x60, 0xba, 0x8f, 0x7a, 0x0e, 0x30, 0x3d, 0x2e,
|
|
0x65, 0x3b, 0x57, 0xd1, 0x76, 0x6b, 0xa8, 0xfa, 0xfc, 0x01, 0x87, 0xd1, 0x55, 0x97, 0xbb, 0x94,
|
|
0x2d, 0x98, 0xbc, 0x9d, 0x1d, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x0a, 0x2a, 0x06, 0x8e,
|
|
0x79, 0xff, 0x5f, 0xfe, 0xbf, 0xf9, 0x7f, 0xa7, 0xfc, 0xc2, 0x5d, 0xcb, 0xa4, 0xc1, 0xb2, 0xd6,
|
|
0xad, 0x7e, 0x30, 0x85, 0xb6, 0x6c, 0xb6, 0xc4, 0x51, 0xd9, 0xb1, 0x68, 0xf2, 0xbe, 0x14, 0xad,
|
|
0x31, 0x97, 0x80, 0x00, 0x00, 0x00, 0x11, 0x41, 0x9a, 0x08, 0xd8, 0xf8, 0x0d, 0x20, 0x14, 0xa4,
|
|
0x2b, 0xff, 0xfe, 0xda, 0xa6, 0x58, 0xce, 0x81, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x0c,
|
|
0x2a, 0x09, 0xe2, 0x56, 0xf9, 0xfe, 0xff, 0xfd, 0x3f, 0x9f, 0xfc, 0xff, 0xeb, 0x89, 0x5c, 0x45,
|
|
0xed, 0x90, 0x6c, 0x9c, 0xee, 0xe0, 0xc3, 0x57, 0xf2, 0xe6, 0xe6, 0x52, 0x87, 0x18, 0x76, 0x09,
|
|
0xd5, 0x81, 0x7d, 0x37, 0x15, 0x14, 0xe0, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x0c, 0x2a,
|
|
0x06, 0x8e, 0x79, 0xfe, 0xdf, 0xfe, 0xdf, 0xbf, 0xff, 0x8f, 0xf9, 0xe6, 0x4a, 0x97, 0x7a, 0xe7,
|
|
0xae, 0xf4, 0xd0, 0x8c, 0x8e, 0x00, 0xc1, 0x1b, 0xe7, 0x82, 0x12, 0x94, 0xa9, 0x2b, 0xde, 0x52,
|
|
0xd7, 0xae, 0x73, 0x48, 0x9c, 0xe7, 0x39, 0xd9, 0xaf, 0x5e, 0x62, 0x73, 0x8d, 0x78, 0x00, 0x00,
|
|
0x00, 0x09, 0x41, 0x9e, 0x10, 0x5e, 0x21, 0x5f, 0x00, 0x05, 0x3c, 0x21, 0x10, 0x04, 0x60, 0x8c,
|
|
0x1c, 0x01, 0x04, 0x2a, 0x09, 0xe2, 0x57, 0x7d, 0xff, 0x7f, 0xfe, 0xbf, 0xe3, 0xff, 0x3f, 0xf6,
|
|
0xb2, 0x5c, 0xb6, 0x4a, 0xa0, 0x73, 0x9e, 0x47, 0xd8, 0x45, 0xd1, 0xd1, 0xfa, 0x5d, 0x07, 0x68,
|
|
0xcb, 0x5f, 0xea, 0x7f, 0xc1, 0x64, 0x46, 0x4b, 0x12, 0xe0, 0x00, 0x00, 0x00, 0x09, 0x01, 0x9e,
|
|
0x18, 0x9a, 0x90, 0x9f, 0x00, 0x0b, 0x29, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x0a, 0x2a,
|
|
0x06, 0x8e, 0x79, 0xff, 0x5f, 0xfe, 0xbf, 0xf9, 0x7f, 0xa7, 0xfb, 0xda, 0x4d, 0x55, 0xce, 0x78,
|
|
0x6d, 0xa1, 0x19, 0x1f, 0xbe, 0x42, 0x37, 0xc0, 0x24, 0x2b, 0x5a, 0xda, 0xdb, 0xa3, 0x1d, 0x5a,
|
|
0xb5, 0x41, 0x0d, 0x4a, 0xb5, 0x2b, 0x0a, 0xae, 0x82, 0xc4, 0x1c, 0x21, 0x10, 0x04, 0x60, 0x8c,
|
|
0x1c, 0x01, 0x0a, 0x2a, 0x09, 0x62, 0x96, 0xf9, 0xfe, 0xff, 0xff, 0x17, 0xfb, 0x7f, 0xdf, 0xfd,
|
|
0xae, 0xae, 0x2e, 0xd9, 0x6a, 0x1f, 0x4d, 0xce, 0xbe, 0x85, 0x11, 0x3a, 0x6a, 0x35, 0xa3, 0x18,
|
|
0xb8, 0x5a, 0x71, 0x92, 0x73, 0x1a, 0xc5, 0x38, 0x00, 0x00, 0x00, 0x1b, 0x41, 0x9a, 0x19, 0x92,
|
|
0xea, 0x04, 0x08, 0x10, 0x16, 0x88, 0x7c, 0x05, 0x90, 0x19, 0x50, 0x16, 0x40, 0x67, 0x00, 0x85,
|
|
0x7f, 0xfe, 0xda, 0xa6, 0x58, 0xce, 0x81, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x0c, 0x2a,
|
|
0x06, 0x8e, 0x79, 0xfe, 0xdf, 0xfe, 0xdf, 0xcf, 0xff, 0x8f, 0xf8, 0xc3, 0x59, 0xc5, 0x6b, 0x2f,
|
|
0x7a, 0x68, 0x46, 0x46, 0x24, 0xf0, 0x8d, 0xf0, 0x7f, 0x0a, 0x52, 0x92, 0xa4, 0xf0, 0xd3, 0x7e,
|
|
0xfd, 0xea, 0x5e, 0x8d, 0xe5, 0xd4, 0xde, 0x52, 0x85, 0xef, 0x17, 0x00, 0x00, 0x00, 0x0a, 0x41,
|
|
0x9e, 0x21, 0x1b, 0x88, 0x57, 0xff, 0x00, 0x05, 0x3c, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01,
|
|
0x08, 0x2a, 0x0a, 0x8e, 0xfb, 0xfe, 0x9f, 0xfd, 0x7f, 0x9f, 0xfe, 0x7f, 0xdf, 0x07, 0x09, 0x37,
|
|
0xe7, 0xc6, 0x82, 0x52, 0x9c, 0x1d, 0x51, 0xa0, 0x79, 0x8f, 0x31, 0x81, 0x97, 0x3c, 0xc4, 0xbc,
|
|
0xc4, 0x86, 0x62, 0xc4, 0x04, 0x06, 0x5c, 0x9e, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x06,
|
|
0x2a, 0x06, 0x8e, 0xfb, 0xff, 0x8f, 0xff, 0x6f, 0xfa, 0xff, 0xbf, 0xfc, 0x92, 0x5b, 0x4a, 0xd6,
|
|
0x6c, 0x5a, 0xd6, 0xad, 0x70, 0xc2, 0x1b, 0x23, 0x18, 0xfb, 0x0b, 0x46, 0xd6, 0xb2, 0xcb, 0x4e,
|
|
0x91, 0xb5, 0xc5, 0x38, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x9e, 0x29, 0x59, 0x24, 0x27, 0xff, 0x00,
|
|
0x0b, 0x29, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x0a, 0x2a, 0x0a, 0x8e, 0x79, 0xfe, 0xff,
|
|
0xff, 0x17, 0xfd, 0xff, 0xdb, 0xfe, 0x48, 0xbd, 0x4a, 0xe7, 0xe3, 0x30, 0x71, 0x42, 0x16, 0xbb,
|
|
0x8c, 0x68, 0xa2, 0x8a, 0x28, 0x81, 0x14, 0x45, 0x12, 0x09, 0x08, 0x0a, 0xca, 0x10, 0xd7, 0x20,
|
|
0x11, 0xc0, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x0c, 0x2a, 0x06, 0x8d, 0xf7, 0xfd, 0x3f,
|
|
0xfd, 0xbf, 0x7f, 0xfd, 0x7f, 0xe7, 0x0a, 0xbe, 0x2a, 0xf3, 0xaf, 0x14, 0x35, 0xca, 0x58, 0xb3,
|
|
0xde, 0x12, 0xd7, 0xaf, 0x5c, 0xe6, 0x94, 0xbc, 0x7e, 0x34, 0xe5, 0x65, 0xa5, 0x38, 0xad, 0x32,
|
|
0x5c, 0x00, 0x00, 0x00, 0x1c, 0x41, 0x9a, 0x2a, 0x53, 0xea, 0x04, 0x08, 0x10, 0x16, 0xd6, 0x88,
|
|
0x6c, 0x0a, 0x40, 0x49, 0x40, 0xa4, 0x04, 0xb0, 0x00, 0x84, 0xff, 0xfe, 0xd6, 0xa5, 0x50, 0xce,
|
|
0x80, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x0a, 0x2a, 0x06, 0x8e, 0xf9, 0xfe, 0xdf, 0xfe,
|
|
0xdf, 0xbf, 0xff, 0xa7, 0xf8, 0xdc, 0x92, 0x71, 0x9a, 0xe7, 0x57, 0xb6, 0x84, 0x64, 0x5e, 0x41,
|
|
0x08, 0xd9, 0x1c, 0x82, 0xa5, 0x29, 0x2a, 0x4e, 0x74, 0xdf, 0x7d, 0xf4, 0xa5, 0xef, 0x4d, 0xfe,
|
|
0x5a, 0x5e, 0xf7, 0xb0, 0xa1, 0x64, 0x29, 0xc0, 0x00, 0x00, 0x00, 0x0a, 0x41, 0x9e, 0x31, 0xd9,
|
|
0x62, 0x15, 0xff, 0x00, 0x05, 0x3d, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x00, 0x2a, 0x0a,
|
|
0x8f, 0x5d, 0xff, 0x7f, 0xff, 0x8b, 0xfc, 0xff, 0xe5, 0xfe, 0xda, 0xa9, 0xaa, 0xb9, 0xae, 0xf5,
|
|
0xcf, 0x02, 0x49, 0x24, 0xc1, 0xd5, 0x18, 0xd2, 0x11, 0x45, 0xdd, 0xfb, 0x08, 0x88, 0x72, 0x64,
|
|
0x57, 0x3c, 0x00, 0x90, 0x20, 0x31, 0x2f, 0xf0, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x0a,
|
|
0x2a, 0x06, 0x8e, 0x7b, 0xfe, 0xff, 0xfd, 0x7f, 0xf2, 0xff, 0x4f, 0xf7, 0xb3, 0x46, 0x89, 0x36,
|
|
0x2d, 0x6b, 0x56, 0xbc, 0xa1, 0x0d, 0x9b, 0x36, 0x23, 0xb3, 0x65, 0xad, 0x6d, 0x88, 0x99, 0x08,
|
|
0xda, 0xbe, 0xc4, 0x65, 0xc0, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x9e, 0x3a, 0x19, 0xa4, 0x27, 0xff,
|
|
0x00, 0x0b, 0x29, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x0c, 0x2a, 0x0a, 0x8c, 0xe7, 0xfb,
|
|
0xff, 0xf5, 0xff, 0x4f, 0xfc, 0xbf, 0xde, 0x24, 0x70, 0x9b, 0xeb, 0xb0, 0xf9, 0x3e, 0xfb, 0xb8,
|
|
0x30, 0xc6, 0xe3, 0xc7, 0xe5, 0x14, 0x42, 0x60, 0x45, 0xc5, 0x4f, 0x95, 0x4a, 0x04, 0x70, 0xa5,
|
|
0x02, 0x1c, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x0c, 0x2a, 0x06, 0x8e, 0x7b, 0xfe, 0x9f,
|
|
0xfe, 0xdf, 0xbf, 0xff, 0x8f, 0xfa, 0x6e, 0x45, 0xea, 0xaf, 0x35, 0xb8, 0xd0, 0x8c, 0x8f, 0x88,
|
|
0xc1, 0x1b, 0x24, 0x7e, 0x12, 0x94, 0xa9, 0x2b, 0xde, 0x52, 0x9e, 0xbd, 0x73, 0x25, 0xaf, 0x5e,
|
|
0xb9, 0xeb, 0x58, 0x91, 0x61, 0x4e, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x30, 0x2a, 0x0a,
|
|
0x8a, 0xad, 0xff, 0xf5, 0xfd, 0xff, 0xdf, 0x89, 0xab, 0xbb, 0xbb, 0x5c, 0x90, 0x44, 0xf2, 0xe4,
|
|
0x7d, 0x84, 0xc3, 0x2a, 0x26, 0x50, 0xa8, 0x99, 0x42, 0xa2, 0x7a, 0x85, 0x44, 0xf5, 0x13, 0xa1,
|
|
0xea, 0x15, 0x13, 0xc3, 0x80, 0x21, 0x10, 0x04, 0x60, 0x8c, 0x1c, 0x01, 0x56, 0x2a, 0x0a, 0x8a,
|
|
0xac, 0xf9, 0xeb, 0xdb, 0x57, 0x77, 0xab, 0x97, 0x24, 0x96, 0x27, 0x5b, 0xc8, 0xce, 0x4a, 0xa1,
|
|
0x91, 0x4e, 0x1e, 0x8a, 0x7a, 0x1e, 0x44, 0xf4, 0x3c, 0x89, 0xd6, 0xf2, 0x27, 0x5b, 0xc8, 0xe6,
|
|
0x5b, 0xdc
|
|
};
|
|
|
|
void Check(bool condition, const std::string& message) {
|
|
if (!condition) throw std::runtime_error(message);
|
|
}
|
|
|
|
int LumaFor(int frame) {
|
|
return 20 + frame * 7;
|
|
}
|
|
|
|
void WriteMovie() {
|
|
std::filesystem::create_directories("app0");
|
|
std::ofstream file(MoviePath, std::ios::binary | std::ios::trunc);
|
|
file.write(reinterpret_cast<const char*>(Movie.data()), static_cast<std::streamsize>(Movie.size()));
|
|
Check(static_cast<bool>(file), "cannot write the movie");
|
|
}
|
|
|
|
struct Block {
|
|
bool texture;
|
|
std::align_val_t alignment;
|
|
};
|
|
|
|
struct Allocations {
|
|
std::mutex mutex;
|
|
std::map<void*, Block> blocks;
|
|
int textures = 0;
|
|
};
|
|
|
|
Allocations allocations;
|
|
|
|
void* Allocate(std::uint32_t alignment, std::uint32_t size, bool texture) {
|
|
const auto aligned = static_cast<std::align_val_t>(std::max<std::uint32_t>(alignment, 16));
|
|
void* memory = ::operator new(size, aligned);
|
|
std::lock_guard lock(allocations.mutex);
|
|
allocations.blocks[memory] = {texture, aligned};
|
|
if (texture) ++allocations.textures;
|
|
return memory;
|
|
}
|
|
|
|
void Release(void* memory, bool texture) {
|
|
std::align_val_t aligned{};
|
|
{
|
|
std::lock_guard lock(allocations.mutex);
|
|
const auto found = allocations.blocks.find(memory);
|
|
if (found == allocations.blocks.end() || found->second.texture != texture) std::abort();
|
|
aligned = found->second.alignment;
|
|
allocations.blocks.erase(found);
|
|
}
|
|
::operator delete(memory, aligned);
|
|
}
|
|
|
|
void* APS5_VABI AllocateMemory(void*, std::uint32_t alignment, std::uint32_t size) { return Allocate(alignment, size, false); }
|
|
void APS5_VABI DeallocateMemory(void*, void* memory) { Release(memory, false); }
|
|
void* APS5_VABI AllocateTexture(void*, std::uint32_t alignment, std::uint32_t size) { return Allocate(alignment, size, true); }
|
|
void APS5_VABI DeallocateTexture(void*, void* memory) { Release(memory, true); }
|
|
|
|
bool IsAllocation(const void* memory, bool texture) {
|
|
std::lock_guard lock(allocations.mutex);
|
|
const auto found = allocations.blocks.find(const_cast<void*>(memory));
|
|
return found != allocations.blocks.end() && found->second.texture == texture;
|
|
}
|
|
|
|
struct Events {
|
|
std::mutex mutex;
|
|
std::vector<std::pair<std::int32_t, std::int32_t>> received;
|
|
|
|
bool Seen(std::int32_t id, std::int32_t warning = 0) {
|
|
std::lock_guard lock(mutex);
|
|
return std::any_of(received.begin(), received.end(), [&](const auto& event) { return event.first == id && event.second == warning; });
|
|
}
|
|
|
|
void Clear() {
|
|
std::lock_guard lock(mutex);
|
|
received.clear();
|
|
}
|
|
};
|
|
|
|
void APS5_VABI OnEvent(void* object, std::int32_t id, std::int32_t source, void* data) {
|
|
auto* events = static_cast<Events*>(object);
|
|
if (source != 0 || (id == EventWarning) != (data != nullptr)) std::abort();
|
|
std::lock_guard lock(events->mutex);
|
|
events->received.emplace_back(id, id == EventWarning ? *static_cast<std::int32_t*>(data) : 0);
|
|
}
|
|
|
|
void APS5_VABI OnLog(void*, const char*) {}
|
|
|
|
struct HostFile {
|
|
std::ifstream stream;
|
|
std::uint64_t size = 0;
|
|
};
|
|
|
|
std::int32_t APS5_VABI OpenFile(void* object, const char* path) {
|
|
auto* file = static_cast<HostFile*>(object);
|
|
if (std::strcmp(path, "/app0/replaced.mp4") != 0) return -1;
|
|
file->stream.open(MoviePath, std::ios::binary);
|
|
file->size = std::filesystem::file_size(MoviePath);
|
|
return file->stream ? 0 : -1;
|
|
}
|
|
|
|
std::int32_t APS5_VABI CloseFile(void* object) {
|
|
static_cast<HostFile*>(object)->stream.close();
|
|
return 0;
|
|
}
|
|
|
|
std::int32_t APS5_VABI ReadFile(void* object, std::uint8_t* buffer, std::uint64_t position, std::uint32_t length) {
|
|
auto* file = static_cast<HostFile*>(object);
|
|
file->stream.clear();
|
|
file->stream.seekg(static_cast<std::streamoff>(position));
|
|
file->stream.read(reinterpret_cast<char*>(buffer), length);
|
|
return static_cast<std::int32_t>(file->stream.gcount());
|
|
}
|
|
|
|
std::uint64_t APS5_VABI FileSize(void* object) {
|
|
return static_cast<HostFile*>(object)->size;
|
|
}
|
|
|
|
bool WaitFor(const std::function<bool()>& condition, int milliseconds = 5000) {
|
|
const auto deadline = std::chrono::steady_clock::now() + std::chrono::milliseconds(milliseconds);
|
|
while (std::chrono::steady_clock::now() < deadline) {
|
|
if (condition()) return true;
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
}
|
|
return condition();
|
|
}
|
|
|
|
AvPlayerInitData InitData(Events* events) {
|
|
AvPlayerInitData init{};
|
|
init.memory_replacement = {nullptr, AllocateMemory, DeallocateMemory, AllocateTexture, DeallocateTexture};
|
|
init.event_replacement = {events, events ? OnEvent : nullptr};
|
|
init.num_output_video_framebuffers = 4;
|
|
init.default_language = "eng";
|
|
return init;
|
|
}
|
|
|
|
int FrameIndex(std::uint64_t timestamp) {
|
|
return static_cast<int>((timestamp * FrameRate + 500) / 1000);
|
|
}
|
|
|
|
void CheckVideoPicture(const AvPlayerFrameInfoEx& info) {
|
|
const auto& video = info.details.video;
|
|
Check(video.width == 112 && video.height == 64 && video.pitch == Pitch, "unexpected frame geometry");
|
|
Check(video.crop_left_offset == 0 && video.crop_top_offset == 0 && video.crop_right_offset == Pitch - Width && video.crop_bottom_offset == 4, "unexpected crop offsets");
|
|
Check(video.luma_bit_depth == 8 && video.chroma_bit_depth == 8, "unexpected bit depth");
|
|
Check(std::fabs(video.aspect_ratio - static_cast<float>(Width) / Height) < 0.01f, "unexpected aspect ratio");
|
|
Check(std::memcmp(video.language_code, "eng", 4) == 0, "missing video language");
|
|
const int index = FrameIndex(info.timestamp);
|
|
Check(index >= 0 && index < FrameCount, "frame timestamp out of range");
|
|
const auto* luma = static_cast<const std::uint8_t*>(info.p_data);
|
|
const auto* chroma = luma + Pitch * 64;
|
|
for (const int row : {2, 30, 57, 63}) {
|
|
Check(std::abs(luma[row * Pitch + 10] - LumaFor(index)) <= 6, "left luma mismatch for frame " + std::to_string(index));
|
|
Check(std::abs(luma[row * Pitch + 90] - (255 - LumaFor(index))) <= 6, "right luma mismatch for frame " + std::to_string(index));
|
|
}
|
|
for (const int row : {0, 15, 31}) {
|
|
Check(std::abs(chroma[row * Pitch + 20] - 128) <= 6 && std::abs(chroma[row * Pitch + 21] - 128) <= 6, "chroma mismatch");
|
|
}
|
|
}
|
|
|
|
void CheckVideoFrame(const AvPlayerFrameInfoEx& info) {
|
|
CheckVideoPicture(info);
|
|
Check(IsAllocation(info.p_data, true), "video frame is not a texture allocation");
|
|
}
|
|
|
|
int Loudest(const AvPlayerFrameInfo& info) {
|
|
const auto* samples = reinterpret_cast<const std::int16_t*>(info.p_data);
|
|
int loudest = 0;
|
|
for (std::uint32_t index = 0; index < info.details.audio.size / sizeof(std::int16_t); ++index) loudest = std::max(loudest, std::abs(static_cast<int>(samples[index])));
|
|
return loudest;
|
|
}
|
|
|
|
void CheckAudioFrame(const AvPlayerFrameInfo& info, std::uint16_t channels, const char* language) {
|
|
Check(info.details.audio.channel_count == channels && info.details.audio.sample_rate == SampleRate, "unexpected audio format");
|
|
Check(info.details.audio.size > 0 && info.details.audio.size <= 1024u * channels * 2 && info.details.audio.size % (channels * 2u) == 0, "unexpected audio size");
|
|
Check(std::memcmp(info.details.audio.language_code, language, 4) == 0, "unexpected audio language");
|
|
Check(IsAllocation(info.p_data, false), "audio frame is not a plain allocation");
|
|
}
|
|
|
|
void CheckEnglishAudio(const AvPlayerFrameInfo& info) {
|
|
CheckAudioFrame(info, 2, "eng");
|
|
Check(Loudest(info) <= 16, "the English track is not silent");
|
|
}
|
|
|
|
void CheckStreamInfo(AvPlayerInternal* player) {
|
|
Check(sceAvPlayerStreamCount(player) == 3, "unexpected stream count");
|
|
for (std::uint32_t index = 0; index < 3; ++index) {
|
|
AvPlayerStreamInfo info{};
|
|
Check(sceAvPlayerGetStreamInfo(player, index, &info) == 0, "stream info failed");
|
|
Check(info.duration >= 950 && info.duration <= 1100, "unexpected stream duration");
|
|
if (index == VideoStream) {
|
|
Check(info.type == 1, "video stream type");
|
|
Check(info.details.video.width == 112 && info.details.video.height == 64, "unexpected video stream size");
|
|
Check(std::strcmp(info.details.video.language_code, "eng") == 0, "unexpected video language");
|
|
} else {
|
|
const bool english = index == EnglishAudioStream;
|
|
Check(info.type == 0, "audio stream type");
|
|
Check(info.details.audio.channel_count == (english ? 2 : 1) && info.details.audio.sample_rate == SampleRate, "unexpected audio stream");
|
|
Check(std::strcmp(info.details.audio.language_code, english ? "eng" : "fra") == 0, "unexpected audio language");
|
|
}
|
|
}
|
|
AvPlayerStreamInfo unused{};
|
|
Check(sceAvPlayerGetStreamInfo(player, 3, &unused) == OperationFailed, "invalid stream accepted");
|
|
Check(sceAvPlayerGetStreamInfo(player, 0, nullptr) == InvalidParams, "null stream info accepted");
|
|
}
|
|
|
|
void CheckStreamInfoEx(AvPlayerInternal* player) {
|
|
for (std::uint32_t index = 0; index < 3; ++index) {
|
|
AvPlayerStreamInfoEx info{};
|
|
info.this_size = sizeof(info);
|
|
Check(sceAvPlayerGetStreamInfoEx(player, index, &info) == 0, "extended stream info failed");
|
|
Check(info.this_size == sizeof(info), "extended stream info size overwritten");
|
|
Check(info.duration >= 950 && info.duration <= 1100, "unexpected extended stream duration");
|
|
if (index == VideoStream) {
|
|
const auto& video = info.details.video;
|
|
Check(info.type == 1, "extended video stream type");
|
|
Check(video.width == 112 && video.height == 64 && video.pitch == Pitch, "unexpected extended video geometry");
|
|
Check(video.crop_left_offset == 0 && video.crop_top_offset == 0 && video.crop_right_offset == Pitch - Width && video.crop_bottom_offset == 4, "unexpected extended crop offsets");
|
|
Check(video.luma_bit_depth == 8 && video.chroma_bit_depth == 8 && !video.video_full_range_flag, "unexpected extended video format");
|
|
Check(std::fabs(video.aspect_ratio - static_cast<float>(Width) / Height) < 0.01f, "unexpected extended aspect ratio");
|
|
Check(std::memcmp(video.language_code, "eng", 4) == 0, "unexpected extended video language");
|
|
} else {
|
|
const bool english = index == EnglishAudioStream;
|
|
const auto& audio = info.details.audio;
|
|
Check(info.type == 0, "extended audio stream type");
|
|
Check(audio.channel_count == (english ? 2 : 1) && audio.sample_rate == SampleRate, "unexpected extended audio stream");
|
|
Check(std::memcmp(audio.language_code, english ? "eng" : "fra", 4) == 0, "unexpected extended audio language");
|
|
}
|
|
}
|
|
AvPlayerStreamInfoEx unused{};
|
|
Check(sceAvPlayerGetStreamInfoEx(player, 3, &unused) == OperationFailed, "invalid extended stream accepted");
|
|
Check(sceAvPlayerGetStreamInfoEx(player, 0, nullptr) == InvalidParams, "null extended stream info accepted");
|
|
Check(sceAvPlayerGetStreamInfoEx(nullptr, 0, &unused) == InvalidParams, "null player accepted");
|
|
}
|
|
|
|
void TestPlayback() {
|
|
Events events;
|
|
AvPlayerInitData init = InitData(&events);
|
|
auto* player = sceAvPlayerInit(&init);
|
|
Check(player != nullptr, "init failed");
|
|
AvPlayerPostInitData post{};
|
|
post.demux_video_buffer_size = 64 * 1024;
|
|
Check(sceAvPlayerPostInit(player, &post) == 0, "post init failed");
|
|
Check(sceAvPlayerPostInit(player, nullptr) == InvalidParams, "post init accepted null data");
|
|
Check(sceAvPlayerStreamCount(player) == OperationFailed, "stream count without a source");
|
|
Check(!sceAvPlayerIsActive(player), "active without a source");
|
|
Check(sceAvPlayerAddSource(player, "/app0/missing.mp4") == OperationFailed, "missing file accepted");
|
|
Check(sceAvPlayerAddSource(player, "/app0/avplayer.mp4") == 0, "add source failed");
|
|
Check(sceAvPlayerAddSource(player, "/app0/avplayer.mp4") == OperationFailed, "second source accepted");
|
|
Check(WaitFor([&] { return events.Seen(EventReady); }), "ready event missing");
|
|
|
|
CheckStreamInfo(player);
|
|
Check(sceAvPlayerEnableStream(player, 7) == OperationFailed, "invalid stream enabled");
|
|
Check(sceAvPlayerEnableStream(player, VideoStream) == 0, "enable video failed");
|
|
Check(sceAvPlayerEnableStream(player, EnglishAudioStream) == 0, "enable audio failed");
|
|
Check(sceAvPlayerIsActive(player), "not active before start");
|
|
Check(sceAvPlayerPause(player) == OperationFailed, "pause accepted before start");
|
|
Check(sceAvPlayerStart(player) == 0, "start failed");
|
|
Check(WaitFor([&] { return events.Seen(EventPlay); }), "play event missing");
|
|
|
|
AvPlayerFrameInfoEx frame{};
|
|
AvPlayerFrameInfo sound{};
|
|
int frames = 0;
|
|
int sounds = 0;
|
|
std::uint64_t last = 0;
|
|
Check(WaitFor([&] {
|
|
if (sceAvPlayerGetAudioData(player, &sound)) {
|
|
CheckEnglishAudio(sound);
|
|
++sounds;
|
|
}
|
|
if (sceAvPlayerGetVideoDataEx(player, &frame)) {
|
|
CheckVideoFrame(frame);
|
|
Check(frames == 0 || frame.timestamp > last, "video timestamps not increasing");
|
|
last = frame.timestamp;
|
|
++frames;
|
|
}
|
|
return frames >= 8 && sounds >= 8;
|
|
}), "playback stalled");
|
|
Check(sceAvPlayerCurrentTime(player) > 0, "clock not running");
|
|
Check(sceAvPlayerSetTrickSpeed(player, 0) == InvalidParams, "zero trick speed accepted");
|
|
Check(sceAvPlayerSetTrickSpeed(player, 100) == 0, "normal trick speed rejected");
|
|
|
|
Check(sceAvPlayerPause(player) == 0, "pause failed");
|
|
Check(WaitFor([&] { return events.Seen(EventPause); }), "pause event missing");
|
|
const auto paused = sceAvPlayerCurrentTime(player);
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
Check(!sceAvPlayerGetVideoDataEx(player, &frame) && !sceAvPlayerGetAudioData(player, &sound), "data delivered while paused");
|
|
Check(sceAvPlayerCurrentTime(player) == paused, "clock moved while paused");
|
|
Check(sceAvPlayerIsActive(player), "inactive while paused");
|
|
events.Clear();
|
|
Check(sceAvPlayerResume(player) == 0, "resume failed");
|
|
Check(sceAvPlayerResume(player) == OperationFailed, "resume accepted while playing");
|
|
Check(WaitFor([&] { return events.Seen(EventPlay); }), "resume event missing");
|
|
|
|
Check(sceAvPlayerJumpToTime(player, 700) == 0, "jump failed");
|
|
Check(WaitFor([&] { return events.Seen(EventWarning, JumpComplete); }), "jump completion missing");
|
|
Check(WaitFor([&] { return sceAvPlayerGetVideoDataEx(player, &frame) != 0; }), "no frame after the jump");
|
|
CheckVideoFrame(frame);
|
|
Check(frame.timestamp >= 700 && frame.timestamp <= 767, "jump landed at " + std::to_string(frame.timestamp));
|
|
|
|
events.Clear();
|
|
const auto forward = sceAvPlayerCurrentTime(player);
|
|
Check(sceAvPlayerSetTrickSpeed(player, -100) == 0, "reverse trick speed rejected");
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
|
Check(!sceAvPlayerGetVideoDataEx(player, &frame) && !sceAvPlayerGetAudioData(player, &sound), "data delivered in reverse");
|
|
const auto rewound = sceAvPlayerCurrentTime(player);
|
|
Check(rewound + 150 <= forward, "clock did not run backwards: " + std::to_string(forward) + " to " + std::to_string(rewound));
|
|
Check(sceAvPlayerSetTrickSpeed(player, 100) == 0, "forward trick speed rejected after reverse");
|
|
Check(WaitFor([&] { return sceAvPlayerGetVideoDataEx(player, &frame) != 0; }), "no frame after reverse");
|
|
CheckVideoFrame(frame);
|
|
Check(frame.timestamp + 100 >= rewound && frame.timestamp <= rewound + 100, "playback resumed at " + std::to_string(frame.timestamp) + " after rewinding to " + std::to_string(rewound));
|
|
Check(!events.Seen(EventWarning, JumpComplete), "rewinding reported a jump");
|
|
|
|
Check(sceAvPlayerSetAvSyncMode(player, 2) == InvalidParams, "invalid sync mode accepted");
|
|
Check(sceAvPlayerSetAvSyncMode(player, 1) == 0, "sync mode rejected");
|
|
Check(WaitFor([&] {
|
|
if (sceAvPlayerGetVideoDataEx(player, &frame)) {
|
|
CheckVideoFrame(frame);
|
|
last = frame.timestamp;
|
|
}
|
|
while (sceAvPlayerGetAudioData(player, &sound)) CheckEnglishAudio(sound);
|
|
return !sceAvPlayerIsActive(player);
|
|
}), "playback never ended");
|
|
Check(FrameIndex(last) >= FrameCount - 2, "last frame missing");
|
|
Check(WaitFor([&] { return events.Seen(EventStop); }), "end of stream stop event missing");
|
|
Check(sceAvPlayerCurrentTime(player) >= 950, "clock not at the end");
|
|
Check(sceAvPlayerStop(player) == 0, "stop after the end failed");
|
|
|
|
events.Clear();
|
|
Check(sceAvPlayerSetLooping(player, 1) == 0, "looping rejected");
|
|
Check(sceAvPlayerStart(player) == 0, "restart failed");
|
|
bool wrapped = false;
|
|
last = 0;
|
|
frames = 0;
|
|
Check(WaitFor([&] {
|
|
while (sceAvPlayerGetAudioData(player, &sound)) CheckEnglishAudio(sound);
|
|
if (sceAvPlayerGetVideoDataEx(player, &frame)) {
|
|
CheckVideoFrame(frame);
|
|
if (frames > 0 && frame.timestamp < last) wrapped = true;
|
|
last = frame.timestamp;
|
|
++frames;
|
|
}
|
|
return wrapped && frames > FrameCount + 5;
|
|
}), "looping never wrapped");
|
|
Check(events.Seen(EventWarning, LoopingBack), "looping warning missing");
|
|
Check(sceAvPlayerIsActive(player), "looping player went inactive");
|
|
Check(sceAvPlayerStop(player) == 0, "stop failed");
|
|
Check(sceAvPlayerStop(player) == OperationFailed, "second stop accepted");
|
|
Check(!sceAvPlayerIsActive(player), "active after stop");
|
|
Check(WaitFor([&] { return events.Seen(EventStop); }), "stop event missing");
|
|
Check(sceAvPlayerClose(player) == 0, "close failed");
|
|
Check(sceAvPlayerClose(nullptr) == InvalidParams, "null close accepted");
|
|
std::lock_guard lock(allocations.mutex);
|
|
Check(allocations.blocks.empty(), "allocations leaked");
|
|
Check(allocations.textures >= 4, "video buffers not allocated as textures");
|
|
}
|
|
|
|
void TestChangeStream() {
|
|
Events events;
|
|
AvPlayerInitData init = InitData(&events);
|
|
auto* player = sceAvPlayerInit(&init);
|
|
Check(player != nullptr, "init failed");
|
|
Check(sceAvPlayerChangeStream(player, EnglishAudioStream, FrenchAudioStream) == OperationFailed, "stream changed without a source");
|
|
Check(sceAvPlayerAddSource(player, "/app0/avplayer.mp4") == 0, "add source failed");
|
|
Check(WaitFor([&] { return events.Seen(EventReady); }), "ready event missing");
|
|
Check(sceAvPlayerChangeStream(nullptr, EnglishAudioStream, FrenchAudioStream) == InvalidParams, "null player accepted");
|
|
Check(sceAvPlayerEnableStream(player, VideoStream) == 0, "enable video failed");
|
|
Check(sceAvPlayerEnableStream(player, EnglishAudioStream) == 0, "enable audio failed");
|
|
Check(sceAvPlayerChangeStream(player, VideoStream, FrenchAudioStream) == OperationFailed, "video changed to audio");
|
|
Check(sceAvPlayerChangeStream(player, EnglishAudioStream, 9) == OperationFailed, "changed to a missing stream");
|
|
Check(sceAvPlayerChangeStream(player, FrenchAudioStream, EnglishAudioStream) == OperationFailed, "changed from a disabled stream");
|
|
Check(sceAvPlayerChangeStream(player, EnglishAudioStream, FrenchAudioStream) == 0, "change before start failed");
|
|
Check(sceAvPlayerChangeStream(player, FrenchAudioStream, EnglishAudioStream) == 0, "change back before start failed");
|
|
Check(sceAvPlayerStart(player) == 0, "start failed");
|
|
|
|
AvPlayerFrameInfo sound{};
|
|
AvPlayerFrameInfoEx frame{};
|
|
int english = 0;
|
|
Check(WaitFor([&] {
|
|
if (sceAvPlayerGetAudioData(player, &sound)) {
|
|
CheckEnglishAudio(sound);
|
|
++english;
|
|
}
|
|
return english >= 2;
|
|
}), "no English audio");
|
|
|
|
events.Clear();
|
|
Check(sceAvPlayerChangeStream(player, EnglishAudioStream, FrenchAudioStream) == 0, "change to the French track failed");
|
|
int french = 0;
|
|
int loudest = 0;
|
|
Check(WaitFor([&] {
|
|
if (sceAvPlayerGetAudioData(player, &sound)) {
|
|
if (french == 0 && std::memcmp(sound.details.audio.language_code, "eng", 4) == 0) {
|
|
CheckEnglishAudio(sound);
|
|
} else {
|
|
CheckAudioFrame(sound, 1, "fra");
|
|
loudest = std::max(loudest, Loudest(sound));
|
|
++french;
|
|
}
|
|
}
|
|
return french >= 4;
|
|
}), "no French audio after the change");
|
|
Check(loudest > 1000, "the French track decoded silent");
|
|
Check(WaitFor([&] { return sceAvPlayerGetVideoDataEx(player, &frame) != 0; }), "no video after the change");
|
|
CheckVideoFrame(frame);
|
|
Check(!events.Seen(EventWarning, JumpComplete), "changing streams reported a jump");
|
|
Check(sceAvPlayerChangeStream(player, EnglishAudioStream, FrenchAudioStream) == OperationFailed, "changed from the replaced stream");
|
|
Check(sceAvPlayerClose(player) == 0, "close failed");
|
|
std::lock_guard lock(allocations.mutex);
|
|
Check(allocations.blocks.empty(), "allocations leaked");
|
|
}
|
|
|
|
void TestExtendedExports() {
|
|
Events events;
|
|
AvPlayerInitData init = InitData(&events);
|
|
auto* player = sceAvPlayerInit(&init);
|
|
Check(player != nullptr, "init failed");
|
|
Check(sceAvPlayerSetLogCallback(reinterpret_cast<void*>(&OnLog), nullptr) == 0, "log callback rejected");
|
|
Check(sceAvPlayerSetAvailableBandwidth(player, 4000, 1000, 8000) == 0, "bandwidth rejected");
|
|
Check(sceAvPlayerSetAvailableBandwidth(nullptr, 4000, 1000, 8000) == InvalidParams, "bandwidth accepted for a null player");
|
|
Check(sceAvPlayerAddSource(player, "/app0/avplayer.mp4") == 0, "add source failed");
|
|
Check(WaitFor([&] { return events.Seen(EventReady); }), "ready event missing");
|
|
CheckStreamInfoEx(player);
|
|
Check(sceAvPlayerEnableStream(player, VideoStream) == 0, "enable video failed");
|
|
Check(sceAvPlayerStartEx(nullptr, nullptr) == InvalidParams, "start accepted a null player");
|
|
Check(sceAvPlayerStartEx(player, nullptr) == 0, "extended start failed");
|
|
Check(WaitFor([&] { return events.Seen(EventPlay); }), "play event missing");
|
|
AvPlayerFrameInfoEx frame{};
|
|
Check(WaitFor([&] { return sceAvPlayerGetVideoDataEx(player, &frame) != 0; }), "no frame after the extended start");
|
|
CheckVideoFrame(frame);
|
|
Check(sceAvPlayerClose(player) == 0, "close failed");
|
|
}
|
|
|
|
void TestWithoutAllocators() {
|
|
AvPlayerInitData init = InitData(nullptr);
|
|
init.memory_replacement = {};
|
|
auto* player = sceAvPlayerInit(&init);
|
|
Check(player != nullptr, "init without allocators failed");
|
|
Check(sceAvPlayerAddSource(player, "/app0/avplayer.mp4") == 0, "add source failed");
|
|
AvPlayerFrameInfoEx frame{};
|
|
Check(WaitFor([&] { return sceAvPlayerGetVideoDataEx(player, &frame) != 0; }), "no frame without allocators");
|
|
CheckVideoPicture(frame);
|
|
Check(!IsAllocation(frame.p_data, true) && !IsAllocation(frame.p_data, false), "frame came from a missing allocator");
|
|
Check(sceAvPlayerClose(player) == 0, "close failed");
|
|
|
|
AvPlayerInitDataEx extended{};
|
|
extended.this_size = sizeof(extended);
|
|
AvPlayerInternal* handle = nullptr;
|
|
Check(sceAvPlayerInitEx(&extended, &handle) == 0 && handle != nullptr, "extended init without allocators failed");
|
|
Check(sceAvPlayerInitEx(nullptr, &handle) == InvalidParams, "extended init accepted null data");
|
|
Check(sceAvPlayerClose(handle) == 0, "close failed");
|
|
}
|
|
|
|
void TestFileReplacementAutoStart() {
|
|
HostFile file;
|
|
AvPlayerInitData init = InitData(nullptr);
|
|
init.file_replacement = {&file, OpenFile, CloseFile, ReadFile, FileSize};
|
|
auto* player = sceAvPlayerInit(&init);
|
|
Check(player != nullptr, "init failed");
|
|
Check(sceAvPlayerAddSource(player, "/app0/replaced.mp4") == 0, "replaced source failed");
|
|
AvPlayerFrameInfo frame{};
|
|
Check(WaitFor([&] { return sceAvPlayerGetVideoData(player, &frame) != 0; }), "auto start never produced a frame");
|
|
Check(frame.details.video.width == 112 && frame.details.video.height == 64 && IsAllocation(frame.p_data, true), "unexpected auto start frame");
|
|
Check(sceAvPlayerClose(player) == 0, "close failed");
|
|
Check(!file.stream.is_open(), "replaced file left open");
|
|
}
|
|
|
|
void TestHandedOutFramesStayIntact() {
|
|
constexpr int Buffers = 6;
|
|
constexpr int Retained = Buffers - 2;
|
|
AvPlayerInitData init = InitData(nullptr);
|
|
init.num_output_video_framebuffers = Buffers;
|
|
auto* player = sceAvPlayerInit(&init);
|
|
Check(player != nullptr, "init failed");
|
|
Check(sceAvPlayerSetAvSyncMode(player, 1) == 0, "sync mode rejected");
|
|
Check(sceAvPlayerAddSource(player, "/app0/avplayer.mp4") == 0, "add source failed");
|
|
struct Taken {
|
|
const std::uint8_t* luma;
|
|
int index;
|
|
};
|
|
std::deque<Taken> taken;
|
|
for (int round = 0; round < 16; ++round) {
|
|
AvPlayerFrameInfoEx frame{};
|
|
Check(WaitFor([&] { return sceAvPlayerGetVideoDataEx(player, &frame) != 0; }), "no frame for round " + std::to_string(round));
|
|
CheckVideoFrame(frame);
|
|
taken.push_back({static_cast<const std::uint8_t*>(frame.p_data), FrameIndex(frame.timestamp)});
|
|
if (taken.size() > Retained) taken.pop_front();
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(30));
|
|
for (std::size_t k = 0; k < taken.size(); ++k) {
|
|
for (std::size_t other = k + 1; other < taken.size(); ++other) Check(taken[k].luma != taken[other].luma, "one buffer handed out twice among the last " + std::to_string(Retained) + " frames");
|
|
const int index = taken[k].index;
|
|
Check(std::abs(taken[k].luma[30 * Pitch + 10] - LumaFor(index)) <= 6, "frame " + std::to_string(index) + " was overwritten " + std::to_string(taken.size() - 1 - k) + " frames after it was handed out");
|
|
}
|
|
}
|
|
Check(sceAvPlayerClose(player) == 0, "close failed");
|
|
}
|
|
|
|
}
|
|
|
|
int main() {
|
|
try {
|
|
WriteMovie();
|
|
TestPlayback();
|
|
TestChangeStream();
|
|
TestExtendedExports();
|
|
TestWithoutAllocators();
|
|
TestFileReplacementAutoStart();
|
|
TestHandedOutFramesStayIntact();
|
|
std::puts("AvPlayer tests passed");
|
|
return 0;
|
|
} catch (const std::exception& error) {
|
|
std::fprintf(stderr, "%s\n", error.what());
|
|
return 1;
|
|
}
|
|
}
|