mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-02-22 04:49:12 -06:00
Cleanup, add comments and rename AnimationMode to PlaybackMode
This commit is contained in:
@@ -59,9 +59,9 @@ namespace {
|
||||
"'YYYY MM DD hh:mm:ss'."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo AnimationModeInfo = {
|
||||
"AnimationMode",
|
||||
"Animation Mode",
|
||||
constexpr openspace::properties::Property::PropertyInfo PlaybackModeInfo = {
|
||||
"PlaybackMode",
|
||||
"Playback Mode",
|
||||
"Determines the way the video should be played. The start and end time of the "
|
||||
"video can be set, or the video can be played as a loop in real time."
|
||||
};
|
||||
@@ -94,14 +94,14 @@ namespace {
|
||||
// [[codegen::verbatim(EndTimeInfo.description)]]
|
||||
std::optional<std::string> endTime [[codegen::datetime()]];
|
||||
|
||||
enum class AnimationMode {
|
||||
enum class PlaybackMode {
|
||||
MapToSimulationTime = 0,
|
||||
RealTimeLoop
|
||||
};
|
||||
|
||||
// The mode of how the animation should be played back.
|
||||
// The mode of how the video should be played back.
|
||||
// Default is video is played back according to the set start and end times.
|
||||
std::optional<AnimationMode> animationMode;
|
||||
std::optional<PlaybackMode> playbackMode;
|
||||
|
||||
};
|
||||
#include "videotileprovider_codegen.cpp"
|
||||
@@ -126,6 +126,8 @@ void* getOpenGLProcAddress(void*, const char* name) {
|
||||
void VideoTileProvider::on_mpv_render_update(void* ctx) {
|
||||
// The wakeup flag is set here to enable the mpv_render_context_render
|
||||
// path in the main loop.
|
||||
// The pattern here with a static function and a void pointer to the the class
|
||||
// instance is a common pattern where C++ integrates a C library
|
||||
static_cast<VideoTileProvider*>(ctx)->_wakeup = 1;
|
||||
}
|
||||
|
||||
@@ -187,20 +189,20 @@ VideoTileProvider::VideoTileProvider(const ghoul::Dictionary& dictionary)
|
||||
|
||||
_videoFile = p.file;
|
||||
|
||||
if (p.animationMode.has_value()) {
|
||||
switch (*p.animationMode) {
|
||||
case Parameters::AnimationMode::RealTimeLoop:
|
||||
_animationMode = AnimationMode::RealTimeLoop;
|
||||
if (p.playbackMode.has_value()) {
|
||||
switch (*p.playbackMode) {
|
||||
case Parameters::PlaybackMode::RealTimeLoop:
|
||||
_playbackMode = PlaybackMode::RealTimeLoop;
|
||||
break;
|
||||
case Parameters::AnimationMode::MapToSimulationTime:
|
||||
_animationMode = AnimationMode::MapToSimulationTime;
|
||||
case Parameters::PlaybackMode::MapToSimulationTime:
|
||||
_playbackMode = PlaybackMode::MapToSimulationTime;
|
||||
break;
|
||||
default:
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
}
|
||||
|
||||
if (_animationMode == AnimationMode::RealTimeLoop) {
|
||||
if (_playbackMode == PlaybackMode::RealTimeLoop) {
|
||||
// Video interaction. Only valid for real time looping
|
||||
_play.onChange([this]() { play(); });
|
||||
addProperty(_play);
|
||||
@@ -209,7 +211,7 @@ VideoTileProvider::VideoTileProvider(const ghoul::Dictionary& dictionary)
|
||||
_goToStart.onChange([this]() { goToStart(); });
|
||||
addProperty(_goToStart);
|
||||
}
|
||||
else if (_animationMode == AnimationMode::MapToSimulationTime) {
|
||||
else if (_playbackMode == PlaybackMode::MapToSimulationTime) {
|
||||
if (!p.startTime.has_value() || !p.endTime.has_value()) {
|
||||
LERROR("Video tile layer tried to map to simulation time but lacked start or"
|
||||
" end time");
|
||||
@@ -354,7 +356,7 @@ void VideoTileProvider::initializeMpv() {
|
||||
// See order at https://github.com/mpv-player/mpv/blob/master/libmpv/client.h#L420
|
||||
// Avoiding async calls in uninitialized state
|
||||
|
||||
if (_animationMode == AnimationMode::RealTimeLoop) {
|
||||
if (_playbackMode == PlaybackMode::RealTimeLoop) {
|
||||
// Loop video
|
||||
// https://mpv.io/manual/master/#options-loop
|
||||
setPropertyStringMpv("loop", "");
|
||||
@@ -443,7 +445,7 @@ void VideoTileProvider::initializeMpv() {
|
||||
observePropertyMpv("metadata", MPV_FORMAT_NODE, LibmpvPropertyKey::Meta);
|
||||
observePropertyMpv("container-fps", MPV_FORMAT_DOUBLE, LibmpvPropertyKey::Fps);
|
||||
|
||||
if (_animationMode == AnimationMode::MapToSimulationTime) {
|
||||
if (_playbackMode == PlaybackMode::MapToSimulationTime) {
|
||||
pause();
|
||||
}
|
||||
|
||||
@@ -485,7 +487,7 @@ void VideoTileProvider::seekToTime(double time) {
|
||||
}
|
||||
|
||||
void VideoTileProvider::renderMpv() {
|
||||
if (_animationMode == AnimationMode::MapToSimulationTime) {
|
||||
if (_playbackMode == PlaybackMode::MapToSimulationTime) {
|
||||
// If we are in valid times, step frames accordingly
|
||||
if (isWithingStartEndTime()) {
|
||||
double now = global::timeManager->time().j2000Seconds();
|
||||
@@ -673,30 +675,13 @@ void VideoTileProvider::handleMpvProperties(mpv_event* event) {
|
||||
_videoDuration = *duration;
|
||||
_frameDuration = ( 1.0 / _fps) * ((_endJ200Time - _startJ200Time) / _videoDuration);
|
||||
|
||||
if (_animationMode == AnimationMode::MapToSimulationTime) {
|
||||
if (_playbackMode == PlaybackMode::MapToSimulationTime) {
|
||||
seekToTime(correctVideoPlaybackTime());
|
||||
}
|
||||
|
||||
LINFO(fmt::format("Duration: {}", *duration));
|
||||
break;
|
||||
}
|
||||
case LibmpvPropertyKey::Eof: {
|
||||
if (!event->data) {
|
||||
LERROR("Could not find eof property");
|
||||
break;
|
||||
}
|
||||
|
||||
struct mpv_event_property* property = (struct mpv_event_property*)event->data;
|
||||
int* eof = static_cast<int*>(property->data);
|
||||
|
||||
if (!eof) {
|
||||
LERROR("Could not find eof property");
|
||||
break;
|
||||
}
|
||||
|
||||
_hasReachedEnd = *eof > 0;
|
||||
break;
|
||||
}
|
||||
case LibmpvPropertyKey::Height: {
|
||||
if (!event->data) {
|
||||
LERROR("Could not find height property");
|
||||
@@ -969,14 +954,6 @@ void VideoTileProvider::createFBO(int width, int height) {
|
||||
|
||||
// Unbind FBO
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
// Render video frame to texture
|
||||
_mpvFbo = mpv_opengl_fbo{
|
||||
static_cast<int>(_fbo),
|
||||
_videoResolution.x,
|
||||
_videoResolution.y,
|
||||
0
|
||||
};
|
||||
}
|
||||
|
||||
void VideoTileProvider::resizeFBO(int width, int height) {
|
||||
|
||||
@@ -45,21 +45,23 @@ public:
|
||||
VideoTileProvider(const ghoul::Dictionary& dictionary);
|
||||
~VideoTileProvider();
|
||||
|
||||
Tile tile(const TileIndex& tileIndex) override final;
|
||||
Tile::Status tileStatus(const TileIndex& tileIndex) override final;
|
||||
TileDepthTransform depthTransform() override final;
|
||||
void update() override final;
|
||||
void reset() override final;
|
||||
int minLevel() override final;
|
||||
int maxLevel() override final;
|
||||
float noDataValueAsFloat() override final;
|
||||
ChunkTile chunkTile(TileIndex tileIndex, int parents, int maxParents = 1337) override;
|
||||
Tile tile(const TileIndex& tileIndex) override final;
|
||||
Tile::Status tileStatus(const TileIndex& tileIndex) override final;
|
||||
TileDepthTransform depthTransform() override final;
|
||||
|
||||
// Video interaction
|
||||
void pause();
|
||||
void play();
|
||||
void goToStart();
|
||||
void stepFrameForward();
|
||||
void stepFrameBackward();
|
||||
void seekToTime(double time);
|
||||
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
@@ -72,19 +74,18 @@ private:
|
||||
// libmpv property keys
|
||||
enum class LibmpvPropertyKey : uint64_t {
|
||||
Duration = 1,
|
||||
Eof,
|
||||
Height,
|
||||
Width,
|
||||
Meta,
|
||||
Params,
|
||||
Time,
|
||||
Command,
|
||||
Seek,
|
||||
Width,
|
||||
Fps,
|
||||
Pause
|
||||
};
|
||||
|
||||
enum class AnimationMode {
|
||||
enum class PlaybackMode {
|
||||
MapToSimulationTime = 0,
|
||||
RealTimeLoop
|
||||
};
|
||||
@@ -97,51 +98,51 @@ private:
|
||||
bool isWithingStartEndTime() const;
|
||||
|
||||
// Libmpv
|
||||
static void on_mpv_render_update(void*); // Has to be static because of C api
|
||||
void initializeMpv(); // Called first time in postSyncPreDraw
|
||||
void renderMpv(); // Called in postSyncPreDraw
|
||||
void handleMpvEvents();
|
||||
void handleMpvProperties(mpv_event* event);
|
||||
void swapBuffersMpv(); // Called in postDraw
|
||||
void cleanUpMpv(); // Called in internalDeinitialze
|
||||
static void on_mpv_render_update(void*); // Has to be static because of C api
|
||||
void observePropertyMpv(std::string name, mpv_format format, LibmpvPropertyKey key);
|
||||
void setPropertyStringMpv(std::string name, std::string value);
|
||||
void getPropertyAsyncMpv(std::string name, mpv_format format, LibmpvPropertyKey key);
|
||||
void commandAsyncMpv(const char* cmd[],
|
||||
LibmpvPropertyKey key = LibmpvPropertyKey::Command);
|
||||
void seekToTime(double time);
|
||||
|
||||
void internalInitialize() override final;
|
||||
void internalDeinitialize() override final;
|
||||
|
||||
AnimationMode _animationMode = AnimationMode::RealTimeLoop; // Default is to loop
|
||||
PlaybackMode _playbackMode = PlaybackMode::RealTimeLoop; // Default is to loop
|
||||
std::filesystem::path _videoFile;
|
||||
|
||||
// Video stretching: map to simulation time animation mode
|
||||
double _startJ200Time = 0.0;
|
||||
double _endJ200Time = 0.0;
|
||||
double _currentVideoTime = 0.0;
|
||||
double _frameDuration = 0.0;
|
||||
double _fps = 0.04166666667; // This values equals 1/24. Fall back to 24 fps
|
||||
double _timeAtLastRender = 0.0;
|
||||
bool _hasReachedEnd = false;
|
||||
bool _tileIsReady = false;
|
||||
bool _isInitialized = false;
|
||||
bool _isSeeking = false;
|
||||
// Threshold where we are officially out of sync
|
||||
double _seekThreshold = 1.0;
|
||||
double _videoDuration = 0.0;
|
||||
glm::ivec2 _videoResolution = glm::ivec2(4096, 2048);
|
||||
double _frameDuration = 0.0;
|
||||
|
||||
// libmpv
|
||||
// Video properties. Try to read all these values from the video
|
||||
double _currentVideoTime = 0.0;
|
||||
double _fps = 24.0; // If when we read it it is 0, use 24 fps
|
||||
double _videoDuration = 0.0;
|
||||
glm::ivec2 _videoResolution = glm::ivec2(4096, 2048); // Used for the fbos
|
||||
|
||||
// Libmpv
|
||||
mpv_handle* _mpvHandle = nullptr;
|
||||
mpv_render_context* _mpvRenderContext = nullptr;
|
||||
std::unique_ptr<ghoul::opengl::Texture>_frameTexture = nullptr;
|
||||
mpv_opengl_fbo _mpvFbo;
|
||||
GLuint _fbo = 0;
|
||||
int _wakeup = 0;
|
||||
bool _didRender = false;
|
||||
std::unique_ptr<ghoul::opengl::Texture> _frameTexture = nullptr;
|
||||
GLuint _fbo = 0; // Our opengl framebuffer where mpv renders to
|
||||
int _wakeup = 0; // Signals when libmpv has a new frame ready
|
||||
bool _didRender = false; // To know when to swap buffers
|
||||
bool _isInitialized = false; // If libmpv has been inititalized
|
||||
bool _isSeeking = false; // Prevent seeking while already seeking
|
||||
double _seekThreshold = 1.0; // Threshold where we are officially out of sync
|
||||
|
||||
// Cache for rendering the same frame
|
||||
std::map<TileIndex::TileHashKey, Tile> _tileCache;
|
||||
// Tile handling
|
||||
std::map<TileIndex::TileHashKey, Tile> _tileCache; // Cache for rendering 1 frame
|
||||
bool _tileIsReady = false;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
Reference in New Issue
Block a user