Cleanup, add comments and rename AnimationMode to PlaybackMode

This commit is contained in:
Ylva Selling
2023-02-09 12:29:25 -05:00
parent e51bd4b337
commit 13762fa4d3
2 changed files with 49 additions and 71 deletions

View File

@@ -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) {

View File

@@ -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