diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index a28887f..f076818 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -20,12 +20,13 @@ "name": "MinGW64", "includePath": [ "${workspaceFolder}/**", - "D:\\msys64\\mingw64\\include" + "C:/MinGW64/include", + "C:/MinGW64/x86_64-w64-mingw32/include/**" ], "defines": [ "USE_OPENGL" ], - "compilerPath": "D:\\msys64\\mingw64\\bin\\gcc.exe", + "compilerPath": "C:/MinGW64/bin/gcc.exe", "cStandard": "c17", "cppStandard": "gnu++17", "intelliSenseMode": "windows-gcc-x64" diff --git a/src/main.cpp b/src/main.cpp index 9f9a4ed..c79d103 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include @@ -18,6 +18,7 @@ static ID3D11DeviceContext* d3dDeviceContext = nullptr; static IDXGISwapChain* d3dSwapChain = nullptr; static ID3D11RenderTargetView* d3dRenderTargetView = nullptr; static HWND hwnd = nullptr; +static mpv_handle* mpv = nullptr; static int osdShow = 0; // Forward declarations of helper functions @@ -35,8 +36,6 @@ static int64_t mpv_property_int(mpv_handle* mpv, const char* key) { extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; - switch (msg) { case WM_SIZE: if (wParam == SIZE_MINIMIZED) return 0; @@ -48,11 +47,46 @@ LRESULT WINAPI wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { break; case WM_KEYUP: if (wParam == VK_RETURN) osdShow = !osdShow; + else if (wParam == VK_SPACE) mpv_command_string(mpv, "set pause yes"); + break; + case WM_USER: + while (true) { + mpv_event* mp_event = mpv_wait_event(mpv, 0); + if (mp_event->event_id == MPV_EVENT_NONE) { + break; + } else if (mp_event->event_id == MPV_EVENT_START_FILE) { + printf("MPV => START FILE\n"); + } else if (mp_event->event_id == MPV_EVENT_FILE_LOADED) { + printf("MPV => FILE LOADED\n"); + } else if (mp_event->event_id == MPV_EVENT_PLAYBACK_RESTART) { + printf("MPV => PLAYBACK RESTART\n"); + } else if (mp_event->event_id == MPV_EVENT_COMMAND_REPLY) { + if (mp_event->error) { + printf("MPV => COMMAND ERROR: %s\n", mpv_error_string(mp_event->error)); + break; + } + } else if (mp_event->event_id == MPV_EVENT_END_FILE) { + auto node = (mpv_event_end_file*)mp_event->data; + if (node->reason == MPV_END_FILE_REASON_ERROR) { + printf("MPV => FILE ERROR: %s\n", mpv_error_string(node->error)); + } else if (node->reason == MPV_END_FILE_REASON_EOF) { + printf("MPV => END_OF_FILE\n"); + } else { + printf("MPV => STOP\n"); + } + return 0; + } else if (mp_event->event_id == MPV_EVENT_PROPERTY_CHANGE) { + /// https://mpv.io/manual/stable/#property-list + mpv_event_property* prop = (mpv_event_property*)mp_event->data; + printf("MPV => PROPERTY `%s` type %d\n", prop->name, int(prop->format)); + } + } break; case WM_DESTROY: ::PostQuitMessage(0); return 0; } + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; return ::DefWindowProcW(hWnd, msg, wParam, lParam); } @@ -67,39 +101,40 @@ int main(int argc, char* argv[]) { wc.lpszClassName = L"MpvClass"; if (!RegisterClassExW(&wc)) die("register class failed"); - hwnd = CreateWindowExW(0, wc.lpszClassName, L"xplayer", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 1280, 720, - nullptr, nullptr, wc.hInstance, nullptr); + hwnd = CreateWindowExW(0, wc.lpszClassName, L"xplayer", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 1280, + 720, nullptr, nullptr, wc.hInstance, nullptr); if (!hwnd) die("create window failed"); if (!InitD3D(hwnd)) die("init dx11 failed"); mpv_render_context* mpv_context = nullptr; - mpv_handle* mpv = mpv_create(); + 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, "terminal", "yes"); mpv_set_option_string(mpv, "ytdl", "no"); mpv_set_option_string(mpv, "hwdec", "auto"); - mpv_set_option_string(mpv, "vo", "gpu-next"); - mpv_set_option_string(mpv, "msg-level", "all=v"); - mpv_set_option(mpv, "wid", MPV_FORMAT_INT64, &hwnd); - mpv_set_option(mpv, "d3d11-device", MPV_FORMAT_INT64, &d3dDevice); + mpv_set_option_string(mpv, "vo", "libmpv"); if (mpv_initialize(mpv) < 0) die("init mpv failed"); + mpv_dxgi_init_params init_params = {d3dDevice, d3dSwapChain}; mpv_render_param params[] = { - {MPV_RENDER_PARAM_API_TYPE, (void*)MPV_RENDER_API_TYPE_SW}, - {MPV_RENDER_PARAM_INVALID, nullptr}, + {MPV_RENDER_PARAM_API_TYPE, const_cast(MPV_RENDER_API_TYPE_DXGI)}, + {MPV_RENDER_PARAM_DXGI_INIT_PARAMS, &init_params}, + {MPV_RENDER_PARAM_INVALID, NULL}, }; + 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) PostMessage(hwnd, WM_NULL, 0, 0); + if (flags & MPV_RENDER_UPDATE_FRAME) PostMessage(hwnd, WM_PAINT, 0, 0); }, mpv_context); + mpv_set_wakeup_callback(mpv, [](void* obj) { PostMessage(hwnd, WM_USER, 0L, (LPARAM)obj); }, mpv); // Show the window ::ShowWindow(hwnd, SW_SHOWDEFAULT); @@ -159,6 +194,8 @@ int main(int argc, char* argv[]) { d3dDeviceContext->OMSetRenderTargets(1, &d3dRenderTargetView, nullptr); ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); + ImGui::EndFrame(); + d3dSwapChain->Present(1, 0); // Present with vsync }