Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Video player #346

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,6 @@
[submodule "lib/libdmusic"]
path = lib/libdmusic
url = https://github.com/frabert/libdmusic.git
[submodule "lib/ffmpeg"]
path = lib/ffmpeg
url = https://github.com/FFmpeg/FFmpeg.git
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ matrix:
- libasound2-dev
- alsa-utils
- alsa-oss
- nasm
script: ./bin/build_unix.sh
before_deploy: ./bin/archive_unix.sh
- os: linux
Expand Down Expand Up @@ -81,6 +82,6 @@ matrix:
compiler: clang
before_install:
- brew update
- brew install libsndfile
- brew install libsndfile nasm
script: ./bin/build_unix.sh
before_deploy: ./bin/archive_unix.sh
13 changes: 13 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ file(GLOB ENGINE_SRC
"src/utils/*.h"
"src/math/*.cpp"
"src/math/*.h"
"src/media/*.cpp"
"src/media/*.h"
"src/ui/*.cpp"
"src/ui/*.h"
"src/logic/*.cpp"
Expand Down Expand Up @@ -287,6 +289,17 @@ include_directories(${CMAKE_SOURCE_DIR}/lib/libdmusic/include)

target_link_libraries(engine dmusic)

# ------------------ FFmpeg ------------------

include("cmake/ffmpeg.cmake")
ffmpeg_build("${CMAKE_CURRENT_SOURCE_DIR}/lib/ffmpeg" "${CMAKE_CURRENT_BINARY_DIR}/lib/ffmpeg"
avcodec avutil avformat
)
if (FFMPEG_ENABLED)
add_definitions(-DRE_ENABLE_FFMPEG)
target_link_libraries(engine FFMPEG_avformat FFMPEG_avcodec FFMPEG_avutil)
endif()

# ------------------ Other ------------------

include_directories(src)
Expand Down
45 changes: 45 additions & 0 deletions cmake/ffmpeg.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@

function(FFMPEG_BUILD SOURCE_DIR BUILD_DIR)
if (UNIX)
include(ExternalProject)

set(BINARY_DIR "${BUILD_DIR}/build")
set(INSTALL_DIR "${BUILD_DIR}/install")

if(NOT EXISTS "${BINARY_DIR}")
file(MAKE_DIRECTORY "${BINARY_DIR}")
endif()

ExternalProject_Add(FFMPEG_PROJECT
SOURCE_DIR "${SOURCE_DIR}"
CONFIGURE_COMMAND "${SOURCE_DIR}/configure" "--prefix=\"${INSTALL_DIR}\""
--disable-iconv
--disable-programs
--disable-doc
--disable-everything
--disable-zlib
--enable-demuxer=bink
--enable-decoder=bink,binkaudio_dct,binkaudio_rdft
--enable-protocol=file
BINARY_DIR "${BINARY_DIR}"
BUILD_COMMAND make
)

foreach(LIBRARY ${ARGN})
set(LOCATION "${INSTALL_DIR}/lib/lib${LIBRARY}.a")
set(INCLUDE_DIR "${INSTALL_DIR}/include")
message(STATUS "FFMPEG library ${LIBRARY} expected at ${LOCATION} (include path: ${INCLUDE_DIR})")

add_library(FFMPEG_${LIBRARY} IMPORTED STATIC)
set_property(TARGET FFMPEG_${LIBRARY} PROPERTY IMPORTED_LOCATION "${LOCATION}")

file(MAKE_DIRECTORY "${INCLUDE_DIR}") # workaround for CMake Issue #15052
set_property(TARGET FFMPEG_${LIBRARY} PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${INCLUDE_DIR}")
add_dependencies(FFMPEG_${LIBRARY} FFMPEG_PROJECT)
endforeach()

set(FFMPEG_ENABLED 1 PARENT_SCOPE)
else()
message(WARNING "No support for video player on this platform")
endif()
endfunction()
1 change: 1 addition & 0 deletions lib/ffmpeg
Submodule ffmpeg added at e28b1f
19 changes: 18 additions & 1 deletion src/content/Texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Handle::TextureHandle TextureAllocator::loadTextureDDS(const std::vector<uint8_t
m_Allocator.getElement(h).textureFormat = bgfx::TextureFormat::Unknown;
m_Allocator.getElement(h).imageData = data;
//m_Allocator.getElement(h).m_TextureHandle = bth;
m_Allocator.getElement(h).m_TextureHandle.idx = bgfx::kInvalidHandle;
m_Allocator.getElement(h).m_TextureName = name;

ZenLoad::DDSURFACEDESC2 desc = ZenLoad::getSurfaceDesc(data);
Expand Down Expand Up @@ -80,6 +81,7 @@ Handle::TextureHandle TextureAllocator::loadTextureRGBA8(const std::vector<uint8
m_Allocator.getElement(h).textureFormat = bgfx::TextureFormat::RGBA8;
m_Allocator.getElement(h).imageData = data;
//m_Allocator.getElement(h).m_TextureHandle = bth;
m_Allocator.getElement(h).m_TextureHandle.idx = bgfx::kInvalidHandle;
m_Allocator.getElement(h).m_TextureName = name;
m_Allocator.getElement(h).m_Width = width;
m_Allocator.getElement(h).m_Height = height;
Expand Down Expand Up @@ -174,10 +176,23 @@ Handle::TextureHandle TextureAllocator::loadTextureVDF(const std::string& name)
return loadTextureVDF(m_Engine.getVDFSIndex(), name);
}

void TextureAllocator::asyncFinalizeLoad(Handle::TextureHandle h)
{
m_Engine.getJobManager().executeInMainThread<void>([this, h](Engine::BaseEngine* pEngine) {
finalizeLoad(h);
});
}

bool TextureAllocator::finalizeLoad(Handle::TextureHandle h)
{
Texture& tx = m_Allocator.getElement(h);

// if there's already a texture loaded for the object, destroy it
if (tx.m_TextureHandle.idx != bgfx::kInvalidHandle) {
bgfx::destroy(tx.m_TextureHandle);
tx.m_TextureHandle.idx = bgfx::kInvalidHandle;
}

std::uint32_t textureFlags = BGFX_TEXTURE_NONE;

if (this->m_Engine.getEngineArgs().noTextureFiltering)
Expand All @@ -197,8 +212,10 @@ bool TextureAllocator::finalizeLoad(Handle::TextureHandle h)
//stbi_image_free(out);

// Couldn't load this one?
if (bth.idx == bgfx::kInvalidHandle)
if (bth.idx == bgfx::kInvalidHandle) {
LogWarn() << "Could not finalize texture load";
return false;
}

tx.m_TextureHandle = bth;
}
Expand Down
2 changes: 2 additions & 0 deletions src/content/Texture.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ namespace Textures
* @return Rough estimation about how much memory the loaded textures need on the GPU in bytes
*/
size_t getEstimatedGPUMemoryConsumption() { return m_EstimatedGPUBytes; }

void asyncFinalizeLoad(Handle::TextureHandle h);
protected:
/**
* Pushes the loaded data to the GPU. Needs to run on the main-thread.
Expand Down
7 changes: 6 additions & 1 deletion src/engine/BaseEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ void BaseEngine::initEngine(int argc, char** argv)

m_AudioEngine = new Audio::AudioEngine(snd_device);

m_VideoPlayer = new Media::VideoPlayer(*this);

// Init HUD
m_pFontCache = new UI::zFontCache(*this);
m_pHUD = new UI::Hud(*this);
Expand All @@ -126,7 +128,10 @@ void BaseEngine::initEngine(int argc, char** argv)

void BaseEngine::frameUpdate(double dt, uint16_t width, uint16_t height)
{
onFrameUpdate(dt * getGameClock().getGameEngineSpeedFactor(), width, height);
if (m_VideoPlayer->active())
m_VideoPlayer->frameUpdate(dt, width, height);
else
onFrameUpdate(dt * getGameClock().getGameEngineSpeedFactor(), width, height);
}

void BaseEngine::loadArchives()
Expand Down
7 changes: 7 additions & 0 deletions src/engine/BaseEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
#include <logic/Console.h>
#include <logic/SavegameManager.h>
#include <memory/StaticReferencedAllocator.h>
#include <media/Video.h>
#include <ui/View.h>
#include <vdfs/fileIndex.h>
#include <media/Video.h>

namespace UI
{
Expand Down Expand Up @@ -116,6 +118,9 @@ namespace Engine
* @return Base-level UI-View. Parent of all other views.
*/
UI::View& getRootUIView() { return m_RootUIView; }

Media::VideoPlayer& getVideoPlayer() { return *m_VideoPlayer; }

/**
* // TODO: Move to GameEngine, or pass GameEngine to world!
* @return HUD
Expand Down Expand Up @@ -220,6 +225,8 @@ namespace Engine

Audio::AudioEngine* m_AudioEngine = nullptr;

Media::VideoPlayer* m_VideoPlayer = nullptr;

/**
* Base UI-View
*/
Expand Down
22 changes: 22 additions & 0 deletions src/logic/scriptExternals/Externals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1503,4 +1503,26 @@ void ::Logic::ScriptExternals::registerEngineExternals(World::WorldInstance& wor
npc.playerController->drawWeaponMelee(true);
}
});

vm->registerExternalFunction("playvideo", [=](Daedalus::DaedalusVM& vm) {
engine->getVideoPlayer().play(vm.popString());
// this function is actually declared as int, but the return value is never used in the original scripts
// and the Gothic compiler doesn't pop unused expressions
vm.setReturn(0);
});

vm->registerExternalFunction("playvideoex", [=](Daedalus::DaedalusVM& vm) {
if (verbose) LogInfo() << "playvideoex";
int exitsession = vm.popDataValue();
if (verbose) LogInfo() << "exitsession: " << exitsession;
int screenblend = vm.popDataValue();
if (verbose) LogInfo() << "screenblend: " << screenblend;
std::string filename = vm.popString();
if (verbose) LogInfo() << "filename: " << filename;

engine->getVideoPlayer().play(filename); // TODO: use exitseesion and screenblend parameters
// this function is actually declared as int, but the return value is never used in the original scripts
// and the Gothic compiler doesn't pop unused expressions
vm.setReturn(0);
});
}
24 changes: 2 additions & 22 deletions src/logic/scriptExternals/Stubs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include <daedalus/DaedalusVM.h>
#include <utils/logger.h>

