diff --git a/main.cpp b/main.cpp index 648efc2..775b36d 100644 --- a/main.cpp +++ b/main.cpp @@ -3,6 +3,7 @@ #include #include +#include #ifdef USE_D3D11 #include @@ -47,24 +48,53 @@ static void die(const char* msg) { exit(1); } +static int64_t mpv_property_int(mpv_handle* mpv, const char* key) { + int64_t value = -1; + mpv_get_property(mpv, key, MPV_FORMAT_INT64, &value); + return value; +} + // Main code int main(int argc, char* argv[]) { if (argc < 2) die("missing file path"); if (!glfwInit()) die("init glfw failed"); + 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, "vd-lavc-dr", "yes"); + mpv_set_option_string(mpv, "terminal", "yes"); + mpv_set_option_string(mpv, "hwdec", "auto"); +#ifdef _DEBUG + mpv_set_option_string(this->mpv, "msg-level", "ffmpeg=trace"); + mpv_set_option_string(this->mpv, "msg-level", "all=v"); +#endif + if (mpv_initialize(mpv) < 0) die("init mpv failed"); + // Create window with graphics context GLFWwindow* window = glfwCreateWindow(1280, 720, argv[1], nullptr, nullptr); if (!window) { glfwTerminate(); return -1; } + glfwSetWindowUserPointer(window, mpv); glfwSetKeyCallback(window, [](GLFWwindow* window, int key, int scancode, int action, int mods) { + mpv_handle* mpv = static_cast(glfwGetWindowUserPointer(window)); if (action == GLFW_PRESS) { if (key == GLFW_KEY_ESCAPE) glfwSetWindowShouldClose(window, 1); else if (key == GLFW_KEY_ENTER) osdShow = !osdShow; + else if (key == GLFW_KEY_LEFT) + mpv_command_string(mpv, "seek -15"); + else if (key == GLFW_KEY_RIGHT) + mpv_command_string(mpv, "seek 15"); + else if (key == GLFW_KEY_SPACE) + mpv_command_string(mpv, ""); + else + printf("glfwKeyCallback key press %d\n", key); } }); #ifdef USE_D3D11 @@ -73,21 +103,63 @@ int main(int argc, char* argv[]) { glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); if (!InitD3D(hwnd)) die("init dx11 failed"); glfwSetFramebufferSizeCallback(window, (GLFWframebuffersizefun)ResizeD3D); + + mpv_dxgi_init_params init_params = {d3dDevice, d3dSwapChain}; + mpv_render_param params[] = { + {MPV_RENDER_PARAM_API_TYPE, (void*)MPV_RENDER_API_TYPE_DXGI}, + {MPV_RENDER_PARAM_DXGI_INIT_PARAMS, &init_params}, + {MPV_RENDER_PARAM_INVALID, nullptr}, + }; #else glfwMakeContextCurrent(window); // Load OpenGL routines using glad gladLoadGLLoader((GLADloadproc)glfwGetProcAddress); glfwSwapInterval(1); glfwSetTime(0); + + mpv_opengl_init_params gl_init_params{ + [](void* fn_ctx, const char* name) { return (void*)glfwGetProcAddress(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}, + }; #endif + if (mpv_render_context_create(&mpv_context, mpv, params) < 0) die("init mpv context failed"); + mpv_render_context_set_update_callback( + mpv_context, + [](void* obj) { + mpv_render_context* ctx = static_cast(obj); + uint64_t flags = mpv_render_context_update(ctx); + if (flags & MPV_RENDER_UPDATE_FRAME) glfwPostEmptyEvent(); + }, + mpv_context); + + const char* args[] = {"loadfile", argv[1], nullptr}; + if (mpv_command(mpv, args) < 0) die("load file failed"); + int fbw = 0, fbh = 0; // Main loop while (!glfwWindowShouldClose(window)) { glfwGetFramebufferSize(window, &fbw, &fbh); +#if defined(USE_D3D11) + mpv_render_param mpv_params[] = { + {MPV_RENDER_PARAM_INVALID, nullptr}, + }; +#else + mpv_opengl_fbo mpv_fbo{0, fbw, fbh}; + 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}, + }; +#endif + // Rendering + mpv_render_context_render(mpv_context, mpv_params); + mpv_render_context_report_swap(mpv_context); #ifdef USE_D3D11 - float clear_color[4] = {0.45f, 0.55f, 0.60f, 1.00f}; d3dDeviceContext->OMSetRenderTargets(1, &d3dRenderTargetView, nullptr); - d3dDeviceContext->ClearRenderTargetView(d3dRenderTargetView, clear_color); d3dSwapChain->Present(1, 0); // Present with vsync #else glViewport(0, 0, fbw, fbh); @@ -96,6 +168,10 @@ int main(int argc, char* argv[]) { glfwWaitEvents(); } + mpv_command_string(mpv, "quit"); + mpv_render_context_free(mpv_context); + mpv_terminate_destroy(mpv); + #ifdef USE_D3D11 CleanupD3D(); #endif