#include #include #include #include #define SCREEN_W 960 #define SCREEN_H 544 static void die(const char* msg) { sceClibPrintf("%s\n", msg); sceKernelExitProcess(1); } static inline void check_error(int status) { if (status < 0) sceClibPrintf("mpv error: %s\n", mpv_error_string(status)); } void mpv_on_update(void* obj) { mpv_render_context* mpv_context = reinterpret_cast(obj); mpv_render_context_update(mpv_context); } void mpv_on_wakeup(void* obj) {} // Main code int main(int argc, char* argv[]) { // Prevent automatic CMA connection sceShellUtilLock(SCE_SHELL_UTIL_LOCK_TYPE_USB_CONNECTION); // Initializing graphics device (Note: we leave physically contiguous memory unused so that we can use it in sceAvPlayer) vglInitWithCustomThreshold( 0, SCREEN_W, SCREEN_H, 4 * 1024 * 1024, 0, 32 * 1024 * 1024, 0, SCE_GXM_MULTISAMPLE_NONE); mpv_render_context* mpv_context = nullptr; mpv_handle* mpv = mpv_create(); mpv_set_option_string(mpv, "subs-fallback", "yes"); mpv_set_option_string(mpv, "video-timing-offset", "0"); // 60fps mpv_set_option_string(mpv, "ytdl", "no"); mpv_set_option_string(mpv, "vo", "null"); if (mpv_initialize(mpv) < 0) die("init mpv failed"); mpv_opengl_init_params gl_init_params{ [](void* fn_ctx, const char* name) { return (void*)vglGetProcAddress(name); }, nullptr}; mpv_render_param params[] = { {MPV_RENDER_PARAM_API_TYPE, const_cast(MPV_RENDER_API_TYPE_OPENGL)}, {MPV_RENDER_PARAM_OPENGL_INIT_PARAMS, &gl_init_params}, {MPV_RENDER_PARAM_INVALID, nullptr}, }; if (mpv_render_context_create(&mpv_context, mpv, params) < 0) die("init mpv context failed"); mpv_set_wakeup_callback(mpv, mpv_on_wakeup, mpv); mpv_render_context_set_update_callback(mpv_context, mpv_on_update, mpv_context); const char* args[] = {"loadfile", "http://static.jjbisai.com/website/videos/jj_pcsite/bannerVideo.mp4", nullptr}; if (mpv_command_async(mpv, 0, args) < 0) die("load file failed"); SceCtrlData pad; mpv_opengl_fbo mpv_fbo{0, SCREEN_W, SCREEN_H}; int flip_y{1}; mpv_render_param mpv_params[3] = { {MPV_RENDER_PARAM_OPENGL_FBO, &mpv_fbo}, {MPV_RENDER_PARAM_FLIP_Y, &flip_y}, {MPV_RENDER_PARAM_INVALID, nullptr}, }; while (sceCtrlPeekBufferPositive(0, &pad, 1)) { if (pad.buttons & SCE_CTRL_TRIANGLE) break; mpv_render_context_render(mpv_context, mpv_params); mpv_render_context_report_swap(mpv_context); } mpv_render_context_free(mpv_context); mpv_terminate_destroy(mpv); return 0; }