#include <media/Video.h>

void ::Logic::ScriptExternals::registerStubs(Daedalus::DaedalusVM& vm, bool verbose)
{
vm.registerExternalFunction("npc_getequippedarmor", [=](Daedalus::DaedalusVM& vm) {
Expand Down Expand Up @@ -838,28 +840,6 @@ void ::Logic::ScriptExternals::registerStubs(Daedalus::DaedalusVM& vm, bool verb
vm.setReturn(0);
});

vm.registerExternalFunction("playvideo", [=](Daedalus::DaedalusVM& vm) {
if (verbose) LogInfo() << "playvideo";
std::string filename = vm.popString();
if (verbose) LogInfo() << "filename: " << filename;
// this function is actually declared as int, but the return value is never used in the original scripts
// and the Gothic compiler doesn't pop unused expressions
vm.setReturn(0);
});

vm.registerExternalFunction("playvideoex", [=](Daedalus::DaedalusVM& vm) {
if (verbose) LogInfo() << "playvideoex";
int exitsession = vm.popDataValue();
if (verbose) LogInfo() << "exitsession: " << exitsession;
int screenblend = vm.popDataValue();
if (verbose) LogInfo() << "screenblend: " << screenblend;
std::string filename = vm.popString();
if (verbose) LogInfo() << "filename: " << filename;
// this function is actually declared as int, but the return value is never used in the original scripts
// and the Gothic compiler doesn't pop unused expressions
vm.setReturn(0);
});

vm.registerExternalFunction("printdialog", [=](Daedalus::DaedalusVM& vm) {
if (verbose) LogInfo() << "printdialog";
int i5 = vm.popDataValue();
Expand Down
Loading