diff --git a/CMake/Packages/FindVLC.cmake b/CMake/Packages/FindVLC.cmake deleted file mode 100644 index 8e002d2cf..000000000 --- a/CMake/Packages/FindVLC.cmake +++ /dev/null @@ -1,57 +0,0 @@ -# - Try to find VLC library -# Once done this will define -# -# VLC_FOUND - system has VLC -# VLC_INCLUDE_DIR - The VLC include directory -# VLC_LIBRARIES - The libraries needed to use VLC -# VLC_DEFINITIONS - Compiler switches required for using VLC -# -# Copyright (C) 2008, Tanguy Krotoff -# Copyright (C) 2008, Lukas Durfina -# Copyright (c) 2009, Fathi Boudra -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. -# - -if(VLC_INCLUDE_DIR AND VLC_LIBRARIES) - # In cache already - set(VLC_FIND_QUIETLY TRUE) -endif(VLC_INCLUDE_DIR AND VLC_LIBRARIES) - -# use pkg-config to get the directories and then use these values -# in the FIND_PATH() and FIND_LIBRARY() calls -if(NOT WIN32 AND NOT APPLE) - find_package(PkgConfig) - pkg_check_modules(VLC REQUIRED libvlc>=3.0.0) - set(VLC_DEFINITIONS ${VLC_CFLAGS}) - set(VLC_LIBRARIES ${VLC_LDFLAGS}) -endif(NOT WIN32 AND NOT APPLE) - -if(WIN32) - # TODO add argument support to pass version on find_package - include(MacroEnsureVersion) - macro_ensure_version(3.0.0 ${VLC_VERSION} VLC_VERSION_OK) - if(VLC_VERSION_OK) - set(VLC_FOUND TRUE) - message(STATUS "VLC library found") - else(VLC_VERSION_OK) - set(VLC_FOUND FALSE) - message(FATAL_ERROR "VLC library not found") - endif(VLC_VERSION_OK) - - find_path(VLC_INCLUDE_DIR - NAMES vlc.h - PATHS ${VLC_INCLUDE_DIRS} - PATH_SUFFIXES vlc) - - find_library(VLC_LIBRARIES - NAMES vlc - PATHS ${VLC_LIBRARY_DIRS}) - - include(FindPackageHandleStandardArgs) - find_package_handle_standard_args(VLC DEFAULT_MSG VLC_INCLUDE_DIR VLC_LIBRARIES) - - # show the VLC_INCLUDE_DIR and VLC_LIBRARIES variables only in the advanced view - mark_as_advanced(VLC_INCLUDE_DIR VLC_LIBRARIES) -endif (WIN32) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2577963f0..0d6b79a2d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,7 +35,6 @@ option(RPI "Set to ON to enable Raspberry Pi specific build" ${RPI}) option(BUNDLED_CERTS "Set to ON to use bundled TLS/SSL certificates" ${BUNDLED_CERTS}) option(CEC "Set to ON to enable CEC" ${CEC}) option(VIDEO_HW_DECODING "Set to ON to enable FFmpeg HW decoding" ${VIDEO_HW_DECODING}) -option(VLC_PLAYER "Set to ON to build the VLC-based video player" ${VLC_PLAYER}) option(CLANG_TIDY "Set to ON to build using the clang-tidy static analyzer" ${CLANG_TIDY}) option(ASAN "Set to ON to build with AddressSanitizer" ${ASAN}) option(TSAN "Set to ON to build with ThreadSanitizer" ${TSAN}) @@ -113,9 +112,6 @@ elseif(NOT WIN32) find_package(Freetype REQUIRED) find_package(Pugixml REQUIRED) find_package(SDL2 REQUIRED) - if(VLC_PLAYER) - find_package(VLC REQUIRED) - endif() endif() # Add libCEC support. @@ -278,10 +274,6 @@ if(VIDEO_HW_DECODING) add_definitions(-DVIDEO_HW_DECODING) endif() -if(VLC_PLAYER) - add_definitions(-DBUILD_VLC_PLAYER) -endif() - if(APPLE AND CMAKE_OSX_DEPLOYMENT_TARGET VERSION_LESS 10.14) add_definitions(-DLEGACY_MACOS) endif() @@ -336,9 +328,6 @@ else() ${FREETYPE_INCLUDE_DIRS} ${PUGIXML_INCLUDE_DIRS} ${SDL2_INCLUDE_DIR}) - if(VLC_PLAYER) - set(COMMON_INCLUDE_DIRS ${COMMON_INCLUDE_DIRS} ${VLC_INCLUDE_DIR}) - endif() endif() # For Windows we need to add local include files for the dependency packages. @@ -349,11 +338,6 @@ if(WIN32) endif() endif() -# Temporary solution until the VLC find module has been updated to work properly on macOS. -if(APPLE AND VLC_PLAYER) - set(COMMON_INCLUDE_DIRS ${COMMON_INCLUDE_DIRS} "/Applications/VLC.app/Contents/MacOS/include") -endif() - if(WIN32) set(COMMON_INCLUDE_DIRS ${COMMON_INCLUDE_DIRS} ${WIN32_INCLUDE_DIR}) endif() @@ -407,9 +391,6 @@ elseif(WIN32) "${PROJECT_SOURCE_DIR}/SDL2main.lib" "${PROJECT_SOURCE_DIR}/SDL2.lib" "Winmm.dll") - if(VLC_PLAYER) - set(COMMON_LIBRARIES ${COMMON_LIBRARIES} "${PROJECT_SOURCE_DIR}/libvlc.lib") - endif() else() set(COMMON_LIBRARIES "${PROJECT_SOURCE_DIR}/avcodec-58.dll" "${PROJECT_SOURCE_DIR}/avfilter-7.dll" @@ -426,9 +407,6 @@ elseif(WIN32) "${PROJECT_SOURCE_DIR}/SDL2.dll" "mingw32" "Winmm.dll") - if(VLC_PLAYER) - set(COMMON_LIBRARIES ${COMMON_LIBRARIES} "${PROJECT_SOURCE_DIR}/libvlc.dll") - endif() endif() else() set(COMMON_LIBRARIES ${CURL_LIBRARIES} @@ -437,9 +415,6 @@ else() ${FREETYPE_LIBRARIES} ${PUGIXML_LIBRARIES} ${SDL2_LIBRARY}) - if(VLC_PLAYER) - set(COMMON_LIBRARIES ${COMMON_LIBRARIES} ${VLC_LIBRARIES}) - endif() endif() if(APPLE) @@ -447,11 +422,6 @@ if(APPLE) # has been added to the install prefix. set(CMAKE_INSTALL_PREFIX "/Applications/EmulationStation Desktop Edition.app/Contents/Resources") - if(VLC_PLAYER) - # Required as the VLC find module doesn't work properly on macOS. - set(COMMON_LIBRARIES ${COMMON_LIBRARIES} "/Applications/VLC.app/Contents/MacOS/lib/libvlc.dylib") - endif() - # Set the same rpath links for the install executable as for the build executable. set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) diff --git a/es-app/CMakeLists.txt b/es-app/CMakeLists.txt index 726b12dd2..7f5aaeb46 100644 --- a/es-app/CMakeLists.txt +++ b/es-app/CMakeLists.txt @@ -153,9 +153,6 @@ if(WIN32) ../VCRUNTIME140.dll ../VCRUNTIME140_1.dll DESTINATION .) - if(VLC_PLAYER) - install(FILES ../libvlc.dll ../libvlccore.dll DESTINATION .) - endif() else() install(FILES ../avcodec-58.dll ../avfilter-7.dll @@ -174,13 +171,8 @@ if(WIN32) ../SDL2.dll ../vcomp140.dll DESTINATION .) - if(VLC_PLAYER) - install(FILES ../libvlc.dll ../libvlccore.dll DESTINATION .) - endif() - endif() - if(VLC_PLAYER) - install(DIRECTORY ${CMAKE_SOURCE_DIR}/plugins DESTINATION .) endif() + install(FILES ../LICENSE DESTINATION .) install(DIRECTORY ${CMAKE_SOURCE_DIR}/licenses DESTINATION .) install(DIRECTORY ${CMAKE_SOURCE_DIR}/themes DESTINATION .) @@ -225,15 +217,6 @@ elseif(APPLE) install(FILES ${CMAKE_SOURCE_DIR}/libSDL2-2.0.dylib PERMISSIONS ${APPLE_DYLIB_PERMISSIONS} DESTINATION ../MacOS) - if(VLC_PLAYER) - install(FILES ${CMAKE_SOURCE_DIR}/libvlc.dylib - PERMISSIONS ${APPLE_DYLIB_PERMISSIONS} DESTINATION ../MacOS) - install(FILES ${CMAKE_SOURCE_DIR}/libvlccore.dylib - PERMISSIONS ${APPLE_DYLIB_PERMISSIONS} DESTINATION ../MacOS) - install(DIRECTORY ${CMAKE_SOURCE_DIR}/plugins - DESTINATION ../MacOS) - endif() - install(FILES ${CMAKE_SOURCE_DIR}/LICENSE DESTINATION ../Resources) install(DIRECTORY ${CMAKE_SOURCE_DIR}/resources DESTINATION ../Resources) install(DIRECTORY ${CMAKE_SOURCE_DIR}/themes DESTINATION ../Resources) @@ -342,9 +325,6 @@ else() set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://es-de.org") set(CPACK_DEBIAN_PACKAGE_SECTION "games") set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional") - if(VLC_PLAYER) - set(CPACK_DEBIAN_PACKAGE_DEPENDS "vlc") - endif() set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) if(LINUX_CPACK_GENERATOR STREQUAL "RPM") set(CPACK_GENERATOR "RPM") @@ -352,9 +332,6 @@ else() set(CPACK_RPM_FILE_NAME "emulationstation-de-${CPACK_PACKAGE_VERSION}-${CPU_ARCHITECTURE}.rpm") set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION}) set(CPACK_RPM_PACKAGE_LICENSE "MIT") - if(VLC_PLAYER) - set(CPACK_RPM_PACKAGE_REQUIRES "vlc") - endif() list(APPEND CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "${CMAKE_INSTALL_PREFIX}") list(APPEND CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "${CMAKE_INSTALL_PREFIX}/bin") list(APPEND CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "${CMAKE_INSTALL_PREFIX}/share") diff --git a/es-app/src/MediaViewer.cpp b/es-app/src/MediaViewer.cpp index 9cb225ca3..4ba2c7be6 100644 --- a/es-app/src/MediaViewer.cpp +++ b/es-app/src/MediaViewer.cpp @@ -8,11 +8,8 @@ #include "MediaViewer.h" -#include "components/VideoFFmpegComponent.h" -#if defined(BUILD_VLC_PLAYER) -#include "components/VideoVlcComponent.h" -#endif #include "Sound.h" +#include "components/VideoFFmpegComponent.h" #include "views/ViewController.h" MediaViewer::MediaViewer(Window* window) @@ -260,15 +257,7 @@ void MediaViewer::playVideo() mDisplayingImage = false; ViewController::get()->onStopVideo(); -#if defined(BUILD_VLC_PLAYER) - if (Settings::getInstance()->getString("VideoPlayer") == "ffmpeg") - mVideo = new VideoFFmpegComponent(mWindow); - else - mVideo = new VideoVlcComponent(mWindow); -#else mVideo = new VideoFFmpegComponent(mWindow); -#endif - mVideo->topWindow(true); mVideo->setOrigin(0.5f, 0.5f); mVideo->setPosition(Renderer::getScreenWidth() / 2.0f, Renderer::getScreenHeight() / 2.0f); diff --git a/es-app/src/SystemScreensaver.cpp b/es-app/src/SystemScreensaver.cpp index a6193d143..619bb0595 100644 --- a/es-app/src/SystemScreensaver.cpp +++ b/es-app/src/SystemScreensaver.cpp @@ -9,13 +9,10 @@ #include "SystemScreensaver.h" -#include "components/VideoFFmpegComponent.h" -#if defined(BUILD_VLC_PLAYER) -#include "components/VideoVlcComponent.h" -#endif #include "FileData.h" #include "Log.h" #include "SystemData.h" +#include "components/VideoFFmpegComponent.h" #include "resources/Font.h" #include "utils/FileSystemUtil.h" #include "utils/StringUtil.h" @@ -159,15 +156,7 @@ void SystemScreensaver::startScreensaver(bool generateMediaList) if (Settings::getInstance()->getBool("ScreensaverVideoGameInfo")) generateOverlayInfo(); -#if defined(BUILD_VLC_PLAYER) - if (Settings::getInstance()->getString("VideoPlayer") == "vlc") - mVideoScreensaver = new VideoVlcComponent(mWindow); - else - mVideoScreensaver = new VideoFFmpegComponent(mWindow); -#else mVideoScreensaver = new VideoFFmpegComponent(mWindow); -#endif - mVideoScreensaver->topWindow(true); mVideoScreensaver->setOrigin(0.5f, 0.5f); mVideoScreensaver->setPosition(Renderer::getScreenWidth() / 2.0f, diff --git a/es-app/src/guis/GuiMenu.cpp b/es-app/src/guis/GuiMenu.cpp index 82e966906..deb1d107f 100644 --- a/es-app/src/guis/GuiMenu.cpp +++ b/es-app/src/guis/GuiMenu.cpp @@ -878,27 +878,6 @@ void GuiMenu::openOtherOptions() } }); -#if defined(BUILD_VLC_PLAYER) - // Video player. - auto video_player = std::make_shared>( - mWindow, getHelpStyle(), "FULLSCREEN MODE", false); - std::string selectedPlayer = Settings::getInstance()->getString("VideoPlayer"); - video_player->add("FFmpeg", "ffmpeg", selectedPlayer == "ffmpeg"); - video_player->add("VLC", "vlc", selectedPlayer == "vlc"); - // If there are no objects returned, then there must be a manually modified entry in the - // configuration file. Simply set the video player to VLC in this case. - if (video_player->getSelectedObjects().size() == 0) - video_player->selectEntry(0); - s->addWithLabel("VIDEO PLAYER", video_player); - s->addSaveFunc([video_player, s] { - if (video_player->getSelected() != Settings::getInstance()->getString("VideoPlayer")) { - Settings::getInstance()->setString("VideoPlayer", video_player->getSelected()); - s->setNeedsSaving(); - s->setNeedsReloading(); - } - }); -#endif - // Exit button configuration. auto exit_button_config = std::make_shared>( mWindow, getHelpStyle(), "EXIT BUTTON COMBO", false); @@ -977,11 +956,7 @@ void GuiMenu::openOtherOptions() // Whether to enable hardware decoding for the FFmpeg video player. auto video_hardware_decoding = std::make_shared(mWindow); video_hardware_decoding->setState(Settings::getInstance()->getBool("VideoHardwareDecoding")); -#if defined(BUILD_VLC_PLAYER) - s->addWithLabel("FFMPEG HARDWARE DECODING (EXPERIMENTAL)", video_hardware_decoding); -#else s->addWithLabel("VIDEO HARDWARE DECODING (EXPERIMENTAL)", video_hardware_decoding); -#endif s->addSaveFunc([video_hardware_decoding, s] { if (video_hardware_decoding->getState() != Settings::getInstance()->getBool("VideoHardwareDecoding")) { @@ -995,11 +970,7 @@ void GuiMenu::openOtherOptions() // Whether to upscale the video frame rate to 60 FPS. auto video_upscale_frame_rate = std::make_shared(mWindow); video_upscale_frame_rate->setState(Settings::getInstance()->getBool("VideoUpscaleFrameRate")); -#if defined(BUILD_VLC_PLAYER) - s->addWithLabel("UPSCALE VIDEO FRAME RATE TO 60 FPS (FFMPEG)", video_upscale_frame_rate); -#else s->addWithLabel("UPSCALE VIDEO FRAME RATE TO 60 FPS", video_upscale_frame_rate); -#endif s->addSaveFunc([video_upscale_frame_rate, s] { if (video_upscale_frame_rate->getState() != Settings::getInstance()->getBool("VideoUpscaleFrameRate")) { diff --git a/es-app/src/views/gamelist/VideoGameListView.cpp b/es-app/src/views/gamelist/VideoGameListView.cpp index 265cc4c4f..e80f90691 100644 --- a/es-app/src/views/gamelist/VideoGameListView.cpp +++ b/es-app/src/views/gamelist/VideoGameListView.cpp @@ -8,13 +8,10 @@ #include "views/gamelist/VideoGameListView.h" -#include "animations/LambdaAnimation.h" -#include "components/VideoFFmpegComponent.h" -#if defined(BUILD_VLC_PLAYER) -#include "components/VideoVlcComponent.h" -#endif #include "CollectionSystemsManager.h" #include "SystemData.h" +#include "animations/LambdaAnimation.h" +#include "components/VideoFFmpegComponent.h" #include "utils/FileSystemUtil.h" #include "views/ViewController.h" @@ -53,16 +50,8 @@ VideoGameListView::VideoGameListView(Window* window, FileData* root) { const float padding = 0.01f; - // Create the correct type of video window. - -#if defined(BUILD_VLC_PLAYER) - if (Settings::getInstance()->getString("VideoPlayer") == "vlc") - mVideo = new VideoVlcComponent(window); - else - mVideo = new VideoFFmpegComponent(window); -#else + // Create the video window. mVideo = new VideoFFmpegComponent(window); -#endif mList.setPosition(mSize.x * (0.50f + padding), mList.getPosition().y); mList.setSize(mSize.x * (0.50f - padding), mList.getSize().y); diff --git a/es-core/CMakeLists.txt b/es-core/CMakeLists.txt index d579317c6..e4884b164 100644 --- a/es-core/CMakeLists.txt +++ b/es-core/CMakeLists.txt @@ -60,7 +60,6 @@ set(CORE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/components/TextListComponent.h ${CMAKE_CURRENT_SOURCE_DIR}/src/components/VideoComponent.h ${CMAKE_CURRENT_SOURCE_DIR}/src/components/VideoFFmpegComponent.h - ${CMAKE_CURRENT_SOURCE_DIR}/src/components/VideoVlcComponent.h # GUIs ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiDetectDevice.h @@ -133,7 +132,6 @@ set(CORE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/components/TextEditComponent.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/components/VideoComponent.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/components/VideoFFmpegComponent.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/components/VideoVlcComponent.cpp # GUIs ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiDetectDevice.cpp diff --git a/es-core/src/Settings.cpp b/es-core/src/Settings.cpp index 60834baa1..d9948d636 100644 --- a/es-core/src/Settings.cpp +++ b/es-core/src/Settings.cpp @@ -221,9 +221,6 @@ void Settings::setDefaults() mIntMap["MaxVRAM"] = {256, 256}; #endif mIntMap["DisplayIndex"] = {1, 1}; -#if defined(BUILD_VLC_PLAYER) - mStringMap["VideoPlayer"] = {"ffmpeg", "ffmpeg"}; -#endif mStringMap["ExitButtonCombo"] = {"F4", "F4"}; mStringMap["SaveGamelistsMode"] = {"always", "always"}; #if defined(_WIN64) diff --git a/es-core/src/Window.cpp b/es-core/src/Window.cpp index 7b8ef391c..2e4140122 100644 --- a/es-core/src/Window.cpp +++ b/es-core/src/Window.cpp @@ -9,15 +9,12 @@ #include "Window.h" -#include "components/HelpComponent.h" -#include "components/ImageComponent.h" -#include "guis/GuiInfoPopup.h" -#if defined(BUILD_VLC_PLAYER) -#include "components/VideoVlcComponent.h" -#endif #include "InputManager.h" #include "Log.h" #include "Sound.h" +#include "components/HelpComponent.h" +#include "components/ImageComponent.h" +#include "guis/GuiInfoPopup.h" #include "resources/Font.h" #include @@ -152,9 +149,6 @@ void Window::deinit() InputManager::getInstance()->deinit(); ResourceManager::getInstance()->unloadAll(); -#if defined(BUILD_VLC_PLAYER) - VideoVlcComponent::deinit(); -#endif Renderer::deinit(); } diff --git a/es-core/src/components/VideoVlcComponent.cpp b/es-core/src/components/VideoVlcComponent.cpp deleted file mode 100644 index c6a780946..000000000 --- a/es-core/src/components/VideoVlcComponent.cpp +++ /dev/null @@ -1,549 +0,0 @@ -// SPDX-License-Identifier: MIT -// -// EmulationStation Desktop Edition -// VideoVlcComponent.cpp -// -// Video player based on libVLC. -// - -#if defined(BUILD_VLC_PLAYER) - -#include "components/VideoVlcComponent.h" - -#include "AudioManager.h" -#include "Settings.h" -#include "Window.h" -#include "renderers/Renderer.h" -#include "resources/TextureResource.h" -#include "utils/StringUtil.h" - -#if defined(__APPLE__) -#include "utils/FileSystemUtil.h" -#endif - -#include -#include -#include - -#if defined(_WIN64) -#include -#include -#endif - -libvlc_instance_t* VideoVlcComponent::mVLC = nullptr; - -VideoVlcComponent::VideoVlcComponent(Window* window) - : VideoComponent(window) - , mMedia(nullptr) - , mMediaPlayer(nullptr) - , mContext({}) - , mHasSetAudioVolume(false) -{ - // Get an empty texture for rendering the video. - mTexture = TextureResource::get(""); - - // Make sure VLC has been initialized. - setupVLC(); -} - -VideoVlcComponent::~VideoVlcComponent() -{ - stopVideo(); - mTexture.reset(); -} - -void VideoVlcComponent::deinit() -{ - if (mVLC) { - libvlc_release(mVLC); - mVLC = nullptr; - } -} - -void VideoVlcComponent::setResize(float width, float height) -{ - // This resize function is used when stretching videos to full screen in the video screensaver. - mTargetSize = glm::vec2{width, height}; - mTargetIsMax = false; - mStaticImage.setResize(width, height); - resize(); -} - -void VideoVlcComponent::setMaxSize(float width, float height) -{ - // This resize function is used in most instances, such as non-stretched video screensaver - // and the gamelist videos. - mTargetSize = glm::vec2{width, height}; - mTargetIsMax = true; - mStaticImage.setMaxSize(width, height); - resize(); -} - -void VideoVlcComponent::setupVLC() -{ - // If VLC hasn't been initialised yet then do it now. - if (!mVLC) { - const char* args[] = {"--quiet"}; - -#if defined(__APPLE__) - // It's required to set the VLC_PLUGIN_PATH variable on macOS, or the libVLC - // initialization will fail (with no error message). - std::string vlcPluginPath = Utils::FileSystem::getExePath() + "/plugins"; - if (Utils::FileSystem::isDirectory(vlcPluginPath)) - setenv("VLC_PLUGIN_PATH", vlcPluginPath.c_str(), 1); - else - setenv("VLC_PLUGIN_PATH", "/Applications/VLC.app/Contents/MacOS/plugins/", 1); -#endif - - mVLC = libvlc_new(1, args); - } -} - -void VideoVlcComponent::setupContext() -{ - if (!mContext.valid) { - // Create an RGBA surface to render the video into. - mContext.surface = SDL_CreateRGBSurface(SDL_SWSURFACE, static_cast(mVideoWidth), - static_cast(mVideoHeight), 32, 0xff000000, - 0x00ff0000, 0x0000ff00, 0x000000ff); - mContext.mutex = SDL_CreateMutex(); - mContext.valid = true; - resize(); - mHasSetAudioVolume = false; - } -} - -void VideoVlcComponent::freeContext() -{ - if (mContext.valid) { - SDL_FreeSurface(mContext.surface); - SDL_DestroyMutex(mContext.mutex); - mContext.valid = false; - } -} - -void VideoVlcComponent::resize() -{ - if (!mTexture) - return; - - const glm::vec2 textureSize(static_cast(mVideoWidth), static_cast(mVideoHeight)); - - if (textureSize == glm::vec2{}) - return; - - if (mTargetIsMax) { - mSize = textureSize; - - glm::vec2 resizeScale{(mTargetSize.x / mSize.x), (mTargetSize.y / mSize.y)}; - - if (resizeScale.x < resizeScale.y) { - mSize.x *= resizeScale.x; - mSize.y *= resizeScale.x; - } - else { - mSize.x *= resizeScale.y; - mSize.y *= resizeScale.y; - } - - mSize.x = (mSize.y / textureSize.y) * textureSize.x; - mSize.y = std::round(mSize[1]); - } - else { - // If both components are set, we just stretch. - // If no components are set, we don't resize at all. - mSize = mTargetSize == glm::vec2{} ? textureSize : mTargetSize; - - // If only one component is set, we resize in a way that maintains aspect ratio. - if (!mTargetSize.x && mTargetSize.y) { - mSize.y = std::round(mTargetSize.y); - mSize.x = (mSize.y / textureSize.y) * textureSize.x; - } - else if (mTargetSize.x && !mTargetSize.y) { - mSize.y = std::round((mTargetSize.x / textureSize.x) * textureSize.y); - mSize.x = (mSize.y / textureSize.y) * textureSize.x; - } - } - - onSizeChanged(); -} - -void VideoVlcComponent::render(const glm::mat4& parentTrans) -{ - // Set the audio volume. As libVLC is very unreliable we need to make an additional - // attempt here in the render loop in addition to the initialization in startVideo(). - // This is required under some circumstances such as when running on a slow computer - // or sometimes even on a faster machine when changing to the video view style or - // when starting the application directly into a gamelist. - if (!mHasSetAudioVolume && mMediaPlayer) - setAudioVolume(); - - VideoComponent::render(parentTrans); - glm::mat4 trans{parentTrans * getTransform()}; - GuiComponent::renderChildren(trans); - - // Check the actual VLC state, i.e. if the video is really playing rather than - // still being opened. - if (mMediaPlayer && mIsPlaying && !mIsActuallyPlaying) { - libvlc_state_t state; - state = libvlc_media_player_get_state(mMediaPlayer); - if (state == libvlc_Playing) - mIsActuallyPlaying = true; - } - - if (mIsPlaying && mContext.valid && mIsActuallyPlaying) { - unsigned int color; - if (mFadeIn < 1) { - const unsigned int fadeIn = static_cast(mFadeIn * 255.0f); - color = - Renderer::convertRGBAToABGR((fadeIn << 24) | (fadeIn << 16) | (fadeIn << 8) | 255); - } - else { - color = 0xFFFFFFFF; - } - - Renderer::Vertex vertices[4]; - Renderer::setMatrix(parentTrans); - - // Render the black rectangle behind the video. - if (mVideoRectangleCoords.size() == 4) { - Renderer::drawRect(mVideoRectangleCoords[0], mVideoRectangleCoords[1], - mVideoRectangleCoords[2], mVideoRectangleCoords[3], // Line break. - 0x000000FF, 0x000000FF); - } - - // clang-format off - vertices[0] = {{0.0f , 0.0f }, {0.0f, 0.0f}, color}; - vertices[1] = {{0.0f , mSize.y}, {0.0f, 1.0f}, color}; - vertices[2] = {{mSize.x, 0.0f }, {1.0f, 0.0f}, color}; - vertices[3] = {{mSize.x, mSize.y}, {1.0f, 1.0f}, color}; - // clang-format on - - // Round vertices. - for (int i = 0; i < 4; ++i) - vertices[i].pos = glm::round(vertices[i].pos); - - // Build a texture for the video frame. - mTexture->initFromPixels(reinterpret_cast(mContext.surface->pixels), - mContext.surface->w, mContext.surface->h); - mTexture->bind(); - -#if defined(USE_OPENGL_21) - // Render scanlines if this option is enabled. However, if this is the media viewer - // or the video screensaver, then skip this as the scanline rendering is then handled - // in those modules as a postprocessing step. - if ((!mScreensaverMode && !mMediaViewerMode) && - Settings::getInstance()->getBool("GamelistVideoScanlines")) { - vertices[0].shaders = Renderer::SHADER_SCANLINES; - } -#endif - - // Render it. - Renderer::setMatrix(trans); - Renderer::drawTriangleStrips(&vertices[0], 4, trans); - } - else { - VideoComponent::renderSnapshot(parentTrans); - } -} - -void VideoVlcComponent::calculateBlackRectangle() -{ - // Calculate the position and size for the black rectangle that will be rendered behind - // videos. If the option to display pillarboxes (and letterboxes) is enabled, then this - // would extend to the entire md_video area (if above the threshold as defined below) or - // otherwise it will exactly match the video size. The reason to add a black rectangle - // behind videos in this second instance is that the scanline rendering will make the - // video partially transparent so this may avoid some unforseen issues with some themes. - if (mVideoAreaPos != glm::vec2{} && mVideoAreaSize != glm::vec2{}) { - mVideoRectangleCoords.clear(); - - if (Settings::getInstance()->getBool("GamelistVideoPillarbox")) { - float rectHeight; - float rectWidth; - // Video is in landscape orientation. - if (mSize.x > mSize.y) { - // Checking the Y size should not normally be required as landscape format - // should mean the height can't be higher than the max size defined by the - // theme. But as the height in mSize is provided by libVLC in integer format - // and then scaled, there could be rounding errors that make the video height - // slightly higher than allowed. It's only a single pixel or a few pixels, but - // it's still visible for some videos. - if (mSize.y < mVideoAreaSize.y && mSize.y / mVideoAreaSize.y < 0.90f) - rectHeight = mVideoAreaSize.y; - else - rectHeight = mSize.y; - // Don't add a black border that is too narrow, that's what the 0.85 constant - // takes care of. - if (mSize.x < mVideoAreaSize.x && mSize.x / mVideoAreaSize.x < 0.85f) - rectWidth = mVideoAreaSize.x; - else - rectWidth = mSize.x; - } - // Video is in portrait orientation (or completely square). - else { - rectWidth = mVideoAreaSize.x; - rectHeight = mSize.y; - } - // Populate the rectangle coordinates to be used in render(). - mVideoRectangleCoords.push_back(std::round(mVideoAreaPos.x - rectWidth * mOrigin.x)); - mVideoRectangleCoords.push_back(std::round(mVideoAreaPos.y - rectHeight * mOrigin.y)); - mVideoRectangleCoords.push_back(std::round(rectWidth)); - mVideoRectangleCoords.push_back(std::round(rectHeight)); - } - // If the option to display pillarboxes is disabled, then make the rectangle equivalent - // to the size of the video. - else { - mVideoRectangleCoords.push_back(std::round(mPosition.x - mSize.x * mOrigin.x)); - mVideoRectangleCoords.push_back(std::round(mPosition.y - mSize.y * mOrigin.y)); - mVideoRectangleCoords.push_back(std::round(mSize.x)); - mVideoRectangleCoords.push_back(std::round(mSize.y)); - } - } -} - -void VideoVlcComponent::setAudioVolume() -{ - if (mMediaPlayer && libvlc_media_player_get_state(mMediaPlayer) == libvlc_Playing) { - // This small delay may avoid a race condition in libVLC that could crash the application. - SDL_Delay(2); - - bool outputSound = false; - - if ((!mScreensaverMode && !mMediaViewerMode) && - Settings::getInstance()->getBool("GamelistVideoAudio")) - outputSound = true; - else if (mScreensaverMode && Settings::getInstance()->getBool("ScreensaverVideoAudio")) - outputSound = true; - else if (mMediaViewerMode && Settings::getInstance()->getBool("MediaViewerVideoAudio")) - outputSound = true; - - if (outputSound) { - if (libvlc_audio_get_mute(mMediaPlayer) == 1) - libvlc_audio_set_mute(mMediaPlayer, 0); - libvlc_audio_set_volume(mMediaPlayer, - Settings::getInstance()->getInt("SoundVolumeVideos")); - } - else { - libvlc_audio_set_volume(mMediaPlayer, 0); - } - - mHasSetAudioVolume = true; - } -} - -void VideoVlcComponent::startVideo() -{ - if (!mIsPlaying && !mGameLaunched) { - mVideoWidth = 0; - mVideoHeight = 0; - -#if defined(_WIN64) - std::string path(Utils::String::replace(mVideoPath, "/", "\\")); -#else - std::string path(mVideoPath); -#endif - // Make sure we have a video path. - if (mVLC && (path.size() > 0)) { - // Set the video that we are going to be playing so we don't attempt to restart it. - mPlayingVideoPath = mVideoPath; - - // Open the media. - mMedia = libvlc_media_new_path(mVLC, path.c_str()); - if (mMedia) { - unsigned track_count; - int parseResult; - - // Asynchronous media parsing. - libvlc_event_attach(libvlc_media_event_manager(mMedia), libvlc_MediaParsedChanged, - VlcMediaParseCallback, 0); - parseResult = libvlc_media_parse_with_options(mMedia, libvlc_media_parse_local, -1); - - if (!parseResult) { - // Wait for a maximum of 1 second for the media parsing. - // This maximum time is quite excessive as this step should normally - // be completed in 15 - 30 ms or so. - for (int i = 0; i < 200; ++i) { - if (libvlc_media_get_parsed_status(mMedia)) - break; - SDL_Delay(5); - }; - } - - libvlc_media_track_t** tracks; - track_count = libvlc_media_tracks_get(mMedia, &tracks); - for (unsigned track = 0; track < track_count; ++track) { - if (tracks[track]->i_type == libvlc_track_video) { - mVideoWidth = tracks[track]->video->i_width; - mVideoHeight = tracks[track]->video->i_height; - break; - } - } - libvlc_media_tracks_release(tracks, track_count); - libvlc_media_parse_stop(mMedia); - libvlc_event_detach(libvlc_media_event_manager(mMedia), libvlc_MediaParsedChanged, - VlcMediaParseCallback, 0); - - // Make sure we found a valid video track. - if ((mVideoWidth > 0) && (mVideoHeight > 0)) { - setupContext(); - - // Setup the media player. - mMediaPlayer = libvlc_media_player_new_from_media(mMedia); - - // The code below enables the libVLC audio output to be processed inside ES-DE. - // Unfortunately this causes excessive stuttering for some reason that I still - // don't understand, so at the moment this code is disabled. - // auto audioFormatCallback = [](void **data, char *format, - // unsigned *rate, unsigned *channels) -> int { - // format = const_cast("F32L"); - // *rate = 48000; - // *channels = 2; - // return 0; - // }; - // - // libvlc_audio_set_format_callbacks(mMediaPlayer, - // audioFormatCallback, nullptr); - // - // auto audioPlayCallback = [](void* data, const void* - // samples, - // unsigned count, int64_t pts) { - // AudioManager::getInstance()->processStream(samples, - // count); - // }; - // - // libvlc_audio_set_callbacks(mMediaPlayer, - // audioPlayCallback, - // nullptr, nullptr, nullptr, nullptr, this); - - libvlc_video_set_format(mMediaPlayer, "RGBA", static_cast(mVideoWidth), - static_cast(mVideoHeight), - static_cast(mVideoWidth * 4)); - - // Lock video memory as a preparation for rendering a frame. - auto videoLockCallback = [](void* data, void** p_pixels) -> void* { - struct VideoContext* videoContext = - reinterpret_cast(data); - SDL_LockMutex(videoContext->mutex); - SDL_LockSurface(videoContext->surface); - *p_pixels = videoContext->surface->pixels; - return nullptr; // Picture identifier, not needed here. - }; - - // Unlock the video memory after rendering a frame. - auto videoUnlockCallback = [](void* data, void*, void* const*) { - struct VideoContext* videoContext = - reinterpret_cast(data); - SDL_UnlockSurface(videoContext->surface); - SDL_UnlockMutex(videoContext->mutex); - }; - - libvlc_video_set_callbacks(mMediaPlayer, videoLockCallback, videoUnlockCallback, - nullptr, reinterpret_cast(&mContext)); - - libvlc_media_player_play(mMediaPlayer); - - // Calculate pillarbox/letterbox sizes. - calculateBlackRectangle(); - - libvlc_state_t state; - state = libvlc_media_player_get_state(mMediaPlayer); - if (state != libvlc_Playing) { - // Wait for a maximum of 100 ms for the status of the video to change - // to libvlc_Playing as there would otherwise be a brief flicker before - // the video starts to play. This is also required to prevent the - // application from crashing under some circumstances as changing the - // video player audio volume is apparently not properly handled by libVLC. - // This maximum time is quite excessive as this step should normally - // be completed in 4 - 16 ms or so even on slower machines. - for (int i = 0; i < 50; ++i) { - state = libvlc_media_player_get_state(mMediaPlayer); - if (state == libvlc_Playing) { - // This additional delay is needed to prevent some kind of race - // condition in libVLC which would otherwise crash the application. - SDL_Delay(2); - break; - } - SDL_Delay(2); - }; - } - - // Attempt to set the audio volume. Under some circumstances it could fail - // as libVLC may not be correctly initialized. Therefore there is an - // additional call to this function in the render() loop. - setAudioVolume(); - - // Update the playing state. - mIsPlaying = true; - mFadeIn = 0.0f; - } - } - } - } -} - -void VideoVlcComponent::stopVideo() -{ - mIsPlaying = false; - mIsActuallyPlaying = false; - mStartDelayed = false; - mPause = false; - // Release the media player so it stops calling back to us. - if (mMediaPlayer) { - libvlc_media_player_stop(mMediaPlayer); - libvlc_media_player_release(mMediaPlayer); - libvlc_media_release(mMedia); - mMediaPlayer = nullptr; - mMedia = nullptr; - freeContext(); - } -} - -void VideoVlcComponent::pauseVideo() -{ - // If a game has been launched and the flag to pause the video has been - // set, then rewind and pause. - if (!mPause || !mMediaPlayer) - return; - - if (libvlc_media_player_get_state(mMediaPlayer) == libvlc_Playing) { - libvlc_media_player_set_position(mMediaPlayer, 0.0f); - libvlc_media_player_pause(mMediaPlayer); - } -} - -void VideoVlcComponent::handleLooping() -{ - if (mIsPlaying && mMediaPlayer) { - libvlc_state_t state = libvlc_media_player_get_state(mMediaPlayer); - if (state == libvlc_Ended) { - // If the screensaver video swap time is set to 0, it means we should - // skip to the next game when the video has finished playing. - if (mScreensaverMode && - Settings::getInstance()->getInt("ScreensaverSwapVideoTimeout") == 0) { - mWindow->screensaverTriggerNextGame(); - } - else { - libvlc_media_player_set_media(mMediaPlayer, mMedia); - libvlc_media_player_play(mMediaPlayer); - - bool outputSound = false; - - if ((!mScreensaverMode && !mMediaViewerMode) && - Settings::getInstance()->getBool("GamelistVideoAudio")) - outputSound = true; - else if (mScreensaverMode && - Settings::getInstance()->getBool("ScreensaverVideoAudio")) - outputSound = true; - else if (mMediaViewerMode && - Settings::getInstance()->getBool("MediaViewerVideoAudio")) - outputSound = true; - - if (!outputSound) - libvlc_audio_set_volume(mMediaPlayer, 0); - } - } - } -} - -#endif diff --git a/es-core/src/components/VideoVlcComponent.h b/es-core/src/components/VideoVlcComponent.h deleted file mode 100644 index 864060155..000000000 --- a/es-core/src/components/VideoVlcComponent.h +++ /dev/null @@ -1,81 +0,0 @@ -// SPDX-License-Identifier: MIT -// -// EmulationStation Desktop Edition -// VideoVlcComponent.h -// -// Video player based on libVLC. -// - -#ifndef ES_CORE_COMPONENTS_VIDEO_VLC_COMPONENT_H -#define ES_CORE_COMPONENTS_VIDEO_VLC_COMPONENT_H - -#include "VideoComponent.h" - -#include - -struct SDL_mutex; -struct SDL_Surface; -struct libvlc_instance_t; -struct libvlc_media_t; -struct libvlc_media_player_t; - -struct VideoContext { - SDL_Surface* surface; - SDL_mutex* mutex; - bool valid; -}; - -class VideoVlcComponent : public VideoComponent -{ -public: - VideoVlcComponent(Window* window); - virtual ~VideoVlcComponent(); - - static void deinit(); - - // Resize the video to fit this size. If one axis is zero, scale that axis to maintain - // aspect ratio. If both are non-zero, potentially break the aspect ratio. If both are - // zero, no resizing. This can be set before or after a video is loaded. - // setMaxSize() and setResize() are mutually exclusive. - void setResize(float width, float height) override; - - // Resize the video to be as large as possible but fit within a box of this size. - // This can be set before or after a video is loaded. - // Never breaks the aspect ratio. setMaxSize() and setResize() are mutually exclusive. - void setMaxSize(float width, float height) override; - -private: - static void setupVLC(); - void setupContext(); - void freeContext(); - - // Calculates the correct mSize from our resizing information (set by setResize/setMaxSize). - // Used internally whenever the resizing parameters or texture change. - void resize(); - - void render(const glm::mat4& parentTrans) override; - void calculateBlackRectangle(); - void setAudioVolume(); - - // Start the video immediately. - virtual void startVideo() override; - // Stop the video. - virtual void stopVideo() override; - // Pause the video when a game has been launched. - virtual void pauseVideo() override; - // Handle looping the video. Must be called periodically. - virtual void handleLooping() override; - - static void VlcMediaParseCallback(const libvlc_event_t* event, void* user_data) {} - - static VideoVlcComponent* sInstance; - static libvlc_instance_t* mVLC; - libvlc_media_t* mMedia; - libvlc_media_player_t* mMediaPlayer; - VideoContext mContext; - bool mHasSetAudioVolume; - std::shared_ptr mTexture; - std::vector mVideoRectangleCoords; -}; - -#endif // ES_CORE_COMPONENTS_VIDEO_VLC_COMPONENT_H