add mpv demo
This commit is contained in:
@@ -24,10 +24,15 @@ set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 17)
|
|||||||
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR})
|
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR})
|
||||||
target_compile_definitions(${PROJECT_NAME} PRIVATE ${RENDER_DRIVER})
|
target_compile_definitions(${PROJECT_NAME} PRIVATE ${RENDER_DRIVER})
|
||||||
|
|
||||||
|
find_package(PkgConfig REQUIRED)
|
||||||
|
pkg_search_module(MPV REQUIRED mpv)
|
||||||
|
target_include_directories(xplayer PRIVATE ${MPV_INCLUDE_DIRS})
|
||||||
|
|
||||||
if (NINTENDO_SWITCH)
|
if (NINTENDO_SWITCH)
|
||||||
target_link_libraries(${PROJECT_NAME}
|
target_link_libraries(${PROJECT_NAME}
|
||||||
PRIVATE
|
PRIVATE
|
||||||
glfw3 glapi drm_nouveau nx m
|
glfw3 glapi drm_nouveau nx m
|
||||||
|
${MPV_LINK_LIBRARIES}
|
||||||
)
|
)
|
||||||
nx_generate_nacp(${PROJECT_NAME}.nacp NAME ${PROJECT_NAME} AUTHOR dragonflylee VERSION 1.0)
|
nx_generate_nacp(${PROJECT_NAME}.nacp NAME ${PROJECT_NAME} AUTHOR dragonflylee VERSION 1.0)
|
||||||
nx_create_nro(${PROJECT_NAME} ICON ${CMAKE_SOURCE_DIR}/icon.jpg NACP ${PROJECT_NAME}.nacp)
|
nx_create_nro(${PROJECT_NAME} ICON ${CMAKE_SOURCE_DIR}/icon.jpg NACP ${PROJECT_NAME}.nacp)
|
||||||
@@ -36,6 +41,6 @@ else ()
|
|||||||
if (MINGW)
|
if (MINGW)
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++")
|
set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++")
|
||||||
endif ()
|
endif ()
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE glfw)
|
target_link_libraries(${PROJECT_NAME} PRIVATE glfw ${MPV_LINK_LIBRARIES})
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
|||||||
3
Makefile
3
Makefile
@@ -26,7 +26,8 @@ CFLAGS += $(INCLUDE) -D__SWITCH__
|
|||||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
|
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
|
||||||
ASFLAGS := -g $(ARCH)
|
ASFLAGS := -g $(ARCH)
|
||||||
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||||
LIBS := -lglfw3 -lEGL -lglapi -ldrm_nouveau -lm -lnx
|
LIBS := `$(PREFIX)pkg-config mpv --libs` \
|
||||||
|
-lglfw3 -lEGL -lglapi -ldrm_nouveau -lm -lnx
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# list of directories containing libraries, this must be the top level containing
|
# list of directories containing libraries, this must be the top level containing
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o)
|
|||||||
INCLUDES := -I$(CURDIR)/imgui
|
INCLUDES := -I$(CURDIR)/imgui
|
||||||
CFLAGS := -O2 -Wall $(INCLUDES) `pkg-config --cflags glfw3`
|
CFLAGS := -O2 -Wall $(INCLUDES) `pkg-config --cflags glfw3`
|
||||||
CXXFLAGS := $(CFLAGS) -std=c++17
|
CXXFLAGS := $(CFLAGS) -std=c++17
|
||||||
LDFLAGS := `pkg-config glfw3 --libs` -lgdi32
|
LDFLAGS := `pkg-config mpv glfw3 --libs` -lgdi32
|
||||||
|
|
||||||
all: $(TARGET)
|
all: $(TARGET)
|
||||||
|
|
||||||
|
|||||||
76
src/main.cpp
76
src/main.cpp
@@ -1,6 +1,9 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include <mpv/client.h>
|
||||||
|
#include <mpv/render_gl.h>
|
||||||
|
|
||||||
#define GLFW_INCLUDE_NONE
|
#define GLFW_INCLUDE_NONE
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
@@ -20,24 +23,56 @@ extern "C" void userAppExit() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void die(const char* msg) {
|
||||||
|
fprintf(stderr, "%s\n", msg);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
// Main code
|
// Main code
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
if (!glfwInit()) return -1;
|
if (argc < 2) die("pass a single media file as argument");
|
||||||
|
|
||||||
|
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, "ytdl", "no");
|
||||||
|
mpv_set_option_string(mpv, "hwdec", "auto");
|
||||||
|
#ifdef _DEBUG
|
||||||
|
mpv_set_option_string(this->mpv, "msg-level", "all=v");
|
||||||
|
#endif
|
||||||
|
if (mpv_initialize(mpv) < 0) die("init mpv failed");
|
||||||
|
|
||||||
static int osdShow = 0;
|
|
||||||
// Create window with graphics context
|
// Create window with graphics context
|
||||||
GLFWwindow* window = glfwCreateWindow(1280, 720, "xPlayer", nullptr, nullptr);
|
GLFWwindow* window = glfwCreateWindow(1280, 720, argv[1], nullptr, nullptr);
|
||||||
if (!window) {
|
if (!window) {
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
glfwSetWindowUserPointer(window, mpv);
|
||||||
glfwSetKeyCallback(window, [](GLFWwindow* window, int key, int scancode, int action, int mods) {
|
glfwSetKeyCallback(window, [](GLFWwindow* window, int key, int scancode, int action, int mods) {
|
||||||
|
mpv_handle* mpv = static_cast<mpv_handle*>(glfwGetWindowUserPointer(window));
|
||||||
if (action == GLFW_PRESS) {
|
if (action == GLFW_PRESS) {
|
||||||
if (key == GLFW_KEY_ESCAPE)
|
if (key == GLFW_KEY_ESCAPE)
|
||||||
glfwSetWindowShouldClose(window, 1);
|
glfwSetWindowShouldClose(window, 1);
|
||||||
else if (key == GLFW_KEY_ENTER)
|
else if (key == GLFW_KEY_ENTER)
|
||||||
osdShow = !osdShow;
|
mpv_command_string(mpv, "script-binding stats/display-stats-toggle");
|
||||||
|
else if (key == GLFW_KEY_SPACE)
|
||||||
|
mpv_command_string(mpv, "cycle pause");
|
||||||
|
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_UP)
|
||||||
|
mpv_command_string(mpv, "playlist-prev");
|
||||||
|
else if (key == GLFW_KEY_DOWN)
|
||||||
|
mpv_command_string(mpv, "playlist-next");
|
||||||
|
else
|
||||||
|
printf("glfwKeyCallback key press %d\n", key);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -45,14 +80,45 @@ int main(int argc, char* argv[]) {
|
|||||||
glfwSwapInterval(1);
|
glfwSwapInterval(1);
|
||||||
glfwSetTime(0);
|
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<char*>(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_render_context_set_update_callback(
|
||||||
|
mpv_context,
|
||||||
|
[](void* obj) {
|
||||||
|
mpv_render_context* ctx = static_cast<mpv_render_context*>(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_async(mpv, 0, args) < 0) die("load file failed");
|
||||||
|
|
||||||
int fbw = 0, fbh = 0;
|
int fbw = 0, fbh = 0;
|
||||||
// Main loop
|
// Main loop
|
||||||
while (!glfwWindowShouldClose(window)) {
|
while (!glfwWindowShouldClose(window)) {
|
||||||
glfwGetFramebufferSize(window, &fbw, &fbh);
|
glfwGetFramebufferSize(window, &fbw, &fbh);
|
||||||
|
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},
|
||||||
|
};
|
||||||
|
mpv_render_context_render(mpv_context, mpv_params);
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
glfwWaitEvents();
|
glfwWaitEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mpv_render_context_free(mpv_context);
|
||||||
|
mpv_terminate_destroy(mpv);
|
||||||
|
|
||||||
glfwDestroyWindow(window);
|
glfwDestroyWindow(window);
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user